@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,626 @@
1
+ <template>
2
+
3
+ <!-- Singleton mode: the one layer that actually renders tooltips. Mounted
4
+ automatically by the tooltip controller, driven by `tooltipState`. -->
5
+ <Teleport v-if="singleton" to="body">
6
+ <Transition name="mx-tooltip">
7
+ <div v-if="state.open"
8
+ ref="tip"
9
+ :id="tooltipId"
10
+ role="tooltip"
11
+ class="mx-tooltip"
12
+ :class="tipClass"
13
+ :data-placement="resolvedPlacement"
14
+ :style="tipStyle">
15
+
16
+ <div class="mx-tooltip__surface">
17
+ <div class="mx-tooltip__content">
18
+ <div v-if="state.title" class="mx-tooltip__title">{{ state.title }}</div>
19
+ <div v-if="state.text" class="mx-tooltip__text">{{ state.text }}</div>
20
+ </div>
21
+ <kbd v-if="state.shortcut" class="mx-tooltip__kbd">{{ state.shortcut }}</kbd>
22
+ </div>
23
+
24
+ <span v-if="state.arrow !== false" class="mx-tooltip__arrow" :style="arrowStyle"></span>
25
+ </div>
26
+ </Transition>
27
+ </Teleport>
28
+
29
+ <!-- Wrapper mode: <Tooltip text="…"><button/></Tooltip> -->
30
+ <component v-else
31
+ :is="tag"
32
+ ref="trigger"
33
+ class="mx-tooltip-trigger"
34
+ @mouseenter="onEnter"
35
+ @mouseleave="onLeave"
36
+ @focus.capture="onFocus"
37
+ @blur.capture="onLeaveNow"
38
+ @click="onLeaveNow">
39
+ <slot></slot>
40
+ </component>
41
+
42
+ </template>
43
+
44
+ <script>
45
+
46
+ import {
47
+ TOOLTIP_ID, TOOLTIP_OFFSET, TOOLTIP_PLACEMENTS,
48
+ hideTooltip, hideTooltipNow, isKeyboardFocus, mountTooltipLayer, showTooltip, tooltipState
49
+ } from '../utils/tooltip.mjs'
50
+
51
+ const VIEWPORT_PADDING = 8
52
+ const ARROW_INSET = 14
53
+ const OPPOSITE = { top: 'bottom', bottom: 'top', left: 'right', right: 'left' }
54
+
55
+ const clamp = (value, min, max) => Math.max(min, Math.min(max, value))
56
+
57
+ export default {
58
+
59
+ name: 'Tooltip',
60
+
61
+ emits: [ 'show', 'hide', 'update:open' ],
62
+
63
+ props: {
64
+
65
+ /** Renders the shared tooltip layer instead of a trigger. Set by the controller. */
66
+ singleton: Boolean,
67
+
68
+ text: String,
69
+
70
+ /** Optional stronger first line, for a label + description tooltip. */
71
+ title: String,
72
+
73
+ /** Optional keyboard hint rendered as a chip, e.g. `⌘S`. */
74
+ shortcut: String,
75
+
76
+ placement: {
77
+ type: String,
78
+ default: 'top' // top|bottom|left|right — flips automatically when it doesn't fit
79
+ },
80
+
81
+ variant: {
82
+ type: String,
83
+ default: 'base' // base|primary|secondary|accent|danger|success
84
+ },
85
+
86
+ /** Hover intent in ms before showing. `null` uses the shared default (400). */
87
+ delay: {
88
+ type: Number,
89
+ default: null
90
+ },
91
+
92
+ offset: {
93
+ type: Number,
94
+ default: TOOLTIP_OFFSET
95
+ },
96
+
97
+ maxWidth: {
98
+ type: [ Number, String ],
99
+ default: null
100
+ },
101
+
102
+ arrow: {
103
+ type: Boolean,
104
+ default: true
105
+ },
106
+
107
+ disabled: Boolean,
108
+
109
+ /** Controlled mode — when set, hover/focus is ignored. */
110
+ open: {
111
+ type: Boolean,
112
+ default: null
113
+ },
114
+
115
+ tag: {
116
+ type: String,
117
+ default: 'span'
118
+ }
119
+
120
+ },
121
+
122
+ computed: {
123
+
124
+ state(){
125
+ return tooltipState
126
+ },
127
+
128
+ tooltipId(){
129
+ return TOOLTIP_ID
130
+ },
131
+
132
+ tipClass(){
133
+ return [
134
+ `mx-tooltip--${this.state.variant}`,
135
+ this.state.arrow === false ? 'mx-tooltip--no-arrow' : ''
136
+ ]
137
+ .filter(_ => _)
138
+ .join(' ')
139
+ },
140
+
141
+ tipStyle(){
142
+
143
+ const style = {
144
+ top: `${this.position.top}px`,
145
+ left: `${this.position.left}px`,
146
+ visibility: this.positioned ? null : 'hidden'
147
+ }
148
+
149
+ if(this.state.maxWidth){
150
+ style['--mx-tooltip-max-width'] = typeof this.state.maxWidth === 'number' ?
151
+ `${this.state.maxWidth}px` :
152
+ this.state.maxWidth
153
+ }
154
+
155
+ return style
156
+ },
157
+
158
+ active(){
159
+ if(this.singleton) return false
160
+ const el = this.anchorEl()
161
+ return !!el && this.state.open && this.state.anchor === el
162
+ },
163
+
164
+ options(){
165
+ return {
166
+ text: this.text,
167
+ title: this.title,
168
+ shortcut: this.shortcut,
169
+ placement: this.placement,
170
+ variant: this.variant,
171
+ delay: this.delay,
172
+ offset: this.offset,
173
+ maxWidth: this.maxWidth,
174
+ arrow: this.arrow
175
+ }
176
+ }
177
+
178
+ },
179
+
180
+ data(){
181
+ return {
182
+ position: { top: 0, left: 0 },
183
+ arrowStyle: {},
184
+ resolvedPlacement: 'top',
185
+ positioned: false
186
+ }
187
+ },
188
+
189
+ watch: {
190
+
191
+ 'state.open'(open){
192
+ if(!this.singleton) return
193
+ open ? this.onOpened() : this.onClosed()
194
+ },
195
+
196
+ 'state.anchor'(){
197
+ if(this.singleton && this.state.open) this.schedulePosition()
198
+ },
199
+
200
+ 'state.text'(){
201
+ if(this.singleton && this.state.open) this.schedulePosition()
202
+ },
203
+
204
+ open(value){
205
+ if(this.singleton || value === null) return
206
+ value ? this.show() : this.hide(true)
207
+ },
208
+
209
+ active(value){
210
+ this.$emit(value ? 'show' : 'hide')
211
+ this.$emit('update:open', value)
212
+ }
213
+
214
+ },
215
+
216
+ mounted(){
217
+ if(!this.singleton){
218
+ mountTooltipLayer()
219
+ if(this.open) this.show()
220
+ }
221
+ },
222
+
223
+ beforeUnmount(){
224
+
225
+ if(this.singleton){
226
+ this.unbindViewportEvents()
227
+ return
228
+ }
229
+
230
+ hideTooltipNow(this.anchorEl())
231
+ },
232
+
233
+ methods: {
234
+
235
+ // --- wrapper mode ---
236
+
237
+ anchorEl(){
238
+ const trigger = this.$refs.trigger
239
+ return trigger && trigger.$el ? trigger.$el : trigger
240
+ },
241
+
242
+ /** Shows this tooltip programmatically. */
243
+ show(){
244
+ if(this.disabled) return
245
+ showTooltip(this.anchorEl(), this.options)
246
+ },
247
+
248
+ /** Hides this tooltip programmatically. */
249
+ hide(immediate){
250
+ immediate ? hideTooltipNow(this.anchorEl()) : hideTooltip(this.anchorEl())
251
+ },
252
+
253
+ onEnter(){
254
+ if(this.open !== null) return
255
+ this.show()
256
+ },
257
+
258
+ onLeave(){
259
+ if(this.open !== null) return
260
+ this.hide()
261
+ },
262
+
263
+ onLeaveNow(){
264
+ if(this.open !== null) return
265
+ this.hide(true)
266
+ },
267
+
268
+ onFocus(e){
269
+ if(this.open !== null) return
270
+ // Only on keyboard focus — a mouse click already had its hover chance.
271
+ if(!isKeyboardFocus(e.target)) return
272
+ this.show()
273
+ },
274
+
275
+ // --- singleton mode ---
276
+
277
+ onOpened(){
278
+ this.positioned = false
279
+ this.resolvedPlacement = this.state.placement
280
+ this.bindViewportEvents()
281
+ this.schedulePosition()
282
+ },
283
+
284
+ onClosed(){
285
+ this.unbindViewportEvents()
286
+ this.positioned = false
287
+ },
288
+
289
+ schedulePosition(){
290
+ this.$nextTick(this.updatePosition)
291
+ },
292
+
293
+ anchorRect(){
294
+
295
+ const anchor = this.state.anchor
296
+ if(!anchor) return null
297
+
298
+ if(typeof anchor.getBoundingClientRect === 'function'){
299
+ if(anchor.isConnected === false) return null
300
+ return anchor.getBoundingClientRect()
301
+ }
302
+
303
+ return anchor // plain rect-like { top, left, width, height, bottom, right }
304
+ },
305
+
306
+ updatePosition(){
307
+
308
+ const tip = this.$refs.tip
309
+ const rect = this.anchorRect()
310
+
311
+ if(!tip || !rect) return
312
+
313
+ const vw = document.documentElement.clientWidth
314
+ const vh = document.documentElement.clientHeight
315
+
316
+ // Anchor scrolled out of sight — nothing left to point at.
317
+ if(rect.bottom < 0 || rect.right < 0 || rect.top > vh || rect.left > vw){
318
+ hideTooltipNow()
319
+ return
320
+ }
321
+
322
+ const tw = tip.offsetWidth
323
+ const th = tip.offsetHeight
324
+ const offset = this.state.offset ?? TOOLTIP_OFFSET
325
+
326
+ let placement = TOOLTIP_PLACEMENTS.includes(this.state.placement) ? this.state.placement : 'top'
327
+
328
+ const space = {
329
+ top: rect.top,
330
+ bottom: vh - rect.bottom,
331
+ left: rect.left,
332
+ right: vw - rect.right
333
+ }
334
+ const needed = (placement === 'top' || placement === 'bottom' ? th : tw) + offset + VIEWPORT_PADDING
335
+
336
+ // Flip only when the opposite side genuinely has more room.
337
+ if(space[placement] < needed && space[OPPOSITE[placement]] > space[placement]){
338
+ placement = OPPOSITE[placement]
339
+ }
340
+
341
+ let top, left
342
+
343
+ if(placement === 'top' || placement === 'bottom'){
344
+ top = placement === 'top' ? rect.top - th - offset : rect.bottom + offset
345
+ left = clamp(rect.left + rect.width / 2 - tw / 2, VIEWPORT_PADDING, Math.max(VIEWPORT_PADDING, vw - tw - VIEWPORT_PADDING))
346
+ this.arrowStyle = {
347
+ left: `${clamp(rect.left + rect.width / 2 - left, ARROW_INSET, Math.max(ARROW_INSET, tw - ARROW_INSET))}px`
348
+ }
349
+ }
350
+ else{
351
+ left = placement === 'left' ? rect.left - tw - offset : rect.right + offset
352
+ top = clamp(rect.top + rect.height / 2 - th / 2, VIEWPORT_PADDING, Math.max(VIEWPORT_PADDING, vh - th - VIEWPORT_PADDING))
353
+ this.arrowStyle = {
354
+ top: `${clamp(rect.top + rect.height / 2 - top, ARROW_INSET, Math.max(ARROW_INSET, th - ARROW_INSET))}px`
355
+ }
356
+ }
357
+
358
+ this.resolvedPlacement = placement
359
+ this.position = { top: Math.round(top), left: Math.round(left) }
360
+ this.positioned = true
361
+ },
362
+
363
+ onViewportChange(){
364
+ if(this.frame) return
365
+ this.frame = requestAnimationFrame(() => {
366
+ this.frame = null
367
+ if(this.state.open) this.updatePosition()
368
+ })
369
+ },
370
+
371
+ onKeydown(e){
372
+ if(e.key === 'Escape') hideTooltipNow()
373
+ },
374
+
375
+ bindViewportEvents(){
376
+ if(this.bound) return
377
+ this.bound = true
378
+ window.addEventListener('scroll', this.onViewportChange, { capture: true, passive: true })
379
+ window.addEventListener('resize', this.onViewportChange, { passive: true })
380
+ window.addEventListener('keydown', this.onKeydown)
381
+ },
382
+
383
+ unbindViewportEvents(){
384
+ if(!this.bound) return
385
+ this.bound = false
386
+ if(this.frame){
387
+ cancelAnimationFrame(this.frame)
388
+ this.frame = null
389
+ }
390
+ window.removeEventListener('scroll', this.onViewportChange, { capture: true })
391
+ window.removeEventListener('resize', this.onViewportChange)
392
+ window.removeEventListener('keydown', this.onKeydown)
393
+ }
394
+
395
+ }
396
+
397
+ }
398
+
399
+ </script>
400
+
401
+ <style>
402
+
403
+ /* Deliberately global (not `module`): a single layer renders every tooltip, and
404
+ apps should be able to restyle it by overriding these custom properties. */
405
+
406
+ .mx-tooltip{
407
+ --mx-tooltip-max-width: 260px;
408
+
409
+ position: fixed;
410
+ top: 0;
411
+ left: 0;
412
+ z-index: var(--mx-tooltip-z, 9999);
413
+ pointer-events: none;
414
+ filter: drop-shadow(0 6px 16px rgba(0, 0, 0, .18)) drop-shadow(0 1px 3px rgba(0, 0, 0, .14));
415
+ will-change: transform, opacity;
416
+ }
417
+
418
+ html[data-theme="dark"] .mx-tooltip{
419
+ filter: drop-shadow(0 8px 20px rgba(0, 0, 0, .55)) drop-shadow(0 1px 3px rgba(0, 0, 0, .45));
420
+ }
421
+
422
+ .mx-tooltip__surface{
423
+ @apply bg-base-500 border-border-100;
424
+ position: relative;
425
+ z-index: 1;
426
+ display: flex;
427
+ align-items: center;
428
+ gap: 8px;
429
+ max-width: var(--mx-tooltip-max-width);
430
+ padding: 6px 9px;
431
+ border-width: 1px;
432
+ border-style: solid;
433
+ border-radius: 8px;
434
+ }
435
+
436
+ .mx-tooltip__arrow{
437
+ @apply bg-base-500 border-border-100;
438
+ position: absolute;
439
+ width: 9px;
440
+ height: 9px;
441
+ border-width: 1px;
442
+ border-style: solid;
443
+ border-radius: 1.5px;
444
+ }
445
+
446
+ .mx-tooltip__content{
447
+ min-width: 0;
448
+ }
449
+
450
+ .mx-tooltip__title,
451
+ .mx-tooltip__text{
452
+ @apply text-text;
453
+ font-size: 12px;
454
+ line-height: 1.45;
455
+ text-align: left;
456
+ white-space: pre-line;
457
+ overflow-wrap: anywhere;
458
+ }
459
+
460
+ .mx-tooltip__title{
461
+ font-weight: 600;
462
+ letter-spacing: .01em;
463
+ }
464
+
465
+ .mx-tooltip__title + .mx-tooltip__text{
466
+ @apply text-text-400;
467
+ margin-top: 1px;
468
+ font-size: 11.5px;
469
+ }
470
+
471
+ .mx-tooltip__kbd{
472
+ @apply bg-base-300 text-text-400;
473
+ flex: none;
474
+ padding: 1px 5px;
475
+ border-radius: 4px;
476
+ font-family: inherit;
477
+ font-size: 10.5px;
478
+ font-weight: 600;
479
+ line-height: 1.5;
480
+ letter-spacing: .02em;
481
+ }
482
+
483
+ /* Variants: the theme's own tones. `-50` is the far end of each scale, so it
484
+ stays readable on `-500` in both the light and the dark palette. */
485
+
486
+ .mx-tooltip--primary .mx-tooltip__surface,
487
+ .mx-tooltip--primary .mx-tooltip__arrow{
488
+ @apply bg-primary-500 border-primary-400;
489
+ }
490
+ .mx-tooltip--primary .mx-tooltip__title,
491
+ .mx-tooltip--primary .mx-tooltip__text{
492
+ @apply text-primary-50;
493
+ }
494
+ .mx-tooltip--primary .mx-tooltip__title + .mx-tooltip__text{
495
+ @apply text-primary-100;
496
+ }
497
+ .mx-tooltip--primary .mx-tooltip__kbd{
498
+ @apply bg-primary-600 text-primary-50;
499
+ }
500
+
501
+ .mx-tooltip--secondary .mx-tooltip__surface,
502
+ .mx-tooltip--secondary .mx-tooltip__arrow{
503
+ @apply bg-secondary-500 border-secondary-400;
504
+ }
505
+ .mx-tooltip--secondary .mx-tooltip__title,
506
+ .mx-tooltip--secondary .mx-tooltip__text{
507
+ @apply text-secondary-50;
508
+ }
509
+ .mx-tooltip--secondary .mx-tooltip__title + .mx-tooltip__text{
510
+ @apply text-secondary-100;
511
+ }
512
+ .mx-tooltip--secondary .mx-tooltip__kbd{
513
+ @apply bg-secondary-600 text-secondary-50;
514
+ }
515
+
516
+ .mx-tooltip--accent .mx-tooltip__surface,
517
+ .mx-tooltip--accent .mx-tooltip__arrow{
518
+ @apply bg-accent-500 border-accent-400;
519
+ }
520
+ .mx-tooltip--accent .mx-tooltip__title,
521
+ .mx-tooltip--accent .mx-tooltip__text{
522
+ @apply text-accent-50;
523
+ }
524
+ .mx-tooltip--accent .mx-tooltip__title + .mx-tooltip__text{
525
+ @apply text-accent-100;
526
+ }
527
+ .mx-tooltip--accent .mx-tooltip__kbd{
528
+ @apply bg-accent-600 text-accent-50;
529
+ }
530
+
531
+ .mx-tooltip--danger .mx-tooltip__surface,
532
+ .mx-tooltip--danger .mx-tooltip__arrow{
533
+ @apply bg-red-500 border-red-400;
534
+ }
535
+ .mx-tooltip--danger .mx-tooltip__title,
536
+ .mx-tooltip--danger .mx-tooltip__text,
537
+ .mx-tooltip--danger .mx-tooltip__title + .mx-tooltip__text,
538
+ .mx-tooltip--danger .mx-tooltip__kbd{
539
+ @apply text-white;
540
+ }
541
+ .mx-tooltip--danger .mx-tooltip__kbd{
542
+ @apply bg-red-600;
543
+ }
544
+
545
+ .mx-tooltip--success .mx-tooltip__surface,
546
+ .mx-tooltip--success .mx-tooltip__arrow{
547
+ @apply bg-lime-600 border-lime-500;
548
+ }
549
+ .mx-tooltip--success .mx-tooltip__title,
550
+ .mx-tooltip--success .mx-tooltip__text,
551
+ .mx-tooltip--success .mx-tooltip__title + .mx-tooltip__text,
552
+ .mx-tooltip--success .mx-tooltip__kbd{
553
+ @apply text-white;
554
+ }
555
+ .mx-tooltip--success .mx-tooltip__kbd{
556
+ @apply bg-lime-700;
557
+ }
558
+
559
+ .mx-tooltip[data-placement="top"] .mx-tooltip__arrow{
560
+ bottom: -5px;
561
+ transform: translateX(-50%) rotate(45deg);
562
+ }
563
+ .mx-tooltip[data-placement="bottom"] .mx-tooltip__arrow{
564
+ top: -5px;
565
+ transform: translateX(-50%) rotate(45deg);
566
+ }
567
+ .mx-tooltip[data-placement="left"] .mx-tooltip__arrow{
568
+ right: -5px;
569
+ transform: translateY(-50%) rotate(45deg);
570
+ }
571
+ .mx-tooltip[data-placement="right"] .mx-tooltip__arrow{
572
+ left: -5px;
573
+ transform: translateY(-50%) rotate(45deg);
574
+ }
575
+
576
+ .mx-tooltip[data-placement="top"]{ transform-origin: bottom center; }
577
+ .mx-tooltip[data-placement="bottom"]{ transform-origin: top center; }
578
+ .mx-tooltip[data-placement="left"]{ transform-origin: right center; }
579
+ .mx-tooltip[data-placement="right"]{ transform-origin: left center; }
580
+
581
+ .mx-tooltip-enter-active{
582
+ transition: opacity .13s ease-out, transform .17s cubic-bezier(.16, 1, .3, 1);
583
+ }
584
+
585
+ .mx-tooltip-leave-active{
586
+ transition: opacity .1s ease-in, transform .1s ease-in;
587
+ }
588
+
589
+ .mx-tooltip-enter-from,
590
+ .mx-tooltip-leave-to{
591
+ opacity: 0;
592
+ transform: scale(.96) translate3d(0, 3px, 0);
593
+ }
594
+
595
+ .mx-tooltip[data-placement="bottom"].mx-tooltip-enter-from,
596
+ .mx-tooltip[data-placement="bottom"].mx-tooltip-leave-to{
597
+ transform: scale(.96) translate3d(0, -3px, 0);
598
+ }
599
+
600
+ .mx-tooltip[data-placement="left"].mx-tooltip-enter-from,
601
+ .mx-tooltip[data-placement="left"].mx-tooltip-leave-to{
602
+ transform: scale(.96) translate3d(3px, 0, 0);
603
+ }
604
+
605
+ .mx-tooltip[data-placement="right"].mx-tooltip-enter-from,
606
+ .mx-tooltip[data-placement="right"].mx-tooltip-leave-to{
607
+ transform: scale(.96) translate3d(-3px, 0, 0);
608
+ }
609
+
610
+ @media (prefers-reduced-motion: reduce){
611
+ .mx-tooltip-enter-active,
612
+ .mx-tooltip-leave-active{
613
+ transition: opacity .08s linear;
614
+ }
615
+ .mx-tooltip-enter-from,
616
+ .mx-tooltip-leave-to{
617
+ transform: none;
618
+ }
619
+ }
620
+
621
+ .mx-tooltip-trigger{
622
+ display: inline-flex;
623
+ max-width: 100%;
624
+ }
625
+
626
+ </style>
@@ -272,7 +272,7 @@ export default{
272
272
 
273
273
  .virtualGrid{
274
274
  @apply flex-1 overflow-y-auto;
275
- @apply md:border-[1px] border-border-50 md:bg-base-400;
275
+ @apply md:bg-base-400;
276
276
  }
277
277
 
278
278
  .scroller{
@@ -285,7 +285,7 @@ export default{
285
285
  .spacer{
286
286
  will-change: auto;
287
287
  position: relative;
288
- @apply grid divide-y divide-border-50 border-t-[1px] border-border-50;
288
+ @apply grid;
289
289
  }
290
290
 
291
291
  .calc{
@@ -250,7 +250,7 @@ export default{
250
250
 
251
251
  appearances: {
252
252
  type: Object,
253
- default: {}
253
+ default: () => ({})
254
254
  },
255
255
 
256
256
  type: String,
@@ -927,7 +927,7 @@ export default{
927
927
 
928
928
  .comp{
929
929
  @apply flex flex-col overflow-hidden;
930
- @apply border-[1px] border-border-50 rounded-md bg-base-400;
930
+ @apply border-[1px] border-border-50 rounded-md bg-base-500;
931
931
  }
932
932
 
933
933
  .comp>*:last-child{
@@ -1031,8 +1031,9 @@ export default{
1031
1031
  @apply px-3 uppercase font-bold;
1032
1032
  }
1033
1033
 
1034
+ /* one step off .comp so the frozen header stays readable as its own pane */
1034
1035
  .freezed{
1035
- @apply bg-base-500;
1036
+ @apply bg-base-400;
1036
1037
  }
1037
1038
 
1038
1039
  /* elevation cue on the frozen pane once the main pane is scrolled sideways;
@@ -67,6 +67,8 @@
67
67
 
68
68
  export default{
69
69
 
70
+ emits: [ 'apply' ],
71
+
70
72
  inject: [ 'alert', 'socketEmit2' ],
71
73
 
72
74
  props: {
@@ -52,7 +52,7 @@ export default{
52
52
 
53
53
  templates: {
54
54
  type: Array,
55
- default: [
55
+ default: () => [
56
56
  {
57
57
  imageUrl: '/assets/templates/empty1.png',
58
58
  layout: {