@uni-design-system/uni-angular 9.0.0 → 10.0.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,296 @@
|
|
|
1
1
|
# @uni-design-system/uni-angular
|
|
2
2
|
|
|
3
|
+
## 10.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- [`21b655d`](https://github.com/uni-design-system/uni/commit/21b655df0f93e2e2de6a22ccf38050b474d4e5ab) Thanks [@gaenglish](https://github.com/gaenglish)! - `uni-slider` is rebuilt on custom thumbs instead of `<input type="range">`,
|
|
8
|
+
gaining range mode, marks, a value readout and an exact decimal step model. This
|
|
9
|
+
is a breaking change to both the component's value shape and its theme options.
|
|
10
|
+
|
|
11
|
+
**Why it could not stay native.** One `<input type="range">` cannot carry two
|
|
12
|
+
thumbs, so range mode, thumb crossing and per-thumb ARIA bounds were all
|
|
13
|
+
unreachable; marks and a value tooltip were unstyleable through it. The
|
|
14
|
+
alternative — a second component for the range case — would have meant two
|
|
15
|
+
keyboard implementations to keep in step, which is the drift the shared step
|
|
16
|
+
model exists to prevent. What the platform was giving us (the slider ARIA
|
|
17
|
+
pattern and the keyboard map) is reimplemented explicitly and covered by 29
|
|
18
|
+
specs.
|
|
19
|
+
|
|
20
|
+
**Breaking: value shape.**
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
// before
|
|
24
|
+
value = model<number>(0);
|
|
25
|
+
// after — the shape follows `mode`, and `null` is empty
|
|
26
|
+
value = model<number | UniNumberRange | null>(null);
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
A `single` slider still reads and writes a plain number, so
|
|
30
|
+
`[(value)]="volume"` is unchanged. Code that relied on `value()` being
|
|
31
|
+
non-nullable, or that read it without narrowing, now needs to handle `null` and
|
|
32
|
+
the `{ start, end }` range.
|
|
33
|
+
|
|
34
|
+
**Breaking: theme options.** `slider.options.color` is **removed**. Fill and
|
|
35
|
+
thumb colour now come from the `variant` role pair, the rule every other
|
|
36
|
+
component follows, so `variant="warn"` recolours a slider with no theme edit. A
|
|
37
|
+
theme that set `color` should delete it and pass `variant` at the call site.
|
|
38
|
+
`trackColor` now defaults to `primary-container` rather than `surface-variant`.
|
|
39
|
+
|
|
40
|
+
New options: `thumbBorderRadius`, `minTouchTarget`, `markSize`, `markColor`,
|
|
41
|
+
`labelTypeface`, `labelColor`, `tooltipColor`, `tooltipTextColor`,
|
|
42
|
+
`tooltipShadow`, `tooltipBorderRadius`, `transitionMs`. `trackHeight`,
|
|
43
|
+
`thumbSize` and `borderRadius` are unchanged.
|
|
44
|
+
|
|
45
|
+
**New capability.**
|
|
46
|
+
- `mode="range"` — two thumbs, a `{ start, end }` value, `minGap` to fence the
|
|
47
|
+
ends apart. Thumbs may cross and swap, and the dragged one keeps focus.
|
|
48
|
+
- `marks` and `snapToMarks` — labelled stops, spoken in place of the number.
|
|
49
|
+
- `valueDisplay` — `none`, `inline`, `tooltip`, or `input`, which seats a
|
|
50
|
+
compact `uni-number-input` at the trailing edge, two-way bound to the same
|
|
51
|
+
value: drag for the ballpark, type for the exact figure. Single mode only.
|
|
52
|
+
- `origin` — anchor the fill somewhere other than `min`, for sliders spanning ±.
|
|
53
|
+
- `sliding` and `changed` outputs, replacing an implicit per-frame model write.
|
|
54
|
+
**Bind `changed` in forms**; `sliding` fires every frame of a drag.
|
|
55
|
+
- `largeStep`, defaulting to a tenth of the range, for `PageUp`/`PageDown` and
|
|
56
|
+
`Shift+Arrow`.
|
|
57
|
+
- Right-to-left support: the horizontal arrows and the track mirror; the value
|
|
58
|
+
does not.
|
|
59
|
+
|
|
60
|
+
**Also new: the `cdk/number` primitives** this is built on, shared with the
|
|
61
|
+
numeric input family still to come — exact scaled-`BigInt` decimal arithmetic
|
|
62
|
+
(`stepDecimal`, `roundDecimal`, `clampDecimal`), locale-aware
|
|
63
|
+
`parseNumber`/`formatNumber` over `Intl`, and `createPressRepeat` for
|
|
64
|
+
hold-to-repeat stepper buttons. Stepping `0.1` twenty times from `0` now lands
|
|
65
|
+
on exactly `2`, and `1.15` rounds to `1.2` where `(1.15).toFixed(1)` gives
|
|
66
|
+
`'1.1'`.
|
|
67
|
+
|
|
68
|
+
### Minor Changes
|
|
69
|
+
|
|
70
|
+
- [`2a79bb8`](https://github.com/uni-design-system/uni/commit/2a79bb8ebd8fd0b5cd792697972b6f48b444c80f) Thanks [@gaenglish](https://github.com/gaenglish)! - New `uni-number-input`: the field for a quantity, a price, a percentage or a
|
|
71
|
+
measurement, with locale-aware parsing, `Intl` formatting on commit,
|
|
72
|
+
prefix/suffix adornments, min/max/step fences and steppers that hold to repeat.
|
|
73
|
+
|
|
74
|
+
```html
|
|
75
|
+
<uni-number-input label="Quantity" [(value)]="qty" [min]="1" />
|
|
76
|
+
<uni-number-input label="Unit price" currency="USD" [(value)]="price" />
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Why not `<input type="number">`.** Per the HTML value sanitization algorithm,
|
|
80
|
+
a number input whose text is not a valid floating-point number reports
|
|
81
|
+
`value === ''`. Type `12,50` as most of Europe does, or paste `1,234.56` from a
|
|
82
|
+
spreadsheet, and the app reads an empty field with no way to tell that from a
|
|
83
|
+
blank one — a data-loss bug, and the reason this is `type="text"` with
|
|
84
|
+
`role="spinbutton"`. The platform control also cannot group thousands, cannot
|
|
85
|
+
place an affix outside the editable text, has ~10px unstyleable spinners below
|
|
86
|
+
the WCAG 2.2 target minimum, changes value on the scroll wheel while focused,
|
|
87
|
+
and steps in floats.
|
|
88
|
+
|
|
89
|
+
**What it does instead.**
|
|
90
|
+
- **Presets** — `decimal`, `integer`, `currency`, `percent` — supply decimals,
|
|
91
|
+
grouping, affix and `inputmode` together, so a money field is `label`,
|
|
92
|
+
`currency="USD"`, `[(value)]`. `numberFormat` is the escape hatch, merged over
|
|
93
|
+
the preset.
|
|
94
|
+
- **Parses what people actually type**: canonical ASCII always, locale grouping
|
|
95
|
+
(`1.234,56` in German), pasted affixes and currency symbols, accounting
|
|
96
|
+
negatives `(1,234.56)`, localized digit systems, compact `1.5k`, and — behind
|
|
97
|
+
`allowExpressions` — spreadsheet arithmetic like `12*3`, via a shunting-yard
|
|
98
|
+
parser that never calls `eval`.
|
|
99
|
+
- **Unreadable text stays in the field**, flagged with a dashed underline and a
|
|
100
|
+
`rejected` event, rather than being silently swallowed.
|
|
101
|
+
- **Exact arithmetic.** Stepping `0.1` twenty times from `0` lands on exactly
|
|
102
|
+
`2`; `1.15` rounds to `1.2` where `(1.15).toFixed(1)` gives `'1.1'`. A second
|
|
103
|
+
`valueAsString` model carries digits a `number` cannot, and a dev-mode warning
|
|
104
|
+
fires when a bound `value` cannot round-trip.
|
|
105
|
+
- **Percent never divides behind your back**: `preset="percent"` shows `15%` for
|
|
106
|
+
`15`. Models that really are fractions set `valueIsFraction`.
|
|
107
|
+
- Clamping on commit rather than per keystroke, visible fences that disable the
|
|
108
|
+
matching stepper and announce, `wrap` for cyclic fields, `emptyStepValue`,
|
|
109
|
+
four stepper layouts, and hold-to-repeat that announces once on release.
|
|
110
|
+
|
|
111
|
+
`uni-slider` gains `valueDisplay="input"`, which seats one of these as its
|
|
112
|
+
readout — drag for the ballpark, type for the exact value.
|
|
113
|
+
|
|
114
|
+
Adds `numberInput` to `ComponentName` with a theme entry. Field chrome is not
|
|
115
|
+
duplicated there: colour, border, radius and focus come from the shared `input`
|
|
116
|
+
options via `uni-input-box`, so a number field restyles with every other field.
|
|
117
|
+
|
|
118
|
+
`uni-input-box` gains a `managedInset` input. The themed leading inset normally
|
|
119
|
+
rides the inner `<input>`, which is right while the text is the field's leading
|
|
120
|
+
edge and wrong the moment an adornment sits in front — a currency prefix would
|
|
121
|
+
hug the border while the number it belongs to sat indented past it. A field with
|
|
122
|
+
adornments sets `managedInset` and places the inset on whichever element is
|
|
123
|
+
actually first. Existing fields are unaffected: the default is `false`.
|
|
124
|
+
|
|
125
|
+
- [`e7875ee`](https://github.com/uni-design-system/uni/commit/e7875ee81030a703f4ca1904bb94cb8ddc7f57b9) Thanks [@gaenglish](https://github.com/gaenglish)! - New `uni-number-range-input`: two linked numeric fields in one chrome with a
|
|
126
|
+
single `{ start, end }` value — price filters, thresholds, tolerances. This
|
|
127
|
+
completes the numeric family alongside `uni-number-input`,
|
|
128
|
+
`uni-quantity-stepper` and the rebuilt `uni-slider`.
|
|
129
|
+
|
|
130
|
+
```html
|
|
131
|
+
<uni-number-range-input label="Price range" currency="USD" [(value)]="price" [minGap]="50" />
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
`start`/`end` deliberately match `UniDateRange`, so the library has one range
|
|
135
|
+
vocabulary, and they never collide with the `min`/`max` **inputs**, which mean
|
|
136
|
+
the fence rather than the value.
|
|
137
|
+
|
|
138
|
+
**The rules that make it one field rather than two glued together:**
|
|
139
|
+
- **Either end alone is a valid value.** `{ start: 50 }` means "50 and up",
|
|
140
|
+
which is a real filter. This is where it diverges from `uni-date-time-input`,
|
|
141
|
+
whose two parts are two halves of one answer.
|
|
142
|
+
- **Stepping is fenced; typing swaps.** A stepper can never walk one end through
|
|
143
|
+
the other — its wall is the other end, held off by `minGap`, and each end's
|
|
144
|
+
`aria-valuemin`/`aria-valuemax` report that wall rather than the outer bounds.
|
|
145
|
+
A _typed_ backwards commit is swapped and announced instead, the rule
|
|
146
|
+
`uni-calendar` applies to a backwards date range: clamping against the other
|
|
147
|
+
end would destroy the number just entered.
|
|
148
|
+
- **`minGap` pushes the end you edited**, not the other one, which is what makes
|
|
149
|
+
stepping behave as a fence rather than dragging the range along.
|
|
150
|
+
- A refused draft flags only the end it was typed into; the other stays valid.
|
|
151
|
+
- `preset`, `currency`, `prefix`, `suffix`, `decimals`, `grouping`, `locale` and
|
|
152
|
+
`roundingMode` are forwarded to both ends so the halves always read alike.
|
|
153
|
+
|
|
154
|
+
It owns its commit path rather than nesting two `uni-number-input`s, because the
|
|
155
|
+
two behaviours above need _different_ bounds — a stepper must be fenced at the
|
|
156
|
+
other end while a typed commit must arrive un-clamped — and a child field
|
|
157
|
+
applies one bound pair to both. The arithmetic, parsing and formatting are still
|
|
158
|
+
the shared `cdk/number` primitives.
|
|
159
|
+
|
|
160
|
+
Adds `numberRangeInput` to `ComponentName` with a theme entry (`partGap`,
|
|
161
|
+
`dividerText`, `dividerColor`). Field chrome is not duplicated there: colour,
|
|
162
|
+
border, radius and focus come from the shared `input` options via
|
|
163
|
+
`uni-input-box`. `dividerText` is literal punctuation rather than an icon token —
|
|
164
|
+
an en dash between two numbers is not a glyph a theme swaps artwork for.
|
|
165
|
+
|
|
166
|
+
- [`589cecb`](https://github.com/uni-design-system/uni/commit/589cecb178d9119eea3fbc3f3cd9149eefdaa036) Thanks [@gaenglish](https://github.com/gaenglish)! - New `uni-quantity-stepper`: `− 3 +` for cart lines, table cells and seat counts
|
|
167
|
+
— the numeric core with no field chrome, no label and no room for either.
|
|
168
|
+
|
|
169
|
+
```html
|
|
170
|
+
<uni-quantity-stepper label="Quantity, Blue T-shirt (M)" [(value)]="qty" [min]="1" />
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
A separate component rather than a `chrome="bare"` flag on `uni-number-input`,
|
|
174
|
+
because this control is defined by what it does _not_ have — presets, affixes,
|
|
175
|
+
expressions, four stepper layouts — and eight inputs are easier to write
|
|
176
|
+
correctly than forty plus a list of which ones to leave alone. The arithmetic,
|
|
177
|
+
parsing and hold-to-repeat come from the same `cdk/number` primitives, so
|
|
178
|
+
`1,200` and the keyboard map behave identically in both.
|
|
179
|
+
- **`deleteAtMin`** is the cart pattern in one attribute: at the floor the
|
|
180
|
+
decrement becomes a remove affordance, renamed `Remove {label}`, and emits
|
|
181
|
+
`removed` rather than stepping to zero. Without it every shop reimplements the
|
|
182
|
+
same `value === 1 ? remove() : step(-1)` branch outside the component. (The
|
|
183
|
+
spec called this output `emptied`; that is a native `HTMLMediaElement` event
|
|
184
|
+
name, which `@angular-eslint/no-output-native` rightly rejects, and `removed`
|
|
185
|
+
is already what `uni-tag` calls the same request.)
|
|
186
|
+
- The middle is a real input by default — typing `12` beats tapping `+` eleven
|
|
187
|
+
times, and it takes the same grouped and locale-aware entry the field does.
|
|
188
|
+
`editable=false` renders the number as text for read-mostly tables, and the
|
|
189
|
+
buttons become the tab stops since there is nothing else to focus.
|
|
190
|
+
- `size` is `sm` / `md` / `lg` at 24 / 32 / 40px _outer_ height, so an `md`
|
|
191
|
+
stepper lines up with a 32px field beside it, with the buttons square at that
|
|
192
|
+
height. `md` and `lg` clear the 24×24 pointer target of WCAG 2.2 SC 2.5.8;
|
|
193
|
+
`sm` leaves 22px inside its border and is the dense desktop option.
|
|
194
|
+
|
|
195
|
+
Adds `quantityStepper` to `ComponentName` with a theme entry. Unlike the other
|
|
196
|
+
numeric controls it does **not** inherit the shared `input` chrome — it is not a
|
|
197
|
+
field — so it carries its own container tokens, defaulted to the same values
|
|
198
|
+
`input` uses so a cart stepper and a form field look related out of the box.
|
|
199
|
+
Height comes from the entry's `sizes` block rather than an option.
|
|
200
|
+
|
|
201
|
+
### Patch Changes
|
|
202
|
+
|
|
203
|
+
- [`ce94c8a`](https://github.com/uni-design-system/uni/commit/ce94c8a6acb5c70351fecfaca3469c46727c2aa4) Thanks [@gaenglish](https://github.com/gaenglish)! - `uni-angular`'s build now runs `tsc --noEmit` first, closing the last gap left
|
|
204
|
+
by the earlier "typecheck the builds" change — core and react already did this,
|
|
205
|
+
angular did not.
|
|
206
|
+
|
|
207
|
+
`ng-packagr` alone does not surface every type error in the package. A real one
|
|
208
|
+
reached a Storybook build unnoticed: a form control declaring
|
|
209
|
+
`min = input(0)` where `FormValueControl` types the property as
|
|
210
|
+
`InputSignal<number | undefined>` (Signal Forms syncs it from `min()`
|
|
211
|
+
validators), which is a variance error `pnpm build` reported as success. Every
|
|
212
|
+
form control must declare `min`/`max` as `input<number | undefined>(…)` and read
|
|
213
|
+
a `resolvedMin()` computed internally.
|
|
214
|
+
|
|
215
|
+
Also here:
|
|
216
|
+
- A `type-check` script, matching core and react, so `turbo type-check` covers
|
|
217
|
+
the whole workspace.
|
|
218
|
+
- `prototypes/**` is excluded from the package tsconfig. Those are standalone
|
|
219
|
+
design explorations that reference modules and dependencies which do not
|
|
220
|
+
exist in this package — excluding them is what makes a real typecheck
|
|
221
|
+
possible over the code that ships.
|
|
222
|
+
- Three latent type errors fixed: `vitest.config.ts` took `defineConfig` from
|
|
223
|
+
`vite`, whose overload does not accept the `test` block (it comes from
|
|
224
|
+
`vitest/config`); `spacing.spec.ts` lost callback inference through an
|
|
225
|
+
untyped `vi.spyOn` return; and `radio.motion.spec.ts` typed a `motion`
|
|
226
|
+
argument as `Record<string, unknown>` rather than `Motions`.
|
|
227
|
+
|
|
228
|
+
- [`5cf120b`](https://github.com/uni-design-system/uni/commit/5cf120b9cb268e74a2ed062d8df2cf5cf9749750) Thanks [@gaenglish](https://github.com/gaenglish)! - Lint MDX prose for stray `{`, which MDX compiles to a JSX expression.
|
|
229
|
+
|
|
230
|
+
Writing `named "Increase {label}"` in a docs bullet makes `label` a reference to
|
|
231
|
+
an undefined variable, and the page dies at runtime with
|
|
232
|
+
`ReferenceError: label is not defined` under Storybook's "The component failed to
|
|
233
|
+
render properly" banner. Nothing caught it: it is a React render error rather
|
|
234
|
+
than a compile error, so **`build-storybook` passes**, and `check-doc-links.mjs`
|
|
235
|
+
only validates link ids. Only opening the page found it — twice.
|
|
236
|
+
|
|
237
|
+
`scripts/check-mdx-braces.mjs` now runs as part of the package's `lint` script,
|
|
238
|
+
so `turbo run lint` (and therefore CI) fails on it. It skips the four places a
|
|
239
|
+
brace is legitimate — fenced code blocks, inline code spans including ones that
|
|
240
|
+
soft-wrap across a line, ESM `import`/`export` statements, and JSX tags such as
|
|
241
|
+
`of={Stories.X}` or `rows={[…]}` — plus MDX comment containers. Hits are
|
|
242
|
+
reported as `file:line:column` with the offending line and the fix: backtick the
|
|
243
|
+
text, or escape the brace as `\{`.
|
|
244
|
+
|
|
245
|
+
Also available on its own as `pnpm lint:mdx`.
|
|
246
|
+
|
|
247
|
+
- [`05f991f`](https://github.com/uni-design-system/uni/commit/05f991f0cc6b0895777763ede7605b5e274dc0a1) Thanks [@gaenglish](https://github.com/gaenglish)! - Three cosmetic fixes in the numeric family.
|
|
248
|
+
|
|
249
|
+
**`uni-quantity-stepper`'s dividers were heavier than its frame.** The rules
|
|
250
|
+
either side of the value took `dividerColor: 'outline'` — a solid grey — against
|
|
251
|
+
an outer border of the 8%-alpha `light` token, so the control read as three
|
|
252
|
+
pieces stuck together rather than one frame. They now take the **same `border`
|
|
253
|
+
token as the container** and move with it on focus, so a focused stepper is not
|
|
254
|
+
accented on the outside and grey down the middle. `dividerColor` remains as an
|
|
255
|
+
opt-in override for a deliberately distinct rule, and is unset in the base theme.
|
|
256
|
+
|
|
257
|
+
**`uni-quantity-stepper` had no focus state.** Every other field gets its focus
|
|
258
|
+
chrome from `uni-input-box`, which the stepper deliberately does not use — and
|
|
259
|
+
its inner input clears its own outline via `removeInputPlatformStyling`, so
|
|
260
|
+
focusing the middle showed nothing at all. The container now carries the same
|
|
261
|
+
`:has(input:focus)` rule and the same `input` theme tokens the box applies
|
|
262
|
+
(`focusOutline`, `focusOutlineOffset`, and the optional `focusBorder` /
|
|
263
|
+
`focusShadow` / `focusColor`), so a stepper highlights exactly like the field
|
|
264
|
+
beside it — including in themes such as Wellsourced that express focus as a
|
|
265
|
+
border and ring rather than an outline. Error state still wins, keeping a
|
|
266
|
+
flagged control visibly flagged while it is corrected.
|
|
267
|
+
|
|
268
|
+
**A trailing suffix sat against the right border.** The leading inset was
|
|
269
|
+
already handled, so the two sides did not match. `uni-number-range-input` — which
|
|
270
|
+
has no steppers — now insets both edges of its row, and `uni-number-input` insets
|
|
271
|
+
the trailing edge whenever no stepper occupies it (`stepperLayout="none"`, or a
|
|
272
|
+
read-only field). Where a stepper _is_ present the trailing edge is still left
|
|
273
|
+
to it, because a button is meant to reach the border.
|
|
274
|
+
|
|
275
|
+
Both insets ride the row rather than the `<input>`: `uni-input-box` styles
|
|
276
|
+
`& input` at a higher specificity than a component class can reach, so padding
|
|
277
|
+
set on the input itself is silently dropped.
|
|
278
|
+
|
|
279
|
+
- [`1fe8941`](https://github.com/uni-design-system/uni/commit/1fe89415c65d38c97d610fb5725e8a050432192f) Thanks [@gaenglish](https://github.com/gaenglish)! - `uni-tag-input`'s first chip no longer rides the left border.
|
|
280
|
+
|
|
281
|
+
The themed leading inset was applied by `uni-input-box` to the inner `<input>`,
|
|
282
|
+
which is the field's leading edge only while it is empty. Once a chip existed,
|
|
283
|
+
the chip sat flush against the border while the text after it stayed indented.
|
|
284
|
+
The chip row now owns the inset — it is the leading content — via the
|
|
285
|
+
`managedInset` input added alongside `uni-number-input`, so the first chip and
|
|
286
|
+
an empty field's placeholder both start at the same 8px as every other field's
|
|
287
|
+
text. Wrapped chip rows are unaffected; vertical padding already handled those.
|
|
288
|
+
|
|
289
|
+
- Updated dependencies [[`2a79bb8`](https://github.com/uni-design-system/uni/commit/2a79bb8ebd8fd0b5cd792697972b6f48b444c80f), [`e7875ee`](https://github.com/uni-design-system/uni/commit/e7875ee81030a703f4ca1904bb94cb8ddc7f57b9), [`589cecb`](https://github.com/uni-design-system/uni/commit/589cecb178d9119eea3fbc3f3cd9149eefdaa036), [`21b655d`](https://github.com/uni-design-system/uni/commit/21b655df0f93e2e2de6a22ccf38050b474d4e5ab)]:
|
|
290
|
+
- @uni-design-system/uni-core@10.0.0
|
|
291
|
+
|
|
292
|
+
## 9.0.1
|
|
293
|
+
|
|
3
294
|
## 9.0.0
|
|
4
295
|
|
|
5
296
|
### Major Changes
|