@reliability-design/web 1.4.9 → 1.4.11

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.
Files changed (55) hide show
  1. package/CHANGELOG.md +161 -2
  2. package/custom-elements.json +18604 -0
  3. package/dist/components/rel-accordion/README.md +9 -2
  4. package/dist/components/rel-alert/README.md +4 -7
  5. package/dist/components/rel-autocomplete/README.md +209 -209
  6. package/dist/components/rel-avatar/README.md +228 -118
  7. package/dist/components/rel-breadcrumb/README.md +1 -0
  8. package/dist/components/rel-button/README.md +9 -9
  9. package/dist/components/rel-calendar/README.md +111 -109
  10. package/dist/components/rel-cardmedia/README.md +1 -1
  11. package/dist/components/rel-carousel/README.md +187 -187
  12. package/dist/components/rel-checkbox/README.md +159 -147
  13. package/dist/components/rel-chip/README.md +141 -138
  14. package/dist/components/rel-container/README.md +1 -1
  15. package/dist/components/rel-date-picker/README.md +221 -206
  16. package/dist/components/rel-drawer/README.md +4 -4
  17. package/dist/components/rel-kbd/README.md +188 -141
  18. package/dist/components/rel-layout/README.md +34 -34
  19. package/dist/components/rel-menu/README.md +17 -10
  20. package/dist/components/rel-menubar/README.md +218 -218
  21. package/dist/components/rel-otp/README.md +4 -8
  22. package/dist/components/rel-pagination/README.md +141 -100
  23. package/dist/components/rel-popover/README.md +220 -203
  24. package/dist/components/rel-radio/README.md +142 -131
  25. package/dist/components/rel-range-picker/README.md +194 -171
  26. package/dist/components/rel-resizable/README.md +220 -199
  27. package/dist/components/rel-segmented-button/README.md +158 -157
  28. package/dist/components/rel-select/README.md +21 -17
  29. package/dist/components/rel-sheet/README.md +3 -2
  30. package/dist/components/rel-signature-pad/README.md +161 -0
  31. package/dist/components/rel-slider/README.md +140 -131
  32. package/dist/components/rel-snackbar/README.md +170 -168
  33. package/dist/components/rel-split-button/README.md +129 -0
  34. package/dist/components/rel-stepper/README.md +171 -171
  35. package/dist/components/rel-switch/README.md +122 -117
  36. package/dist/components/rel-tab/README.md +184 -174
  37. package/dist/components/rel-textfield/README.md +21 -28
  38. package/dist/components/rel-time-picker/README.md +188 -170
  39. package/dist/components/rel-toast/README.md +20 -11
  40. package/dist/components/rel-tooltip/README.md +5 -4
  41. package/dist/components/rel-tree/README.md +157 -0
  42. package/dist/components/rel-upload/README.md +8 -5
  43. package/dist/index.d.mts +1608 -624
  44. package/dist/index.d.ts +1608 -624
  45. package/dist/index.js +11933 -6802
  46. package/dist/index.js.map +1 -1
  47. package/dist/index.mjs +11009 -5885
  48. package/dist/index.mjs.map +1 -1
  49. package/dist/styles/ag-grid.css +274 -0
  50. package/dist/styles/motion.css +31 -0
  51. package/dist/styles/motion.tokens.json +38 -0
  52. package/dist/styles/vars.css +88 -64
  53. package/dist/{vars-DXX6QOAG.css → vars-E22LYFMV.css} +88 -64
  54. package/package.json +61 -37
  55. package/dist/styles/focus-ring.ts +0 -84
package/CHANGELOG.md CHANGED
@@ -1,5 +1,163 @@
1
1
  # Changelog — @reliability-design/web
2
2
 
3
+ ## 1.5.0 (TBD)
4
+
5
+
6
+ React 19, naming and accessibility release. Several defaults change behaviour without a rename — they are listed under [Changed](#changed-150), each with what to do. The release notes and migration checklist are on the docs site at `/docs/migration`.
7
+
8
+ Paired releases: `@reliability-design/angular` 1.5.0, which now requires web `^1.5.0` — install both together. `@reliability-design/icons` 1.5.0 ships alongside: 224 new icons (121 from the design file, 103 FO icons redrawn in the DS style), 65 existing icons redrawn from the design file, `caret-left` / `caret-right` / `arrow-from-left` / `go-back` now point the way their names say, and name aliases (see its changelog). Web keeps accepting any icons version.
9
+
10
+ ### Added
11
+
12
+ - **`rel-toast` `tone="success"` and `tone="info"`**, on `rel-alert`'s solid fill and text tokens, so a toast matches an alert of the same tone. Announced politely; they show a leading icon, as `destructive` now does (see Changed). The design file's Toast has both tones.
13
+ - **`rel-accordion` `content-type`** — `text` (default, unchanged) | `custom`: no body padding, type or colour, 8px radius on the body wrapper (Figma Content Type=Custom).
14
+ - **`rel-segmented-button` `disabled`** disables the whole group (click, keyboard, Tab stop); per-option `disabled` is kept.
15
+ - **`rel-chip` `field-aria-label`** names an icon-only chip and its remove button; the remove button is exposed as **`::part(remove)`**.
16
+ - **`rel-breadcrumbs` `aria-label`** names the navigation (default "Breadcrumb").
17
+ - **`rel-range-picker` editable From / To boxes** in the panel: labelled inputs over the draft range, with inline errors; nothing commits until Apply.
18
+ - **An outer `<label>` works for `rel-switch`, `rel-checkbox` and `rel-radio`**, wrapping or `for=`. The three are form-associated; see Changed.
19
+ - **Motion v1 tokens** — 19 `--rel-motion-*` properties (6 durations, 4 easings, 4 duration + easing recipes, a loading cycle) in `vars.css`, plus the new exports `@reliability-design/web/motion.css` and `@reliability-design/web/motion.tokens.json`. The recipe durations drop to 0ms under `prefers-reduced-motion`. Opt-in: no component reads them yet.
20
+ - **Kebab-case attribute spellings** for 33 attributes on 13 components (`full-width`, `error-message`, `total-pages`, …) — see Deprecated.
21
+ - **`rel-checkbox` `supportingText`** (camelCase property) now renders; it silently did nothing.
22
+ - **`unavailable` CSS part** on unavailable day cells — `rel-calendar` (`part="item unavailable"`), `rel-date-picker` and `rel-range-picker` (`part="unavailable"`). Use it in place of `::part(item):disabled`; see Changed.
23
+ - **`rel-checkbox` `disabled`** (property and attribute), ORed with `state="disabled"`, which stays the documented spelling.
24
+ - **`rel-kbd` `key-name` and `platform`** — named keys in the platform's convention (Mac symbols ⌘ ⌥ ⇧ …, short words elsewhere) and a `mod` key (⌘ on Mac, Ctrl elsewhere); `platform="auto|mac|other"` also on `rel-kbd-group`. Screen readers hear the full key name.
25
+ - **`rel-resizable-panel` `panel-label`** names a panel while its content overflows and it is a focusable region (default "Panel N"); read-only `scrollable`.
26
+ - **`rel-chip` `presentational`** — the chip body is plain text (no button role, Tab stop or key handling); the remove button stays a real button.
27
+ - **`rel-tree`** (new, Figma Nested Tree) — an `items` tree with hierarchy guides, `selection="single" | "none" | "multiple"` (multiple: cascading checkboxes with indeterminate parents), controlled `selected` / `selected-values` / `expanded-values`, `expandAll()` / `collapseAll()`, lazy children (`rel-load-children`), `rel-change` and `rel-expanded-change`, and the full WAI-ARIA tree keyboard (arrows, Home / End, `*`, type-ahead), RTL and forced colours.
28
+ - **`rel-avatar-group`** (new, Figma Avatar Group) — slotted avatars get the group's `size` and a `ring` and overlap by 10 / 8 / 6 / 4px; `max` and `total` produce a "+N" circle (named "{n} more", `overflow-label`); `role="group"` named by `label`.
29
+ - **`rel-avatar` `ring`, `badge`, `badge-icon`, `badge-label`, `icon`** — a 2px page-colour ring outside the circle; a 12 / 10 / 8 / 6px status badge (`dot`: green; `icon`: neutral disc with `badge-icon`), read as `badge-label` or hidden without one; `icon` names a rel-icon for `type="icon"`. New hooks `--rel-avatar-ring-color`, `--rel-avatar-badge-bg`, part `badge`.
30
+ - **`rel-pagination` `type="page-select"` and `show-rows-per-page`** — a "Page [dropdown] of N" jump-to-page layout, and a "Results per Page" dropdown after the navigation with any type (`rows-per-page-options`, default `[10, 20, 50, 100]`; `rows-per-page-label`). A rows pick sets `per-page`, fires `rel-per-page-change` (`{ perPage }`) and returns to page 1. New parts `page-select`, `rows-per-page`.
31
+ - **`custom-elements.json`** — a Custom Elements Manifest of every element's API (`customElements` field; `@reliability-design/web/custom-elements.json`), with deprecations, status, `since` and accessibility notes under `rds`.
32
+ - **`rel-upload` `max-files`** (property `maxFiles`, `0` = no limit) — with `multiple`, files beyond the limit become error rows ("only 5 files allowed") and `rel-invalid` rejections with the new `reason: "count"`; rows already in the list count first, then new files in order; `retry()` re-checks the limit.
33
+ - **`rel-upload` `rel-file-replaced`** (`{ name, previous, next }`) — picking a file whose name is already in the list still replaces that row, and now also fires this event, announces "report.pdf replaced" and shows an info notice in the alert slot (the delay warning and the failure alert take the slot first).
34
+ - **`rel-upload` `rel-upload-complete`** (`{ succeeded, failed }`, this batch's rows) — once per batch when nothing is uploading any more, in both modes: in controlled mode it follows the statuses the app writes. Not after `cancel()`. Announced politely; no built-in toast (the docs show a `rel-toast` recipe). `rel-complete` (self-driving only) is unchanged.
35
+ - **`rel-tab` `orientation="vertical"`** — the tab list sits in a column beside the panel (`--rel-tab-list-width`), with `aria-orientation="vertical"`, tabs 24px apart along a rule on the list's inline-start edge with the active bar on that edge, and Up / Down instead of Left / Right. Long labels wrap; no built-in breakpoint (switch to horizontal on small screens).
36
+ - **`rel-tab` `icon-placement="top"`** — stacks each tab's icon above its label, with the badge beside the label; stacked tabs are 76 / 64 / 52px tall at large / medium / small. Works in both orientations.
37
+ - **`rel-signature-pad`** (new, status stable) — captures a handwritten signature with a mouse, pen or finger on a 160px pad that fills its container (`--rel-signature-pad-height`; focus, drawing and error draw a 2px border inside the pad edge, and focus in error adds a 2px danger ring outside), or a typed name: the "Type your name instead" link switches to `mode="type"` (Poppins italic), the keyboard alternative to drawing (WCAG 2.2 SC 2.5.7). `value` is a trimmed PNG data URL (2×, black ink in every theme) and the **form value**: the pad is form-associated and submits it under `name`, is invalid (`valueMissing`) when `required` and empty, empties on form reset and comes back on state restore (decision 0006; switch, checkbox and radio still set no form value). Also `strokes` (the vector record), `signedAt`, `typed-name`, `toDataURL(type)`, `toSVG()`, `isEmpty()`, `undo()` / `clear()`. Undo is stroke level and also reverses Clear, so Clear asks no confirmation; Ctrl/Cmd+Z undoes inside the field; the helper row shows "Signed {date, time, time zone}". Label, `helper-text`, `error` / `error-message`, `disabled` and `readonly` work as on `rel-textfield`. `rel-change` (`{ value, strokes, signedAt, mode }`, user actions only) and `rel-begin` / `rel-end`.
38
+ - **`rel-split-button`** (new, status stable) — the Combo Button: a main action and a chevron that opens a `rel-menu` of `items` (`{ value, label, icon?, disabled? }`) below the pill, end-aligned and at least as wide. Both segments are drawn with `rel-button`'s own styles, so `variant` (primary | secondary, the default | ghost | static), `tone` (neutral | brand | destructive) and `size` (32 / 40 / 48px) match `rel-button` exactly, including hover, pressed, focus and disabled; outer corners keep the pill radius and the seam is square. While the menu is open the chevron keeps its pressed look. Also `disabled`, `loading` (a spinner only on the main action, which keeps its accessible name; the chevron is disabled), `icon-only` with `aria-label` (the main action is a square too), `icon`, `menu-label` (the chevron's name, default "More options") and `open`. The host's `click` is the main action; `rel-select` (`{ value, item }`) and `rel-open-change` (`{ open }`). WAI-ARIA menu button: two Tab stops; Enter, Space or Down opens on the first entry and Up on the last; Escape or a choice returns focus to the chevron; Tab closes; a mouse open shows no ring. Divider: its own 1px column, in the outline border (secondary; the hover colour while either segment is hovered or pressed, or the menu is open), the label colour (primary), white (static) or `--rel-border-subtle` (ghost).
39
+ - **`rel-popover` `has-popup`** (property `hasPopup`) — the value written to the trigger's `aria-haspopup`: `dialog` (default, unchanged), or `menu` for a panel holding a `rel-menu` (also `listbox`, `tree`, `grid`, `true`).
40
+ - **`rel-menu` item icons and `focusItem(index)`** — `MenuItem.icon` draws a `rel-icon` before the label on `list` and `arrow` rows (20 / 18 / 16px by size, hidden from screen readers); `focusItem()` moves the virtual focus (`aria-activedescendant`), clamped, a negative index counting from the end, for menu buttons that open on the last row.
41
+ - **`createGridNavigation(grid, options)`** (a utility, exported from the main entry) — the WAI-ARIA grid keyboard for plain markup (`[role="row"]` > `[role="gridcell"]`): a roving Tab stop, arrows, Home / End, Ctrl+Home / Ctrl+End, PageUp / PageDown with `pageSize`, right-to-left, `disabledCells` (`"focus"`, the default, or `"skip"`), `wrap`, `onActivate` (Enter, Space, click), `onMove`, a custom `resolve` key map, and a handle with `active`, `focusCell()`, `refresh()` and `destroy()`. Framework-free, so recipes can use it; the Rate Calendar recipe does.
42
+ - **`@reliability-design/web/ag-grid.css`** — an AG Grid theme (v33+ with the Theming API; 32.2–32.3 when the app passes `theme: themeQuartz`) that maps AG Grid's theme params to our tokens, light and dark. Scope it with a `.rel-data-table` wrapper; set `data-density` to `dense` (40px rows) or `comfortable` (64px) on it (default 56px, header 48px). Row-state classes for `rowClassRules`: `rel-data-table__row--error` (wins over selected) and `rel-data-table__row--disabled`. Sortable headers show the unsorted icon at rest, as `unSortIcon: true` would. AG Grid itself is not a dependency. Docs: the Data Table recipe.
43
+
44
+ ### Changed
45
+
46
+ <a id="changed-150"></a>Visible or behavioural, with no rename to warn you:
47
+
48
+ - **`="false"` turns a Boolean attribute off.** Presence and `""` stay true. Before, any value read as true. Default-true props (`dismissible`, `icon-close`, `show-separator`, `pause-on-hover`, `close-on-select`, `close-on-escape`, `close-on-outside-click`, `responsive`) can now be switched off from HTML. Markup writing `="false"` — including Angular `[attr.x]="false"` and React 18 `x={false}` — now reads false: React 18 `<rel-alert dismissible={false}>` writes `dismissible="false"`, which was still dismissible in 1.4.9 and is not in 1.5.0.
49
+ - **A string assigned as a property is converted** for Array, Object, Number and Boolean props (React 19 sets custom-element props as properties). Unparseable JSON warns once and falls back to `[]` / `{}` instead of `null`. Every component now extends the new `RelElement` base.
50
+ - **`rel-switch`, `rel-checkbox`, `rel-radio` are form-associated.** They appear in `form.elements` and `el.click()` toggles a switch or checkbox. Form submission is unchanged (no form value). With an outer label on a checkbox, set `label=""`.
51
+ - **The same three behave disabled inside a `<fieldset disabled>`** (no click, label click or key; out of the Tab order; disabled styling). Their own `disabled` / `state` is untouched, so re-enabling the fieldset restores it. They now match `:disabled` when disabled, which they never did in 1.4.9. Known limit: a host with `disabled="false"` is enabled but still matches `:disabled`.
52
+ - **Popups stay open on an outside scroll while their field is visible** (select, autocomplete, date / range / time picker, menu submenus) and close once it scrolls out of view or under a sticky header; 1.4.9 closed on any scroll. A wheel over an open panel no longer scrolls the page.
53
+ - **`rel-popover` moves focus into the panel on open and back to the trigger's control on close**; `trap-focus` now wraps. With nothing focusable, `rel-popover-content`'s dialog takes focus.
54
+ - **Unavailable days are `aria-disabled` (focusable), not `disabled`**, in `rel-date-picker` and `rel-calendar`, as in `rel-range-picker`. **Breaking for custom CSS:** `rel-calendar::part(item):disabled` no longer matches them (only a wholly disabled calendar); style them with `::part(unavailable)`.
55
+ - **Out-of-month days are interactive** in the date and range pickers; min / max (and `isDateDisabled` on the date picker) apply as usual.
56
+ - **`rel-radio` and `rel-checkbox` geometry.** Radio follows the rebuilt design-file control (wall 1.6px small / medium; large ring 19.2px, dot 9.6px). Both paint the same size wherever they sit. In forced colors the checked radio dot and the checkbox tick / dash are now visible. Disabled labels lose subpixel anti-aliasing in Chromium.
57
+ - **`rel-upload`:** inside strokes per the design file — icon badge 46 → 44px, file rows 70 → 68px, dropzone 2px shorter, 6/4 dashes; the file row's progress track on `--rel-border-subtle` (dark `#404040` → `#2B2B2B`).
58
+ - **`rel-drawer`** renders its footer only when the `footer` slot has content, and the footer divider (drawer and `rel-modal`) now tracks content that grows after opening.
59
+ - **`rel-toast`:** an unknown `tone` resolves to `neutral`; it used to be added as a raw class (`tone="hidden"` hid the toast).
60
+ - **`rel-pagination`** `total-pages`, `default-page`, `total-items`, `per-page` are observed (were read once on connect); `show-label` and `href-template` now work.
61
+ - **`rel-menu`:** the row focus ring shows for keyboard focus only; `type="arrow"` flyouts open in the top layer, so containers no longer clip them, and they flip at the viewport edge.
62
+ - **`rel-range-picker`** colours and radii follow the design file's tokens (8px period cells, outlined switchers, darker From / To label in light mode, full-pill lone endpoint, scrim backdrop).
63
+ - **`rel-select`:** `role="listbox"` moves from the panel to the options container; the panel is a named group. **`rel-tooltip`:** text is set as `aria-description` on the focused control; `aria-describedby` is no longer set.
64
+ - **Pickers:** the error border beats the filled border; 24 × 24 icon targets (heights unchanged).
65
+ - **`rel-accordion`:** open bodies are no longer capped at 1000px.
66
+ - **`rel-select` multi-select chips sit in an overlay beside the trigger, not inside the button.** Same look and position; a click on a chip label or "+N" opens the panel; Tab goes trigger → each "Remove {label}" (no dead stops); remove targets ≥ 24 × 24px; a keyboard removal moves focus to the next remove button; "+N" is `aria-hidden`. `::part(value)` in multi mode with chips is now the overlay; CSS that shifted chips through `::part(trigger)` padding no longer moves them.
67
+ - **Day tones:** out-of-month and weekend days in `rel-calendar`, `rel-date-picker` and `rel-range-picker` use `--rel-text-caption` instead of a 40% / 70% fade; unavailable days use `--rel-text-disabled` at full opacity, with no extra fade; days inside a selected range are full strength; the range panel binds `--rel-bg-neutral` (same value). In `rel-calendar` and `rel-date-picker`, today keeps its `--rel-border-brand` ring when it is unavailable or the calendar is disabled, as in the design file (it used to switch to a faint `--rel-border-subtle` ring; `rel-range-picker` already kept it).
68
+ - **24px targets:** `rel-carousel` dot buttons are ≥ 24 × 24px cells (visible dot unchanged; the row is 24px tall; the cells touch, so the dots sit 24px apart centre to centre, 16px apart edge to edge). **Breaking for custom CSS:** `::part(dot)` is now the transparent cell — style the visible dot with `::part(dot)::before`. `rel-slider`'s rail is ≥ 24px tall (Small 16 → 24, Medium 20 → 24; track and thumb unchanged).
69
+ - **`rel-button`:** Pressed is exactly the Hover fill in every style, also for a keyboard or touch press; only the scale is added.
70
+ - **`rel-tab`:** a disabled tab keeps the enabled badge colours (was white on white in dark mode). **`rel-slider`:** fixed bubble height 18 / 22 / 24px. **`rel-menu`:** keyboard navigation rings only the current row (no ring around the whole menu).
71
+ - **`rel-tab` follows the updated design file (sandbox Tabs):** every tab is at least 80px wide; an inactive label uses `--rel-text-caption` (was `--rel-text-body`); hover darkens the label to `--rel-text-default` with no fill (`--rel-tab-hover-color` now defaults to `transparent`; set it to bring a fill back); icons stay `--rel-text-default`; the strip is `--rel-border-subtle` (the same in light, `#2B2B2B` instead of `#404040` in dark). The active label keeps its semibold `--rel-text-default`.
72
+ - **`rel-range-picker`:** Apply stays disabled while only a start day is picked (Reset → Apply still clears a committed range); a preset whose range equals the picked days shows as selected; after a mouse click on the start day the To box shows its hover border as the next field, while keyboard focus stays in the grid; day hover uses `--rel-bg-neutral-elevated-2`; the error line gains a 14px error icon.
73
+ - **`rel-autocomplete`:** 12px between a row's icon and its text (was 8); a disabled row keeps its icon and shows its text in `--rel-text-disabled` instead of fading the whole row to 40%; the matched characters in the supporting line are semibold, like the label's.
74
+ - **`rel-kbd-group`** `items` entries are named keys: on a Mac `"Ctrl"` shows ⌃; off-Mac `"Escape"` shows Esc. Use `"mod"` for the primary modifier, or `platform="other"`.
75
+ - **`rel-resizable-panel`:** an overflowing panel is a named, focusable `role="region"` with a focus ring until its content fits again.
76
+ - **`rel-switch` follows the updated design file** (API and defaults unchanged): the label is one step smaller (12 / 14 / 16px, was 14 / 16 / 20); one square 1.5px focus ring around control and label (Pill loses its inner ring); a disabled label uses `--rel-text-disabled` instead of 40% opacity, with the dulled handle on every disabled switch; hover and pressed cover the whole component.
77
+ - **`rel-carousel` dot colours:** inactive dots use `--rel-bg-neutral-elevated-3` (was elevated-2); the active pill is `--rel-bg-surface-brand` with a 1px `--rel-text-default` edge.
78
+ - **`rel-button`:** the legacy `variant="icon"` Neutral button darkens on hover (the Icon Only hover over its grey fill); its hover used to equal its rest fill.
79
+ - **Colours follow the design file's contrast update** (WCAG AA in light and dark; no token added, removed or renamed):
80
+ - **Borders:** `--rel-border-default` goes light `#E5E5E5` → `#707070`, dark `#2B2B2B` → `#707070` (3:1). `--rel-border-accent` goes light `#C2C2C2` → `#575757`, dark `#525252` → `#989898`. `--rel-border-subtle` goes light `#F7F7F7` → `#E5E5E5`, dark `#1B1B1B` → `#2B2B2B`.
81
+ - **Solid status fills:** danger `#FF5252` → `#CE3131`; info `#0091EA` → `#00528D` (dark too); success `#00A86B` → `#008655`.
82
+ - **Hover and dragged:** hover is lighter than dragged in every tone (neutral hover `#2B2B2B` → `#404040`).
83
+ - **Light status text:** danger → `#942323`, success → `#006440`, info → `#00528D`.
84
+ - **Placeholder:** light → `#707070`, dark → `#989898`.
85
+ - **Dark text:** a step lighter (label `#F7F7F7`, body `#E5E5E5`, caption `#C2C2C2`).
86
+ - **Dark `--rel-bg-surface-elevated`:** `#111111` → `#2B2B2B`. This changes `rel-container surface="elevated"`, disabled picker triggers, picker icon-button hover and time-picker shortcut keys.
87
+ - **Link hover:** the light destructive link hover goes to `#3E0E0E` and the dark neutral link hover to `#C2C2C2`.
88
+ - **Primitives:** gray-300 / 400 / 500 → `#989898` / `#707070` / `#575757`, and green-300 → `#60C9A3`.
89
+ - **Dividers and decorative edges** move to `--rel-border-subtle`, so they stay soft. This covers drawer and sheet dividers, the neutral tooltip edge, the menubar separator, picker shortcut keys, the range presets divider, `rel-card-media`, `rel-kbd`, the `rel-textfield` prefix and suffix divider and the `rel-upload` rows.
90
+ - **Fills:**
91
+ - the time picker's column scrollbar thumb is `--rel-bg-neutral-elevated-3`: light `#E5E5E5` → `#989898`, dark `#2B2B2B` → `#575757`;
92
+ - an inset muted `rel-kbd` is `--rel-bg-neutral-elevated-2`: dark `#2B2B2B` → `#404040`, light unchanged.
93
+ - **The `rel-upload` dropzone dash** moves to `--rel-border-default`.
94
+ - **What to do:** update screenshot tests, and replace `--rel-border-default` with `--rel-border-subtle` wherever your own CSS uses it as a divider or background.
95
+ - **`rel-kbd`:** a single-symbol key is a square cap, 20 × 20 / 24 × 24 / 28 × 28px at small / medium / large, with the symbol centred. This applies whether the symbol is slotted or comes from `key-name`: ⌘ ⌥ ⇧ ⌃, `mod` when it shows ⌘, the arrows, and ↩ ⎋ ⇥ ⌫. A small ⌘ used to be about 30px wide. Letters, digits and words are unchanged.
96
+ - **`rel-toast`:** `destructive`, `success` and `info` show a 20px leading icon (`error`, `check-circle`, `info`) in the static-light colour. It is `::part(icon)` and is hidden from screen readers. The gap is 8px, or 12px at `size="large"`. Neutral toasts are unchanged.
97
+ - **`rel-upload` same-name replace is no longer silent:** an info notice shows where nothing did, and screen readers hear it (see Added). `UploadRejection.reason` gains `"count"`; an exhaustive TypeScript `switch` over it needs the new case.
98
+
99
+ - **`rel-upload` success state and image previews:** when a batch finishes with no failures, a success alert shows in the alert slot ("3 files uploaded"); the delay warning and the failure alert come first. Image files show a 40×40 preview in place of the file icon (object URLs revoked when the row leaves the list or the element disconnects); an image that cannot be decoded keeps the icon.
100
+ - **`rel-kbd` `variant="muted"`:** the label moves to `--rel-text-caption` and now passes AA (5.74:1 light, 5.82:1 dark; it was 3.9 / 3.6 on placeholder).
101
+ - **Disabled fields are readable** and follow the design file's TextField Disabled frame: the whole field at 0.65 opacity, an elevated-2 box with the accent border, the label in `--rel-text-label` and the value and placeholder in `--rel-text-caption`. The text used to be `--rel-text-disabled` under the 0.65, which painted about 1.2–1.4:1. This covers `rel-textfield` (every variant, floating and legend labels included), `rel-autocomplete`, `rel-date-picker`, `rel-time-picker` (both were 0.4 / 0.6 before, now 0.65) and `rel-range-picker` (which was the enabled look at 0.6). `rel-select` already looked this way; `rel-otp` and `rel-signature-pad` keep their own disabled looks.
102
+
103
+ ### Fixed
104
+
105
+ - **Calendar keyboard:** `rel-calendar`, `rel-date-picker` and `rel-range-picker` move by date, not grid position (Sep 27 + ArrowDown went to Nov 1); Home / End honour `week-start`; PageUp / PageDown (Shift: year) clamp to the month's end; the Tab stop follows the last-used day.
106
+ - **Panels closed within their opening frame** could stay painted or stick open on `rel-select`, `rel-autocomplete` and `rel-popover`. `rel-select` also ignored Escape / Tab pressed just after opening.
107
+ - **`rel-tooltip` was never announced**: its `aria-describedby` pointed into a shadow root.
108
+ - **`rel-drawer` / `rel-modal`** share one page scroll lock (closing one no longer unlocks the page under another); no more "ResizeObserver loop" error events; the drawer no longer leaks an observer per open.
109
+ - **Dialog focus** skips inert, disabled and `visibility: hidden` elements.
110
+ - **`rel-button`** keeps its accessible name while loading.
111
+ - **`rel-autocomplete`** multi rows and Select-all are named; **`rel-select`**'s listbox no longer fails `aria-required-children`.
112
+ - **`rel-carousel`** keeps measuring after a DOM move; **`rel-pagination`**'s page buttons are natively disabled with the host; **`rel-upload-actions`** no longer triggers an unfixable `rel-button` "no tone" notice.
113
+ - Pagination, segmented-button and tooltip transitions respect `prefers-reduced-motion`.
114
+ - **`rel-select`:** Enter or Space on a multi-select chip's remove button did nothing (it sat inside the trigger button); a keyboard removal dropped focus to `<body>`.
115
+ - **`rel-switch`:** the pressed state never showed (mouse or Space); a disabled checked Pill painted with the checked fills; forced colours painted nothing.
116
+ - **`rel-carousel`:** the dots were invisible in forced colours.
117
+ - **`rel-popover` / `rel-menu`:** a mouse open no longer draws a focus ring in the panel (or, after a mouse close, on the trigger); keyboard opens still do, and in a menu opened with the mouse the first arrow key brings the row ring back.
118
+
119
+ - **Fields in error lost their focus ring:** a focused `rel-textfield` (and `rel-autocomplete`) in error showed only the caret. Error + focus now draws the 2px ring outside the danger border in `--rel-border-danger` on the textfield (underline: a 2px danger line below; legend: the danger outline doubles), `rel-select` and the date, time and range pickers (WCAG 2.4.7).
120
+ - **`rel-popover` panel sat at a stale spot until the next frame:** it is now placed in the same task that opens it. Before, for one frame it stayed at its previous position, or at 0,0 on a first open; nothing painted there, but a quick pointer release could land on the unplaced panel instead of the trigger.
121
+ - **`rel-button` `variant="static" icon-only` was not square:** the static style's 40 / 50 / 60px minimum width outranked the icon-only reset, so a static icon-only button was 40 / 50 / 60 wide instead of a 32 / 40 / 48 square. Static label buttons keep their minimum width; no other style changes.
122
+ - **`rel-popover` panel text followed the `align` attribute:** Chromium maps an element's `align` attribute to `text-align`, and rel-popover reflects `align` (default `center`), so every popover centred its panel text (and its trigger's inline content) and `align="end"` right-aligned it. The host now takes its parent's alignment, as if the attribute were not there. If you relied on the centring, set `text-align` on your panel content.
123
+ - **`rel-pagination` `type="page-select"`: the dropdown squeezed its rows.** The panel was as narrow as the 72px trigger, so the search box shrank to its icon and, with a classic scrollbar, the selected row showed only its check, not the number. The page list now has no search box (typing a page number still jumps to it) and is at least as wide as the longest number, the check and a scrollbar need. The rows-per-page dropdown had the same squeeze (the selected "20" showed as "2…") and gets the same floor. The width comes from a new opt-in hook on `rel-select`, **`--rel-select-panel-min-width`** (unset by default: the panel still matches the trigger).
124
+ - **`rel-select` / `rel-autocomplete` multi-select logged a deprecation notice the app never caused:** their option checkboxes used the deprecated `supportingtext` attribute spelling, so every multi-select logged `[rel-checkbox] "supportingtext" is deprecated`. They now set the property.
125
+ - **`rel-signature-pad` focused in error drew seams:** the 2px danger edge inside the pad was a border plus a clipped pseudo element, and focus added an outline outside, so light gaps showed between three red bands (clearest when the browser is zoomed). The edge is now one outline, 2px inside at rest and 2px inside plus 2px outside when focused. Same look, no seams.
126
+ - **`rel-split-button` secondary: the chevron showed three dark sides.** Hovered, pressed or open, the chevron's border darkened but the divider beside it didn't, while the main action's hover darkens the divider too. The divider now follows either segment, and the open menu.
127
+ - **`rel-pagination` extended layout lost its ellipsis between 480 and 768px.** In that width it keeps only the first, last and current ±1 pages but also hid every "…", so 5 pages on page 1 read "1 2 5" with nothing between 2 and 5 (and 20 pages on page 10 read "1 9 10 11 20"). A "…" now marks each gap that width opens; a gap of a single page shows that page instead.
128
+
129
+ ### Known issues
130
+
131
+ - **`disabled="false"` still matches `:disabled`** on `rel-switch`, `rel-checkbox` and `rel-radio`: the control is enabled, but the browser counts the attribute's presence. Remove the attribute instead of writing `"false"`.
132
+
133
+ ### Deprecated (still supported — removal targeted for 3.0)
134
+
135
+ The old lowercase-joined attribute spellings below log one notice per (component, attribute): `[rel-textfield] "fullwidth" is deprecated and will be removed in 3.0 — use "full-width" instead. (attribute spelling only; the fullWidth property is unchanged)`. Property names are unchanged. Reflected props (marked †) still write the old name in 1.x, so `[fullwidth]`-style CSS selectors keep matching. React 18 JSX writes camelCase props as these lowercase attributes, so `fullWidth` in JSX logs the notice — write `full-width`.
136
+
137
+ | Component | Old → new |
138
+ | --- | --- |
139
+ | `rel-checkbox` | `supportingtext` → `supporting-text` |
140
+ | `rel-date-picker`, `rel-range-picker`, `rel-time-picker` | `fullwidth`† → `full-width` |
141
+ | `rel-pagination` | `defaultpage`, `totalpages`, `totalitems`, `perpage`, `showlabel`, `hreftemplate` → `default-page`, `total-pages`, `total-items`, `per-page`, `show-label`, `href-template` |
142
+ | `rel-popover` | `defaultopen`, `sideoffset`, `alignoffset`, `trapfocus`, `closeonescape`, `closeonoutsideclick` → `default-open`, `side-offset`, `align-offset`, `trap-focus`, `close-on-escape`, `close-on-outside-click` |
143
+ | `rel-radio` | `selectedvalue`†, `errormessage` → `selected-value`, `error-message` |
144
+ | `rel-resizable-panel` | `defaultsize`, `minsize`, `maxsize` → `default-size`, `min-size`, `max-size` |
145
+ | `rel-slider` | `showticklabels`†, `showbubble` → `show-tick-labels`, `show-bubble` |
146
+ | `rel-snackbar` | `iconclose` → `icon-close` |
147
+ | `rel-tab` | `activeindex`† → `active-index` |
148
+ | `rel-textfield` | `lefticon`, `righticon`, `prefixicon`, `prefixiconarialabel`, `errormessage`, `helpertext`, `fullwidth`† → `left-icon`, `right-icon`, `prefix-icon`, `prefix-icon-aria-label`, `error-message`, `helper-text`, `full-width` |
149
+ | `rel-toast` | `actionlabel` → `action-label` |
150
+
151
+ Not aliased: `arialabel` (badge, pagination), native-mirror `maxlength`, and attributes of props that are already deprecated.
152
+
153
+ **Events:** `rel-upload`'s `rel-complete` is deprecated, with removal in 3.0. Use `rel-upload-complete`, which fires once per batch in both modes (self-driving and controlled). `rel-complete` still fires exactly as before (self-driving mode only). Adding a listener for it on the element logs a one-time console warning, and `custom-elements.json` marks the event deprecated.
154
+
155
+ ### Package hygiene
156
+
157
+ - `exports["."]` carries per-condition types (`import` → `index.d.mts`, `require` → `index.d.ts`); no consumer change expected. New exports `./motion.css`, `./motion.tokens.json`.
158
+ - **The package no longer ships `dist/styles/focus-ring.ts`**, a TypeScript source file; `dist/styles` holds only `vars.css`, `motion.css` and `motion.tokens.json`.
159
+ - The build fails if the icons package is unbuilt, a published entry file is missing, or a non-declaration `.ts` lands in `dist`; `prepublishOnly` builds.
160
+
3
161
  ## 1.4.9 (2026-09-26)
4
162
 
5
163
 
@@ -8,8 +166,9 @@ variant gates cannot see, because those gates read source text and bound token n
8
166
  of these defects is about what the browser actually *paints*. Two reported items turned out not to
9
167
  be defects at all and are noted under [Not changed](#notchanged-149) so they are not re-filed.
10
168
 
11
- Paired releases: `@reliability-design/angular` 1.4.9, which now requires web `^1.4.9`.
12
- `@reliability-design/icons` is unchanged and stays on 1.4.4.
169
+ Paired releases: `@reliability-design/angular` 1.4.9 — install it together with this version. (Its
170
+ published peer range still reads `^1.4.8`; the move to `^1.4.9` lands in the next release. See the
171
+ Angular changelog.) `@reliability-design/icons` is unchanged and stays on 1.4.4.
13
172
 
14
173
  Three changes are visible without a rename to warn you; they are listed under
15
174
  [Changed](#changed-149).