@bagelink/vue 1.4.105 → 1.4.109
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/bin/generateFormSchema.ts +0 -4
- package/dist/components/Btn.vue.d.ts +8 -0
- package/dist/components/Btn.vue.d.ts.map +1 -1
- package/dist/components/Card.vue.d.ts +1 -0
- package/dist/components/Card.vue.d.ts.map +1 -1
- package/dist/components/Dropdown.vue.d.ts.map +1 -1
- package/dist/components/calendar/CalendarPopover.vue.d.ts +6 -0
- package/dist/components/calendar/CalendarPopover.vue.d.ts.map +1 -1
- package/dist/components/dataTable/DataTable.vue.d.ts +1 -1
- package/dist/components/dataTable/DataTable.vue.d.ts.map +1 -1
- package/dist/components/dataTable/useTableVirtualization.d.ts +1 -1
- package/dist/components/dataTable/useTableVirtualization.d.ts.map +1 -1
- package/dist/components/form/inputs/CodeEditor/CodeTypes.d.ts +4 -0
- package/dist/components/form/inputs/CodeEditor/CodeTypes.d.ts.map +1 -1
- package/dist/components/form/inputs/CodeEditor/Index.vue.d.ts +82 -5
- package/dist/components/form/inputs/CodeEditor/Index.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/CodeEditor/useHighlight.d.ts +4 -2
- package/dist/components/form/inputs/CodeEditor/useHighlight.d.ts.map +1 -1
- package/dist/composables/useSchemaField.d.ts.map +1 -1
- package/dist/index.cjs +4 -4
- package/dist/index.mjs +20 -20
- package/dist/style.css +1 -1
- package/dist/types/BagelForm.d.ts +2 -2
- package/dist/types/BagelForm.d.ts.map +1 -1
- package/dist/utils/BagelFormUtils.d.ts +1 -0
- package/dist/utils/BagelFormUtils.d.ts.map +1 -1
- package/dist/utils/elementUtils.d.ts +8 -8
- package/dist/utils/elementUtils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/Btn.vue +53 -0
- package/src/components/Card.vue +7 -1
- package/src/components/Dropdown.vue +9 -3
- package/src/components/dataTable/DataTable.vue +2 -9
- package/src/components/dataTable/useTableData.ts +1 -1
- package/src/components/dataTable/useTableVirtualization.ts +14 -3
- package/src/components/form/inputs/CodeEditor/CodeTypes.ts +260 -0
- package/src/components/form/inputs/CodeEditor/Index.vue +20 -30
- package/src/components/form/inputs/CodeEditor/useHighlight.ts +40 -3
- package/src/composables/useSchemaField.ts +45 -14
- package/src/styles/modal.css +81 -81
- package/src/types/BagelForm.ts +2 -2
- package/src/utils/BagelFormUtils.ts +1 -0
- package/src/utils/elementUtils.ts +51 -30
|
@@ -201,6 +201,263 @@ export const codeLanguages = {
|
|
|
201
201
|
|
|
202
202
|
export type Language = 'html' | 'css' | 'javascript' | 'typescript' | 'json' | 'markdown' | string
|
|
203
203
|
|
|
204
|
+
export type HighlightTheme = 'dark' | 'light'
|
|
205
|
+
| '1c-light'
|
|
206
|
+
| 'a11y-dark'
|
|
207
|
+
| 'a11y-light'
|
|
208
|
+
| 'agate'
|
|
209
|
+
| 'an-old-hope'
|
|
210
|
+
| 'androidstudio'
|
|
211
|
+
| 'arduino-light'
|
|
212
|
+
| 'arta'
|
|
213
|
+
| 'ascetic'
|
|
214
|
+
| 'atom-one-dark-reasonable'
|
|
215
|
+
| 'atom-one-dark'
|
|
216
|
+
| 'atom-one-light'
|
|
217
|
+
| 'base16-3024'
|
|
218
|
+
| 'base16-apathy'
|
|
219
|
+
| 'base16-apprentice'
|
|
220
|
+
| 'base16-ashes'
|
|
221
|
+
| 'base16-atelier-cave-light'
|
|
222
|
+
| 'base16-atelier-cave'
|
|
223
|
+
| 'base16-atelier-dune-light'
|
|
224
|
+
| 'base16-atelier-dune'
|
|
225
|
+
| 'base16-atelier-estuary-light'
|
|
226
|
+
| 'base16-atelier-estuary'
|
|
227
|
+
| 'base16-atelier-forest-light'
|
|
228
|
+
| 'base16-atelier-forest'
|
|
229
|
+
| 'base16-atelier-heath-light'
|
|
230
|
+
| 'base16-atelier-heath'
|
|
231
|
+
| 'base16-atelier-lakeside-light'
|
|
232
|
+
| 'base16-atelier-lakeside'
|
|
233
|
+
| 'base16-atelier-plateau-light'
|
|
234
|
+
| 'base16-atelier-plateau'
|
|
235
|
+
| 'base16-atelier-savanna-light'
|
|
236
|
+
| 'base16-atelier-savanna'
|
|
237
|
+
| 'base16-atelier-seaside-light'
|
|
238
|
+
| 'base16-atelier-seaside'
|
|
239
|
+
| 'base16-atelier-sulphurpool-light'
|
|
240
|
+
| 'base16-atelier-sulphurpool'
|
|
241
|
+
| 'base16-atlas'
|
|
242
|
+
| 'base16-bespin'
|
|
243
|
+
| 'base16-black-metal-bathory'
|
|
244
|
+
| 'base16-black-metal-burzum'
|
|
245
|
+
| 'base16-black-metal-dark-funeral'
|
|
246
|
+
| 'base16-black-metal-gorgoroth'
|
|
247
|
+
| 'base16-black-metal-immortal'
|
|
248
|
+
| 'base16-black-metal-khold'
|
|
249
|
+
| 'base16-black-metal-marduk'
|
|
250
|
+
| 'base16-black-metal-mayhem'
|
|
251
|
+
| 'base16-black-metal-nile'
|
|
252
|
+
| 'base16-black-metal-venom'
|
|
253
|
+
| 'base16-black-metal'
|
|
254
|
+
| 'base16-brewer'
|
|
255
|
+
| 'base16-bright'
|
|
256
|
+
| 'base16-brogrammer'
|
|
257
|
+
| 'base16-brush-trees-dark'
|
|
258
|
+
| 'base16-brush-trees'
|
|
259
|
+
| 'base16-chalk'
|
|
260
|
+
| 'base16-circus'
|
|
261
|
+
| 'base16-classic-dark'
|
|
262
|
+
| 'base16-classic-light'
|
|
263
|
+
| 'base16-codeschool'
|
|
264
|
+
| 'base16-colors'
|
|
265
|
+
| 'base16-cupcake'
|
|
266
|
+
| 'base16-cupertino'
|
|
267
|
+
| 'base16-danqing'
|
|
268
|
+
| 'base16-darcula'
|
|
269
|
+
| 'base16-dark-violet'
|
|
270
|
+
| 'base16-darkmoss'
|
|
271
|
+
| 'base16-darktooth'
|
|
272
|
+
| 'base16-decaf'
|
|
273
|
+
| 'base16-default-dark'
|
|
274
|
+
| 'base16-default-light'
|
|
275
|
+
| 'base16-dirtysea'
|
|
276
|
+
| 'base16-dracula'
|
|
277
|
+
| 'base16-edge-dark'
|
|
278
|
+
| 'base16-edge-light'
|
|
279
|
+
| 'base16-eighties'
|
|
280
|
+
| 'base16-embers'
|
|
281
|
+
| 'base16-equilibrium-dark'
|
|
282
|
+
| 'base16-equilibrium-gray-dark'
|
|
283
|
+
| 'base16-equilibrium-gray-light'
|
|
284
|
+
| 'base16-equilibrium-light'
|
|
285
|
+
| 'base16-espresso'
|
|
286
|
+
| 'base16-eva-dim'
|
|
287
|
+
| 'base16-eva'
|
|
288
|
+
| 'base16-flat'
|
|
289
|
+
| 'base16-framer'
|
|
290
|
+
| 'base16-fruit-soda'
|
|
291
|
+
| 'base16-gigavolt'
|
|
292
|
+
| 'base16-github'
|
|
293
|
+
| 'base16-google-dark'
|
|
294
|
+
| 'base16-google-light'
|
|
295
|
+
| 'base16-grayscale-dark'
|
|
296
|
+
| 'base16-grayscale-light'
|
|
297
|
+
| 'base16-green-screen'
|
|
298
|
+
| 'base16-gruvbox-dark-hard'
|
|
299
|
+
| 'base16-gruvbox-dark-medium'
|
|
300
|
+
| 'base16-gruvbox-dark-pale'
|
|
301
|
+
| 'base16-gruvbox-dark-soft'
|
|
302
|
+
| 'base16-gruvbox-light-hard'
|
|
303
|
+
| 'base16-gruvbox-light-medium'
|
|
304
|
+
| 'base16-gruvbox-light-soft'
|
|
305
|
+
| 'base16-hardcore'
|
|
306
|
+
| 'base16-harmonic16-dark'
|
|
307
|
+
| 'base16-harmonic16-light'
|
|
308
|
+
| 'base16-heetch-dark'
|
|
309
|
+
| 'base16-heetch-light'
|
|
310
|
+
| 'base16-helios'
|
|
311
|
+
| 'base16-hopscotch'
|
|
312
|
+
| 'base16-horizon-dark'
|
|
313
|
+
| 'base16-horizon-light'
|
|
314
|
+
| 'base16-humanoid-dark'
|
|
315
|
+
| 'base16-humanoid-light'
|
|
316
|
+
| 'base16-ia-dark'
|
|
317
|
+
| 'base16-ia-light'
|
|
318
|
+
| 'base16-icy-dark'
|
|
319
|
+
| 'base16-ir-black'
|
|
320
|
+
| 'base16-isotope'
|
|
321
|
+
| 'base16-kimber'
|
|
322
|
+
| 'base16-london-tube'
|
|
323
|
+
| 'base16-macintosh'
|
|
324
|
+
| 'base16-marrakesh'
|
|
325
|
+
| 'base16-materia'
|
|
326
|
+
| 'base16-material-darker'
|
|
327
|
+
| 'base16-material-lighter'
|
|
328
|
+
| 'base16-material-palenight'
|
|
329
|
+
| 'base16-material-vivid'
|
|
330
|
+
| 'base16-material'
|
|
331
|
+
| 'base16-mellow-purple'
|
|
332
|
+
| 'base16-mexico-light'
|
|
333
|
+
| 'base16-mocha'
|
|
334
|
+
| 'base16-monokai'
|
|
335
|
+
| 'base16-nebula'
|
|
336
|
+
| 'base16-nord'
|
|
337
|
+
| 'base16-nova'
|
|
338
|
+
| 'base16-ocean'
|
|
339
|
+
| 'base16-oceanicnext'
|
|
340
|
+
| 'base16-one-light'
|
|
341
|
+
| 'base16-onedark'
|
|
342
|
+
| 'base16-outrun-dark'
|
|
343
|
+
| 'base16-papercolor-dark'
|
|
344
|
+
| 'base16-papercolor-light'
|
|
345
|
+
| 'base16-paraiso'
|
|
346
|
+
| 'base16-pasque'
|
|
347
|
+
| 'base16-phd'
|
|
348
|
+
| 'base16-pico'
|
|
349
|
+
| 'base16-pop'
|
|
350
|
+
| 'base16-porple'
|
|
351
|
+
| 'base16-qualia'
|
|
352
|
+
| 'base16-railscasts'
|
|
353
|
+
| 'base16-rebecca'
|
|
354
|
+
| 'base16-ros-pine-dawn'
|
|
355
|
+
| 'base16-ros-pine-moon'
|
|
356
|
+
| 'base16-ros-pine'
|
|
357
|
+
| 'base16-sagelight'
|
|
358
|
+
| 'base16-sandcastle'
|
|
359
|
+
| 'base16-seti-ui'
|
|
360
|
+
| 'base16-shapeshifter'
|
|
361
|
+
| 'base16-silk-dark'
|
|
362
|
+
| 'base16-silk-light'
|
|
363
|
+
| 'base16-snazzy'
|
|
364
|
+
| 'base16-solar-flare-light'
|
|
365
|
+
| 'base16-solar-flare'
|
|
366
|
+
| 'base16-solarized-dark'
|
|
367
|
+
| 'base16-solarized-light'
|
|
368
|
+
| 'base16-spacemacs'
|
|
369
|
+
| 'base16-summercamp'
|
|
370
|
+
| 'base16-summerfruit-dark'
|
|
371
|
+
| 'base16-summerfruit-light'
|
|
372
|
+
| 'base16-synth-midnight-terminal-dark'
|
|
373
|
+
| 'base16-synth-midnight-terminal-light'
|
|
374
|
+
| 'base16-tango'
|
|
375
|
+
| 'base16-tender'
|
|
376
|
+
| 'base16-tomorrow-night'
|
|
377
|
+
| 'base16-tomorrow'
|
|
378
|
+
| 'base16-twilight'
|
|
379
|
+
| 'base16-unikitty-dark'
|
|
380
|
+
| 'base16-unikitty-light'
|
|
381
|
+
| 'base16-vulcan'
|
|
382
|
+
| 'base16-windows-10-light'
|
|
383
|
+
| 'base16-windows-10'
|
|
384
|
+
| 'base16-windows-95-light'
|
|
385
|
+
| 'base16-windows-95'
|
|
386
|
+
| 'base16-windows-high-contrast-light'
|
|
387
|
+
| 'base16-windows-high-contrast'
|
|
388
|
+
| 'base16-windows-nt-light'
|
|
389
|
+
| 'base16-windows-nt'
|
|
390
|
+
| 'base16-woodland'
|
|
391
|
+
| 'base16-xcode-dusk'
|
|
392
|
+
| 'base16-zenburn'
|
|
393
|
+
| 'brown-paper'
|
|
394
|
+
| 'codepen-embed'
|
|
395
|
+
| 'color-brewer'
|
|
396
|
+
| 'cybertopia-cherry'
|
|
397
|
+
| 'cybertopia-dimmer'
|
|
398
|
+
| 'cybertopia-icecap'
|
|
399
|
+
| 'cybertopia-saturated'
|
|
400
|
+
| 'default'
|
|
401
|
+
| 'devibeans'
|
|
402
|
+
| 'docco'
|
|
403
|
+
| 'far'
|
|
404
|
+
| 'felipec'
|
|
405
|
+
| 'foundation'
|
|
406
|
+
| 'github-dark-dimmed'
|
|
407
|
+
| 'github-dark'
|
|
408
|
+
| 'github'
|
|
409
|
+
| 'gml'
|
|
410
|
+
| 'googlecode'
|
|
411
|
+
| 'gradient-dark'
|
|
412
|
+
| 'gradient-light'
|
|
413
|
+
| 'grayscale'
|
|
414
|
+
| 'hybrid'
|
|
415
|
+
| 'idea'
|
|
416
|
+
| 'intellij-light'
|
|
417
|
+
| 'ir-black'
|
|
418
|
+
| 'isbl-editor-dark'
|
|
419
|
+
| 'isbl-editor-light'
|
|
420
|
+
| 'kimbie-dark'
|
|
421
|
+
| 'kimbie-light'
|
|
422
|
+
| 'lightfair'
|
|
423
|
+
| 'lioshi'
|
|
424
|
+
| 'magula'
|
|
425
|
+
| 'mono-blue'
|
|
426
|
+
| 'monokai-sublime'
|
|
427
|
+
| 'monokai'
|
|
428
|
+
| 'night-owl'
|
|
429
|
+
| 'nnfx-dark'
|
|
430
|
+
| 'nnfx-light'
|
|
431
|
+
| 'nord'
|
|
432
|
+
| 'obsidian'
|
|
433
|
+
| 'panda-syntax-dark'
|
|
434
|
+
| 'panda-syntax-light'
|
|
435
|
+
| 'paraiso-dark'
|
|
436
|
+
| 'paraiso-light'
|
|
437
|
+
| 'pojoaque'
|
|
438
|
+
| 'purebasic'
|
|
439
|
+
| 'qtcreator-dark'
|
|
440
|
+
| 'qtcreator-light'
|
|
441
|
+
| 'rainbow'
|
|
442
|
+
| 'rose-pine-dawn'
|
|
443
|
+
| 'rose-pine-moon'
|
|
444
|
+
| 'rose-pine'
|
|
445
|
+
| 'routeros'
|
|
446
|
+
| 'school-book'
|
|
447
|
+
| 'shades-of-purple'
|
|
448
|
+
| 'srcery'
|
|
449
|
+
| 'stackoverflow-dark'
|
|
450
|
+
| 'stackoverflow-light'
|
|
451
|
+
| 'sunburst'
|
|
452
|
+
| 'tokyo-night-dark'
|
|
453
|
+
| 'tokyo-night-light'
|
|
454
|
+
| 'tomorrow-night-blue'
|
|
455
|
+
| 'tomorrow-night-bright'
|
|
456
|
+
| 'vs'
|
|
457
|
+
| 'vs2015'
|
|
458
|
+
| 'xcode'
|
|
459
|
+
| 'xt256'
|
|
460
|
+
|
|
204
461
|
export interface CodeEditorProps {
|
|
205
462
|
language?: Language
|
|
206
463
|
readonly?: boolean
|
|
@@ -209,4 +466,7 @@ export interface CodeEditorProps {
|
|
|
209
466
|
ignoreIllegals?: boolean
|
|
210
467
|
label?: string
|
|
211
468
|
height?: string
|
|
469
|
+
disabled?: boolean
|
|
470
|
+
/** highlight.js theme selection */
|
|
471
|
+
theme?: HighlightTheme
|
|
212
472
|
}
|
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import type {
|
|
3
|
-
import { onMounted, ref, computed, watch } from 'vue'
|
|
2
|
+
import type { Language, HighlightTheme } from './CodeTypes'
|
|
3
|
+
import { onMounted, ref, computed, watch, type PropType } from 'vue'
|
|
4
4
|
import { useHighlight } from './useHighlight'
|
|
5
5
|
|
|
6
|
-
// Props with
|
|
7
|
-
const props =
|
|
8
|
-
language: 'html',
|
|
9
|
-
readonly: false,
|
|
10
|
-
modelValue: '',
|
|
11
|
-
autodetect: true,
|
|
12
|
-
ignoreIllegals: true,
|
|
13
|
-
label: '',
|
|
14
|
-
height: '240px'
|
|
6
|
+
// Props with runtime defaults to avoid undefined at runtime
|
|
7
|
+
const props = defineProps({
|
|
8
|
+
language: { type: String as PropType<Language>, default: 'html' },
|
|
9
|
+
readonly: { type: Boolean, default: false },
|
|
10
|
+
modelValue: { type: String, default: '' },
|
|
11
|
+
autodetect: { type: Boolean, default: true },
|
|
12
|
+
ignoreIllegals: { type: Boolean, default: true },
|
|
13
|
+
label: { type: String, default: '' },
|
|
14
|
+
height: { type: String, default: '240px' },
|
|
15
|
+
disabled: { type: Boolean, default: false },
|
|
16
|
+
theme: { type: String as PropType<HighlightTheme>, default: 'dark' }
|
|
15
17
|
})
|
|
16
18
|
|
|
17
19
|
const emit = defineEmits(['update:modelValue'])
|
|
18
20
|
// State
|
|
19
21
|
const code = ref(props.modelValue || '')
|
|
20
22
|
const editorRef = ref<HTMLDivElement>()
|
|
21
|
-
const { loaded, loadHighlight, highlightCode } = useHighlight()
|
|
23
|
+
const { loaded, loadHighlight, highlightCode, setTheme } = useHighlight(props.theme)
|
|
22
24
|
|
|
23
|
-
// Computed
|
|
24
25
|
const maxHeight = computed(() => {
|
|
25
26
|
const h = props.height ?? '240px'
|
|
26
27
|
return h.match(/^\d+$/) ? `${h}px` : h
|
|
@@ -65,7 +66,7 @@ onMounted(async () => {
|
|
|
65
66
|
await loadHighlight()
|
|
66
67
|
})
|
|
67
68
|
|
|
68
|
-
|
|
69
|
+
watch(() => props.theme, (t) => { setTheme(t) })
|
|
69
70
|
watch(() => props.modelValue, (newVal) => {
|
|
70
71
|
if (newVal !== undefined && newVal !== code.value) {
|
|
71
72
|
code.value = newVal
|
|
@@ -76,22 +77,12 @@ watch(() => props.modelValue, (newVal) => {
|
|
|
76
77
|
<template>
|
|
77
78
|
<div class="code-editor-container ltr" :style="{ maxHeight }">
|
|
78
79
|
<label v-if="label" class="label">{{ label }}</label>
|
|
79
|
-
<div
|
|
80
|
-
v-if="loaded"
|
|
81
|
-
ref="editorRef"
|
|
82
|
-
class="code-editor-grandpa"
|
|
83
|
-
>
|
|
80
|
+
<div v-if="loaded" ref="editorRef" class="code-editor-grandpa hljs">
|
|
84
81
|
<div class="editor-content-papa relative">
|
|
85
82
|
<pre class="code-display" wrap><code v-html="formattedCode" /></pre>
|
|
86
83
|
<textarea
|
|
87
|
-
v-if="!readonly"
|
|
88
|
-
|
|
89
|
-
class="code-input"
|
|
90
|
-
spellcheck="false"
|
|
91
|
-
autocomplete="off"
|
|
92
|
-
autocorrect="off"
|
|
93
|
-
autocapitalize="off"
|
|
94
|
-
@input="handleInput"
|
|
84
|
+
v-if="!readonly && !disabled" :value="code" class="code-input" spellcheck="false"
|
|
85
|
+
autocomplete="off" autocorrect="off" autocapitalize="off" @input="handleInput"
|
|
95
86
|
@keydown="handleTab"
|
|
96
87
|
/>
|
|
97
88
|
</div>
|
|
@@ -112,7 +103,6 @@ watch(() => props.modelValue, (newVal) => {
|
|
|
112
103
|
}
|
|
113
104
|
|
|
114
105
|
.code-editor-grandpa {
|
|
115
|
-
background: #22252A;
|
|
116
106
|
border-radius: 0.25rem;
|
|
117
107
|
width: 100%;
|
|
118
108
|
height: 100%;
|
|
@@ -131,6 +121,7 @@ watch(() => props.modelValue, (newVal) => {
|
|
|
131
121
|
width: 100%;
|
|
132
122
|
padding-bottom: calc(100% - 5lh);
|
|
133
123
|
}
|
|
124
|
+
|
|
134
125
|
.code-display,
|
|
135
126
|
.code-input {
|
|
136
127
|
inset: 0;
|
|
@@ -149,7 +140,6 @@ watch(() => props.modelValue, (newVal) => {
|
|
|
149
140
|
|
|
150
141
|
.code-display {
|
|
151
142
|
position: relative;
|
|
152
|
-
color: #fff;
|
|
153
143
|
pointer-events: none;
|
|
154
144
|
z-index: 1;
|
|
155
145
|
}
|
|
@@ -164,7 +154,7 @@ watch(() => props.modelValue, (newVal) => {
|
|
|
164
154
|
position: absolute;
|
|
165
155
|
background: transparent;
|
|
166
156
|
color: transparent;
|
|
167
|
-
caret-color:
|
|
157
|
+
caret-color: #fff;
|
|
168
158
|
border: none;
|
|
169
159
|
resize: none;
|
|
170
160
|
outline: none;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { HighlightJS } from './CodeTypes'
|
|
1
|
+
import type { HighlightJS, HighlightTheme } from './CodeTypes'
|
|
2
2
|
import { appendStyle, appendScript } from '@bagelink/vue'
|
|
3
3
|
import { ref } from 'vue'
|
|
4
4
|
|
|
@@ -8,9 +8,44 @@ interface CustomWindow extends Window {
|
|
|
8
8
|
}
|
|
9
9
|
declare const window: CustomWindow
|
|
10
10
|
|
|
11
|
-
export function useHighlight() {
|
|
11
|
+
export function useHighlight(theme: HighlightTheme = 'dark') {
|
|
12
12
|
const hljs = ref<HighlightJS | null>(null)
|
|
13
13
|
const loaded = ref(false)
|
|
14
|
+
const currentTheme = ref<HighlightTheme>(theme)
|
|
15
|
+
|
|
16
|
+
const normalizeTheme = (t: HighlightTheme): HighlightTheme => {
|
|
17
|
+
if (t === 'dark') return 'atom-one-dark'
|
|
18
|
+
if (t === 'light') return 'atom-one-light'
|
|
19
|
+
return t
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const getThemeCssUrl = (t: HighlightTheme) => `https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/styles/${t}.min.css`
|
|
23
|
+
|
|
24
|
+
const removeExistingThemeLinks = () => {
|
|
25
|
+
document.querySelectorAll('link[rel="stylesheet"]').forEach((link) => {
|
|
26
|
+
if (link instanceof HTMLLinkElement && link.href.includes('/styles/')) {
|
|
27
|
+
if (link.href.includes('highlight.js')) link.parentElement?.removeChild(link)
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const setTheme = async (theme: HighlightTheme) => {
|
|
33
|
+
const next = normalizeTheme(theme)
|
|
34
|
+
if (next === currentTheme.value) return
|
|
35
|
+
try {
|
|
36
|
+
removeExistingThemeLinks()
|
|
37
|
+
const url = getThemeCssUrl(next)
|
|
38
|
+
console.log('setTheme', url)
|
|
39
|
+
await appendStyle(url)
|
|
40
|
+
currentTheme.value = next
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error('Failed to apply theme. Falling back to atom-one-dark:', error)
|
|
43
|
+
removeExistingThemeLinks()
|
|
44
|
+
currentTheme.value = 'atom-one-dark'
|
|
45
|
+
const url = getThemeCssUrl(currentTheme.value)
|
|
46
|
+
await appendStyle(url)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
14
49
|
|
|
15
50
|
const loadHighlight = async () => {
|
|
16
51
|
if (loaded.value) return
|
|
@@ -18,7 +53,7 @@ export function useHighlight() {
|
|
|
18
53
|
try {
|
|
19
54
|
// Load highlight.js
|
|
20
55
|
await appendScript('https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/highlight.min.js', { id: 'hljs-cdn' })
|
|
21
|
-
await
|
|
56
|
+
await setTheme(currentTheme.value)
|
|
22
57
|
|
|
23
58
|
if (window.hljs) {
|
|
24
59
|
hljs.value = window.hljs
|
|
@@ -70,6 +105,8 @@ export function useHighlight() {
|
|
|
70
105
|
hljs,
|
|
71
106
|
loaded,
|
|
72
107
|
loadHighlight,
|
|
108
|
+
setTheme,
|
|
109
|
+
currentTheme,
|
|
73
110
|
escapeHtml,
|
|
74
111
|
highlightCode
|
|
75
112
|
}
|
|
@@ -118,16 +118,21 @@ export function useSchemaField<T extends { [key: string]: any }, SP extends Path
|
|
|
118
118
|
const condition = field.vIf ?? field['v-if']
|
|
119
119
|
if (condition !== undefined) {
|
|
120
120
|
if (typeof condition === 'function') {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
rowData
|
|
125
|
-
|
|
126
|
-
|
|
121
|
+
// Compute currentValue for the vIf check
|
|
122
|
+
const vIfCurrentValue = field.id
|
|
123
|
+
? ('get' in (rowData || {})
|
|
124
|
+
? (rowData as any)?.get(field.id)
|
|
125
|
+
: (rowData as any)?.[field.id as keyof T])
|
|
126
|
+
: undefined
|
|
127
|
+
|
|
128
|
+
const vIfResult = field.id
|
|
129
|
+
? condition(vIfCurrentValue, rowData)
|
|
130
|
+
: (condition as any)(rowData)
|
|
131
|
+
if (!vIfResult) {
|
|
127
132
|
return
|
|
128
133
|
}
|
|
129
134
|
} else if (typeof condition === 'string') {
|
|
130
|
-
if (!rowData?.[condition]) {
|
|
135
|
+
if (!(rowData as any)?.[condition]) {
|
|
131
136
|
return
|
|
132
137
|
}
|
|
133
138
|
} else if (!condition) {
|
|
@@ -136,10 +141,10 @@ export function useSchemaField<T extends { [key: string]: any }, SP extends Path
|
|
|
136
141
|
}
|
|
137
142
|
|
|
138
143
|
const {
|
|
139
|
-
$el,
|
|
144
|
+
$el: _$el,
|
|
140
145
|
children,
|
|
141
|
-
options,
|
|
142
|
-
attrs,
|
|
146
|
+
options: _options,
|
|
147
|
+
attrs: _attrs,
|
|
143
148
|
class: fieldClass,
|
|
144
149
|
id,
|
|
145
150
|
transform,
|
|
@@ -156,11 +161,16 @@ export function useSchemaField<T extends { [key: string]: any }, SP extends Path
|
|
|
156
161
|
// Use the get method if available, otherwise fall back to direct access
|
|
157
162
|
const currentValue = field.id
|
|
158
163
|
? ('get' in (rowData || {})
|
|
159
|
-
? rowData?.get(field.id)
|
|
160
|
-
: rowData?.[field.id])
|
|
164
|
+
? (rowData as any)?.get(field.id)
|
|
165
|
+
: (rowData as any)?.[field.id as keyof T])
|
|
161
166
|
: undefined
|
|
162
167
|
|
|
163
|
-
|
|
168
|
+
// Apply transform with conditional args: provide (val,row) only when id exists; otherwise provide only (row)
|
|
169
|
+
const transformedValue = transform
|
|
170
|
+
? (id
|
|
171
|
+
? transform(currentValue, rowData)
|
|
172
|
+
: (transform as any)(rowData))
|
|
173
|
+
: currentValue
|
|
164
174
|
|
|
165
175
|
// First bind any function attributes with the current value and row data
|
|
166
176
|
const boundFieldProps = bindAttrs(fieldProps as Attributes<T, Path<T>> | undefined, currentValue, rowData)
|
|
@@ -182,6 +192,18 @@ export function useSchemaField<T extends { [key: string]: any }, SP extends Path
|
|
|
182
192
|
onUpdate,
|
|
183
193
|
}
|
|
184
194
|
|
|
195
|
+
// Wire top-level onClick with conditional args
|
|
196
|
+
if (typeof (field as any).onClick === 'function') {
|
|
197
|
+
const original = (field as any).onClick as (val?: any, row?: T) => void
|
|
198
|
+
props.onClick = (..._args: any[]) => {
|
|
199
|
+
if (id) {
|
|
200
|
+
original(currentValue, rowData)
|
|
201
|
+
} else {
|
|
202
|
+
;(original as any)(rowData)
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
185
207
|
// For form mode, always use the original value for modelValue
|
|
186
208
|
if (mode === 'form') {
|
|
187
209
|
props.modelValue = currentValue
|
|
@@ -214,7 +236,16 @@ export function useSchemaField<T extends { [key: string]: any }, SP extends Path
|
|
|
214
236
|
const boundAttrs = bindAttrs(field.attrs, currentValue, rowData)
|
|
215
237
|
Object.entries(boundAttrs).forEach(([key, value]) => {
|
|
216
238
|
if (typeof value === 'function') {
|
|
217
|
-
if (key
|
|
239
|
+
if (key === 'onClick') {
|
|
240
|
+
const original = value as (val?: any, row?: T) => void
|
|
241
|
+
props.onClick = (..._args: any[]) => {
|
|
242
|
+
if (id) {
|
|
243
|
+
original(currentValue, rowData)
|
|
244
|
+
} else {
|
|
245
|
+
;(original as any)(rowData)
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
} else if (key.startsWith('on')) {
|
|
218
249
|
props[key] = value
|
|
219
250
|
} else {
|
|
220
251
|
props[key] = value(currentValue, rowData)
|