@uni-design-system/uni-core 5.0.0 → 5.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.
@@ -762,6 +762,65 @@ var Z_INDEX = {
762
762
  overlay: 1080
763
763
  };
764
764
  //#endregion
765
+ //#region src/concepts/generation/dtcg.emitter.ts
766
+ var dimensionEntries = (record) => Object.fromEntries(Object.entries(record ?? {}).filter(([, value]) => value !== void 0 && value !== "none").map(([key, value]) => [key, {
767
+ $value: String(value),
768
+ $type: "dimension"
769
+ }]));
770
+ /**
771
+ * Render one theme mode's tokens as W3C DTCG JSON for external pipelines
772
+ * (Style Dictionary etc.). Token names are exactly Uni's `ColorToken` strings —
773
+ * one vocabulary everywhere. The native `UniTheme` object remains the primary,
774
+ * lossless output; this is the interop layer.
775
+ */
776
+ var emitDtcgTokens = (input) => ({
777
+ color: Object.fromEntries(Object.entries(input.colors).filter(([, value]) => value !== void 0).map(([key, value]) => [key, {
778
+ $value: value,
779
+ $type: "color"
780
+ }])),
781
+ size: {
782
+ radius: dimensionEntries(input.radii),
783
+ spacing: dimensionEntries(input.spacing)
784
+ }
785
+ });
786
+ //#endregion
787
+ //#region src/concepts/generation/shadow.generator.ts
788
+ var rgba = (hex, alpha) => {
789
+ const { red, green, blue } = hexToRgb(hex);
790
+ return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
791
+ };
792
+ /**
793
+ * Brand-tinted, theme-scoped elevation shadows (PRD §3.5.C).
794
+ *
795
+ * Light mode replaces the dead-neutral black stacks with a shadow ink pulled
796
+ * toward the brand hue — dark and low-chroma enough to read as shadow, tinted
797
+ * enough to kill the grey "mud" where shadows meet brand surfaces. Dark mode
798
+ * goes near-zero: elevation is carried by the surface lightness steps, with
799
+ * only a faint veil kept on floating overlays (menus/dialogs genuinely need
800
+ * separation) and the `warn` glow tinted by the theme's own error color.
801
+ */
802
+ var generateShadows = (colors, mode = "light") => {
803
+ const error = colors["error"] ?? "#CC2827";
804
+ if (mode === "dark") return {
805
+ raised: "none",
806
+ menu: `0px 4px 12px ${rgba("#000000", .45)}`,
807
+ dialog: `0px 8px 28px ${rgba("#000000", .55)}`,
808
+ warn: `0 0 5px ${rgba(error, .55)}, inset 0 0 5px ${rgba(error, .35)}`
809
+ };
810
+ const { h } = hexToOklch(colors["primary"] ?? "#000000");
811
+ const ink = oklchToHex({
812
+ l: .22,
813
+ c: .035,
814
+ h
815
+ });
816
+ return {
817
+ raised: `${rgba(ink, .2)} 0px 2px 1px -1px, ${rgba(ink, .14)} 0px 1px 1px 0px, ${rgba(ink, .12)} 0px 1px 3px 0px`,
818
+ menu: `${rgba(ink, .2)} 0px 3px 3px -2px, ${rgba(ink, .14)} 0px 3px 4px 0px, ${rgba(ink, .12)} 0px 1px 8px 0px`,
819
+ dialog: `${rgba(ink, .2)} 0px 3px 5px -1px, ${rgba(ink, .14)} 0px 6px 10px 0px, ${rgba(ink, .12)} 0px 1px 18px 0px`,
820
+ warn: `0 0 5px ${rgba(error, .5)}, inset 0 0 5px ${rgba(error, .3)}`
821
+ };
822
+ };
823
+ //#endregion
765
824
  //#region src/concepts/theme/themes/base.theme.ts
766
825
  var BaseTypography = {
767
826
  "display-large": {
@@ -959,6 +1018,90 @@ var buildComponents = (c) => ({
959
1018
  transitionSpeed: .35,
960
1019
  elevation: "md"
961
1020
  } },
1021
+ breadcrumb: { options: {
1022
+ typeface: "label",
1023
+ color: "on-background-variant",
1024
+ currentColor: "on-background",
1025
+ separatorSymbol: "chevron_right",
1026
+ gap: "xs"
1027
+ } },
1028
+ appBar: { options: {
1029
+ color: "surface",
1030
+ height: 56,
1031
+ divider: "light",
1032
+ typeface: "title-large",
1033
+ padding: "md",
1034
+ gap: "md",
1035
+ elevation: void 0
1036
+ } },
1037
+ drawer: { options: {
1038
+ color: "surface",
1039
+ width: 280,
1040
+ divider: "light",
1041
+ elevation: "menu",
1042
+ padding: "md",
1043
+ backdrop: { background: "rgba(0, 0, 0, 0.4)" }
1044
+ } },
1045
+ avatar: {
1046
+ options: {
1047
+ borderRadius: "max",
1048
+ typeface: "subtitle-2",
1049
+ fallbackSymbol: "person"
1050
+ },
1051
+ variants: {
1052
+ primary: {
1053
+ backgroundColor: c["primary-container"],
1054
+ color: c["on-primary-container"]
1055
+ },
1056
+ secondary: {
1057
+ backgroundColor: c["secondary-container"],
1058
+ color: c["on-secondary-container"]
1059
+ },
1060
+ tertiary: {
1061
+ backgroundColor: c["tertiary-container"],
1062
+ color: c["on-tertiary-container"]
1063
+ },
1064
+ quaternary: {
1065
+ backgroundColor: c["surface-variant"],
1066
+ color: c["on-surface-variant"]
1067
+ },
1068
+ warn: {
1069
+ backgroundColor: c["warn-container"],
1070
+ color: c["on-warn-container"]
1071
+ },
1072
+ success: {
1073
+ backgroundColor: c["success-container"],
1074
+ color: c["on-success-container"]
1075
+ }
1076
+ },
1077
+ sizes: {
1078
+ sm: {
1079
+ height: 24,
1080
+ width: 24,
1081
+ fontSize: 10
1082
+ },
1083
+ md: {
1084
+ height: 32,
1085
+ width: 32,
1086
+ fontSize: 13
1087
+ },
1088
+ lg: {
1089
+ height: 40,
1090
+ width: 40,
1091
+ fontSize: 16
1092
+ },
1093
+ xl: {
1094
+ height: 56,
1095
+ width: 56,
1096
+ fontSize: 22
1097
+ }
1098
+ }
1099
+ },
1100
+ avatarGroup: { options: {
1101
+ overlap: "sm",
1102
+ ringColor: "surface",
1103
+ ringWidth: 2
1104
+ } },
962
1105
  checkbox: { options: { size: 20 } },
963
1106
  dialog: { options: {
964
1107
  borderRadius: "lg",
@@ -1007,6 +1150,22 @@ var buildComponents = (c) => ({
1007
1150
  focusOutline: `2px solid ${c.primary}`,
1008
1151
  focusOutlineOffset: 2
1009
1152
  } },
1153
+ textarea: { options: {
1154
+ rows: 3,
1155
+ resize: "vertical"
1156
+ } },
1157
+ tabs: { options: {
1158
+ typeface: "title-small",
1159
+ textColor: "on-surface-variant",
1160
+ activeTextColor: "primary",
1161
+ indicatorColor: "primary",
1162
+ indicatorThickness: "standard",
1163
+ divider: "light",
1164
+ gap: "sm",
1165
+ borderRadius: "none",
1166
+ padding: "md",
1167
+ activeColor: void 0
1168
+ } },
1010
1169
  multiSelectDropdown: { options: {
1011
1170
  textRole: "input",
1012
1171
  textColor: "on-primary-surface",
@@ -1018,13 +1177,16 @@ var buildComponents = (c) => ({
1018
1177
  } },
1019
1178
  badge: { options: { borderRadius: "xxs" } },
1020
1179
  button: {
1180
+ options: {
1181
+ borderRadius: "max",
1182
+ typeface: "button"
1183
+ },
1021
1184
  fixed: {
1022
1185
  position: "relative",
1023
1186
  overflow: "hidden",
1024
1187
  outline: "0",
1025
1188
  border: "0",
1026
1189
  cursor: "pointer",
1027
- fontFamily: "Euphemia, sans-serif",
1028
1190
  transition: "all 0.28s ease"
1029
1191
  },
1030
1192
  variants: {
@@ -1075,33 +1237,29 @@ var buildComponents = (c) => ({
1075
1237
  sizes: {
1076
1238
  sm: {
1077
1239
  height: 22,
1078
- borderRadius: 11,
1079
1240
  fontSize: 12,
1080
1241
  padding: "0 12px",
1081
- fontFamily: "Euphemia Bold, sans-serif",
1082
1242
  fontWeight: 600
1083
1243
  },
1084
1244
  md: {
1085
1245
  height: 26,
1086
- borderRadius: 13,
1087
1246
  fontSize: 16,
1088
1247
  padding: "0 16px"
1089
1248
  },
1090
1249
  lg: {
1091
1250
  height: 36,
1092
- borderRadius: 18,
1093
1251
  fontSize: 18,
1094
1252
  padding: "0 18px"
1095
1253
  },
1096
1254
  xl: {
1097
1255
  height: 48,
1098
- borderRadius: 24,
1099
1256
  fontSize: 24,
1100
1257
  padding: "0 22px"
1101
1258
  }
1102
1259
  }
1103
1260
  },
1104
1261
  iconButton: {
1262
+ options: { borderRadius: "max" },
1105
1263
  variants: {
1106
1264
  ghost: {
1107
1265
  backgroundColor: "transparent",
@@ -1167,23 +1325,23 @@ var buildComponents = (c) => ({
1167
1325
  fixed: { textFill: c["on-background"] },
1168
1326
  variants: {
1169
1327
  primary: {
1170
- backgroundColor: "#b3d4ea",
1328
+ backgroundColor: c["primary-container"],
1171
1329
  color: c.primary
1172
1330
  },
1173
1331
  secondary: {
1174
- backgroundColor: "#b3e7c2",
1332
+ backgroundColor: c["secondary-container"],
1175
1333
  color: c.secondary
1176
1334
  },
1177
1335
  tertiary: {
1178
- backgroundColor: "#ffe2b3",
1336
+ backgroundColor: c["tertiary-container"],
1179
1337
  color: c.tertiary
1180
1338
  },
1181
1339
  warn: {
1182
- backgroundColor: "#ffc2b3",
1340
+ backgroundColor: c["warn-container"],
1183
1341
  color: c.warn
1184
1342
  },
1185
1343
  success: {
1186
- backgroundColor: "#b3e7c2",
1344
+ backgroundColor: c["success-container"],
1187
1345
  color: c.success
1188
1346
  }
1189
1347
  },
@@ -1195,33 +1353,10 @@ var buildComponents = (c) => ({
1195
1353
  }
1196
1354
  },
1197
1355
  card: {
1356
+ options: { borderRadius: "xs" },
1198
1357
  fixed: {
1199
- borderStyle: "solid",
1200
- borderWidth: "1px",
1201
- borderRadius: "8px",
1202
- overflow: "hidden"
1203
- },
1204
- variants: {
1205
- primary: {
1206
- borderColor: c.primary,
1207
- backgroundColor: c.background
1208
- },
1209
- secondary: {
1210
- borderColor: c.secondary,
1211
- backgroundColor: c.background
1212
- },
1213
- tertiary: {
1214
- borderColor: c.tertiary,
1215
- backgroundColor: c.background
1216
- },
1217
- warn: {
1218
- borderColor: c.warn,
1219
- backgroundColor: c.background
1220
- },
1221
- success: {
1222
- borderColor: c.success,
1223
- backgroundColor: c.background
1224
- }
1358
+ overflow: "hidden",
1359
+ backgroundColor: c.background
1225
1360
  }
1226
1361
  },
1227
1362
  cardHeader: {
@@ -1292,6 +1427,21 @@ var buildComponents = (c) => ({
1292
1427
  currentPageBorder: "light",
1293
1428
  currentPageBorderRadius: "xs"
1294
1429
  } },
1430
+ slider: { options: {
1431
+ color: "primary",
1432
+ trackColor: "surface-variant",
1433
+ borderRadius: "max",
1434
+ trackHeight: 4,
1435
+ thumbSize: 16
1436
+ } },
1437
+ skeleton: { options: {
1438
+ color: "surface-variant",
1439
+ highlightColor: "surface",
1440
+ borderRadius: "xs",
1441
+ animation: "shimmer",
1442
+ duration: 1.4,
1443
+ gap: "sm"
1444
+ } },
1295
1445
  snackbar: { options: {
1296
1446
  bottomPosition: 40,
1297
1447
  transitionDelay: "0.35s",
@@ -1337,12 +1487,17 @@ var createTheme = ({ id, name, colors, icons = {}, radii = BaseRadii, shadows =
1337
1487
  * one-call path a theme builder uses to turn a brand color (or a seed +
1338
1488
  * scheme + category) into a complete, ready-to-apply theme.
1339
1489
  */
1340
- var createThemeFromPalette = (config) => createTheme({
1341
- id: config.id ?? "CustomTheme",
1342
- name: config.name ?? "Custom Theme",
1343
- colors: generatePalette(config),
1344
- icons: config.icons
1345
- });
1490
+ var createThemeFromPalette = (config) => {
1491
+ const colors = generatePalette(config);
1492
+ return createTheme({
1493
+ id: config.id ?? "CustomTheme",
1494
+ name: config.name ?? "Custom Theme",
1495
+ colors,
1496
+ radii: config.radii,
1497
+ shadows: generateShadows(colors, config.mode ?? "light"),
1498
+ icons: config.icons
1499
+ });
1500
+ };
1346
1501
  /**
1347
1502
  * Seed for the shipped Light/Dark themes. Swap these three values (or call
1348
1503
  * `generatePalette` with your own) to reskin the entire system — every color
@@ -1465,6 +1620,8 @@ var generateThemes = (input) => {
1465
1620
  lightColors,
1466
1621
  darkColors,
1467
1622
  radii: input.shape ? ShapeRadii[input.shape] : void 0,
1623
+ lightShadows: generateShadows(lightColors, "light"),
1624
+ darkShadows: generateShadows(darkColors, "dark"),
1468
1625
  report: {
1469
1626
  checks,
1470
1627
  worstRatio,
@@ -1477,7 +1634,7 @@ var generateThemes = (input) => {
1477
1634
  * returning a registration-ready light/dark {@link UniTheme} pair.
1478
1635
  */
1479
1636
  var generateUniThemes = (input) => {
1480
- const { lightColors, darkColors, radii } = generateThemes(input);
1637
+ const { lightColors, darkColors, radii, lightShadows, darkShadows } = generateThemes(input);
1481
1638
  const name = input.name ?? "Brand";
1482
1639
  const id = name.replace(/\W+/g, "") || "Brand";
1483
1640
  return {
@@ -1485,13 +1642,15 @@ var generateUniThemes = (input) => {
1485
1642
  id: `${id}Light`,
1486
1643
  name: `${name} Light`,
1487
1644
  colors: lightColors,
1488
- radii
1645
+ radii,
1646
+ shadows: lightShadows
1489
1647
  }),
1490
1648
  dark: createTheme({
1491
1649
  id: `${id}Dark`,
1492
1650
  name: `${name} Dark`,
1493
1651
  colors: darkColors,
1494
- radii
1652
+ radii,
1653
+ shadows: darkShadows
1495
1654
  })
1496
1655
  };
1497
1656
  };
@@ -1508,24 +1667,25 @@ var bordersLiteral = () => [
1508
1667
  " * shared token picks up the change.",
1509
1668
  " */",
1510
1669
  "const borders = (colors: Colors): Borders => ({",
1511
- " primary: `1px solid ${colors.primary}`,",
1512
- " secondary: `1px solid ${colors.secondary}`,",
1513
- " tertiary: `1px solid ${colors.tertiary}`,",
1514
- " quaternary: `1px solid ${colors.quaternary}`,",
1515
- " warn: `1px solid ${colors.warn}`,",
1516
- " success: `1px solid ${colors.success}`,",
1517
- " light: `1px solid ${colors.outline}`,",
1670
+ " primary: `1px solid ${colors['primary']}`,",
1671
+ " secondary: `1px solid ${colors['secondary']}`,",
1672
+ " tertiary: `1px solid ${colors['tertiary']}`,",
1673
+ " quaternary: `1px solid ${colors['quaternary']}`,",
1674
+ " warn: `1px solid ${colors['warn']}`,",
1675
+ " success: `1px solid ${colors['success']}`,",
1676
+ " light: `1px solid ${colors['outline']}`,",
1518
1677
  " dark: `1px solid ${colors['on-background']}`,",
1519
1678
  " dotted: `1px dotted ${colors['on-background']}`,",
1520
1679
  "});"
1521
1680
  ].join("\n");
1522
- var themeExport = (exportName, displayName, colorsConst, radii) => [
1681
+ var themeExport = (exportName, displayName, colorsConst, shadowsConst, radii) => [
1523
1682
  `export const ${exportName}: UniTheme = createTheme({`,
1524
1683
  ` id: '${exportName}',`,
1525
1684
  ` name: '${displayName}',`,
1526
1685
  ` colors: ${colorsConst},`,
1527
1686
  ` borders: borders(${colorsConst}),`,
1528
1687
  ` components: components(${colorsConst}),`,
1688
+ ` shadows: ${shadowsConst},`,
1529
1689
  ...radii ? [" radii,"] : [],
1530
1690
  "});"
1531
1691
  ].join("\n");
@@ -1540,7 +1700,7 @@ var themeExport = (exportName, displayName, colorsConst, radii) => [
1540
1700
  */
1541
1701
  var emitThemeFile = (input) => {
1542
1702
  const { darkMode = true, name = "Brand" } = input;
1543
- const { lightColors, darkColors, radii, report } = generateThemes(input);
1703
+ const { lightColors, darkColors, radii, lightShadows, darkShadows, report } = generateThemes(input);
1544
1704
  const id = name.replace(/\W+/g, "") || "Brand";
1545
1705
  const regenerate = [
1546
1706
  `--brand=${(Array.isArray(input.seed) ? input.seed : [input.seed]).join(",")}`,
@@ -1554,12 +1714,16 @@ var emitThemeFile = (input) => {
1554
1714
  exportName: `${id}Light`,
1555
1715
  displayName: `${name} Light`,
1556
1716
  colorsConst: "lightColors",
1557
- colors: lightColors
1717
+ colors: lightColors,
1718
+ shadowsConst: "lightShadows",
1719
+ shadows: lightShadows
1558
1720
  }, ...darkMode ? [{
1559
1721
  exportName: `${id}Dark`,
1560
1722
  displayName: `${name} Dark`,
1561
1723
  colorsConst: "darkColors",
1562
- colors: darkColors
1724
+ colors: darkColors,
1725
+ shadowsConst: "darkShadows",
1726
+ shadows: darkShadows
1563
1727
  }] : []];
1564
1728
  return {
1565
1729
  content: [
@@ -1576,16 +1740,19 @@ var emitThemeFile = (input) => {
1576
1740
  " type Borders,",
1577
1741
  " type Colors,",
1578
1742
  " type ComponentThemes,",
1743
+ " type Shadows,",
1579
1744
  " type UniTheme,",
1580
1745
  "} from '@uni-design-system/uni-core';",
1581
1746
  "",
1582
1747
  ...modes.map(({ colorsConst, colors }) => `const ${colorsConst}: Colors = {\n${recordLiteral(colors, " ")}\n};\n`),
1748
+ "/** Brand-tinted elevation shadows — theme-scoped, edit freely. */",
1749
+ ...modes.map(({ shadowsConst, shadows }) => `const ${shadowsConst}: Shadows = {\n${recordLiteral(shadows, " ")}\n};\n`),
1583
1750
  bordersLiteral(),
1584
1751
  "",
1585
1752
  "/**",
1586
1753
  " * Sparse component overrides, deep-merged over Uni component defaults: only",
1587
1754
  " * what you write here changes. Point components at your own primitives, e.g.:",
1588
- " * button: { variants: { secondary: { border: `2px dashed ${colors.tertiary}` } } },",
1755
+ " * button: { variants: { secondary: { border: `2px dashed ${colors['tertiary']}` } } },",
1589
1756
  " * input: { options: { borderRadius: 'max' } },",
1590
1757
  " */",
1591
1758
  "const components = (colors: Colors): ComponentThemes => ({});",
@@ -1595,7 +1762,7 @@ var emitThemeFile = (input) => {
1595
1762
  `const radii = {\n${recordLiteral(radii, " ")}\n};`,
1596
1763
  ""
1597
1764
  ] : [],
1598
- ...modes.map(({ exportName, displayName, colorsConst }) => `${themeExport(exportName, displayName, colorsConst, !!radii)}\n`),
1765
+ ...modes.map(({ exportName, displayName, colorsConst, shadowsConst }) => `${themeExport(exportName, displayName, colorsConst, shadowsConst, !!radii)}\n`),
1599
1766
  "/** First key wins as the default theme when registered via UNI_THEMES. */",
1600
1767
  `export const ${id}Themes = { ${modes.map((m) => m.exportName).join(", ")} };`,
1601
1768
  ""
@@ -1730,14 +1897,16 @@ var darkColors = generatePalette({
1730
1897
  var DarkTheme = createTheme({
1731
1898
  id: "DarkTheme",
1732
1899
  name: "Dark Theme",
1733
- colors: darkColors
1900
+ colors: darkColors,
1901
+ shadows: generateShadows(darkColors, "dark")
1734
1902
  });
1735
1903
  //#endregion
1736
1904
  //#region src/concepts/theme/themes/light.theme.ts
1737
1905
  var LightTheme = createTheme({
1738
1906
  id: "LightTheme",
1739
1907
  name: "Light Theme",
1740
- colors: lightColors
1908
+ colors: lightColors,
1909
+ shadows: generateShadows(lightColors, "light")
1741
1910
  });
1742
1911
  //#endregion
1743
1912
  //#region src/concepts/theme/theme.records.ts
@@ -1824,12 +1993,14 @@ exports.createThemeFromPalette = createThemeFromPalette;
1824
1993
  exports.cycle = cycle;
1825
1994
  exports.darkColors = darkColors;
1826
1995
  exports.debounce = debounce;
1996
+ exports.emitDtcgTokens = emitDtcgTokens;
1827
1997
  exports.emitThemeFile = emitThemeFile;
1828
1998
  exports.expandFadeIn = expandFadeIn;
1829
1999
  exports.fadeIn = fadeIn;
1830
2000
  exports.fadeOut = fadeOut;
1831
2001
  exports.generateColors = generateColors;
1832
2002
  exports.generatePalette = generatePalette;
2003
+ exports.generateShadows = generateShadows;
1833
2004
  exports.generateThemes = generateThemes;
1834
2005
  exports.generateUniThemes = generateUniThemes;
1835
2006
  exports.getAnalogousHues = getAnalogousHues;