From 75a814f8a0664a4661e24f9d9c6a6abb73bbc490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20S=C3=A1nchez?= Date: Tue, 11 Nov 2025 06:21:04 +0100 Subject: [PATCH 1/4] fix(ui): remove flash when switching to dark (#909) --- packages/devtools-ui-kit/src/components/NDarkToggle.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/devtools-ui-kit/src/components/NDarkToggle.vue b/packages/devtools-ui-kit/src/components/NDarkToggle.vue index 2b9086b345..3ff5338685 100644 --- a/packages/devtools-ui-kit/src/components/NDarkToggle.vue +++ b/packages/devtools-ui-kit/src/components/NDarkToggle.vue @@ -55,6 +55,7 @@ function toggle(event?: MouseEvent) { { duration: 400, easing: 'ease-in', + fill: 'forwards', pseudoElement: isDark.value ? '::view-transition-old(root)' : '::view-transition-new(root)', From bc1d11c92a7da9bc6e1870417029c50cb66a964e Mon Sep 17 00:00:00 2001 From: Rihan Arfan Date: Fri, 21 Nov 2025 03:34:15 +0000 Subject: [PATCH 2/4] feat: support passing additional permissions to the iframe (#911) --- docs/content/2.module/0.guide.md | 15 +++++++++++++++ docs/content/2.module/1.utils-kit.md | 15 +++++++++++++++ packages/devtools-kit/src/_types/custom-tabs.ts | 7 +++++++ .../devtools/client/components/IframeView.vue | 2 +- 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/docs/content/2.module/0.guide.md b/docs/content/2.module/0.guide.md index 4c588734a2..54961c1c78 100644 --- a/docs/content/2.module/0.guide.md +++ b/docs/content/2.module/0.guide.md @@ -59,6 +59,21 @@ nuxt.hook('devtools:customTabs', (tabs) => { }) ``` +### Iframe Permissions + +By default, iframes have `clipboard-write` and `clipboard-read` permissions enabled. You can add additional permissions using the `permissions` option: + +```ts +const view: ModuleIframeView = { + type: 'iframe', + src: '/url-to-your-module-view', + // Additional permissions to allow in the iframe + permissions: ['camera', 'microphone', 'geolocation'], +} +``` + +These permissions will be merged with the default ones and set on the iframe's `allow` attribute. + Learn more about [DevTools Utility Kit](/module/utils-kit). ## Lazy Service Launching diff --git a/docs/content/2.module/1.utils-kit.md b/docs/content/2.module/1.utils-kit.md index d5b626b7b5..e18adf4476 100644 --- a/docs/content/2.module/1.utils-kit.md +++ b/docs/content/2.module/1.utils-kit.md @@ -39,6 +39,21 @@ addCustomTab(() => ({ })) ``` +The iframe view supports the following options: + +- `src`: URL of the iframe +- `persistent`: Whether to persist the iframe instance when switching tabs (default: `true`) +- `permissions`: Additional permissions to allow in the iframe (merged with default `clipboard-write` and `clipboard-read`) + +```ts +const view: ModuleIframeView = { + type: 'iframe', + src: '/url-to-your-module-view', + persistent: true, + permissions: ['camera', 'microphone'], +} +``` + ### `refreshCustomTabs()` A shorthand for call hook `devtools:customTabs:refresh`. It will refresh all custom tabs. diff --git a/packages/devtools-kit/src/_types/custom-tabs.ts b/packages/devtools-kit/src/_types/custom-tabs.ts index 5ed71ad131..e1fd8b312a 100644 --- a/packages/devtools-kit/src/_types/custom-tabs.ts +++ b/packages/devtools-kit/src/_types/custom-tabs.ts @@ -68,6 +68,13 @@ export interface ModuleIframeView { * @default true */ persistent?: boolean + /** + * Additional permissions to allow in the iframe + * These will be merged with the default permissions (clipboard-write, clipboard-read) + * + * @example ['camera', 'microphone', 'geolocation'] + */ + permissions?: string[] } export interface ModuleVNodeView { diff --git a/packages/devtools/client/components/IframeView.vue b/packages/devtools/client/components/IframeView.vue index 1ad1513238..b9d87d6951 100644 --- a/packages/devtools/client/components/IframeView.vue +++ b/packages/devtools/client/components/IframeView.vue @@ -23,7 +23,7 @@ const box = reactive(useElementBounding(anchor)) onMounted(() => { const view = props.tab.view as ModuleIframeView const isPersistent = view.persistent !== false - const allowedPermissions = ['clipboard-write', 'clipboard-read'] + const allowedPermissions = ['clipboard-write', 'clipboard-read', ...(view.permissions || [])] if (iframeCacheMap.get(key.value) && isPersistent) { iframeEl.value = iframeCacheMap.get(key.value)! From 9b54c01c041c29b9fe3132abf85b351c972336d2 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Tue, 25 Nov 2025 17:54:10 +0900 Subject: [PATCH 3/4] chore: update deps --- package.json | 2 +- .../components/NuxtDevtoolsInspectPanel.vue | 2 +- pnpm-lock.yaml | 1874 +++++++++-------- pnpm-workspace.yaml | 54 +- 4 files changed, 1007 insertions(+), 925 deletions(-) diff --git a/package.json b/package.json index bab73e356d..08e12d258a 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "type": "module", "version": "3.1.0", "private": true, - "packageManager": "pnpm@10.20.0", + "packageManager": "pnpm@10.23.0", "repository": { "type": "git", "url": "git+https://github.com/nuxt/devtools.git" diff --git a/packages/devtools/src/webcomponents/components/NuxtDevtoolsInspectPanel.vue b/packages/devtools/src/webcomponents/components/NuxtDevtoolsInspectPanel.vue index 583a9a05c7..f1fa985d94 100644 --- a/packages/devtools/src/webcomponents/components/NuxtDevtoolsInspectPanel.vue +++ b/packages/devtools/src/webcomponents/components/NuxtDevtoolsInspectPanel.vue @@ -78,7 +78,7 @@ async function openInEditor() {