@reliability-design/web 1.4.6 → 1.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/CHANGELOG.md +246 -49
  2. package/dist/components/rel-accordion/README.md +133 -132
  3. package/dist/components/rel-alert/README.md +145 -141
  4. package/dist/components/rel-autocomplete/README.md +172 -61
  5. package/dist/components/rel-avatar/README.md +118 -130
  6. package/dist/components/rel-badge/README.md +97 -93
  7. package/dist/components/rel-breadcrumb/README.md +96 -102
  8. package/dist/components/rel-button/README.md +190 -130
  9. package/dist/components/rel-calendar/README.md +109 -109
  10. package/dist/components/rel-card/README.md +75 -94
  11. package/dist/components/rel-cardmedia/README.md +100 -127
  12. package/dist/components/rel-carousel/README.md +186 -166
  13. package/dist/components/rel-checkbox/README.md +96 -75
  14. package/dist/components/rel-chip/README.md +138 -121
  15. package/dist/components/rel-container/README.md +107 -99
  16. package/dist/components/rel-date-picker/README.md +200 -289
  17. package/dist/components/rel-divider/README.md +88 -100
  18. package/dist/components/rel-drawer/README.md +187 -200
  19. package/dist/components/rel-kbd/README.md +141 -151
  20. package/dist/components/rel-layout/README.md +34 -0
  21. package/dist/components/rel-menu/README.md +180 -151
  22. package/dist/components/rel-menubar/README.md +218 -329
  23. package/dist/components/rel-otp/README.md +171 -440
  24. package/dist/components/rel-pagination/README.md +100 -424
  25. package/dist/components/rel-popover/README.md +203 -568
  26. package/dist/components/rel-progress/README.md +88 -110
  27. package/dist/components/rel-radio/README.md +131 -138
  28. package/dist/components/rel-range-picker/README.md +165 -0
  29. package/dist/components/rel-resizable/README.md +199 -140
  30. package/dist/components/rel-segmented-button/README.md +156 -141
  31. package/dist/components/rel-select/README.md +156 -93
  32. package/dist/components/rel-sheet/README.md +168 -224
  33. package/dist/components/rel-skeleton/README.md +104 -0
  34. package/dist/components/rel-slider/README.md +131 -135
  35. package/dist/components/rel-snackbar/README.md +168 -134
  36. package/dist/components/rel-stepper/README.md +162 -160
  37. package/dist/components/rel-switch/README.md +117 -102
  38. package/dist/components/rel-tab/README.md +173 -163
  39. package/dist/components/rel-textfield/README.md +176 -69
  40. package/dist/components/rel-time-picker/README.md +122 -157
  41. package/dist/components/rel-toast/README.md +165 -148
  42. package/dist/components/rel-tooltip/README.md +119 -111
  43. package/dist/components/rel-upload/README.md +220 -0
  44. package/dist/index.d.mts +1726 -447
  45. package/dist/index.d.ts +1726 -447
  46. package/dist/index.js +13715 -10870
  47. package/dist/index.js.map +1 -1
  48. package/dist/index.mjs +14018 -11163
  49. package/dist/index.mjs.map +1 -1
  50. package/dist/styles/focus-ring.ts +84 -0
  51. package/dist/styles/vars.css +892 -866
  52. package/dist/{vars-XNMTSRVN.css → vars-DXX6QOAG.css} +892 -866
  53. package/package.json +3 -2
  54. package/dist/components/rel-accordion/rel-accordion.ts +0 -336
  55. package/dist/components/rel-alert/rel-alert.ts +0 -305
  56. package/dist/components/rel-autocomplete/rel-autocomplete.ts +0 -720
  57. package/dist/components/rel-avatar/rel-avatar.ts +0 -142
  58. package/dist/components/rel-badge/rel-badge.ts +0 -175
  59. package/dist/components/rel-breadcrumb/rel-breadcrumb.ts +0 -106
  60. package/dist/components/rel-button/rel-button.ts +0 -560
  61. package/dist/components/rel-calendar/index.ts +0 -1
  62. package/dist/components/rel-calendar/rel-calendar.ts +0 -565
  63. package/dist/components/rel-card/rel-card.ts +0 -88
  64. package/dist/components/rel-cardmedia/rel-cardmedia.ts +0 -88
  65. package/dist/components/rel-carousel/index.ts +0 -1
  66. package/dist/components/rel-carousel/rel-carousel.ts +0 -723
  67. package/dist/components/rel-chart/README.md +0 -286
  68. package/dist/components/rel-chart/index.ts +0 -1
  69. package/dist/components/rel-chart/rel-chart.ts +0 -754
  70. package/dist/components/rel-checkbox/rel-checkbox.ts +0 -382
  71. package/dist/components/rel-chip/rel-chip.ts +0 -483
  72. package/dist/components/rel-container/rel-container.ts +0 -95
  73. package/dist/components/rel-date-picker/date-format.test.ts +0 -43
  74. package/dist/components/rel-date-picker/date-format.ts +0 -47
  75. package/dist/components/rel-date-picker/date-parse.test.ts +0 -116
  76. package/dist/components/rel-date-picker/date-parse.ts +0 -178
  77. package/dist/components/rel-date-picker/index.ts +0 -1
  78. package/dist/components/rel-date-picker/rel-date-picker.ts +0 -1676
  79. package/dist/components/rel-divider/rel-divider.ts +0 -54
  80. package/dist/components/rel-drawer/index.ts +0 -1
  81. package/dist/components/rel-drawer/rel-drawer-footer.ts +0 -27
  82. package/dist/components/rel-drawer/rel-drawer.ts +0 -607
  83. package/dist/components/rel-kbd/rel-kbd.ts +0 -188
  84. package/dist/components/rel-layout/rel-layout.ts +0 -49
  85. package/dist/components/rel-menu/rel-menu.ts +0 -541
  86. package/dist/components/rel-menubar/index.ts +0 -2
  87. package/dist/components/rel-menubar/rel-menubar-menu.css +0 -3
  88. package/dist/components/rel-menubar/rel-menubar-menu.ts +0 -17
  89. package/dist/components/rel-menubar/rel-menubar.ts +0 -777
  90. package/dist/components/rel-nav-menu/README.md +0 -289
  91. package/dist/components/rel-nav-menu/index.ts +0 -3
  92. package/dist/components/rel-nav-menu/rel-nav-menu-item.ts +0 -243
  93. package/dist/components/rel-nav-menu/rel-nav-menu-panel.ts +0 -72
  94. package/dist/components/rel-nav-menu/rel-nav-menu.ts +0 -270
  95. package/dist/components/rel-navbar/README.md +0 -126
  96. package/dist/components/rel-navbar/rel-navbar.ts +0 -105
  97. package/dist/components/rel-otp/index.ts +0 -1
  98. package/dist/components/rel-otp/rel-otp.ts +0 -527
  99. package/dist/components/rel-pagination/index.ts +0 -1
  100. package/dist/components/rel-pagination/rel-pagination.ts +0 -522
  101. package/dist/components/rel-popover/index.ts +0 -2
  102. package/dist/components/rel-popover/rel-popover-content.ts +0 -81
  103. package/dist/components/rel-popover/rel-popover.ts +0 -475
  104. package/dist/components/rel-progress/rel-progress.ts +0 -234
  105. package/dist/components/rel-radio/rel-radio.ts +0 -481
  106. package/dist/components/rel-range-picker/rel-range-picker.ts +0 -1688
  107. package/dist/components/rel-resizable/index.ts +0 -3
  108. package/dist/components/rel-resizable/rel-resizable-group.ts +0 -405
  109. package/dist/components/rel-resizable/rel-resizable-handle.ts +0 -150
  110. package/dist/components/rel-resizable/rel-resizable-panel.ts +0 -58
  111. package/dist/components/rel-segmented-button/rel-segmented-button.ts +0 -217
  112. package/dist/components/rel-select/rel-select.ts +0 -1416
  113. package/dist/components/rel-sheet/rel-sheet.ts +0 -610
  114. package/dist/components/rel-sidebar/README.md +0 -209
  115. package/dist/components/rel-sidebar/rel-sidebar.ts +0 -1191
  116. package/dist/components/rel-skeleton/rel-skeleton.ts +0 -143
  117. package/dist/components/rel-slider/rel-slider.ts +0 -673
  118. package/dist/components/rel-snackbar/rel-snackbar.ts +0 -329
  119. package/dist/components/rel-stepper/rel-stepper.ts +0 -567
  120. package/dist/components/rel-switch/rel-switch.ts +0 -199
  121. package/dist/components/rel-tab/rel-tab.ts +0 -264
  122. package/dist/components/rel-table/README.md +0 -178
  123. package/dist/components/rel-table/rel-table-body.ts +0 -22
  124. package/dist/components/rel-table/rel-table-caption.ts +0 -30
  125. package/dist/components/rel-table/rel-table-cell.ts +0 -43
  126. package/dist/components/rel-table/rel-table-footer.ts +0 -24
  127. package/dist/components/rel-table/rel-table-head.ts +0 -47
  128. package/dist/components/rel-table/rel-table-header.ts +0 -22
  129. package/dist/components/rel-table/rel-table-row.ts +0 -37
  130. package/dist/components/rel-table/rel-table.ts +0 -62
  131. package/dist/components/rel-textfield/rel-textfield.ts +0 -1054
  132. package/dist/components/rel-time-picker/rel-time-picker.ts +0 -1482
  133. package/dist/components/rel-time-picker/time-parse.test.ts +0 -67
  134. package/dist/components/rel-time-picker/time-parse.ts +0 -85
  135. package/dist/components/rel-toast/rel-toast.ts +0 -206
  136. package/dist/components/rel-tooltip/rel-tooltip.ts +0 -193
  137. package/dist/components/rel-topbar/rel-topbar-actions.ts +0 -27
  138. package/dist/components/rel-topbar/rel-topbar-brand.ts +0 -54
  139. package/dist/components/rel-topbar/rel-topbar-dropdown-item.ts +0 -69
  140. package/dist/components/rel-topbar/rel-topbar-dropdown.ts +0 -31
  141. package/dist/components/rel-topbar/rel-topbar-item.ts +0 -324
  142. package/dist/components/rel-topbar/rel-topbar-mobile-panel.ts +0 -27
  143. package/dist/components/rel-topbar/rel-topbar-profile.ts +0 -243
  144. package/dist/components/rel-topbar/rel-topbar-utilities.ts +0 -27
  145. package/dist/components/rel-topbar/rel-topbar.ts +0 -446
  146. package/dist/components/rel-upload/UPLOAD-DESIGN-CHANGES.md +0 -134
  147. package/dist/components/rel-upload/rel-upload-actions.ts +0 -163
  148. package/dist/components/rel-upload/rel-upload.ts +0 -968
@@ -1,141 +1,156 @@
1
- # rel-segmented-button
2
-
3
- ## Overview
4
- A segmented button group for mutually exclusive selections. Displays multiple options as connected buttons with a single active selection. Supports size variants, alignment options, and individual option states (disabled).
5
-
6
- ## Usage
7
- ```html
8
- <!-- Basic segmented button -->
9
- <rel-segmented-button id="viewMode" active="grid"></rel-segmented-button>
10
- <script>
11
- const viewMode = document.getElementById('viewMode');
12
- viewMode.options = [
13
- { label: 'List', value: 'list' },
14
- { label: 'Grid', value: 'grid' },
15
- { label: 'Table', value: 'table' }
16
- ];
17
- </script>
18
-
19
- <!-- Small size with alignment -->
20
- <rel-segmented-button
21
- id="textAlign"
22
- size="small"
23
- align="middle"
24
- active="center">
25
- </rel-segmented-button>
26
- <script>
27
- const textAlign = document.getElementById('textAlign');
28
- textAlign.options = [
29
- { label: 'Left', value: 'left' },
30
- { label: 'Center', value: 'center' },
31
- { label: 'Right', value: 'right' }
32
- ];
33
- </script>
34
-
35
- <!-- With disabled option -->
36
- <rel-segmented-button id="planSelector"></rel-segmented-button>
37
- <script>
38
- const planSelector = document.getElementById('planSelector');
39
- planSelector.options = [
40
- { label: 'Free', value: 'free' },
41
- { label: 'Pro', value: 'pro' },
42
- { label: 'Enterprise', value: 'enterprise', disabled: true }
43
- ];
44
- planSelector.active = 'free';
45
- </script>
46
-
47
- <!-- Listen for changes -->
48
- <rel-segmented-button id="sortOrder"></rel-segmented-button>
49
- <script>
50
- const sortOrder = document.getElementById('sortOrder');
51
- sortOrder.options = [
52
- { label: 'Newest', value: 'newest' },
53
- { label: 'Oldest', value: 'oldest' },
54
- { label: 'Popular', value: 'popular' }
55
- ];
56
- sortOrder.addEventListener('changed', (e) => {
57
- console.log('Selected:', e.detail.value);
58
- });
59
- </script>
60
- ```
61
-
62
- ## API
63
-
64
- ### Attributes/Properties
65
- | Name | Type | Default | Description |
66
- |------|------|---------|-------------|
67
- | `options` | `SegmentOption[]` | `[]` | Array of segment options (see SegmentOption interface below) |
68
- | `active` | `string` | `""` | Value of the currently active segment |
69
- | `size` | `"small" \| "medium"` | `"medium"` | Size variant |
70
- | `align` | `"left" \| "middle" \| "right"` | `"left"` | Horizontal alignment of the button group |
71
-
72
- ### SegmentOption Interface
73
- ```typescript
74
- interface SegmentOption {
75
- label: string; // Display text for the button
76
- value: string; // Unique value identifier
77
- disabled?: boolean; // Optional: disable this specific segment
78
- }
79
- ```
80
-
81
- ## Events
82
- | Event | Detail | Description |
83
- |-------|--------|-------------|
84
- | `changed` | `{ value: string }` | Fired when a different segment is selected |
85
-
86
- ## Slots
87
- Default slot not used.
88
-
89
- ## CSS Parts
90
- None exposed.
91
-
92
- ## Tokens / CSS Variables
93
-
94
- ### Semantic Tokens
95
- - `--rel-fonts-font-family` - Font family
96
- - `--rel-body-xs-regular-font-size`, `--rel-body-sm-regular-font-size` - Font sizes for small and medium variants
97
- - `--rel-fonts-weight-body-medium` - Font weight for segment labels
98
-
99
- ### Spacing Tokens
100
- - `--rel-spacing-3xs`, `--rel-spacing-2xs` - Vertical padding for sizes
101
- - `--rel-spacing-xs`, `--rel-spacing-sm` - Horizontal padding for sizes
102
-
103
- ### Color Tokens
104
- - `--rel-bg-surface` - Default segment background
105
- - `--rel-border-default` - Outer border and segment dividers
106
- - `--rel-text-label` - Active segment background and default text color
107
- - `--rel-bg-neutral-elevated-1` - Hover and disabled background
108
- - `--rel-text-disabled` - Disabled text color
109
- - `--rel-border-info` - Focus outline color
110
-
111
- ### Border Tokens
112
- - `--rel-border-radius-md` - Border radius for the group
113
-
114
- ## Accessibility
115
- - Uses native `<button>` elements for proper keyboard navigation
116
- - Focus visible state with inner outline for keyboard users
117
- - Disabled segments use `pointer-events: none` and reduced opacity
118
- - Each segment can receive focus independently
119
-
120
- ### Keyboard Interactions
121
- - `Tab` - Move focus between segments
122
- - `Space/Enter` - Activate focused segment
123
- - `Arrow Left/Right` - Navigate between segments (browser default)
124
-
125
- ### Focus Behavior
126
- - Focus outline appears inside the button boundary with `-2px` offset
127
- - Uses info border color for high contrast
128
- - Active button has `z-index: 1` to ensure focus ring is visible over adjacent segments
129
-
130
- ## Notes / Edge Cases
131
- - The component is `display: inline-block` and sizes to fit content
132
- - All segments are connected with shared borders (2px solid gray)
133
- - The last segment has no right border to avoid doubling with the outer container border
134
- - Active segment has inverted colors (dark background, white text)
135
- - Hovering a non-active, non-disabled segment shows a light gray background
136
- - Hovering the active segment does not change its appearance
137
- - Disabled segments show reduced opacity (0.5), gray background, and are non-interactive
138
- - The `align` property uses flexbox justify-content (left → flex-start, middle → center, right → flex-end)
139
- - Size variants affect both font size and padding
140
- - Smooth transitions (0.2s ease-in-out) apply to all visual changes
141
- - Clicking a disabled option will not change the `active` value or dispatch events
1
+ # rel-segmented-button
2
+
3
+ A single-select segmented button group: a row of buttons on a 2px-inset track where exactly one segment is active at a time. Each entry in `options` renders as a native `<button role="radio">` inside a `role="radiogroup"`, so the group behaves like a compact radio group (one Tab stop, arrow keys move the selection). Use it for mutually exclusive view or mode switches with two to five short options (list / grid, day / week / month, sort order); do not use it for navigation between pages (use `rel-tab`) or for actions (use `rel-button`).
4
+
5
+ The control comes in three sizes that match the text field ramp — `small` 32px, `medium` 40px, `large` 48px — and each option can carry a leading `icon`.
6
+
7
+ ## Usage
8
+
9
+ ```html
10
+ <!-- Basic: options are set as a property, `active` holds the selected value -->
11
+ <rel-segmented-button id="view-mode" active="grid" field-aria-label="View mode"></rel-segmented-button>
12
+ <script>
13
+ document.getElementById('view-mode').options = [
14
+ { label: 'List', value: 'list' },
15
+ { label: 'Grid', value: 'grid' },
16
+ { label: 'Table', value: 'table' }
17
+ ];
18
+ </script>
19
+
20
+ <!-- Options as a JSON attribute, small size -->
21
+ <rel-segmented-button
22
+ size="small"
23
+ active="week"
24
+ field-aria-label="Calendar range"
25
+ options='[{"label":"Day","value":"day"},{"label":"Week","value":"week"},{"label":"Month","value":"month"}]'>
26
+ </rel-segmented-button>
27
+
28
+ <!-- Large size (48px), matching a large text field -->
29
+ <rel-segmented-button
30
+ size="large"
31
+ active="grid"
32
+ field-aria-label="View mode"
33
+ options='[{"label":"List","value":"list"},{"label":"Grid","value":"grid"}]'>
34
+ </rel-segmented-button>
35
+
36
+ <!-- Leading icons: `icon` names a rel-icon, sized 16 / 18 / 20 with the control -->
37
+ <rel-segmented-button
38
+ active="list"
39
+ field-aria-label="View mode"
40
+ options='[{"label":"List","value":"list","icon":"bullet-list"},{"label":"Grid","value":"grid","icon":"dashboard"}]'>
41
+ </rel-segmented-button>
42
+
43
+ <!-- Disabled option: rendered but not selectable or focusable -->
44
+ <rel-segmented-button id="plan" active="free" field-aria-label="Plan"></rel-segmented-button>
45
+ <script>
46
+ document.getElementById('plan').options = [
47
+ { label: 'Free', value: 'free' },
48
+ { label: 'Pro', value: 'pro' },
49
+ { label: 'Enterprise', value: 'enterprise', disabled: true }
50
+ ];
51
+ </script>
52
+
53
+ <!-- Alignment inside a wider host (align only matters when the host is stretched) -->
54
+ <rel-segmented-button
55
+ style="display: block; width: 100%"
56
+ align="middle"
57
+ active="asc"
58
+ field-aria-label="Sort direction"
59
+ options='[{"label":"Ascending","value":"asc"},{"label":"Descending","value":"desc"}]'>
60
+ </rel-segmented-button>
61
+
62
+ <!-- Listen for changes -->
63
+ <rel-segmented-button id="sort-order" active="newest" field-aria-label="Sort order"></rel-segmented-button>
64
+ <script>
65
+ const sortOrder = document.getElementById('sort-order');
66
+ sortOrder.options = [
67
+ { label: 'Newest', value: 'newest' },
68
+ { label: 'Oldest', value: 'oldest' },
69
+ { label: 'Popular', value: 'popular' }
70
+ ];
71
+ sortOrder.addEventListener('changed', (e) => {
72
+ console.log('Selected:', e.detail.value);
73
+ });
74
+ </script>
75
+ ```
76
+
77
+ The `SegmentOption` interface and the `SegmentSize` / `SegmentAlign` unions are exported from the package:
78
+
79
+ ```typescript
80
+ import type { SegmentOption } from '@reliability-design/web';
81
+
82
+ const options: SegmentOption[] = [
83
+ { label: 'List', value: 'list' }, // label = visible text, value = what `active` / the event carry
84
+ { label: 'Grid', value: 'grid', icon: 'dashboard' }, // icon = a rel-icon name, drawn before the label
85
+ { label: 'Archive', value: 'archive', disabled: true } // rendered at 50% opacity, skipped by the arrow keys
86
+ ];
87
+ ```
88
+
89
+ <!-- readme-gen:start -->
90
+
91
+ <!-- Generated from rel-segmented-button.ts — do not edit; run readme-generate.mjs -->
92
+
93
+ ## API
94
+
95
+ ### Attributes / Properties
96
+
97
+ | Property | Attribute | Type | Default | Description |
98
+ | --- | --- | --- | --- | --- |
99
+ | `options` | `options` | `SegmentOption[]` | `[]` | The segments in order, each `{ label: string; value: string; disabled?: boolean; icon?: string; badge?: number \| string \| boolean }`. Set as a property (or a JSON array attribute); a disabled entry is rendered but cannot be selected, and `icon` names a `rel-icon` drawn before the label. |
100
+ | `active` | `active` | `string` | `""` | `value` of the currently selected segment. Updated by the component on click / arrow keys; set it to pre-select a segment (an unknown value selects nothing). |
101
+ | `size` | `size` | `"small" \| "medium" \| "large"` | `"medium"` | Control height, matching the TextField ramp: `small` (32px — 28px segments, `action-md` 12px text, 16px icons), `medium` (default, 40px — 36px segments, `action-lg` 14px text, 18px icons) or `large` (48px — 44px segments, `action-xl` 16px text, 20px icons). |
102
+ | `align` | `align` | `"left" \| "middle" \| "right"` | `"left"` | `justify-content` of the group's inline-flex container: `left` (default), `middle` or `right`. Only visible when the host is made wider than its content. |
103
+ | `fieldAriaLabel` | `field-aria-label` | `string` | `undefined` | Accessible name for the radiogroup (it renders no visible group label). |
104
+
105
+ ## Events
106
+
107
+ | Event | Detail | Bubbles / composed | Description |
108
+ | --- | --- | --- | --- |
109
+ | `changed` | `{ value: option.value }` | bubbles / composed | Fired after a non-disabled segment is selected by click or arrow / Home / End key (also when it was already the active one). Detail: `{ value: string }`. |
110
+
111
+ ## Slots
112
+
113
+ | Slot | Description |
114
+ | --- | --- |
115
+ | — | This element has no slots. |
116
+
117
+ ## CSS Parts
118
+
119
+ | Part | Description |
120
+ | --- | --- |
121
+ | `option` | Each segment's native `<button role="radio">`; the active one carries the `active` class and `aria-checked="true"`. |
122
+ | `icon` | A segment's optional leading `rel-icon` element. |
123
+ | `label` | The wrapper around a segment's label text. |
124
+ | `badge` | A segment's optional trailing `rel-badge`; rendered only when the option sets `badge`. |
125
+ | `base` | The `role="radiogroup"` track that lays out the segments. |
126
+
127
+ <!-- readme-gen:end -->
128
+
129
+ ## Accessibility
130
+
131
+ - The container is a `role="radiogroup"`; give it a name with `field-aria-label` — the component renders no visible group label, so without it screen readers announce an unnamed group.
132
+ - Every segment is a native `<button role="radio">` with `aria-checked="true"` on the active one and `aria-checked="false"` on the rest. Disabled options get the native `disabled` attribute, so they are not focusable and do not fire `click`.
133
+ - Roving tabindex (APG radio-group pattern): the whole group is a single Tab stop. The active segment carries `tabindex="0"`; if `active` matches no enabled option, the first enabled segment takes the Tab stop instead (without becoming selected). All other segments are `tabindex="-1"`.
134
+ - Arrow keys both move focus and select, so they emit `changed` immediately. Focus is moved to the newly active segment after the re-render.
135
+ - Focus ring: a 2px `border-focus` outline drawn inside the segment (`outline-offset: -2px`) and raised with `z-index: 1` so it stays above the neighbouring segment.
136
+ - Nothing is announced beyond the native `aria-checked` change.
137
+
138
+ | Key | Action |
139
+ | --- | --- |
140
+ | `Tab` / `Shift+Tab` | Move focus into / out of the group (one stop, on the active segment) |
141
+ | `ArrowRight` / `ArrowDown` | Select and focus the next enabled segment (wraps to the first) |
142
+ | `ArrowLeft` / `ArrowUp` | Select and focus the previous enabled segment (wraps to the last) |
143
+ | `Home` / `End` | Select and focus the first / last enabled segment |
144
+ | `Enter` / `Space` | Native button activation: selects the focused segment |
145
+
146
+ ## Notes / Edge Cases
147
+
148
+ - The change event is named `changed` (no `rel-` prefix, unlike most components); it bubbles and is composed, so it can be listened for on any ancestor. It also fires when the already-active segment is clicked again.
149
+ - `active` is a plain string compared against `option.value`; setting it to a value that is not in `options` (or to a disabled option's value) renders no active segment.
150
+ - `options` is compared by reference: mutate-in-place changes are not picked up — assign a new array.
151
+ - The host is `display: inline-block` and the group `inline-flex`, so it sizes to its content; `align` has no visible effect until the host is stretched (e.g. `style="display: block; width: 100%"`). Every segment has `min-width: 80px`, so a group is never narrower than 80px per segment.
152
+ - Sizing: the track is a `bg-neutral` surface with `spacing-3xs` (2px) padding and a `border-radius-xs` corner — there is no outer border and no dividers between segments. Each segment carries the full `border-radius-xs` on all four corners in every state. Segment heights are 28 / 36 / 44 for `small` / `medium` / `large`, which with the 2px inset give control heights of 32 / 40 / 48.
153
+ - Per size: padding `spacing-3xs spacing-sm` / `spacing-2xs spacing-md` / `spacing-xs spacing-lg`, text `action-md` (12px) / `action-lg` (14px) / `action-xl` (16px), and leading icons at 16 / 18 / 20px with an `spacing-xs` (8px) gap.
154
+ - Colours: the active segment uses `action-neutral-fill` with inverse text (and `action-neutral-fill-hover` on hover); a non-active segment is transparent so the `action-overlay-hover` alpha composites over the track; disabled segments are drawn at 50% opacity with `bg-neutral-elevated-1` and a `not-allowed` cursor. Background and colour transitions are 0.2s.
155
+ - A per-option `icon` renders a `rel-icon` before the label. Its size rides `--rel-icon-size` set directly on the `rel-icon` element — not on a wrapper, since `rel-icon` reflects `size="md"` and its own `:host([size])` rule would otherwise win.
156
+ - No design-token overrides or `--rel-segmented-button-*` hooks are exposed; style through the `base` / `option` / `icon` / `label` parts.