@edgedev/create-edge-app 1.2.32 → 1.2.34
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/deploy.sh +77 -0
- package/edge/components/cms/block.vue +228 -18
- package/edge/components/cms/blockApi.vue +3 -3
- package/edge/components/cms/blockEditor.vue +374 -85
- package/edge/components/cms/blockPicker.vue +29 -3
- package/edge/components/cms/blockRender.vue +3 -3
- package/edge/components/cms/blocksManager.vue +755 -82
- package/edge/components/cms/codeEditor.vue +15 -6
- package/edge/components/cms/fontUpload.vue +318 -2
- package/edge/components/cms/htmlContent.vue +230 -89
- package/edge/components/cms/menu.vue +5 -4
- package/edge/components/cms/page.vue +750 -21
- package/edge/components/cms/site.vue +624 -84
- package/edge/components/cms/sitesManager.vue +5 -4
- package/edge/components/cms/themeEditor.vue +196 -162
- package/edge/components/editor.vue +5 -1
- package/edge/composables/global.ts +37 -5
- package/edge/composables/useCmsNewDocs.js +100 -0
- package/edge/composables/useEdgeCmsDialogPositionFix.js +19 -0
- package/edge/routes/cms/dashboard/blocks/[block].vue +5 -0
- package/edge/routes/cms/dashboard/blocks/index.vue +12 -1
- package/edge/routes/cms/dashboard/media/index.vue +5 -0
- package/edge/routes/cms/dashboard/sites/[site]/[[page]].vue +4 -0
- package/edge/routes/cms/dashboard/sites/[site].vue +4 -0
- package/edge/routes/cms/dashboard/sites/index.vue +4 -0
- package/edge/routes/cms/dashboard/templates/[page].vue +4 -0
- package/edge/routes/cms/dashboard/templates/index.vue +4 -0
- package/edge/routes/cms/dashboard/themes/[theme].vue +5 -0
- package/edge/routes/cms/dashboard/themes/index.vue +330 -1
- package/firebase.json +4 -0
- package/nuxt.config.ts +1 -1
- package/package.json +2 -2
- package/pages/app.vue +12 -12
package/deploy.sh
CHANGED
|
@@ -81,12 +81,89 @@ warn_edge_subtree_sync() {
|
|
|
81
81
|
fi
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
resolve_functions_region() {
|
|
85
|
+
if [ -n "${FIREBASE_STORE_REGION:-}" ]; then
|
|
86
|
+
echo "$FIREBASE_STORE_REGION"
|
|
87
|
+
return
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
if [ -f "functions/.env.prod" ]; then
|
|
91
|
+
local env_region
|
|
92
|
+
env_region="$(rg '^FIREBASE_STORE_REGION=' functions/.env.prod -N | tail -n 1 | sed 's/^FIREBASE_STORE_REGION=//; s/^"//; s/"$//')"
|
|
93
|
+
if [ -n "$env_region" ]; then
|
|
94
|
+
echo "$env_region"
|
|
95
|
+
return
|
|
96
|
+
fi
|
|
97
|
+
fi
|
|
98
|
+
|
|
99
|
+
echo "us-west1"
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
ensure_callable_public_access() {
|
|
103
|
+
if ! command -v gcloud >/dev/null 2>&1; then
|
|
104
|
+
echo "Deploy aborted: gcloud CLI not found. It is required to enforce callable invoker access." >&2
|
|
105
|
+
exit 1
|
|
106
|
+
fi
|
|
107
|
+
|
|
108
|
+
local region
|
|
109
|
+
region="$(resolve_functions_region)"
|
|
110
|
+
|
|
111
|
+
local callable_functions
|
|
112
|
+
callable_functions="$(
|
|
113
|
+
node - <<'NODE'
|
|
114
|
+
const fs = require('fs')
|
|
115
|
+
const path = require('path')
|
|
116
|
+
|
|
117
|
+
const root = process.cwd()
|
|
118
|
+
const indexPath = path.join(root, 'functions', 'index.js')
|
|
119
|
+
const indexSource = fs.readFileSync(indexPath, 'utf8')
|
|
120
|
+
|
|
121
|
+
const moduleRequirePattern = /^\s*exports\.(\w+)\s*=\s*require\(\s*['"]\.\/([^'"]+)['"]\s*\)/gm
|
|
122
|
+
const callablePattern = /^\s*exports\.(\w+)\s*=\s*onCall\s*\(/gm
|
|
123
|
+
|
|
124
|
+
const functions = new Set()
|
|
125
|
+
let moduleMatch
|
|
126
|
+
|
|
127
|
+
while ((moduleMatch = moduleRequirePattern.exec(indexSource)) !== null) {
|
|
128
|
+
const prefix = moduleMatch[1]
|
|
129
|
+
const modulePath = path.join(root, 'functions', `${moduleMatch[2]}.js`)
|
|
130
|
+
if (!fs.existsSync(modulePath))
|
|
131
|
+
continue
|
|
132
|
+
|
|
133
|
+
const moduleSource = fs.readFileSync(modulePath, 'utf8')
|
|
134
|
+
let callableMatch
|
|
135
|
+
|
|
136
|
+
while ((callableMatch = callablePattern.exec(moduleSource)) !== null)
|
|
137
|
+
functions.add(`${prefix}-${callableMatch[1]}`)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
console.log(Array.from(functions).join('\n'))
|
|
141
|
+
NODE
|
|
142
|
+
)"
|
|
143
|
+
|
|
144
|
+
if [ -z "$callable_functions" ]; then
|
|
145
|
+
echo "No onCall functions detected. Skipping public invoker enforcement."
|
|
146
|
+
return
|
|
147
|
+
fi
|
|
148
|
+
|
|
149
|
+
echo "Ensuring public invoker access for callable functions in region '${region}'..."
|
|
150
|
+
while IFS= read -r function_name; do
|
|
151
|
+
[ -z "$function_name" ] && continue
|
|
152
|
+
echo " - ${function_name}"
|
|
153
|
+
gcloud functions add-invoker-policy-binding "$function_name" \
|
|
154
|
+
--gen2 \
|
|
155
|
+
--region "$region" \
|
|
156
|
+
--member="allUsers" >/dev/null
|
|
157
|
+
done <<< "$callable_functions"
|
|
158
|
+
}
|
|
159
|
+
|
|
84
160
|
check_repo "." "root"
|
|
85
161
|
warn_edge_subtree_sync
|
|
86
162
|
|
|
87
163
|
pnpm run generate
|
|
88
164
|
export NODE_ENV=production
|
|
89
165
|
firebase deploy --only functions
|
|
166
|
+
ensure_callable_public_access
|
|
90
167
|
firebase deploy --only hosting
|
|
91
168
|
firebase deploy --only firestore
|
|
92
169
|
firebase deploy --only storage
|
|
@@ -26,25 +26,118 @@ const props = defineProps({
|
|
|
26
26
|
type: String,
|
|
27
27
|
default: 'auto',
|
|
28
28
|
},
|
|
29
|
+
allowDelete: {
|
|
30
|
+
type: Boolean,
|
|
31
|
+
default: true,
|
|
32
|
+
},
|
|
33
|
+
containFixed: {
|
|
34
|
+
type: Boolean,
|
|
35
|
+
default: false,
|
|
36
|
+
},
|
|
29
37
|
})
|
|
30
38
|
const emit = defineEmits(['update:modelValue', 'delete'])
|
|
31
39
|
const edgeFirebase = inject('edgeFirebase')
|
|
40
|
+
|
|
41
|
+
function normalizeConfigLiteral(str) {
|
|
42
|
+
return str
|
|
43
|
+
.replace(/(\{|,)\s*([A-Za-z_][\w-]*)\s*:/g, '$1"$2":')
|
|
44
|
+
.replace(/'/g, '"')
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function safeParseTagConfig(raw) {
|
|
48
|
+
try {
|
|
49
|
+
return JSON.parse(normalizeConfigLiteral(raw))
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return null
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function findMatchingBrace(str, startIdx) {
|
|
57
|
+
let depth = 0
|
|
58
|
+
let inString = false
|
|
59
|
+
let quote = null
|
|
60
|
+
let escape = false
|
|
61
|
+
|
|
62
|
+
for (let i = startIdx; i < str.length; i++) {
|
|
63
|
+
const ch = str[i]
|
|
64
|
+
if (inString) {
|
|
65
|
+
if (escape) {
|
|
66
|
+
escape = false
|
|
67
|
+
continue
|
|
68
|
+
}
|
|
69
|
+
if (ch === '\\') {
|
|
70
|
+
escape = true
|
|
71
|
+
continue
|
|
72
|
+
}
|
|
73
|
+
if (ch === quote) {
|
|
74
|
+
inString = false
|
|
75
|
+
quote = null
|
|
76
|
+
}
|
|
77
|
+
continue
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (ch === '"' || ch === '\'') {
|
|
81
|
+
inString = true
|
|
82
|
+
quote = ch
|
|
83
|
+
continue
|
|
84
|
+
}
|
|
85
|
+
if (ch === '{')
|
|
86
|
+
depth++
|
|
87
|
+
else if (ch === '}') {
|
|
88
|
+
depth--
|
|
89
|
+
if (depth === 0)
|
|
90
|
+
return i
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return -1
|
|
95
|
+
}
|
|
96
|
+
|
|
32
97
|
function extractFieldsInOrder(template) {
|
|
33
98
|
if (!template || typeof template !== 'string')
|
|
34
99
|
return []
|
|
100
|
+
|
|
35
101
|
const fields = []
|
|
36
102
|
const seen = new Set()
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
103
|
+
|
|
104
|
+
const TAG_START_RE = /\{\{\{\#([A-Za-z0-9_-]+)\s*\{/g
|
|
105
|
+
TAG_START_RE.lastIndex = 0
|
|
106
|
+
|
|
107
|
+
for (;;) {
|
|
108
|
+
const m = TAG_START_RE.exec(template)
|
|
109
|
+
if (!m)
|
|
110
|
+
break
|
|
111
|
+
|
|
112
|
+
const configStart = TAG_START_RE.lastIndex - 1
|
|
113
|
+
if (configStart < 0 || template[configStart] !== '{')
|
|
114
|
+
continue
|
|
115
|
+
|
|
116
|
+
const configEnd = findMatchingBrace(template, configStart)
|
|
117
|
+
if (configEnd === -1)
|
|
118
|
+
continue
|
|
119
|
+
|
|
120
|
+
const rawCfg = template.slice(configStart, configEnd + 1)
|
|
121
|
+
const parsedCfg = safeParseTagConfig(rawCfg)
|
|
122
|
+
|
|
123
|
+
let field = typeof parsedCfg?.field === 'string'
|
|
124
|
+
? parsedCfg.field.trim()
|
|
125
|
+
: ''
|
|
126
|
+
|
|
127
|
+
if (!field) {
|
|
128
|
+
const fm = rawCfg.match(/["']?field["']?\s*:\s*["']([^"']+)["']/)
|
|
129
|
+
field = fm?.[1]?.trim() || ''
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (field && !seen.has(field)) {
|
|
133
|
+
fields.push(field)
|
|
134
|
+
seen.add(field)
|
|
45
135
|
}
|
|
46
|
-
|
|
136
|
+
|
|
137
|
+
const closeTriple = template.indexOf('}}}', configEnd)
|
|
138
|
+
TAG_START_RE.lastIndex = closeTriple !== -1 ? closeTriple + 3 : configEnd + 1
|
|
47
139
|
}
|
|
140
|
+
|
|
48
141
|
return fields
|
|
49
142
|
}
|
|
50
143
|
|
|
@@ -71,6 +164,70 @@ const state = reactive({
|
|
|
71
164
|
validationErrors: [],
|
|
72
165
|
})
|
|
73
166
|
|
|
167
|
+
const INTERACTIVE_CLICK_SELECTOR = [
|
|
168
|
+
'[data-cms-interactive]',
|
|
169
|
+
'.cms-block-interactive',
|
|
170
|
+
'.cms-nav-toggle',
|
|
171
|
+
'.cms-nav-overlay',
|
|
172
|
+
'.cms-nav-panel',
|
|
173
|
+
'.cms-nav-close',
|
|
174
|
+
'.cms-nav-link',
|
|
175
|
+
].join(', ')
|
|
176
|
+
|
|
177
|
+
const hasFixedPositionInContent = computed(() => {
|
|
178
|
+
const content = String(modelValue.value?.content || '')
|
|
179
|
+
return /\bfixed\b/.test(content)
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
const normalizePreviewType = (value) => {
|
|
183
|
+
return value === 'dark' ? 'dark' : 'light'
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const resolvedPreviewType = computed(() => normalizePreviewType(modelValue.value?.previewType))
|
|
187
|
+
const sourceBlockDocId = computed(() => {
|
|
188
|
+
const direct = String(modelValue.value?.blockId || '').trim()
|
|
189
|
+
if (direct)
|
|
190
|
+
return direct
|
|
191
|
+
return String(props.blockId || '').trim()
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
const inheritedPreviewType = computed(() => {
|
|
195
|
+
const explicit = modelValue.value?.previewType
|
|
196
|
+
if (explicit === 'light' || explicit === 'dark')
|
|
197
|
+
return explicit
|
|
198
|
+
const docId = sourceBlockDocId.value
|
|
199
|
+
if (!docId)
|
|
200
|
+
return null
|
|
201
|
+
const blockDoc = edgeFirebase.data?.[`${edgeGlobal.edgeState.organizationDocPath}/blocks`]?.[docId]
|
|
202
|
+
const inherited = blockDoc?.previewType
|
|
203
|
+
return (inherited === 'light' || inherited === 'dark') ? inherited : null
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
const effectivePreviewType = computed(() => {
|
|
207
|
+
return normalizePreviewType(inheritedPreviewType.value ?? resolvedPreviewType.value)
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
const shouldContainFixedPreview = computed(() => {
|
|
211
|
+
return (props.editMode || props.containFixed) && hasFixedPositionInContent.value
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
const blockWrapperClass = computed(() => ({
|
|
215
|
+
'overflow-visible': shouldContainFixedPreview.value,
|
|
216
|
+
'min-h-[88px]': props.editMode && shouldContainFixedPreview.value,
|
|
217
|
+
'z-30': shouldContainFixedPreview.value,
|
|
218
|
+
'bg-white text-black': props.editMode && effectivePreviewType.value === 'light',
|
|
219
|
+
'bg-neutral-950 text-neutral-50': props.editMode && effectivePreviewType.value === 'dark',
|
|
220
|
+
'cms-nav-edit-static': props.editMode,
|
|
221
|
+
}))
|
|
222
|
+
|
|
223
|
+
const blockWrapperStyle = computed(() => {
|
|
224
|
+
if (!shouldContainFixedPreview.value || !props.editMode)
|
|
225
|
+
return null
|
|
226
|
+
return {
|
|
227
|
+
transform: 'translateZ(0)',
|
|
228
|
+
}
|
|
229
|
+
})
|
|
230
|
+
|
|
74
231
|
const isLightName = (value) => {
|
|
75
232
|
if (!value)
|
|
76
233
|
return false
|
|
@@ -147,9 +304,12 @@ const resetArrayItems = (field, metaSource = null) => {
|
|
|
147
304
|
}
|
|
148
305
|
}
|
|
149
306
|
|
|
150
|
-
const openEditor = async () => {
|
|
307
|
+
const openEditor = async (event) => {
|
|
151
308
|
if (!props.editMode)
|
|
152
309
|
return
|
|
310
|
+
const target = event?.target
|
|
311
|
+
if (target?.closest?.(INTERACTIVE_CLICK_SELECTOR))
|
|
312
|
+
return
|
|
153
313
|
const blockData = edgeFirebase.data[`${edgeGlobal.edgeState.organizationDocPath}/blocks`]?.[modelValue.value.blockId]
|
|
154
314
|
const templateMeta = blockData?.meta || modelValue.value?.meta || {}
|
|
155
315
|
const storedMeta = modelValue.value?.meta || {}
|
|
@@ -192,6 +352,11 @@ const openEditor = async () => {
|
|
|
192
352
|
state.afterLoad = true
|
|
193
353
|
}
|
|
194
354
|
|
|
355
|
+
const isLimitOne = (field) => {
|
|
356
|
+
const limit = Number(state.meta?.[field]?.limit)
|
|
357
|
+
return Number.isFinite(limit) && limit === 1
|
|
358
|
+
}
|
|
359
|
+
|
|
195
360
|
const normalizeValidationNumber = (value) => {
|
|
196
361
|
if (value === null || value === undefined || value === '')
|
|
197
362
|
return null
|
|
@@ -264,6 +429,31 @@ const orderedMeta = computed(() => {
|
|
|
264
429
|
return out
|
|
265
430
|
})
|
|
266
431
|
|
|
432
|
+
const hasEditableArrayControls = (entry) => {
|
|
433
|
+
if (!entry?.meta)
|
|
434
|
+
return false
|
|
435
|
+
|
|
436
|
+
// Manual arrays are editable through the schema/list UI.
|
|
437
|
+
if (!entry.meta?.api && !entry.meta?.collection)
|
|
438
|
+
return true
|
|
439
|
+
|
|
440
|
+
const collectionPath = entry.meta?.collection?.path
|
|
441
|
+
const supportsQueryControls = collectionPath !== 'post'
|
|
442
|
+
const queryOptions = Array.isArray(entry.meta?.queryOptions) ? entry.meta.queryOptions : []
|
|
443
|
+
const hasQueryOptions = supportsQueryControls && queryOptions.length > 0
|
|
444
|
+
const hasLimitControl = supportsQueryControls && !isLimitOne(entry.field)
|
|
445
|
+
|
|
446
|
+
return hasQueryOptions || hasLimitControl
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
const editableMetaEntries = computed(() => {
|
|
450
|
+
return orderedMeta.value.filter((entry) => {
|
|
451
|
+
if (entry?.meta?.type === 'array')
|
|
452
|
+
return hasEditableArrayControls(entry)
|
|
453
|
+
return true
|
|
454
|
+
})
|
|
455
|
+
})
|
|
456
|
+
|
|
267
457
|
const genTitleFromField = (field) => {
|
|
268
458
|
if (field?.title)
|
|
269
459
|
return field.title
|
|
@@ -324,7 +514,7 @@ const save = () => {
|
|
|
324
514
|
}
|
|
325
515
|
|
|
326
516
|
const aiFieldOptions = computed(() => {
|
|
327
|
-
return
|
|
517
|
+
return editableMetaEntries.value
|
|
328
518
|
.map(entry => ({
|
|
329
519
|
id: entry.field,
|
|
330
520
|
label: genTitleFromField(entry),
|
|
@@ -479,9 +669,10 @@ const getTagsFromPosts = computed(() => {
|
|
|
479
669
|
<template>
|
|
480
670
|
<div>
|
|
481
671
|
<div
|
|
482
|
-
:class="{ 'cursor-pointer': props.editMode }"
|
|
483
|
-
|
|
484
|
-
|
|
672
|
+
:class="[{ 'cursor-pointer': props.editMode }, blockWrapperClass]"
|
|
673
|
+
:style="blockWrapperStyle"
|
|
674
|
+
class="relative group"
|
|
675
|
+
@click="openEditor($event)"
|
|
485
676
|
>
|
|
486
677
|
<!-- Content -->
|
|
487
678
|
<edge-cms-block-api :site-id="props.siteId" :theme="props.theme" :content="modelValue?.content" :values="modelValue?.values" :meta="modelValue?.meta" :viewport-mode="props.viewportMode" @pending="state.loading = $event" />
|
|
@@ -499,7 +690,7 @@ const getTagsFromPosts = computed(() => {
|
|
|
499
690
|
<!-- Hover controls -->
|
|
500
691
|
<div v-if="props.editMode" class="absolute inset-0 opacity-0 group-hover:opacity-100 transition-opacity duration-200 z-20">
|
|
501
692
|
<!-- Delete button top right -->
|
|
502
|
-
<div class="absolute top-2 right-2">
|
|
693
|
+
<div v-if="props.allowDelete" class="absolute top-2 right-2">
|
|
503
694
|
<edge-shad-button
|
|
504
695
|
variant="destructive"
|
|
505
696
|
size="icon"
|
|
@@ -562,7 +753,7 @@ const getTagsFromPosts = computed(() => {
|
|
|
562
753
|
</SheetHeader>
|
|
563
754
|
|
|
564
755
|
<edge-shad-form ref="blockFormRef">
|
|
565
|
-
<div v-if="
|
|
756
|
+
<div v-if="editableMetaEntries.length === 0">
|
|
566
757
|
<Alert variant="info" class="mt-4 mb-4">
|
|
567
758
|
<AlertTitle>No editable fields found</AlertTitle>
|
|
568
759
|
<AlertDescription class="text-sm">
|
|
@@ -571,7 +762,7 @@ const getTagsFromPosts = computed(() => {
|
|
|
571
762
|
</Alert>
|
|
572
763
|
</div>
|
|
573
764
|
<div :class="modelValue.synced ? 'h-[calc(100vh-160px)]' : 'h-[calc(100vh-130px)]'" class="p-6 space-y-4 overflow-y-auto">
|
|
574
|
-
<template v-for="entry in
|
|
765
|
+
<template v-for="entry in editableMetaEntries" :key="entry.field">
|
|
575
766
|
<div v-if="entry.meta.type === 'array'">
|
|
576
767
|
<div v-if="!entry.meta?.api && !entry.meta?.collection">
|
|
577
768
|
<div v-if="entry.meta?.schema">
|
|
@@ -698,7 +889,12 @@ const getTagsFromPosts = computed(() => {
|
|
|
698
889
|
/>
|
|
699
890
|
</div>
|
|
700
891
|
</template>
|
|
701
|
-
<edge-shad-number
|
|
892
|
+
<edge-shad-number
|
|
893
|
+
v-if="entry.meta?.collection?.path !== 'post' && !isLimitOne(entry.field)"
|
|
894
|
+
v-model="state.meta[entry.field].limit"
|
|
895
|
+
name="limit"
|
|
896
|
+
label="Limit"
|
|
897
|
+
/>
|
|
702
898
|
</div>
|
|
703
899
|
</div>
|
|
704
900
|
<div v-else-if="entry.meta?.type === 'image'" class="w-full">
|
|
@@ -848,3 +1044,17 @@ const getTagsFromPosts = computed(() => {
|
|
|
848
1044
|
</Sheet>
|
|
849
1045
|
</div>
|
|
850
1046
|
</template>
|
|
1047
|
+
|
|
1048
|
+
<style scoped>
|
|
1049
|
+
.cms-nav-edit-static :deep([data-cms-nav-root] .cms-nav-toggle),
|
|
1050
|
+
.cms-nav-edit-static :deep([data-cms-nav-root] .cms-nav-close),
|
|
1051
|
+
.cms-nav-edit-static :deep([data-cms-nav-root] .cms-nav-link) {
|
|
1052
|
+
pointer-events: none !important;
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
.cms-nav-edit-static :deep([data-cms-nav-root] .cms-nav-overlay),
|
|
1056
|
+
.cms-nav-edit-static :deep([data-cms-nav-root] .cms-nav-panel) {
|
|
1057
|
+
display: none !important;
|
|
1058
|
+
pointer-events: none !important;
|
|
1059
|
+
}
|
|
1060
|
+
</style>
|
|
@@ -11,15 +11,15 @@ import { computedAsync } from '@vueuse/core'
|
|
|
11
11
|
const props = defineProps({
|
|
12
12
|
content: {
|
|
13
13
|
type: String,
|
|
14
|
-
|
|
14
|
+
default: '',
|
|
15
15
|
},
|
|
16
16
|
values: {
|
|
17
17
|
type: Object,
|
|
18
|
-
|
|
18
|
+
default: () => ({}),
|
|
19
19
|
},
|
|
20
20
|
meta: {
|
|
21
21
|
type: Object,
|
|
22
|
-
|
|
22
|
+
default: () => ({}),
|
|
23
23
|
},
|
|
24
24
|
theme: {
|
|
25
25
|
type: Object,
|