nuxtseo-layer-devtools 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/css/global.css +15 -5
- package/components/DevtoolsLayout.vue +88 -21
- package/package.json +1 -1
package/assets/css/global.css
CHANGED
|
@@ -216,7 +216,7 @@ h1, h2, h3, h4, h5, h6 {
|
|
|
216
216
|
}
|
|
217
217
|
|
|
218
218
|
.dark .glass {
|
|
219
|
-
background: oklch(9% 0.005 260 / 0.
|
|
219
|
+
background: oklch(9% 0.005 260 / 0.7);
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
/* Code block styling */
|
|
@@ -565,19 +565,29 @@ html.dark {
|
|
|
565
565
|
flex: 1;
|
|
566
566
|
display: flex;
|
|
567
567
|
flex-direction: column;
|
|
568
|
-
padding: 0.75rem;
|
|
569
568
|
min-height: calc(100vh - 60px);
|
|
570
569
|
}
|
|
571
570
|
|
|
571
|
+
.devtools-main-content {
|
|
572
|
+
display: flex;
|
|
573
|
+
flex-direction: column;
|
|
574
|
+
width: 100%;
|
|
575
|
+
max-width: 80rem;
|
|
576
|
+
margin: 0 auto;
|
|
577
|
+
padding: 0.75rem 1rem;
|
|
578
|
+
}
|
|
579
|
+
|
|
572
580
|
@media (min-width: 640px) {
|
|
573
|
-
.devtools-main {
|
|
574
|
-
padding: 1rem;
|
|
581
|
+
.devtools-main-content {
|
|
582
|
+
padding: 1rem 1.25rem;
|
|
575
583
|
}
|
|
576
584
|
}
|
|
577
585
|
|
|
578
586
|
@media (max-height: 600px) {
|
|
579
587
|
.devtools-main {
|
|
580
|
-
padding: 0;
|
|
581
588
|
min-height: 0;
|
|
582
589
|
}
|
|
590
|
+
.devtools-main-content {
|
|
591
|
+
padding: 0;
|
|
592
|
+
}
|
|
583
593
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import { onClickOutside } from '@vueuse/core'
|
|
3
|
+
import { computed, ref } from 'vue'
|
|
3
4
|
import { colorMode } from '../composables/rpc'
|
|
4
5
|
import { hasProductionUrl, isProductionMode, previewSource, productionUrl } from '../composables/state'
|
|
5
6
|
|
|
@@ -58,6 +59,15 @@ const productionHostname = computed(() => {
|
|
|
58
59
|
})
|
|
59
60
|
|
|
60
61
|
const isRouteNav = computed(() => navItems.some(item => item.to))
|
|
62
|
+
|
|
63
|
+
const modeDropdownOpen = ref(false)
|
|
64
|
+
const modeDropdownRef = ref<HTMLElement>()
|
|
65
|
+
onClickOutside(modeDropdownRef, () => { modeDropdownOpen.value = false })
|
|
66
|
+
|
|
67
|
+
function selectMode(mode: 'local' | 'production') {
|
|
68
|
+
previewSource.value = mode
|
|
69
|
+
modeDropdownOpen.value = false
|
|
70
|
+
}
|
|
61
71
|
</script>
|
|
62
72
|
|
|
63
73
|
<template>
|
|
@@ -94,16 +104,8 @@ const isRouteNav = computed(() => navItems.some(item => item.to))
|
|
|
94
104
|
>
|
|
95
105
|
v{{ version }}
|
|
96
106
|
</UBadge>
|
|
97
|
-
<
|
|
98
|
-
|
|
99
|
-
:items="[
|
|
100
|
-
{ label: 'Local', icon: 'carbon:laptop', onSelect: () => previewSource = 'local' },
|
|
101
|
-
{ label: 'Production', icon: 'carbon:cloud', hostname: productionHostname, onSelect: () => previewSource = 'production' },
|
|
102
|
-
]"
|
|
103
|
-
:content="{ side: 'bottom', align: 'start', sideOffset: 8 }"
|
|
104
|
-
:ui="{ content: 'z-[200]' }"
|
|
105
|
-
>
|
|
106
|
-
<button type="button" class="devtools-mode-btn">
|
|
107
|
+
<div v-if="hasProductionUrl" ref="modeDropdownRef" class="mode-dropdown-wrapper">
|
|
108
|
+
<button type="button" class="devtools-mode-btn" @click="modeDropdownOpen = !modeDropdownOpen">
|
|
107
109
|
<UIcon :name="isProductionMode ? 'carbon:cloud' : 'carbon:laptop'" class="w-3.5 h-3.5" />
|
|
108
110
|
<span class="hidden sm:inline">{{ isProductionMode ? 'Production' : 'Local' }}</span>
|
|
109
111
|
<template v-if="isProductionMode">
|
|
@@ -112,16 +114,25 @@ const isRouteNav = computed(() => navItems.some(item => item.to))
|
|
|
112
114
|
{{ productionHostname }}
|
|
113
115
|
</span>
|
|
114
116
|
</template>
|
|
115
|
-
<UIcon name="carbon:chevron-down" class="w-3 h-3 opacity-50" />
|
|
117
|
+
<UIcon name="carbon:chevron-down" class="w-3 h-3 opacity-50 transition-transform" :class="modeDropdownOpen ? 'rotate-180' : ''" />
|
|
116
118
|
</button>
|
|
117
|
-
<
|
|
118
|
-
<
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
119
|
+
<Transition name="dropdown">
|
|
120
|
+
<div v-if="modeDropdownOpen" class="mode-dropdown-menu">
|
|
121
|
+
<button type="button" class="mode-dropdown-item" @click="selectMode('local')">
|
|
122
|
+
<UIcon name="carbon:laptop" class="w-4 h-4" />
|
|
123
|
+
<span>Local</span>
|
|
124
|
+
</button>
|
|
125
|
+
<button type="button" class="mode-dropdown-item" @click="selectMode('production')">
|
|
126
|
+
<UIcon name="carbon:cloud" class="w-4 h-4" />
|
|
127
|
+
<span>Production</span>
|
|
128
|
+
<span class="devtools-production-badge text-[10px]">
|
|
129
|
+
<span class="devtools-production-dot" />
|
|
130
|
+
{{ productionHostname }}
|
|
131
|
+
</span>
|
|
132
|
+
</button>
|
|
133
|
+
</div>
|
|
134
|
+
</Transition>
|
|
135
|
+
</div>
|
|
125
136
|
</div>
|
|
126
137
|
</div>
|
|
127
138
|
|
|
@@ -207,7 +218,7 @@ const isRouteNav = computed(() => navItems.some(item => item.to))
|
|
|
207
218
|
|
|
208
219
|
<!-- Main Content -->
|
|
209
220
|
<div class="devtools-main">
|
|
210
|
-
<main class="
|
|
221
|
+
<main class="devtools-main-content">
|
|
211
222
|
<DevtoolsLoading v-if="loading" />
|
|
212
223
|
<div v-show="!loading">
|
|
213
224
|
<slot />
|
|
@@ -217,3 +228,59 @@ const isRouteNav = computed(() => navItems.some(item => item.to))
|
|
|
217
228
|
</div>
|
|
218
229
|
</UApp>
|
|
219
230
|
</template>
|
|
231
|
+
|
|
232
|
+
<style scoped>
|
|
233
|
+
.mode-dropdown-wrapper {
|
|
234
|
+
position: relative;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.mode-dropdown-menu {
|
|
238
|
+
position: absolute;
|
|
239
|
+
top: calc(100% + 6px);
|
|
240
|
+
left: 0;
|
|
241
|
+
min-width: 180px;
|
|
242
|
+
padding: 4px;
|
|
243
|
+
border-radius: var(--radius-md);
|
|
244
|
+
border: 1px solid var(--color-border);
|
|
245
|
+
background: var(--color-surface-elevated);
|
|
246
|
+
box-shadow: 0 8px 24px oklch(0% 0 0 / 0.12);
|
|
247
|
+
z-index: 100;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.dark .mode-dropdown-menu {
|
|
251
|
+
box-shadow: 0 8px 24px oklch(0% 0 0 / 0.4);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.mode-dropdown-item {
|
|
255
|
+
display: flex;
|
|
256
|
+
align-items: center;
|
|
257
|
+
gap: 0.5rem;
|
|
258
|
+
width: 100%;
|
|
259
|
+
padding: 0.4rem 0.625rem;
|
|
260
|
+
font-size: 0.75rem;
|
|
261
|
+
font-weight: 500;
|
|
262
|
+
color: var(--color-text-muted);
|
|
263
|
+
border-radius: var(--radius-sm);
|
|
264
|
+
cursor: pointer;
|
|
265
|
+
transition: background 100ms, color 100ms;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.mode-dropdown-item:hover {
|
|
269
|
+
background: var(--color-surface-sunken);
|
|
270
|
+
color: var(--color-text);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.dropdown-enter-active {
|
|
274
|
+
transition: opacity 150ms ease, transform 150ms ease;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.dropdown-leave-active {
|
|
278
|
+
transition: opacity 100ms ease, transform 100ms ease;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.dropdown-enter-from,
|
|
282
|
+
.dropdown-leave-to {
|
|
283
|
+
opacity: 0;
|
|
284
|
+
transform: translateY(-4px);
|
|
285
|
+
}
|
|
286
|
+
</style>
|