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