Skip to content

Commit 7c614c9

Browse files
authored
feat: hide panel by default when not explicit enabled (#440)
1 parent 57deaf0 commit 7c614c9

10 files changed

Lines changed: 143 additions & 46 deletions

File tree

docs/pages/index.vue

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,15 @@ const { data } = await useAsyncData('landing', () => {
2222
queryContent('/').findOne(),
2323
])
2424
})
25-
const [getStarted, page] = data.value
25+
26+
const [getStarted, page] = data.value! || []
2627
2728
const intervalId = ref()
2829
const currentStep = ref(0)
2930
const projectsSectionVisible = ref(false)
3031
const nuxtProjectsSection = ref(null)
3132
32-
const { data: module } = await useFetch<{
33+
const { data: mod } = await useFetch<{
3334
stats: {
3435
downloads: number
3536
stars: number
@@ -216,9 +217,9 @@ watch(projectsSectionVisible, () => {
216217
</template>
217218

218219
<template #links>
219-
<UAvatarGroup :max="13" size="md" class="flex-wrap lg:self-start [&_span:first-child]:text-xs">
220+
<UAvatarGroup v-if="mod" :max="13" size="md" class="flex-wrap lg:self-start [&_span:first-child]:text-xs">
220221
<UTooltip
221-
v-for="(contributor, idx) of module.contributors" :key="idx" :text="contributor.username"
222+
v-for="(contributor, idx) of mod.contributors" :key="idx" :text="contributor.username"
222223
class="rounded-full" :ui="{ background: 'bg-gray-50 dark:bg-gray-800/50' }"
223224
:popper="{ offsetDistance: 16 }"
224225
>
@@ -241,12 +242,12 @@ watch(projectsSectionVisible, () => {
241242
</p>
242243
</template>
243244

244-
<div class="flex flex-col items-center justify-center gap-8 sm:flex-row lg:gap-16">
245+
<div v-if="mod" class="flex flex-col items-center justify-center gap-8 sm:flex-row lg:gap-16">
245246
<NuxtLink class="group text-center" to="https://npmjs.org/package/@nuxt/devtools" target="_blank">
246247
<p
247248
class="group-hover:text-primary-500 dark:group-hover:text-primary-400 text-6xl font-semibold text-gray-900 dark:text-white"
248249
>
249-
{{ formatNumber(module.stats.downloads) }}+
250+
{{ formatNumber(mod.stats.downloads) }}+
250251
</p>
251252
<p>Monthly Downloads</p>
252253
</NuxtLink>
@@ -255,7 +256,7 @@ watch(projectsSectionVisible, () => {
255256
<p
256257
class="group-hover:text-primary-500 dark:group-hover:text-primary-400 text-6xl font-semibold text-gray-900 dark:text-white"
257258
>
258-
{{ formatNumber(module.stats.stars) }}+
259+
{{ formatNumber(mod.stats.stars) }}+
259260
</p>
260261
<p>Stars</p>
261262
</NuxtLink>

packages/devtools-kit/src/_types/options.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ export interface NuxtDevToolsOptions {
163163
scale: number
164164
showExperimentalFeatures: boolean
165165
showHelpButtons: boolean
166+
showPanel: boolean | null
166167
sidebarExpanded: boolean
167168
sidebarScrollable: boolean
168169
}

packages/devtools/client/pages/index.vue

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,16 @@ definePageMeta({
66
})
77
88
const telemetry = ref(true)
9+
const enableFloatPanel = ref(true)
10+
11+
const {
12+
showPanel,
13+
} = useDevToolsUIOptions()
914
1015
function visit() {
1116
telemetryEnabled.value = telemetry.value
17+
if (showPanel.value == null && enableFloatPanel.value)
18+
showPanel.value = true
1219
isFirstVisit.value = false
1320
}
1421
</script>
@@ -34,9 +41,14 @@ function visit() {
3441
</NButton>
3542

3643
<div absolute bottom-0 left-0 right-0 p4>
37-
<NCheckbox v-model="telemetry">
38-
<span op50>Send anonymous statistics, help us improving DevTools</span>
39-
</NCheckbox>
44+
<div flex="~ col gap-2" mxa w-max>
45+
<NCheckbox v-if="showPanel == null" v-model="enableFloatPanel" n="green6">
46+
<span op50>Show floating panel from now on</span>
47+
</NCheckbox>
48+
<NCheckbox v-model="telemetry" n="green6">
49+
<span op50>Send anonymous statistics, help us improving DevTools</span>
50+
</NCheckbox>
51+
</div>
4052
</div>
4153
</NPanelGrids>
4254
</template>

packages/devtools/client/pages/settings.vue

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ definePageMeta({
77
88
const {
99
interactionCloseOnOutsideClick,
10-
// showExperimentalFeatures,
10+
showPanel,
1111
showHelpButtons,
1212
scale,
1313
hiddenTabs,
@@ -107,7 +107,7 @@ watchEffect(() => {
107107
<NSwitch
108108
flex="~ row-reverse" py1 pl2 pr1 n-lime
109109
:model-value="!hiddenTabCategories.includes(name)"
110-
@update:model-value="v => toggleTabCategory(name, v)"
110+
@update:model-value="(v: boolean) => toggleTabCategory(name, v)"
111111
>
112112
<div flex="~ gap-2" flex-auto items-center justify-start>
113113
<span capitalize op75>{{ name }}</span>
@@ -120,7 +120,7 @@ watchEffect(() => {
120120
<NSwitch
121121
flex="~ row-reverse" py1 pl2 pr1 n-primary
122122
:model-value="!hiddenTabs.includes(tab.name)"
123-
@update:model-value="v => toggleTab(tab.name, v)"
123+
@update:model-value="(v: boolean) => toggleTab(tab.name, v)"
124124
>
125125
<div flex="~ gap-2" flex-auto items-center justify-start pr-4 :class="hiddenTabs.includes(tab.name) ? 'op25' : ''">
126126
<TabIcon text-xl :icon="tab.icon" :title="tab.title" />
@@ -197,10 +197,14 @@ watchEffect(() => {
197197
<span>Show help buttons</span>
198198
</NCheckbox>
199199

200+
<NCheckbox v-model="showPanel" n-primary>
201+
<span>Always show the floating panel</span>
202+
</NCheckbox>
203+
200204
<div mx--2 my1 h-1px border="b base" op75 />
201205

202206
<p>Minimize floating panel on inactive</p>
203-
<NSelect v-model.number="minimizePanelInactive" n="primary">
207+
<NSelect v-model.number="minimizePanelInactive" n-primary>
204208
<option v-for="i of MinimizeInactiveOptions" :key="i[0]" :value="i[1]">
205209
{{ i[0] }}
206210
</option>

packages/devtools/src/constant.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export const defaultTabOptions: NuxtDevToolsOptions = {
3434
interactionCloseOnOutsideClick: false,
3535
showExperimentalFeatures: false,
3636
showHelpButtons: true,
37+
showPanel: null,
3738
scale: 1,
3839
minimizePanelInactive: 5000,
3940
hiddenTabs: [],

packages/devtools/src/module-main.ts

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@ import { existsSync } from 'node:fs'
22
import os from 'node:os'
33
import { join } from 'pathe'
44
import type { Nuxt } from 'nuxt/schema'
5-
import { addPlugin, addVitePlugin, logger } from '@nuxt/kit'
5+
import { addPlugin, addTemplate, addVitePlugin, logger } from '@nuxt/kit'
66
import type { ViteDevServer } from 'vite'
77
import { searchForWorkspaceRoot } from 'vite'
88
import sirv from 'sirv'
99
import { colors } from 'consola/utils'
1010
import { version } from '../package.json'
11-
import type { ModuleOptions } from './types'
11+
import type { ModuleOptions, NuxtDevToolsOptions } from './types'
1212
import { setupRPC } from './server-rpc'
1313
import { clientDir, isGlobalInstall, packageDir, runtimeDir } from './dirs'
14-
import { ROUTE_ANALYZE, ROUTE_AUTH, ROUTE_AUTH_VERIFY, ROUTE_CLIENT } from './constant'
14+
import { ROUTE_ANALYZE, ROUTE_AUTH, ROUTE_AUTH_VERIFY, ROUTE_CLIENT, defaultTabOptions } from './constant'
1515
import { getDevAuthToken } from './dev-auth'
16+
import { readLocalOptions } from './utils/local-options'
1617

1718
export async function enableModule(options: ModuleOptions, nuxt: Nuxt) {
1819
// Disable in test mode
@@ -30,8 +31,14 @@ export async function enableModule(options: ModuleOptions, nuxt: Nuxt) {
3031
return
3132
}
3233

34+
// Determine if user aware devtools, by checking the presentation in the config
35+
const enabledExplicitly = (nuxt.options.devtools === true)
36+
|| (nuxt.options.devtools && nuxt.options.devtools.enabled)
37+
|| !!nuxt.options.modules.find(m => m === '@nuxt/devtools' || m === '@nuxt/devtools-edge')
38+
3339
await nuxt.callHook('devtools:before')
3440

41+
// Make unimport exposing more information, like the usage of each auto imported function
3542
nuxt.options.imports.collectMeta = true
3643

3744
addPlugin({
@@ -44,6 +51,25 @@ export async function enableModule(options: ModuleOptions, nuxt: Nuxt) {
4451
mode: 'server',
4552
})
4653

54+
// Mainly for the injected runtime plugin to access the settings
55+
// Usage `import settings from '#build/devtools/settings'`
56+
addTemplate({
57+
filename: 'devtools/settings.mjs',
58+
async getContents() {
59+
const uiOptions = await readLocalOptions<NuxtDevToolsOptions['ui']>(
60+
{
61+
...defaultTabOptions.ui,
62+
// When not enabled explicitly, we hide the panel by default
63+
showPanel: enabledExplicitly ? true : null,
64+
},
65+
{ root: nuxt.options.rootDir },
66+
)
67+
return `export default ${JSON.stringify({
68+
ui: uiOptions,
69+
})}`
70+
},
71+
})
72+
4773
// Inject inline script
4874
nuxt.hook('nitro:config', (config) => {
4975
config.externals = config.externals || {}

packages/devtools/src/runtime/plugins/view/Main.vue

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<script setup lang="ts">
2-
import type { CSSProperties } from 'vue'
32
import { computed, onMounted, reactive, ref, watchEffect } from 'vue'
3+
import type { CSSProperties } from 'vue'
44
import type { NuxtDevtoolsHostClient } from '../../../types'
5+
import { settings } from '../../settings'
56
import { state } from './state'
67
import { millisecondToHumanreadable, useEventListener, useScreenSafeArea } from './utils'
78
import FrameBox from './FrameBox.vue'
@@ -20,6 +21,12 @@ const panelMargins = reactive({
2021
const safeArea = useScreenSafeArea()
2122
2223
const isSafari = navigator.userAgent.includes('Safari') && !navigator.userAgent.includes('Chrome')
24+
let isInit = true
25+
26+
watchEffect(() => {
27+
if (state.value.open)
28+
isInit = false
29+
})
2330
2431
watchEffect(() => {
2532
panelMargins.left = safeArea.left.value + 10
@@ -167,6 +174,17 @@ function bringUp() {
167174
}
168175
169176
const isHidden = computed(() => {
177+
if (state.value.open)
178+
return false
179+
if (settings.ui.showPanel === true)
180+
return false
181+
if (settings.ui.showPanel === false)
182+
return true
183+
// If not explicitly set, hide the panel on first load
184+
return isInit
185+
})
186+
187+
const isMinimized = computed(() => {
170188
if (state.value.minimizePanelInactive < 0)
171189
return false
172190
if (state.value.minimizePanelInactive === 0)
@@ -180,18 +198,25 @@ const isHidden = computed(() => {
180198
&& state.value.minimizePanelInactive
181199
})
182200
183-
const anchorStyle = computed(() => ({
184-
left: `${anchorPos.value.left}px`,
185-
top: `${anchorPos.value.top}px`,
186-
}))
201+
const anchorStyle = computed(() => {
202+
return {
203+
left: `${anchorPos.value.left}px`,
204+
top: `${anchorPos.value.top}px`,
205+
pointerEvents: isHidden.value ? 'none' : 'auto',
206+
} as const
207+
})
187208
188209
const panelStyle = computed(() => {
189210
const style: any = {
190211
transform: isVertical.value
191-
? `translate(${isHidden.value ? `calc(-50% ${state.value.position === 'right' ? '+' : '-'} 15px)` : '-50%'}, -50%) rotate(90deg)`
192-
: `translate(-50%, ${isHidden.value ? `calc(-50% ${state.value.position === 'top' ? '-' : '+'} 15px)` : '-50%'})`,
212+
? `translate(${isMinimized.value ? `calc(-50% ${state.value.position === 'right' ? '+' : '-'} 15px)` : '-50%'}, -50%) rotate(90deg)`
213+
: `translate(-50%, ${isMinimized.value ? `calc(-50% ${state.value.position === 'top' ? '-' : '+'} 15px)` : '-50%'})`,
193214
}
194215
if (isHidden.value) {
216+
style.opacity = 0
217+
style.pointerEvents = 'none'
218+
}
219+
if (isMinimized.value) {
195220
switch (state.value.position) {
196221
case 'top':
197222
case 'right':
@@ -313,11 +338,15 @@ onMounted(() => {
313338
:style="[anchorStyle, vars]"
314339
:class="{
315340
'nuxt-devtools-vertical': isVertical,
316-
'nuxt-devtools-hide': isHidden,
341+
'nuxt-devtools-hide': isMinimized,
317342
}"
318343
@mousemove="bringUp"
319344
>
320-
<div v-if="!isSafari" class="nuxt-devtools-glowing" :style="isDragging ? 'opacity: 0.6 !important' : ''" />
345+
<div
346+
v-if="!isSafari"
347+
class="nuxt-devtools-glowing"
348+
:style="isDragging ? 'opacity: 0.6 !important' : ''"
349+
/>
321350
<div
322351
ref="panelEl"
323352
class="nuxt-devtools-panel"
@@ -460,7 +489,7 @@ onMounted(() => {
460489
user-select: none;
461490
touch-action: none;
462491
max-width: 150px;
463-
transition: max-width 0.6s ease, padding 0.5s ease, transform 0.4s ease, all 0.6s ease;
492+
transition: all 0.6s ease, max-width 0.6s ease, padding 0.5s ease, transform 0.4s ease, opacity 0.2s ease;
464493
}
465494
466495
#nuxt-devtools-anchor.nuxt-devtools-hide .nuxt-devtools-panel {
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import type { NuxtDevToolsOptions } from '../types'
2+
3+
// @ts-expect-error virtual module
4+
import _settings from '#build/devtools/settings'
5+
6+
export const settings = _settings as {
7+
ui: NuxtDevToolsOptions['ui']
8+
}

packages/devtools/src/server-rpc/options.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { NuxtDevToolsOptions, NuxtDevtoolsServerContext, ServerFunctions } from '../types'
2-
import { readOptions, writeOptions } from '../utils/options'
2+
import { readLocalOptions, writeLocalOptions } from '../utils/local-options'
33
import { defaultTabOptions } from '../constant'
44

55
export function setupOptionsRPC({ nuxt }: NuxtDevtoolsServerContext) {
@@ -15,7 +15,7 @@ export function setupOptionsRPC({ nuxt }: NuxtDevtoolsServerContext) {
1515
}
1616

1717
async function read<T extends keyof NuxtDevToolsOptions>(tab: T) {
18-
options![tab] = await readOptions<NuxtDevToolsOptions[T]>(defaultTabOptions[tab], {
18+
options![tab] = await readLocalOptions<NuxtDevToolsOptions[T]>(defaultTabOptions[tab], {
1919
root: nuxt.options.rootDir,
2020
key: tab !== 'ui' && tab,
2121
})
@@ -26,9 +26,17 @@ export function setupOptionsRPC({ nuxt }: NuxtDevtoolsServerContext) {
2626
async updateOptions(tab, _settings) {
2727
const settings = await getOptions(tab)
2828
Object.assign(settings, _settings)
29-
await writeOptions({ ...settings }, {
30-
root: nuxt.options.rootDir,
31-
key: tab !== 'ui' && tab,
29+
await writeLocalOptions(
30+
{ ...settings },
31+
{
32+
root: nuxt.options.rootDir,
33+
key: tab !== 'ui' && tab,
34+
},
35+
)
36+
nuxt.callHook('builder:generateApp', {
37+
filter(template) {
38+
return template.filename.includes('devtools/settings.mjs')
39+
},
3240
})
3341
},
3442
getOptions,

0 commit comments

Comments
 (0)