Skip to content

Commit 14a585b

Browse files
committed
perf(devtools): drop json-editor-vue
1 parent 362cee2 commit 14a585b

File tree

8 files changed

+170
-1409
lines changed

8 files changed

+170
-1409
lines changed

devtools/app.vue

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import type { GlobalDebugResponse, PathDebugResponse } from './composables/types
44
import { computed, provide, useAsyncData, useNuxtApp, useRoute, watch } from '#imports'
55
import defu from 'defu'
66
import { appFetch } from 'nuxtseo-layer-devtools/composables/rpc'
7-
87
import { loadShiki } from 'nuxtseo-layer-devtools/composables/shiki'
98
import { path, productionUrl, query, refreshTime } from 'nuxtseo-layer-devtools/composables/state'
109
import { encodeOgImageParams } from '../src/runtime/shared/urlEncoding'
@@ -14,7 +13,6 @@ import RendererSelectModal from './components/RendererSelectModal.vue'
1413
import { GlobalDebugKey, PathDebugKey, PathDebugStatusKey, RefetchPathDebugKey } from './composables/keys'
1514
import { useOgImage } from './composables/og-image'
1615
import { ogImageKey, options, optionsOverrides } from './util/logic'
17-
import 'vanilla-jsoneditor/themes/jse-theme-dark.css'
1816
1917
const RE_IMAGE_EXT = /\.(png|jpeg|jpg|webp)$/
2018

devtools/composables/rpc.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { BirpcReturn } from 'birpc'
33
import type { ClientFunctions, ServerFunctions } from '../../src/rpc-types'
44
import { appFetch, useDevtoolsConnection } from 'nuxtseo-layer-devtools/composables/rpc'
55
import { base, path, query, refreshSources } from 'nuxtseo-layer-devtools/composables/state'
6-
import { computed, onMounted, onUnmounted, ref } from 'vue'
6+
import { computed, ref } from 'vue'
77

88
export const devtoolsClient = ref<NuxtDevtoolsIframeClient>()
99

@@ -28,24 +28,32 @@ async function tryFallbackConnection() {
2828
return false
2929
}
3030

31+
let timer: null | NodeJS.Timeout = null
32+
3133
// Set timeout for connection - if not connected within 2s, try fallback
3234
onMounted(() => {
33-
const timer = setTimeout(async () => {
35+
timer = setTimeout(async () => {
3436
if (connectionState.value === 'connecting') {
3537
const fallbackWorked = await tryFallbackConnection()
3638
if (!fallbackWorked) {
3739
connectionState.value = 'failed'
3840
}
3941
}
42+
timer = null
4043
}, 2000)
4144

4245
onUnmounted(() => {
43-
clearTimeout(timer)
46+
if (timer) {
47+
clearTimeout(timer)
48+
}
4449
})
4550
})
4651

4752
useDevtoolsConnection({
4853
onConnected(client) {
54+
if (timer) {
55+
clearTimeout(timer)
56+
}
4957
connectionState.value = 'connected'
5058
base.value = client.host.nuxt.vueApp.config.globalProperties?.$router?.options?.history?.base || client.host.app.baseURL || '/'
5159
devtoolsClient.value = client

devtools/nuxt.config.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ export default defineNuxtConfig({
2222
optimizeDeps: {
2323
include: [
2424
'@vueuse/core',
25-
'json-editor-vue',
2625
],
2726
},
2827
},

devtools/package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@
55
"@iconify-json/carbon": "catalog:",
66
"@iconify-json/simple-icons": "catalog:devtools",
77
"@nuxt/devtools-kit": "catalog:",
8-
"@nuxt/devtools-ui-kit": "catalog:",
98
"@nuxt/kit": "catalog:",
109
"@vueuse/core": "catalog:",
11-
"json-editor-vue": "catalog:devtools",
1210
"nuxt": "catalog:",
1311
"nuxtseo-layer-devtools": "catalog:",
1412
"shiki": "catalog:devtools",

devtools/pages/index.vue

Lines changed: 117 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
<script lang="ts" setup>
2-
import JsonEditorVue from 'json-editor-vue'
32
import { useHead } from 'nuxt/app'
43
import { hasProductionUrl, previewSource, productionUrl } from 'nuxtseo-layer-devtools/composables/state'
54
import { withHttps } from 'ufo'
@@ -10,6 +9,27 @@ import { isConnectionFailed, isFallbackMode } from '../composables/rpc'
109
1110
const RE_SINGLE_QUOTE = /'/g
1211
const RE_VUE_FILENAME = /[^/]+\.vue$/
12+
const RE_HEX_COLOR = /^#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i
13+
14+
const EXCLUDED_PROPS = new Set(['colorMode'])
15+
const editableProps = computed(() =>
16+
Object.keys(propEditor.value).filter(k => !EXCLUDED_PROPS.has(k)),
17+
)
18+
19+
function editProp(key: string, value: unknown) {
20+
propEditor.value = { ...propEditor.value, [key]: value }
21+
updateProps({ [key]: value })
22+
}
23+
24+
function inferPropType(value: unknown): 'color' | 'number' | 'json' | 'string' {
25+
if (typeof value === 'number')
26+
return 'number'
27+
if (typeof value === 'string' && RE_HEX_COLOR.test(value))
28+
return 'color'
29+
if (typeof value === 'string')
30+
return 'string'
31+
return 'json'
32+
}
1333
1434
const {
1535
globalDebug,
@@ -953,13 +973,45 @@ const productionHostname = computed(() => {
953973
</UButton>
954974
</div>
955975

956-
<JsonEditorVue
957-
:model-value="propEditor"
958-
class="jse-theme-dark"
959-
:main-menu-bar="false"
960-
:navigation-bar="false"
961-
@update:model-value="updateProps"
962-
/>
976+
<div v-if="editableProps.length" class="prop-editor">
977+
<div v-for="key in editableProps" :key="key" class="prop-field">
978+
<label class="prop-label">{{ key }}</label>
979+
<input
980+
v-if="inferPropType(propEditor[key]) === 'color'"
981+
type="color"
982+
:value="propEditor[key]"
983+
class="prop-input prop-input-color"
984+
@input="editProp(key, ($event.target as HTMLInputElement).value)"
985+
>
986+
<input
987+
v-else-if="inferPropType(propEditor[key]) === 'number'"
988+
type="number"
989+
:value="propEditor[key]"
990+
class="prop-input"
991+
@input="editProp(key, Number(($event.target as HTMLInputElement).value))"
992+
>
993+
<textarea
994+
v-else-if="inferPropType(propEditor[key]) === 'json'"
995+
:value="JSON.stringify(propEditor[key], null, 2)"
996+
class="prop-input prop-input-json"
997+
rows="3"
998+
@change="(() => {
999+
try { editProp(key, JSON.parse(($event.target as HTMLTextAreaElement).value)) }
1000+
catch {}
1001+
})()"
1002+
/>
1003+
<input
1004+
v-else
1005+
type="text"
1006+
:value="propEditor[key]"
1007+
class="prop-input"
1008+
@input="editProp(key, ($event.target as HTMLInputElement).value)"
1009+
>
1010+
</div>
1011+
</div>
1012+
<div v-else class="prop-editor-empty">
1013+
No props defined
1014+
</div>
9631015
</div>
9641016

9651017
<!-- Fonts Tab -->
@@ -1558,6 +1610,63 @@ const productionHostname = computed(() => {
15581610
text-align: center;
15591611
}
15601612
1613+
/* Prop editor */
1614+
.prop-editor {
1615+
display: flex;
1616+
flex-direction: column;
1617+
gap: 0.375rem;
1618+
padding: 0.5rem 0.75rem;
1619+
}
1620+
1621+
.prop-field {
1622+
display: flex;
1623+
flex-direction: column;
1624+
gap: 0.125rem;
1625+
}
1626+
1627+
.prop-label {
1628+
font-family: var(--font-mono);
1629+
font-size: 0.6875rem;
1630+
color: var(--color-text-subtle);
1631+
letter-spacing: 0.01em;
1632+
}
1633+
1634+
.prop-input {
1635+
font-family: var(--font-mono);
1636+
font-size: 0.75rem;
1637+
padding: 0.25rem 0.375rem;
1638+
border-radius: var(--radius-sm);
1639+
border: 1px solid var(--color-border-subtle);
1640+
background: var(--color-surface-sunken);
1641+
color: var(--color-text);
1642+
outline: none;
1643+
transition: border-color 150ms;
1644+
}
1645+
1646+
.prop-input:focus {
1647+
border-color: var(--seo-green);
1648+
}
1649+
1650+
.prop-input-color {
1651+
width: 2.5rem;
1652+
height: 1.5rem;
1653+
padding: 0.125rem;
1654+
cursor: pointer;
1655+
}
1656+
1657+
.prop-input-json {
1658+
resize: vertical;
1659+
min-height: 2.5rem;
1660+
line-height: 1.4;
1661+
}
1662+
1663+
.prop-editor-empty {
1664+
padding: 1rem 0.75rem;
1665+
font-size: 0.75rem;
1666+
color: var(--color-text-subtle);
1667+
text-align: center;
1668+
}
1669+
15611670
/* Inline code */
15621671
.inline-code {
15631672
padding: 0.125rem 0.375rem;

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,6 @@
158158
"@img/sharp-linux-x64": "catalog:",
159159
"@nuxt/content": "catalog:",
160160
"@nuxt/devtools": "catalog:",
161-
"@nuxt/devtools-ui-kit": "catalog:",
162161
"@nuxt/fonts": "catalog:",
163162
"@nuxt/icon": "catalog:",
164163
"@nuxt/image": "catalog:",

0 commit comments

Comments
 (0)