@work-rjkashyap/unified-ui 0.3.2 → 0.3.4

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.
@@ -1,4 +1,4 @@
1
- import { blue, red, amber, green, zinc, slate, gray, teal, brand, zIndex, shadow, radius, semanticLight, shadowDark, semanticDark } from './chunk-IVZAB7BV.mjs';
1
+ import { blue, red, amber, green, zinc, slate, gray, teal, brand, indigo, purple, pink, cyan, emerald, yellow, fuchsia, sky, lime, zIndex, shadow, radius, semanticLight, shadowDark, semanticDark } from './chunk-AAEWG5VR.mjs';
2
2
  import { fontFamily } from './chunk-ITBG42M5.mjs';
3
3
  import { easingCSS, durationCSS } from './chunk-EZ2L3XPS.mjs';
4
4
  import { cn } from './chunk-ZT3PCXDF.mjs';
@@ -578,6 +578,46 @@ var COLOR_PRESETS = [
578
578
  {
579
579
  swatch: brand[600],
580
580
  ...buildChromaticPreset("Brand", "brand", brand)
581
+ },
582
+ {
583
+ swatch: indigo[600],
584
+ ...buildChromaticPreset("Indigo", "indigo", indigo)
585
+ },
586
+ {
587
+ swatch: purple[600],
588
+ ...buildChromaticPreset("Purple", "purple", purple)
589
+ },
590
+ {
591
+ swatch: pink[600],
592
+ ...buildChromaticPreset("Pink", "pink", pink)
593
+ },
594
+ {
595
+ swatch: cyan[600],
596
+ ...buildChromaticPreset("Cyan", "cyan", cyan)
597
+ },
598
+ {
599
+ swatch: emerald[600],
600
+ ...buildChromaticPreset("Emerald", "emerald", emerald)
601
+ },
602
+ {
603
+ swatch: yellow[600],
604
+ ...buildChromaticPreset("Yellow", "yellow", yellow)
605
+ },
606
+ {
607
+ swatch: fuchsia[600],
608
+ ...buildChromaticPreset("Fuchsia", "fuchsia", fuchsia)
609
+ },
610
+ {
611
+ swatch: sky[600],
612
+ ...buildChromaticPreset("Sky", "sky", sky)
613
+ },
614
+ {
615
+ swatch: lime[600],
616
+ ...buildChromaticPreset("Lime", "lime", lime)
617
+ },
618
+ {
619
+ swatch: amber[600],
620
+ ...buildChromaticPreset("Amber", "amber", amber)
581
621
  }
582
622
  ];
583
623
  function getColorPreset(key) {
@@ -598,6 +638,7 @@ function getRadiusPreset(key) {
598
638
  return RADIUS_PRESETS.find((r) => r.key === key) ?? RADIUS_PRESETS[4];
599
639
  }
600
640
  var FONT_PRESETS = [
641
+ // ---- Built-in fonts (loaded via next/font in the docs app) ----
601
642
  {
602
643
  name: "Outfit",
603
644
  key: "outfit",
@@ -610,6 +651,164 @@ var FONT_PRESETS = [
610
651
  value: 'var(--font-inter), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
611
652
  sample: "Aa"
612
653
  },
654
+ {
655
+ name: "Geist Sans",
656
+ key: "geist-sans",
657
+ value: 'var(--font-geist-sans), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
658
+ sample: "Aa"
659
+ },
660
+ {
661
+ name: "DM Sans",
662
+ key: "dm-sans",
663
+ value: 'var(--font-dm-sans), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
664
+ sample: "Aa"
665
+ },
666
+ {
667
+ name: "Plus Jakarta Sans",
668
+ key: "plus-jakarta-sans",
669
+ value: 'var(--font-plus-jakarta-sans), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
670
+ sample: "Aa"
671
+ },
672
+ {
673
+ name: "Open Sans",
674
+ key: "open-sans",
675
+ value: 'var(--font-open-sans), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
676
+ sample: "Aa"
677
+ },
678
+ {
679
+ name: "Poppins",
680
+ key: "poppins",
681
+ value: 'var(--font-poppins), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
682
+ sample: "Aa"
683
+ },
684
+ {
685
+ name: "Montserrat",
686
+ key: "montserrat",
687
+ value: 'var(--font-montserrat), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
688
+ sample: "Aa"
689
+ },
690
+ {
691
+ name: "Lato",
692
+ key: "lato",
693
+ value: 'var(--font-lato), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
694
+ sample: "Aa"
695
+ },
696
+ {
697
+ name: "Nunito",
698
+ key: "nunito",
699
+ value: 'var(--font-nunito), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
700
+ sample: "Aa"
701
+ },
702
+ {
703
+ name: "Raleway",
704
+ key: "raleway",
705
+ value: 'var(--font-raleway), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
706
+ sample: "Aa"
707
+ },
708
+ {
709
+ name: "Rubik",
710
+ key: "rubik",
711
+ value: 'var(--font-rubik), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
712
+ sample: "Aa"
713
+ },
714
+ {
715
+ name: "Source Sans 3",
716
+ key: "source-sans-3",
717
+ value: 'var(--font-source-sans-3), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
718
+ sample: "Aa"
719
+ },
720
+ {
721
+ name: "Work Sans",
722
+ key: "work-sans",
723
+ value: 'var(--font-work-sans), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
724
+ sample: "Aa"
725
+ },
726
+ {
727
+ name: "Manrope",
728
+ key: "manrope",
729
+ value: 'var(--font-manrope), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
730
+ sample: "Aa"
731
+ },
732
+ {
733
+ name: "Space Grotesk",
734
+ key: "space-grotesk",
735
+ value: 'var(--font-space-grotesk), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
736
+ sample: "Aa"
737
+ },
738
+ // ---- Additional popular fonts ----
739
+ {
740
+ name: "Figtree",
741
+ key: "figtree",
742
+ value: 'var(--font-figtree), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
743
+ sample: "Aa"
744
+ },
745
+ {
746
+ name: "IBM Plex Sans",
747
+ key: "ibm-plex-sans",
748
+ value: 'var(--font-ibm-plex-sans), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
749
+ sample: "Aa"
750
+ },
751
+ {
752
+ name: "Quicksand",
753
+ key: "quicksand",
754
+ value: 'var(--font-quicksand), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
755
+ sample: "Aa"
756
+ },
757
+ {
758
+ name: "Cabin",
759
+ key: "cabin",
760
+ value: 'var(--font-cabin), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
761
+ sample: "Aa"
762
+ },
763
+ {
764
+ name: "Barlow",
765
+ key: "barlow",
766
+ value: 'var(--font-barlow), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
767
+ sample: "Aa"
768
+ },
769
+ {
770
+ name: "Josefin Sans",
771
+ key: "josefin-sans",
772
+ value: 'var(--font-josefin-sans), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
773
+ sample: "Aa"
774
+ },
775
+ {
776
+ name: "Karla",
777
+ key: "karla",
778
+ value: 'var(--font-karla), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
779
+ sample: "Aa"
780
+ },
781
+ {
782
+ name: "Mulish",
783
+ key: "mulish",
784
+ value: 'var(--font-mulish), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
785
+ sample: "Aa"
786
+ },
787
+ {
788
+ name: "Noto Sans",
789
+ key: "noto-sans",
790
+ value: 'var(--font-noto-sans), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
791
+ sample: "Aa"
792
+ },
793
+ {
794
+ name: "Ubuntu",
795
+ key: "ubuntu",
796
+ value: 'var(--font-ubuntu), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
797
+ sample: "Aa"
798
+ },
799
+ {
800
+ name: "Sora",
801
+ key: "sora",
802
+ value: 'var(--font-sora), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
803
+ sample: "Aa"
804
+ },
805
+ {
806
+ name: "Lexend",
807
+ key: "lexend",
808
+ value: 'var(--font-lexend), system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
809
+ sample: "Aa"
810
+ },
811
+ // ---- Generic stacks ----
613
812
  {
614
813
  name: "System",
615
814
  key: "system",
@@ -749,6 +948,53 @@ var SURFACE_STYLE_PRESETS = [
749
948
  }
750
949
  ];
751
950
  var DEFAULT_SURFACE_STYLE_KEY = "bordered";
951
+ var MENU_COLOR_PRESETS = [
952
+ {
953
+ name: "Default",
954
+ key: "default",
955
+ description: "Uses the color preset's built-in sidebar colors"
956
+ },
957
+ {
958
+ name: "Muted",
959
+ key: "muted",
960
+ description: "Sidebar matches the muted/surface tone \u2014 blends with content"
961
+ },
962
+ {
963
+ name: "Inverted",
964
+ key: "inverted",
965
+ description: "Dark sidebar in light mode, lighter sidebar in dark mode for contrast"
966
+ },
967
+ {
968
+ name: "Primary",
969
+ key: "primary",
970
+ description: "Sidebar uses the primary color as its background"
971
+ }
972
+ ];
973
+ var DEFAULT_MENU_COLOR_KEY = "default";
974
+ function getMenuColorPreset(key) {
975
+ return MENU_COLOR_PRESETS.find((p) => p.key === key) ?? MENU_COLOR_PRESETS[0];
976
+ }
977
+ var MENU_ACCENT_PRESETS = [
978
+ {
979
+ name: "None",
980
+ key: "none",
981
+ description: "No visual accent highlight on sidebar items"
982
+ },
983
+ {
984
+ name: "Subtle",
985
+ key: "subtle",
986
+ description: "Soft background tint on hover and active sidebar items"
987
+ },
988
+ {
989
+ name: "Bold",
990
+ key: "bold",
991
+ description: "Prominent primary-colored accent on active sidebar items"
992
+ }
993
+ ];
994
+ var DEFAULT_MENU_ACCENT_KEY = "subtle";
995
+ function getMenuAccentPreset(key) {
996
+ return MENU_ACCENT_PRESETS.find((p) => p.key === key) ?? MENU_ACCENT_PRESETS[1];
997
+ }
752
998
  var STYLE_PRESETS = [
753
999
  {
754
1000
  name: "Vega",
@@ -866,7 +1112,9 @@ var DEFAULT_THEME_CONFIG = {
866
1112
  radius: DEFAULT_RADIUS_KEY,
867
1113
  font: DEFAULT_FONT_KEY,
868
1114
  shadow: DEFAULT_SHADOW_KEY,
869
- surfaceStyle: DEFAULT_SURFACE_STYLE_KEY
1115
+ surfaceStyle: DEFAULT_SURFACE_STYLE_KEY,
1116
+ menuColor: DEFAULT_MENU_COLOR_KEY,
1117
+ menuAccent: DEFAULT_MENU_ACCENT_KEY
870
1118
  };
871
1119
  function buildThemeOverrides(config, mode) {
872
1120
  const vars = {};
@@ -976,6 +1224,76 @@ function buildThemeOverrides(config, mode) {
976
1224
  vars["--ds-gap-default"] = sv.gapDefault;
977
1225
  vars["--ds-border-width"] = sv.borderWidth;
978
1226
  vars["--ds-control-height"] = sv.controlHeight;
1227
+ const colorPresetObj = getColorPreset(config.colorPreset);
1228
+ const presetColors = mode === "dark" ? colorPresetObj.dark : colorPresetObj.light;
1229
+ if (config.menuColor === "muted") {
1230
+ if (mode === "light") {
1231
+ vars["--sidebar"] = presetColors.muted;
1232
+ vars["--sidebar-foreground"] = presetColors.foreground;
1233
+ vars["--sidebar-border"] = presetColors.border;
1234
+ } else {
1235
+ vars["--sidebar"] = presetColors.muted;
1236
+ vars["--sidebar-foreground"] = presetColors.foreground;
1237
+ vars["--sidebar-border"] = presetColors.border;
1238
+ }
1239
+ } else if (config.menuColor === "inverted") {
1240
+ if (mode === "light") {
1241
+ vars["--sidebar"] = "oklch(0.205 0 0)";
1242
+ vars["--sidebar-foreground"] = "oklch(0.95 0 0)";
1243
+ vars["--sidebar-primary"] = presetColors.primary;
1244
+ vars["--sidebar-primary-foreground"] = "oklch(0.985 0 0)";
1245
+ vars["--sidebar-border"] = "oklch(1 0 0 / 10%)";
1246
+ vars["--sidebar-ring"] = "oklch(0.439 0 0)";
1247
+ } else {
1248
+ vars["--sidebar"] = "oklch(0.269 0 0)";
1249
+ vars["--sidebar-foreground"] = "oklch(0.95 0 0)";
1250
+ vars["--sidebar-primary"] = presetColors.primary;
1251
+ vars["--sidebar-primary-foreground"] = "oklch(0.985 0 0)";
1252
+ vars["--sidebar-border"] = "oklch(1 0 0 / 8%)";
1253
+ vars["--sidebar-ring"] = "oklch(0.5 0 0)";
1254
+ }
1255
+ } else if (config.menuColor === "primary") {
1256
+ if (mode === "light") {
1257
+ vars["--sidebar"] = presetColors.primary;
1258
+ vars["--sidebar-foreground"] = presetColors.primaryForeground;
1259
+ vars["--sidebar-primary"] = presetColors.primaryForeground;
1260
+ vars["--sidebar-primary-foreground"] = presetColors.primary;
1261
+ vars["--sidebar-border"] = `color-mix(in oklch, ${presetColors.primaryForeground} 15%, transparent)`;
1262
+ vars["--sidebar-ring"] = presetColors.primaryForeground;
1263
+ } else {
1264
+ vars["--sidebar"] = presetColors.primary;
1265
+ vars["--sidebar-foreground"] = presetColors.primaryForeground;
1266
+ vars["--sidebar-primary"] = presetColors.primaryForeground;
1267
+ vars["--sidebar-primary-foreground"] = presetColors.primary;
1268
+ vars["--sidebar-border"] = `color-mix(in oklch, ${presetColors.primaryForeground} 15%, transparent)`;
1269
+ vars["--sidebar-ring"] = presetColors.primaryForeground;
1270
+ }
1271
+ }
1272
+ if (config.menuAccent === "none") {
1273
+ vars["--sidebar-accent"] = "transparent";
1274
+ vars["--sidebar-accent-foreground"] = vars["--sidebar-foreground"] ?? presetColors.sidebarForeground;
1275
+ } else if (config.menuAccent === "bold") {
1276
+ if (config.menuColor === "primary") {
1277
+ if (mode === "light") {
1278
+ vars["--sidebar-accent"] = `color-mix(in oklch, ${presetColors.primaryForeground} 20%, transparent)`;
1279
+ vars["--sidebar-accent-foreground"] = presetColors.primaryForeground;
1280
+ } else {
1281
+ vars["--sidebar-accent"] = `color-mix(in oklch, ${presetColors.primaryForeground} 20%, transparent)`;
1282
+ vars["--sidebar-accent-foreground"] = presetColors.primaryForeground;
1283
+ }
1284
+ } else if (config.menuColor === "inverted") {
1285
+ vars["--sidebar-accent"] = presetColors.primary;
1286
+ vars["--sidebar-accent-foreground"] = presetColors.primaryForeground;
1287
+ } else {
1288
+ if (mode === "light") {
1289
+ vars["--sidebar-accent"] = presetColors.primaryMuted;
1290
+ vars["--sidebar-accent-foreground"] = presetColors.primary;
1291
+ } else {
1292
+ vars["--sidebar-accent"] = presetColors.primaryMuted;
1293
+ vars["--sidebar-accent-foreground"] = presetColors.primaryMutedForeground;
1294
+ }
1295
+ }
1296
+ }
979
1297
  if (config.surfaceStyle === "elevated") {
980
1298
  vars["--card"] = mode === "dark" ? "oklch(0.205 0 0)" : "oklch(1 0 0)";
981
1299
  vars["--border"] = mode === "dark" ? "oklch(0.205 0 0 / 0)" : "oklch(0.922 0 0 / 0)";
@@ -998,6 +1316,8 @@ function generateThemeCSS(config) {
998
1316
  ` * Radius: ${getRadiusPreset(config.radius).label}`,
999
1317
  ` * Font: ${getFontPreset(config.font).name}`,
1000
1318
  ` * Shadows: ${getShadowPreset(config.shadow).name}`,
1319
+ ` * Menu Color: ${getMenuColorPreset(config.menuColor).name}`,
1320
+ ` * Menu Accent: ${getMenuAccentPreset(config.menuAccent).name}`,
1001
1321
  " * ============================================ */",
1002
1322
  "",
1003
1323
  ":root {",
@@ -1007,7 +1327,7 @@ function generateThemeCSS(config) {
1007
1327
  ".dark {",
1008
1328
  formatVars(darkVars),
1009
1329
  "}"
1010
- ].join("\n");
1330
+ ].filter(Boolean).join("\n");
1011
1331
  }
1012
1332
  var STORAGE_KEY = "ds-theme-customizer";
1013
1333
  var STYLE_ELEMENT_ID = "ds-theme-customizer";
@@ -1035,7 +1355,9 @@ function loadConfig() {
1035
1355
  shadow: SHADOW_PRESETS.some((s) => s.key === parsed.shadow) ? parsed.shadow : DEFAULT_THEME_CONFIG.shadow,
1036
1356
  surfaceStyle: SURFACE_STYLE_PRESETS.some(
1037
1357
  (s) => s.key === parsed.surfaceStyle
1038
- ) ? parsed.surfaceStyle : DEFAULT_THEME_CONFIG.surfaceStyle
1358
+ ) ? parsed.surfaceStyle : DEFAULT_THEME_CONFIG.surfaceStyle,
1359
+ menuColor: MENU_COLOR_PRESETS.some((p) => p.key === parsed.menuColor) ? parsed.menuColor : DEFAULT_THEME_CONFIG.menuColor,
1360
+ menuAccent: MENU_ACCENT_PRESETS.some((p) => p.key === parsed.menuAccent) ? parsed.menuAccent : DEFAULT_THEME_CONFIG.menuAccent
1039
1361
  };
1040
1362
  } catch {
1041
1363
  return DEFAULT_THEME_CONFIG;
@@ -1079,7 +1401,7 @@ function removeStyles() {
1079
1401
  }
1080
1402
  }
1081
1403
  function configsEqual(a, b) {
1082
- return a.style === b.style && a.colorPreset === b.colorPreset && a.radius === b.radius && a.font === b.font && a.shadow === b.shadow && a.surfaceStyle === b.surfaceStyle;
1404
+ return a.style === b.style && a.colorPreset === b.colorPreset && a.radius === b.radius && a.font === b.font && a.shadow === b.shadow && a.surfaceStyle === b.surfaceStyle && a.menuColor === b.menuColor && a.menuAccent === b.menuAccent;
1083
1405
  }
1084
1406
  function ThemeCustomizerProvider({
1085
1407
  children,
@@ -1185,6 +1507,18 @@ function ThemeCustomizerProvider({
1185
1507
  return { ...prev, surfaceStyle: key };
1186
1508
  });
1187
1509
  }, []);
1510
+ const setMenuColor = useCallback((key) => {
1511
+ setConfigState((prev) => {
1512
+ if (prev.menuColor === key) return prev;
1513
+ return { ...prev, menuColor: key };
1514
+ });
1515
+ }, []);
1516
+ const setMenuAccent = useCallback((key) => {
1517
+ setConfigState((prev) => {
1518
+ if (prev.menuAccent === key) return prev;
1519
+ return { ...prev, menuAccent: key };
1520
+ });
1521
+ }, []);
1188
1522
  const resetConfig = useCallback(() => {
1189
1523
  setConfigState(DEFAULT_THEME_CONFIG);
1190
1524
  }, []);
@@ -1202,6 +1536,8 @@ function ThemeCustomizerProvider({
1202
1536
  setFont,
1203
1537
  setShadow,
1204
1538
  setSurfaceStyle,
1539
+ setMenuColor,
1540
+ setMenuAccent,
1205
1541
  resetConfig,
1206
1542
  isDefault,
1207
1543
  generateCSS: generateCSSFn
@@ -1215,6 +1551,8 @@ function ThemeCustomizerProvider({
1215
1551
  setFont,
1216
1552
  setShadow,
1217
1553
  setSurfaceStyle,
1554
+ setMenuColor,
1555
+ setMenuAccent,
1218
1556
  resetConfig,
1219
1557
  isDefault,
1220
1558
  generateCSSFn
@@ -1249,50 +1587,6 @@ function CheckIcon({ className }) {
1249
1587
  }
1250
1588
  );
1251
1589
  }
1252
- function ColorSwatch({
1253
- preset,
1254
- isActive,
1255
- onClick
1256
- }) {
1257
- return /* @__PURE__ */ jsxs(
1258
- "button",
1259
- {
1260
- type: "button",
1261
- onClick,
1262
- className: cn(
1263
- "group relative flex items-center gap-2 rounded-md border px-3 py-2 text-left text-sm transition-all duration-fast ease-standard",
1264
- "hover:border-border-strong hover:bg-muted/50",
1265
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
1266
- isActive ? "border-primary bg-muted/60 shadow-sm" : "border-border bg-transparent"
1267
- ),
1268
- title: preset.name,
1269
- children: [
1270
- /* @__PURE__ */ jsx(
1271
- "span",
1272
- {
1273
- className: cn(
1274
- "size-5 shrink-0 rounded-full border shadow-xs",
1275
- isActive ? "border-primary/50 ring-2 ring-primary/20" : "border-border"
1276
- ),
1277
- style: { backgroundColor: preset.swatch },
1278
- "aria-hidden": "true"
1279
- }
1280
- ),
1281
- /* @__PURE__ */ jsx(
1282
- "span",
1283
- {
1284
- className: cn(
1285
- "text-sm font-medium",
1286
- isActive ? "text-foreground" : "text-muted-foreground"
1287
- ),
1288
- children: preset.name
1289
- }
1290
- ),
1291
- isActive && /* @__PURE__ */ jsx(CheckIcon, { className: "ml-auto text-primary" })
1292
- ]
1293
- }
1294
- );
1295
- }
1296
1590
  function RadiusOption({
1297
1591
  preset,
1298
1592
  isActive,
@@ -1333,49 +1627,433 @@ function RadiusOption({
1333
1627
  }
1334
1628
  );
1335
1629
  }
1336
- function FontOption({
1337
- preset,
1338
- isActive,
1339
- onClick
1340
- }) {
1630
+ function ChevronDownIcon({ className }) {
1631
+ return /* @__PURE__ */ jsx(
1632
+ "svg",
1633
+ {
1634
+ className: cn("size-4 shrink-0", className),
1635
+ xmlns: "http://www.w3.org/2000/svg",
1636
+ viewBox: "0 0 24 24",
1637
+ fill: "none",
1638
+ stroke: "currentColor",
1639
+ strokeWidth: "2",
1640
+ strokeLinecap: "round",
1641
+ strokeLinejoin: "round",
1642
+ "aria-hidden": "true",
1643
+ children: /* @__PURE__ */ jsx("path", { d: "m6 9 6 6 6-6" })
1644
+ }
1645
+ );
1646
+ }
1647
+ function SearchIcon({ className }) {
1341
1648
  return /* @__PURE__ */ jsxs(
1342
- "button",
1649
+ "svg",
1343
1650
  {
1344
- type: "button",
1345
- onClick,
1346
- className: cn(
1347
- "flex items-center gap-2 rounded-md border px-3 py-2 text-left transition-all duration-fast ease-standard",
1348
- "hover:border-border-strong hover:bg-muted/50",
1349
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
1350
- isActive ? "border-primary bg-muted/60 shadow-sm" : "border-border bg-transparent"
1351
- ),
1352
- title: preset.name,
1651
+ className: cn("size-4 shrink-0", className),
1652
+ xmlns: "http://www.w3.org/2000/svg",
1653
+ viewBox: "0 0 24 24",
1654
+ fill: "none",
1655
+ stroke: "currentColor",
1656
+ strokeWidth: "2",
1657
+ strokeLinecap: "round",
1658
+ strokeLinejoin: "round",
1659
+ "aria-hidden": "true",
1353
1660
  children: [
1354
- /* @__PURE__ */ jsx(
1355
- "span",
1356
- {
1357
- className: cn(
1358
- "text-base font-semibold leading-none",
1359
- isActive ? "text-foreground" : "text-muted-foreground"
1360
- ),
1361
- style: { fontFamily: preset.value },
1362
- children: preset.sample
1363
- }
1661
+ /* @__PURE__ */ jsx("circle", { cx: "11", cy: "11", r: "8" }),
1662
+ /* @__PURE__ */ jsx("path", { d: "m21 21-4.3-4.3" })
1663
+ ]
1664
+ }
1665
+ );
1666
+ }
1667
+ function FontCombobox({
1668
+ presets,
1669
+ activeKey,
1670
+ onSelect
1671
+ }) {
1672
+ const [open, setOpen] = useState(false);
1673
+ const [search, setSearch] = useState("");
1674
+ const [highlightIndex, setHighlightIndex] = useState(-1);
1675
+ const containerRef = useRef(null);
1676
+ const listRef = useRef(null);
1677
+ const inputRef = useRef(null);
1678
+ const activePreset = useMemo(
1679
+ () => presets.find((p) => p.key === activeKey) ?? presets[0],
1680
+ [presets, activeKey]
1681
+ );
1682
+ const filtered = useMemo(() => {
1683
+ if (!search.trim()) return presets;
1684
+ const q = search.toLowerCase();
1685
+ return presets.filter((p) => p.name.toLowerCase().includes(q));
1686
+ }, [presets, search]);
1687
+ useEffect(() => {
1688
+ setHighlightIndex(0);
1689
+ }, [filtered]);
1690
+ useEffect(() => {
1691
+ if (!open) return;
1692
+ function handleClick(e) {
1693
+ if (containerRef.current && !containerRef.current.contains(e.target)) {
1694
+ setOpen(false);
1695
+ }
1696
+ }
1697
+ document.addEventListener("mousedown", handleClick);
1698
+ return () => document.removeEventListener("mousedown", handleClick);
1699
+ }, [open]);
1700
+ useEffect(() => {
1701
+ if (!open) return;
1702
+ function handleKey(e) {
1703
+ if (e.key === "Escape") {
1704
+ setOpen(false);
1705
+ }
1706
+ }
1707
+ document.addEventListener("keydown", handleKey);
1708
+ return () => document.removeEventListener("keydown", handleKey);
1709
+ }, [open]);
1710
+ useEffect(() => {
1711
+ if (open) {
1712
+ requestAnimationFrame(() => inputRef.current?.focus());
1713
+ } else {
1714
+ setSearch("");
1715
+ setHighlightIndex(-1);
1716
+ }
1717
+ }, [open]);
1718
+ useEffect(() => {
1719
+ if (!open || highlightIndex < 0 || !listRef.current) return;
1720
+ const items = listRef.current.querySelectorAll("[data-font-item]");
1721
+ items[highlightIndex]?.scrollIntoView({ block: "nearest" });
1722
+ }, [highlightIndex, open]);
1723
+ const handleSelect = useCallback(
1724
+ (key) => {
1725
+ onSelect(key);
1726
+ setOpen(false);
1727
+ },
1728
+ [onSelect]
1729
+ );
1730
+ const handleKeyDown = useCallback(
1731
+ (e) => {
1732
+ if (e.key === "ArrowDown") {
1733
+ e.preventDefault();
1734
+ setHighlightIndex((i) => Math.min(i + 1, filtered.length - 1));
1735
+ } else if (e.key === "ArrowUp") {
1736
+ e.preventDefault();
1737
+ setHighlightIndex((i) => Math.max(i - 1, 0));
1738
+ } else if (e.key === "Enter") {
1739
+ e.preventDefault();
1740
+ if (highlightIndex >= 0 && highlightIndex < filtered.length) {
1741
+ handleSelect(filtered[highlightIndex].key);
1742
+ }
1743
+ }
1744
+ },
1745
+ [filtered, highlightIndex, handleSelect]
1746
+ );
1747
+ return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "relative", children: [
1748
+ /* @__PURE__ */ jsxs(
1749
+ "button",
1750
+ {
1751
+ type: "button",
1752
+ onClick: () => setOpen((prev) => !prev),
1753
+ className: cn(
1754
+ "flex w-full items-center gap-2 rounded-md border px-3 py-2 text-left text-sm transition-all duration-fast ease-standard",
1755
+ "hover:border-border-strong hover:bg-muted/50",
1756
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
1757
+ open ? "border-primary shadow-sm" : "border-border"
1364
1758
  ),
1365
- /* @__PURE__ */ jsx(
1366
- "span",
1367
- {
1368
- className: cn(
1369
- "text-sm",
1370
- isActive ? "text-foreground font-medium" : "text-muted-foreground"
1371
- ),
1372
- children: preset.name
1373
- }
1759
+ "aria-haspopup": "listbox",
1760
+ "aria-expanded": open,
1761
+ children: [
1762
+ /* @__PURE__ */ jsx(
1763
+ "span",
1764
+ {
1765
+ className: "text-sm font-semibold leading-none text-muted-foreground",
1766
+ style: { fontFamily: activePreset.value },
1767
+ children: activePreset.sample
1768
+ }
1769
+ ),
1770
+ /* @__PURE__ */ jsx("span", { className: "flex-1 truncate font-medium text-foreground", children: activePreset.name }),
1771
+ /* @__PURE__ */ jsx(
1772
+ ChevronDownIcon,
1773
+ {
1774
+ className: cn(
1775
+ "text-muted-foreground transition-transform duration-fast",
1776
+ open && "rotate-180"
1777
+ )
1778
+ }
1779
+ )
1780
+ ]
1781
+ }
1782
+ ),
1783
+ open && /* @__PURE__ */ jsxs(
1784
+ "div",
1785
+ {
1786
+ className: cn(
1787
+ "absolute left-0 z-50 mt-1 w-full rounded-md border border-border bg-popover shadow-md",
1788
+ "animate-in fade-in-0 zoom-in-95 slide-in-from-top-2"
1374
1789
  ),
1375
- isActive && /* @__PURE__ */ jsx(CheckIcon, { className: "ml-auto text-primary" })
1376
- ]
1790
+ role: "dialog",
1791
+ "aria-label": "Select font",
1792
+ children: [
1793
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 border-b border-border px-3 py-2", children: [
1794
+ /* @__PURE__ */ jsx(SearchIcon, { className: "text-muted-foreground" }),
1795
+ /* @__PURE__ */ jsx(
1796
+ "input",
1797
+ {
1798
+ ref: inputRef,
1799
+ type: "text",
1800
+ value: search,
1801
+ onChange: (e) => setSearch(e.target.value),
1802
+ onKeyDown: handleKeyDown,
1803
+ placeholder: "Search fonts\u2026",
1804
+ className: "flex-1 bg-transparent text-sm text-foreground placeholder:text-muted-foreground outline-none",
1805
+ "aria-label": "Search fonts",
1806
+ autoComplete: "off",
1807
+ spellCheck: false
1808
+ }
1809
+ )
1810
+ ] }),
1811
+ /* @__PURE__ */ jsx(
1812
+ "div",
1813
+ {
1814
+ ref: listRef,
1815
+ className: "max-h-52 overflow-y-auto overscroll-contain p-1",
1816
+ role: "listbox",
1817
+ children: filtered.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-3 py-4 text-center text-sm text-muted-foreground", children: "No fonts found" }) : filtered.map((preset, index) => {
1818
+ const isActive = preset.key === activeKey;
1819
+ const isHighlighted = index === highlightIndex;
1820
+ return /* @__PURE__ */ jsxs(
1821
+ "button",
1822
+ {
1823
+ type: "button",
1824
+ "data-font-item": "",
1825
+ role: "option",
1826
+ "aria-selected": isActive,
1827
+ onClick: () => handleSelect(preset.key),
1828
+ onMouseEnter: () => setHighlightIndex(index),
1829
+ className: cn(
1830
+ "flex w-full items-center gap-2.5 rounded-sm px-2.5 py-1.5 text-left text-sm transition-colors",
1831
+ "outline-none",
1832
+ isHighlighted && "bg-muted",
1833
+ isActive && "text-foreground font-medium",
1834
+ !isActive && "text-muted-foreground"
1835
+ ),
1836
+ children: [
1837
+ /* @__PURE__ */ jsx(
1838
+ "span",
1839
+ {
1840
+ className: "w-6 text-center text-base font-semibold leading-none",
1841
+ style: { fontFamily: preset.value },
1842
+ "aria-hidden": "true",
1843
+ children: preset.sample
1844
+ }
1845
+ ),
1846
+ /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: preset.name }),
1847
+ isActive && /* @__PURE__ */ jsx(CheckIcon, { className: "text-primary shrink-0" })
1848
+ ]
1849
+ },
1850
+ preset.key
1851
+ );
1852
+ })
1853
+ }
1854
+ )
1855
+ ]
1856
+ }
1857
+ )
1858
+ ] });
1859
+ }
1860
+ function ColorCombobox({
1861
+ presets,
1862
+ activeKey,
1863
+ onSelect
1864
+ }) {
1865
+ const [open, setOpen] = useState(false);
1866
+ const [search, setSearch] = useState("");
1867
+ const [highlightIndex, setHighlightIndex] = useState(-1);
1868
+ const containerRef = useRef(null);
1869
+ const listRef = useRef(null);
1870
+ const inputRef = useRef(null);
1871
+ const activePreset = useMemo(
1872
+ () => presets.find((p) => p.key === activeKey) ?? presets[0],
1873
+ [presets, activeKey]
1874
+ );
1875
+ const filtered = useMemo(() => {
1876
+ if (!search.trim()) return presets;
1877
+ const q = search.toLowerCase();
1878
+ return presets.filter((p) => p.name.toLowerCase().includes(q));
1879
+ }, [presets, search]);
1880
+ useEffect(() => {
1881
+ setHighlightIndex(0);
1882
+ }, [filtered]);
1883
+ useEffect(() => {
1884
+ if (!open) return;
1885
+ function handleClick(e) {
1886
+ if (containerRef.current && !containerRef.current.contains(e.target)) {
1887
+ setOpen(false);
1888
+ }
1889
+ }
1890
+ document.addEventListener("mousedown", handleClick);
1891
+ return () => document.removeEventListener("mousedown", handleClick);
1892
+ }, [open]);
1893
+ useEffect(() => {
1894
+ if (!open) return;
1895
+ function handleKey(e) {
1896
+ if (e.key === "Escape") {
1897
+ setOpen(false);
1898
+ }
1377
1899
  }
1900
+ document.addEventListener("keydown", handleKey);
1901
+ return () => document.removeEventListener("keydown", handleKey);
1902
+ }, [open]);
1903
+ useEffect(() => {
1904
+ if (open) {
1905
+ requestAnimationFrame(() => inputRef.current?.focus());
1906
+ } else {
1907
+ setSearch("");
1908
+ setHighlightIndex(-1);
1909
+ }
1910
+ }, [open]);
1911
+ useEffect(() => {
1912
+ if (!open || highlightIndex < 0 || !listRef.current) return;
1913
+ const items = listRef.current.querySelectorAll("[data-color-item]");
1914
+ items[highlightIndex]?.scrollIntoView({ block: "nearest" });
1915
+ }, [highlightIndex, open]);
1916
+ const handleSelect = useCallback(
1917
+ (key) => {
1918
+ onSelect(key);
1919
+ setOpen(false);
1920
+ },
1921
+ [onSelect]
1378
1922
  );
1923
+ const handleKeyDown = useCallback(
1924
+ (e) => {
1925
+ if (e.key === "ArrowDown") {
1926
+ e.preventDefault();
1927
+ setHighlightIndex((i) => Math.min(i + 1, filtered.length - 1));
1928
+ } else if (e.key === "ArrowUp") {
1929
+ e.preventDefault();
1930
+ setHighlightIndex((i) => Math.max(i - 1, 0));
1931
+ } else if (e.key === "Enter") {
1932
+ e.preventDefault();
1933
+ if (highlightIndex >= 0 && highlightIndex < filtered.length) {
1934
+ handleSelect(filtered[highlightIndex].key);
1935
+ }
1936
+ }
1937
+ },
1938
+ [filtered, highlightIndex, handleSelect]
1939
+ );
1940
+ return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "relative", children: [
1941
+ /* @__PURE__ */ jsxs(
1942
+ "button",
1943
+ {
1944
+ type: "button",
1945
+ onClick: () => setOpen((prev) => !prev),
1946
+ className: cn(
1947
+ "flex w-full items-center gap-2 rounded-md border px-3 py-2 text-left text-sm transition-all duration-fast ease-standard",
1948
+ "hover:border-border-strong hover:bg-muted/50",
1949
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
1950
+ open ? "border-primary shadow-sm" : "border-border"
1951
+ ),
1952
+ "aria-haspopup": "listbox",
1953
+ "aria-expanded": open,
1954
+ children: [
1955
+ /* @__PURE__ */ jsx(
1956
+ "span",
1957
+ {
1958
+ className: cn(
1959
+ "size-5 shrink-0 rounded-full border shadow-xs",
1960
+ "border-border"
1961
+ ),
1962
+ style: { backgroundColor: activePreset.swatch },
1963
+ "aria-hidden": "true"
1964
+ }
1965
+ ),
1966
+ /* @__PURE__ */ jsx("span", { className: "flex-1 truncate font-medium text-foreground", children: activePreset.name }),
1967
+ /* @__PURE__ */ jsx(
1968
+ ChevronDownIcon,
1969
+ {
1970
+ className: cn(
1971
+ "text-muted-foreground transition-transform duration-fast",
1972
+ open && "rotate-180"
1973
+ )
1974
+ }
1975
+ )
1976
+ ]
1977
+ }
1978
+ ),
1979
+ open && /* @__PURE__ */ jsxs(
1980
+ "div",
1981
+ {
1982
+ className: cn(
1983
+ "absolute left-0 z-50 mt-1 w-full rounded-md border border-border bg-popover shadow-md",
1984
+ "animate-in fade-in-0 zoom-in-95 slide-in-from-top-2"
1985
+ ),
1986
+ role: "dialog",
1987
+ "aria-label": "Select color",
1988
+ children: [
1989
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 border-b border-border px-3 py-2", children: [
1990
+ /* @__PURE__ */ jsx(SearchIcon, { className: "text-muted-foreground" }),
1991
+ /* @__PURE__ */ jsx(
1992
+ "input",
1993
+ {
1994
+ ref: inputRef,
1995
+ type: "text",
1996
+ value: search,
1997
+ onChange: (e) => setSearch(e.target.value),
1998
+ onKeyDown: handleKeyDown,
1999
+ placeholder: "Search colors\u2026",
2000
+ className: "flex-1 bg-transparent text-sm text-foreground placeholder:text-muted-foreground outline-none",
2001
+ "aria-label": "Search colors",
2002
+ autoComplete: "off",
2003
+ spellCheck: false
2004
+ }
2005
+ )
2006
+ ] }),
2007
+ /* @__PURE__ */ jsx(
2008
+ "div",
2009
+ {
2010
+ ref: listRef,
2011
+ className: "max-h-52 overflow-y-auto overscroll-contain p-1",
2012
+ role: "listbox",
2013
+ children: filtered.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-3 py-4 text-center text-sm text-muted-foreground", children: "No colors found" }) : filtered.map((preset, index) => {
2014
+ const isActive = preset.key === activeKey;
2015
+ const isHighlighted = index === highlightIndex;
2016
+ return /* @__PURE__ */ jsxs(
2017
+ "button",
2018
+ {
2019
+ type: "button",
2020
+ "data-color-item": "",
2021
+ role: "option",
2022
+ "aria-selected": isActive,
2023
+ onClick: () => handleSelect(preset.key),
2024
+ onMouseEnter: () => setHighlightIndex(index),
2025
+ className: cn(
2026
+ "flex w-full items-center gap-2.5 rounded-sm px-2.5 py-1.5 text-left text-sm transition-colors",
2027
+ "outline-none",
2028
+ isHighlighted && "bg-muted",
2029
+ isActive && "text-foreground font-medium",
2030
+ !isActive && "text-muted-foreground"
2031
+ ),
2032
+ children: [
2033
+ /* @__PURE__ */ jsx(
2034
+ "span",
2035
+ {
2036
+ className: cn(
2037
+ "size-4 shrink-0 rounded-full border shadow-xs",
2038
+ isActive ? "border-primary/50 ring-2 ring-primary/20" : "border-border"
2039
+ ),
2040
+ style: { backgroundColor: preset.swatch },
2041
+ "aria-hidden": "true"
2042
+ }
2043
+ ),
2044
+ /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: preset.name }),
2045
+ isActive && /* @__PURE__ */ jsx(CheckIcon, { className: "text-primary shrink-0" })
2046
+ ]
2047
+ },
2048
+ preset.key
2049
+ );
2050
+ })
2051
+ }
2052
+ )
2053
+ ]
2054
+ }
2055
+ )
2056
+ ] });
1379
2057
  }
1380
2058
  function PillToggle({
1381
2059
  label,
@@ -1533,6 +2211,8 @@ function ThemeCustomizer({
1533
2211
  setFont,
1534
2212
  setShadow,
1535
2213
  setSurfaceStyle,
2214
+ setMenuColor,
2215
+ setMenuAccent,
1536
2216
  resetConfig,
1537
2217
  isDefault,
1538
2218
  generateCSS
@@ -1553,15 +2233,14 @@ function ThemeCustomizer({
1553
2233
  },
1554
2234
  preset.key
1555
2235
  )) }) }),
1556
- /* @__PURE__ */ jsx(Section, { title: "Color", children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-2", children: COLOR_PRESETS.map((preset) => /* @__PURE__ */ jsx(
1557
- ColorSwatch,
2236
+ /* @__PURE__ */ jsx(Section, { title: "Color", children: /* @__PURE__ */ jsx(
2237
+ ColorCombobox,
1558
2238
  {
1559
- preset,
1560
- isActive: config.colorPreset === preset.key,
1561
- onClick: () => setColorPreset(preset.key)
1562
- },
1563
- preset.key
1564
- )) }) }),
2239
+ presets: COLOR_PRESETS,
2240
+ activeKey: config.colorPreset,
2241
+ onSelect: setColorPreset
2242
+ }
2243
+ ) }),
1565
2244
  /* @__PURE__ */ jsx(Section, { title: "Radius", children: /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: RADIUS_PRESETS.map((preset) => /* @__PURE__ */ jsx(
1566
2245
  RadiusOption,
1567
2246
  {
@@ -1571,15 +2250,14 @@ function ThemeCustomizer({
1571
2250
  },
1572
2251
  preset.key
1573
2252
  )) }) }),
1574
- /* @__PURE__ */ jsx(Section, { title: "Font", children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 gap-2", children: FONT_PRESETS.map((preset) => /* @__PURE__ */ jsx(
1575
- FontOption,
2253
+ /* @__PURE__ */ jsx(Section, { title: "Font", children: /* @__PURE__ */ jsx(
2254
+ FontCombobox,
1576
2255
  {
1577
- preset,
1578
- isActive: config.font === preset.key,
1579
- onClick: () => setFont(preset.key)
1580
- },
1581
- preset.key
1582
- )) }) }),
2256
+ presets: FONT_PRESETS,
2257
+ activeKey: config.font,
2258
+ onSelect: setFont
2259
+ }
2260
+ ) }),
1583
2261
  /* @__PURE__ */ jsx(Section, { title: "Shadow", children: /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: SHADOW_PRESETS.map((preset) => /* @__PURE__ */ jsx(
1584
2262
  PillToggle,
1585
2263
  {
@@ -1600,6 +2278,26 @@ function ThemeCustomizer({
1600
2278
  },
1601
2279
  preset.key
1602
2280
  )) }) }),
2281
+ /* @__PURE__ */ jsx(Section, { title: "Menu Color", children: /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: MENU_COLOR_PRESETS.map((preset) => /* @__PURE__ */ jsx(
2282
+ PillToggle,
2283
+ {
2284
+ label: preset.name,
2285
+ isActive: config.menuColor === preset.key,
2286
+ onClick: () => setMenuColor(preset.key),
2287
+ description: preset.description
2288
+ },
2289
+ preset.key
2290
+ )) }) }),
2291
+ /* @__PURE__ */ jsx(Section, { title: "Menu Accent", children: /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: MENU_ACCENT_PRESETS.map((preset) => /* @__PURE__ */ jsx(
2292
+ PillToggle,
2293
+ {
2294
+ label: preset.name,
2295
+ isActive: config.menuAccent === preset.key,
2296
+ onClick: () => setMenuAccent(preset.key),
2297
+ description: preset.description
2298
+ },
2299
+ preset.key
2300
+ )) }) }),
1603
2301
  (showCopyButton || showResetButton) && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 border-t border-border pt-4", children: [
1604
2302
  showCopyButton && /* @__PURE__ */ jsx(CopyButton, { getText: generateCSS, className: "flex-1" }),
1605
2303
  showResetButton && !isDefault && /* @__PURE__ */ jsxs(
@@ -1732,4 +2430,4 @@ function DSThemeProvider({
1732
2430
  return /* @__PURE__ */ jsx(DSThemeContext.Provider, { value, children });
1733
2431
  }
1734
2432
 
1735
- export { COLOR_PRESETS, COLOR_PRESET_KEYS, DEFAULT_FONT_KEY, DEFAULT_RADIUS_KEY, DEFAULT_SHADOW_KEY, DEFAULT_STYLE_KEY, DEFAULT_SURFACE_STYLE_KEY, DEFAULT_THEME_CONFIG, DSThemeProvider, FONT_PRESETS, RADIUS_PRESETS, SHADOW_PRESETS, STYLE_PRESETS, SURFACE_STYLE_PRESETS, ThemeCustomizer, ThemeCustomizerProvider, buildDarkThemeVars, buildLightThemeVars, buildThemeCSS, buildThemeOverrides, contract, cssVar, generateThemeCSS, getColorPreset, getFontPreset, getRadiusPreset, getShadowPreset, getStylePreset, useDSTheme, useThemeCustomizer };
2433
+ export { COLOR_PRESETS, COLOR_PRESET_KEYS, DEFAULT_FONT_KEY, DEFAULT_MENU_ACCENT_KEY, DEFAULT_MENU_COLOR_KEY, DEFAULT_RADIUS_KEY, DEFAULT_SHADOW_KEY, DEFAULT_STYLE_KEY, DEFAULT_SURFACE_STYLE_KEY, DEFAULT_THEME_CONFIG, DSThemeProvider, FONT_PRESETS, MENU_ACCENT_PRESETS, MENU_COLOR_PRESETS, RADIUS_PRESETS, SHADOW_PRESETS, STYLE_PRESETS, SURFACE_STYLE_PRESETS, ThemeCustomizer, ThemeCustomizerContext, ThemeCustomizerProvider, buildDarkThemeVars, buildLightThemeVars, buildThemeCSS, buildThemeOverrides, contract, cssVar, generateThemeCSS, getColorPreset, getFontPreset, getMenuAccentPreset, getMenuColorPreset, getRadiusPreset, getShadowPreset, getStylePreset, useDSTheme, useThemeCustomizer };