diff --git a/apps/files_sharing/lib/Listener/LoadSidebarListener.php b/apps/files_sharing/lib/Listener/LoadSidebarListener.php
index e6a30a5688173..4768f2e0657ca 100644
--- a/apps/files_sharing/lib/Listener/LoadSidebarListener.php
+++ b/apps/files_sharing/lib/Listener/LoadSidebarListener.php
@@ -38,6 +38,10 @@ public function handle(Event $event): void {
return;
}
Util::addScript(Application::APP_ID, 'files_sharing_tab', 'files');
+ // Vue 3 bridge exposing the unified sharing dialog on OCA.Sharing for the
+ // (Vue 2) sidebar to trigger without bundling Vue 3.
+ Util::addStyle(Application::APP_ID, 'sharing-dialog');
+ Util::addScript(Application::APP_ID, 'sharing-dialog', 'files');
$appConfig = Server::get(IAppConfig::class);
$gsConfig = Server::get(IConfig::class);
diff --git a/apps/files_sharing/src/components/SharingEntry.vue b/apps/files_sharing/src/components/SharingEntry.vue
index 28ad1d4d89f33..4b0d66732a37f 100644
--- a/apps/files_sharing/src/components/SharingEntry.vue
+++ b/apps/files_sharing/src/components/SharingEntry.vue
@@ -28,13 +28,14 @@
+
+
+
+
+
+
+ {{ t('files_sharing', 'Edit share') }}
+
+
+
+
+
+ {{ t('files_sharing', 'Delete share') }}
+
+
diff --git a/apps/files_sharing/src/components/SharingEntryLink.vue b/apps/files_sharing/src/components/SharingEntryLink.vue
index e67b3447335e1..e2bb0e4e48f72 100644
--- a/apps/files_sharing/src/components/SharingEntryLink.vue
+++ b/apps/files_sharing/src/components/SharingEntryLink.vue
@@ -21,7 +21,7 @@
{{ subtitle }}
@@ -151,6 +151,7 @@
@@ -159,6 +160,16 @@
{{ t('files_sharing', 'Customize link') }}
+
+
+
+
+ {{ t('files_sharing', 'Customize link') }}
+
+ openShareEditDialog(shareId: string | number, node?: Node): Promise
+}
+
+/**
+ * Get the sharing dialog API registered by the Vue 3 bridge, if loaded.
+ */
+function sharingDialogApi(): SharingDialogApi | undefined {
+ return (window.OCA?.Sharing as Partial | undefined) as SharingDialogApi | undefined
+}
+
+/**
+ * Whether the server provides the unified sharing API this dialog talks to.
+ * Mirrors the library check so the sidebar can gate on it without importing
+ * the Vue 3 code.
+ */
+export function isSharingDialogAvailable(): boolean {
+ const capabilities = getCapabilities() as { sharing?: { api_versions?: unknown[] } }
+ return (capabilities.sharing?.api_versions?.length ?? 0) > 0
+}
+
+/**
+ * Open the unified sharing dialog to create a new share for a node.
+ *
+ * @param node The file or folder to share
+ */
+export function openShareCreateDialog(node: Node): Promise {
+ const api = sharingDialogApi()
+ if (!api?.openSharingDialog) {
+ return Promise.reject(new Error('The unified sharing dialog is not available'))
+ }
+ return api.openSharingDialog(node)
+}
+
+/**
+ * Open the unified sharing dialog to edit an existing share.
+ *
+ * @param shareId The share id (mapped to the unified API by the legacy bridge)
+ * @param node The backing node, used for the dialog title
+ */
+export function openShareEditDialog(shareId: string | number, node?: Node): Promise {
+ const api = sharingDialogApi()
+ if (!api?.openShareEditDialog) {
+ return Promise.reject(new Error('The unified sharing dialog is not available'))
+ }
+ return api.openShareEditDialog(shareId, node)
+}
diff --git a/apps/files_sharing/src/sharing-dialog-bridge.ts b/apps/files_sharing/src/sharing-dialog-bridge.ts
new file mode 100644
index 0000000000000..2cd81c671b9d9
--- /dev/null
+++ b/apps/files_sharing/src/sharing-dialog-bridge.ts
@@ -0,0 +1,39 @@
+/**
+ * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import type { Node } from '@nextcloud/files'
+
+import { getShare, isSharingDialogAvailable, openSharingDialog } from '@nextcloud/sharing/dialog'
+
+/**
+ * Bridge the Vue 3 unified sharing dialog into the global `OCA.Sharing`
+ * namespace so the (still Vue 2) files_sharing sidebar can trigger it without
+ * importing Vue 3 code into its bundle. The dialog spawns its own Vue 3 app,
+ * so it must be registered from this Vue 3 entry point where `vue` and
+ * `@nextcloud/vue` resolve to their Vue 3 versions.
+ *
+ * Once files_sharing is migrated to Vue 3 this bridge can be dropped and the
+ * library imported directly.
+ */
+
+window.OCA ??= {}
+window.OCA.Sharing ??= {}
+
+Object.assign(window.OCA.Sharing, {
+ openSharingDialog,
+
+ /**
+ * Open the unified sharing dialog to edit an existing share.
+ *
+ * @param shareId The share id (mapped to the unified API by the legacy bridge)
+ * @param node The backing node, used for the dialog title
+ */
+ async openShareEditDialog(shareId: string | number, node?: Node): Promise {
+ const share = await getShare(String(shareId))
+ return share.showDialog(node)
+ },
+
+ isSharingDialogAvailable,
+})
diff --git a/apps/files_sharing/src/views/SharingTab.vue b/apps/files_sharing/src/views/SharingTab.vue
index 0463a9969d28f..230454e761cef 100644
--- a/apps/files_sharing/src/views/SharingTab.vue
+++ b/apps/files_sharing/src/views/SharingTab.vue
@@ -27,6 +27,19 @@
+
+
+
+
+
+ {{ t('files_sharing', 'Share') }}
+
+
=0.10.0"
@@ -8945,7 +8934,7 @@
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"is-extglob": "^2.1.1"
@@ -9005,7 +8994,7 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"engines": {
"node": ">=0.12.0"
@@ -10508,7 +10497,7 @@
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"braces": "^3.0.3",
@@ -10522,7 +10511,7 @@
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
"integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"engines": {
"node": ">=8.6"
@@ -10815,7 +10804,6 @@
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
"integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
- "dev": true,
"license": "MIT",
"optional": true
},
@@ -11824,6 +11812,15 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/qrcode.vue": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/qrcode.vue/-/qrcode.vue-3.10.0.tgz",
+ "integrity": "sha512-1bjeBds9hRKMszZuBuYQZor9HdJYWtb0S44HG1JofZ9uicpJpdF+TtDvqo3+2ZlH0k80WVIkmiKB4hq0/N6/rA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "vue": "^3.0.0"
+ }
+ },
"node_modules/qs": {
"version": "6.15.3",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz",
@@ -12461,7 +12458,7 @@
"version": "1.102.0",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.102.0.tgz",
"integrity": "sha512-NSOyTnaQF7rTAEOtI2fwb386vL+akyiQLBZu8Na7hXCb+umJy0GAqlcMIaqACZ6Z1VgTBS4K9PG6B3IdjHGJsw==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"chokidar": "^5.0.0",
@@ -13914,7 +13911,7 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"is-number": "^7.0.0"
@@ -14142,7 +14139,7 @@
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz",
"integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==",
- "dev": true,
+ "devOptional": true,
"license": "MIT"
},
"node_modules/unicorn-magic": {
@@ -14641,7 +14638,6 @@
"cpu": [
"ppc64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -14658,7 +14654,6 @@
"cpu": [
"arm"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -14675,7 +14670,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -14692,7 +14686,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -14709,7 +14702,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -14726,7 +14718,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -14743,7 +14734,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -14760,7 +14750,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -14777,7 +14766,6 @@
"cpu": [
"arm"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -14794,7 +14782,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -14811,7 +14798,6 @@
"cpu": [
"ia32"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -14828,7 +14814,6 @@
"cpu": [
"loong64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -14845,7 +14830,6 @@
"cpu": [
"mips64el"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -14862,7 +14846,6 @@
"cpu": [
"ppc64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -14879,7 +14862,6 @@
"cpu": [
"riscv64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -14896,7 +14878,6 @@
"cpu": [
"s390x"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -14913,7 +14894,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -14930,7 +14910,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -14947,7 +14926,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -14964,7 +14942,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -14981,7 +14958,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -14998,7 +14974,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -15015,7 +14990,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -15032,7 +15006,6 @@
"cpu": [
"arm64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -15049,7 +15022,6 @@
"cpu": [
"ia32"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
@@ -15066,7 +15038,6 @@
"cpu": [
"x64"
],
- "dev": true,
"license": "MIT",
"optional": true,
"os": [
diff --git a/package.json b/package.json
index 7db9296f7e47b..8c80c3b77408c 100644
--- a/package.json
+++ b/package.json
@@ -54,7 +54,7 @@
"@nextcloud/password-confirmation": "^6.1.0",
"@nextcloud/paths": "^3.1.0",
"@nextcloud/router": "^3.1.0",
- "@nextcloud/sharing": "^0.4.0",
+ "@nextcloud/sharing": "^1.0.0-beta.1",
"@nextcloud/vue": "^9.3.1",
"@vueuse/core": "^14.1.0",
"@vueuse/integrations": "^14.1.0",