@mixd-id/web-scaffold 0.2.250801014 → 0.2.260801002

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.
Files changed (113) hide show
  1. package/README.md +25 -1
  2. package/docs/components/AIDashboard.md +117 -32
  3. package/docs/components/Alert.md +3 -1
  4. package/docs/components/Card.md +5 -0
  5. package/docs/components/PivotList.md +207 -0
  6. package/docs/components/Textbox.md +20 -1
  7. package/docs/components/Tooltip.md +148 -0
  8. package/package.json +17 -61
  9. package/src/components/AIChat.vue +14 -5
  10. package/src/components/AIChatItem.vue +34 -3
  11. package/src/components/AIDashboard.vue +144 -98
  12. package/src/components/Alert.vue +58 -35
  13. package/src/components/Card.vue +55 -6
  14. package/src/components/Carousel.vue +1 -1
  15. package/src/{widgets → components}/CartSetting.vue +1 -0
  16. package/src/components/Chart.vue +2 -2
  17. package/src/components/Checkbox.vue +22 -24
  18. package/src/components/CodeEditor.vue +2 -0
  19. package/src/{widgets → components}/CollapsiblePanelSetting.vue +1 -0
  20. package/src/components/ColorPicker.vue +2 -2
  21. package/src/{widgets → components}/ComponentSetting2.vue +1 -1
  22. package/src/components/Confirm.vue +2 -0
  23. package/src/{widgets → components}/ContactForm.vue +1 -1
  24. package/src/components/CopyToClipboard.vue +0 -1
  25. package/src/components/Datepicker.vue +2 -0
  26. package/src/components/Datetimepicker.vue +1 -1
  27. package/src/components/Dropdown.vue +1 -1
  28. package/src/{widgets → components}/FeatureList.vue +1 -1
  29. package/src/components/Gmaps.vue +1 -1
  30. package/src/{widgets → components}/IconList.vue +1 -1
  31. package/src/components/Image.vue +1 -1
  32. package/src/components/ImagePreview.vue +32 -51
  33. package/src/components/List.vue +45 -8
  34. package/src/components/MarkdownEdit.vue +1 -1
  35. package/src/components/MarkdownPreview.vue +4 -1
  36. package/src/{widgets → components}/MenuItem1Setting.vue +1 -0
  37. package/src/components/Metric.vue +30 -7
  38. package/src/components/MultiDropdown.vue +3 -1
  39. package/src/{widgets → components}/MultiValueSetting.vue +2 -2
  40. package/src/{widgets → components}/MultiValueSetting2.vue +2 -2
  41. package/src/components/OTPField.vue +3 -1
  42. package/src/components/PivotList.vue +1239 -0
  43. package/src/{widgets → components}/PresetBar.vue +1 -1
  44. package/src/components/PresetSelectorFilterItem.vue +1 -1
  45. package/src/components/Radio.vue +1 -1
  46. package/src/{widgets → components}/Share.vue +1 -1
  47. package/src/components/SvgEditor.vue +1 -1
  48. package/src/components/Switch.vue +1 -1
  49. package/src/components/TextWithTag.vue +2 -2
  50. package/src/components/Textbox.vue +63 -5
  51. package/src/components/Toast.vue +2 -1
  52. package/src/components/Tooltip.vue +626 -0
  53. package/src/components/VirtualGrid.vue +2 -2
  54. package/src/components/VirtualTable.vue +4 -3
  55. package/src/{widgets → components}/WebDatasourceSelector.vue +2 -0
  56. package/src/{widgets → components}/WebLayoutSelector.vue +1 -1
  57. package/src/directives/tooltip.js +131 -0
  58. package/src/index.js +11 -235
  59. package/src/themes/default/index.js +16 -0
  60. package/src/utils/ai-dashboard.js +163 -38
  61. package/src/utils/helpers.mjs +52 -5
  62. package/src/utils/list.mjs +4 -1
  63. package/src/utils/pivot-formula.mjs +358 -0
  64. package/src/utils/pivot-list.mjs +557 -0
  65. package/src/utils/tooltip.mjs +243 -0
  66. package/src/utils/wss.js +26 -6
  67. package/src/utils/wss.mjs +29 -2
  68. /package/src/{widgets → components}/AhrefSetting.vue +0 -0
  69. /package/src/{widgets → components}/ArticleSetting.vue +0 -0
  70. /package/src/{widgets → components}/BackgroundColorSetting.vue +0 -0
  71. /package/src/{widgets → components}/BlockSetting.vue +0 -0
  72. /package/src/{widgets → components}/BorderColorSetting.vue +0 -0
  73. /package/src/{widgets → components}/ButtonSetting.vue +0 -0
  74. /package/src/{widgets → components}/CarouselSetting.vue +0 -0
  75. /package/src/{widgets → components}/ColumnSelector.vue +0 -0
  76. /package/src/{widgets → components}/ComponentSetting.vue +0 -0
  77. /package/src/{widgets → components}/ContactFormSetting.vue +0 -0
  78. /package/src/{widgets → components}/CountdownSetting.vue +0 -0
  79. /package/src/{widgets → components}/DataListSetting.vue +0 -0
  80. /package/src/{widgets → components}/EmbeddedVideo.vue +0 -0
  81. /package/src/{widgets → components}/EmbeddedVideoSetting.vue +0 -0
  82. /package/src/{widgets → components}/FAQ.vue +0 -0
  83. /package/src/{widgets → components}/FAQSetting.vue +0 -0
  84. /package/src/{widgets → components}/FeatureListSetting.vue +0 -0
  85. /package/src/{widgets → components}/FlexSetting.vue +0 -0
  86. /package/src/{widgets → components}/GridSetting.vue +0 -0
  87. /package/src/{widgets → components}/Header2.vue +0 -0
  88. /package/src/{widgets → components}/Header2Setting.vue +0 -0
  89. /package/src/{widgets → components}/IconListSetting.vue +0 -0
  90. /package/src/{widgets → components}/ImageSetting.vue +0 -0
  91. /package/src/{widgets → components}/LLMChat.vue +0 -0
  92. /package/src/{widgets → components}/LinkSetting.vue +0 -0
  93. /package/src/{widgets → components}/LinkSettingModal.vue +0 -0
  94. /package/src/{widgets → components}/ModalSetting.vue +0 -0
  95. /package/src/{widgets → components}/OGSettingModal.vue +0 -0
  96. /package/src/{widgets → components}/ParagraphSetting.vue +0 -0
  97. /package/src/{widgets → components}/PositionSetting.vue +0 -0
  98. /package/src/{widgets → components}/PresetBarPivot.vue +0 -0
  99. /package/src/{widgets → components}/PresetBarPivotColumnEdit.vue +0 -0
  100. /package/src/{widgets → components}/PresetBarPivotValueEdit.vue +0 -0
  101. /package/src/{widgets → components}/PresetSelector.vue +0 -0
  102. /package/src/{widgets → components}/Review.vue +0 -0
  103. /package/src/{widgets → components}/ReviewSetting.vue +0 -0
  104. /package/src/{widgets → components}/SearchModalSetting.vue +0 -0
  105. /package/src/{widgets → components}/ShareSetting.vue +0 -0
  106. /package/src/{widgets → components}/SvgSetting.vue +0 -0
  107. /package/src/{widgets → components}/TableSetting.vue +0 -0
  108. /package/src/{widgets → components}/TestimonialSetting.vue +0 -0
  109. /package/src/{widgets → components}/TextBlockSetting.vue +0 -0
  110. /package/src/{widgets → components}/ThumbnailSetting.vue +0 -0
  111. /package/src/{widgets → components}/WebComponentSelector.vue +0 -0
  112. /package/src/{widgets → components}/WebPageBuilder.vue +0 -0
  113. /package/src/{widgets → components}/YoutubeVideoSetting.vue +0 -0
@@ -0,0 +1,131 @@
1
+ // directives/tooltip.js
2
+ //
3
+ // `v-tooltip` — thin trigger layer on top of the shared tooltip controller.
4
+ // All rendering lives in components/Tooltip.vue.
5
+ //
6
+ // v-tooltip="'Save changes'"
7
+ // v-tooltip:bottom="'Save changes'"
8
+ // v-tooltip.bottom.light="'Save changes'"
9
+ // v-tooltip="{ title: 'Save', text: 'Writes to the server', shortcut: '⌘S' }"
10
+
11
+ import {
12
+ TOOLTIP_PLACEMENTS, TOOLTIP_TOUCH_DELAY, TOOLTIP_TOUCH_TIMEOUT, TOOLTIP_VARIANTS,
13
+ hideTooltip, hideTooltipNow, isKeyboardFocus, mountTooltipLayer, normalizeTooltipOptions,
14
+ registerDisabledTarget, showTooltip, unregisterDisabledTarget
15
+ } from '../utils/tooltip.mjs'
16
+
17
+ const resolveOptions = (binding) => {
18
+
19
+ const defaults = {}
20
+
21
+ const placement = TOOLTIP_PLACEMENTS.find(_ => binding.modifiers[_]) ||
22
+ (TOOLTIP_PLACEMENTS.includes(binding.arg) ? binding.arg : null)
23
+ if(placement) defaults.placement = placement
24
+
25
+ const variant = TOOLTIP_VARIANTS.find(_ => binding.modifiers[_])
26
+ if(variant) defaults.variant = variant
27
+
28
+ if(binding.modifiers.now) defaults.delay = 0
29
+
30
+ return normalizeTooltipOptions(binding.value, defaults)
31
+ }
32
+
33
+ const isDisabled = (el) => el.disabled === true || el.getAttribute('aria-disabled') === 'true'
34
+
35
+ export default {
36
+
37
+ mounted(el, binding){
38
+
39
+ if(typeof document === 'undefined') return
40
+
41
+ mountTooltipLayer()
42
+
43
+ const ctx = {
44
+ options: resolveOptions(binding),
45
+ touchTimer: null,
46
+ touchTimeout: null
47
+ }
48
+
49
+ ctx.show = () => {
50
+ if(!ctx.options.text && !ctx.options.title) return
51
+ showTooltip(el, ctx.options)
52
+ }
53
+
54
+ ctx.hide = () => hideTooltip(el)
55
+
56
+ const hideNow = () => {
57
+ clearTimeout(ctx.touchTimer)
58
+ clearTimeout(ctx.touchTimeout)
59
+ hideTooltipNow(el)
60
+ }
61
+
62
+ const onFocus = () => {
63
+ // Keyboard focus only — pointer users already get it on hover.
64
+ if(!isKeyboardFocus(el)) return
65
+ ctx.show()
66
+ }
67
+
68
+ const onTouchStart = () => {
69
+ clearTimeout(ctx.touchTimer)
70
+ ctx.touchTimer = setTimeout(() => {
71
+ ctx.show()
72
+ ctx.touchTimeout = setTimeout(hideNow, TOOLTIP_TOUCH_TIMEOUT)
73
+ }, TOOLTIP_TOUCH_DELAY)
74
+ }
75
+
76
+ ctx.sync = () => {
77
+ // Disabled controls swallow mouse events; the controller hit-tests those.
78
+ if(isDisabled(el) && (ctx.options.text || ctx.options.title)){
79
+ registerDisabledTarget(el, { show: ctx.show, hide: ctx.hide })
80
+ }
81
+ else{
82
+ unregisterDisabledTarget(el)
83
+ }
84
+ }
85
+
86
+ el.addEventListener('mouseenter', ctx.show)
87
+ el.addEventListener('mouseleave', ctx.hide)
88
+ el.addEventListener('click', hideNow)
89
+ el.addEventListener('focus', onFocus, true)
90
+ el.addEventListener('blur', hideNow, true)
91
+ el.addEventListener('touchstart', onTouchStart, { passive: true })
92
+ el.addEventListener('touchend', hideNow, { passive: true })
93
+ el.addEventListener('touchcancel', hideNow, { passive: true })
94
+
95
+ ctx.destroy = () => {
96
+ clearTimeout(ctx.touchTimer)
97
+ clearTimeout(ctx.touchTimeout)
98
+ unregisterDisabledTarget(el)
99
+ hideTooltipNow(el)
100
+ el.removeEventListener('mouseenter', ctx.show)
101
+ el.removeEventListener('mouseleave', ctx.hide)
102
+ el.removeEventListener('click', hideNow)
103
+ el.removeEventListener('focus', onFocus, true)
104
+ el.removeEventListener('blur', hideNow, true)
105
+ el.removeEventListener('touchstart', onTouchStart)
106
+ el.removeEventListener('touchend', hideNow)
107
+ el.removeEventListener('touchcancel', hideNow)
108
+ }
109
+
110
+ el._tooltip = ctx
111
+ ctx.sync()
112
+ },
113
+
114
+ updated(el, binding){
115
+
116
+ const ctx = el._tooltip
117
+ if(!ctx) return
118
+
119
+ ctx.options = resolveOptions(binding)
120
+ ctx.sync()
121
+
122
+ // Text removed while it was on screen.
123
+ if(!ctx.options.text && !ctx.options.title) hideTooltipNow(el)
124
+ },
125
+
126
+ unmounted(el){
127
+ el._tooltip?.destroy()
128
+ delete el._tooltip
129
+ }
130
+
131
+ }
package/src/index.js CHANGED
@@ -3,6 +3,7 @@ import {arrayPush, arrayRemove, arrayUnshift, downloadUrl, invokeAfterIdle, obse
3
3
  import dayjs from "dayjs";
4
4
  import {useDevice} from './hooks/device.js'
5
5
  import IntersectDirective from './directives/intersect';
6
+ import TooltipDirective from './directives/tooltip';
6
7
 
7
8
 
8
9
  let _UNIQID = 0
@@ -253,105 +254,6 @@ export default{
253
254
 
254
255
  install: (app, options) => {
255
256
 
256
- // Inject tooltip CSS once — independent of whether Tooltip.vue is ever mounted
257
- if(typeof document !== 'undefined' && !document.getElementById('vt-styles')){
258
- const s = document.createElement('style')
259
- s.id = 'vt-styles'
260
- s.textContent = `
261
- .vt-tip{position:fixed;z-index:9999;font-size:.75rem;line-height:1rem;padding:3px 8px;
262
- border-radius:6px;pointer-events:none;max-width:240px;word-break:break-word;
263
- background:rgba(30,30,30,.92);color:#fff;box-shadow:0 2px 8px rgba(0,0,0,.18);
264
- opacity:0;transition:opacity .12s ease;}
265
- .vt-tip.vt-tip--on{opacity:1;}
266
- `
267
- document.head.appendChild(s)
268
- }
269
-
270
- const VT_OFFSET = 8
271
-
272
- function vtPosition(tip, rect, placement){
273
- const tw = tip.offsetWidth
274
- const th = tip.offsetHeight
275
- let top, left
276
-
277
- switch(placement){
278
- case 'bottom':
279
- top = rect.bottom + VT_OFFSET
280
- left = rect.left + rect.width / 2 - tw / 2
281
- break
282
- case 'left':
283
- top = rect.top + rect.height / 2 - th / 2
284
- left = rect.left - tw - VT_OFFSET
285
- break
286
- case 'right':
287
- top = rect.top + rect.height / 2 - th / 2
288
- left = rect.right + VT_OFFSET
289
- break
290
- default: // top
291
- top = rect.top - th - VT_OFFSET
292
- left = rect.left + rect.width / 2 - tw / 2
293
- }
294
-
295
- // Clamp to viewport
296
- tip.style.top = Math.max(8, Math.min(window.innerHeight - th - 8, top)) + 'px'
297
- tip.style.left = Math.max(8, Math.min(window.innerWidth - tw - 8, left)) + 'px'
298
- }
299
-
300
- app.directive('tooltip', {
301
- mounted(el, binding){
302
- if(!binding.value) return
303
-
304
- const tip = document.createElement('div')
305
- tip.className = 'vt-tip'
306
- document.body.appendChild(tip)
307
-
308
- let timer = null
309
-
310
- const show = () => {
311
- const value = binding.value
312
- const text = typeof value === 'string' ? value : value?.text
313
- const placement = (typeof value === 'object' ? value?.placement : null) || binding.arg || 'top'
314
- if(!text) return
315
-
316
- // XSS-safe: textContent instead of innerHTML
317
- tip.textContent = text
318
- vtPosition(tip, el.getBoundingClientRect(), placement)
319
- tip.classList.add('vt-tip--on')
320
- }
321
-
322
- const hide = () => {
323
- clearTimeout(timer)
324
- tip.classList.remove('vt-tip--on')
325
- }
326
-
327
- const onEnter = () => {
328
- clearTimeout(timer)
329
- timer = setTimeout(show, 400)
330
- }
331
-
332
- el.addEventListener('mouseenter', onEnter)
333
- el.addEventListener('mouseleave', hide)
334
- el.addEventListener('click', hide)
335
-
336
- // Store cleanup so unmounted can remove everything
337
- el._vtCleanup = () => {
338
- clearTimeout(timer)
339
- el.removeEventListener('mouseenter', onEnter)
340
- el.removeEventListener('mouseleave', hide)
341
- el.removeEventListener('click', hide)
342
- tip.remove()
343
- }
344
- },
345
-
346
- updated(el, binding){
347
- // Nothing needed — show() reads binding.value at call time
348
- },
349
-
350
- unmounted(el){
351
- el._vtCleanup?.()
352
- }
353
- })
354
-
355
257
  const privateVars = {}
356
258
 
357
259
  app.config.globalProperties.$t = t => t
@@ -428,7 +330,7 @@ export default{
428
330
  })
429
331
 
430
332
  resizeEvents.forEach((fn) => fn())
431
- }, 100)
333
+ }, { delay: 100, flushOnExit: false })
432
334
  window.addEventListener('resize', onWindowResize)
433
335
 
434
336
  app.config.globalProperties.$addResizeListener = (el, fn) => {
@@ -495,141 +397,15 @@ export default{
495
397
  }
496
398
 
497
399
  app.directive('intersect', IntersectDirective)
498
-
499
- app.component('Ahref', defineAsyncComponent(() => import("./components/Ahref.vue")))
500
- app.component('Paragraph', defineAsyncComponent(() => import("./components/Paragraph.vue")))
501
- app.component('Alert', defineAsyncComponent(() => import("./components/Alert.vue")))
502
- app.component('Article', defineAsyncComponent(() => import("./components/Article.vue")))
503
- app.component('BarChart', defineAsyncComponent(() => import("./components/BarChart.vue")))
504
- app.component('LineChart', defineAsyncComponent(() => import("./components/LineChart.vue")))
505
- app.component('PieChart', defineAsyncComponent(() => import("./components/PieChart.vue")))
506
- app.component('DoughnutChart', defineAsyncComponent(() => import("./components/DoughnutChart.vue")))
507
- app.component('Dashboard', defineAsyncComponent(() => import("./components/Dashboard.vue")))
508
- app.component('AIDashboard', defineAsyncComponent(() => import("./components/AIDashboard.vue")))
509
- app.component('AIChat', defineAsyncComponent(() => import("./components/AIChat.vue")))
510
- app.component('Metric', defineAsyncComponent(() => import("./components/Metric.vue")))
511
- app.component('Block', defineAsyncComponent(() => import("./components/Block.vue")))
512
- app.component('Button', defineAsyncComponent(() => import("./components/Button.vue")))
513
- app.component('Card', defineAsyncComponent(() => import("./components/Card.vue")))
514
- app.component('ColorPicker', defineAsyncComponent(() => import("./components/ColorPicker.vue")))
515
- app.component('Confirm', defineAsyncComponent(() => import("./components/Confirm.vue")))
516
- app.component('ChatTyping', defineAsyncComponent(() => import("./components/ChatTyping.vue")))
517
- app.component('Checkbox', defineAsyncComponent(() => import("./components/Checkbox.vue")))
518
- app.component('CodeEditor', defineAsyncComponent(() => import("./components/CodeEditor.vue")))
519
- app.component('SvgEditor', defineAsyncComponent(() => import("./components/SvgEditor.vue")))
520
- app.component('CopyToClipboard', defineAsyncComponent(() => import("./components/CopyToClipboard.vue")))
521
- app.component('Countdown', defineAsyncComponent(() => import("./components/Countdown.vue")))
522
- app.component('Datepicker', defineAsyncComponent(() => import("./components/Datepicker.vue")))
523
- app.component('Dropdown', defineAsyncComponent(() => import("./components/Dropdown.vue")))
524
- app.component('Gmaps', defineAsyncComponent(() => import("./components/Gmaps.vue")))
525
- app.component('HTMLEditor', defineAsyncComponent(() => import("./components/HTMLEditor.vue")))
526
- app.component('Switch', defineAsyncComponent(() => import("./components/Switch.vue")))
527
- app.component('IconMenu2', defineAsyncComponent(() => import("./components/IconMenu2.vue")))
528
- app.component('Image', defineAsyncComponent(() => import("./components/Image.vue")))
529
- app.component('ImageUploader', defineAsyncComponent(() => import("./components/ImageUploader.vue")))
530
- app.component('Video', defineAsyncComponent(() => import("./components/Video.vue")))
531
- app.component('ImagePreview', defineAsyncComponent(() => import("./components/ImagePreview.vue")))
532
- app.component('Link', defineAsyncComponent(() => import("./components/Link.vue")))
533
- app.component('ListItem', defineAsyncComponent(() => import("./components/ListItem.vue")))
534
- app.component('MultiDropdown', defineAsyncComponent(() => import("./components/MultiDropdown.vue")))
535
- app.component('Carousel', defineAsyncComponent(() => import("./components/Carousel.vue")))
536
- app.component('ContextMenu', defineAsyncComponent(() => import("./components/ContextMenu.vue")))
537
- app.component('ContextMenuItem', defineAsyncComponent(() => import("./components/ContextMenuItem.vue")))
538
- app.component('FAQ', defineAsyncComponent(() => import("./widgets/FAQ.vue")))
539
- app.component('Flex', defineAsyncComponent(() => import("./components/Flex.vue")))
540
- app.component('Grid', defineAsyncComponent(() => import("./components/Grid.vue")))
541
- app.component('OTPField', defineAsyncComponent(() => import("./components/OTPField.vue")))
542
- app.component('Radio', defineAsyncComponent(() => import("./components/Radio.vue")))
543
- app.component('Tabs', defineAsyncComponent(() => import("./components/Tabs.vue")))
544
- app.component('Textbox', defineAsyncComponent(() => import("./components/Textbox.vue")))
545
- app.component('Textarea', defineAsyncComponent(() => import("./components/Textarea.vue")))
546
- app.component('Timepicker', defineAsyncComponent(() => import("./components/Timepicker.vue")))
547
- app.component('Datetimepicker', defineAsyncComponent(() => import("./components/Datetimepicker.vue")))
548
- app.component('Toast', defineAsyncComponent(() => import("./components/Toast.vue")))
549
- app.component('TreeView', defineAsyncComponent(() => import("./components/TreeView.vue")))
550
- app.component('TreeViewItem', defineAsyncComponent(() => import("./components/TreeViewItem.vue")))
551
- app.component('Uploader', defineAsyncComponent(() => import("./components/Uploader.vue")))
552
- app.component('VirtualGrid', defineAsyncComponent(() => import("./components/VirtualGrid.vue")))
553
- app.component('VirtualTable', defineAsyncComponent(() => import("./components/VirtualTable.vue")))
554
- app.component('Slider', defineAsyncComponent(() => import("./components/Slider.vue")))
555
- app.component('Table', defineAsyncComponent(() => import("./components/Table.vue")))
556
- app.component('Thumbnail', defineAsyncComponent(() => import("./components/Thumbnail.vue")))
557
- app.component('Testimonial', defineAsyncComponent(() => import("./components/Testimonial.vue")))
558
- app.component('TextBlock', defineAsyncComponent(() => import("./components/TextBlock.vue")))
559
- app.component('YoutubeVideo', defineAsyncComponent(() => import("./components/YoutubeVideo.vue")))
560
- app.component('Svg', defineAsyncComponent(() => import("./components/Svg.vue")))
561
- app.component('TextWithTag', defineAsyncComponent(() => import("./components/TextWithTag.vue")))
562
- app.component('List', defineAsyncComponent(() => import("./components/List.vue")))
563
- app.component('Chart', defineAsyncComponent(() => import("./components/Chart.vue")))
564
-
565
- app.component('AhrefSetting', defineAsyncComponent(() => import("./widgets/AhrefSetting.vue")))
566
- app.component('ArticleSetting', defineAsyncComponent(() => import("./widgets/ArticleSetting.vue")))
567
- app.component('BlockSetting', defineAsyncComponent(() => import("./widgets/BlockSetting.vue")))
568
- app.component('ButtonSetting', defineAsyncComponent(() => import("./widgets/ButtonSetting.vue")))
569
- app.component('CarouselSetting', defineAsyncComponent(() => import("./widgets/CarouselSetting.vue")))
570
- app.component('CountdownSetting', defineAsyncComponent(() => import("./widgets/CountdownSetting.vue")))
571
- app.component('ComponentSetting', defineAsyncComponent(() => import("./widgets/ComponentSetting.vue")))
572
- app.component('ComponentSetting2', defineAsyncComponent(() => import("./widgets/ComponentSetting2.vue")))
573
- app.component('ContactForm', defineAsyncComponent(() => import("./widgets/ContactForm.vue")))
574
- app.component('ContactFormSetting', defineAsyncComponent(() => import("./widgets/ContactFormSetting.vue")))
575
- app.component('EmbeddedVideo', defineAsyncComponent(() => import("./widgets/EmbeddedVideo.vue")))
576
- app.component('EmbeddedVideoSetting', defineAsyncComponent(() => import("./widgets/EmbeddedVideoSetting.vue")))
577
- app.component('FAQSetting', defineAsyncComponent(() => import("./widgets/FAQSetting.vue")))
578
- app.component('FeatureList', defineAsyncComponent(() => import("./widgets/FeatureList.vue")))
579
- app.component('FeatureListSetting', defineAsyncComponent(() => import("./widgets/FeatureListSetting.vue")))
580
- app.component('BackgroundColorSetting', defineAsyncComponent(() => import("./widgets/BackgroundColorSetting.vue")))
581
- app.component('BorderColorSetting', defineAsyncComponent(() => import("./widgets/BorderColorSetting.vue")))
582
- app.component('FlexSetting', defineAsyncComponent(() => import("./widgets/FlexSetting.vue")))
583
- app.component('GridSetting', defineAsyncComponent(() => import("./widgets/GridSetting.vue")))
584
- app.component('Header2', defineAsyncComponent(() => import("./widgets/Header2.vue")))
585
- app.component('Header2Setting', defineAsyncComponent(() => import("./widgets/Header2Setting.vue")))
586
- app.component('IconList', defineAsyncComponent(() => import("./widgets/IconList.vue")))
587
- app.component('IconListSetting', defineAsyncComponent(() => import("./widgets/IconListSetting.vue")))
588
- app.component('LinkSetting', defineAsyncComponent(() => import("./widgets/LinkSetting.vue")))
589
- app.component('ImageSetting', defineAsyncComponent(() => import("./widgets/ImageSetting.vue")))
590
- app.component('MultiValueSetting', defineAsyncComponent(() => import("./widgets/MultiValueSetting.vue")))
591
- app.component('MultiValueSetting2', defineAsyncComponent(() => import("./widgets/MultiValueSetting2.vue")))
592
- app.component('PositionSetting', defineAsyncComponent(() => import("./widgets/PositionSetting.vue")))
593
- app.component('ParagraphSetting', defineAsyncComponent(() => import("./widgets/ParagraphSetting.vue")))
594
- app.component('Review', defineAsyncComponent(() => import("./widgets/Review.vue")))
595
- app.component('ReviewSetting', defineAsyncComponent(() => import("./widgets/ReviewSetting.vue")))
596
- app.component('Share', defineAsyncComponent(() => import("./widgets/Share.vue")))
597
- app.component('ShareSetting', defineAsyncComponent(() => import("./widgets/ShareSetting.vue")))
598
- app.component('TableSetting', defineAsyncComponent(() => import("./widgets/TableSetting.vue")))
599
- app.component('ThumbnailSetting', defineAsyncComponent(() => import("./widgets/ThumbnailSetting.vue")))
600
- app.component('TestimonialSetting', defineAsyncComponent(() => import("./widgets/TestimonialSetting.vue")))
601
- app.component('TextBlockSetting', defineAsyncComponent(() => import("./widgets/TextBlockSetting.vue")))
602
- app.component('WebPageBuilder', defineAsyncComponent(() => import("./widgets/WebPageBuilder.vue")))
603
- app.component('WebComponentSelector', defineAsyncComponent(() => import("./widgets/WebComponentSelector.vue")))
604
- app.component('WebDatasourceSelector', defineAsyncComponent(() => import("./widgets/WebDatasourceSelector.vue")))
605
- app.component('WebLayoutSelector', defineAsyncComponent(() => import("./widgets/WebLayoutSelector.vue")))
606
- app.component('ModalSetting', defineAsyncComponent(() => import("./widgets/ModalSetting.vue")))
607
- app.component('DataListSetting', defineAsyncComponent(() => import("./widgets/DataListSetting.vue")))
608
- app.component('YoutubeVideoSetting', defineAsyncComponent(() => import("./widgets/YoutubeVideoSetting.vue")))
609
- app.component('SvgSetting', defineAsyncComponent(() => import("./widgets/SvgSetting.vue")))
610
- app.component('PresetBar', defineAsyncComponent(() => import("./widgets/PresetBar.vue")))
611
- app.component('PresetSelector', defineAsyncComponent(() => import("./widgets/PresetSelector.vue")))
612
- app.component('PresetBarPivotColumnEdit', defineAsyncComponent(() => import("./widgets/PresetBarPivotColumnEdit.vue")))
613
- app.component('ColumnSelector', defineAsyncComponent(() => import("./widgets/ColumnSelector.vue")))
614
- app.component('Text', defineAsyncComponent(() => import("./components/Text.vue")))
615
- app.component('MenuItem1', defineAsyncComponent(() => import("./components/MenuItem1.vue")))
616
- app.component('MenuItem1Setting', defineAsyncComponent(() => import("./widgets/MenuItem1Setting.vue")))
617
- app.component('CollapsiblePanel', defineAsyncComponent(() => import("./components/CollapsiblePanel.vue")))
618
- app.component('CollapsiblePanelSetting', defineAsyncComponent(() => import("./widgets/CollapsiblePanelSetting.vue")))
619
- app.component('LLMChat', defineAsyncComponent(() => import("./widgets/LLMChat.vue")))
620
-
621
- app.component('AccountIcon', defineAsyncComponent(() => import("./components/AccountIcon.vue")))
622
- app.component('CartIcon', defineAsyncComponent(() => import("./components/CartIcon.vue")))
623
-
624
- app.component('SearchModal', defineAsyncComponent(() => import("./components/SearchModal.vue")))
625
- app.component('SearchModalSetting', defineAsyncComponent(() => import("./widgets/SearchModalSetting.vue")))
626
-
627
- app.component('Cart', defineAsyncComponent(() => import("./components/Cart.vue")))
628
- app.component('CartSetting', defineAsyncComponent(() => import("./widgets/CartSetting.vue")))
629
-
630
- app.component('TreeMenu', defineAsyncComponent(() => import("./components/TreeMenu.vue")))
631
- app.component('MarkdownEdit', defineAsyncComponent(() => import("./components/MarkdownEdit.vue")))
632
- app.component('MarkdownPreview', defineAsyncComponent(() => import("./components/MarkdownPreview.vue")))
400
+ app.directive('tooltip', TooltipDirective)
401
+
402
+ // Auto-register every component in ./components as a lazy global component,
403
+ // named after its file (e.g. Button.vue -> <Button>).
404
+ const componentModules = import.meta.glob('./components/*.vue')
405
+ for(const path in componentModules){
406
+ const name = path.split('/').pop().replace(/\.vue$/, '')
407
+ app.component(name, defineAsyncComponent(componentModules[path]))
408
+ }
633
409
  }
634
410
 
635
411
  }
@@ -253,7 +253,23 @@ const plugin = Plugin(function({ addBase, addUtilities, config, theme }) {
253
253
  900: "var(--secondary-900)",
254
254
  DEFAULT: "var(--secondary-500)"
255
255
  },
256
+ // Third tone for tri-tone themes. Themes that only define two tones
257
+ // fall back to secondary, so accent-* is always safe to use.
258
+ accent: {
259
+ 50: "var(--accent-50, var(--secondary-50))",
260
+ 100: "var(--accent-100, var(--secondary-100))",
261
+ 200: "var(--accent-200, var(--secondary-200))",
262
+ 300: "var(--accent-300, var(--secondary-300))",
263
+ 400: "var(--accent-400, var(--secondary-400))",
264
+ 500: "var(--accent-500, var(--secondary-500))",
265
+ 600: "var(--accent-600, var(--secondary-600))",
266
+ 700: "var(--accent-700, var(--secondary-700))",
267
+ 800: "var(--accent-800, var(--secondary-800))",
268
+ 900: "var(--accent-900, var(--secondary-900))",
269
+ DEFAULT: "var(--accent-500, var(--secondary-500))"
270
+ },
256
271
  base: {
272
+ 200: "var(--base-200, var(--base-400))",
257
273
  300: "var(--base-300)",
258
274
  400: "var(--base-400)",
259
275
  500: "var(--base-500)",