@reliability-design/web 1.4.5 → 1.4.7
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 +211 -49
- package/dist/components/rel-accordion/README.md +132 -132
- package/dist/components/rel-alert/README.md +145 -141
- package/dist/components/rel-autocomplete/README.md +156 -61
- package/dist/components/rel-avatar/README.md +116 -130
- package/dist/components/rel-badge/README.md +98 -93
- package/dist/components/rel-breadcrumb/README.md +96 -102
- package/dist/components/rel-button/README.md +160 -130
- package/dist/components/rel-calendar/README.md +109 -109
- package/dist/components/rel-card/README.md +75 -94
- package/dist/components/rel-cardmedia/README.md +100 -127
- package/dist/components/rel-carousel/README.md +184 -166
- package/dist/components/rel-checkbox/README.md +93 -75
- package/dist/components/rel-chip/README.md +132 -121
- package/dist/components/rel-container/README.md +107 -99
- package/dist/components/rel-date-picker/README.md +200 -289
- package/dist/components/rel-divider/README.md +78 -100
- package/dist/components/rel-drawer/README.md +187 -200
- package/dist/components/rel-kbd/README.md +141 -151
- package/dist/components/rel-menu/README.md +178 -151
- package/dist/components/rel-menubar/README.md +218 -329
- package/dist/components/rel-otp/README.md +170 -440
- package/dist/components/rel-pagination/README.md +100 -424
- package/dist/components/rel-popover/README.md +203 -568
- package/dist/components/rel-progress/README.md +88 -110
- package/dist/components/rel-radio/README.md +131 -135
- package/dist/components/rel-range-picker/README.md +162 -0
- package/dist/components/rel-resizable/README.md +199 -140
- package/dist/components/rel-segmented-button/README.md +155 -141
- package/dist/components/rel-select/README.md +154 -93
- package/dist/components/rel-sheet/README.md +168 -224
- package/dist/components/rel-skeleton/README.md +103 -0
- package/dist/components/rel-slider/README.md +130 -135
- package/dist/components/rel-snackbar/README.md +162 -134
- package/dist/components/rel-stepper/README.md +158 -160
- package/dist/components/rel-switch/README.md +108 -102
- package/dist/components/rel-tab/README.md +171 -163
- package/dist/components/rel-textfield/README.md +159 -69
- package/dist/components/rel-time-picker/README.md +122 -157
- package/dist/components/rel-toast/README.md +157 -148
- package/dist/components/rel-tooltip/README.md +108 -103
- package/dist/components/rel-upload/README.md +220 -0
- package/dist/index.d.mts +1387 -350
- package/dist/index.d.ts +1387 -350
- package/dist/index.js +5863 -3600
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5864 -3592
- package/dist/index.mjs.map +1 -1
- package/dist/styles/vars.css +877 -866
- package/dist/{vars-XNMTSRVN.css → vars-JHTUGNRG.css} +877 -866
- package/package.json +4 -3
- package/dist/components/rel-accordion/rel-accordion.ts +0 -336
- package/dist/components/rel-alert/rel-alert.ts +0 -305
- package/dist/components/rel-autocomplete/rel-autocomplete.ts +0 -689
- package/dist/components/rel-avatar/rel-avatar.ts +0 -142
- package/dist/components/rel-badge/rel-badge.ts +0 -170
- package/dist/components/rel-breadcrumb/rel-breadcrumb.ts +0 -106
- package/dist/components/rel-button/rel-button.ts +0 -560
- package/dist/components/rel-calendar/index.ts +0 -1
- package/dist/components/rel-calendar/rel-calendar.ts +0 -519
- package/dist/components/rel-card/rel-card.ts +0 -88
- package/dist/components/rel-cardmedia/rel-cardmedia.ts +0 -88
- package/dist/components/rel-carousel/index.ts +0 -1
- package/dist/components/rel-carousel/rel-carousel.ts +0 -700
- package/dist/components/rel-chart/README.md +0 -286
- package/dist/components/rel-chart/index.ts +0 -1
- package/dist/components/rel-chart/rel-chart.ts +0 -754
- package/dist/components/rel-checkbox/rel-checkbox.ts +0 -382
- package/dist/components/rel-chip/rel-chip.ts +0 -472
- package/dist/components/rel-container/rel-container.ts +0 -95
- package/dist/components/rel-date-picker/date-format.test.ts +0 -43
- package/dist/components/rel-date-picker/date-format.ts +0 -47
- package/dist/components/rel-date-picker/index.ts +0 -1
- package/dist/components/rel-date-picker/rel-date-picker.ts +0 -1237
- package/dist/components/rel-divider/rel-divider.ts +0 -54
- package/dist/components/rel-drawer/index.ts +0 -1
- package/dist/components/rel-drawer/rel-drawer-footer.ts +0 -27
- package/dist/components/rel-drawer/rel-drawer.ts +0 -604
- package/dist/components/rel-kbd/rel-kbd.ts +0 -188
- package/dist/components/rel-layout/rel-layout.ts +0 -49
- package/dist/components/rel-menu/rel-menu.ts +0 -535
- package/dist/components/rel-menubar/index.ts +0 -2
- package/dist/components/rel-menubar/rel-menubar-menu.css +0 -3
- package/dist/components/rel-menubar/rel-menubar-menu.ts +0 -17
- package/dist/components/rel-menubar/rel-menubar.ts +0 -777
- package/dist/components/rel-nav-menu/README.md +0 -289
- package/dist/components/rel-nav-menu/index.ts +0 -3
- package/dist/components/rel-nav-menu/rel-nav-menu-item.ts +0 -243
- package/dist/components/rel-nav-menu/rel-nav-menu-panel.ts +0 -72
- package/dist/components/rel-nav-menu/rel-nav-menu.ts +0 -270
- package/dist/components/rel-navbar/README.md +0 -126
- package/dist/components/rel-navbar/rel-navbar.ts +0 -105
- package/dist/components/rel-otp/index.ts +0 -1
- package/dist/components/rel-otp/rel-otp.ts +0 -517
- package/dist/components/rel-pagination/index.ts +0 -1
- package/dist/components/rel-pagination/rel-pagination.ts +0 -509
- package/dist/components/rel-popover/index.ts +0 -2
- package/dist/components/rel-popover/rel-popover-content.ts +0 -81
- package/dist/components/rel-popover/rel-popover.ts +0 -444
- package/dist/components/rel-progress/rel-progress.ts +0 -225
- package/dist/components/rel-radio/rel-radio.ts +0 -305
- package/dist/components/rel-range-picker/rel-range-picker.ts +0 -1331
- package/dist/components/rel-resizable/index.ts +0 -3
- package/dist/components/rel-resizable/rel-resizable-group.ts +0 -405
- package/dist/components/rel-resizable/rel-resizable-handle.ts +0 -150
- package/dist/components/rel-resizable/rel-resizable-panel.ts +0 -58
- package/dist/components/rel-segmented-button/rel-segmented-button.ts +0 -213
- package/dist/components/rel-select/rel-select.ts +0 -1385
- package/dist/components/rel-sheet/rel-sheet.ts +0 -465
- package/dist/components/rel-sidebar/README.md +0 -209
- package/dist/components/rel-sidebar/rel-sidebar.ts +0 -1185
- package/dist/components/rel-skeleton/rel-skeleton.ts +0 -134
- package/dist/components/rel-slider/rel-slider.ts +0 -670
- package/dist/components/rel-snackbar/rel-snackbar.ts +0 -325
- package/dist/components/rel-stepper/rel-stepper.ts +0 -565
- package/dist/components/rel-switch/rel-switch.ts +0 -197
- package/dist/components/rel-tab/rel-tab.ts +0 -264
- package/dist/components/rel-table/README.md +0 -178
- package/dist/components/rel-table/rel-table-body.ts +0 -22
- package/dist/components/rel-table/rel-table-caption.ts +0 -30
- package/dist/components/rel-table/rel-table-cell.ts +0 -43
- package/dist/components/rel-table/rel-table-footer.ts +0 -24
- package/dist/components/rel-table/rel-table-head.ts +0 -47
- package/dist/components/rel-table/rel-table-header.ts +0 -22
- package/dist/components/rel-table/rel-table-row.ts +0 -37
- package/dist/components/rel-table/rel-table.ts +0 -62
- package/dist/components/rel-textfield/rel-textfield.ts +0 -866
- package/dist/components/rel-time-picker/rel-time-picker.ts +0 -1126
- package/dist/components/rel-toast/rel-toast.ts +0 -204
- package/dist/components/rel-tooltip/rel-tooltip.ts +0 -190
- package/dist/components/rel-topbar/rel-topbar-actions.ts +0 -27
- package/dist/components/rel-topbar/rel-topbar-brand.ts +0 -54
- package/dist/components/rel-topbar/rel-topbar-dropdown-item.ts +0 -69
- package/dist/components/rel-topbar/rel-topbar-dropdown.ts +0 -31
- package/dist/components/rel-topbar/rel-topbar-item.ts +0 -324
- package/dist/components/rel-topbar/rel-topbar-mobile-panel.ts +0 -27
- package/dist/components/rel-topbar/rel-topbar-profile.ts +0 -243
- package/dist/components/rel-topbar/rel-topbar-utilities.ts +0 -27
- package/dist/components/rel-topbar/rel-topbar.ts +0 -446
- package/dist/components/rel-upload/UPLOAD-DESIGN-CHANGES.md +0 -134
- package/dist/components/rel-upload/rel-upload-actions.ts +0 -163
- package/dist/components/rel-upload/rel-upload.ts +0 -943
|
@@ -1,110 +1,88 @@
|
|
|
1
|
-
# rel-progress
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
```html
|
|
8
|
-
<!-- Linear
|
|
9
|
-
<rel-progress mode="linear-determinate" value="45"></rel-progress>
|
|
10
|
-
<rel-progress mode="linear-determinate" value="100"></rel-progress>
|
|
11
|
-
|
|
12
|
-
<!-- Linear
|
|
13
|
-
<rel-progress mode="linear-indeterminate"></rel-progress>
|
|
14
|
-
|
|
15
|
-
<!-- Circular
|
|
16
|
-
<rel-progress mode="circular-determinate" value="75"></rel-progress>
|
|
17
|
-
|
|
18
|
-
<!-- Circular
|
|
19
|
-
<rel-progress mode="circular-indeterminate"></rel-progress>
|
|
20
|
-
|
|
21
|
-
<!--
|
|
22
|
-
<rel-progress
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
##
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
Default
|
|
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
|
-
- Circle radius: `15.9155`, circumference: `~100`
|
|
90
|
-
- Rotated -90° to start at top
|
|
91
|
-
- Progress transition: `0.35s`
|
|
92
|
-
- **Indeterminate (spinner)**:
|
|
93
|
-
- Rotates continuously (2s linear infinite)
|
|
94
|
-
- Stroke dash animates (1.5s ease-in-out infinite)
|
|
95
|
-
|
|
96
|
-
- **Value clamping**: Values are automatically clamped to 0-100 range via `safeValue` getter
|
|
97
|
-
|
|
98
|
-
- **Motion preferences**:
|
|
99
|
-
- When `prefers-reduced-motion: reduce`:
|
|
100
|
-
- Linear determinate: no transition
|
|
101
|
-
- Linear indeterminate: no animation, shows full-width bar at 50% opacity
|
|
102
|
-
- Circular determinate: no transition
|
|
103
|
-
- Circular indeterminate: no rotation/dash animation, shows static partial arc
|
|
104
|
-
|
|
105
|
-
- **Display modes**:
|
|
106
|
-
- Linear modes: `display: block` (full width)
|
|
107
|
-
- Circular modes: `display: inline-block` (sized to content)
|
|
108
|
-
|
|
109
|
-
- The component automatically switches render methods based on `mode` property
|
|
110
|
-
- Indeterminate modes ignore the `value` property
|
|
1
|
+
# rel-progress
|
|
2
|
+
|
|
3
|
+
`<rel-progress>` is the Figma "Progress" indicator in its two shapes and two behaviours: a full-width 6px linear bar or a 48px 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
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```html
|
|
8
|
+
<!-- Linear, determinate -->
|
|
9
|
+
<rel-progress mode="linear-determinate" value="45"></rel-progress>
|
|
10
|
+
<rel-progress mode="linear-determinate" value="100"></rel-progress>
|
|
11
|
+
|
|
12
|
+
<!-- Linear, indeterminate (loading) -->
|
|
13
|
+
<rel-progress mode="linear-indeterminate"></rel-progress>
|
|
14
|
+
|
|
15
|
+
<!-- Circular, determinate -->
|
|
16
|
+
<rel-progress mode="circular-determinate" value="75"></rel-progress>
|
|
17
|
+
|
|
18
|
+
<!-- Circular, indeterminate (spinner) -->
|
|
19
|
+
<rel-progress mode="circular-indeterminate"></rel-progress>
|
|
20
|
+
|
|
21
|
+
<!-- Accessible name -->
|
|
22
|
+
<rel-progress mode="linear-determinate" value="30" label="Uploading invoices"></rel-progress>
|
|
23
|
+
<rel-progress mode="circular-indeterminate" label="Loading shipments"></rel-progress>
|
|
24
|
+
|
|
25
|
+
<!-- Driving the value from script -->
|
|
26
|
+
<rel-progress id="uploadProgress" mode="linear-determinate" value="0" label="Upload"></rel-progress>
|
|
27
|
+
<script>
|
|
28
|
+
const progress = document.getElementById('uploadProgress');
|
|
29
|
+
let value = 0;
|
|
30
|
+
const interval = setInterval(() => {
|
|
31
|
+
value += 10;
|
|
32
|
+
progress.value = value;
|
|
33
|
+
if (value >= 100) clearInterval(interval);
|
|
34
|
+
}, 500);
|
|
35
|
+
</script>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
<!-- readme-gen:start -->
|
|
39
|
+
|
|
40
|
+
<!-- Generated from rel-progress.ts — do not edit; run readme-generate.mjs -->
|
|
41
|
+
|
|
42
|
+
## API
|
|
43
|
+
|
|
44
|
+
### Attributes / Properties
|
|
45
|
+
|
|
46
|
+
| Property | Attribute | Type | Default | Description |
|
|
47
|
+
| --- | --- | --- | --- | --- |
|
|
48
|
+
| `mode` | `mode` | `"linear-determinate" \| "linear-indeterminate" \| "circular-determinate" \| "circular-indeterminate"` | `"linear-determinate"` | Shape and behaviour: `linear-*` is a full-width 6px bar, `circular-*` a 48px ring; `*-determinate` fills to `value`, `*-indeterminate` loops an animation and ignores `value`. Reflected. |
|
|
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
|
+
| `label` | `label` | `string` | `""` | Accessible name of the progressbar (not rendered visually); defaults to "Progress" for determinate and "Loading" for indeterminate modes. |
|
|
51
|
+
|
|
52
|
+
## Events
|
|
53
|
+
|
|
54
|
+
| Event | Detail | Bubbles / composed | Description |
|
|
55
|
+
| --- | --- | --- | --- |
|
|
56
|
+
| — | — | — | This element emits no custom events. |
|
|
57
|
+
|
|
58
|
+
## Slots
|
|
59
|
+
|
|
60
|
+
| Slot | Description |
|
|
61
|
+
| --- | --- |
|
|
62
|
+
| — | This element has no slots. |
|
|
63
|
+
|
|
64
|
+
## CSS Parts
|
|
65
|
+
|
|
66
|
+
| Part | Description |
|
|
67
|
+
| --- | --- |
|
|
68
|
+
| `track` | The linear track `<div>` that carries `role="progressbar"` (linear modes only) |
|
|
69
|
+
| `indicator` | The filled / sliding bar inside the linear track (linear modes only) |
|
|
70
|
+
|
|
71
|
+
<!-- readme-gen:end -->
|
|
72
|
+
|
|
73
|
+
## Accessibility
|
|
74
|
+
|
|
75
|
+
- Every mode renders one element with `role="progressbar"` and an `aria-label` taken from `label`; when `label` is empty the name is "Progress" for determinate modes and "Loading" for indeterminate ones. Give it a specific `label` ("Uploading invoices") when more than one indicator can be on screen.
|
|
76
|
+
- Determinate modes also set `aria-valuenow` (the clamped `value`), `aria-valuemin="0"` and `aria-valuemax="100"`. Indeterminate modes omit the value attributes, which is what tells assistive technology the progress is unknown.
|
|
77
|
+
- The element is not focusable and handles no keys.
|
|
78
|
+
- It does not announce anything by itself: neither the start of loading nor reaching 100% is spoken. Announce those from the surrounding UI (for example with a status message) when they matter.
|
|
79
|
+
- `prefers-reduced-motion: reduce` is respected: the determinate transitions are removed, the linear indeterminate bar becomes a static full-width bar at 50% opacity, and the circular spinner stops rotating and shows a static partial arc.
|
|
80
|
+
|
|
81
|
+
## Notes / Edge Cases
|
|
82
|
+
|
|
83
|
+
- `value` is clamped to 0–100 before rendering and before `aria-valuenow`; the indeterminate modes ignore it entirely.
|
|
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 6px tall with a square radius and stretch to the host's width (host is `display: block`). Circular rings are fixed at 48px and the host switches to `display: inline-block`, so they sit inline with text.
|
|
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
|
+
- 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
|
+
- 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.
|
|
@@ -1,135 +1,131 @@
|
|
|
1
|
-
# rel-radio
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
```html
|
|
8
|
-
<!-- Basic
|
|
9
|
-
<rel-radio
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
<!--
|
|
32
|
-
<rel-radio id="
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
- The `
|
|
130
|
-
-
|
|
131
|
-
-
|
|
132
|
-
- The `error` property on `RadioOption` changes the radio button color to red but does not prevent selection
|
|
133
|
-
- Supporting text is optional and appears below the label with left margin alignment
|
|
134
|
-
- Native radio inputs are visually hidden but maintain all accessibility features
|
|
135
|
-
- The `name` attribute groups radios together for form submission and mutual exclusion
|
|
1
|
+
# rel-radio
|
|
2
|
+
|
|
3
|
+
`<rel-radio>` is the single-select radio group of the Reliability Design System (Figma "Radio"). One element is one group: it renders a native radio input for every entry in `options`, with optional supporting text and an icon or avatar prefix, in the Figma Size (S/M/L), Density (compact / comfortable) and Layout (leading / trailing) variants, plus error and disabled states. Use it when the user must pick exactly one of a few visible choices (2–7). For long lists use `<rel-select>`, for independent on/off choices use `<rel-checkbox>` or `<rel-switch>`.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```html
|
|
8
|
+
<!-- Basic group; options as a JSON attribute, preselected via selectedvalue -->
|
|
9
|
+
<rel-radio
|
|
10
|
+
name="color"
|
|
11
|
+
field-aria-label="Colour"
|
|
12
|
+
options='[{"value":"red","label":"Red"},{"value":"blue","label":"Blue"},{"value":"green","label":"Green"}]'
|
|
13
|
+
selectedvalue="blue"
|
|
14
|
+
></rel-radio>
|
|
15
|
+
|
|
16
|
+
<!-- Two independent groups on one page: give each its own name -->
|
|
17
|
+
<rel-radio id="plan" name="plan" field-aria-label="Plan"></rel-radio>
|
|
18
|
+
<rel-radio id="billing" name="billing" field-aria-label="Billing cycle" orientation="horizontal"></rel-radio>
|
|
19
|
+
|
|
20
|
+
<!-- Sizes (S and M share the 20px control; L is 24px) -->
|
|
21
|
+
<rel-radio id="small" name="size-small" size="small"></rel-radio>
|
|
22
|
+
<rel-radio id="medium" name="size-medium" size="medium"></rel-radio>
|
|
23
|
+
<rel-radio id="large" name="size-large" size="large"></rel-radio>
|
|
24
|
+
|
|
25
|
+
<!-- Supporting text beside the control instead of on its own line -->
|
|
26
|
+
<rel-radio id="comfortable" name="tier" density="comfortable"></rel-radio>
|
|
27
|
+
|
|
28
|
+
<!-- Control on the far edge of each row (always comfortable density) -->
|
|
29
|
+
<rel-radio id="trailing" name="notify" alignment="trailing"></rel-radio>
|
|
30
|
+
|
|
31
|
+
<!-- Error state with a message; disabled group -->
|
|
32
|
+
<rel-radio id="consent" name="consent" error errormessage="Choose one option to continue"></rel-radio>
|
|
33
|
+
<rel-radio id="locked" name="locked" disabled></rel-radio>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```js
|
|
37
|
+
const plan = document.getElementById("plan");
|
|
38
|
+
plan.options = [
|
|
39
|
+
{ value: "basic", label: "Basic", supportingText: "$9.99 / month" },
|
|
40
|
+
{ value: "pro", label: "Pro", supportingText: "$19.99 / month", icon: "settings" },
|
|
41
|
+
{ value: "team", label: "Team", avatar: "TM" },
|
|
42
|
+
{ value: "enterprise", label: "Enterprise", supportingText: "Contact sales", disabled: true },
|
|
43
|
+
];
|
|
44
|
+
plan.selectedValue = "basic";
|
|
45
|
+
|
|
46
|
+
plan.addEventListener("rel-change", (e) => {
|
|
47
|
+
e.detail.value; // "pro" — the selected option's value
|
|
48
|
+
e.detail.checked; // always true
|
|
49
|
+
plan.selectedValue === e.detail.value; // already updated
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
<!-- readme-gen:start -->
|
|
54
|
+
|
|
55
|
+
<!-- Generated from rel-radio.ts — do not edit; run readme-generate.mjs -->
|
|
56
|
+
|
|
57
|
+
## API
|
|
58
|
+
|
|
59
|
+
### Attributes / Properties
|
|
60
|
+
|
|
61
|
+
| Property | Attribute | Type | Default | Description |
|
|
62
|
+
| --- | --- | --- | --- | --- |
|
|
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
|
+
| `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
|
+
| `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 (Figma Size). `"medium"` (default, Figma M) = 20px control with body-lg labels; `"large"` (Figma L) = 24px control with body-xl labels; `"small"` (Figma S) = 20px control with body-md labels — S and M share the control size in the spec, only typography steps down. Reflected. |
|
|
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
|
+
| `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
|
+
| `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. |
|
|
70
|
+
| `disabled` | `disabled` | `boolean` | `false` | Disables every option (Figma State=Disabled: the whole group at 40% opacity). Individual options can also be disabled via `RadioOption.disabled`. |
|
|
71
|
+
| `error` | `error` | `boolean` | `false` | Error state (Figma State=Error): rings, dots and supporting text turn danger. Applies to every option while nothing is selected, and only to the selected option once a choice is made. Selection is still allowed. |
|
|
72
|
+
| `errorMessage` | `errormessage` | `string` | `""` | Message rendered under the group (live region) while `error` is set; hidden when `error` is false or the text is empty. |
|
|
73
|
+
| `fieldAriaLabel` | `field-aria-label` | `string` | `undefined` | Accessible name for the radiogroup (it renders no visible group label). |
|
|
74
|
+
| `value` | `value` | `string` | `""` | Value reported to the Angular forms bridge (`registerOnChange` callback) on each change and compared by `writeValue`. Not used for rendering; read `selectedValue` or the `rel-change` detail for the selected option. |
|
|
75
|
+
|
|
76
|
+
### Public fields / accessors
|
|
77
|
+
|
|
78
|
+
| Name | Type | Description |
|
|
79
|
+
| --- | --- | --- |
|
|
80
|
+
| `checked` | `boolean` | Set by the Angular forms bridge (`writeValue`) to whether the written form value equals `value`. Not used for rendering — read `selectedValue` for the selection. |
|
|
81
|
+
|
|
82
|
+
## Events
|
|
83
|
+
|
|
84
|
+
| Event | Detail | Bubbles / composed | Description |
|
|
85
|
+
| --- | --- | --- | --- |
|
|
86
|
+
| `rel-change` | `{ value, checked: true }` | bubbles / composed | Fired when the user selects an option (after `selectedValue` is updated). Detail: `{ value: string, checked: true }` — `value` is the selected option's value. |
|
|
87
|
+
|
|
88
|
+
## Slots
|
|
89
|
+
|
|
90
|
+
| Slot | Description |
|
|
91
|
+
| --- | --- |
|
|
92
|
+
| — | This element has no slots. |
|
|
93
|
+
|
|
94
|
+
## CSS Parts
|
|
95
|
+
|
|
96
|
+
| Part | Description |
|
|
97
|
+
| --- | --- |
|
|
98
|
+
| `label` | The visible label text of each option |
|
|
99
|
+
| `base` | The `role="radiogroup"` container that lays out the options |
|
|
100
|
+
|
|
101
|
+
<!-- readme-gen:end -->
|
|
102
|
+
|
|
103
|
+
## Accessibility
|
|
104
|
+
|
|
105
|
+
- The option container (part `base`) is a `role="radiogroup"` with `aria-orientation` = `orientation`, `aria-label` = `field-aria-label` (set it — the group renders no visible legend) and `aria-describedby` pointing at the error line.
|
|
106
|
+
- Every option is a native `<input type="radio">` inside a `<label>`, so the whole row (control, label, supporting text) is the click target and the input's accessible name is the option label. The input is visually hidden (`opacity: 0`, absolutely positioned over the row) but stays in the Tab order; the drawn ring / dot mirror its `:checked` state.
|
|
107
|
+
- Disabled options get the native `disabled` attribute (skipped by Tab and arrow keys) and render at 40% opacity; `disabled` on the host disables all of them.
|
|
108
|
+
- The error message is a persistent `aria-live="polite"` region under the group, so a message that appears after submission is read out.
|
|
109
|
+
- Avatar chips are `aria-hidden`; a prefix icon is a `<rel-icon>` and decorative.
|
|
110
|
+
- Keyboard focus is shown as a 1.5px `--rel-border-focus` outline (1px offset) around the focused option; it appears only for `:focus-visible` (keyboard) focus.
|
|
111
|
+
- Keyboard behaviour is the browser's native radio behaviour — the component adds no key handlers of its own:
|
|
112
|
+
|
|
113
|
+
| Key | Action |
|
|
114
|
+
| --- | --- |
|
|
115
|
+
| Tab / Shift + Tab | Enter the group (on the checked option, else the first enabled one) or leave it |
|
|
116
|
+
| ArrowDown / ArrowRight | Move to the next enabled option and select it (fires `rel-change`) |
|
|
117
|
+
| ArrowUp / ArrowLeft | Move to the previous enabled option and select it (fires `rel-change`) |
|
|
118
|
+
| Space | Select the focused option if it is not yet selected |
|
|
119
|
+
|
|
120
|
+
## Notes / Edge Cases
|
|
121
|
+
|
|
122
|
+
- `RadioOption` shape: `{ value: string; label: string; supportingText?: string; disabled?: boolean; icon?: string; avatar?: string }`. `icon` is a `rel-icon` name rendered before the label (Figma Has Icon/Avatar, Type=Icon); `avatar` is 1–2 initials rendered as a circular chip and is ignored when `icon` is also set.
|
|
123
|
+
- `rel-change` fires only on user selection. Setting `selectedValue` from code (or via the `selectedvalue` attribute) updates the UI silently.
|
|
124
|
+
- Grouping by `name`: the native inputs of one `<rel-radio>` share `name`, which is what gives arrow-key movement and mutual exclusion; they live in the element's shadow root, so they are not submitted with a surrounding `<form>`. Read `selectedValue` or listen to `rel-change` to collect the value. Give every group on a page its own `name` so the intent is unambiguous.
|
|
125
|
+
- Error rules: while nothing is selected, every option shows the danger ring; once an option is selected only that option does. Labels keep their default colour; rings, dots and supporting text turn `--rel-border-danger` / `--rel-text-danger`. Error never blocks selection.
|
|
126
|
+
- `alignment="trailing"` always renders comfortable density. Combining it with `density="compact"` logs `[rel-radio] density="compact" has no trailing layout; rendering comfortable density.` (a `console.warn`, every time either prop changes).
|
|
127
|
+
- Compact supporting text is indented past the control box: 28px (S/M) and 32px (L). Comfortable density widens the control-to-label gap from 8px to 12px.
|
|
128
|
+
- Hover shifts the ring, dot, label and prefix icon from `--rel-text-default` to `--rel-text-body` on enabled, non-error options.
|
|
129
|
+
- `value` and `checked` exist for the Angular forms bridge (`registerOnChange` / `registerOnTouched` / `writeValue`, which are internal API). The bridge callback receives the `value` property, not the selected option — plain DOM consumers should ignore both and use `selectedValue` / `rel-change`.
|
|
130
|
+
- `<rel-menu type="select-option">` renders an `inert`, `aria-hidden` `<rel-radio>` inside each row purely as a visual control; that usage does not fire `rel-change`.
|
|
131
|
+
- The hidden native input is absolutely positioned inside a `position: relative` row on purpose — without that containing block, tabbing to it scrolls the wrong ancestor and jumps the page (shared fix with `rel-checkbox`).
|