vunor 0.1.6 → 0.2.0

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/dist/theme.mjs CHANGED
@@ -29,32 +29,6 @@ const toastShortcuts = defineShortcuts({
29
29
  }
30
30
  });
31
31
  //#endregion
32
- //#region src/components/Button/shortcuts.ts
33
- const buttonShortcuts = defineShortcuts({
34
- "btn": {
35
- "": "h-fingertip flex items-center justify-center px-$m gap-$xs select-none fw-bold tracking-wide relative",
36
- "[&.btn-round]:": "px-fingertip-half rounded-fingertip-half",
37
- "[&.btn-square]:": "size-fingertip px-0",
38
- "[&.btn-round.btn-square]:": "px-0",
39
- "disabled:": "opacity-80 cursor-not-allowed",
40
- "[&>span]:data-[loading]:": "opacity-0 pointer-events-none",
41
- "[&>div:not(.loading-indicator-wrapper)]:data-[loading]:": "opacity-0 pointer-events-none",
42
- "[&>.loading-indicator-wrapper]:": "absolute left-0 top-0 right-0 bottom-0 flex items-center justify-center cursor-wait"
43
- },
44
- "btn-square": { "": "" },
45
- "btn-label": {
46
- "": "lh-1em ellipsis whitespace-nowrap overflow-x-clip overflow-y-visible",
47
- "group-[.btn-square]/btn:": "hidden"
48
- },
49
- "btn-icon": {
50
- "": "size-1em font-size-1.25em",
51
- "group-[.btn-round]/btn:[&.btn-icon-left]:": "ml-[-0.5em]",
52
- "group-[.btn-round]/btn:[&.btn-icon-right]:": "mr-[-0.5em]",
53
- "group-[.btn-square]/btn:": "font-size-1.5em m-0!",
54
- "group-[.btn-round.btn-square]/btn:": "m-0!"
55
- }
56
- });
57
- //#endregion
58
32
  //#region src/components/Calendar/shortcuts.ts
59
33
  const calendarShortcuts = defineShortcuts({
60
34
  "calendar-root": "inline-block",
@@ -62,9 +36,8 @@ const calendarShortcuts = defineShortcuts({
62
36
  "calendar-grid-row": "grid grid-cols-7 text-body-s",
63
37
  "calendar-month-grid": "flex flex-col gap-$m sm:flex-row flex-wrap sm:gap-$m",
64
38
  "calendar-cell": {
65
- "": "c8-flat relative flex items-center justify-center lh-1em rounded-r0 whitespace-nowrap font-normal size-3em outline-none",
39
+ "": "disabled-soft c8-flat relative flex items-center justify-center lh-1em rounded-r0 whitespace-nowrap font-normal size-3em outline-none",
66
40
  "focus-visible:": "shadow-[0_0_0_2px] shadow-black",
67
- "data-[disabled]:": "opacity-30",
68
41
  "data-[unavailable]:": "pointer-events-none opacity-50 line-through",
69
42
  "before:": "absolute bottom-[0.6em] w-[1.5em] h-[2px] bg-scope-color-500/75 block",
70
43
  "[&[data-today]::before]:": "content-['']",
@@ -103,9 +76,9 @@ const cardShortcuts = defineShortcuts({ card: `data-[rounded=true]:rounded-$card
103
76
  //#region src/components/Checkbox/shortcuts.ts
104
77
  const checkboxShortcuts = defineShortcuts({
105
78
  "checkbox-root": {
106
- "": "text-body select-none flex gap-$m cursor-default current-bg-scope-color-500 current-border-scope-color-500",
79
+ "": "disabled-soft text-body select-none flex gap-$m cursor-default current-bg-scope-color-500 current-border-scope-color-500",
107
80
  "data-[error=true]:": "current-border-error-500",
108
- "aria-[disabled=true]:": "scope-grey opacity-50 cursor-not-allowed"
81
+ "aria-[disabled=true]:": "scope-grey"
109
82
  },
110
83
  "checkbox": {
111
84
  "": "cursor-default shrink-0 select-none rounded-r0 transition-all transition-duration-100 flex size-1.5em appearance-none items-center justify-center bg-current/0 border-current border-[0.16em] current-icon-white",
@@ -156,12 +129,6 @@ const loadingShortcuts = defineShortcuts({
156
129
  "inner-loading": "bg-white/50 dark:bg-black/50 flex items-center justify-center absolute left-0 top-0 right-0 bottom-0 z-5 cursor-wait"
157
130
  });
158
131
  //#endregion
159
- //#region src/components/Menu/shortcuts.ts
160
- const menuShortcuts = defineShortcuts({
161
- "menu-root": "flex flex-col overflow-hidden",
162
- "menu-item": "justify-start c8-flat gap-$m w-full fw-400"
163
- });
164
- //#endregion
165
132
  //#region src/components/ProgressBar/shortcuts.ts
166
133
  const progressShortcuts = defineShortcuts({
167
134
  "progress-track": {
@@ -190,8 +157,6 @@ const progressShortcuts = defineShortcuts({
190
157
  //#region src/components/shortcuts.ts
191
158
  const shortcuts = [
192
159
  cardShortcuts,
193
- menuShortcuts,
194
- buttonShortcuts,
195
160
  checkboxShortcuts,
196
161
  defineShortcuts({
197
162
  "rb-container": { "": "flex flex-col gap-$s text-body" },
@@ -203,22 +168,22 @@ const shortcuts = [
203
168
  },
204
169
  "rb-item-wrapper": { "": "flex" },
205
170
  "rb-item": {
206
- "": "select-none shrink-0 current-bg-scope-color-500 bg-current/0 size-1.25em rounded-full cursor-default current-border-grey-500 border-current/40 border-[0.16em] transition-none",
171
+ "": "disabled-soft select-none shrink-0 current-bg-scope-color-500 bg-current/0 size-1.25em rounded-full cursor-default current-border-grey-500 border-current/40 border-[0.16em] transition-none",
207
172
  "data-[state=checked]:not-[[data-error='true']]:": "current-border-scope-color-500 border-current",
208
173
  "data-[state=checked]:": "bg-current",
209
174
  "active:enabled:": "bg-current/20",
210
- "aria-[disabled=true]:": "scope-grey opacity-50 cursor-not-allowed",
175
+ "aria-[disabled=true]:": "scope-grey",
211
176
  "data-[error=true]:": "current-border-error-500 current-bg-error-500"
212
177
  },
213
178
  "rb-item-indicator": { "": "flex items-center justify-center w-full h-full rounded-full relative after:content-[''] after:block after:size-[0.5em] after:rounded-[50%] after:bg-white animate-zoom-in animate-duration-100" },
214
179
  "rb-item-label": {
215
- "": "select-none px-$s text-body leading-none lh-1.25em",
216
- "aria-[disabled=true]:": "scope-grey opacity-50 cursor-not-allowed"
180
+ "": "disabled-soft select-none px-$s text-body leading-none lh-1.25em",
181
+ "aria-[disabled=true]:": "scope-grey"
217
182
  }
218
183
  }),
219
184
  defineShortcuts({
220
185
  "select-content": {
221
- "": "min-w-[60px] rounded-r1 surface-0 bg-current overflow-hidden shadow-popup z-[100] current-border-grey-400 border-current/20 ",
186
+ "": "popup-card min-w-[60px]",
222
187
  "data-[design=round]:": "rounded-fingertip-half",
223
188
  "[&>div[data-reka-combobox-viewport]]:": "max-h-[var(--reka-popper-available-height)] [scrollbar-width:auto]",
224
189
  "[&>div[data-reka-combobox-viewport]::-webkit-scrollbar]:": "block"
@@ -230,8 +195,8 @@ const shortcuts = [
230
195
  "[&>span]:": "text-label text-grey-400"
231
196
  },
232
197
  "select-item": {
233
- "": "text-body leading-none flex items-center min-h-fingertip relative select-none relative",
234
- "data-[disabled]:": "opacity-40 pointer-events-none",
198
+ "": "disabled-soft text-body leading-none flex items-center min-h-fingertip relative select-none relative",
199
+ "data-[disabled]:": "pointer-events-none",
235
200
  "data-[highlighted]:": "outline-none bg-scope-color-500/15",
236
201
  "[&>span]:": "px-$m",
237
202
  "group-data-[design=round]:[&>span]:": "px-fingertip-half",
@@ -263,10 +228,35 @@ const shortcuts = [
263
228
  dialogShortcuts,
264
229
  calendarShortcuts,
265
230
  progressShortcuts,
266
- toastShortcuts,
267
- { "shadow-popup": "shadow-[0_0_10px_rgba(0,0,0,0.1),0_4px_20px_rgba(0,0,0,0.15)]" }
231
+ toastShortcuts
268
232
  ];
269
233
  //#endregion
234
+ //#region src/theme/shortcuts/btn.ts
235
+ const btn = defineShortcuts({
236
+ "btn": {
237
+ "": "h-fingertip flex items-center justify-center px-$m gap-$xs select-none fw-bold tracking-wide relative",
238
+ "[&.btn-round]:": "px-fingertip-half rounded-fingertip-half",
239
+ "[&.btn-square]:": "size-fingertip px-0",
240
+ "[&.btn-round.btn-square]:": "px-0",
241
+ "disabled:": "opacity-80 cursor-not-allowed",
242
+ "[&>span]:data-[loading]:": "opacity-0 pointer-events-none",
243
+ "[&>div:not(.loading-indicator-wrapper)]:data-[loading]:": "opacity-0 pointer-events-none",
244
+ "[&>.loading-indicator-wrapper]:": "absolute left-0 top-0 right-0 bottom-0 flex items-center justify-center cursor-wait"
245
+ },
246
+ "btn-square": { "": "" },
247
+ "btn-label": {
248
+ "": "lh-1em ellipsis whitespace-nowrap overflow-x-clip overflow-y-visible",
249
+ "group-[.btn-square]/btn:": "hidden"
250
+ },
251
+ "btn-icon": {
252
+ "": "size-1em font-size-1.25em",
253
+ "group-[.btn-round]/btn:[&.btn-icon-left]:": "ml-[-0.5em]",
254
+ "group-[.btn-round]/btn:[&.btn-icon-right]:": "mr-[-0.5em]",
255
+ "group-[.btn-square]/btn:": "font-size-1.5em m-0!",
256
+ "group-[.btn-round.btn-square]/btn:": "m-0!"
257
+ }
258
+ });
259
+ //#endregion
270
260
  //#region src/theme/shortcuts/c8.ts
271
261
  const c8 = defineShortcuts({
272
262
  "c8-filled": {
@@ -294,6 +284,7 @@ const c8 = defineShortcuts({
294
284
  "active:": "c8-flat-active",
295
285
  "data-[active]:": "c8-flat-active",
296
286
  "data-[selected=true]:": "c8-flat-selected",
287
+ "data-[on=true]:": "c8-flat-selected",
297
288
  "aria-[selected=true]:": "c8-flat-selected",
298
289
  "aria-[pressed=true]:": "c8-flat-selected"
299
290
  },
@@ -322,6 +313,7 @@ const c8 = defineShortcuts({
322
313
  "active:": "c8-chrome-active",
323
314
  "data-[active]:": "c8-chrome-active",
324
315
  "data-[selected=true]:": "c8-chrome-selected",
316
+ "data-[on=true]:": "c8-chrome-selected",
325
317
  "aria-[selected=true]:": "c8-chrome-selected",
326
318
  "aria-[pressed=true]:": "c8-chrome-selected"
327
319
  },
@@ -346,6 +338,7 @@ const c8 = defineShortcuts({
346
338
  "active:": "c8-light-active",
347
339
  "data-[active]:": "c8-light-active",
348
340
  "data-[selected=true]:": "c8-light-hover",
341
+ "data-[on=true]:": "c8-light-hover",
349
342
  "aria-[selected=true]:": "c8-light-hover",
350
343
  "aria-[pressed=true]:": "c8-light-hover"
351
344
  },
@@ -353,10 +346,22 @@ const c8 = defineShortcuts({
353
346
  "c8-light-active": { "not-([disabled]):": "bg-current/30" }
354
347
  });
355
348
  //#endregion
349
+ //#region src/theme/shortcuts/extras.ts
350
+ const popupCard = defineShortcuts({
351
+ "shadow-popup": "shadow-[0_0_10px_rgba(0,0,0,0.1),0_4px_20px_rgba(0,0,0,0.15)]",
352
+ "popup-card": { "": "surface-0 bg-current rounded-r2 overflow-hidden shadow-popup z-[100] border current-border-grey-400 border-current/20" }
353
+ });
354
+ const disabledPaint = "opacity-40 cursor-not-allowed";
355
+ const disabledSoft = defineShortcuts({ "disabled-soft": {
356
+ "disabled:": disabledPaint,
357
+ "aria-[disabled=true]:": disabledPaint,
358
+ "data-[disabled]:": disabledPaint
359
+ } });
360
+ //#endregion
356
361
  //#region src/theme/shortcuts/i8.ts
357
362
  const i8 = defineShortcuts({
358
363
  "i8": {
359
- "": "h-fingertip min-w-3em flex items-center select-none relative icon-current content-box",
364
+ "": "h-fingertip min-w-3em flex items-center select-none relative icon-current content-box disabled-soft",
360
365
  "data-[type=textarea]:": "min-h-fingertip h-auto items-start",
361
366
  "data-[active=true]:": "icon-current-hl",
362
367
  "focus-within:": "icon-current-hl",
@@ -372,9 +377,14 @@ const i8 = defineShortcuts({
372
377
  "data-[active=true]:": "current-border-hl outline i8-apply-outline",
373
378
  "focus-within:": "current-border-hl outline i8-apply-outline"
374
379
  },
375
- "aria-[disabled=true]:": "opacity-50 cursor-not-allowed",
376
380
  "group-[[data-error=true]]/i8:": { "": "current-border-error-500 current-outline-error-500 border-opacity-100 border-current" }
377
381
  },
382
+ "i8-bare": {
383
+ "": "i8-apply-bg i8-apply-border current-outline-hl rounded-r1 outline-none text-current placeholder:text-current/50 disabled-soft",
384
+ "hover:": "border-current-hover",
385
+ "focus:": "current-border-hl outline i8-apply-outline",
386
+ "data-[error=true]:": "current-border-error-500 current-outline-error-500 border-current"
387
+ },
378
388
  "i8-loading": {
379
389
  "": "text-current-icon pl-$m",
380
390
  "last:": "pr-$m"
@@ -469,6 +479,12 @@ const i8 = defineShortcuts({
469
479
  }
470
480
  });
471
481
  //#endregion
482
+ //#region src/theme/shortcuts/menu.ts
483
+ const menu = defineShortcuts({
484
+ "menu-root": "flex flex-col overflow-hidden",
485
+ "menu-item": "justify-start c8-flat gap-$m w-full fw-400"
486
+ });
487
+ //#endregion
472
488
  //#region src/theme/utils/shortcut-obj.ts
473
489
  /**
474
490
  * Build uno shortcut from vunor shortcut object
@@ -527,833 +543,6 @@ const mergeTwoVunorShortcuts = (target, source) => {
527
543
  */
528
544
  const mergeVunorShortcuts = (shortcuts) => shortcuts.reduce((acc, shortcut) => mergeTwoVunorShortcuts(acc, shortcut), {});
529
545
  //#endregion
530
- //#region src/theme/palitra.ts
531
- const defaultOpts = {
532
- colors: {
533
- primary: {
534
- color: "#004eaf",
535
- preserveInputColor: true,
536
- saturate: {
537
- dark: -.2,
538
- light: -.2
539
- }
540
- },
541
- grey: {
542
- color: "#858892",
543
- saturate: {
544
- dark: 0,
545
- light: 0
546
- }
547
- },
548
- secondary: {
549
- color: "#edd812",
550
- vivid: {
551
- dark: .4,
552
- light: .4
553
- }
554
- },
555
- neutral: {
556
- color: "#5da0c5",
557
- vivid: {
558
- dark: .1,
559
- light: .1
560
- }
561
- },
562
- good: {
563
- color: "#7bc76a",
564
- vivid: {
565
- dark: .2,
566
- light: .5
567
- }
568
- },
569
- warn: {
570
- color: "#ef9421",
571
- vivid: {
572
- dark: .2,
573
- light: .3
574
- }
575
- },
576
- error: { color: "#bf5a5f" }
577
- },
578
- lightest: .97,
579
- darkest: .24,
580
- layersDepth: .08,
581
- flatness: 1,
582
- mainPalette: {
583
- preserveInputColor: false,
584
- luminance: {
585
- useMiddle: true,
586
- middle: .62
587
- },
588
- saturate: {
589
- dark: -.25,
590
- light: -.25
591
- },
592
- vivid: {
593
- dark: .1,
594
- light: .2
595
- }
596
- },
597
- layerPalette: {
598
- desaturate: .2,
599
- saturate: {
600
- dark: -.2,
601
- light: -.2
602
- },
603
- vivid: {
604
- dark: 0,
605
- light: 0
606
- }
607
- },
608
- surfaces: {
609
- "0": [
610
- "scope-light-0",
611
- "scope-dark-1",
612
- "scope-color-100",
613
- "scope-dark-0",
614
- "scope-light-1",
615
- "scope-color-800"
616
- ],
617
- "1": [
618
- "scope-light-1",
619
- "scope-dark-1",
620
- "scope-color-100",
621
- "scope-dark-1",
622
- "scope-light-1",
623
- "scope-color-800"
624
- ],
625
- "2": [
626
- "scope-light-2",
627
- "scope-dark-1",
628
- "scope-color-100",
629
- "scope-dark-2",
630
- "scope-light-1",
631
- "scope-color-800"
632
- ],
633
- "3": [
634
- "scope-light-3",
635
- "scope-dark-1",
636
- "scope-color-100",
637
- "scope-dark-3",
638
- "scope-light-1",
639
- "scope-color-800"
640
- ],
641
- "4": [
642
- "scope-light-4",
643
- "scope-dark-1",
644
- "scope-color-100",
645
- "scope-dark-4",
646
- "scope-light-1",
647
- "scope-color-800"
648
- ],
649
- "50": [
650
- "scope-color-50",
651
- "scope-color-700",
652
- "scope-color-200",
653
- "scope-color-900",
654
- "scope-color-200",
655
- "scope-color-500"
656
- ],
657
- "100": [
658
- "scope-color-100",
659
- "scope-color-800",
660
- "scope-color-200",
661
- "scope-color-800",
662
- "scope-color-200",
663
- "scope-color-500"
664
- ],
665
- "200": [
666
- "scope-color-200",
667
- "scope-color-800",
668
- "scope-color-400",
669
- "scope-color-700",
670
- "scope-color-100",
671
- "scope-color-400"
672
- ],
673
- "300": [
674
- "scope-color-300",
675
- "scope-color-900",
676
- "scope-color-500",
677
- "scope-color-600",
678
- "scope-color-100",
679
- "scope-color-300"
680
- ],
681
- "400": [
682
- "scope-color-400",
683
- "scope-color-50",
684
- "scope-color-200",
685
- "scope-color-500",
686
- "scope-color-50",
687
- "scope-color-200"
688
- ],
689
- "500": [
690
- "scope-color-500",
691
- "scope-color-50",
692
- "scope-color-200",
693
- "scope-color-400",
694
- "scope-color-50",
695
- "scope-color-100"
696
- ],
697
- "600": [
698
- "scope-color-600",
699
- "scope-color-100",
700
- "scope-color-300",
701
- "scope-color-300",
702
- "scope-color-900",
703
- "scope-color-700"
704
- ],
705
- "700": [
706
- "scope-color-700",
707
- "scope-color-100",
708
- "scope-color-300",
709
- "scope-color-200",
710
- "scope-color-800",
711
- "scope-color-600"
712
- ],
713
- "800": [
714
- "scope-color-800",
715
- "scope-color-200",
716
- "scope-color-400",
717
- "scope-color-100",
718
- "scope-color-800",
719
- "scope-color-500"
720
- ],
721
- "900": [
722
- "scope-color-900",
723
- "scope-color-200",
724
- "scope-color-400",
725
- "scope-color-50",
726
- "scope-color-700",
727
- "scope-color-500"
728
- ]
729
- }
730
- };
731
- function generatePalette(_opts) {
732
- const _colors = _opts?.colors || {};
733
- for (const key of Object.keys(_colors)) {
734
- const col = _opts?.colors?.[key];
735
- if (typeof col === "string") _colors[key] = { color: col };
736
- }
737
- const opts = defu$1({
738
- ..._opts,
739
- colors: _colors
740
- }, defaultOpts);
741
- const bgOptions = {
742
- count: 5,
743
- preserveInputColor: false,
744
- flatness: opts.layerPalette.flatness ?? opts.flatness,
745
- luminance: {
746
- dark: opts.layerPalette.luminance?.dark ?? opts.darkest,
747
- light: opts.layerPalette.luminance?.light ?? opts.darkest + opts.layersDepth,
748
- useMiddle: false
749
- },
750
- saturate: opts.layerPalette.saturate,
751
- vivid: opts.layerPalette.vivid,
752
- suffixes: [
753
- "dark-0",
754
- "dark-1",
755
- "dark-2",
756
- "dark-3",
757
- "dark-4"
758
- ]
759
- };
760
- const darks = palitra(multiplySaturation(opts.colors, opts.layerPalette.desaturate), bgOptions).toStrings();
761
- bgOptions.suffixes = [
762
- "light-0",
763
- "light-1",
764
- "light-2",
765
- "light-3",
766
- "light-4"
767
- ].toReversed();
768
- const lumDark = bgOptions.luminance?.dark ?? opts.darkest;
769
- bgOptions.luminance = {
770
- dark: 1 - ((bgOptions.luminance?.light ?? opts.darkest + opts.layersDepth) - lumDark),
771
- light: 1,
772
- useMiddle: false
773
- };
774
- const lights = palitra(multiplySaturation(opts.colors, opts.layerPalette.desaturate), bgOptions).toStrings();
775
- const colors = palitra({
776
- primary: opts.colors.primary,
777
- grey: opts.colors.grey,
778
- secondary: opts.colors.secondary,
779
- neutral: opts.colors.neutral,
780
- good: opts.colors.good,
781
- warn: opts.colors.warn,
782
- error: opts.colors.error
783
- }, {
784
- count: 10,
785
- preserveInputColor: opts.mainPalette.preserveInputColor,
786
- flatness: opts.mainPalette.flatness ?? opts.flatness,
787
- luminance: {
788
- dark: opts.mainPalette.luminance?.dark ?? opts.darkest + opts.layersDepth + .02,
789
- light: opts.mainPalette.luminance?.light ?? opts.lightest,
790
- useMiddle: opts.mainPalette.luminance?.useMiddle,
791
- middle: opts.mainPalette.luminance?.middle
792
- },
793
- saturate: opts.mainPalette.saturate,
794
- vivid: opts.mainPalette.vivid
795
- }).toStrings();
796
- return {
797
- opts,
798
- colors: {
799
- ...darks,
800
- ...lights,
801
- ...colors
802
- },
803
- surfaces: opts.surfaces
804
- };
805
- }
806
- function multiplySaturation(colors, m = .5) {
807
- const newObj = {};
808
- for (const [key, val] of Object.entries(colors)) {
809
- const col = typeof val === "string" ? val : val.color;
810
- if (col) {
811
- const [h, s, l] = color(col).hsl();
812
- newObj[key] = color(h, s * m, l, "hsl").hex();
813
- }
814
- }
815
- return newObj;
816
- }
817
- const layerN = (n, reverse) => reverse ? 4 - n : n;
818
- function getPaletteShortcuts() {
819
- return [
820
- [/^layer-([0-4])$/, ([, a], { theme }) => {
821
- const d = layerN(Number(a), theme.reverseDarkLayers);
822
- return toUnoShortcut({
823
- "": `current-bg-scope-light-${layerN(Number(a), theme.reverseLightLayers)} current-text-scope-dark-2 current-icon-scope-dark-2 current-border-grey-500 bg-current text-current`,
824
- "dark:": `current-bg-scope-dark-${d} current-text-scope-light-2 current-icon-scope-light-2`,
825
- "[&.dark]:": `current-bg-scope-dark-${d} current-text-scope-light-2 current-icon-scope-light-2`
826
- });
827
- }],
828
- [/^(bg|text|current-text|current-bg|current-icon|current-border|current-outline|current-caret|current-hl|i8-bg|i8-border|i8-outline)-layer-([0-4])$/, ([, target, a], { theme }) => {
829
- const d = layerN(Number(a), theme.reverseDarkLayers);
830
- return toUnoShortcut({
831
- "": `${target}-scope-light-${layerN(Number(a), theme.reverseLightLayers)}`,
832
- "dark:": `${target}-scope-dark-${d}`,
833
- "[&.dark]:": `${target}-scope-dark-${d}`
834
- });
835
- }],
836
- [/^surface-(.+)$/, ([, s], { theme }) => theme.surfaces[s] ? toUnoShortcut({
837
- "": `current-bg-${theme.surfaces[s][0]} current-text-${theme.surfaces[s][1]} current-icon-${theme.surfaces[s][1]} current-border-${theme.surfaces[s][2]} bg-current text-current border-current icon-current`,
838
- "dark:": `current-bg-${theme.surfaces[s][3]} current-text-${theme.surfaces[s][4]} current-icon-${theme.surfaces[s][4]} current-border-${theme.surfaces[s][5]} shadow-black/30`,
839
- "[&.dark]:": `current-bg-${theme.surfaces[s][3]} current-text-${theme.surfaces[s][4]} current-icon-${theme.surfaces[s][4]} current-border-${theme.surfaces[s][5]} shadow-black/30`
840
- }) : ""],
841
- { surface: "surface-100" }
842
- ];
843
- }
844
- //#endregion
845
- //#region src/theme/rules/palette.ts
846
- function colorToRgbWithOpacity(c) {
847
- const [r, g, b, _a] = color(c).rgba();
848
- return `${r} ${g} ${b}`;
849
- }
850
- function getOpacityVar(key) {
851
- return {
852
- bg: "--un-bg-opacity",
853
- text: "--un-text-opacity",
854
- fill: "--un-text-opacity",
855
- stroke: "--un-text-opacity",
856
- icon: "--un-icon-opacity",
857
- border: "--un-border-opacity",
858
- outline: "--un-outline-opacity",
859
- caret: "--un-caret-opacity",
860
- shadow: "--un-shadow-opacity",
861
- ring: "--un-ring-opacity"
862
- }[key];
863
- }
864
- function getCssTarget(key) {
865
- return {
866
- bg: "background-color",
867
- text: "color",
868
- fill: "fill",
869
- stroke: "stroke",
870
- icon: "color",
871
- border: "border-color",
872
- outline: "outline-color",
873
- caret: "caret-color",
874
- shadow: "--un-shadow-color",
875
- ring: "--un-ring-color"
876
- }[key];
877
- }
878
- const SCOPE_SHADES = [
879
- "50",
880
- "100",
881
- "200",
882
- "300",
883
- "400",
884
- "500",
885
- "600",
886
- "700",
887
- "800",
888
- "900"
889
- ];
890
- const SCOPE_LAYERS = [
891
- "0",
892
- "1",
893
- "2",
894
- "3",
895
- "4"
896
- ];
897
- function getScopeCssVars(c, theme) {
898
- const col = theme.colors[c];
899
- if (!col) return;
900
- const vars = { "--scope-color": colorToRgbWithOpacity(col) };
901
- for (const shade of SCOPE_SHADES) vars[`--scope-color-${shade}`] = colorToRgbWithOpacity(theme.colors[`${c}-${shade}`]) || "";
902
- for (const layer of SCOPE_LAYERS) {
903
- vars[`--scope-light-${layer}`] = colorToRgbWithOpacity(theme.colors[`${c}-light-${layer}`]) || "";
904
- vars[`--scope-dark-${layer}`] = colorToRgbWithOpacity(theme.colors[`${c}-dark-${layer}`]) || "";
905
- }
906
- vars["--current-hl"] = colorToRgbWithOpacity(theme.colors[`${c}-500`]) || "";
907
- return vars;
908
- }
909
- const paletteRules = [
910
- [/^current-(text|bg|icon|border|outline|caret|hl)-(.+)$/, (match, { theme }) => {
911
- const t = match[1];
912
- const c = match[2];
913
- if (c.startsWith("scope-")) return { [`--current-${t}`]: `var(--${c})` };
914
- if (c === "hl") return { [`--current-${t}`]: `var(--current-hl)` };
915
- const col = theme.colors[c] || c;
916
- if (col) return { [`--current-${t}`]: colorToRgbWithOpacity(col.DEFAULT || col) };
917
- }],
918
- [/^(text|bg|icon|border|outline|caret|fill|shadow|ring)-current(-text|-bg|-icon|-border|-outline|-caret|-hl)?(\/\d{1,3})?$/, (match, { theme: _theme }) => {
919
- const target = match[1];
920
- const source = match[2] || `-${target}`;
921
- const opacityVar = getOpacityVar(target);
922
- const cssVar = getCssTarget(target);
923
- const o = match[3];
924
- const opacity = o ? Number(o.slice(1)) / 100 : 1;
925
- const opacityVal = opacity === 1 ? `var(${opacityVar})` : opacity;
926
- if (target === "icon") return {
927
- [opacityVar]: opacity,
928
- "--current-icon": source === "-hl" ? `var(--current${source})` : void 0
929
- };
930
- if (["shadow", "ring"].includes(target) && source === "-border") return {
931
- [opacityVar]: opacity === 1 ? `var(--un-border-opacity)` : opacity,
932
- [`--un-${target}-color`]: `rgb(var(--current-border) / ${opacityVal})`
933
- };
934
- return {
935
- [opacityVar]: opacity,
936
- [cssVar]: `rgb(var(--current${source}) / ${opacityVal})`
937
- };
938
- }],
939
- [/^scope-(.*)$/, (match, { theme }) => getScopeCssVars(match[1], theme)],
940
- [/^(bg|text|fill|stroke|border|outline|icon|caret)-scope-((?:color|dark|light|text|bg|white|black|icon)(?:-\d+)?)(\/\d{1,3})?$/, (match, { theme }) => {
941
- const cssVar = getCssTarget(match[1]);
942
- const opacityVar = getOpacityVar(match[1]);
943
- const source = match[2];
944
- const o = match[3];
945
- const opacity = o ? Number(o.slice(1)) / 100 : 1;
946
- const fallback = source.startsWith("color") ? `grey-${source.slice(6)}` : `grey-${source}`;
947
- const opacityVal = opacity === 1 ? `var(${opacityVar})` : opacity;
948
- return {
949
- [opacityVar]: opacity,
950
- [cssVar]: `rgb(var(--scope-${source}, ${theme.colors[fallback] || ""}) / ${opacityVal})`
951
- };
952
- }],
953
- [/^icon-opacity-(\d{1,3})$/, (match, { theme: _theme }) => {
954
- const o = match[1];
955
- return { "--un-icon-opacity": Number(o) / 100 };
956
- }],
957
- [/^icon-color$/, () => ({ color: `rgb(var(--current-icon) / var(--un-icon-opacity, 1))` })],
958
- [/^icon-size-(.*)$/, (match, { theme }) => {
959
- const name = match[1];
960
- if (name.startsWith("[") && name.endsWith("]")) return { "--icon-size": name.slice(1, -1) };
961
- if (theme.spacing[name]) return { "--icon-size": theme.spacing[name] };
962
- }],
963
- [/^icon-size$/, () => ({
964
- width: `var(--icon-size, 1em)`,
965
- height: `var(--icon-size, 1em)`
966
- })]
967
- ];
968
- //#endregion
969
- //#region src/theme/utils/round.ts
970
- function round(v, decimals = 0) {
971
- const d = 10 ** decimals;
972
- return Math.round(v * d) / d;
973
- }
974
- //#endregion
975
- //#region src/theme/utils/unit-by.ts
976
- function unitBy(input, factor, roundTo = 3) {
977
- const v = Number.parseFloat(input);
978
- const units = /(px|em|rem|%)$/.exec(input)?.[1] || "";
979
- return `${round(v * factor, roundTo)}${units}`;
980
- }
981
- //#endregion
982
- //#region src/theme/preflights.ts
983
- const fontsPreflights = { getCSS: ({ theme }) => `${renderFontCss("body", theme.fontSize.body) + renderFontCss("figcaption", theme.fontSize.caption) + renderFontCss("h1", theme.fontSize.h1) + renderFontCss("h2", theme.fontSize.h2) + renderFontCss("h3", theme.fontSize.h3) + renderFontCss("h4", theme.fontSize.h4) + renderFontCss("h5", theme.fontSize.h5) + renderFontCss("h6", theme.fontSize.h6)}
984
- :root {
985
- --un-border-opacity: 0.25;
986
- --un-default-border-color: rgb(150 150 150 / var(--un-border-opacity));
987
- --scope-black: 0 0 0;
988
- --scope-white: 255 255 255;
989
- --scope-hl: var(--scope-color-500);
990
- --v-fingertip: ${theme.spacing["fingertip-m"] || "3em"};
991
- --v-fingertip-half: ${unitBy(theme.spacing["fingertip-m"] || "3em", .5)};
992
- ${renderDefaultScope(theme)}}
993
-
994
-
995
- ::-webkit-scrollbar {
996
- width: 10px;
997
- height: 10px;
998
- }
999
-
1000
- ::-webkit-scrollbar-track {
1001
- background: rgba(0,0,0,0.05);
1002
- border-radius: 5px;
1003
- }
1004
-
1005
- ::-webkit-scrollbar-thumb {
1006
- background-color: rgba(0,0,0,0.2);
1007
- border-radius: 5px;
1008
- border: 2px solid transparent;
1009
- background-clip: padding-box;
1010
- }
1011
-
1012
- ::-webkit-scrollbar-thumb:hover {
1013
- background-color: rgba(0,0,0,0.3);
1014
- }
1015
-
1016
-
1017
- .dark ::-webkit-scrollbar-track {
1018
- background: rgba(255,255,255,0.05);
1019
- }
1020
-
1021
- .dark ::-webkit-scrollbar-thumb {
1022
- background-color: rgba(255,255,255,0.2);
1023
- }
1024
-
1025
- .dark ::-webkit-scrollbar-thumb:hover {
1026
- background-color: rgba(255,255,255,0.3);
1027
- }
1028
- ` };
1029
- function renderDefaultScope(theme) {
1030
- const vars = getScopeCssVars("neutral", theme);
1031
- if (!vars) return "";
1032
- return `${Object.entries(vars).map(([k, v]) => ` ${k}: ${v};`).join("\n")}\n`;
1033
- }
1034
- function renderFontCss(selector, font) {
1035
- return `${selector} { font-size: ${font[0]}; ${Object.entries(font[1]).map((e) => `${e[0]}: ${e[1]};`).join(" ")} }\n`;
1036
- }
1037
- //#endregion
1038
- //#region src/theme/rules/i8-rules.ts
1039
- const i8Rules = [
1040
- [/^i8-(border|outline|bg)-(.+)$/, (match, { theme }) => {
1041
- const target = match[1];
1042
- const value = match[2];
1043
- if (value === "none") return { [`--i8-${target}-width`]: "0" };
1044
- if (value === "transparent") return { [`--i8-${target}-color`]: "0" };
1045
- if (value.startsWith("scope-")) return { [`--i8-${target}-color`]: `var(--${value})` };
1046
- const col = theme.colors[value];
1047
- if (col) return { [`--i8-${target}-color`]: colorToRgbWithOpacity(String(col.DEFAULT || col)) };
1048
- const width = theme.spacing[value];
1049
- if (width) return { [`--i8-${target}-width`]: width };
1050
- if (value.endsWith("px") || value.endsWith("em") || value.endsWith("rem")) return { [`--i8-${target}-width`]: value };
1051
- if (value.startsWith("[") && value.endsWith("]")) {
1052
- const v = value.slice(1, -1);
1053
- if (v.endsWith("px") || v.endsWith("em") || v.endsWith("rem")) return { [`--i8-${target}-width`]: v };
1054
- return { [`--i8-${target}-color`]: v };
1055
- }
1056
- }],
1057
- [/^i8-(border|outline|bg)-opacity-(\d{1,3})$/, (match, { theme: _theme }) => {
1058
- const target = match[1];
1059
- const value = match[2];
1060
- return { [`--i8-${target}-opacity`]: Number(value) / 100 };
1061
- }],
1062
- [/^i8-apply-(border|outline|bg)$/, (match, { theme: _theme }) => {
1063
- const target = match[1];
1064
- const prop = {
1065
- border: "border-color",
1066
- outline: "outline-color",
1067
- bg: "background-color"
1068
- }[target];
1069
- const variable = {
1070
- border: "--i8-border-color, var(--current-border)",
1071
- outline: "--i8-outline-color, var(--current-outline)",
1072
- bg: "--i8-bg-color, var(--current-bg)"
1073
- }[target];
1074
- const op = {
1075
- border: `--i8-border-opacity, 0.2`,
1076
- outline: `--i8-outline-opacity, 0.5`,
1077
- bg: "--i8-bg-opacity, 1"
1078
- }[target];
1079
- return target === "bg" ? { [prop]: `rgb(var(${variable}) / var(${op}))` } : {
1080
- [prop]: `rgb(var(${variable}) / var(${op}))`,
1081
- [`${target}-width`]: `var(--i8-${target}-width, ${target === "border" ? 1 : 2}px)`
1082
- };
1083
- }]
1084
- ];
1085
- //#endregion
1086
- //#region src/theme/rules/index.ts
1087
- const rules = [
1088
- ...[
1089
- [
1090
- /^text-m([bty])?-(.*)$/,
1091
- (match, { theme }) => {
1092
- const dir = match[1];
1093
- const size = match[2];
1094
- const d = dir ? {
1095
- y: ["top", "bottom"],
1096
- t: ["top"],
1097
- b: ["bottom"]
1098
- }[dir] : [
1099
- "top",
1100
- "bottom",
1101
- "left",
1102
- "right"
1103
- ];
1104
- const result = {};
1105
- if (theme.spacing[size]) {
1106
- for (const prop of d) result[`margin-${prop}`] = ["left", "right"].includes(prop) ? theme.spacing[size] : `calc(${theme.spacing[size]} + var(--font-${prop === "top" ? "tc" : "bc"}))`;
1107
- return result;
1108
- } else if (/^\d+(em|rem|px)?$/.test(size)) {
1109
- let s = size;
1110
- if (/^[\d.]+$/.test(size)) s = `${Number(size) * .25}rem`;
1111
- for (const prop of d) result[`margin-${prop}`] = ["left", "right"].includes(prop) ? s : `calc(${s} + var(--font-${prop === "top" ? "tc" : "bc"}))`;
1112
- return result;
1113
- }
1114
- },
1115
- { layer: "utilities" }
1116
- ],
1117
- [
1118
- /^card-dense$/,
1119
- (_match, { theme: _theme }) => ({ "--card-spacing": "var(--card-spacing-dense)" }),
1120
- { layer: "utilities" }
1121
- ],
1122
- [/^card-(.*)$/, (match, { theme }) => {
1123
- const name = match[1];
1124
- if (theme.fontSize[name]) {
1125
- const props = theme.fontSize[name][1];
1126
- return {
1127
- "--card-spacing": `${unitBy(props["--font-corrected"], theme.cardSpacingFactor.regular)}`,
1128
- "--card-spacing-dense": `${unitBy(props["--font-corrected"], theme.cardSpacingFactor.dense)}`,
1129
- "--card-heading-size": props["--font-size"],
1130
- "--card-heading-bold": props["--font-bold"],
1131
- "--card-heading-corrected": props["--font-corrected"],
1132
- "--card-heading-weight": props["font-weight"],
1133
- "--card-heading-lh": props["line-height"],
1134
- "--card-heading-ls": props["letter-spacing"],
1135
- "--card-heading-bc": props["--font-bc"],
1136
- "--card-heading-tc": props["--font-tc"],
1137
- "padding": "var(--card-spacing)"
1138
- };
1139
- }
1140
- }],
1141
- [/^fingertip-(.*)/, (match, { theme }) => {
1142
- const name = match[1];
1143
- if (name.startsWith("[") && name.endsWith("]")) return {
1144
- "--v-fingertip": name.slice(1, -1),
1145
- "--v-fingertip-half": unitBy(name.slice(1, -1), .5)
1146
- };
1147
- if ([
1148
- "xs",
1149
- "s",
1150
- "m",
1151
- "l",
1152
- "xl"
1153
- ].includes(name)) return {
1154
- "--v-fingertip": theme.spacing[`fingertip-${name}`],
1155
- "--v-fingertip-half": unitBy(theme.spacing[`fingertip-${name}`], .5)
1156
- };
1157
- if (theme.spacing[name]) return {
1158
- "--v-fingertip": theme.spacing[name],
1159
- "--v-fingertip-half": unitBy(theme.spacing[name], .5)
1160
- };
1161
- }]
1162
- ],
1163
- ...paletteRules,
1164
- ...i8Rules
1165
- ];
1166
- //#endregion
1167
- //#region src/theme/types.ts
1168
- function k$1(n, base = 1) {
1169
- return base * 1.618 ** n;
1170
- }
1171
- //#endregion
1172
- //#region src/theme/typography.ts
1173
- function font(weight, boldWeight, size, height, spacing) {
1174
- return {
1175
- weight,
1176
- boldWeight,
1177
- size,
1178
- height,
1179
- spacing
1180
- };
1181
- }
1182
- const defaultTypography = {
1183
- "h1": font(400, 700, k$1(3.5), k$1(.5), -.025),
1184
- "h2": font(400, 700, k$1(2.5), k$1(.5), -.022),
1185
- "h3": font(400, 700, k$1(2), k$1(.5), -.022),
1186
- "h4": font(400, 600, k$1(1), k$1(.5), -.02),
1187
- "h5": font(400, 600, k$1(.5), k$1(.5), -.017),
1188
- "h6": font(600, 700, k$1(.25), k$1(.5), -.014),
1189
- "subheading": font(400, 600, k$1(-.2), k$1(.5), -.007),
1190
- "body-l": font(400, 600, k$1(.5), k$1(.75), -.014),
1191
- "body": font(400, 600, k$1(0), k$1(.75), -.011),
1192
- "body-s": font(400, 600, k$1(-.5), k$1(1), 0),
1193
- "callout": font(400, 600, k$1(-.25), k$1(.5), -.009),
1194
- "label": font(500, 700, k$1(-.25), k$1(.5), -.004),
1195
- "caption": font(400, 600, k$1(-.5), k$1(.5), -.007),
1196
- "overline": font(400, 600, k$1(-.5), k$1(.5), .0618)
1197
- };
1198
- function buildFontTheme(size, w, wBold, lh, ls, actualFontHeightFactor = 1, actualFontHeightTopBottomRatio = .5) {
1199
- const correctedSize = size * actualFontHeightFactor;
1200
- const m = (lh * size - correctedSize) / size;
1201
- const half = correctedSize / 2;
1202
- const offt = correctedSize * actualFontHeightTopBottomRatio - half + m / 2;
1203
- const offb = correctedSize * (1 - actualFontHeightTopBottomRatio) - half + m / 2;
1204
- const mt = round(offt, 4);
1205
- const mb = round(offb, 4);
1206
- return {
1207
- mt,
1208
- mb,
1209
- size,
1210
- correctedSize,
1211
- theme: [`${size}em`, {
1212
- "--font-bold": wBold,
1213
- "--font-size": `${size}em`,
1214
- "--font-corrected": `${correctedSize}em`,
1215
- "--font-bc": `${-mb}em`,
1216
- "--font-tc": `${-mt}em`,
1217
- "font-weight": w,
1218
- "line-height": `${lh}em`,
1219
- "letter-spacing": `${ls}em`
1220
- }]
1221
- };
1222
- }
1223
- //#endregion
1224
- //#region src/theme/utils/radius-scale.ts
1225
- const ROOT_FONT_PX = 16;
1226
- function parseRadius(input) {
1227
- const m = input.trim().match(/^(-?\d*\.?\d+)(px|em|rem)?$/);
1228
- if (!m) return null;
1229
- const n = Number.parseFloat(m[1]);
1230
- if (!Number.isFinite(n)) return null;
1231
- return {
1232
- n,
1233
- unit: m[2] ?? ""
1234
- };
1235
- }
1236
- function computeRadiusScale(baseRadius) {
1237
- const parsed = parseRadius(baseRadius);
1238
- if (!parsed) return {
1239
- r0: `min(${baseRadius}, clamp(2px, calc(${baseRadius} / 2), 4px))`,
1240
- r1: baseRadius,
1241
- r2: `calc(${baseRadius} * 1.5)`,
1242
- r3: `calc(${baseRadius} * 2)`,
1243
- r4: `calc(${baseRadius} * 2.5)`
1244
- };
1245
- const { n, unit } = parsed;
1246
- if (n === 0) return {
1247
- r0: "0",
1248
- r1: "0",
1249
- r2: "0",
1250
- r3: "0",
1251
- r4: "0"
1252
- };
1253
- const basePx = unit === "em" || unit === "rem" ? n * ROOT_FONT_PX : n;
1254
- const r0Px = Math.min(basePx, Math.max(2, Math.min(basePx / 2, 4)));
1255
- const scaled = unit ? baseRadius : `${n}px`;
1256
- return {
1257
- r0: `${round(r0Px, 3)}px`,
1258
- r1: baseRadius,
1259
- r2: unitBy(scaled, 1.5),
1260
- r3: unitBy(scaled, 2),
1261
- r4: unitBy(scaled, 2.5)
1262
- };
1263
- }
1264
- //#endregion
1265
- //#region src/theme/theme.ts
1266
- const themeFactory = (opts) => {
1267
- /**
1268
- * Spacing
1269
- */
1270
- const spacing = {
1271
- "$xxs": `${round(1 / opts.spacingFactor ** 3, 3)}em`,
1272
- "$xs": `${round(1 / opts.spacingFactor ** 2, 3)}em`,
1273
- "$s": `${round(1 / opts.spacingFactor, 3)}em`,
1274
- "$m": "1em",
1275
- "$l": `${round(opts.spacingFactor, 3)}em`,
1276
- "$xl": `${round(opts.spacingFactor ** 2, 3)}em`,
1277
- "$xxl": `${round(opts.spacingFactor ** 3, 3)}em`,
1278
- "fingertip": "var(--v-fingertip)",
1279
- "fingertip-half": "var(--v-fingertip-half)",
1280
- "fingertip-xs": opts.fingertip.xs,
1281
- "fingertip-s": opts.fingertip.s,
1282
- "fingertip-m": opts.fingertip.m,
1283
- "fingertip-l": opts.fingertip.l,
1284
- "fingertip-xl": opts.fingertip.xl,
1285
- "$font-tc": "var(--font-bc)",
1286
- "$font-bc": "var(--font-tc)",
1287
- "$font-size": "var(--font-size)",
1288
- "$font-corrected": "var(--font-corrected)",
1289
- "$card-spacing": "var(--card-spacing)",
1290
- "$card-spacing-dense": "var(--card-spacing-dense)",
1291
- "$card-heading-size": "var(--card-heading-size)",
1292
- "$card-heading-corrected": "var(--card-heading-corrected)",
1293
- "base-radius": opts.baseRadius
1294
- };
1295
- const lineHeight = {
1296
- "fingertip": "var(--v-fingertip)",
1297
- "fingertip-half": "var(--v-fingertip-half)",
1298
- "fingertip-xs": opts.fingertip.xs,
1299
- "fingertip-s": opts.fingertip.s,
1300
- "fingertip-m": opts.fingertip.m,
1301
- "fingertip-l": opts.fingertip.l,
1302
- "fingertip-xl": opts.fingertip.xl
1303
- };
1304
- const borderRadius = {
1305
- ...spacing,
1306
- base: opts.baseRadius,
1307
- ...computeRadiusScale(opts.baseRadius)
1308
- };
1309
- /**
1310
- * Typography
1311
- */
1312
- const fontWeight = { $bold: "var(--font-bold)" };
1313
- const fontSize = { "card-header": ["var(--card-heading-size)", {
1314
- "--font-bold": "var(--card-heading-bold)",
1315
- "--font-size": "var(--card-heading-size)",
1316
- "--font-corrected": "var(--card-heading-corrected)",
1317
- "--font-bc": "var(--card-heading-bc)",
1318
- "--font-tc": "var(--card-heading-tc)",
1319
- "font-weight": "var(--card-heading-weight)",
1320
- "line-height": "var(--card-heading-lh)",
1321
- "letter-spacing": "var(--card-heading-ls)"
1322
- }] };
1323
- for (const [name, val] of Object.entries(opts.typography)) if (val?.size) {
1324
- const ft = buildFontTheme(val.size || 1, val.weight || 400, val.boldWeight || 700, val.height || 1, val.spacing || 0, val.actualHeightFactor || opts.actualFontHeightFactor, val.actualHeightTopBottomRatio || opts.actualFontHeightTopBottomRatio);
1325
- fontSize[name] = ft.theme;
1326
- spacing[name] = `${ft.size}em`;
1327
- }
1328
- const palette = generatePalette(opts.palette);
1329
- /**
1330
- * Putting all together
1331
- */
1332
- return {
1333
- paletteOpts: palette.opts,
1334
- theme: {
1335
- colors: palette.colors,
1336
- surfaces: palette.surfaces,
1337
- reverseLightLayers: opts.layers.reverseLight,
1338
- reverseDarkLayers: opts.layers.reverseDark,
1339
- lineHeight,
1340
- spacing,
1341
- fontWeight,
1342
- actualFontHeightFactor: opts.actualFontHeightFactor,
1343
- cardSpacingFactor: opts.cardSpacingFactor,
1344
- fontSize,
1345
- width: spacing,
1346
- height: spacing,
1347
- maxWidth: spacing,
1348
- maxHeight: spacing,
1349
- minWidth: spacing,
1350
- minHeight: spacing,
1351
- borderRadius,
1352
- animation: opts.animation
1353
- }
1354
- };
1355
- };
1356
- //#endregion
1357
546
  //#region src/theme/generated/component-classes.ts
1358
547
  const componentClasses = {
1359
548
  AppLayout: [
@@ -1391,9 +580,6 @@ const componentClasses = {
1391
580
  AppToasts: [
1392
581
  "[grid-area:_action]",
1393
582
  "[grid-area:_title]",
1394
- "btn",
1395
- "btn-icon",
1396
- "btn-label",
1397
583
  "c8-flat",
1398
584
  "fw-$bold",
1399
585
  "icon-color",
@@ -1406,27 +592,18 @@ const componentClasses = {
1406
592
  "toasts-viewport"
1407
593
  ],
1408
594
  Button: [
1409
- "btn",
1410
- "btn-icon",
1411
- "btn-label",
1412
595
  "icon-color",
1413
596
  "icon-size",
1414
597
  "loading-indicator",
1415
598
  "loading-indicator-ring"
1416
599
  ],
1417
600
  ButtonBase: [
1418
- "btn",
1419
- "btn-icon",
1420
- "btn-label",
1421
601
  "icon-color",
1422
602
  "icon-size",
1423
603
  "loading-indicator",
1424
604
  "loading-indicator-ring"
1425
605
  ],
1426
606
  Calendar: [
1427
- "btn",
1428
- "btn-icon",
1429
- "btn-label",
1430
607
  "c8-flat",
1431
608
  "calendar-cell",
1432
609
  "calendar-grid-row",
@@ -1573,9 +750,6 @@ const componentClasses = {
1573
750
  "absolute",
1574
751
  "blur",
1575
752
  "bottom-0",
1576
- "btn",
1577
- "btn-icon",
1578
- "btn-label",
1579
753
  "c8-flat",
1580
754
  "calendar-cell",
1581
755
  "calendar-grid-row",
@@ -1646,9 +820,6 @@ const componentClasses = {
1646
820
  "absolute",
1647
821
  "blur",
1648
822
  "bottom-0",
1649
- "btn",
1650
- "btn-icon",
1651
- "btn-label",
1652
823
  "c8-flat",
1653
824
  "calendar-cell",
1654
825
  "calendar-grid-row",
@@ -1706,9 +877,6 @@ const componentClasses = {
1706
877
  "px-0"
1707
878
  ],
1708
879
  DatePickerPopup: [
1709
- "btn",
1710
- "btn-icon",
1711
- "btn-label",
1712
880
  "c8-flat",
1713
881
  "calendar-cell",
1714
882
  "calendar-grid-row",
@@ -1737,16 +905,12 @@ const componentClasses = {
1737
905
  DevTools: [
1738
906
  "[&>.checkbox]:hover:bg-neutral-100",
1739
907
  "absolute",
1740
- "b",
1741
908
  "bg-transparent",
1742
909
  "border",
1743
910
  "border-0",
1744
911
  "border-b",
1745
912
  "border-grey-500/30",
1746
913
  "border-grey-500/50",
1747
- "btn",
1748
- "btn-icon",
1749
- "btn-label",
1750
914
  "c8-flat",
1751
915
  "card",
1752
916
  "checkbox",
@@ -1854,9 +1018,6 @@ const componentClasses = {
1854
1018
  ],
1855
1019
  Dialog: [
1856
1020
  "b",
1857
- "btn",
1858
- "btn-icon",
1859
- "btn-label",
1860
1021
  "c8-filled",
1861
1022
  "c8-flat",
1862
1023
  "card",
@@ -1982,9 +1143,6 @@ const componentClasses = {
1982
1143
  "b",
1983
1144
  "blur",
1984
1145
  "bottom-0",
1985
- "btn",
1986
- "btn-icon",
1987
- "btn-label",
1988
1146
  "cursor-pointer",
1989
1147
  "flex",
1990
1148
  "flex-grow",
@@ -2018,8 +1176,6 @@ const componentClasses = {
2018
1176
  "loading-indicator-ring",
2019
1177
  "max-w-100%",
2020
1178
  "mb-$s",
2021
- "menu-item",
2022
- "menu-root",
2023
1179
  "overflow-hidden",
2024
1180
  "overflow-x-hidden",
2025
1181
  "overflow-y-auto",
@@ -2044,22 +1200,15 @@ const componentClasses = {
2044
1200
  "whitespace-nowrap"
2045
1201
  ],
2046
1202
  MenuItem: [
2047
- "btn",
2048
- "btn-icon",
2049
- "btn-label",
2050
1203
  "icon-color",
2051
1204
  "icon-size",
2052
1205
  "loading-indicator",
2053
1206
  "loading-indicator-ring",
2054
- "menu-item",
2055
1207
  "scope-grey"
2056
1208
  ],
2057
1209
  OverflowContainer: ["flex", "whitespace-nowrap"],
2058
1210
  Pagination: [
2059
- "btn",
2060
- "btn-icon",
2061
1211
  "c8-flat",
2062
- "disabled:opacity-30",
2063
1212
  "flex",
2064
1213
  "gap-1",
2065
1214
  "icon-color",
@@ -2071,9 +1220,6 @@ const componentClasses = {
2071
1220
  "size-fingertip"
2072
1221
  ],
2073
1222
  Popover: [
2074
- "btn",
2075
- "btn-icon",
2076
- "btn-label",
2077
1223
  "icon-color",
2078
1224
  "icon-size",
2079
1225
  "loading-indicator",
@@ -2195,24 +1341,899 @@ const componentClasses = {
2195
1341
  "text-label",
2196
1342
  "whitespace-nowrap"
2197
1343
  ],
2198
- Tabs: [
2199
- "c8-flat",
2200
- "flex",
2201
- "grow",
2202
- "relative",
2203
- "tab",
2204
- "tabs-indicator"
2205
- ]
1344
+ Tabs: [
1345
+ "c8-flat",
1346
+ "flex",
1347
+ "grow",
1348
+ "relative",
1349
+ "tab",
1350
+ "tabs-indicator"
1351
+ ]
1352
+ };
1353
+ function getComponentClasses(...components) {
1354
+ const set = /* @__PURE__ */ new Set();
1355
+ for (const name of components) {
1356
+ const key = name.startsWith("Vu") ? name.slice(2) : name;
1357
+ for (const cls of componentClasses[key] ?? []) set.add(cls);
1358
+ }
1359
+ return [...set];
1360
+ }
1361
+ //#endregion
1362
+ //#region src/theme/palitra.ts
1363
+ const defaultOpts = {
1364
+ colors: {
1365
+ primary: {
1366
+ color: "#004eaf",
1367
+ preserveInputColor: true,
1368
+ saturate: {
1369
+ dark: -.2,
1370
+ light: -.2
1371
+ }
1372
+ },
1373
+ grey: {
1374
+ color: "#858892",
1375
+ saturate: {
1376
+ dark: 0,
1377
+ light: 0
1378
+ }
1379
+ },
1380
+ secondary: {
1381
+ color: "#edd812",
1382
+ vivid: {
1383
+ dark: .4,
1384
+ light: .4
1385
+ }
1386
+ },
1387
+ neutral: {
1388
+ color: "#5da0c5",
1389
+ vivid: {
1390
+ dark: .1,
1391
+ light: .1
1392
+ }
1393
+ },
1394
+ good: {
1395
+ color: "#7bc76a",
1396
+ vivid: {
1397
+ dark: .2,
1398
+ light: .5
1399
+ }
1400
+ },
1401
+ warn: {
1402
+ color: "#ef9421",
1403
+ vivid: {
1404
+ dark: .2,
1405
+ light: .3
1406
+ }
1407
+ },
1408
+ error: { color: "#bf5a5f" }
1409
+ },
1410
+ lightest: .97,
1411
+ darkest: .24,
1412
+ layersDepth: .08,
1413
+ flatness: 1,
1414
+ mainPalette: {
1415
+ preserveInputColor: false,
1416
+ luminance: {
1417
+ useMiddle: true,
1418
+ middle: .62
1419
+ },
1420
+ saturate: {
1421
+ dark: -.25,
1422
+ light: -.25
1423
+ },
1424
+ vivid: {
1425
+ dark: .1,
1426
+ light: .2
1427
+ }
1428
+ },
1429
+ layerPalette: {
1430
+ desaturate: .2,
1431
+ saturate: {
1432
+ dark: -.2,
1433
+ light: -.2
1434
+ },
1435
+ vivid: {
1436
+ dark: 0,
1437
+ light: 0
1438
+ }
1439
+ },
1440
+ surfaces: {
1441
+ "0": [
1442
+ "scope-light-0",
1443
+ "scope-dark-1",
1444
+ "scope-color-100",
1445
+ "scope-dark-0",
1446
+ "scope-light-1",
1447
+ "scope-color-800"
1448
+ ],
1449
+ "1": [
1450
+ "scope-light-1",
1451
+ "scope-dark-1",
1452
+ "scope-color-100",
1453
+ "scope-dark-1",
1454
+ "scope-light-1",
1455
+ "scope-color-800"
1456
+ ],
1457
+ "2": [
1458
+ "scope-light-2",
1459
+ "scope-dark-1",
1460
+ "scope-color-100",
1461
+ "scope-dark-2",
1462
+ "scope-light-1",
1463
+ "scope-color-800"
1464
+ ],
1465
+ "3": [
1466
+ "scope-light-3",
1467
+ "scope-dark-1",
1468
+ "scope-color-100",
1469
+ "scope-dark-3",
1470
+ "scope-light-1",
1471
+ "scope-color-800"
1472
+ ],
1473
+ "4": [
1474
+ "scope-light-4",
1475
+ "scope-dark-1",
1476
+ "scope-color-100",
1477
+ "scope-dark-4",
1478
+ "scope-light-1",
1479
+ "scope-color-800"
1480
+ ],
1481
+ "50": [
1482
+ "scope-color-50",
1483
+ "scope-color-700",
1484
+ "scope-color-200",
1485
+ "scope-color-900",
1486
+ "scope-color-200",
1487
+ "scope-color-500"
1488
+ ],
1489
+ "100": [
1490
+ "scope-color-100",
1491
+ "scope-color-800",
1492
+ "scope-color-200",
1493
+ "scope-color-800",
1494
+ "scope-color-200",
1495
+ "scope-color-500"
1496
+ ],
1497
+ "200": [
1498
+ "scope-color-200",
1499
+ "scope-color-800",
1500
+ "scope-color-400",
1501
+ "scope-color-700",
1502
+ "scope-color-100",
1503
+ "scope-color-400"
1504
+ ],
1505
+ "300": [
1506
+ "scope-color-300",
1507
+ "scope-color-900",
1508
+ "scope-color-500",
1509
+ "scope-color-600",
1510
+ "scope-color-100",
1511
+ "scope-color-300"
1512
+ ],
1513
+ "400": [
1514
+ "scope-color-400",
1515
+ "scope-color-50",
1516
+ "scope-color-200",
1517
+ "scope-color-500",
1518
+ "scope-color-50",
1519
+ "scope-color-200"
1520
+ ],
1521
+ "500": [
1522
+ "scope-color-500",
1523
+ "scope-color-50",
1524
+ "scope-color-200",
1525
+ "scope-color-400",
1526
+ "scope-color-50",
1527
+ "scope-color-100"
1528
+ ],
1529
+ "600": [
1530
+ "scope-color-600",
1531
+ "scope-color-100",
1532
+ "scope-color-300",
1533
+ "scope-color-300",
1534
+ "scope-color-900",
1535
+ "scope-color-700"
1536
+ ],
1537
+ "700": [
1538
+ "scope-color-700",
1539
+ "scope-color-100",
1540
+ "scope-color-300",
1541
+ "scope-color-200",
1542
+ "scope-color-800",
1543
+ "scope-color-600"
1544
+ ],
1545
+ "800": [
1546
+ "scope-color-800",
1547
+ "scope-color-200",
1548
+ "scope-color-400",
1549
+ "scope-color-100",
1550
+ "scope-color-800",
1551
+ "scope-color-500"
1552
+ ],
1553
+ "900": [
1554
+ "scope-color-900",
1555
+ "scope-color-200",
1556
+ "scope-color-400",
1557
+ "scope-color-50",
1558
+ "scope-color-700",
1559
+ "scope-color-500"
1560
+ ]
1561
+ }
1562
+ };
1563
+ function generatePalette(_opts) {
1564
+ const _colors = _opts?.colors || {};
1565
+ for (const key of Object.keys(_colors)) {
1566
+ const col = _opts?.colors?.[key];
1567
+ if (typeof col === "string") _colors[key] = { color: col };
1568
+ }
1569
+ const opts = defu$1({
1570
+ ..._opts,
1571
+ colors: _colors
1572
+ }, defaultOpts);
1573
+ const bgOptions = {
1574
+ count: 5,
1575
+ preserveInputColor: false,
1576
+ flatness: opts.layerPalette.flatness ?? opts.flatness,
1577
+ luminance: {
1578
+ dark: opts.layerPalette.luminance?.dark ?? opts.darkest,
1579
+ light: opts.layerPalette.luminance?.light ?? opts.darkest + opts.layersDepth,
1580
+ useMiddle: false
1581
+ },
1582
+ saturate: opts.layerPalette.saturate,
1583
+ vivid: opts.layerPalette.vivid,
1584
+ suffixes: [
1585
+ "dark-0",
1586
+ "dark-1",
1587
+ "dark-2",
1588
+ "dark-3",
1589
+ "dark-4"
1590
+ ]
1591
+ };
1592
+ const darks = palitra(multiplySaturation(opts.colors, opts.layerPalette.desaturate), bgOptions).toStrings();
1593
+ bgOptions.suffixes = [
1594
+ "light-0",
1595
+ "light-1",
1596
+ "light-2",
1597
+ "light-3",
1598
+ "light-4"
1599
+ ].toReversed();
1600
+ const lumDark = bgOptions.luminance?.dark ?? opts.darkest;
1601
+ bgOptions.luminance = {
1602
+ dark: 1 - ((bgOptions.luminance?.light ?? opts.darkest + opts.layersDepth) - lumDark),
1603
+ light: 1,
1604
+ useMiddle: false
1605
+ };
1606
+ const lights = palitra(multiplySaturation(opts.colors, opts.layerPalette.desaturate), bgOptions).toStrings();
1607
+ const colors = palitra({
1608
+ primary: opts.colors.primary,
1609
+ grey: opts.colors.grey,
1610
+ secondary: opts.colors.secondary,
1611
+ neutral: opts.colors.neutral,
1612
+ good: opts.colors.good,
1613
+ warn: opts.colors.warn,
1614
+ error: opts.colors.error
1615
+ }, {
1616
+ count: 10,
1617
+ preserveInputColor: opts.mainPalette.preserveInputColor,
1618
+ flatness: opts.mainPalette.flatness ?? opts.flatness,
1619
+ luminance: {
1620
+ dark: opts.mainPalette.luminance?.dark ?? opts.darkest + opts.layersDepth + .02,
1621
+ light: opts.mainPalette.luminance?.light ?? opts.lightest,
1622
+ useMiddle: opts.mainPalette.luminance?.useMiddle,
1623
+ middle: opts.mainPalette.luminance?.middle
1624
+ },
1625
+ saturate: opts.mainPalette.saturate,
1626
+ vivid: opts.mainPalette.vivid
1627
+ }).toStrings();
1628
+ return {
1629
+ opts,
1630
+ colors: {
1631
+ ...darks,
1632
+ ...lights,
1633
+ ...colors
1634
+ },
1635
+ surfaces: opts.surfaces
1636
+ };
1637
+ }
1638
+ function multiplySaturation(colors, m = .5) {
1639
+ const newObj = {};
1640
+ for (const [key, val] of Object.entries(colors)) {
1641
+ const col = typeof val === "string" ? val : val.color;
1642
+ if (col) {
1643
+ const [h, s, l] = color(col).hsl();
1644
+ newObj[key] = color(h, s * m, l, "hsl").hex();
1645
+ }
1646
+ }
1647
+ return newObj;
1648
+ }
1649
+ const layerN = (n, reverse) => reverse ? 4 - n : n;
1650
+ function getPaletteShortcuts() {
1651
+ return [
1652
+ [/^layer-([0-4])$/, ([, a], { theme }) => {
1653
+ const sideTemplate = (bg, n) => {
1654
+ const fg = bg === "light" ? "dark" : "light";
1655
+ return `current-bg-scope-${bg}-${n} current-text-scope-${fg}-0 current-icon-scope-${fg}-0 current-text-muted-scope-${fg}-2 current-icon-muted-scope-${fg}-2 current-bg-hover-scope-${bg}-${Math.min(n + 1, 4)} current-border-hover-scope-${bg}-3 current-text-hover-scope-${fg}-0`;
1656
+ };
1657
+ const d = layerN(Number(a), theme.reverseDarkLayers);
1658
+ const l = layerN(Number(a), theme.reverseLightLayers);
1659
+ const dark = sideTemplate("dark", d);
1660
+ return toUnoShortcut({
1661
+ "": `${sideTemplate("light", l)} current-border-grey-500 bg-current text-current`,
1662
+ "dark:": dark,
1663
+ "[&.dark]:": dark
1664
+ });
1665
+ }],
1666
+ [/^(current-text-muted|current-icon-muted|current-text-hover|current-bg-hover|current-border-hover|bg|text|current-text|current-bg|current-icon|current-border|current-outline|current-caret|current-hl|i8-bg|i8-border|i8-outline)-layer-([0-4])$/, ([, target, a], { theme }) => {
1667
+ const d = layerN(Number(a), theme.reverseDarkLayers);
1668
+ return toUnoShortcut({
1669
+ "": `${target}-scope-light-${layerN(Number(a), theme.reverseLightLayers)}`,
1670
+ "dark:": `${target}-scope-dark-${d}`,
1671
+ "[&.dark]:": `${target}-scope-dark-${d}`
1672
+ });
1673
+ }],
1674
+ [/^surface-(.+)$/, ([, s], { theme }) => theme.surfaces[s] ? toUnoShortcut({
1675
+ "": `current-bg-${theme.surfaces[s][0]} current-text-${theme.surfaces[s][1]} current-icon-${theme.surfaces[s][1]} current-border-${theme.surfaces[s][2]} bg-current text-current border-current icon-current`,
1676
+ "dark:": `current-bg-${theme.surfaces[s][3]} current-text-${theme.surfaces[s][4]} current-icon-${theme.surfaces[s][4]} current-border-${theme.surfaces[s][5]} shadow-black/30`,
1677
+ "[&.dark]:": `current-bg-${theme.surfaces[s][3]} current-text-${theme.surfaces[s][4]} current-icon-${theme.surfaces[s][4]} current-border-${theme.surfaces[s][5]} shadow-black/30`
1678
+ }) : ""],
1679
+ { surface: "surface-100" }
1680
+ ];
1681
+ }
1682
+ //#endregion
1683
+ //#region src/theme/rules/palette.ts
1684
+ function colorToRgbWithOpacity(c) {
1685
+ const [r, g, b, _a] = color(c).rgba();
1686
+ return `${r} ${g} ${b}`;
1687
+ }
1688
+ function getOpacityVar(key) {
1689
+ return {
1690
+ bg: "--un-bg-opacity",
1691
+ text: "--un-text-opacity",
1692
+ fill: "--un-text-opacity",
1693
+ stroke: "--un-text-opacity",
1694
+ icon: "--un-icon-opacity",
1695
+ border: "--un-border-opacity",
1696
+ outline: "--un-outline-opacity",
1697
+ caret: "--un-caret-opacity",
1698
+ shadow: "--un-shadow-opacity",
1699
+ ring: "--un-ring-opacity"
1700
+ }[key];
1701
+ }
1702
+ function getCssTarget(key) {
1703
+ return {
1704
+ bg: "background-color",
1705
+ text: "color",
1706
+ fill: "fill",
1707
+ stroke: "stroke",
1708
+ icon: "color",
1709
+ border: "border-color",
1710
+ outline: "outline-color",
1711
+ caret: "caret-color",
1712
+ shadow: "--un-shadow-color",
1713
+ ring: "--un-ring-color"
1714
+ }[key];
1715
+ }
1716
+ const SCOPE_SHADES = [
1717
+ "50",
1718
+ "100",
1719
+ "200",
1720
+ "300",
1721
+ "400",
1722
+ "500",
1723
+ "600",
1724
+ "700",
1725
+ "800",
1726
+ "900"
1727
+ ];
1728
+ const SCOPE_LAYERS = [
1729
+ "0",
1730
+ "1",
1731
+ "2",
1732
+ "3",
1733
+ "4"
1734
+ ];
1735
+ const CURRENT_SLOTS = [
1736
+ "text-muted",
1737
+ "icon-muted",
1738
+ "text-hover",
1739
+ "bg-hover",
1740
+ "border-hover",
1741
+ "text",
1742
+ "bg",
1743
+ "icon",
1744
+ "border",
1745
+ "outline",
1746
+ "caret",
1747
+ "hl"
1748
+ ];
1749
+ const slotAlt = CURRENT_SLOTS.join("|");
1750
+ const sourceAlt = [
1751
+ ...CURRENT_SLOTS,
1752
+ "muted",
1753
+ "hover"
1754
+ ].map((s) => `-${s}`).join("|");
1755
+ const currentSlotRe = new RegExp(`^current-(${slotAlt})-(.+)$`);
1756
+ const currentPaintRe = new RegExp(`^(text|bg|icon|border|outline|caret|fill|shadow|ring)-current(${sourceAlt})?(\\/\\d{1,3})?$`);
1757
+ function getScopeCssVars(c, theme) {
1758
+ const col = theme.colors[c];
1759
+ if (!col) return;
1760
+ const vars = { "--scope-color": colorToRgbWithOpacity(col) };
1761
+ for (const shade of SCOPE_SHADES) vars[`--scope-color-${shade}`] = colorToRgbWithOpacity(theme.colors[`${c}-${shade}`]) || "";
1762
+ for (const layer of SCOPE_LAYERS) {
1763
+ vars[`--scope-light-${layer}`] = colorToRgbWithOpacity(theme.colors[`${c}-light-${layer}`]) || "";
1764
+ vars[`--scope-dark-${layer}`] = colorToRgbWithOpacity(theme.colors[`${c}-dark-${layer}`]) || "";
1765
+ }
1766
+ vars["--current-hl"] = colorToRgbWithOpacity(theme.colors[`${c}-500`]) || "";
1767
+ const greyMuted = colorToRgbWithOpacity(theme.colors[`grey-500`]) || "";
1768
+ vars["--current-text-muted"] = greyMuted;
1769
+ vars["--current-icon-muted"] = greyMuted;
1770
+ vars["--current-text-hover"] = colorToRgbWithOpacity(theme.colors[`${c}-dark-0`]) || "";
1771
+ vars["--current-bg-hover"] = colorToRgbWithOpacity(theme.colors[`${c}-light-1`]) || "";
1772
+ vars["--current-border-hover"] = colorToRgbWithOpacity(theme.colors[`${c}-light-3`]) || "";
1773
+ return vars;
1774
+ }
1775
+ const paletteRules = [
1776
+ [currentSlotRe, (match, { theme }) => {
1777
+ const t = match[1];
1778
+ const c = match[2];
1779
+ if (c.startsWith("scope-")) return { [`--current-${t}`]: `var(--${c})` };
1780
+ if (c === "hl") return { [`--current-${t}`]: `var(--current-hl)` };
1781
+ const themeCol = theme.colors[c];
1782
+ const colStr = typeof themeCol === "string" ? themeCol : themeCol?.DEFAULT;
1783
+ if (!colStr) return;
1784
+ try {
1785
+ return { [`--current-${t}`]: colorToRgbWithOpacity(colStr) };
1786
+ } catch {
1787
+ return;
1788
+ }
1789
+ }],
1790
+ [currentPaintRe, (match, { theme: _theme }) => {
1791
+ const target = match[1];
1792
+ let source = match[2] || `-${target}`;
1793
+ if (source === "-muted" || source === "-hover") source = `-${target}${source}`;
1794
+ const opacityVar = getOpacityVar(target);
1795
+ const cssVar = getCssTarget(target);
1796
+ const o = match[3];
1797
+ const opacity = o ? Number(o.slice(1)) / 100 : 1;
1798
+ const opacityVal = opacity === 1 ? `var(${opacityVar})` : opacity;
1799
+ if (target === "icon") {
1800
+ const indirect = [
1801
+ "-hl",
1802
+ "-icon-muted",
1803
+ "-icon-hover"
1804
+ ].includes(source);
1805
+ return {
1806
+ [opacityVar]: opacity,
1807
+ "--current-icon": indirect ? `var(--current${source})` : void 0
1808
+ };
1809
+ }
1810
+ if (["shadow", "ring"].includes(target) && source === "-border") return {
1811
+ [opacityVar]: opacity === 1 ? `var(--un-border-opacity)` : opacity,
1812
+ [`--un-${target}-color`]: `rgb(var(--current-border) / ${opacityVal})`
1813
+ };
1814
+ return {
1815
+ [opacityVar]: opacity,
1816
+ [cssVar]: `rgb(var(--current${source}) / ${opacityVal})`
1817
+ };
1818
+ }],
1819
+ [/^scope-(.*)$/, (match, { theme }) => getScopeCssVars(match[1], theme)],
1820
+ [/^(bg|text|fill|stroke|border|outline|icon|caret)-scope-((?:color|dark|light|text|bg|white|black|icon)(?:-\d+)?)(\/\d{1,3})?$/, (match, { theme }) => {
1821
+ const cssVar = getCssTarget(match[1]);
1822
+ const opacityVar = getOpacityVar(match[1]);
1823
+ const source = match[2];
1824
+ const o = match[3];
1825
+ const opacity = o ? Number(o.slice(1)) / 100 : 1;
1826
+ const fallback = source.startsWith("color") ? `grey-${source.slice(6)}` : `grey-${source}`;
1827
+ const opacityVal = opacity === 1 ? `var(${opacityVar})` : opacity;
1828
+ return {
1829
+ [opacityVar]: opacity,
1830
+ [cssVar]: `rgb(var(--scope-${source}, ${theme.colors[fallback] || ""}) / ${opacityVal})`
1831
+ };
1832
+ }],
1833
+ [/^icon-opacity-(\d{1,3})$/, (match, { theme: _theme }) => {
1834
+ const o = match[1];
1835
+ return { "--un-icon-opacity": Number(o) / 100 };
1836
+ }],
1837
+ [/^icon-color$/, () => ({ color: `rgb(var(--current-icon) / var(--un-icon-opacity, 1))` })],
1838
+ [/^icon-size-(.*)$/, (match, { theme }) => {
1839
+ const name = match[1];
1840
+ if (name.startsWith("[") && name.endsWith("]")) return { "--icon-size": name.slice(1, -1) };
1841
+ if (theme.spacing[name]) return { "--icon-size": theme.spacing[name] };
1842
+ }],
1843
+ [/^icon-size$/, () => ({
1844
+ width: `var(--icon-size, 1em)`,
1845
+ height: `var(--icon-size, 1em)`
1846
+ })]
1847
+ ];
1848
+ //#endregion
1849
+ //#region src/theme/utils/round.ts
1850
+ function round(v, decimals = 0) {
1851
+ const d = 10 ** decimals;
1852
+ return Math.round(v * d) / d;
1853
+ }
1854
+ //#endregion
1855
+ //#region src/theme/utils/unit-by.ts
1856
+ function unitBy(input, factor, roundTo = 3) {
1857
+ const v = Number.parseFloat(input);
1858
+ const units = /(px|em|rem|%)$/.exec(input)?.[1] || "";
1859
+ return `${round(v * factor, roundTo)}${units}`;
1860
+ }
1861
+ //#endregion
1862
+ //#region src/theme/preflights.ts
1863
+ const fontsPreflights = { getCSS: ({ theme }) => `${renderFontCss("body", theme.fontSize.body) + renderFontCss("figcaption", theme.fontSize.caption) + renderFontCss("h1", theme.fontSize.h1) + renderFontCss("h2", theme.fontSize.h2) + renderFontCss("h3", theme.fontSize.h3) + renderFontCss("h4", theme.fontSize.h4) + renderFontCss("h5", theme.fontSize.h5) + renderFontCss("h6", theme.fontSize.h6)}
1864
+ :root {
1865
+ --un-border-opacity: 0.25;
1866
+ --un-default-border-color: rgb(150 150 150 / var(--un-border-opacity));
1867
+ --scope-black: 0 0 0;
1868
+ --scope-white: 255 255 255;
1869
+ --scope-hl: var(--scope-color-500);
1870
+ --v-fingertip: ${theme.spacing["fingertip-m"] || "3em"};
1871
+ --v-fingertip-half: ${unitBy(theme.spacing["fingertip-m"] || "3em", .5)};
1872
+ ${renderDefaultScope(theme)}}
1873
+
1874
+
1875
+ ::-webkit-scrollbar {
1876
+ width: 10px;
1877
+ height: 10px;
1878
+ }
1879
+
1880
+ ::-webkit-scrollbar-track {
1881
+ background: rgba(0,0,0,0.05);
1882
+ border-radius: 5px;
1883
+ }
1884
+
1885
+ ::-webkit-scrollbar-thumb {
1886
+ background-color: rgba(0,0,0,0.2);
1887
+ border-radius: 5px;
1888
+ border: 2px solid transparent;
1889
+ background-clip: padding-box;
1890
+ }
1891
+
1892
+ ::-webkit-scrollbar-thumb:hover {
1893
+ background-color: rgba(0,0,0,0.3);
1894
+ }
1895
+
1896
+
1897
+ .dark ::-webkit-scrollbar-track {
1898
+ background: rgba(255,255,255,0.05);
1899
+ }
1900
+
1901
+ .dark ::-webkit-scrollbar-thumb {
1902
+ background-color: rgba(255,255,255,0.2);
1903
+ }
1904
+
1905
+ .dark ::-webkit-scrollbar-thumb:hover {
1906
+ background-color: rgba(255,255,255,0.3);
1907
+ }
1908
+ ` };
1909
+ function renderDefaultScope(theme) {
1910
+ const vars = getScopeCssVars("neutral", theme);
1911
+ if (!vars) return "";
1912
+ return `${Object.entries(vars).map(([k, v]) => ` ${k}: ${v};`).join("\n")}\n`;
1913
+ }
1914
+ function renderFontCss(selector, font) {
1915
+ return `${selector} { font-size: ${font[0]}; ${Object.entries(font[1]).map((e) => `${e[0]}: ${e[1]};`).join(" ")} }\n`;
1916
+ }
1917
+ //#endregion
1918
+ //#region src/theme/rules/i8-rules.ts
1919
+ const i8Rules = [
1920
+ [/^i8-(border|outline|bg)-(.+)$/, (match, { theme }) => {
1921
+ const target = match[1];
1922
+ const value = match[2];
1923
+ if (value === "none") return { [`--i8-${target}-width`]: "0" };
1924
+ if (value === "transparent") return { [`--i8-${target}-color`]: "0" };
1925
+ if (value.startsWith("scope-")) return { [`--i8-${target}-color`]: `var(--${value})` };
1926
+ const col = theme.colors[value];
1927
+ if (col) return { [`--i8-${target}-color`]: colorToRgbWithOpacity(String(col.DEFAULT || col)) };
1928
+ const width = theme.spacing[value];
1929
+ if (width) return { [`--i8-${target}-width`]: width };
1930
+ if (value.endsWith("px") || value.endsWith("em") || value.endsWith("rem")) return { [`--i8-${target}-width`]: value };
1931
+ if (value.startsWith("[") && value.endsWith("]")) {
1932
+ const v = value.slice(1, -1);
1933
+ if (v.endsWith("px") || v.endsWith("em") || v.endsWith("rem")) return { [`--i8-${target}-width`]: v };
1934
+ return { [`--i8-${target}-color`]: v };
1935
+ }
1936
+ }],
1937
+ [/^i8-(border|outline|bg)-opacity-(\d{1,3})$/, (match, { theme: _theme }) => {
1938
+ const target = match[1];
1939
+ const value = match[2];
1940
+ return { [`--i8-${target}-opacity`]: Number(value) / 100 };
1941
+ }],
1942
+ [/^i8-apply-(border|outline|bg)$/, (match, { theme: _theme }) => {
1943
+ const target = match[1];
1944
+ const prop = {
1945
+ border: "border-color",
1946
+ outline: "outline-color",
1947
+ bg: "background-color"
1948
+ }[target];
1949
+ const variable = {
1950
+ border: "--i8-border-color, var(--current-border)",
1951
+ outline: "--i8-outline-color, var(--current-outline)",
1952
+ bg: "--i8-bg-color, var(--current-bg)"
1953
+ }[target];
1954
+ const op = {
1955
+ border: `--i8-border-opacity, 0.2`,
1956
+ outline: `--i8-outline-opacity, 0.5`,
1957
+ bg: "--i8-bg-opacity, 1"
1958
+ }[target];
1959
+ return target === "bg" ? { [prop]: `rgb(var(${variable}) / var(${op}))` } : {
1960
+ [prop]: `rgb(var(${variable}) / var(${op}))`,
1961
+ [`${target}-width`]: `var(--i8-${target}-width, ${target === "border" ? 1 : 2}px)`
1962
+ };
1963
+ }]
1964
+ ];
1965
+ //#endregion
1966
+ //#region src/theme/rules/index.ts
1967
+ const rules = [
1968
+ ...[
1969
+ [
1970
+ /^text-m([bty])?-(.*)$/,
1971
+ (match, { theme }) => {
1972
+ const dir = match[1];
1973
+ const size = match[2];
1974
+ const d = dir ? {
1975
+ y: ["top", "bottom"],
1976
+ t: ["top"],
1977
+ b: ["bottom"]
1978
+ }[dir] : [
1979
+ "top",
1980
+ "bottom",
1981
+ "left",
1982
+ "right"
1983
+ ];
1984
+ const result = {};
1985
+ if (theme.spacing[size]) {
1986
+ for (const prop of d) result[`margin-${prop}`] = ["left", "right"].includes(prop) ? theme.spacing[size] : `calc(${theme.spacing[size]} + var(--font-${prop === "top" ? "tc" : "bc"}))`;
1987
+ return result;
1988
+ } else if (/^\d+(em|rem|px)?$/.test(size)) {
1989
+ let s = size;
1990
+ if (/^[\d.]+$/.test(size)) s = `${Number(size) * .25}rem`;
1991
+ for (const prop of d) result[`margin-${prop}`] = ["left", "right"].includes(prop) ? s : `calc(${s} + var(--font-${prop === "top" ? "tc" : "bc"}))`;
1992
+ return result;
1993
+ }
1994
+ },
1995
+ { layer: "utilities" }
1996
+ ],
1997
+ [
1998
+ /^card-dense$/,
1999
+ (_match, { theme: _theme }) => ({ "--card-spacing": "var(--card-spacing-dense)" }),
2000
+ { layer: "utilities" }
2001
+ ],
2002
+ [/^card-(.*)$/, (match, { theme }) => {
2003
+ const name = match[1];
2004
+ if (theme.fontSize[name]) {
2005
+ const props = theme.fontSize[name][1];
2006
+ return {
2007
+ "--card-spacing": `${unitBy(props["--font-corrected"], theme.cardSpacingFactor.regular)}`,
2008
+ "--card-spacing-dense": `${unitBy(props["--font-corrected"], theme.cardSpacingFactor.dense)}`,
2009
+ "--card-heading-size": props["--font-size"],
2010
+ "--card-heading-bold": props["--font-bold"],
2011
+ "--card-heading-corrected": props["--font-corrected"],
2012
+ "--card-heading-weight": props["font-weight"],
2013
+ "--card-heading-lh": props["line-height"],
2014
+ "--card-heading-ls": props["letter-spacing"],
2015
+ "--card-heading-bc": props["--font-bc"],
2016
+ "--card-heading-tc": props["--font-tc"],
2017
+ "padding": "var(--card-spacing)"
2018
+ };
2019
+ }
2020
+ }],
2021
+ [/^fingertip-(.*)/, (match, { theme }) => {
2022
+ const name = match[1];
2023
+ if (name.startsWith("[") && name.endsWith("]")) return {
2024
+ "--v-fingertip": name.slice(1, -1),
2025
+ "--v-fingertip-half": unitBy(name.slice(1, -1), .5)
2026
+ };
2027
+ if ([
2028
+ "xs",
2029
+ "s",
2030
+ "m",
2031
+ "l",
2032
+ "xl"
2033
+ ].includes(name)) return {
2034
+ "--v-fingertip": theme.spacing[`fingertip-${name}`],
2035
+ "--v-fingertip-half": unitBy(theme.spacing[`fingertip-${name}`], .5)
2036
+ };
2037
+ if (theme.spacing[name]) return {
2038
+ "--v-fingertip": theme.spacing[name],
2039
+ "--v-fingertip-half": unitBy(theme.spacing[name], .5)
2040
+ };
2041
+ }]
2042
+ ],
2043
+ ...paletteRules,
2044
+ ...i8Rules
2045
+ ];
2046
+ //#endregion
2047
+ //#region src/theme/types.ts
2048
+ function k$1(n, base = 1) {
2049
+ return base * 1.618 ** n;
2050
+ }
2051
+ //#endregion
2052
+ //#region src/theme/typography.ts
2053
+ function font(weight, boldWeight, size, height, spacing) {
2054
+ return {
2055
+ weight,
2056
+ boldWeight,
2057
+ size,
2058
+ height,
2059
+ spacing
2060
+ };
2061
+ }
2062
+ const defaultTypography = {
2063
+ "h1": font(400, 700, k$1(3.5), k$1(.5), -.025),
2064
+ "h2": font(400, 700, k$1(2.5), k$1(.5), -.022),
2065
+ "h3": font(400, 700, k$1(2), k$1(.5), -.022),
2066
+ "h4": font(400, 600, k$1(1), k$1(.5), -.02),
2067
+ "h5": font(400, 600, k$1(.5), k$1(.5), -.017),
2068
+ "h6": font(600, 700, k$1(.25), k$1(.5), -.014),
2069
+ "subheading": font(400, 600, k$1(-.2), k$1(.5), -.007),
2070
+ "body-l": font(400, 600, k$1(.5), k$1(.75), -.014),
2071
+ "body": font(400, 600, k$1(0), k$1(.75), -.011),
2072
+ "body-s": font(400, 600, k$1(-.5), k$1(1), 0),
2073
+ "callout": font(400, 600, k$1(-.25), k$1(.5), -.009),
2074
+ "label": font(500, 700, k$1(-.25), k$1(.5), -.004),
2075
+ "caption": font(400, 600, k$1(-.5), k$1(.5), -.007),
2076
+ "overline": font(400, 600, k$1(-.5), k$1(.5), .0618)
2206
2077
  };
2207
- function getComponentClasses(...components) {
2208
- const set = /* @__PURE__ */ new Set();
2209
- for (const name of components) {
2210
- const key = name.startsWith("Vu") ? name.slice(2) : name;
2211
- for (const cls of componentClasses[key] ?? []) set.add(cls);
2212
- }
2213
- return [...set];
2078
+ function buildFontTheme(size, w, wBold, lh, ls, actualFontHeightFactor = 1, actualFontHeightTopBottomRatio = .5) {
2079
+ const correctedSize = size * actualFontHeightFactor;
2080
+ const m = (lh * size - correctedSize) / size;
2081
+ const half = correctedSize / 2;
2082
+ const offt = correctedSize * actualFontHeightTopBottomRatio - half + m / 2;
2083
+ const offb = correctedSize * (1 - actualFontHeightTopBottomRatio) - half + m / 2;
2084
+ const mt = round(offt, 4);
2085
+ const mb = round(offb, 4);
2086
+ return {
2087
+ mt,
2088
+ mb,
2089
+ size,
2090
+ correctedSize,
2091
+ theme: [`${size}em`, {
2092
+ "--font-bold": wBold,
2093
+ "--font-size": `${size}em`,
2094
+ "--font-corrected": `${correctedSize}em`,
2095
+ "--font-bc": `${-mb}em`,
2096
+ "--font-tc": `${-mt}em`,
2097
+ "font-weight": w,
2098
+ "line-height": `${lh}em`,
2099
+ "letter-spacing": `${ls}em`
2100
+ }]
2101
+ };
2102
+ }
2103
+ //#endregion
2104
+ //#region src/theme/utils/radius-scale.ts
2105
+ const ROOT_FONT_PX = 16;
2106
+ function parseRadius(input) {
2107
+ const m = input.trim().match(/^(-?\d*\.?\d+)(px|em|rem)?$/);
2108
+ if (!m) return null;
2109
+ const n = Number.parseFloat(m[1]);
2110
+ if (!Number.isFinite(n)) return null;
2111
+ return {
2112
+ n,
2113
+ unit: m[2] ?? ""
2114
+ };
2115
+ }
2116
+ function computeRadiusScale(baseRadius) {
2117
+ const parsed = parseRadius(baseRadius);
2118
+ if (!parsed) return {
2119
+ r0: `min(${baseRadius}, clamp(2px, calc(${baseRadius} / 2), 4px))`,
2120
+ r1: baseRadius,
2121
+ r2: `calc(${baseRadius} * 1.5)`,
2122
+ r3: `calc(${baseRadius} * 2)`,
2123
+ r4: `calc(${baseRadius} * 2.5)`
2124
+ };
2125
+ const { n, unit } = parsed;
2126
+ if (n === 0) return {
2127
+ r0: "0",
2128
+ r1: "0",
2129
+ r2: "0",
2130
+ r3: "0",
2131
+ r4: "0"
2132
+ };
2133
+ const basePx = unit === "em" || unit === "rem" ? n * ROOT_FONT_PX : n;
2134
+ const r0Px = Math.min(basePx, Math.max(2, Math.min(basePx / 2, 4)));
2135
+ const scaled = unit ? baseRadius : `${n}px`;
2136
+ return {
2137
+ r0: `${round(r0Px, 3)}px`,
2138
+ r1: baseRadius,
2139
+ r2: unitBy(scaled, 1.5),
2140
+ r3: unitBy(scaled, 2),
2141
+ r4: unitBy(scaled, 2.5)
2142
+ };
2214
2143
  }
2215
2144
  //#endregion
2145
+ //#region src/theme/theme.ts
2146
+ const themeFactory = (opts) => {
2147
+ /**
2148
+ * Spacing
2149
+ */
2150
+ const spacing = {
2151
+ "$xxs": `${round(1 / opts.spacingFactor ** 3, 3)}em`,
2152
+ "$xs": `${round(1 / opts.spacingFactor ** 2, 3)}em`,
2153
+ "$s": `${round(1 / opts.spacingFactor, 3)}em`,
2154
+ "$m": "1em",
2155
+ "$l": `${round(opts.spacingFactor, 3)}em`,
2156
+ "$xl": `${round(opts.spacingFactor ** 2, 3)}em`,
2157
+ "$xxl": `${round(opts.spacingFactor ** 3, 3)}em`,
2158
+ "fingertip": "var(--v-fingertip)",
2159
+ "fingertip-half": "var(--v-fingertip-half)",
2160
+ "fingertip-xs": opts.fingertip.xs,
2161
+ "fingertip-s": opts.fingertip.s,
2162
+ "fingertip-m": opts.fingertip.m,
2163
+ "fingertip-l": opts.fingertip.l,
2164
+ "fingertip-xl": opts.fingertip.xl,
2165
+ "$font-tc": "var(--font-bc)",
2166
+ "$font-bc": "var(--font-tc)",
2167
+ "$font-size": "var(--font-size)",
2168
+ "$font-corrected": "var(--font-corrected)",
2169
+ "$card-spacing": "var(--card-spacing)",
2170
+ "$card-spacing-dense": "var(--card-spacing-dense)",
2171
+ "$card-heading-size": "var(--card-heading-size)",
2172
+ "$card-heading-corrected": "var(--card-heading-corrected)",
2173
+ "base-radius": opts.baseRadius
2174
+ };
2175
+ const lineHeight = {
2176
+ "fingertip": "var(--v-fingertip)",
2177
+ "fingertip-half": "var(--v-fingertip-half)",
2178
+ "fingertip-xs": opts.fingertip.xs,
2179
+ "fingertip-s": opts.fingertip.s,
2180
+ "fingertip-m": opts.fingertip.m,
2181
+ "fingertip-l": opts.fingertip.l,
2182
+ "fingertip-xl": opts.fingertip.xl
2183
+ };
2184
+ const borderRadius = {
2185
+ ...spacing,
2186
+ base: opts.baseRadius,
2187
+ ...computeRadiusScale(opts.baseRadius)
2188
+ };
2189
+ /**
2190
+ * Typography
2191
+ */
2192
+ const fontWeight = { $bold: "var(--font-bold)" };
2193
+ const fontSize = { "card-header": ["var(--card-heading-size)", {
2194
+ "--font-bold": "var(--card-heading-bold)",
2195
+ "--font-size": "var(--card-heading-size)",
2196
+ "--font-corrected": "var(--card-heading-corrected)",
2197
+ "--font-bc": "var(--card-heading-bc)",
2198
+ "--font-tc": "var(--card-heading-tc)",
2199
+ "font-weight": "var(--card-heading-weight)",
2200
+ "line-height": "var(--card-heading-lh)",
2201
+ "letter-spacing": "var(--card-heading-ls)"
2202
+ }] };
2203
+ for (const [name, val] of Object.entries(opts.typography)) if (val?.size) {
2204
+ const ft = buildFontTheme(val.size || 1, val.weight || 400, val.boldWeight || 700, val.height || 1, val.spacing || 0, val.actualHeightFactor || opts.actualFontHeightFactor, val.actualHeightTopBottomRatio || opts.actualFontHeightTopBottomRatio);
2205
+ fontSize[name] = ft.theme;
2206
+ spacing[name] = `${ft.size}em`;
2207
+ }
2208
+ const palette = generatePalette(opts.palette);
2209
+ /**
2210
+ * Putting all together
2211
+ */
2212
+ return {
2213
+ paletteOpts: palette.opts,
2214
+ theme: {
2215
+ colors: palette.colors,
2216
+ surfaces: palette.surfaces,
2217
+ reverseLightLayers: opts.layers.reverseLight,
2218
+ reverseDarkLayers: opts.layers.reverseDark,
2219
+ lineHeight,
2220
+ spacing,
2221
+ fontWeight,
2222
+ actualFontHeightFactor: opts.actualFontHeightFactor,
2223
+ cardSpacingFactor: opts.cardSpacingFactor,
2224
+ fontSize,
2225
+ width: spacing,
2226
+ height: spacing,
2227
+ maxWidth: spacing,
2228
+ maxHeight: spacing,
2229
+ minWidth: spacing,
2230
+ minHeight: spacing,
2231
+ borderRadius,
2232
+ animation: opts.animation
2233
+ }
2234
+ };
2235
+ };
2236
+ //#endregion
2216
2237
  //#region src/theme/preset-vunor.ts
2217
2238
  function createVunorExtractor() {
2218
2239
  return {
@@ -2319,10 +2340,11 @@ const presetVunor = (_opts) => {
2319
2340
  wind.rules.push(...rules);
2320
2341
  const paletteShortcuts = getPaletteShortcuts();
2321
2342
  const theme = themeFactory(opts);
2322
- wind.preflights.push({ getCSS: () => `__vunor_palette_options {background-image: url("data:image/gif;base64,${Buffer.from(JSON.stringify({
2343
+ const paletteOptsCss = `__vunor_palette_options {background-image: url("data:image/gif;base64,${Buffer.from(JSON.stringify({
2323
2344
  ...theme.paletteOpts,
2324
2345
  surfaces: void 0
2325
- })).toString("base64")}")}` });
2346
+ })).toString("base64")}")}`;
2347
+ wind.preflights.push({ getCSS: () => paletteOptsCss });
2326
2348
  return {
2327
2349
  ...wind,
2328
2350
  name: "vunor",
@@ -2355,6 +2377,10 @@ function getFixedWind() {
2355
2377
  const rawVunorShortcuts = [
2356
2378
  i8,
2357
2379
  c8,
2380
+ btn,
2381
+ menu,
2382
+ popupCard,
2383
+ disabledSoft,
2358
2384
  ...shortcuts
2359
2385
  ];
2360
2386
  /**