@uni-design-system/uni-core 8.3.1 → 8.4.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,124 @@
1
1
  # @uni-design-system/uni-core
2
2
 
3
+ ## 8.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`1aca747`](https://github.com/uni-design-system/uni/commit/1aca747c7bdff6cf72a9fa349e77a6e7985b97c7) Thanks [@gaenglish](https://github.com/gaenglish)! - `uni-callout` and `uni-expand` now read their timing from the theme's `motion`
8
+ scale, so every animated surface in the library is retimed from one place.
9
+ They were the last two carrying their own motion options — in different units,
10
+ under different names (`transitionMs` in milliseconds, `transitionSpeed` in
11
+ seconds).
12
+
13
+ A third token joins `popup` and `panel`:
14
+
15
+ | Token | Default | Used by |
16
+ | -------- | ----------------- | --------------------- |
17
+ | `reveal` | 350ms ease-in-out | expand, expand-toggle |
18
+
19
+ `reveal` is a _base_ speed, not a final duration: `uni-expand` still scales it
20
+ by content height (√-of-height, clamped) so short regions stay snappy and tall
21
+ ones aren't rushed, and its easing now drives the reveal curve, which was
22
+ hardcoded. `uni-expand-toggle` resolves the token the same way, so the chevron
23
+ and the region cannot drift apart. `uni-callout` maps onto `panel`, whose
24
+ 250ms matches what it already used.
25
+
26
+ **Not breaking.** `transitionMs` and `transitionSpeed` are deprecated but
27
+ still honoured, and deliberately outrank `motion` — a theme that set either
28
+ keeps precisely its current timing rather than being retimed underneath it.
29
+ They are removed next major. Per-instance inputs, like `uni-expand`'s
30
+ `transitionSpeed`, still outrank everything.
31
+
32
+ Nothing moves differently by default: callout renders 0.25s ease and expand
33
+ 0.35s ease-in-out exactly as before, verified against the rendered styles.
34
+
35
+ - [`6f76c1d`](https://github.com/uni-design-system/uni/commit/6f76c1d3cc1ba2ed5e2747b6d2142d16cb4f537b) Thanks [@gaenglish](https://github.com/gaenglish)! - `uni-alert`, `uni-snackbar`, `uni-radio` and `uni-menu-item` now read their
36
+ timing from the theme's `motion` scale, which completes the migration: every
37
+ animated component in the library is retimed from one place.
38
+
39
+ Two tokens join `popup`, `panel` and `reveal`:
40
+
41
+ | Token | Default | Used by |
42
+ | -------------- | ----------------- | ---------------- |
43
+ | `notification` | 350ms ease-in-out | alert, snackbar |
44
+ | `control` | 300ms ease | radio, menu-item |
45
+
46
+ **One thing moves differently:** `menu-item`'s hover transition goes from
47
+ 0.35s to 0.3s, joining `radio` on the shared `control` token. The two were
48
+ never deliberately different — `radio`'s own option documented its 0.3 as
49
+ "matching menuItem", which was not true — so this corrects drift rather than
50
+ changing a decision. A theme that wants the old timing can set the deprecated
51
+ `transitionSpeed`, or retime `control`. Everything else is byte-identical,
52
+ verified against the rendered styles.
53
+
54
+ **Deprecated, still honoured, removed next major:**
55
+ `alert.transitionSpeed`, `snackbar.transitionDelay`, `radio.transitionSpeed`
56
+ and `menuItem.transitionSpeed` all still work and still outrank `motion`, so a
57
+ theme that set them keeps its exact timing. `menu-item`'s escape hatch is
58
+ intact too: with neither the option nor a token set it still renders no
59
+ transition at all, and a token with `duration: 0` is the way to ask for
60
+ instant now.
61
+
62
+ `card.transitionSpeed` and `input-box.transitionSpeed` are also deprecated,
63
+ for a different reason: **neither was ever read by its component.** Setting
64
+ them has never had any effect. They are removed next major and nothing needs
65
+ to replace them.
66
+
67
+ `uni-skeleton` is deliberately left out. Its shimmer is a loop rather than a
68
+ transition, and folding a repeating animation into a scale built around
69
+ entering and leaving would make the scale mean two different things.
70
+
71
+ - [`228c17f`](https://github.com/uni-design-system/uni/commit/228c17f9fb7a4e4eb8d6a9cd0a6301d02ddd3dd3) Thanks [@gaenglish](https://github.com/gaenglish)! - `uni-skeleton` picks up the knobs an app theme could not reach. `color`, `highlightColor` and `borderRadius` are now inputs that take a token name and fall back to the theme option, because one screen routinely needs several of each — text bars and a pill chip do not share a corner (`borderRadius="max"`), and a skeleton on a card wants a different tint than one on the page background.
72
+
73
+ The shimmer is now a band swept with `transform` rather than an animated `background-position`: it composites instead of repainting every frame, and its geometry is themeable via two new options, `direction` (`'ltr' | 'rtl'`, default `'ltr'` — the sweep previously ran right-to-left) and `highlightWidth` (band width as a percentage of the block, default `40`). Both ends of the band are the base color, so it dissolves into the block with no alpha and no fringing.
74
+
75
+ A new `label` input announces a standalone skeleton: set it and the host becomes `role="status"` with visually hidden text instead of `aria-hidden="true"`. Unlabelled skeletons stay `aria-hidden`, so container-level `aria-busy` patterns are unchanged.
76
+
77
+ - [`3b51ace`](https://github.com/uni-design-system/uni/commit/3b51acee92659526c1c8c91668b37db8c5933162) Thanks [@gaenglish](https://github.com/gaenglish)! - Overlay timing is now a theme token. `UniTheme` gains a `motion` scale
78
+ alongside `radii`, `shadows` and the rest, and the overlays point at it by
79
+ name instead of carrying their own hardcoded durations.
80
+
81
+ Until now a theme could slow a skeleton shimmer but not a dropdown: `expand`,
82
+ `skeleton` and `callout` each exposed their own motion option while
83
+ `uni-dropdown` hardcoded 100ms and the combobox-style listbox popups copied
84
+ that constant. Retiming the library meant editing components.
85
+
86
+ Two tokens ship, because two things genuinely move differently — a small panel
87
+ attached to a control snaps, a larger free-floating surface settles:
88
+
89
+ | Token | Default | Used by |
90
+ | ------- | ------------------ | --------------------------------------------------------------------------- |
91
+ | `popup` | 100ms linear, ×0.8 | dropdown, menu, multi-select, combobox, search-input, tag-input, time-input |
92
+ | `panel` | 250ms ease | popover |
93
+
94
+ A token carries `duration` (ms), `easing`, and an optional `scale` for panels
95
+ that grow into place — one token rather than separate duration and easing
96
+ scales, because they are one design decision: slowing a panel without
97
+ softening its curve reads as sluggish rather than calm.
98
+
99
+ ```ts
100
+ createTheme({
101
+ id: 'Calm',
102
+ name: 'Calm',
103
+ colors,
104
+ motion: { popup: { duration: 240, easing: 'ease-out', scale: 0.95 } },
105
+ });
106
+ ```
107
+
108
+ Tokens you don't restate keep their base values, and a component can still
109
+ point at a token of its own through its `motion` option.
110
+
111
+ Nothing moves differently by default — every current duration, easing and
112
+ scale is preserved exactly, verified against the rendered styles. Themes that
113
+ predate the scale keep working: `createTheme` fills it in, the validator does
114
+ not require it, and a theme registered as JSON without it resolves to the base
115
+ timing rather than failing. `motionSafe` remains the floor, so a theme decides
116
+ how overlays move for people who want movement, never whether they move at
117
+ all.
118
+
119
+ `callout`'s existing `transitionMs` option and the `expand`/`skeleton`
120
+ durations are untouched for now; folding them into this scale is a follow-up.
121
+
3
122
  ## 8.3.1
4
123
 
5
124
  ## 8.3.0
@@ -1126,6 +1126,43 @@ var BaseThicknesses = {
1126
1126
  standard: 2,
1127
1127
  thick: 4
1128
1128
  };
1129
+ /**
1130
+ * Shared motion timing, named by what moves rather than by how fast:
1131
+ * a small panel attached to a control snaps (`popup`), a larger free-floating
1132
+ * surface settles (`panel`), content growing in place eases at both ends
1133
+ * (`reveal`), a transient message arrives and leaves under its own steam
1134
+ * (`notification`), and a control answering a pointer should feel immediate
1135
+ * (`control`).
1136
+ *
1137
+ * Fast and linear is deliberate for `popup`. It is the timing every
1138
+ * trigger-anchored panel in the library uses — dropdown, menu, multi-select
1139
+ * and the combobox-style listboxes — so a form full of them opens uniformly;
1140
+ * at 100ms an easing curve is imperceptible anyway, and linear avoids the
1141
+ * lag a slow-in curve adds to something the user is waiting on.
1142
+ */
1143
+ var BaseMotion = {
1144
+ popup: {
1145
+ duration: 100,
1146
+ easing: "linear",
1147
+ scale: .8
1148
+ },
1149
+ panel: {
1150
+ duration: 250,
1151
+ easing: "ease"
1152
+ },
1153
+ reveal: {
1154
+ duration: 350,
1155
+ easing: "ease-in-out"
1156
+ },
1157
+ notification: {
1158
+ duration: 350,
1159
+ easing: "ease-in-out"
1160
+ },
1161
+ control: {
1162
+ duration: 300,
1163
+ easing: "ease"
1164
+ }
1165
+ };
1129
1166
  var BaseRadii = {
1130
1167
  none: "none",
1131
1168
  xxs: "4px",
@@ -1169,7 +1206,7 @@ var buildComponents = (c) => ({
1169
1206
  alert: { options: {
1170
1207
  topPosition: 40,
1171
1208
  borderRadius: "sm",
1172
- transitionSpeed: .35,
1209
+ motion: "notification",
1173
1210
  elevation: "md"
1174
1211
  } },
1175
1212
  breadcrumb: { options: {
@@ -1275,7 +1312,7 @@ var buildComponents = (c) => ({
1275
1312
  size: 20,
1276
1313
  ringColor: "outline",
1277
1314
  fillColor: "surface",
1278
- transitionSpeed: .3
1315
+ motion: "control"
1279
1316
  } },
1280
1317
  dialog: { options: {
1281
1318
  borderRadius: "lg",
@@ -1312,7 +1349,8 @@ var buildComponents = (c) => ({
1312
1349
  border: "none",
1313
1350
  borderRadius: "xxs",
1314
1351
  color: "primary-surface",
1315
- shadow: "menu"
1352
+ shadow: "menu",
1353
+ motion: "popup"
1316
1354
  } },
1317
1355
  menu: { options: {
1318
1356
  minWidth: 184,
@@ -1335,7 +1373,7 @@ var buildComponents = (c) => ({
1335
1373
  textColor: void 0,
1336
1374
  hoverColor: "primary-container",
1337
1375
  activeSymbol: "check",
1338
- transitionSpeed: .35
1376
+ motion: "control"
1339
1377
  },
1340
1378
  variants: { warn: {
1341
1379
  color: c.warn,
@@ -1359,9 +1397,10 @@ var buildComponents = (c) => ({
1359
1397
  headerTypeface: "title-small",
1360
1398
  tooltipPadding: "4px 8px",
1361
1399
  tooltipOpenDelay: 500,
1362
- tooltipCloseDelay: 150
1400
+ tooltipCloseDelay: 150,
1401
+ motion: "panel"
1363
1402
  } },
1364
- expand: { options: { transitionSpeed: .35 } },
1403
+ expand: { options: { motion: "reveal" } },
1365
1404
  footer: { options: {
1366
1405
  height: 52,
1367
1406
  color: "primary",
@@ -1822,11 +1861,13 @@ var buildComponents = (c) => ({
1822
1861
  borderRadius: "xs",
1823
1862
  animation: "shimmer",
1824
1863
  duration: 1.4,
1864
+ direction: "ltr",
1865
+ highlightWidth: 40,
1825
1866
  gap: "sm"
1826
1867
  } },
1827
1868
  snackbar: { options: {
1828
1869
  bottomPosition: 40,
1829
- transitionDelay: "0.35s",
1870
+ motion: "notification",
1830
1871
  autoCloseDelay: 35e3
1831
1872
  } },
1832
1873
  symbol: { options: {
@@ -1862,7 +1903,7 @@ var buildComponents = (c) => ({
1862
1903
  spotlightPadding: 6,
1863
1904
  spotlightRadius: "xs",
1864
1905
  ringWidth: 2,
1865
- transitionMs: 250
1906
+ motion: "panel"
1866
1907
  } },
1867
1908
  tour: { options: {
1868
1909
  progressStyle: "dots",
@@ -1876,7 +1917,7 @@ var deepMerge = (base, override) => {
1876
1917
  for (const [key, value] of Object.entries(override)) out[key] = isRecord$1(value) && isRecord$1(out[key]) ? deepMerge(out[key], value) : value;
1877
1918
  return out;
1878
1919
  };
1879
- var createTheme = ({ id, name, colors, icons = {}, radii = BaseRadii, shadows = BaseShadows, typography, borders, thicknesses, components }) => ({
1920
+ var createTheme = ({ id, name, colors, icons = {}, radii = BaseRadii, shadows = BaseShadows, motion, typography, borders, thicknesses, components }) => ({
1880
1921
  id,
1881
1922
  name,
1882
1923
  colors,
@@ -1885,6 +1926,10 @@ var createTheme = ({ id, name, colors, icons = {}, radii = BaseRadii, shadows =
1885
1926
  radii,
1886
1927
  shadows,
1887
1928
  spacing: BaseSpacing,
1929
+ motion: {
1930
+ ...BaseMotion,
1931
+ ...motion
1932
+ },
1888
1933
  thicknesses: {
1889
1934
  ...BaseThicknesses,
1890
1935
  ...thicknesses