@reliability-design/web 1.4.6 → 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 -138
- 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 -111
- package/dist/components/rel-upload/README.md +220 -0
- package/dist/index.d.mts +1147 -340
- package/dist/index.d.ts +1147 -340
- package/dist/index.js +3451 -3163
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3416 -3118
- 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 +3 -2
- 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 -720
- package/dist/components/rel-avatar/rel-avatar.ts +0 -142
- package/dist/components/rel-badge/rel-badge.ts +0 -175
- 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 -565
- 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 -723
- 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 -483
- 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/date-parse.test.ts +0 -116
- package/dist/components/rel-date-picker/date-parse.ts +0 -178
- package/dist/components/rel-date-picker/index.ts +0 -1
- package/dist/components/rel-date-picker/rel-date-picker.ts +0 -1676
- 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 -607
- 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 -541
- 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 -527
- package/dist/components/rel-pagination/index.ts +0 -1
- package/dist/components/rel-pagination/rel-pagination.ts +0 -522
- 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 -475
- package/dist/components/rel-progress/rel-progress.ts +0 -234
- package/dist/components/rel-radio/rel-radio.ts +0 -481
- package/dist/components/rel-range-picker/rel-range-picker.ts +0 -1688
- 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 -217
- package/dist/components/rel-select/rel-select.ts +0 -1416
- package/dist/components/rel-sheet/rel-sheet.ts +0 -610
- package/dist/components/rel-sidebar/README.md +0 -209
- package/dist/components/rel-sidebar/rel-sidebar.ts +0 -1191
- package/dist/components/rel-skeleton/rel-skeleton.ts +0 -143
- package/dist/components/rel-slider/rel-slider.ts +0 -673
- package/dist/components/rel-snackbar/rel-snackbar.ts +0 -329
- package/dist/components/rel-stepper/rel-stepper.ts +0 -567
- package/dist/components/rel-switch/rel-switch.ts +0 -199
- 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 -1054
- package/dist/components/rel-time-picker/rel-time-picker.ts +0 -1482
- package/dist/components/rel-time-picker/time-parse.test.ts +0 -67
- package/dist/components/rel-time-picker/time-parse.ts +0 -85
- package/dist/components/rel-toast/rel-toast.ts +0 -206
- package/dist/components/rel-tooltip/rel-tooltip.ts +0 -193
- 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 -968
|
@@ -1,160 +1,158 @@
|
|
|
1
|
-
# rel-stepper
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
```html
|
|
8
|
-
<!--
|
|
9
|
-
<rel-stepper id="checkout"></rel-stepper>
|
|
10
|
-
<script>
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
{ title: '
|
|
14
|
-
{ title: '
|
|
15
|
-
{ title: '
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
<rel-stepper
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
{ title: '
|
|
46
|
-
{ title: '
|
|
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
|
-
|
|
132
|
-
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
-
|
|
156
|
-
-
|
|
157
|
-
-
|
|
158
|
-
-
|
|
159
|
-
- The component uses flexbox extensively for layout management
|
|
160
|
-
- The stepper is `display: block` and `width: 100%`
|
|
1
|
+
# rel-stepper
|
|
2
|
+
|
|
3
|
+
A multi-step progress indicator implementing the Figma "Stepper" component: its `Type` axis (default, dot, number, icon indicators), its `Typel` label-placement axis (top, centered, inverted), two sizes and both orientations. Each entry in `steps` renders as a focusable step with a circular indicator, a label and a connector to the next step, styled by its status (`done`, `progress`, `disabled`). Use it to show where the user is in a linear flow (checkout, onboarding, a wizard) and to let them jump back to completed steps; the component is presentation only — it never changes a step's status itself, so drive `steps` from your own state.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```html
|
|
8
|
+
<!-- Horizontal (default), labels under the indicators -->
|
|
9
|
+
<rel-stepper id="checkout"></rel-stepper>
|
|
10
|
+
<script>
|
|
11
|
+
document.getElementById('checkout').steps = [
|
|
12
|
+
{ title: 'Cart', status: 'done' },
|
|
13
|
+
{ title: 'Shipping', status: 'progress' },
|
|
14
|
+
{ title: 'Payment', status: 'disabled' },
|
|
15
|
+
{ title: 'Confirmation', status: 'disabled' }
|
|
16
|
+
];
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<!-- Vertical, small, label beside the indicator (Figma Typel = Centered) -->
|
|
20
|
+
<rel-stepper id="onboarding" orientation="vertical" label-placement="centered" size="small"></rel-stepper>
|
|
21
|
+
<script>
|
|
22
|
+
document.getElementById('onboarding').steps = [
|
|
23
|
+
{ title: 'Create account', status: 'done' },
|
|
24
|
+
{ title: 'Verify email', status: 'done' },
|
|
25
|
+
{ title: 'Set up profile', status: 'progress' },
|
|
26
|
+
{ title: 'Done', status: 'disabled' }
|
|
27
|
+
];
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<!-- Figma Type axis: dot / number / icon indicators -->
|
|
31
|
+
<rel-stepper type="dot" steps='[{"title":"Plan","status":"done"},{"title":"Build","status":"progress"},{"title":"Ship","status":"disabled"}]'></rel-stepper>
|
|
32
|
+
<rel-stepper type="number" steps='[{"title":"Plan","status":"done"},{"title":"Build","status":"progress"},{"title":"Ship","status":"disabled"}]'></rel-stepper>
|
|
33
|
+
<rel-stepper type="icon" steps='[{"title":"Plan","status":"done"},{"title":"Build","status":"progress"},{"title":"Ship","status":"disabled"}]'></rel-stepper>
|
|
34
|
+
|
|
35
|
+
<!-- Label placement (Figma Typel): top-aligned beside the indicator, or indicator above the label -->
|
|
36
|
+
<rel-stepper orientation="vertical" label-placement="top" steps='[{"title":"Review","status":"done"},{"title":"Approve","status":"progress"}]'></rel-stepper>
|
|
37
|
+
<rel-stepper label-placement="inverted" steps='[{"title":"Review","status":"done"},{"title":"Approve","status":"progress"}]'></rel-stepper>
|
|
38
|
+
|
|
39
|
+
<!-- Let users jump back to a completed step -->
|
|
40
|
+
<rel-stepper id="wizard"></rel-stepper>
|
|
41
|
+
<script>
|
|
42
|
+
const wizard = document.getElementById('wizard');
|
|
43
|
+
wizard.steps = [
|
|
44
|
+
{ title: 'Select', status: 'done' },
|
|
45
|
+
{ title: 'Configure', status: 'progress' },
|
|
46
|
+
{ title: 'Review', status: 'disabled' }
|
|
47
|
+
];
|
|
48
|
+
wizard.addEventListener('rel-step-change', (e) => {
|
|
49
|
+
console.log('Activated step', e.detail.index, e.detail.step.title);
|
|
50
|
+
// Recompute statuses and assign a new array so the stepper re-renders
|
|
51
|
+
wizard.steps = wizard.steps.map((s, i) => ({
|
|
52
|
+
...s,
|
|
53
|
+
status: i < e.detail.index ? 'done' : i === e.detail.index ? 'progress' : 'disabled'
|
|
54
|
+
}));
|
|
55
|
+
});
|
|
56
|
+
</script>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Deprecated aliases
|
|
60
|
+
|
|
61
|
+
```html
|
|
62
|
+
<!-- textalign="right" → label-placement="centered"; textalign="below" → label-placement="inverted".
|
|
63
|
+
Still supported and still the fallback when label-placement is unset; no console notice is logged. -->
|
|
64
|
+
<rel-stepper textalign="right" steps='[{"title":"Review","status":"done"},{"title":"Approve","status":"progress"}]'></rel-stepper>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
The `Step` type and the `StepStatus`, `StepperType` and `LabelPlacement` unions are exported from the package:
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import type { Step } from '@reliability-design/web';
|
|
71
|
+
|
|
72
|
+
const steps: Step[] = [
|
|
73
|
+
{ title: 'Cart', status: 'done' }, // filled indicator with a check mark
|
|
74
|
+
{ title: 'Shipping', status: 'progress' }, // current step (aria-current="step")
|
|
75
|
+
{ title: 'Payment', status: 'disabled' } // not yet reachable; rendered at 40% opacity, not focusable
|
|
76
|
+
];
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
<!-- readme-gen:start -->
|
|
80
|
+
|
|
81
|
+
<!-- Generated from rel-stepper.ts — do not edit; run readme-generate.mjs -->
|
|
82
|
+
|
|
83
|
+
## API
|
|
84
|
+
|
|
85
|
+
### Attributes / Properties
|
|
86
|
+
|
|
87
|
+
| Property | Attribute | Type | Default | Description |
|
|
88
|
+
| --- | --- | --- | --- | --- |
|
|
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. |
|
|
90
|
+
| `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
|
+
| `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
|
+
| `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
|
+
|
|
95
|
+
#### Deprecated (still supported — removal targeted for 3.0)
|
|
96
|
+
|
|
97
|
+
| Property | Attribute | Type | Use instead |
|
|
98
|
+
| --- | --- | --- | --- |
|
|
99
|
+
| `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"`. |
|
|
100
|
+
|
|
101
|
+
## Events
|
|
102
|
+
|
|
103
|
+
| Event | Detail | Bubbles / composed | Description |
|
|
104
|
+
| --- | --- | --- | --- |
|
|
105
|
+
| `rel-step-change` | `{ index, step, }` | bubbles / composed | Fired when a step whose status is not `disabled` is clicked or activated with Enter / Space. Detail: `{ index: number, step: Step }`. Statuses are not changed by the component — update `steps` in the handler. |
|
|
106
|
+
|
|
107
|
+
## Slots
|
|
108
|
+
|
|
109
|
+
| Slot | Description |
|
|
110
|
+
| --- | --- |
|
|
111
|
+
| — | This element has no slots. |
|
|
112
|
+
|
|
113
|
+
## CSS Parts
|
|
114
|
+
|
|
115
|
+
| Part | Description |
|
|
116
|
+
| --- | --- |
|
|
117
|
+
| `indicator` | The 24px circle (8px for `type="dot"`) that holds the step number, check mark or icon. |
|
|
118
|
+
| `track` | The 1px connector line from a step to the next one (not rendered on the last step). |
|
|
119
|
+
| `label` | The step title text. |
|
|
120
|
+
|
|
121
|
+
## Tokens / CSS Variables
|
|
122
|
+
|
|
123
|
+
### Component hooks
|
|
124
|
+
|
|
125
|
+
Set these on the host (or an ancestor) to customise the element without touching design tokens.
|
|
126
|
+
|
|
127
|
+
| Custom property | Default | Description |
|
|
128
|
+
| --- | --- | --- |
|
|
129
|
+
| `--rel-stepper-connector-length-lg` | `86px` | Connector length and step gap for `size="large"` in both orientations (default 86px). |
|
|
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). |
|
|
132
|
+
| `--rel-stepper-indicator-size` | `24px` | Indicator diameter (default 24px; `type="dot"` is fixed at 8px). |
|
|
133
|
+
|
|
134
|
+
<!-- readme-gen:end -->
|
|
135
|
+
|
|
136
|
+
## Accessibility
|
|
137
|
+
|
|
138
|
+
- The list renders as a `role="group"` with the fixed name "Progress steps" (not configurable).
|
|
139
|
+
- Every step is a `role="button"` element with `aria-label="<title>, step n of N"`, plus ", completed" for `done` steps. The `progress` step carries `aria-current="step"`; `disabled` steps carry `aria-disabled="true"` and `tabindex="-1"` so they are skipped in the Tab order and by the arrow keys.
|
|
140
|
+
- Enabled steps are individual Tab stops (`tabindex="0"`) with a 2px focus ring; the indicators and connectors are purely visual (the check mark SVG is `aria-hidden`).
|
|
141
|
+
- Activating a step only emits `rel-step-change`; nothing is announced and no status changes until you update `steps`.
|
|
142
|
+
|
|
143
|
+
| Key | Action |
|
|
144
|
+
| --- | --- |
|
|
145
|
+
| `Enter` / `Space` | Activate the focused step (emits `rel-step-change`; ignored on `disabled` steps) |
|
|
146
|
+
| `ArrowRight` / `ArrowDown` | Move focus to the next enabled step (wraps to the first) |
|
|
147
|
+
| `ArrowLeft` / `ArrowUp` | Move focus to the previous enabled step (wraps to the last) |
|
|
148
|
+
| `Home` / `End` | Move focus to the first / last enabled step |
|
|
149
|
+
|
|
150
|
+
## Notes / Edge Cases
|
|
151
|
+
|
|
152
|
+
- `label-placement` is the canonical layout switch (Figma `Typel`). When it is unset the deprecated `textalign` prop decides: `below` renders like `inverted` (indicator above the label), `right` renders like `centered` (label beside the indicator). `top` differs from `centered` only in aligning the label to the top of the indicator. Figma marks Top + Horizontal as an unsupported combination.
|
|
153
|
+
- Statuses map to the Figma `.Artwork` states: `done` = inverse fill with a check mark (or the number when `type="number"`, nothing when `type="dot"`), `progress` = neutral fill with a strong 1px border, `disabled` = the same drawn at 40% opacity. Connectors are `border-strong` after a `done` / `progress` step and `border-default` otherwise.
|
|
154
|
+
- `type="icon"` shows the check mark on every step regardless of status; `type="dot"` shrinks the indicator to 8px and fills it for `done` and `progress`.
|
|
155
|
+
- Connector length doubles as the gap between steps and depends on `size` and `orientation`: large = `--rel-stepper-connector-length-lg` (86px) in both orientations; small horizontal = `--rel-stepper-connector-length-md` (60px); small vertical = `--rel-stepper-connector-length-sm` (42px). Note the `md` / `sm` suffixes refer to those defaults, not to a size value.
|
|
156
|
+
- Labels never wrap (`white-space: nowrap`); keep titles short or widen the connector hooks.
|
|
157
|
+
- `steps` is compared by reference: mutate-in-place changes are not picked up — assign a new array.
|
|
158
|
+
- Steps are `<div role="button">` elements, not native buttons, so they do not submit forms and do not get native disabled styling.
|
|
@@ -1,102 +1,108 @@
|
|
|
1
|
-
# rel-switch
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
```html
|
|
8
|
-
<!-- Basic
|
|
9
|
-
<rel-switch></rel-switch>
|
|
10
|
-
|
|
11
|
-
<!--
|
|
12
|
-
<rel-switch checked></rel-switch>
|
|
13
|
-
|
|
14
|
-
<!-- Disabled
|
|
15
|
-
<rel-switch disabled></rel-switch>
|
|
16
|
-
<rel-switch checked disabled></rel-switch>
|
|
17
|
-
|
|
18
|
-
<!--
|
|
19
|
-
<rel-switch
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
<
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
</script>
|
|
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
|
-
|
|
1
|
+
# rel-switch
|
|
2
|
+
|
|
3
|
+
`<rel-switch>` implements the Figma **Switch** component (5917:1174, Type=Line): a 44×20 toggle with a thin 10px track and a 20px handle that slides 20px, with hover, focused, pressed and disabled states from the Figma State axis. It wraps a native checkbox with `role="switch"`, so keyboard and screen-reader behaviour are native. Use it for settings that take effect immediately (notifications on/off, dark mode); for choices that are collected and submitted with a form use `<rel-checkbox>`.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```html
|
|
8
|
+
<!-- Basic -->
|
|
9
|
+
<rel-switch field-aria-label="Email notifications"></rel-switch>
|
|
10
|
+
|
|
11
|
+
<!-- On by default -->
|
|
12
|
+
<rel-switch checked field-aria-label="Dark mode"></rel-switch>
|
|
13
|
+
|
|
14
|
+
<!-- Disabled, off and on -->
|
|
15
|
+
<rel-switch disabled field-aria-label="Locked setting"></rel-switch>
|
|
16
|
+
<rel-switch checked disabled field-aria-label="Locked setting"></rel-switch>
|
|
17
|
+
|
|
18
|
+
<!-- One handler for several switches: `value` is echoed in the event detail -->
|
|
19
|
+
<rel-switch value="marketing" field-aria-label="Marketing emails"></rel-switch>
|
|
20
|
+
<rel-switch value="product" field-aria-label="Product updates"></rel-switch>
|
|
21
|
+
<script>
|
|
22
|
+
document.addEventListener('rel-change', (e) => {
|
|
23
|
+
if (e.target.tagName !== 'REL-SWITCH') return;
|
|
24
|
+
console.log(e.detail.value, e.detail.checked); // "marketing", true
|
|
25
|
+
});
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<!-- Programmatic control (no event is fired) -->
|
|
29
|
+
<rel-switch id="wifi" field-aria-label="Wi-Fi"></rel-switch>
|
|
30
|
+
<script>
|
|
31
|
+
const wifi = document.getElementById('wifi');
|
|
32
|
+
wifi.checked = true;
|
|
33
|
+
</script>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
<!-- readme-gen:start -->
|
|
37
|
+
|
|
38
|
+
<!-- Generated from rel-switch.ts — do not edit; run readme-generate.mjs -->
|
|
39
|
+
|
|
40
|
+
## API
|
|
41
|
+
|
|
42
|
+
### Attributes / Properties
|
|
43
|
+
|
|
44
|
+
| Property | Attribute | Type | Default | Description |
|
|
45
|
+
| --- | --- | --- | --- | --- |
|
|
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
|
+
| `disabled` | `disabled` | `boolean` | `false` | Disables interaction, dims the control to 50% and removes the handle shadow. |
|
|
48
|
+
| `value` | `value` | `string` | `""` | Arbitrary string echoed in the `rel-change` event detail — useful when one handler serves several switches. |
|
|
49
|
+
| `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. |
|
|
50
|
+
|
|
51
|
+
## Events
|
|
52
|
+
|
|
53
|
+
| Event | Detail | Bubbles / composed | Description |
|
|
54
|
+
| --- | --- | --- | --- |
|
|
55
|
+
| `rel-change` | `{ checked: this.checked, value: this.value, }` | bubbles / composed | Fired when the user toggles the switch (not on programmatic `checked` changes). Detail: `{ checked: boolean, value: string }`. |
|
|
56
|
+
|
|
57
|
+
## Slots
|
|
58
|
+
|
|
59
|
+
| Slot | Description |
|
|
60
|
+
| --- | --- |
|
|
61
|
+
| — | This element has no slots. |
|
|
62
|
+
|
|
63
|
+
## CSS Parts
|
|
64
|
+
|
|
65
|
+
| Part | Description |
|
|
66
|
+
| --- | --- |
|
|
67
|
+
| `base` | The `<label>` wrapper around the hidden input and the track |
|
|
68
|
+
| `track` | The thin rail; the handle is its `::before` pseudo-element |
|
|
69
|
+
|
|
70
|
+
## Tokens / CSS Variables
|
|
71
|
+
|
|
72
|
+
### Component hooks
|
|
73
|
+
|
|
74
|
+
Set these on the host (or an ancestor) to customise the element without touching design tokens.
|
|
75
|
+
|
|
76
|
+
| Custom property | Default | Description |
|
|
77
|
+
| --- | --- | --- |
|
|
78
|
+
| `--rel-switch-disabled` | `var(--switch-disabled)` | Handle colour while disabled; default `var(--rel-bg-neutral-elevated-1)` |
|
|
79
|
+
| `--rel-switch-knob-off` | `var(--switch-knob-off)` | Handle colour when unchecked; default `var(--rel-text-static-light)` |
|
|
80
|
+
| `--rel-switch-knob-on` | `var(--switch-knob-on)` | Handle colour when checked; default `var(--rel-bg-neutral-inverse-2)` |
|
|
81
|
+
| `--rel-switch-thumb-size` | `20px` | Handle diameter; default 20px (the handle always travels 20px) |
|
|
82
|
+
| `--rel-switch-track` | `var(--switch-track)` | Rail colour; default `var(--rel-bg-neutral-elevated-2)` |
|
|
83
|
+
| `--rel-switch-track-height` | `20px` | Overall control height; default 20px |
|
|
84
|
+
| `--rel-switch-track-width` | `44px` | Overall control width; default 44px |
|
|
85
|
+
|
|
86
|
+
<!-- readme-gen:end -->
|
|
87
|
+
|
|
88
|
+
## Accessibility
|
|
89
|
+
|
|
90
|
+
- Renders a native `<input type="checkbox" role="switch">` with `aria-checked` mirroring `checked`; the input is visually hidden (opacity 0, zero size) inside a `<label part="base">`, so clicking anywhere on the control toggles it.
|
|
91
|
+
- `field-aria-label` becomes the input's `aria-label`. The input lives in the shadow root, so an external `<label for>` cannot reference it — set `field-aria-label` for the accessible name and place any visible text beside the switch.
|
|
92
|
+
- Focus: the wrapper shows a 1.5px focus outline whenever the input is focused (mouse or keyboard).
|
|
93
|
+
- `disabled` disables the native input (removed from the tab order), dims the control to 50% and drops the handle shadow.
|
|
94
|
+
- `prefers-reduced-motion: reduce` removes the track and handle transitions.
|
|
95
|
+
|
|
96
|
+
| Key | Action |
|
|
97
|
+
| --- | --- |
|
|
98
|
+
| `Space` | Toggles the switch (native checkbox behaviour). |
|
|
99
|
+
| `Tab` / `Shift+Tab` | Moves focus to / from the switch. |
|
|
100
|
+
|
|
101
|
+
## Notes / Edge Cases
|
|
102
|
+
|
|
103
|
+
- `rel-change` fires for user toggles only; setting `checked` from JavaScript updates the visuals but emits nothing.
|
|
104
|
+
- Geometry is fixed to the Figma Line switch: 44×20 control, 40×10 track inset 2px, 20px handle. The handle always travels 20px, so changing `--rel-switch-track-width` widens the control without moving the "on" position.
|
|
105
|
+
- Figma's default Type=Pill switch (44×24 filled track with the handle inside) is not implemented.
|
|
106
|
+
- 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
|
+
- 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.
|
|
108
|
+
- `registerOnChange`, `registerOnTouched` and `writeValue` exist for the Angular `ControlValueAccessor` wrapper and are not public API.
|