@uni-design-system/uni-core 8.4.0 → 9.0.1

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,142 @@
1
1
  # @uni-design-system/uni-core
2
2
 
3
+ ## 9.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`f926cd5`](https://github.com/uni-design-system/uni/commit/f926cd513a5cac593adef559e21bada4dada76ee) Thanks [@gaenglish](https://github.com/gaenglish)! - `uni-react`'s Switch reads the `success` color token instead of hand-rolling an
8
+ HSL string from a color-generation internal, and both packages now typecheck as
9
+ part of their build.
10
+
11
+ The Switch built its "on" color as `hsl(${RoleHues.success.default}, 32%, 50%)`
12
+ — a fixed green assembled from the HSL generation tables rather than the theme,
13
+ so it never recolored with the theme and broke when those tables were removed.
14
+ It now reads `useTheme().colors.success`.
15
+
16
+ The reason that reached a deploy is the build. `vite build` transpiles with
17
+ esbuild, which strips types without checking them, and it treats
18
+ `@uni-design-system/uni-core` as an external — so neither the type layer nor the
19
+ module graph ever verified that an imported core export exists. `pnpm turbo run
20
+ build` passed on a package whose source did not compile.
21
+ - `core` and `react` now run `tsc --noEmit` as the first half of `build`, so a
22
+ removed or renamed core export fails the consumer's build.
23
+ - A `type-check` turbo task exists for running that pass alone.
24
+ - CI builds **both** Storybooks, not just Angular's. These bundle uni-core
25
+ instead of externalizing it, so they are the step that resolves its exports
26
+ against real consumer source.
27
+
28
+ This also cleared four pre-existing type errors in `IconTextRow`, which did
29
+ arithmetic on `fontSize` / `lineHeight` — typed `CssLength` (`number | string`)
30
+ — and passed the result to props typed `number`. They are coerced through one
31
+ documented helper now.
32
+
33
+ ## 9.0.0
34
+
35
+ ### Major Changes
36
+
37
+ - [`8250162`](https://github.com/uni-design-system/uni/commit/8250162c35e418f976080904df4c20783feeb6e2) Thanks [@gaenglish](https://github.com/gaenglish)! - Every deprecated API is removed. The library now carries no `@deprecated`
38
+ symbols at all.
39
+
40
+ **Per-component duration options → the `motion` scale.** Six components carried
41
+ their own duration knob that predated the motion scale and _won over_ it:
42
+ `expand.transitionSpeed`, `callout.transitionMs`, `radio.transitionSpeed`,
43
+ `menuItem.transitionSpeed`, `alert.transitionSpeed` and
44
+ `snackbar.transitionDelay`. All are gone, along with the precedence branch each
45
+ one required — timing now comes from the token, full stop.
46
+
47
+ Retime the token instead; one edit covers every component pointing at it. To
48
+ retime a single component, define a token of your own and point that
49
+ component's `motion` option at it:
50
+
51
+ ```ts
52
+ createTheme({
53
+ …,
54
+ motion: { productive: { duration: 110, easing: 'ease' } },
55
+ components: { menuItem: { options: { motion: 'productive' } } },
56
+ });
57
+ ```
58
+
59
+ A `duration: 0` token is how a theme opts out of motion — that is what
60
+ `transitionSpeed: 0` used to mean. Both showcase themes are migrated this way
61
+ (Carbon to a 110ms `productive` token, Wellsourced to an `instant` one).
62
+
63
+ **Options that never did anything.** `card.transitionSpeed` and
64
+ `inputBox.transitionSpeed` were read by nothing and never had been. Delete them
65
+ from your theme; nothing replaces them.
66
+
67
+ **Renames and obsolete APIs**
68
+ - `inputBox.typeFace` → `typeface` (the casing every other component uses).
69
+ - `uni-tooltip`'s `appendToBody` input — inert since the tooltip moved to the
70
+ native top layer, which escapes any overflow context by itself.
71
+ - Box's `elevation` input → `shadow`, in both the Angular and React packages.
72
+ It was a second name for the same thing.
73
+ - The Angular `icons` re-export → import `BaseIcons` from
74
+ `@uni-design-system/uni-core`. The default set ships with every theme.
75
+
76
+ **The HSL color legacy is gone from uni-core.** `uniColor`, `randomRangeValue`,
77
+ `CategorySaturation` and `CategoryLightness` are removed, superseded by the
78
+ deterministic OKLCH engine (`generateThemes` / `generatePalette`) — same input,
79
+ same theme, WCAG-checked. `RoleHues` and the `UniColor` type go with them: they
80
+ were reachable only through `uniColor`, and `RoleHues` had gone stale enough to
81
+ hold saturation values in a table of hues.
82
+
83
+ **Deferred output renames.** Three outputs were held back because renaming is
84
+ breaking; this is that release. Each also drops an eslint escape it needed for
85
+ shadowing a native event name or using an `on` prefix.
86
+
87
+ | Component | Before | After |
88
+ | -------------------- | ----------------- | ---------------- |
89
+ | `uni-debounce-input` | `(change)` | `(valueChange)` |
90
+ | `uni-search-input` | `(change)` | `(searchChange)` |
91
+ | `uni-search-input` | `(search)` | `(searchSubmit)` |
92
+ | `dragAndDrop` | `(onFileDropped)` | `(fileDropped)` |
93
+
94
+ **`uni-dropdown`'s `color` input → `containerColor`,** completing the rule the
95
+ layout directives set: every container-pair input in the library is now
96
+ `containerColor`, and plain `color` always means the CSS property.
97
+
98
+ **`ThemeService.getSpacing('none')` now returns `0`, not the string `'none'`.**
99
+ `'none'` is not a valid length, so it was silently dropped wherever it landed —
100
+ `uni-menu` carried a comment working around exactly that, which is now deleted.
101
+
102
+ - [`c0c6056`](https://github.com/uni-design-system/uni/commit/c0c6056c61e994a45af9c379f3c99f55eebcb79a) Thanks [@gaenglish](https://github.com/gaenglish)! - The spacing scale is open, and `createTheme` finally accepts one.
103
+
104
+ The scale was a closed seven-name union on a doubling curve (2/4/8/16/32/64px).
105
+ Real layouts are rarely built exclusively on one — the gaps between 8 and 16,
106
+ and 16 and 32, are where a lot of real spacing lives — and there was no way to
107
+ add a step, because **`ThemeConfig` had no `spacing` field at all**:
108
+ `createTheme` hardcoded the base scale. The Wellsourced showcase theme had to
109
+ bolt its scale on after the fact with a post-hoc spread.
110
+
111
+ Three changes, which only work together:
112
+ - `NullableSize` gains a `(string & {})` arm, so any name the theme defines is a
113
+ valid `padding` / `gap` / `marginInline` value while the seven named steps keep
114
+ their autocomplete. `Size` itself stays closed — it also types _component_
115
+ sizes, where an arbitrary name has nothing to resolve against.
116
+ - `Spacing` is spelled out as named-optional-keys plus an index signature
117
+ (mirroring `Typography`), rather than a `Partial<Record<…>>` that would
118
+ collapse to a plain string record and lose the named steps.
119
+ - `createTheme({ spacing })` merges over the base scale.
120
+
121
+ ```ts
122
+ createTheme({ id, name, colors, spacing: { tight: '6px', snug: '10px' } });
123
+ ```
124
+
125
+ ```html
126
+ <div stack-layout padding="tight" gap="snug">…</div>
127
+ ```
128
+
129
+ Because the scale is open, a mistyped token can no longer be a compile error. It
130
+ is dropped — an `undefined` CSS value simply does not render — and
131
+ `ThemeService` now warns once per unknown token in development, naming the
132
+ tokens the active theme does define. Scaffolded `uni-theme.ts` files carry a
133
+ `spacing` block so the static theme file stays the editable source of truth.
134
+
135
+ **Behavior change:** `xxl` was in the `Size` union but defined by no base theme,
136
+ so `padding="xxl"` type-checked and rendered nothing. It is now `128px`,
137
+ completing the doubling — any element relying on the silent drop will start
138
+ showing spacing.
139
+
3
140
  ## 8.4.0
4
141
 
5
142
  ### Minor Changes
@@ -60,183 +60,6 @@ var collapseFadeOut = {
60
60
  }
61
61
  };
62
62
  //#endregion
63
- //#region src/concepts/color/color.records.ts
64
- /**
65
- * @deprecated HSL saturation ranges are superseded by the perceptual OKLCH
66
- * chroma model inside `concepts/generation` (see `generateThemes`). Kept for
67
- * legacy callers of `uniColor`; removal follows the changeset major process.
68
- */
69
- var CategorySaturation = {
70
- jewel: {
71
- low: 73,
72
- high: 83
73
- },
74
- pastel: {
75
- low: 14,
76
- high: 21
77
- },
78
- earth: {
79
- low: 36,
80
- high: 41
81
- },
82
- neutral: {
83
- low: 1,
84
- high: 10
85
- },
86
- florescent: {
87
- low: 63,
88
- high: 100
89
- },
90
- shades: {
91
- low: 0,
92
- high: 0
93
- }
94
- };
95
- /**
96
- * @deprecated HSL lightness ranges are superseded by the perceptual OKLCH
97
- * tone slots inside `concepts/generation` (see `generateThemes`).
98
- */
99
- var CategoryLightness = {
100
- jewel: {
101
- low: 56,
102
- high: 76
103
- },
104
- pastel: {
105
- low: 89,
106
- high: 96
107
- },
108
- earth: {
109
- low: 36,
110
- high: 77
111
- },
112
- neutral: {
113
- low: 70,
114
- high: 99
115
- },
116
- florescent: {
117
- low: 82,
118
- high: 100
119
- },
120
- shades: {
121
- low: 0,
122
- high: 100
123
- }
124
- };
125
- var RoleHues = {
126
- primary: {
127
- low: 73,
128
- high: 83,
129
- default: 0
130
- },
131
- secondary: {
132
- low: 14,
133
- high: 21,
134
- default: 0
135
- },
136
- tertiary: {
137
- low: 36,
138
- high: 41,
139
- default: 0
140
- },
141
- inverse: {
142
- low: 63,
143
- high: 100,
144
- default: 0
145
- },
146
- ghost: {
147
- low: 0,
148
- high: 0,
149
- default: 0
150
- },
151
- warn: {
152
- low: 320,
153
- high: 20,
154
- default: 0
155
- },
156
- alert: {
157
- low: 40,
158
- high: 70,
159
- default: 60
160
- },
161
- success: {
162
- low: 90,
163
- high: 150,
164
- default: 120
165
- },
166
- info: {
167
- low: 200,
168
- high: 260,
169
- default: 240
170
- }
171
- };
172
- //#endregion
173
- //#region src/concepts/color/color.utils.ts
174
- /**
175
- * @deprecated Randomized generation is superseded by the deterministic OKLCH
176
- * engine in `concepts/generation` — same input, same theme. Seeded "surprise
177
- * me" behavior belongs in the consumer (playground), not the engine.
178
- */
179
- var randomRangeValue = ({ low, high }) => {
180
- low = Math.ceil(low);
181
- high = Math.floor(high);
182
- return Math.floor(Math.random() * (high - low + 1)) + low;
183
- };
184
- var cycle = (angle) => {
185
- if (angle > 360) return angle - 360;
186
- if (angle < 0) return angle + 360;
187
- return angle;
188
- };
189
- var getAnalogousHues = (hue) => [cycle(hue + 30), cycle(hue + 60)];
190
- var getComplimentaryHue = (hue) => cycle(hue + 180);
191
- var getTriadicHues = (hue) => [cycle(hue + 120), cycle(hue - 120)];
192
- var getSplitComplimentaryHues = (hue) => [cycle(hue + 150), cycle(hue - 150)];
193
- /**
194
- * Derive the primary/secondary/tertiary hues from a seed hue using the color
195
- * wheel relationships in {@link ColorScheme}. Pure angle math — works in any
196
- * hue space (HSL historically, OKLCH in the generation engine).
197
- */
198
- var schemeHues = (hue, scheme) => {
199
- switch (scheme) {
200
- case "monochromatic": return {
201
- primary: hue,
202
- secondary: hue,
203
- tertiary: hue
204
- };
205
- case "analogous": {
206
- const [a, b] = getAnalogousHues(hue);
207
- return {
208
- primary: hue,
209
- secondary: a,
210
- tertiary: b
211
- };
212
- }
213
- case "complimentary": {
214
- const [a] = getAnalogousHues(hue);
215
- return {
216
- primary: hue,
217
- secondary: getComplimentaryHue(hue),
218
- tertiary: a
219
- };
220
- }
221
- case "splitComplimentary": {
222
- const [a, b] = getSplitComplimentaryHues(hue);
223
- return {
224
- primary: hue,
225
- secondary: a,
226
- tertiary: b
227
- };
228
- }
229
- case "triadic": {
230
- const [a, b] = getTriadicHues(hue);
231
- return {
232
- primary: hue,
233
- secondary: a,
234
- tertiary: b
235
- };
236
- }
237
- }
238
- };
239
- //#endregion
240
63
  //#region src/concepts/color/color.helper.ts
241
64
  function HSLAToString({ hue, saturation, lightness, alpha = 1 }) {
242
65
  return `hsla(${hue}, ${saturation}%, ${lightness}%, ${alpha})`;
@@ -244,19 +67,6 @@ function HSLAToString({ hue, saturation, lightness, alpha = 1 }) {
244
67
  function RGBToString({ red, green, blue }) {
245
68
  return `rgb(${red}, ${green}, ${blue})`;
246
69
  }
247
- /**
248
- * @deprecated Random HSL generation produces non-deterministic, perceptually
249
- * uneven colors. Use the OKLCH engine (`generateThemes` in
250
- * `concepts/generation`) or `generatePalette` instead.
251
- */
252
- function uniColor({ role, category, alpha = 1 }) {
253
- return HSLAToString({
254
- hue: randomRangeValue(RoleHues[role]),
255
- saturation: randomRangeValue(CategorySaturation[category]),
256
- lightness: randomRangeValue(CategoryLightness[category]),
257
- alpha
258
- });
259
- }
260
70
  var RGBToHSL = ({ red, green, blue }) => {
261
71
  red /= 255;
262
72
  green /= 255;
@@ -340,6 +150,63 @@ var contrastRatio = (a, b) => {
340
150
  return (hi + .05) / (lo + .05);
341
151
  };
342
152
  //#endregion
153
+ //#region src/concepts/color/color.utils.ts
154
+ var cycle = (angle) => {
155
+ if (angle > 360) return angle - 360;
156
+ if (angle < 0) return angle + 360;
157
+ return angle;
158
+ };
159
+ var getAnalogousHues = (hue) => [cycle(hue + 30), cycle(hue + 60)];
160
+ var getComplimentaryHue = (hue) => cycle(hue + 180);
161
+ var getTriadicHues = (hue) => [cycle(hue + 120), cycle(hue - 120)];
162
+ var getSplitComplimentaryHues = (hue) => [cycle(hue + 150), cycle(hue - 150)];
163
+ /**
164
+ * Derive the primary/secondary/tertiary hues from a seed hue using the color
165
+ * wheel relationships in {@link ColorScheme}. Pure angle math — works in any
166
+ * hue space (HSL historically, OKLCH in the generation engine).
167
+ */
168
+ var schemeHues = (hue, scheme) => {
169
+ switch (scheme) {
170
+ case "monochromatic": return {
171
+ primary: hue,
172
+ secondary: hue,
173
+ tertiary: hue
174
+ };
175
+ case "analogous": {
176
+ const [a, b] = getAnalogousHues(hue);
177
+ return {
178
+ primary: hue,
179
+ secondary: a,
180
+ tertiary: b
181
+ };
182
+ }
183
+ case "complimentary": {
184
+ const [a] = getAnalogousHues(hue);
185
+ return {
186
+ primary: hue,
187
+ secondary: getComplimentaryHue(hue),
188
+ tertiary: a
189
+ };
190
+ }
191
+ case "splitComplimentary": {
192
+ const [a, b] = getSplitComplimentaryHues(hue);
193
+ return {
194
+ primary: hue,
195
+ secondary: a,
196
+ tertiary: b
197
+ };
198
+ }
199
+ case "triadic": {
200
+ const [a, b] = getTriadicHues(hue);
201
+ return {
202
+ primary: hue,
203
+ secondary: a,
204
+ tertiary: b
205
+ };
206
+ }
207
+ }
208
+ };
209
+ //#endregion
343
210
  //#region src/concepts/generation/oklch.helper.ts
344
211
  var clamp$1 = (value, min, max) => Math.min(max, Math.max(min, value));
345
212
  var srgbToLinear = (channel) => channel <= .04045 ? channel / 12.92 : Math.pow((channel + .055) / 1.055, 2.4);
@@ -1119,7 +986,8 @@ var BaseSpacing = {
1119
986
  sm: "8px",
1120
987
  md: "16px",
1121
988
  lg: "32px",
1122
- xl: "64px"
989
+ xl: "64px",
990
+ xxl: "128px"
1123
991
  };
1124
992
  var BaseThicknesses = {
1125
993
  thin: 1,
@@ -1917,7 +1785,7 @@ var deepMerge = (base, override) => {
1917
1785
  for (const [key, value] of Object.entries(override)) out[key] = isRecord$1(value) && isRecord$1(out[key]) ? deepMerge(out[key], value) : value;
1918
1786
  return out;
1919
1787
  };
1920
- var createTheme = ({ id, name, colors, icons = {}, radii = BaseRadii, shadows = BaseShadows, motion, typography, borders, thicknesses, components }) => ({
1788
+ var createTheme = ({ id, name, colors, icons = {}, radii = BaseRadii, shadows = BaseShadows, motion, typography, borders, thicknesses, spacing, components }) => ({
1921
1789
  id,
1922
1790
  name,
1923
1791
  colors,
@@ -1925,7 +1793,10 @@ var createTheme = ({ id, name, colors, icons = {}, radii = BaseRadii, shadows =
1925
1793
  borders: deepMerge(buildBorders(colors), borders),
1926
1794
  radii,
1927
1795
  shadows,
1928
- spacing: BaseSpacing,
1796
+ spacing: {
1797
+ ...BaseSpacing,
1798
+ ...spacing
1799
+ },
1929
1800
  motion: {
1930
1801
  ...BaseMotion,
1931
1802
  ...motion
@@ -2178,6 +2049,7 @@ var themeExport = (exportName, displayName, colorsConst, shadowsConst, radii) =>
2178
2049
  ` shadows: ${shadowsConst},`,
2179
2050
  " icons,",
2180
2051
  ...radii ? [" radii,"] : [],
2052
+ " spacing,",
2181
2053
  "});"
2182
2054
  ].join("\n");
2183
2055
  /**
@@ -2233,6 +2105,7 @@ var emitThemeFile = (input) => {
2233
2105
  " type ComponentThemes,",
2234
2106
  " type Icons,",
2235
2107
  " type Shadows,",
2108
+ " type Spacing,",
2236
2109
  " type UniTheme,",
2237
2110
  "} from '@uni-design-system/uni-core';",
2238
2111
  "",
@@ -2269,6 +2142,15 @@ var emitThemeFile = (input) => {
2269
2142
  " */",
2270
2143
  "const icons: Icons = {};",
2271
2144
  "",
2145
+ "/**",
2146
+ " * Spacing steps, merged over the base scale",
2147
+ " * (none: 0, xxs: 2px, xs: 4px, sm: 8px, md: 16px, lg: 32px, xl: 64px, xxl: 128px).",
2148
+ " * Restate a named step to retune the rhythm, and add your own names for the",
2149
+ " * gaps your design actually uses — every extra key is then a valid `padding`,",
2150
+ " * `gap` or `marginInline` value: `<div stack-layout gap='tight'>`.",
2151
+ " */",
2152
+ "const spacing: Spacing = {};",
2153
+ "",
2272
2154
  ...radii ? [
2273
2155
  `/** Shape language: '${input.shape}'. */`,
2274
2156
  `const radii = {\n${recordLiteral(radii, " ")}\n};`,
@@ -2776,8 +2658,6 @@ exports.BASE_PALETTE_CONFIG = BASE_PALETTE_CONFIG;
2776
2658
  exports.BaseIcons = BaseIcons;
2777
2659
  exports.BaseTheme = BaseTheme;
2778
2660
  exports.CategoryChroma = CategoryChroma;
2779
- exports.CategoryLightness = CategoryLightness;
2780
- exports.CategorySaturation = CategorySaturation;
2781
2661
  exports.DarkTheme = DarkTheme;
2782
2662
  exports.DefaultThemeId = DefaultThemeId;
2783
2663
  exports.EXPAND_DEFAULT_SPEED = EXPAND_DEFAULT_SPEED;
@@ -2798,7 +2678,6 @@ exports.REQUIRED_TEXT_ROLES = REQUIRED_TEXT_ROLES;
2798
2678
  exports.REQUIRED_THICKNESSES = REQUIRED_THICKNESSES;
2799
2679
  exports.RGBToHSL = RGBToHSL;
2800
2680
  exports.RGBToString = RGBToString;
2801
- exports.RoleHues = RoleHues;
2802
2681
  exports.ShadowCssMap = ShadowCssMap;
2803
2682
  exports.ShadowMap = ShadowMap;
2804
2683
  exports.ShapeRadii = ShapeRadii;
@@ -2843,7 +2722,6 @@ exports.isUniTheme = isUniTheme;
2843
2722
  exports.lightColors = lightColors;
2844
2723
  exports.oklchToHex = oklchToHex;
2845
2724
  exports.parseTheme = parseTheme;
2846
- exports.randomRangeValue = randomRangeValue;
2847
2725
  exports.relativeLuminance = relativeLuminance;
2848
2726
  exports.removeInputPlatformStyling = removeInputPlatformStyling;
2849
2727
  exports.rgbToHex = rgbToHex;
@@ -2852,6 +2730,5 @@ exports.summarizeContrast = summarizeContrast;
2852
2730
  exports.svgToIconUri = svgToIconUri;
2853
2731
  exports.toTypeface = toTypeface;
2854
2732
  exports.toTypefaces = toTypefaces;
2855
- exports.uniColor = uniColor;
2856
2733
 
2857
2734
  //# sourceMappingURL=index.cjs.map