@uni-design-system/uni-core 10.1.0 → 10.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/CHANGELOG.md CHANGED
@@ -1,5 +1,92 @@
1
1
  # @uni-design-system/uni-core
2
2
 
3
+ ## 10.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`1cd0140`](https://github.com/uni-design-system/uni/commit/1cd0140d2e6a4c753f48fb46418ba08769979263) Thanks [@gaenglish](https://github.com/gaenglish)! - Checkbox, radio and toggle take their accent from the theme, not from the
8
+ variant's name.
9
+
10
+ **Twelve sites across the three controls resolved a variant name as a colour
11
+ token.** That held together only because every name in the closed union happened
12
+ to also be a colour. Under an open registry the coincidence ends by design:
13
+ `<uni-checkbox variant="destructive">` would look up `colors['destructive']`,
14
+ miss, and **silently render primary** — a wrong-coloured control with no error,
15
+ no warning, and nothing to grep for.
16
+
17
+ Checkbox was worse than it looked. Alongside five `getThemeColor` calls it had
18
+ two more through a second resolver that built `on-${variant}`, so an
19
+ unregistered intent also missed its paired content colour and fell back to
20
+ `on-primary` — the tick would have stayed light on a dark fill even after the
21
+ box was fixed.
22
+
23
+ The theme now says which colour draws each intent, through a new
24
+ `variantOptions` map on `ComponentTheme`:
25
+
26
+ ```ts
27
+ checkbox: {
28
+ variantOptions: {
29
+ primary: { accent: 'primary' },
30
+ warn: { accent: 'warn' },
31
+ },
32
+ }
33
+ ```
34
+
35
+ `variantOptions` is per-variant data a component **reads**, as against `variants`,
36
+ which is CSS that gets **applied**. The distinction earns its place here: a
37
+ checkbox's accent lands on the box outline, the checked and indeterminate fills,
38
+ the tick and the focus ring at once, and expressing that as CSS would have meant
39
+ the theme naming `.checkbox-check` and `.radio-inner` — promoting private DOM to
40
+ public theme contract.
41
+
42
+ All three controls gain a `checkedColor` input as the per-instance override,
43
+ matching the one `uni-toggle` already had; its resolution order is now input →
44
+ the variant's themed accent → theme option. The base theme defines the same
45
+ seven intents `button` and `iconButton` do, so the library is consistent about
46
+ which exist by default, and `getThemeColor` — triplicated byte-for-byte across
47
+ the three components, with a silent fallback to primary — is gone.
48
+
49
+ Rendering is unchanged for anything that does not set `variant`: the default
50
+ still resolves to the primary accent and its paired on-colour.
51
+
52
+ - [`1cd0140`](https://github.com/uni-design-system/uni/commit/1cd0140d2e6a4c753f48fb46418ba08769979263) Thanks [@gaenglish](https://github.com/gaenglish)! - `Variant` is an open registry: a design system can define its own intents.
53
+
54
+ A variant names _what an action means_, and it is the theme's job to describe
55
+ how that intent is drawn. So the set of names was never Uni's to fix — an app
56
+ whose actions are `destructive`, `subtle` and `info` had to translate them onto
57
+ twelve names chosen elsewhere. `Variant` is now `keyof UniVariantRegistry`,
58
+ extended by declaration merging:
59
+
60
+ ```ts
61
+ declare module '@uni-design-system/uni-core' {
62
+ interface UniVariantRegistry {
63
+ destructive: true;
64
+ }
65
+ }
66
+ ```
67
+
68
+ `variant="destructive"` then compiles wherever a variant is accepted, and
69
+ `variant="destructve"` still does not — which the library's other open-token
70
+ idiom, `Named | (string & {})`, cannot give you, and which would also have
71
+ collapsed the theme's `variants` map keys to `string`.
72
+
73
+ Only the type was ever closed: theme validation checks the _shape_ of a
74
+ `variants` block and never its key names, so a custom variant already reached
75
+ `componentStyle` untouched at runtime.
76
+
77
+ **The registry extends; it cannot replace.** Declaration merging has no way to
78
+ remove a member, so Uni's twelve names stay legal in a consuming app; enforcing
79
+ a house set is a lint concern rather than a type. Two names are reserved and
80
+ documented as always present: `primary`, which every component inherits as its
81
+ default, and `disabled`, which the disabled state resolves to.
82
+
83
+ **An unthemed variant now says so.** With a closed union this was nearly
84
+ impossible; with an open set it is the ordinary state of a work in progress —
85
+ a variant registered and used before its theme block exists. The theme service
86
+ warns once per component and variant in dev, naming what the theme does define,
87
+ mirroring what it already did for an unknown spacing token. Components that
88
+ theme no variants at all stay silent, since a missing key there is not a gap.
89
+
3
90
  ## 10.1.0
4
91
 
5
92
  ### Minor Changes
@@ -1057,6 +1057,30 @@ var buildBorders = (c) => ({
1057
1057
  * surface and draws the edge — so every role stays consistent and a theme can
1058
1058
  * still override any single cell.
1059
1059
  */
1060
+ /**
1061
+ * Accent roles for the selection controls (checkbox, radio, toggle).
1062
+ *
1063
+ * A variant names the intent; this says which colour token draws it, and the
1064
+ * component decides where it lands — the box fill, the ring, the dot, the
1065
+ * track, the focus ring. Keeping it as a role rather than a `variants`
1066
+ * StyleExpression is what stops interior class names like `.checkbox-check`
1067
+ * becoming public theme contract.
1068
+ *
1069
+ * The same seven names `button` and `iconButton` theme, so the library is
1070
+ * consistent about which intents exist by default.
1071
+ */
1072
+ var SELECTION_ACCENTS = {
1073
+ primary: { accent: "primary" },
1074
+ secondary: { accent: "secondary" },
1075
+ tertiary: { accent: "tertiary" },
1076
+ warn: { accent: "warn" },
1077
+ success: { accent: "success" },
1078
+ disabled: { accent: "disabled" },
1079
+ ghost: {
1080
+ accent: "ghost",
1081
+ onAccent: "on-primary"
1082
+ }
1083
+ };
1060
1084
  var tagVariant = (c, role) => ({ [role]: {
1061
1085
  backgroundColor: c[`${role}-container`],
1062
1086
  color: c[`on-${role}-container`],
@@ -1193,18 +1217,24 @@ var buildComponents = (c) => ({
1193
1217
  activeColor: "primary-container",
1194
1218
  maxSuggestions: 8
1195
1219
  } },
1196
- checkbox: { options: {
1197
- size: 20,
1198
- boxColor: "surface",
1199
- borderRadius: 2,
1200
- focusRingGap: 2
1201
- } },
1202
- radio: { options: {
1203
- size: 20,
1204
- ringColor: "outline",
1205
- fillColor: "surface",
1206
- motion: "control"
1207
- } },
1220
+ checkbox: {
1221
+ options: {
1222
+ size: 20,
1223
+ boxColor: "surface",
1224
+ borderRadius: 2,
1225
+ focusRingGap: 2
1226
+ },
1227
+ variantOptions: SELECTION_ACCENTS
1228
+ },
1229
+ radio: {
1230
+ options: {
1231
+ size: 20,
1232
+ ringColor: "outline",
1233
+ fillColor: "surface",
1234
+ motion: "control"
1235
+ },
1236
+ variantOptions: SELECTION_ACCENTS
1237
+ },
1208
1238
  dialog: { options: {
1209
1239
  borderRadius: "lg",
1210
1240
  color: "primary-surface",
@@ -1266,13 +1296,16 @@ var buildComponents = (c) => ({
1266
1296
  activeSymbol: "check",
1267
1297
  motion: "control"
1268
1298
  },
1269
- variants: { warn: {
1270
- color: c.warn,
1271
- [HOVER_OR_KEYBOARD_FOCUS]: {
1272
- backgroundColor: c["warn-container"],
1273
- color: c["on-warn-container"]
1299
+ variants: {
1300
+ primary: {},
1301
+ warn: {
1302
+ color: c.warn,
1303
+ [HOVER_OR_KEYBOARD_FOCUS]: {
1304
+ backgroundColor: c["warn-container"],
1305
+ color: c["on-warn-container"]
1306
+ }
1274
1307
  }
1275
- } }
1308
+ }
1276
1309
  },
1277
1310
  popover: { options: {
1278
1311
  color: "primary-surface",
@@ -1821,6 +1854,7 @@ var buildComponents = (c) => ({
1821
1854
  knobColor: "surface",
1822
1855
  motion: "control"
1823
1856
  },
1857
+ variantOptions: SELECTION_ACCENTS,
1824
1858
  sizes: {
1825
1859
  sm: {
1826
1860
  width: 28,
@@ -2643,6 +2677,17 @@ var checkComponents = (value, issues) => {
2643
2677
  }
2644
2678
  for (const [key, style] of Object.entries(styles)) if (style !== void 0) checkStyleExpression(style, `components.${name}.${section}.${key}`, issues);
2645
2679
  }
2680
+ const variantOptions = entry["variantOptions"];
2681
+ if (variantOptions !== void 0) {
2682
+ if (!isRecord(variantOptions)) issues.push({
2683
+ path: `components.${name}.variantOptions`,
2684
+ message: "must be an object"
2685
+ });
2686
+ else for (const [key, roles] of Object.entries(variantOptions)) if (roles !== void 0 && !isRecord(roles)) issues.push({
2687
+ path: `components.${name}.variantOptions.${key}`,
2688
+ message: "must be an object"
2689
+ });
2690
+ }
2646
2691
  if (entry["options"] !== void 0 && !isRecord(entry["options"])) issues.push({
2647
2692
  path: `components.${name}.options`,
2648
2693
  message: "must be an object"