@reliability-design/web 1.4.7 → 1.4.8
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 +37 -2
- package/dist/components/rel-accordion/README.md +2 -1
- package/dist/components/rel-autocomplete/README.md +21 -5
- package/dist/components/rel-avatar/README.md +9 -7
- package/dist/components/rel-badge/README.md +4 -5
- package/dist/components/rel-button/README.md +32 -2
- package/dist/components/rel-card/README.md +3 -3
- package/dist/components/rel-carousel/README.md +2 -0
- package/dist/components/rel-checkbox/README.md +7 -4
- package/dist/components/rel-chip/README.md +13 -7
- package/dist/components/rel-container/README.md +8 -8
- package/dist/components/rel-date-picker/README.md +1 -1
- package/dist/components/rel-divider/README.md +11 -1
- package/dist/components/rel-kbd/README.md +2 -2
- package/dist/components/rel-layout/README.md +34 -0
- package/dist/components/rel-menu/README.md +3 -1
- package/dist/components/rel-menubar/README.md +1 -1
- package/dist/components/rel-otp/README.md +4 -3
- package/dist/components/rel-pagination/README.md +2 -2
- package/dist/components/rel-popover/README.md +5 -5
- package/dist/components/rel-progress/README.md +3 -3
- package/dist/components/rel-radio/README.md +1 -1
- package/dist/components/rel-range-picker/README.md +4 -1
- package/dist/components/rel-segmented-button/README.md +2 -1
- package/dist/components/rel-select/README.md +5 -3
- package/dist/components/rel-sheet/README.md +3 -3
- package/dist/components/rel-skeleton/README.md +5 -4
- package/dist/components/rel-slider/README.md +3 -2
- package/dist/components/rel-snackbar/README.md +13 -7
- package/dist/components/rel-stepper/README.md +11 -7
- package/dist/components/rel-switch/README.md +16 -7
- package/dist/components/rel-tab/README.md +4 -2
- package/dist/components/rel-textfield/README.md +18 -1
- package/dist/components/rel-toast/README.md +14 -6
- package/dist/components/rel-tooltip/README.md +13 -2
- package/dist/components/rel-upload/README.md +2 -2
- package/dist/index.d.mts +709 -237
- package/dist/index.d.ts +709 -237
- package/dist/index.js +10397 -7840
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +7458 -4901
- package/dist/index.mjs.map +1 -1
- package/dist/styles/focus-ring.ts +84 -0
- package/dist/styles/vars.css +75 -60
- package/dist/{vars-JHTUGNRG.css → vars-DXX6QOAG.css} +75 -60
- package/package.json +1 -1
|
@@ -84,7 +84,8 @@ actions.items = [...actions.items, { label: "Duplicate" }];
|
|
|
84
84
|
|
|
85
85
|
| Property | Attribute | Type | Default | Description |
|
|
86
86
|
| --- | --- | --- | --- | --- |
|
|
87
|
-
| `type` | `type` | `"
|
|
87
|
+
| `type` | `type` | `"list" \| "checkbox" \| "select-option" \| "arrow" \| "default" \| "fixed" \| "fit"` | `"list"` | Row shape (Figma ".Menu Item" Type). `list` (default) = plain rows; `checkbox` = toggling rows with a checkbox; `select-option` = single-select rows with a trailing check. `arrow` is a code-only extension with no Figma counterpart: rows whose `submenu` opens a flyout. Because it rides this axis, submenus cannot currently be combined with checkbox or select-option rows — see the README. DEPRECATED values, all still working: `default` is the old spelling of `list`; `fixed` / `fit` were width modes and now set `width` instead, leaving the row shape at `list`. |
|
|
88
|
+
| `width` | `width` | `"fixed" \| "fit"` | `undefined` | Sizing mode (Figma "Menu" Type). Both modes are `--rel-menu-width` (300px) wide — Figma's Fixed and Fit variants are both 300px — and the axis varies the HEIGHT: `fixed` pins the panel to `--rel-menu-height` (500px) and scrolls, `fit` hugs its rows. `fit` previously varied the width instead, which was the wrong dimension. This was also fused into `type`, where choosing a width silently forced plain rows and choosing a row shape silently forced the default width. Reflected. |
|
|
88
89
|
| `size` | `size` | `"large" \| "medium" \| "small"` | `"large"` | Row size (Figma ".Menu Item" Size, 6326:616): large = 48px rows with body-lg labels (Figma default), medium = 40px / body-md, small = 32px / body-sm. Added in 1.4.7; before that rows were a fixed 36px. Reflected. |
|
|
89
90
|
| `items` | `items` | `MenuItem[]` | `[]` | The rows to render, in order. Each entry is a `MenuItem` (`label`, optional `active`, `checked`, `disabled`, `submenu`, `open`). The array is copied on assignment, so mutate and reassign it to update the menu. |
|
|
90
91
|
|
|
@@ -166,6 +167,7 @@ actions.items = [...actions.items, { label: "Duplicate" }];
|
|
|
166
167
|
|
|
167
168
|
## Notes / Edge Cases
|
|
168
169
|
|
|
170
|
+
- **Known limitation — submenus are mutually exclusive with checkbox and select-option rows.** Figma models row shape and width as two independent axes, which is why they are now two props (`type` and `width`). Submenus, however, are a code-only feature with no Figma counterpart, and they ride the `type` axis as `type="arrow"` — so a checkbox menu with submenus cannot currently be expressed. Tracked for 3.0, where `arrow` would become its own boolean the same way the width values just moved off `type`.
|
|
169
171
|
- `MenuItem` shape: `{ label: string; active?: boolean; checked?: boolean; disabled?: boolean; submenu?: MenuItem[]; open?: boolean }`. `active` marks the selected row (`default`, `fixed`, `fit`, `select-option`, submenu entries), `checked` the checkbox state, `submenu` / `open` the flyout rows and their initial visibility (`arrow` only).
|
|
170
172
|
- The menu keeps an internal copy of `items`; user interaction updates that copy, never your array. Read the current state from the event detail (`item`, `checked`, `parent` / `sub`) — the objects in `e.detail` are the updated copies. Reassign `items` to change the rows.
|
|
171
173
|
- Light DOM: `createRenderRoot()` returns the element, so the menu's CSS is injected as a `<style>` block and page styles can reach it. The parts are plain `part` attributes — target them with `rel-menu [part="list"]` / `rel-menu [part="panel"]`, not `::part()`.
|
|
@@ -128,7 +128,7 @@ Items are plain HTML placed inside a `<rel-menubar-menu>`; the menubar recognise
|
|
|
128
128
|
| Property | Attribute | Type | Default | Description |
|
|
129
129
|
| --- | --- | --- | --- | --- |
|
|
130
130
|
| `bindShortcuts` | `bind-shortcuts` | `boolean` | `false` | Opt-in: actually bind the keys declared via `data-shortcut` on items (e.g. `data-shortcut="Ctrl+Z"`) instead of only displaying them; a "Mod" token means Cmd on Apple platforms and Ctrl elsewhere, and keystrokes that originate in inputs, textareas or contenteditable regions are ignored. |
|
|
131
|
-
| `type` | `type` | `"fixed" \| "fit"` | `"fit"` | Width mode (Figma "Menu Bar" Type, 8699:4): `fit` sizes the bar to its triggers, `fixed` stretches it across its container (override the stretched width with `--rel-menubar-width`).
|
|
131
|
+
| `type` | `type` | `"fixed" \| "fit"` | `"fit"` | Width mode (Figma "Menu Bar" Type, 8699:4): `fit` sizes the bar to its triggers, `fixed` stretches it across its container (override the stretched width with `--rel-menubar-width`). The default stays `fit`, which is how the bar has always rendered. Reflected. |
|
|
132
132
|
|
|
133
133
|
### Events
|
|
134
134
|
|
|
@@ -89,11 +89,11 @@ A one-time-password input implementing the Figma "OTP Input" cell: one single-ch
|
|
|
89
89
|
| --- | --- | --- | --- | --- |
|
|
90
90
|
| `value` | `value` | `string` | `""` | The concatenated code (all cells joined). Set it to fill the cells programmatically; it never exceeds `length` characters. Reflected. |
|
|
91
91
|
| `length` | `length` | `number` | `6` | Total number of cells (characters in the code). |
|
|
92
|
-
| `groupSize` | `group-size` | `number` | `3` | Cells per visual group; a separator renders between groups. `0` (or `show-separator` off) renders one ungrouped row. |
|
|
92
|
+
| `groupSize` | `group-size` | `number` | `3` | Cells per visual group; a separator renders between groups. Grouping applies only when `length` divides evenly by this — otherwise the row renders ungrouped, because a ragged final group would put a separator before a lone cell. So the default `length="6"` is 3–3, `length="4"` is one ungrouped row of four, and `group-size="2"` with `length="4"` is 2–2. `0` (or `show-separator` off) also renders one ungrouped row. |
|
|
93
93
|
| `placeholder` | `placeholder` | `string` | `""` | Placeholder character shown in every empty cell. |
|
|
94
94
|
| `inputMode` | `input-mode` | `"numeric" \| "alphanumeric" \| ""` | `""` | Accepted character set (Trello 5). Describes what the field ACCEPTS, not a semantic input type — hence the name. Explicitly set it wins over the deprecated `type`; unset (`""`, like the native `inputMode` accessor it shadows on the host), `type` (default `"numeric"`) applies. Note the lowercase `inputmode` prop is a different thing: the raw native keyboard hint forwarded to each cell. |
|
|
95
95
|
| `mask` | `mask` | `boolean` | `false` | Renders the cells as `type="password"` so entered characters are masked. |
|
|
96
|
-
| `disabled` | `disabled` | `boolean` | `false` | Disables every cell and dims the control to 0.
|
|
96
|
+
| `disabled` | `disabled` | `boolean` | `false` | Disables every cell and dims the control to 0.4 opacity (cell fill and border unchanged, as Figma specifies). Reflected. |
|
|
97
97
|
| `readonly` | `readonly` | `boolean` | `false` | Makes every cell read-only: the value is shown but typing, paste and keyboard editing are ignored. Reflected. |
|
|
98
98
|
| `required` | `required` | `boolean` | `false` | Marks the first cell `required` for native form validation. |
|
|
99
99
|
| `name` | `name` | `string \| null` | `null` | When set, renders a hidden `<input name="…">` (part `hidden-input`) carrying `value` for native form submission. |
|
|
@@ -102,7 +102,7 @@ A one-time-password input implementing the Figma "OTP Input" cell: one single-ch
|
|
|
102
102
|
| `pattern` | `pattern` | `string \| null` | `null` | Native `pattern` attribute forwarded to every cell (per-character regex for form validation). |
|
|
103
103
|
| `ariaLabel` | `aria-label` | `string \| null` | `null` | Accessible name of the whole group; defaults to "One-time password input". Each cell is additionally labelled "Digit/Character N of M". |
|
|
104
104
|
| `invalid` | `invalid` | `boolean` | `false` | Error styling (danger border on every cell) and `aria-invalid="true"`. Reflected. |
|
|
105
|
-
| `showSeparator` | `show-separator` | `boolean` | `true` | Renders the dash separator between groups. Boolean attribute: its presence means true — set the property to `false` to hide separators. |
|
|
105
|
+
| `showSeparator` | `show-separator` | `boolean` | `true` | Renders the dash separator between groups. Boolean attribute: its presence means true — set the property to `false` to hide separators. Even when on, separators appear only if `length` divides evenly by `group-size`; see `groupSize`. |
|
|
106
106
|
| `size` | `size` | `"small" \| "medium" \| "large" \| "sm" \| "md" \| "lg"` | `"medium"` | Cell size on the shared field scale (square, border-box): `small` 32px, `medium` 40px, `large` 48px (the Figma OTP Input cell). `sm` / `md` / `lg` are deprecated aliases of the full words. Reflected. |
|
|
107
107
|
|
|
108
108
|
#### Deprecated (still supported — removal targeted for 3.0)
|
|
@@ -164,6 +164,7 @@ A one-time-password input implementing the Figma "OTP Input" cell: one single-ch
|
|
|
164
164
|
- `input-mode` unset (`""`) falls back to the deprecated `type` prop (default `"numeric"`); set `input-mode` explicitly and it always wins.
|
|
165
165
|
- The lowercase `inputmode` prop is the raw native keyboard hint, not the accepted character set — normally leave it unset.
|
|
166
166
|
- `show-separator` is a boolean attribute: `show-separator="false"` still enables separators. Hide them with `el.showSeparator = false` or `group-size="0"`.
|
|
167
|
+
- **Separators require an even split.** Grouping applies only when `length` divides evenly by `group-size`; otherwise the cells render as one ungrouped row. A separator marks a boundary between two equal groups, so a length that does not divide would put one before a lone trailing cell — `length="4"` with the default `group-size="3"` used to draw `3 – 1`. Affected lengths at the default group size are 4, 5, 7 and 8; each now renders ungrouped. To group a length of 4, set `group-size="2"` for `2 – 2`.
|
|
167
168
|
- `required` is applied to the first cell only, so native form validation blocks submission when the code is empty but not when it is partial — check `e.detail.complete` yourself.
|
|
168
169
|
- The `autocomplete` prop currently has no effect: every cell always renders `autocomplete="one-time-code"`.
|
|
169
170
|
- `disabled` and `readonly` also suppress paste and keyboard handling; the value stays visible.
|
|
@@ -48,8 +48,8 @@ Page navigation implementing the Figma "Pagination" component in its three **Typ
|
|
|
48
48
|
| `totalPages` | `totalpages` | `number` | `0` | Total number of pages. `0` (the default) lets `totalItems` / `perPage` compute the page count instead. Attribute `totalPages`, also read once as `total-pages` on connect. |
|
|
49
49
|
| `totalItems` | `totalitems` | `number` | `0` | Total item count; with `perPage` it computes the page count when `totalPages` is `0` and is the "of N" figure in the count-text readout. Attribute `totalItems`, also read once as `total-items` on connect. |
|
|
50
50
|
| `perPage` | `perpage` | `number` | `10` | Items per page, used to compute the page count from `totalItems` and the "start–end" range in the count-text readout. Attribute `perPage`, also read once as `per-page` on connect. |
|
|
51
|
-
| `showLabel` | `showlabel` | `boolean` | `false` |
|
|
52
|
-
| `disabled` | `disabled` | `boolean` | `false` | Dims the whole control to
|
|
51
|
+
| `showLabel` | `showlabel` | `boolean` | `false` | DELIBERATE DIVERGENCE — do not flip this default to `true`. Figma's `Type=Extended` has no boolean for the caption: the "Viewing page 1 of 10" text is a fixed child of both Extended variants and is load-bearing for their 78px height (40 + spacing-md + 22). Here it stays opt-in. Ruled by the user: our behaviour stands and the DESIGN FILE follows our docs. Defaulting it on would silently add 38px to every existing extended pagination. |
|
|
52
|
+
| `disabled` | `disabled` | `boolean` | `false` | Dims the whole control to 40% opacity, shows a `not-allowed` cursor and ignores every page change. Reflected. |
|
|
53
53
|
| `hrefTemplate` | `hreftemplate` | `string` | `""` | Reserved for link-mode pagination. Currently accepted but not rendered: every page control is a `<button>`, so navigate in your `rel-change` handler instead. |
|
|
54
54
|
| `ariaLabel` | `arialabel` | `string` | `"Pagination"` | Accessible name of the `role="navigation"` landmark (attribute `ariaLabel`). Set it when a page contains more than one pagination control. |
|
|
55
55
|
|
|
@@ -17,11 +17,11 @@ A click-to-open floating panel anchored to a trigger, implementing the Figma "Po
|
|
|
17
17
|
<!-- Panel padding (Figma Size S / M / L = 12 / 16 / 20px) -->
|
|
18
18
|
<rel-popover>
|
|
19
19
|
<rel-button variant="secondary">Compact</rel-button>
|
|
20
|
-
<rel-popover-content size="
|
|
20
|
+
<rel-popover-content size="small" aria-label="Compact panel"><p>12px padding</p></rel-popover-content>
|
|
21
21
|
</rel-popover>
|
|
22
22
|
<rel-popover>
|
|
23
23
|
<rel-button variant="secondary">Roomy</rel-button>
|
|
24
|
-
<rel-popover-content size="
|
|
24
|
+
<rel-popover-content size="large" aria-label="Roomy panel"><p>20px padding</p></rel-popover-content>
|
|
25
25
|
</rel-popover>
|
|
26
26
|
|
|
27
27
|
<!-- Positioning: side, alignment and pixel offsets -->
|
|
@@ -143,7 +143,7 @@ Set these on the host (or an ancestor) to customise the element without touching
|
|
|
143
143
|
| Custom property | Default | Description |
|
|
144
144
|
| --- | --- | --- |
|
|
145
145
|
| `--rel-popover-arrow-bg` | `var(--rel-bg-neutral)` | Fill of the `arrow` chevron (default `--rel-bg-neutral`, matching `<rel-popover-content>`). |
|
|
146
|
-
| `--rel-popover-arrow-border` | `
|
|
146
|
+
| `--rel-popover-arrow-border` | `transparent` | **Deprecated.** Stroke of the `arrow` chevron's two slanted edges. The panel no longer draws a border — overlapping surfaces are separated by shadow — so this defaults to `transparent` and the chevron has no edge. Set it to restore a stroke. |
|
|
147
147
|
|
|
148
148
|
### `<rel-popover-content>`
|
|
149
149
|
|
|
@@ -152,7 +152,7 @@ Set these on the host (or an ancestor) to customise the element without touching
|
|
|
152
152
|
| Property | Attribute | Type | Default | Description |
|
|
153
153
|
| --- | --- | --- | --- | --- |
|
|
154
154
|
| `ariaLabel` | `aria-label` | `string` | `""` | Accessible name applied to the inner `role="dialog"` box (attribute `aria-label`); describe what the panel is for. |
|
|
155
|
-
| `size` | `size` | `"sm" \| "md" \| "lg"` | `"
|
|
155
|
+
| `size` | `size` | `"small" \| "medium" \| "large" \| "sm" \| "md" \| "lg"` | `"medium"` | Figma Size axis: panel padding 12px (`small`), 16px (`medium`, default) or 20px (`large`). `sm` / `md` / `lg` are alternative spellings and stay supported — they are normalised to the full words, not deprecated. Reflected. |
|
|
156
156
|
|
|
157
157
|
### Events
|
|
158
158
|
|
|
@@ -200,4 +200,4 @@ Set these on the host (or an ancestor) to customise the element without touching
|
|
|
200
200
|
- **Arrow.** `arrow` draws a 14×11 chevron on the panel edge facing the trigger, centred on the trigger and clamped 15px in from the panel corners; the trigger gap becomes `max(sideoffset, 13px)`. Colour it with `--rel-popover-arrow-bg` / `--rel-popover-arrow-border` (defaults match `<rel-popover-content>`); if you use a custom panel with a different surface, set both so the chevron blends in.
|
|
201
201
|
- **`<rel-popover-content>`** is `display: block; width: 100%; max-width: 400px`; override `max-width` on the element for wider panels. Slotted `h1`–`h6` get heading-sm type and `p` gets placeholder-tone body text with a bottom margin (none on the last paragraph).
|
|
202
202
|
- **`disabled`** blocks the trigger and dims the host but does not close a panel that is already open — set `open = false` first if needed.
|
|
203
|
-
- The `size` values on `<rel-popover-content>` are
|
|
203
|
+
- The `size` values on `<rel-popover-content>` are `small` / `medium` / `large`. The short spellings `sm` / `md` / `lg` are alternative spellings and keep working — they are normalised to the full words before the attribute reflects, so `rel-popover-content[size="medium"]` matches whichever spelling was written.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# rel-progress
|
|
2
2
|
|
|
3
|
-
`<rel-progress>` is the Figma "Progress" indicator in its two shapes and two behaviours: a full-width
|
|
3
|
+
`<rel-progress>` is the Figma "Progress" indicator in its two shapes and two behaviours: a full-width 2px linear bar or a 36px circular ring, each either determinate (fills to `value`, 0–100) or indeterminate (loops an animation while you wait). Use `linear-determinate` / `circular-determinate` for uploads, imports and multi-step flows where progress is known, and the `*-indeterminate` modes as a loading signal while a request is in flight. It is a passive `role="progressbar"` element — it does not block interaction (use `rel-modal` with `loading` for that) and does not announce completion on its own.
|
|
4
4
|
|
|
5
5
|
## Usage
|
|
6
6
|
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
|
|
46
46
|
| Property | Attribute | Type | Default | Description |
|
|
47
47
|
| --- | --- | --- | --- | --- |
|
|
48
|
-
| `mode` | `mode` | `"linear-determinate" \| "linear-indeterminate" \| "circular-determinate" \| "circular-indeterminate"` | `"linear-determinate"` | Shape and behaviour: `linear-*` is a full-width
|
|
48
|
+
| `mode` | `mode` | `"linear-determinate" \| "linear-indeterminate" \| "circular-determinate" \| "circular-indeterminate"` | `"linear-determinate"` | Shape and behaviour: `linear-*` is a full-width 2px bar, `circular-*` a 36px ring; `*-determinate` fills to `value`, `*-indeterminate` loops an animation and ignores `value`. Reflected. |
|
|
49
49
|
| `value` | `value` | `number` | `0` | Completion percentage 0–100 for the determinate modes; out-of-range values are clamped before rendering and before `aria-valuenow`. |
|
|
50
50
|
| `label` | `label` | `string` | `""` | Accessible name of the progressbar (not rendered visually); defaults to "Progress" for determinate and "Loading" for indeterminate modes. |
|
|
51
51
|
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
|
|
83
83
|
- `value` is clamped to 0–100 before rendering and before `aria-valuenow`; the indeterminate modes ignore it entirely.
|
|
84
84
|
- The `track` and `indicator` parts exist only in the two linear modes. The circular modes render an inline `<svg>` with no parts, so `::part(track)` matches nothing there.
|
|
85
|
-
- Linear bars are
|
|
85
|
+
- Linear bars are 2px tall with a 4px radius and stretch to the host's width (host is `display: block`). Circular rings are fixed at 36px and the host switches to `display: inline-block`, so they sit inline with text.
|
|
86
86
|
- The linear determinate width animates over 0.3s and the circular arc over 0.35s; a value that jumps from 0 to 100 therefore takes a moment to catch up visually.
|
|
87
87
|
- Circular strokes are 3px (determinate) and 4px (indeterminate) with a flat (`butt`) line cap; the determinate ring starts at 12 o'clock via a −90° rotation.
|
|
88
88
|
- The indeterminate linear bar is a 30%-wide segment that sweeps left to right on a 1.5s loop; the spinner rotates on a 2s loop with a 1.5s dash animation.
|
|
@@ -63,7 +63,7 @@ plan.addEventListener("rel-change", (e) => {
|
|
|
63
63
|
| `options` | `options` | `RadioOption[]` | `[]` | The options to render, in order. Each entry is a `RadioOption` (`value`, `label`, optional `supportingText`, `disabled`, `icon` or `avatar`). Set as a property (`.options=`) or as a JSON attribute. |
|
|
64
64
|
| `name` | `name` | `string` | `"radio-group"` | `name` given to every native radio input inside this element. It scopes native radio-group behaviour (arrow-key movement, mutual exclusion) to this group, so give each group on a page a distinct name. |
|
|
65
65
|
| `orientation` | `orientation` | `"horizontal" \| "vertical"` | `"vertical"` | Layout axis of the option list. `"vertical"` (default) stacks options in a column; `"horizontal"` lays them out in a wrapping row. Reflected. |
|
|
66
|
-
| `size` | `size` | `"small" \| "medium" \| "large"` | `"medium"` | Control scale
|
|
66
|
+
| `size` | `size` | `"small" \| "medium" \| "large" \| "sm" \| "md" \| "lg"` | `"medium"` | Control scale. `"medium"` (default, Figma M) = 20px control with body-lg labels; `"large"` (Figma L) = 24px control with body-xl labels; `"small"` = 16px control with body-md labels. `sm` / `md` / `lg` are alternative spellings and stay supported — normalised to the full words, not deprecated. DELIBERATE FIGMA DIVERGENCE on Small. Figma's `.Radio Control` has one size (20x20) and its row variants pin Small AND Medium to 20, so the two rendered identically and the Size axis did nothing between them. 16px is not invented: it is rel-checkbox's Small, and checkbox is radio's sibling selection control. See the size ramp in the styles below. Reflected. |
|
|
67
67
|
| `density` | `density` | `"compact" \| "comfortable"` | `"compact"` | Supporting-text layout (Figma Density). `"compact"` (default) puts the supporting text on its own line under the row, indented past the control; `"comfortable"` stacks label + supporting text beside the control. Reflected. |
|
|
68
68
|
| `alignment` | `alignment` | `"leading" \| "trailing"` | `"leading"` | Control position (Figma Layout). `"leading"` (default) renders the control before the label; `"trailing"` pushes it to the far edge of the row. Trailing has no compact layout in the spec, so it always renders with comfortable density. Meant for vertical orientation — trailing options stretch to the group's full width. Reflected. |
|
|
69
69
|
| `selectedValue` | `selectedvalue` | `string \| null` | `null` | `value` of the currently selected option, or `null` when nothing is selected. Set it to preselect an option; it is updated on every user selection. Reflected. |
|
|
@@ -81,6 +81,7 @@ The left pane lists Today (`T`), Tomorrow (`M`), Yesterday (`Y`), This Week (`W`
|
|
|
81
81
|
| `triggerVariant` | `trigger-variant` | `"default" \| "icon"` | `"default"` | `default` renders the text field; `icon` renders a single calendar icon button instead (no typed entry, no clear button, parts `trigger`/`value` absent). |
|
|
82
82
|
| `clearable` | `clearable` | `boolean` | `false` | Shows a clear (×) icon while a range is set; clearing fires `rel-change` with empty `from`/`to`. Only with the default trigger. |
|
|
83
83
|
| `fullWidth` | `fullwidth` | `boolean` | `false` | Stretches the host to fill its parent's width (attribute `fullwidth`), mirroring rel-time-picker / rel-date-picker. Off by default so the existing intrinsic-width (`inline-block`) rendering is unchanged. Reflected. |
|
|
84
|
+
| `size` | `size` | `"small" \| "medium" \| "large" \| "sm" \| "md" \| "lg"` | `"medium"` | Trigger height on the shared field scale — `small` 32 / `medium` 40 / `large` 48px border-box — matching rel-textfield, rel-date-picker and rel-time-picker so the four align in a form row. Also ramps the trigger's text and inline padding. The panel is unaffected: Figma specifies one panel size. `sm` / `md` / `lg` are alternative spellings and stay supported — normalised to the full words, not deprecated. Reflected. |
|
|
84
85
|
|
|
85
86
|
### Public fields / accessors
|
|
86
87
|
|
|
@@ -112,7 +113,7 @@ The left pane lists Today (`T`), Tomorrow (`M`), Yesterday (`Y`), This Week (`W`
|
|
|
112
113
|
| `panel` | The floating panel (`role="dialog"`) holding presets and calendar |
|
|
113
114
|
| `list` | The preset column and the day grid |
|
|
114
115
|
| `option` | Each quick-select preset button |
|
|
115
|
-
| `action` | The previous
|
|
116
|
+
| `action` | The header's previous and next buttons; they step a month, a year or a 12-year page depending on which view the panel is showing |
|
|
116
117
|
| `footer` | The Reset / Cancel / Apply button row |
|
|
117
118
|
|
|
118
119
|
<!-- readme-gen:end -->
|
|
@@ -148,6 +149,8 @@ The left pane lists Today (`T`), Tomorrow (`M`), Yesterday (`Y`), This Week (`W`
|
|
|
148
149
|
|
|
149
150
|
## Notes / Edge Cases
|
|
150
151
|
|
|
152
|
+
- **The header month and year are buttons.** Clicking the month opens a 12-month grid; clicking the year opens a 12-year page that pages back indefinitely with the chevrons, so a date years in the past is a few clicks rather than a few dozen. Picking a year drills to Months, picking a month returns to the day grid. The chevrons step whatever the current view shows — a month, a year or a whole page — and the panel always reopens on the day grid.
|
|
153
|
+
- **Navigating does not select.** The switcher moves the VIEW only: it writes to the month and year on display and never to the draft or the committed range, so Reset, Cancel and Apply behave exactly as they did, and reopening still seeds the view from the committed start date.
|
|
151
154
|
- Draft vs committed: grid picks and presets only change the draft shown in the From / To readouts. Apply commits it (fires `rel-change`, closes); Cancel, Escape, an outside click, or the popup backdrop discard it; Reset empties the draft. Reset followed by Apply clears the committed range (`rel-change` with empty strings) — Apply is disabled only when both the draft and the committed range are empty.
|
|
152
155
|
- Second-click ordering: picking a day before the current draft start makes it the new start and the old start the end.
|
|
153
156
|
- Setting `open = true` from code shows the panel but neither seeds the draft from `from`/`to` nor fires `rel-open-change`; only user interaction does both.
|
|
@@ -96,7 +96,7 @@ const options: SegmentOption[] = [
|
|
|
96
96
|
|
|
97
97
|
| Property | Attribute | Type | Default | Description |
|
|
98
98
|
| --- | --- | --- | --- | --- |
|
|
99
|
-
| `options` | `options` | `SegmentOption[]` | `[]` | The segments in order, each `{ label: string; value: string; disabled?: boolean; icon?: string }`. Set as a property (or a JSON array attribute); a disabled entry is rendered but cannot be selected, and `icon` names a `rel-icon` drawn before the label. |
|
|
99
|
+
| `options` | `options` | `SegmentOption[]` | `[]` | The segments in order, each `{ label: string; value: string; disabled?: boolean; icon?: string; badge?: number \| string \| boolean }`. Set as a property (or a JSON array attribute); a disabled entry is rendered but cannot be selected, and `icon` names a `rel-icon` drawn before the label. |
|
|
100
100
|
| `active` | `active` | `string` | `""` | `value` of the currently selected segment. Updated by the component on click / arrow keys; set it to pre-select a segment (an unknown value selects nothing). |
|
|
101
101
|
| `size` | `size` | `"small" \| "medium" \| "large"` | `"medium"` | Control height, matching the TextField ramp: `small` (32px — 28px segments, `action-md` 12px text, 16px icons), `medium` (default, 40px — 36px segments, `action-lg` 14px text, 18px icons) or `large` (48px — 44px segments, `action-xl` 16px text, 20px icons). |
|
|
102
102
|
| `align` | `align` | `"left" \| "middle" \| "right"` | `"left"` | `justify-content` of the group's inline-flex container: `left` (default), `middle` or `right`. Only visible when the host is made wider than its content. |
|
|
@@ -121,6 +121,7 @@ const options: SegmentOption[] = [
|
|
|
121
121
|
| `option` | Each segment's native `<button role="radio">`; the active one carries the `active` class and `aria-checked="true"`. |
|
|
122
122
|
| `icon` | A segment's optional leading `rel-icon` element. |
|
|
123
123
|
| `label` | The wrapper around a segment's label text. |
|
|
124
|
+
| `badge` | A segment's optional trailing `rel-badge`; rendered only when the option sets `badge`. |
|
|
124
125
|
| `base` | The `role="radiogroup"` track that lays out the segments. |
|
|
125
126
|
|
|
126
127
|
<!-- readme-gen:end -->
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
| `labelStyle` | `label-style` | `"default" \| "floating" \| "none"` | `"default"` | Label presentation: `default` static label above the trigger; `floating` label rests in the value area and floats onto the border when focused, open or filled; `none` renders no label (supply `fieldAriaLabel` / `fieldAriaLabelledby`). Reflected. |
|
|
71
71
|
| `fieldAriaLabel` | `field-aria-label` | `string` | `undefined` | Accessible name for the trigger. Required when `labelStyle="none"`, since no `<label>` renders and a placeholder is not a valid naming mechanism. |
|
|
72
72
|
| `fieldAriaLabelledby` | `field-aria-labelledby` | `string` | `undefined` | IDREF list of external element(s) naming the trigger. Wins over `fieldAriaLabel`. |
|
|
73
|
-
| `options` | `options` | `(string \| SelectOptionObject)[]` | `[]` | Options to list. Each entry is a plain string (used as both value and label) or `{ value, label?, supportingText?, icon? }`; `icon` is a `rel-icon` name rendered before the label, `supportingText`
|
|
73
|
+
| `options` | `options` | `(string \| SelectOptionObject)[]` | `[]` | Options to list. Each entry is a plain string (used as both value and label) or `{ value, label?, supportingText?, icon? }`; `icon` is a `rel-icon` name rendered before the label, `supportingText` renders as a second line in both single- and multi-select rows. NOTE — the panel's search matches the LABEL ONLY. `supportingText` is displayed but not searched, so an option is not findable by its second line here. This differs deliberately from `rel-autocomplete`, whose filter matches the supporting line as well: there the second line carries identifying data (a DOT or MC number) that a user types to find the row, whereas a select's is descriptive ("Read-only", "Can edit, not delete") and matching it would return rows whose visible label has nothing to do with the query. |
|
|
74
74
|
| `multiple` | `multiple` | `boolean` | `false` | Enables multi-select: selected values render as removable chips, options as checkboxes, and a Select-all row appears in the panel. |
|
|
75
75
|
| `selected` | `selected` | `string` | `""` | Selected option value in single-select mode. Ignored when `multiple` is set. |
|
|
76
76
|
| `selectedValues` | `selected-values` | `string[]` | `[]` | Selected option values in multi-select mode. Reset to `[]` when `multiple` is turned off. |
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
| `searchPlaceholder` | `search-placeholder` | `string` | `"Search option"` | Placeholder of the in-panel search field (the field is hidden when `noSearch` is set). |
|
|
86
86
|
| `selectAllLabel` | `select-all-label` | `string` | `"Select all"` | Label of the Select-all row shown at the top of the panel in multi-select mode. |
|
|
87
87
|
| `maxVisibleChips` | `max-visible-chips` | `number` | `Infinity` | Optional hard cap on visible chips. By default (no cap) the visible count adapts to the trigger's width: chips collapse into the "+N" badge one by one instead of wrapping to a second line. |
|
|
88
|
-
| `noSearch` | `no-search` | `boolean` | `false` |
|
|
88
|
+
| `noSearch` | `no-search` | `boolean` | `false` | DELIBERATE DIVERGENCE — do not default this to `!multiple`. Figma's `.Menu Dropdown` shows the search row only on `Type=Multioption`; its `Type=Single Option` panels contain five Select Option items and nothing else. Here the search row renders for single-select too unless this is set. Ruled by the user: our behaviour stands and the DESIGN FILE follows our docs. A long single-select list is unusable without search, and making the default depend on `multiple` would change the panel of every existing single-select. |
|
|
89
89
|
|
|
90
90
|
## Events
|
|
91
91
|
|
|
@@ -111,6 +111,8 @@
|
|
|
111
111
|
| `list` | Alias of `panel` |
|
|
112
112
|
| `input` | The search input inside the panel |
|
|
113
113
|
| `option` | A single-select option row |
|
|
114
|
+
| `option-label` | A single-select row's first line (the option label) |
|
|
115
|
+
| `option-supporting-text` | A single-select row's optional second line; rendered only when the option supplies `supportingText` |
|
|
114
116
|
|
|
115
117
|
## Tokens / CSS Variables
|
|
116
118
|
|
|
@@ -120,7 +122,7 @@ Set these on the host (or an ancestor) to customise the element without touching
|
|
|
120
122
|
|
|
121
123
|
| Custom property | Default | Description |
|
|
122
124
|
| --- | --- | --- |
|
|
123
|
-
| `--rel-field-label-reserve` | `calc(var(--rel-body-md-regular-line-height) + var(--rel-spacing-2xs))` | Height held for the
|
|
125
|
+
| `--rel-field-label-reserve` | `calc(var(--rel-body-md-regular-line-height) + var(--rel-spacing-2xs))` | Height held for the label row whenever no label renders above the trigger — `labelStyle="none"`, and `labelStyle="floating"` where the label sits inside the trigger — so the trigger still lines up with labelled siblings in a form row. Defaults to that size's label line-height plus the wrapper gap (24px at `small`, 26px at `medium` and `large`). Set to `0` to collapse the row entirely (toolbars, table cells). |
|
|
124
126
|
| `--rel-select-bg` | `var(--rel-bg-neutral)` | Background of the trigger, the floating label, the panel and its sticky header |
|
|
125
127
|
| `--rel-select-bg-disabled` | `var(--rel-bg-neutral-elevated-2)` | Trigger background when `state="disabled"` |
|
|
126
128
|
| `--rel-select-border-default` | `var(--rel-border-default)` | Trigger border colour at rest |
|
|
@@ -24,12 +24,12 @@
|
|
|
24
24
|
</script>
|
|
25
25
|
|
|
26
26
|
<!-- Centred dialog, small width -->
|
|
27
|
-
<rel-modal side="center" size="
|
|
27
|
+
<rel-modal side="center" size="small" title="Session expired" description="Sign in again to continue.">
|
|
28
28
|
<rel-button slot="footer" variant="primary">Sign in</rel-button>
|
|
29
29
|
</rel-modal>
|
|
30
30
|
|
|
31
31
|
<!-- Top-anchored sheet with extra header content -->
|
|
32
|
-
<rel-modal side="top" size="
|
|
32
|
+
<rel-modal side="top" size="large" title="New release">
|
|
33
33
|
<rel-tab slot="header" size="small">
|
|
34
34
|
<rel-tab-item slot="items" label="Summary"></rel-tab-item>
|
|
35
35
|
<rel-tab-item slot="items" label="Details"></rel-tab-item>
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
| `subtitle` | `subtitle` | `string` | `""` | Alias for `description`; rendered only when `description` is empty. |
|
|
87
87
|
| `dismissible` | `dismissible` | `boolean` | `true` | Coarse dismissal switch. When false the close button is hidden and backdrop clicks / Escape are ignored regardless of the granular `close-on-*` / `show-close-button` props. |
|
|
88
88
|
| `modal` | `modal` | `boolean` | `true` | Modal mode: renders the scrim, sets `role="dialog"` + `aria-modal`, traps Tab inside the panel and moves focus in on open. When false the panel is a `region` with no scrim and no focus trap. |
|
|
89
|
-
| `size` | `size` | `"
|
|
89
|
+
| `size` | `size` | `"small" \| "medium" \| "large" \| "extra-large" \| "fullscreen" \| "sm" \| "md" \| "lg" \| "xl"` | `"medium"` | Panel width scale. `medium` (default) matches the Figma Modal Sheet width; `fullscreen` covers the viewport. `sm` / `md` / `lg` / `xl` are alternative spellings of `small` / `medium` / `large` / `extra-large` and stay supported — they are normalised to the full words, not deprecated. Reflected. |
|
|
90
90
|
| `variant` | `variant` | `"default" \| "text"` | `"default"` | Body treatment — see `ModalVariant`. `"text"` styles the default slot as the Figma "Text" message slot; the header (and its divider) render as usual above it. Default rendering is unchanged. Reflected. |
|
|
91
91
|
| `closeOnBackdropClick` | `close-on-backdrop-click` | `boolean` | `true` | Close when the scrim is clicked. Only effective while `dismissible` is true; ignored while `disabled` or `loading`. |
|
|
92
92
|
| `closeOnEscape` | `close-on-escape` | `boolean` | `true` | Close on the Escape key. Only effective while `dismissible` is true; ignored while `disabled`. |
|
|
@@ -51,11 +51,11 @@ Loading placeholder that reserves the space of content still being fetched: a ne
|
|
|
51
51
|
|
|
52
52
|
| Property | Attribute | Type | Default | Description |
|
|
53
53
|
| --- | --- | --- | --- | --- |
|
|
54
|
-
| `shape` | `shape` | `"line" \| "circle" \| "block"` | `"block"` | Placeholder shape: `block` fills the host (min 16px tall), `circle` is a square-aspect disc sized by the host width, `line` renders `lines`
|
|
55
|
-
| `lines` | `lines` | `number` | `1` | Number of text bars when `shape="line"` (minimum 1,
|
|
54
|
+
| `shape` | `shape` | `"line" \| "circle" \| "block"` | `"block"` | Placeholder shape: `block` fills the host (min 16px tall), `circle` is a square-aspect disc sized by the host width, `line` renders `lines` 16px text bars with the last one at 65% width. Reflected. |
|
|
55
|
+
| `lines` | `lines` | `number` | `1` | Number of text bars when `shape="line"` (minimum 1, --rel-spacing-xs apart); ignored by the other shapes. |
|
|
56
56
|
| `width` | `width` | `string` | `""` | Any CSS width (e.g. `"240px"`, `"50%"`) applied to the host's inline style. Empty leaves the host at its natural block width. |
|
|
57
57
|
| `height` | `height` | `string` | `""` | Any CSS height (e.g. `"120px"`) applied to the host's inline style. Not needed for `circle`, which derives its height from the width. |
|
|
58
|
-
| `animation` | `animation` | `"pulse" \| "shimmer" \| "none"` | `"pulse"` | Motion: `pulse` fades opacity between
|
|
58
|
+
| `animation` | `animation` | `"pulse" \| "shimmer" \| "none"` | `"pulse"` | Motion: `pulse` fades opacity between 20% and 40% (Figma's Start/End states), `shimmer` sweeps a highlight band left to right, `none` is static. Both animations are disabled under `prefers-reduced-motion: reduce`. Reflected. |
|
|
59
59
|
| `loaded` | `loaded` | `boolean` | `false` | Set once the real content is ready: hides the skeleton (`display: none`) and removes its `role="status"` / "Loading" label. Reflected. |
|
|
60
60
|
|
|
61
61
|
## Events
|
|
@@ -86,6 +86,7 @@ Set these on the host (or an ancestor) to customise the element without touching
|
|
|
86
86
|
| --- | --- | --- |
|
|
87
87
|
| `--rel-skeleton-color` | `var(--rel-bg-neutral-elevated-3)` | Fill colour of the placeholder (defaults to the elevated-3 neutral background token). |
|
|
88
88
|
| `--rel-skeleton-highlight` | `var(--rel-bg-neutral-elevated-2)` | Lighter band that sweeps across the placeholder when `animation="shimmer"` (defaults to the elevated-2 neutral background token). |
|
|
89
|
+
| `--rel-skeleton-line-height` | `16px` | Height of each text bar when `shape="line"`; default 16px (Figma's Line shape). |
|
|
89
90
|
|
|
90
91
|
<!-- readme-gen:end -->
|
|
91
92
|
|
|
@@ -97,7 +98,7 @@ Set these on the host (or an ancestor) to customise the element without touching
|
|
|
97
98
|
|
|
98
99
|
## Notes / Edge Cases
|
|
99
100
|
|
|
100
|
-
- **Sizing.** `width` / `height` are written to the host's inline `style` and accept any CSS length. A `block` with no `height` is 16px tall (its `min-height`); a `circle` needs only a width (`aspect-ratio: 1 / 1`); `line` bars are
|
|
101
|
+
- **Sizing.** `width` / `height` are written to the host's inline `style` and accept any CSS length. A `block` with no `height` is 16px tall (its `min-height`); a `circle` needs only a width (`aspect-ratio: 1 / 1`); `line` bars are 16px tall, `--rel-spacing-xs` apart, full width, with the last bar at 65% when there is more than one.
|
|
101
102
|
- **`loaded` hides, it does not remove.** The host switches to `display: none` and stays in the DOM; place the real content as a sibling rather than inside the skeleton (the element has no slot).
|
|
102
103
|
- **Multiple `base` parts.** With `shape="line"` every bar carries `part="base"`, so `::part(base)` styles all of them.
|
|
103
104
|
- **Shimmer overrides the fill.** In `shimmer` mode the background becomes a gradient built from `--rel-skeleton-color` and `--rel-skeleton-highlight`; set both when customising colours.
|
|
@@ -49,13 +49,14 @@
|
|
|
49
49
|
| Property | Attribute | Type | Default | Description |
|
|
50
50
|
| --- | --- | --- | --- | --- |
|
|
51
51
|
| `type` | `type` | `"continuous" \| "discrete" \| "default" \| "range"` | `"continuous"` | Slider mode: `continuous` (or its alias `default`) accepts any integer value, `discrete` snaps to `step` and draws tick marks, `range` shows two thumbs bounding `value`…`valueEnd`. Reflected. |
|
|
52
|
-
| `
|
|
52
|
+
| `showTicks` | `show-ticks` | `boolean` | `undefined` | Draws the tick marks (Figma's separate `Is Determinated` boolean). Works with ANY `type` — Figma shows ticks on every variant, where the code used to gate them behind the code-only `type="discrete"`, so a `default` or `range` slider could never show them. Left unset it follows `type="discrete"`, so nothing changes for existing sliders; set it explicitly to override in either direction. Reflected. |
|
|
53
|
+
| `size` | `size` | `"small" \| "medium" \| "large" \| "sm" \| "md" \| "lg"` | `"medium"` | Figma Size axis: `small` (6px track / 16px thumb), `medium` (8 / 20, default) or `large` (10 / 24), which also scales the ticks and the value bubble. `sm` / `md` / `lg` are alternative spellings and stay supported — they are normalised to the full words, not deprecated. Reflected. |
|
|
53
54
|
| `min` | `min` | `number` | `0` | Lowest selectable value. |
|
|
54
55
|
| `max` | `max` | `number` | `100` | Highest selectable value. |
|
|
55
56
|
| `step` | `step` | `number` | `1` | Increment between values. In `discrete` mode it also spaces the tick marks; in `continuous` mode the native input always moves in steps of 1. |
|
|
56
57
|
| `disabled` | `disabled` | `boolean` | `false` | Disables interaction and dims the track, thumb and ticks; the tooltip is hidden. |
|
|
57
58
|
| `track` | `track` | `"solid" \| "dotted"` | `"solid"` | Style of the filled part of the track: `solid` or a `dotted` pattern. |
|
|
58
|
-
| `showTickLabels` | `showticklabels` | `boolean` | `false` | Print the numeric value under every tick mark. Only has an effect in `discrete` mode. |
|
|
59
|
+
| `showTickLabels` | `showticklabels` | `boolean` | `false` | Print the numeric value under every tick mark. Only has an effect in `discrete` mode. Reflected. |
|
|
59
60
|
| `showBubble` | `showbubble` | `boolean` | `true` | Show the value tooltip above the thumb(s). |
|
|
60
61
|
| `value` | `value` | `number` | `0` | Current value (the lower value in `range` mode). |
|
|
61
62
|
| `valueEnd` | `value-end` | `number` | `100` | Upper value when type="range" (attribute value-end). |
|
|
@@ -19,16 +19,20 @@
|
|
|
19
19
|
<!-- Action button -->
|
|
20
20
|
<rel-snackbar id="deleted" message="Item deleted" action="Undo"></rel-snackbar>
|
|
21
21
|
|
|
22
|
-
<!-- Double-line layout with a longer (2 × duration) dismiss delay
|
|
23
|
-
(attributes are lower-case: longeraction) -->
|
|
22
|
+
<!-- Double-line layout with a longer (2 × duration) dismiss delay -->
|
|
24
23
|
<rel-snackbar
|
|
25
24
|
id="archived"
|
|
26
25
|
message="12 conversations were archived and will be deleted in 30 days"
|
|
27
26
|
action="Undo"
|
|
28
|
-
|
|
29
|
-
longeraction
|
|
27
|
+
variant="longer-action"
|
|
30
28
|
></rel-snackbar>
|
|
31
29
|
|
|
30
|
+
<!-- Deprecated aliases — both still work and both log a one-time console notice.
|
|
31
|
+
`lines="double"` sets the stacked layout but NOT the doubled delay; `longeraction`
|
|
32
|
+
doubles the delay but does not stack. `variant="longer-action"` above does both.
|
|
33
|
+
Note the attribute is lower-case `longeraction`, not `longer-action`. -->
|
|
34
|
+
<rel-snackbar message="Older markup" action="Undo" lines="double" longeraction></rel-snackbar>
|
|
35
|
+
|
|
32
36
|
<!-- Persistent, without the close icon (the boolean must be cleared from script — see the js block) -->
|
|
33
37
|
<rel-snackbar id="busy" message="Processing…" duration="0"></rel-snackbar>
|
|
34
38
|
```
|
|
@@ -93,10 +97,9 @@ rel-snackbar {
|
|
|
93
97
|
| --- | --- | --- | --- | --- |
|
|
94
98
|
| `message` | `message` | `string` | `"This is a snackbar message"` | Message text. Announced to screen readers through the shared live-region announcer when the snackbar is shown and whenever it changes while shown. The default is a placeholder — always set it. |
|
|
95
99
|
| `action` | `action` | `string` | `undefined` | Label of the optional action button (Figma trailing button, Static / Small); omitted when unset. Clicking it fires `actionClick` and then dismisses the snackbar. |
|
|
96
|
-
| `
|
|
100
|
+
| `variant` | `variant` | `"default" \| "longer-action"` | `undefined` | Layout and timing (Figma "Type"): `"default"` (message and actions on one row) \| `"longer-action"` (message stacked above the actions, which align to the end, with the auto-dismiss delay doubled so there is time to use the action). Takes precedence over the deprecated `lines` and `longerAction` props. |
|
|
97
101
|
| `iconClose` | `iconclose` | `boolean` | `true` | Shows the trailing close icon button. Defaults to true; because it is a Lit boolean, `iconclose="false"` is still true — set the property to `false` from script to hide the button. |
|
|
98
|
-
| `
|
|
99
|
-
| `duration` | `duration` | `number` | `4000` | Auto-dismiss delay in milliseconds (doubled by `longerAction`), started when `show` becomes true and restarted when `duration` or `longerAction` changes while shown. `0` (or a negative value) disables auto-dismiss. |
|
|
102
|
+
| `duration` | `duration` | `number` | `4000` | Auto-dismiss delay in milliseconds (doubled by `variant="longer-action"`), started when `show` becomes true and restarted when `duration` or the layout changes while shown. `0` (or a negative value) disables auto-dismiss. |
|
|
100
103
|
| `tone` | `tone` | `"neutral" \| "success" \| "warning" \| "destructive" \| "default" \| "error" \| "danger" \| "critical"` | `undefined` | Semantic tone (Figma "Tone"): `"neutral"` (default: no accent, no icon) \| `"success"` \| `"warning"` \| `"destructive"` — the status tones add a 4px left accent and a leading icon (check-circle / warning / error) in the tone colour. `"default"` is a deprecated alias of `"neutral"`; `"error"`, `"danger"` and `"critical"` are deprecated aliases of `"destructive"`; each logs a one-time console notice. Takes precedence over the deprecated `type` prop. |
|
|
101
104
|
| `show` | `show` | `boolean` | `false` | Whether the snackbar is visible. Set it to true to show the snackbar and start the auto-dismiss timer; it is set back to false by the close icon, the action button and the timer. There is no open/close method — toggle this property. Reflected. |
|
|
102
105
|
|
|
@@ -104,12 +107,15 @@ rel-snackbar {
|
|
|
104
107
|
|
|
105
108
|
| Property | Attribute | Type | Use instead |
|
|
106
109
|
| --- | --- | --- | --- |
|
|
110
|
+
| `longerAction` | `longeraction` | `boolean` | — use `variant="longer-action"`, which also sets the stacked layout. Doubles the auto-dismiss delay (`duration * 2`) on its own. Ignored when `variant` is set. Logs a one-time console notice. |
|
|
111
|
+
| `lines` | `lines` | `"single" \| "double"` | — use `variant`; `lines="double"` maps to `variant="longer-action"`. Sets the stacked layout on its own but not the doubled delay. Ignored when `variant` is set. Logs a one-time console notice. |
|
|
107
112
|
| `type` | `type` | `"neutral" \| "success" \| "warning" \| "destructive" \| "default" \| "error" \| "danger" \| "critical"` | Deprecated since 1.4.7 — alias of `tone`; use `tone`. Same values as `tone`; `type="error"` maps to `tone="destructive"` and `type="default"` to `tone="neutral"`. Ignored when `tone` is set. Logs a one-time console notice. |
|
|
108
113
|
|
|
109
114
|
### Public fields / accessors
|
|
110
115
|
|
|
111
116
|
| Name | Type | Description |
|
|
112
117
|
| --- | --- | --- |
|
|
118
|
+
| `resolvedVariant` | `SnackbarVariant` | Read-only canonical layout actually rendered: explicit `variant` wins, else either deprecated prop (`lines="double"` or `longerAction`) promotes to `"longer-action"`, else `"default"`. |
|
|
113
119
|
| `resolvedTone` | `SnackbarTone` | Read-only canonical tone actually rendered: explicit `tone` wins, else `type`, else `"neutral"`; deprecated aliases are resolved to `"neutral"` / `"destructive"`. |
|
|
114
120
|
|
|
115
121
|
## Events
|
|
@@ -16,8 +16,13 @@ A multi-step progress indicator implementing the Figma "Stepper" component: its
|
|
|
16
16
|
];
|
|
17
17
|
</script>
|
|
18
18
|
|
|
19
|
-
<!-- Vertical,
|
|
20
|
-
|
|
19
|
+
<!-- Vertical, label beside the indicator (Figma Type = Centered).
|
|
20
|
+
`size` is DEPRECATED and deliberately omitted: Figma has no Size axis on the
|
|
21
|
+
Stepper — the connector geometry is fixed — so it was a code-only scale. It is
|
|
22
|
+
still accepted so existing markup keeps working, but it now resolves to the one
|
|
23
|
+
Figma geometry and logs a one-time notice. Retune with
|
|
24
|
+
`--rel-stepper-connector-length` instead. -->
|
|
25
|
+
<rel-stepper id="onboarding" orientation="vertical" label-placement="centered"></rel-stepper>
|
|
21
26
|
<script>
|
|
22
27
|
document.getElementById('onboarding').steps = [
|
|
23
28
|
{ title: 'Create account', status: 'done' },
|
|
@@ -86,9 +91,8 @@ const steps: Step[] = [
|
|
|
86
91
|
|
|
87
92
|
| Property | Attribute | Type | Default | Description |
|
|
88
93
|
| --- | --- | --- | --- | --- |
|
|
89
|
-
| `steps` | `steps` | `Step[]` | `[]` | The steps in order, each `{ title: string; status: "done" \| "progress" \| "disabled" }`. Set as a property (or a JSON array attribute); the component never mutates it — update it from the `rel-step-change` handler. |
|
|
94
|
+
| `steps` | `steps` | `Step[]` | `[]` | The steps in order, each `{ title: string; subtitle?: string; status: "done" \| "progress" \| "disabled" }`. Set as a property (or a JSON array attribute); the component never mutates it — update it from the `rel-step-change` handler. |
|
|
90
95
|
| `orientation` | `orientation` | `"horizontal" \| "vertical"` | `"horizontal"` | Layout axis: `horizontal` (default) lays the steps out in a centred row; `vertical` stacks them. |
|
|
91
|
-
| `size` | `size` | `"small" \| "large"` | `"large"` | `large` (default) or `small`: controls the label type (body-md vs body-sm) and the connector length / step gap (see the `--rel-stepper-connector-length-*` hooks). |
|
|
92
96
|
| `type` | `type` | `"default" \| "dot" \| "number" \| "icon"` | `"default"` | Figma "Type" axis — what the indicator shows: `default` (step number, check mark once done), `dot` (8px dot, no glyph), `number` (always the number) or `icon` (always the check mark). Reflected. |
|
|
93
97
|
| `labelPlacement` | `label-placement` | `"top" \| "centered" \| "inverted"` | `undefined` | Figma "Typel" axis — where the label sits: `top` (top-aligned beside the indicator), `centered` (vertically centred beside it) or `inverted` (indicator above the label). When unset, the deprecated `textAlign` prop drives the layout (`below` ≈ `inverted`, `right` ≈ `centered`). Figma marks Top + Horizontal as an unsupported combination. Reflected. |
|
|
94
98
|
|
|
@@ -97,6 +101,7 @@ const steps: Step[] = [
|
|
|
97
101
|
| Property | Attribute | Type | Use instead |
|
|
98
102
|
| --- | --- | --- | --- |
|
|
99
103
|
| `textAlign` | `textalign` | `"right" \| "below"` | Deprecated alias of `label-placement`; use `label-placement="inverted"` instead of `textalign="below"` and `label-placement="centered"` instead of `textalign="right"`. |
|
|
104
|
+
| `size` | `size` | `"small" \| "large"` | Figma has no Size axis on the Stepper — the connector geometry is fixed — so this was a code-only scale. It stays accepted so existing markup keeps working, and now resolves to the one Figma geometry. Retune it with `--rel-stepper-connector-length` instead. Logs a one-time notice. |
|
|
100
105
|
|
|
101
106
|
## Events
|
|
102
107
|
|
|
@@ -117,6 +122,7 @@ const steps: Step[] = [
|
|
|
117
122
|
| `indicator` | The 24px circle (8px for `type="dot"`) that holds the step number, check mark or icon. |
|
|
118
123
|
| `track` | The 1px connector line from a step to the next one (not rendered on the last step). |
|
|
119
124
|
| `label` | The step title text. |
|
|
125
|
+
| `subtitle` | The optional second line under the title; rendered only when a step sets `subtitle`. |
|
|
120
126
|
|
|
121
127
|
## Tokens / CSS Variables
|
|
122
128
|
|
|
@@ -126,9 +132,7 @@ Set these on the host (or an ancestor) to customise the element without touching
|
|
|
126
132
|
|
|
127
133
|
| Custom property | Default | Description |
|
|
128
134
|
| --- | --- | --- |
|
|
129
|
-
| `--rel-stepper-connector-length
|
|
130
|
-
| `--rel-stepper-connector-length-md` | `60px` | Connector length and step gap for `size="small"` in `orientation="horizontal"` (default 60px). |
|
|
131
|
-
| `--rel-stepper-connector-length-sm` | `42px` | Connector length and step gap for `size="small"` in `orientation="vertical"` (default 42px). |
|
|
135
|
+
| `--rel-stepper-connector-length` | `var(--rel-stepper-connector-length-lg, 96px)` | Length of the connector line; the step gap is derived from it by adding Figma's clear space at both ends. Defaults to Figma's fixed geometry: 96px horizontally, 34px vertically with `label-placement="centered"`, 51px with `inverted`. |
|
|
132
136
|
| `--rel-stepper-indicator-size` | `24px` | Indicator diameter (default 24px; `type="dot"` is fixed at 8px). |
|
|
133
137
|
|
|
134
138
|
<!-- readme-gen:end -->
|
|
@@ -44,9 +44,13 @@
|
|
|
44
44
|
| Property | Attribute | Type | Default | Description |
|
|
45
45
|
| --- | --- | --- | --- | --- |
|
|
46
46
|
| `checked` | `checked` | `boolean` | `false` | Whether the switch is on. Set it to control the state programmatically; user toggles update it and fire `rel-change`. |
|
|
47
|
-
| `
|
|
47
|
+
| `type` | `type` | `"line" \| "pill"` | `"line"` | Shape (Figma "Type"): `"line"` (default) is the 44x20 control with a thin 40x10 rail and the handle riding on it; `"pill"` is the 44x24 filled track with the handle inside it. NOTE: Figma's own default is Pill. We default to `line` deliberately — flipping it would restyle every existing switch — so this is a recorded divergence from the design default, not an oversight. Reflected. |
|
|
48
|
+
| `disabled` | `disabled` | `boolean` | `false` | Disables interaction and swaps in the dulled rail / handle fills; the handle shadow is removed. |
|
|
48
49
|
| `value` | `value` | `string` | `""` | Arbitrary string echoed in the `rel-change` event detail — useful when one handler serves several switches. |
|
|
49
50
|
| `fieldAriaLabel` | `field-aria-label` | `string` | `undefined` | Accessible name for the native input. Without it the switch has no label of its own, so pair it with a visible `<label>` or set this. |
|
|
51
|
+
| `label` | `label` | `string` | `undefined` | Visible text beside the control. Clicking it toggles the switch, and it becomes the accessible name — use `fieldAriaLabel` instead when the switch has no visible text. For rich content (a bold word, an icon) slot it in the default slot rather than setting this. |
|
|
52
|
+
| `labelPlacement` | `label-placement` | `"end" \| "start"` | `"end"` | Which side the label sits on: `end` (default) puts it after the control, `start` before it. Note this is a PHYSICAL side, not a writing-direction one, matching every other placement prop in the library. Reflected. |
|
|
53
|
+
| `size` | `size` | `"small" \| "medium" \| "large" \| "sm" \| "md" \| "lg"` | `"medium"` | Control scale: `small`, `medium` (default) or `large`. `sm` / `md` / `lg` are alternative spellings and stay supported — normalised to the full words, not deprecated. Figma's Switch has axes Type / State / Enabled only, with no Size, so this ramp is ours. `medium` is exactly the control that shipped before it existed, so an existing switch is unchanged. It does NOT respond to viewport width. Picking a size per breakpoint is the consuming application's decision — a control that silently resized itself at some width would be undocumentable behaviour, and the breakpoint that matters belongs to the layout around it, not to the switch. Reflected. |
|
|
50
54
|
|
|
51
55
|
## Events
|
|
52
56
|
|
|
@@ -58,14 +62,16 @@
|
|
|
58
62
|
|
|
59
63
|
| Slot | Description |
|
|
60
64
|
| --- | --- |
|
|
61
|
-
|
|
|
65
|
+
| (default) | Rich label content beside the control, as an alternative to the `label` property. Clicking it toggles the switch. |
|
|
62
66
|
|
|
63
67
|
## CSS Parts
|
|
64
68
|
|
|
65
69
|
| Part | Description |
|
|
66
70
|
| --- | --- |
|
|
67
|
-
| `
|
|
71
|
+
| `root` | The `<label>` holding the control and its optional text; carries the `label-placement` order |
|
|
72
|
+
| `base` | The control box around the hidden input and the track |
|
|
68
73
|
| `track` | The thin rail; the handle is its `::before` pseudo-element |
|
|
74
|
+
| `label` | The text beside the control; not rendered when there is neither a `label` nor slotted content |
|
|
69
75
|
|
|
70
76
|
## Tokens / CSS Variables
|
|
71
77
|
|
|
@@ -78,10 +84,11 @@ Set these on the host (or an ancestor) to customise the element without touching
|
|
|
78
84
|
| `--rel-switch-disabled` | `var(--switch-disabled)` | Handle colour while disabled; default `var(--rel-bg-neutral-elevated-1)` |
|
|
79
85
|
| `--rel-switch-knob-off` | `var(--switch-knob-off)` | Handle colour when unchecked; default `var(--rel-text-static-light)` |
|
|
80
86
|
| `--rel-switch-knob-on` | `var(--switch-knob-on)` | Handle colour when checked; default `var(--rel-bg-neutral-inverse-2)` |
|
|
81
|
-
| `--rel-switch-thumb-size` | `
|
|
87
|
+
| `--rel-switch-thumb-size` | `var(--_rel-sw-thumb)` | Handle diameter; defaults to the `size` ramp (16 / 20 / 24px), and the handle always travels its own width minus the 2px inset on each side |
|
|
82
88
|
| `--rel-switch-track` | `var(--switch-track)` | Rail colour; default `var(--rel-bg-neutral-elevated-2)` |
|
|
83
|
-
| `--rel-switch-track-height` | `
|
|
84
|
-
| `--rel-switch-track-width` | `
|
|
89
|
+
| `--rel-switch-track-height` | `var(--_rel-sw-h)` | Overall control height; defaults to the `size` ramp — 16 / 20 / 24px for `type="line"`, 20 / 24 / 28px for `type="pill"` |
|
|
90
|
+
| `--rel-switch-track-width` | `var(--_rel-sw-w)` | Overall control width; defaults to the `size` ramp (36 / 44 / 52px) |
|
|
91
|
+
| `--switch-halo` | `var(--rel-action-overlay-hover-strong)` | — |
|
|
85
92
|
|
|
86
93
|
<!-- readme-gen:end -->
|
|
87
94
|
|
|
@@ -101,7 +108,9 @@ Set these on the host (or an ancestor) to customise the element without touching
|
|
|
101
108
|
## Notes / Edge Cases
|
|
102
109
|
|
|
103
110
|
- `rel-change` fires for user toggles only; setting `checked` from JavaScript updates the visuals but emits nothing.
|
|
104
|
-
- Geometry
|
|
111
|
+
- Geometry follows the `size` ramp, derived from the Figma Line switch at `medium`: 44×20 control, 40×10 track inset 2px, 20px handle travelling 20px. `small` is 36×16 and `large` 52×24, holding the same invariants (handle = control height, width = 2× height + 4, rail = height ÷ 2, travel = width − 4 − handle). `type="pill"` shares the width, handle and travel but is 4px taller at every size — 20 / 24 / 28 — because its height is the handle plus its 2px inset, where Line's height *is* the handle. Changing `--rel-switch-track-width` widens the control without moving the "on" position.
|
|
112
|
+
- **`size` does not respond to viewport width.** Figma has no Size axis on Switch, so the ramp is ours, and choosing a size per breakpoint is the application's decision — set it from your own media queries or container queries. A control that resized itself at some width would be behaviour a design system cannot document, and the breakpoint that matters belongs to the layout around the switch, not to the switch.
|
|
113
|
+
- A `label` (or slotted content) becomes the switch's accessible name and is clickable, because the root element is the `<label>` that owns the input. Use `field-aria-label` instead when there is no visible text; when both are set, `label` wins.
|
|
105
114
|
- Figma's default Type=Pill switch (44×24 filled track with the handle inside) is not implemented.
|
|
106
115
|
- Hover tints the track with the action overlay and raises the handle shadow; pressed shows a 28px overlay disc behind the handle and squashes it to 20×16.
|
|
107
116
|
- Legacy hook aliases still honoured: `--switch-track`, `--switch-knob-on`, `--switch-knob-off` and `--switch-disabled` are read as fallbacks of the `--rel-switch-*` hooks. The old `--switch-halo` name was never read by any rule and is not a hook.
|
|
@@ -95,6 +95,7 @@
|
|
|
95
95
|
| --- | --- |
|
|
96
96
|
| `list` | The `role="tablist"` row |
|
|
97
97
|
| `item` | Each `role="tab"` element |
|
|
98
|
+
| `icon` | — |
|
|
98
99
|
| `label` | The text span inside each tab |
|
|
99
100
|
|
|
100
101
|
### Tokens / CSS Variables
|
|
@@ -108,9 +109,9 @@ Set these on the host (or an ancestor) to customise the element without touching
|
|
|
108
109
|
| `--rel-tab-active-color` | `var(--tab-active-color)` | Underline colour of the active tab; default `var(--rel-bg-brand)` |
|
|
109
110
|
| `--rel-tab-hover-color` | `var(--tab-hover-color)` | Background of an inactive tab on hover; default `var(--rel-bg-neutral-elevated-1)` |
|
|
110
111
|
| `--rel-tab-text-default` | `var(--tab-text-default)` | Label colour of the active tab; default `var(--rel-text-default)` |
|
|
111
|
-
| `--rel-tab-text-disabled` | `
|
|
112
|
+
| `--rel-tab-text-disabled` | `inherit` | Label colour of a disabled tab; default `var(--rel-text-disabled)` |
|
|
112
113
|
| `--rel-tab-text-hover` | `var(--tab-text-hover)` | Label colour while hovering an enabled tab; default `var(--rel-text-label)` |
|
|
113
|
-
| `--rel-tab-underline-height` | `var(--tab-underline-height)` | Thickness of the active underline; default 3px |
|
|
114
|
+
| `--rel-tab-underline-height` | `var(--tab-underline-height)` | Thickness of the active underline; default 1px (`--rel-stroke-sm`, the weight Figma draws). Set it to restore the heavier 3px bar shipped previously. |
|
|
114
115
|
|
|
115
116
|
### `<rel-tab-item>`
|
|
116
117
|
|
|
@@ -119,6 +120,7 @@ Set these on the host (or an ancestor) to customise the element without touching
|
|
|
119
120
|
| Property | Attribute | Type | Default | Description |
|
|
120
121
|
| --- | --- | --- | --- | --- |
|
|
121
122
|
| `label` | `label` | `string` | `""` | Text shown on the tab. |
|
|
123
|
+
| `icon` | `icon` | `string` | `""` | Icon name from the generated icon dictionary, rendered before the label (Figma "Show Icon" / "Icon"). Sized 20 / 18 / 16px with the tab's own size step. |
|
|
122
124
|
| `value` | `value` | `string` | `""` | Optional identifier for the tab. `<rel-tab>` does not read it; look it up from the item at `event.detail` when handling `rel-tab-change`. |
|
|
123
125
|
| `badge` | `badge` | `number` | `0` | Count shown in a small badge after the label; `0` hides the badge. |
|
|
124
126
|
| `badgeDot` | `badge-dot` | `boolean` | `false` | Shows a small dot instead of a numbered badge — takes precedence over `badge`. |
|