@reliability-design/web 1.4.8 → 1.4.10
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 +214 -0
- package/custom-elements.json +18600 -0
- package/dist/components/rel-accordion/README.md +9 -2
- package/dist/components/rel-alert/README.md +5 -8
- package/dist/components/rel-autocomplete/README.md +209 -208
- package/dist/components/rel-avatar/README.md +228 -118
- package/dist/components/rel-breadcrumb/README.md +1 -0
- package/dist/components/rel-button/README.md +9 -9
- package/dist/components/rel-calendar/README.md +111 -109
- package/dist/components/rel-cardmedia/README.md +1 -1
- package/dist/components/rel-carousel/README.md +187 -186
- package/dist/components/rel-checkbox/README.md +159 -146
- package/dist/components/rel-chip/README.md +141 -138
- package/dist/components/rel-container/README.md +1 -1
- package/dist/components/rel-date-picker/README.md +221 -200
- package/dist/components/rel-drawer/README.md +4 -4
- package/dist/components/rel-kbd/README.md +188 -141
- package/dist/components/rel-layout/README.md +34 -34
- package/dist/components/rel-menu/README.md +17 -10
- package/dist/components/rel-menubar/README.md +218 -218
- package/dist/components/rel-otp/README.md +4 -8
- package/dist/components/rel-pagination/README.md +141 -100
- package/dist/components/rel-popover/README.md +220 -203
- package/dist/components/rel-radio/README.md +142 -131
- package/dist/components/rel-range-picker/README.md +194 -165
- package/dist/components/rel-resizable/README.md +220 -199
- package/dist/components/rel-segmented-button/README.md +158 -156
- package/dist/components/rel-select/README.md +22 -16
- package/dist/components/rel-sheet/README.md +3 -2
- package/dist/components/rel-signature-pad/README.md +161 -0
- package/dist/components/rel-slider/README.md +140 -131
- package/dist/components/rel-snackbar/README.md +170 -168
- package/dist/components/rel-split-button/README.md +129 -0
- package/dist/components/rel-stepper/README.md +171 -162
- package/dist/components/rel-switch/README.md +122 -117
- package/dist/components/rel-tab/README.md +184 -173
- package/dist/components/rel-textfield/README.md +23 -30
- package/dist/components/rel-time-picker/README.md +188 -164
- package/dist/components/rel-toast/README.md +20 -11
- package/dist/components/rel-tooltip/README.md +5 -4
- package/dist/components/rel-tree/README.md +157 -0
- package/dist/components/rel-upload/README.md +8 -5
- package/dist/index.d.mts +1698 -607
- package/dist/index.d.ts +1698 -607
- package/dist/index.js +12276 -6347
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +12218 -6296
- package/dist/index.mjs.map +1 -1
- package/dist/styles/motion.css +31 -0
- package/dist/styles/motion.tokens.json +38 -0
- package/dist/styles/vars.css +88 -64
- package/dist/{vars-DXX6QOAG.css → vars-E22LYFMV.css} +88 -64
- package/package.json +60 -37
- package/dist/styles/focus-ring.ts +0 -84
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# rel-signature-pad
|
|
2
|
+
|
|
3
|
+
<!-- @unreleased-component 1.5.0 -->
|
|
4
|
+
|
|
5
|
+
A field that captures a handwritten signature. The user signs with a mouse, pen or finger on a 160px pad that fills its container's width. Like `rel-textfield`, the field has a label, helper text, and error, disabled and read-only states. Undo and Clear sit in the helper row. Undo removes the last stroke, and it also brings back a signature that Clear removed, so Clear asks no confirmation. `value` is the signature as a trimmed PNG data URL; `strokes` keeps the vector record, and `toSVG()` exports it.
|
|
6
|
+
|
|
7
|
+
A "Type your name instead" link beside the label switches to type mode: the user types their name and it renders on the baseline in Poppins italic. The value is the same kind of PNG. Type mode is the keyboard and screen-reader alternative to drawing (WCAG 2.2 SC 2.5.7, Dragging Movements), and it is offered to everyone.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
```html
|
|
12
|
+
<rel-signature-pad id="sig" label="Driver signature" required></rel-signature-pad>
|
|
13
|
+
<script>
|
|
14
|
+
const sig = document.getElementById('sig');
|
|
15
|
+
sig.addEventListener('rel-change', (e) => {
|
|
16
|
+
console.log(e.detail.value); // "data:image/png;base64,…", or "" once cleared
|
|
17
|
+
console.log(e.detail.strokes); // [{ points: [[x, y, t, pressure], …], pointerType }, …]
|
|
18
|
+
console.log(e.detail.signedAt); // ISO 8601 time of the first stroke
|
|
19
|
+
});
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<!-- An error message replaces the helper text -->
|
|
23
|
+
<rel-signature-pad label="Driver signature" required error
|
|
24
|
+
error-message="A signature is required to confirm delivery"></rel-signature-pad>
|
|
25
|
+
|
|
26
|
+
<!-- Show a stored signature without letting it change -->
|
|
27
|
+
<rel-signature-pad label="Driver signature" readonly value="data:image/png;base64,…"></rel-signature-pad>
|
|
28
|
+
|
|
29
|
+
<!-- Start in type mode, with a name filled in -->
|
|
30
|
+
<rel-signature-pad label="Signature" mode="type" typed-name="Ada Lovelace"></rel-signature-pad>
|
|
31
|
+
|
|
32
|
+
<!-- A taller pad -->
|
|
33
|
+
<rel-signature-pad label="Signature" style="--rel-signature-pad-height: 200px"></rel-signature-pad>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Once there is ink, the helper row shows "Signed" with the date, time and a short time zone (for example "Signed 18/10/2026, 2:14 PM GMT+5"), formatted for the nearest `lang` attribute. `signedAt` holds the same moment as an ISO string. It is set by the first stroke and cleared by Clear.
|
|
37
|
+
|
|
38
|
+
The exported PNG and SVG always use black ink on a transparent background, so a signature captured in dark mode still prints. On screen the ink follows the theme (`--rel-text-default`), and a stored `value` is recoloured to match. The PNG is trimmed to the ink plus 8px and drawn at 2×.
|
|
39
|
+
|
|
40
|
+
`strokes` coordinates are CSS pixels of the pad at the moment the signature began. If the pad later gets narrower, the signature is drawn scaled down to fit and the coordinates do not change. Assigning `strokes` redraws a stored record that can still be added to; assigning `value` shows a stored image that Undo cannot take apart. Both start a new Undo history.
|
|
41
|
+
|
|
42
|
+
Each mode keeps its own content when the user switches, and only the active mode makes the `value`. In type mode, Clear empties the name and Undo brings it back; while focus is in the name input, Ctrl/Cmd+Z is the input's own undo. `signedAt` in type mode is when the name was first typed. The value updates as the user types, and `rel-change` fires when the name is committed (on blur or Enter) and when the mode switch changes the value.
|
|
43
|
+
|
|
44
|
+
`rel-change` reports what the user did: a stroke, Undo, Clear, a committed name or a mode switch. It does not fire when your code sets `value`, `strokes`, `typed-name` or `mode`, or calls `undo()` or `clear()`. Read the new state from the element after those calls.
|
|
45
|
+
|
|
46
|
+
## Forms
|
|
47
|
+
|
|
48
|
+
The pad is a form control (decision 0006). Inside a `<form>` it submits its `value`, the PNG data URL, under its `name`; an empty pad submits `""`. The data URL is typically 5–30 KB, so post the form (`method="post"`) and check your server's request-size limit.
|
|
49
|
+
|
|
50
|
+
```html
|
|
51
|
+
<form method="post" action="/deliveries/42/confirm">
|
|
52
|
+
<rel-signature-pad name="signature" label="Driver signature" required></rel-signature-pad>
|
|
53
|
+
<button>Confirm delivery</button>
|
|
54
|
+
</form>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
- **Validation:** a `required` pad is invalid while empty (`valueMissing`), so the form will not submit and the browser focuses the pad, or the name input in type mode. The field does not turn red by itself. Listen for `invalid` and set `error` and `error-message`, as with the other fields. A `readonly` pad is not validated.
|
|
58
|
+
- **Reset:** a form reset empties both modes and the Undo history, without firing `rel-change`.
|
|
59
|
+
- **Restore:** when the browser restores a form (back and forward navigation), the strokes, the stored image or the typed name come back.
|
|
60
|
+
- **Labels and fieldsets:** an outer `<label for>` (or a wrapping one) names the pad and focuses it when clicked. A `<fieldset disabled>` disables the pad, and a disabled pad is left out of the form data.
|
|
61
|
+
|
|
62
|
+
<!-- readme-gen:start -->
|
|
63
|
+
|
|
64
|
+
<!-- Generated from rel-signature-pad.ts — do not edit; run readme-generate.mjs -->
|
|
65
|
+
|
|
66
|
+
## API
|
|
67
|
+
|
|
68
|
+
### Attributes / Properties
|
|
69
|
+
|
|
70
|
+
| Property | Attribute | Type | Default | Description |
|
|
71
|
+
| --- | --- | --- | --- | --- |
|
|
72
|
+
| `label` | `label` | `string` | `undefined` | Visible label above the pad. A `required` asterisk is appended. |
|
|
73
|
+
| `required` | `required` | `boolean` | `false` | Marks the signature as required: the label gets an asterisk. Reflected. |
|
|
74
|
+
| `helperText` | `helper-text` | `string` | `undefined` | Helper line below the pad. Defaults to "Use a mouse, pen or finger to sign"; once signed, the line shows "Signed {date and time}" instead. |
|
|
75
|
+
| `disabledText` | `disabled-text` | `string` | `undefined` | Text in the helper line while disabled (default "Signing is unavailable"). |
|
|
76
|
+
| `error` | `error` | `boolean` | `false` | Puts the field in the error state: danger border, and `error-message` replacing the helper text. Reflected. |
|
|
77
|
+
| `errorMessage` | `error-message` | `string` | `undefined` | Text shown below the pad, with an alert icon, instead of the helper text while `error` is set. |
|
|
78
|
+
| `disabled` | `disabled` | `boolean` | `false` | Disables the field: no drawing, Undo and Clear disabled, the pad leaves the Tab order, and the helper line shows `disabled-text`. Reflected. |
|
|
79
|
+
| `readonly` | `readonly` | `boolean` | `false` | Shows the signature and its timestamp without letting it change: a subtle border, no Undo or Clear buttons, no drawing. Reflected. |
|
|
80
|
+
| `placeholder` | `placeholder` | `string` | `"Sign here"` | Text in the empty pad (default "Sign here"). It hides on the first ink; the baseline stays. |
|
|
81
|
+
| `name` | `name` | `string` | `undefined` | Name of the field in a form. Reflected. |
|
|
82
|
+
| `fieldAriaLabel` | `field-aria-label` | `string` | `undefined` | Accessible name of the pad when there is no visible `label`. |
|
|
83
|
+
| `value` | `value` | `string` | `""` | The signature as a PNG data URL, trimmed to the ink at 2×, with black ink on a transparent background in every theme; `""` when empty. Set it to show a stored signature: it is drawn in the theme's ink colour and replaces the strokes, so Undo cannot take it apart stroke by stroke (Clear removes it, and Undo brings it back). Setting `""` empties the pad. |
|
|
84
|
+
| `strokes` | — | `SignatureStroke[]` | `[]` | The vector record of the signature, one entry per stroke: `{ points: [x, y, t, pressure][], pointerType? }`. Coordinates are CSS pixels of the pad when the first stroke was drawn (a narrower pad later shows the signature scaled down to fit, and the coordinates do not change); `t` is epoch milliseconds. Set it to redraw a stored signature that can be added to; that starts a new Undo history. Property only. |
|
|
85
|
+
| `mode` | `mode` | `"draw" \| "type"` | `"draw"` | `draw` (default) captures the signature with a pointer; `type` takes a typed name and renders it in Poppins italic. The user switches with the link beside the label. Each mode keeps its own content; only the active mode makes the `value`. Reflected. |
|
|
86
|
+
| `typedName` | `typed-name` | `string` | `""` | The name typed in type mode. The `value` in type mode is this name rendered as a PNG, black, in Poppins italic. |
|
|
87
|
+
|
|
88
|
+
### Public fields / accessors
|
|
89
|
+
|
|
90
|
+
| Name | Type | Description |
|
|
91
|
+
| --- | --- | --- |
|
|
92
|
+
| `signedAt` | `string` | When the signature was started, as an ISO 8601 string; `""` while empty. Set by the first stroke and cleared by Clear. Read-only. |
|
|
93
|
+
|
|
94
|
+
### Methods
|
|
95
|
+
|
|
96
|
+
| Method | Signature | Description |
|
|
97
|
+
| --- | --- | --- |
|
|
98
|
+
| `isEmpty` | `isEmpty(): boolean` | True when the active mode has no signature: no strokes and no stored signature in draw mode, a blank name in type mode. |
|
|
99
|
+
| `undo` | `undo(): void` | Removes the last stroke, or restores what Clear removed (in type mode, the cleared name). Does not fire `rel-change`. |
|
|
100
|
+
| `clear` | `clear(): void` | Removes the whole signature of the active mode; Undo brings it back. Does not fire `rel-change`. |
|
|
101
|
+
| `toDataURL` | `toDataURL(type = "image/png"): string` | The signature as a data URL of the given type (default `"image/png"`), trimmed to the ink at 2× with black ink; `"image/svg+xml"` returns `toSVG()` as a data URL, and `"image/jpeg"` gets a white background. `""` when empty. |
|
|
102
|
+
| `toSVG` | `toSVG(): string` | The signature as an SVG document string, in black and trimmed. Draw mode gives smoothed paths in the `strokes` coordinate space (a stored signature from `value` is embedded as an image); type mode gives the name as `<text>` in Poppins italic. `""` when empty. |
|
|
103
|
+
|
|
104
|
+
## Events
|
|
105
|
+
|
|
106
|
+
| Event | Detail | Bubbles / composed | Description |
|
|
107
|
+
| --- | --- | --- | --- |
|
|
108
|
+
| `rel-begin` | `{}` | bubbles / composed | The user put the pointer down to start a stroke. Detail: `{}`. |
|
|
109
|
+
| `rel-change` | `{ value, strokes, signedAt, mode }` | bubbles / composed | The signature changed through the user: a finished stroke, Undo, Clear, a committed typed name (on blur or Enter) or a switch of mode. Detail: `{ value, strokes, signedAt, mode }`. Not fired for property changes or the `undo()` / `clear()` methods. |
|
|
110
|
+
| `rel-end` | `{}` | bubbles / composed | The user finished a stroke. Detail: `{}`. |
|
|
111
|
+
|
|
112
|
+
## Slots
|
|
113
|
+
|
|
114
|
+
| Slot | Description |
|
|
115
|
+
| --- | --- |
|
|
116
|
+
| — | This element has no slots. |
|
|
117
|
+
|
|
118
|
+
## CSS Parts
|
|
119
|
+
|
|
120
|
+
| Part | Description |
|
|
121
|
+
| --- | --- |
|
|
122
|
+
| `label` | The label above the pad. |
|
|
123
|
+
| `mode-toggle` | The link-style `rel-button` beside the label that switches between drawing ("Type your name instead") and typing ("Draw instead"). Hidden while `readonly`. |
|
|
124
|
+
| `pad` | The bordered drawing area. In draw mode it is a focusable `role="img"` named by the label and the signature's state; in type mode it holds the name input. |
|
|
125
|
+
| `canvas` | The `<canvas>` the ink is drawn on. |
|
|
126
|
+
| `placeholder` | The "Sign here" text ("Type your full name" in type mode), shown while the pad is empty. |
|
|
127
|
+
| `baseline` | The line near the bottom of the pad. |
|
|
128
|
+
| `typed-input` | The text input of type mode, drawn on the baseline in Poppins italic. |
|
|
129
|
+
| `helper` | The helper, error or "Signed …" text below the pad. |
|
|
130
|
+
| `actions` | The row that holds the Undo and Clear buttons. |
|
|
131
|
+
| `undo` | The Undo `rel-button` (ghost, small). |
|
|
132
|
+
| `clear` | The Clear `rel-button` (secondary, small). |
|
|
133
|
+
|
|
134
|
+
## Tokens / CSS Variables
|
|
135
|
+
|
|
136
|
+
### Component hooks
|
|
137
|
+
|
|
138
|
+
Set these on the host (or an ancestor) to customise the element without touching design tokens.
|
|
139
|
+
|
|
140
|
+
| Custom property | Default | Description |
|
|
141
|
+
| --- | --- | --- |
|
|
142
|
+
| `--rel-signature-pad-height` | `160px` | Height of the pad, border included (default 160px). |
|
|
143
|
+
|
|
144
|
+
<!-- readme-gen:end -->
|
|
145
|
+
|
|
146
|
+
## Accessibility
|
|
147
|
+
|
|
148
|
+
- The "Type your name instead" / "Draw instead" link comes before the pad in the Tab order, so keyboard users reach the typed alternative first. Switching moves focus to the name input or to the pad. The input is named "{label}, type your full name", carries `aria-required` and `aria-invalid`, and is described by the helper or error text.
|
|
149
|
+
- In draw mode the pad is a focusable `role="img"`. Its name is the label (or `field-aria-label`) plus its state: "Driver signature, required, signature pad, empty", or "Driver signature, required, signed 18/10/2026, 2:14 PM GMT+5". It is described by the helper or error text.
|
|
150
|
+
- Undo and Clear are real buttons, named "Undo last stroke" ("Undo clear" in type mode) and "Clear signature". When a button disables itself (Clear, or the last Undo), focus moves to the pad.
|
|
151
|
+
- Changes are announced politely: "Signature captured" on the first stroke, then "Last stroke removed", "Signature cleared" and "Signature restored".
|
|
152
|
+
- The pad has the field border (`--rel-border-default`, 3:1 or more). Focus, and drawing, draw a 2px `--rel-border-strong` border inside the pad edge; the error state draws it in `--rel-border-danger` at rest, and focus in error adds a 2px danger ring outside, so focus stays visible. Both stay visible in forced-colours mode, where the ink is drawn in `CanvasText`.
|
|
153
|
+
- Only the canvas sets `touch-action: none`. The page still scrolls from the label, the helper row and a read-only or disabled pad.
|
|
154
|
+
|
|
155
|
+
### Keyboard
|
|
156
|
+
|
|
157
|
+
| Key | Action |
|
|
158
|
+
| --- | --- |
|
|
159
|
+
| Tab / Shift+Tab | Moves between the mode link, the pad (or the name input in type mode), Undo and Clear. The pad leaves the Tab order while disabled. |
|
|
160
|
+
| Ctrl+Z / Cmd+Z | Undoes the last stroke, or a Clear, while focus is in the field (in the name input it is the input's own undo) |
|
|
161
|
+
| Enter / Space | Activates the mode link, Undo or Clear |
|
|
@@ -1,131 +1,140 @@
|
|
|
1
|
-
# rel-slider
|
|
2
|
-
|
|
3
|
-
`<rel-slider>` implements the Figma **Slider** component (6417:1340): a pill-shaped track with a stroked round thumb, an optional value tooltip, discrete tick marks with labels, a dotted track style and a dual-thumb `range` mode. It is built on native `<input type="range">` elements, so keyboard and assistive-technology behaviour come from the browser. Use it when a user picks a value or an interval from a bounded numeric range and the relative position matters more than exact digits (volume, opacity, price band); for precise numeric entry use `<rel-textfield>`, and for a handful of named options use `<rel-radio>` or `<rel-tab>`.
|
|
4
|
-
|
|
5
|
-
## Usage
|
|
6
|
-
|
|
7
|
-
```html
|
|
8
|
-
<!-- Continuous slider -->
|
|
9
|
-
<rel-slider value="40" min="0" max="100" field-aria-label="Volume"></rel-slider>
|
|
10
|
-
|
|
11
|
-
<!-- Discrete slider: snaps to step, shows tick marks and tick labels -->
|
|
12
|
-
<rel-slider type="discrete" value="3" min="1" max="5" step="1"
|
|
13
|
-
|
|
14
|
-
<!-- Range slider: two thumbs bounding value…value-end -->
|
|
15
|
-
<rel-slider type="range" value="20" value-end="80" min="0" max="100" field-aria-label="Price"></rel-slider>
|
|
16
|
-
|
|
17
|
-
<!-- Sizes (Figma S / M / L) -->
|
|
18
|
-
<rel-slider size="sm" value="30"></rel-slider>
|
|
19
|
-
<rel-slider size="md" value="50"></rel-slider>
|
|
20
|
-
<rel-slider size="lg" value="70"></rel-slider>
|
|
21
|
-
|
|
22
|
-
<!-- Dotted fill, no tooltip -->
|
|
23
|
-
<rel-slider id="opacity" track="dotted" value="60"></rel-slider>
|
|
24
|
-
<script>
|
|
25
|
-
// showBubble defaults to true; an absent attribute keeps the default, so switch it off from JS.
|
|
26
|
-
document.getElementById('opacity').showBubble = false;
|
|
27
|
-
</script>
|
|
28
|
-
|
|
29
|
-
<!-- Disabled -->
|
|
30
|
-
<rel-slider value="30" disabled></rel-slider>
|
|
31
|
-
|
|
32
|
-
<!-- Listening for changes -->
|
|
33
|
-
<rel-slider id="budget" type="range" value="10" value-end="90"></rel-slider>
|
|
34
|
-
<script>
|
|
35
|
-
document.getElementById('budget').addEventListener('rel-change', (e) => {
|
|
36
|
-
console.log(e.detail.value, e.detail.valueEnd); // valueEnd only in range mode
|
|
37
|
-
});
|
|
38
|
-
</script>
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
|
59
|
-
|
|
|
60
|
-
| `
|
|
61
|
-
| `
|
|
62
|
-
| `
|
|
63
|
-
| `
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
|
68
|
-
|
|
|
69
|
-
| `
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
|
83
|
-
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
|
92
|
-
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
-
|
|
105
|
-
|
|
106
|
-
-
|
|
107
|
-
-
|
|
108
|
-
|
|
109
|
-
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
1
|
+
# rel-slider
|
|
2
|
+
|
|
3
|
+
`<rel-slider>` implements the Figma **Slider** component (6417:1340): a pill-shaped track with a stroked round thumb, an optional value tooltip, discrete tick marks with labels, a dotted track style and a dual-thumb `range` mode. It is built on native `<input type="range">` elements, so keyboard and assistive-technology behaviour come from the browser. Use it when a user picks a value or an interval from a bounded numeric range and the relative position matters more than exact digits (volume, opacity, price band); for precise numeric entry use `<rel-textfield>`, and for a handful of named options use `<rel-radio>` or `<rel-tab>`.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```html
|
|
8
|
+
<!-- Continuous slider -->
|
|
9
|
+
<rel-slider value="40" min="0" max="100" field-aria-label="Volume"></rel-slider>
|
|
10
|
+
|
|
11
|
+
<!-- Discrete slider: snaps to step, shows tick marks and tick labels -->
|
|
12
|
+
<rel-slider type="discrete" value="3" min="1" max="5" step="1" show-tick-labels field-aria-label="Rating"></rel-slider>
|
|
13
|
+
|
|
14
|
+
<!-- Range slider: two thumbs bounding value…value-end -->
|
|
15
|
+
<rel-slider type="range" value="20" value-end="80" min="0" max="100" field-aria-label="Price"></rel-slider>
|
|
16
|
+
|
|
17
|
+
<!-- Sizes (Figma S / M / L) -->
|
|
18
|
+
<rel-slider size="sm" value="30"></rel-slider>
|
|
19
|
+
<rel-slider size="md" value="50"></rel-slider>
|
|
20
|
+
<rel-slider size="lg" value="70"></rel-slider>
|
|
21
|
+
|
|
22
|
+
<!-- Dotted fill, no tooltip -->
|
|
23
|
+
<rel-slider id="opacity" track="dotted" value="60"></rel-slider>
|
|
24
|
+
<script>
|
|
25
|
+
// showBubble defaults to true; an absent attribute keeps the default, so switch it off from JS.
|
|
26
|
+
document.getElementById('opacity').showBubble = false;
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<!-- Disabled -->
|
|
30
|
+
<rel-slider value="30" disabled></rel-slider>
|
|
31
|
+
|
|
32
|
+
<!-- Listening for changes -->
|
|
33
|
+
<rel-slider id="budget" type="range" value="10" value-end="90"></rel-slider>
|
|
34
|
+
<script>
|
|
35
|
+
document.getElementById('budget').addEventListener('rel-change', (e) => {
|
|
36
|
+
console.log(e.detail.value, e.detail.valueEnd); // valueEnd only in range mode
|
|
37
|
+
});
|
|
38
|
+
</script>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Deprecated aliases
|
|
42
|
+
|
|
43
|
+
```html
|
|
44
|
+
<!-- showticklabels / showbubble → show-tick-labels / show-bubble (since 1.5.0; still work, log a one-time
|
|
45
|
+
console notice, removed in 3.0). showTickLabels still reflects as showticklabels in 1.x. -->
|
|
46
|
+
<rel-slider type="discrete" min="1" max="5" step="1" showticklabels showbubble="false"></rel-slider>
|
|
47
|
+
<rel-slider type="discrete" min="1" max="5" step="1" show-tick-labels show-bubble="false"></rel-slider>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
<!-- readme-gen:start -->
|
|
51
|
+
|
|
52
|
+
<!-- Generated from rel-slider.ts — do not edit; run readme-generate.mjs -->
|
|
53
|
+
|
|
54
|
+
## API
|
|
55
|
+
|
|
56
|
+
### Attributes / Properties
|
|
57
|
+
|
|
58
|
+
| Property | Attribute | Type | Default | Description |
|
|
59
|
+
| --- | --- | --- | --- | --- |
|
|
60
|
+
| `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. |
|
|
61
|
+
| `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. |
|
|
62
|
+
| `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. |
|
|
63
|
+
| `min` | `min` | `number` | `0` | Lowest selectable value. |
|
|
64
|
+
| `max` | `max` | `number` | `100` | Highest selectable value. |
|
|
65
|
+
| `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. |
|
|
66
|
+
| `disabled` | `disabled` | `boolean` | `false` | Disables interaction and dims the track, thumb and ticks; the tooltip is hidden. |
|
|
67
|
+
| `track` | `track` | `"solid" \| "dotted"` | `"solid"` | Style of the filled part of the track: `solid` or a `dotted` pattern. |
|
|
68
|
+
| `showTickLabels` | `show-tick-labels` | `boolean` | `false` | Print the numeric value under every tick mark. Only has an effect in `discrete` mode. Reflected (as `showticklabels` in 1.x). The `showticklabels` attribute spelling is deprecated (still works; removal targeted for 3.0). |
|
|
69
|
+
| `showBubble` | `show-bubble` | `boolean` | `true` | Show the value tooltip above the thumb(s). The `showbubble` attribute spelling is deprecated (still works; removal targeted for 3.0). |
|
|
70
|
+
| `value` | `value` | `number` | `0` | Current value (the lower value in `range` mode). |
|
|
71
|
+
| `valueEnd` | `value-end` | `number` | `100` | Upper value when type="range" (attribute value-end). |
|
|
72
|
+
| `fieldAriaLabel` | `field-aria-label` | `string` | `undefined` | Accessible name for the native range input. In `range` mode it is suffixed with " minimum" / " maximum" per thumb; without it the two thumbs read "Minimum value" / "Maximum value" and a single slider has no name. |
|
|
73
|
+
|
|
74
|
+
## Events
|
|
75
|
+
|
|
76
|
+
| Event | Detail | Bubbles / composed | Description |
|
|
77
|
+
| --- | --- | --- | --- |
|
|
78
|
+
| `rel-change` | `{ value: this.value, valueEnd: this.valueEnd } / { value: this.value }` | bubbles / composed | Fired on every user change of the value. Detail: `{ value }` for single-thumb sliders, `{ value, valueEnd }` in `range` mode. |
|
|
79
|
+
|
|
80
|
+
## Slots
|
|
81
|
+
|
|
82
|
+
| Slot | Description |
|
|
83
|
+
| --- | --- |
|
|
84
|
+
| — | This element has no slots. |
|
|
85
|
+
|
|
86
|
+
## CSS Parts
|
|
87
|
+
|
|
88
|
+
| Part | Description |
|
|
89
|
+
| --- | --- |
|
|
90
|
+
| `tooltip` | The value bubble + chevron above each thumb (only while `showBubble` is on) |
|
|
91
|
+
| `thumb` | The round grab handle (one per thumb in range mode) |
|
|
92
|
+
| `track` | The rail behind the thumb (the filled portion has no part) |
|
|
93
|
+
|
|
94
|
+
## Tokens / CSS Variables
|
|
95
|
+
|
|
96
|
+
### Component hooks
|
|
97
|
+
|
|
98
|
+
Set these on the host (or an ancestor) to customise the element without touching design tokens.
|
|
99
|
+
|
|
100
|
+
| Custom property | Default | Description |
|
|
101
|
+
| --- | --- | --- |
|
|
102
|
+
| `--rel-slider-bubble-radius` | `var(--bubble-radius)` | Corner radius of the value bubble; 8px for size sm, otherwise 10px |
|
|
103
|
+
| `--rel-slider-thumb-halo-color` | `var(--thumb-halo-color)` | Colour of the keyboard-focus ring; default `var(--rel-border-default)` |
|
|
104
|
+
| `--rel-slider-thumb-size` | `var(--thumb-size)` | Thumb diameter; 16 / 20 / 24px for size sm / md / lg |
|
|
105
|
+
| `--rel-slider-thumb-stroke` | `var(--thumb-stroke)` | Width of the hover / pressed / focus ring around the thumb; default 6px |
|
|
106
|
+
| `--rel-slider-tick-size` | `var(--tick-size)` | Tick-mark diameter in discrete mode; 4 / 5 / 6px for size sm / md / lg |
|
|
107
|
+
| `--rel-slider-track-height` | `var(--track-height)` | Rail thickness; 6 / 8 / 10px for size sm / md / lg |
|
|
108
|
+
|
|
109
|
+
<!-- readme-gen:end -->
|
|
110
|
+
|
|
111
|
+
## Accessibility
|
|
112
|
+
|
|
113
|
+
- Each thumb is a native `<input type="range">`; the custom track, thumb and tooltip are decorative (`pointer-events: none`) and the tooltip is `aria-hidden="true"`.
|
|
114
|
+
- `field-aria-label` becomes the input's `aria-label`. In `range` mode the two inputs are named `"<label> minimum"` / `"<label> maximum"`; without a label they fall back to `"Minimum value"` / `"Maximum value"`. A single-thumb slider without `field-aria-label` has no accessible name, so always set one (or label it from the surrounding form).
|
|
115
|
+
- `min`, `max` and `step` are forwarded to the native input, so screen readers announce the current value and the range. In `continuous` mode the native step is always 1 regardless of `step`.
|
|
116
|
+
- The keyboard-focus ring is drawn on the custom thumb via `:focus-visible` (`--rel-slider-thumb-halo-color`); mouse focus shows no ring.
|
|
117
|
+
- `disabled` disables the native inputs (removed from the tab order) and hides the tooltip.
|
|
118
|
+
- In `range` mode pointer input is handled by the container so either thumb can be grabbed (the nearer thumb wins); keyboard input still goes through the two native inputs.
|
|
119
|
+
- `prefers-reduced-motion: reduce` removes the thumb and tick transitions.
|
|
120
|
+
|
|
121
|
+
Keys come from the native range input:
|
|
122
|
+
|
|
123
|
+
| Key | Action |
|
|
124
|
+
| --- | --- |
|
|
125
|
+
| `ArrowRight` / `ArrowUp` | Increase by one step (`step` in `discrete` mode, 1 otherwise). |
|
|
126
|
+
| `ArrowLeft` / `ArrowDown` | Decrease by one step. |
|
|
127
|
+
| `Home` | Jump to `min`. |
|
|
128
|
+
| `End` | Jump to `max`. |
|
|
129
|
+
| `PageUp` / `PageDown` | Larger jump (browser-defined). |
|
|
130
|
+
|
|
131
|
+
## Notes / Edge Cases
|
|
132
|
+
|
|
133
|
+
- `type="default"` is an alias of `continuous` (Figma's Type axis). Only `discrete` draws ticks and snaps to `step`; `continuous` sliders move in integer steps whatever `step` says.
|
|
134
|
+
- Ticks are generated from `min` to `max` in `step` increments; if the range does not divide evenly a final tick is added at `max`. `show-tick-labels` only has an effect in `discrete` mode.
|
|
135
|
+
- In `range` mode the thumbs cannot cross: `value` is clamped to `≤ value-end` and `value-end` to `≥ value`. The default `value-end` is 100.
|
|
136
|
+
- `rel-change` fires for user interaction only; setting `value` / `valueEnd` programmatically updates the visuals but emits nothing.
|
|
137
|
+
- The element is `display: block`. Its rail (the pointer target) is at least 24px tall at every size (since 1.5.0, so Small and Medium grow from 16 / 20px to 24px); the track and thumb keep their 6/16, 8/20 and 10/24px sizes. The value bubble overflows above the rail and is not reserved; tick labels reserve their own space below it.
|
|
138
|
+
- Size presets set the track/thumb/tick/bubble dimensions per `size`; a `--rel-slider-*` hook set on the host overrides the preset for every size.
|
|
139
|
+
- Legacy hook aliases still honoured: `--track-height`, `--thumb-size`, `--thumb-stroke`, `--thumb-halo-color`, `--tick-size` and `--bubble-radius` are read as fallbacks of the `--rel-slider-*` hooks.
|
|
140
|
+
- `registerOnChange`, `registerOnTouched` and `writeValue` exist for the Angular `ControlValueAccessor` wrapper and are not public API.
|