@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,135 +1,131 @@
1
- # rel-slider
2
-
3
- ## Overview
4
- A highly customizable range slider component supporting continuous and discrete modes. Features include tick marks, value bubble display, solid/dotted track styles, custom theming via CSS properties, and full accessibility support. Automatically snaps to steps in discrete mode.
5
-
6
- ## Usage
7
- ```html
8
- <!-- Basic continuous slider -->
9
- <rel-slider value="50" min="0" max="100"></rel-slider>
10
-
11
- <!-- Discrete slider with ticks -->
12
- <rel-slider
13
- type="discrete"
14
- value="25"
15
- min="0"
16
- max="100"
17
- step="25">
18
- </rel-slider>
19
-
20
- <!-- Discrete slider with tick labels -->
21
- <rel-slider
22
- type="discrete"
23
- value="3"
24
- min="1"
25
- max="5"
26
- step="1"
27
- showTickLabels>
28
- </rel-slider>
29
-
30
- <!-- Dotted track without value bubble -->
31
- <rel-slider
32
- value="60"
33
- min="0"
34
- max="100"
35
- track="dotted"
36
- showBubble="false">
37
- </rel-slider>
38
-
39
- <!-- Disabled slider -->
40
- <rel-slider value="30" disabled></rel-slider>
41
-
42
- <!-- Listen for value changes -->
43
- <rel-slider id="volumeSlider" value="75" min="0" max="100"></rel-slider>
44
- <script>
45
- const slider = document.getElementById('volumeSlider');
46
- slider.addEventListener('valueChange', (e) => {
47
- console.log('New value:', e.detail.value);
48
- });
49
- </script>
50
- ```
51
-
52
- ## API
53
-
54
- ### Attributes/Properties
55
- | Name | Type | Default | Description |
56
- |------|------|---------|-------------|
57
- | `type` | `"continuous" \| "discrete"` | `"continuous"` | Slider mode: continuous allows any value, discrete snaps to steps |
58
- | `min` | `number` | `0` | Minimum value |
59
- | `max` | `number` | `100` | Maximum value |
60
- | `step` | `number` | `1` | Step increment (used in discrete mode for snapping and ticks) |
61
- | `value` | `number` | `0` | Current slider value |
62
- | `disabled` | `boolean` | `false` | Disables the slider |
63
- | `track` | `"solid" \| "dotted"` | `"solid"` | Visual style of the active track |
64
- | `showTickLabels` | `boolean` | `false` | Show numeric labels at each tick (discrete mode only) |
65
- | `showBubble` | `boolean` | `true` | Show value bubble marker above the thumb |
66
-
67
- ## Events
68
- | Event | Detail | Description |
69
- |-------|--------|-------------|
70
- | `valueChange` | `{ value: number }` | Fired when the slider value changes through user interaction |
71
-
72
- ## Slots
73
- Default slot not used.
74
-
75
- ## CSS Parts
76
- None exposed.
77
-
78
- ## Tokens / CSS Variables
79
-
80
- ### Component-Level Custom Properties
81
- The component defines these CSS custom properties on `:host` which can be overridden:
82
-
83
- - `--track-height` - Height of the slider track (default: `5px`)
84
- - `--thumb-size` - Diameter of the thumb (default: `10px`)
85
- - `--thumb-stroke` - Thickness of focus/active halo around thumb (default: `7px`)
86
- - `--thumb-halo-color` - Color of thumb halo (default: `--rel-border-default`)
87
- - `--tick-size` - Diameter of tick marks (default: `4px`)
88
- - `--shadow` - Thumb drop shadow (default: `0 2px 4px rgba(0,0,0,0.25)`)
89
- - `--halo` - Additional halo shadow (default: `0 2px 0 var(--rel-bg-neutral-elevated-1), 0 6px 10px rgba(0,0,0,0.07)`)
90
- - `--marker-width` - Width of value bubble (default: `24px`)
91
- - `--marker-height` - Height of value bubble (default: `28px`)
92
-
93
- ### Design Token References
94
- - `--rel-fonts-font-family` - Font family
95
- - `--rel-border-default` - Inactive track color
96
- - `--rel-text-default` - Active track and thumb color
97
- - `--rel-bg-surface` - Used in dotted track and tick marks
98
- - `--rel-text-default` - Tick mark color (inactive)
99
- - `--rel-text-label` - Tick label color
100
- - `--rel-text-placeholder` - Disabled active track and tick colors
101
- - `--rel-border-default` - Default thumb halo color
102
- - `--rel-bg-neutral-elevated-1` - Disabled track background, used in dotted pattern
103
- - `--rel-body-xs-regular-font-size` - Tick label font size
104
-
105
- ## Accessibility
106
- - Uses native `<input type="range">` for full keyboard and screen reader support
107
- - Native input is transparent overlay, custom visuals beneath are purely decorative
108
- - Focus visible state shows halo around custom thumb
109
- - Disabled state prevents interaction with styled cursor and reduced contrast
110
- - Respects `prefers-reduced-motion` media query (disables transitions)
111
-
112
- ### Keyboard Interactions
113
- - `Arrow Left/Down` - Decrease value
114
- - `Arrow Right/Up` - Increase value
115
- - `Home` - Jump to minimum value
116
- - `End` - Jump to maximum value
117
- - `Page Up/Down` - Larger increments (browser-dependent)
118
-
119
- ### Focus Behavior
120
- - Focus shows halo around custom thumb using `--thumb-halo-color`
121
- - Active (mouse down) state also shows the halo
122
-
123
- ## Notes / Edge Cases
124
- - In **discrete mode**, the slider automatically snaps to the nearest step value as the user drags
125
- - Tick marks are generated automatically in discrete mode based on `min`, `max`, and `step`
126
- - If the range doesn't divide evenly by step, a final tick is added at `max`
127
- - Ticks change color (become white) when the value passes them (active state)
128
- - **showTickLabels** only has effect in discrete mode
129
- - **showBubble** displays a pin-drop shaped SVG marker with the current value as text
130
- - The value bubble uses the "Poppins" font (you may need to load this separately or it will fall back)
131
- - **Dotted track** uses a `radial-gradient` pattern with white dots over the active color
132
- - The component has a fixed height of `60px` to accommodate the value bubble
133
- - When disabled, all interactive colors become muted gray tones
134
- - Active track width updates dynamically based on the percentage value
135
- - The component respects `prefers-reduced-motion` and disables all transitions when requested
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" showticklabels 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
+ <!-- readme-gen:start -->
42
+
43
+ <!-- Generated from rel-slider.ts — do not edit; run readme-generate.mjs -->
44
+
45
+ ## API
46
+
47
+ ### Attributes / Properties
48
+
49
+ | Property | Attribute | Type | Default | Description |
50
+ | --- | --- | --- | --- | --- |
51
+ | `type` | `type` | `"continuous" \| "discrete" \| "default" \| "range"` | `"continuous"` | Slider mode: `continuous` (or its alias `default`) accepts any integer value, `discrete` snaps to `step` and draws tick marks, `range` shows two thumbs bounding `value`…`valueEnd`. Reflected. |
52
+ | `showTicks` | `show-ticks` | `boolean` | `undefined` | Draws the tick marks (Figma's separate `Is Determinated` boolean). Works with ANY `type` — Figma shows ticks on every variant, where the code used to gate them behind the code-only `type="discrete"`, so a `default` or `range` slider could never show them. Left unset it follows `type="discrete"`, so nothing changes for existing sliders; set it explicitly to override in either direction. Reflected. |
53
+ | `size` | `size` | `"small" \| "medium" \| "large" \| "sm" \| "md" \| "lg"` | `"medium"` | Figma Size axis: `small` (6px track / 16px thumb), `medium` (8 / 20, default) or `large` (10 / 24), which also scales the ticks and the value bubble. `sm` / `md` / `lg` are alternative spellings and stay supported — they are normalised to the full words, not deprecated. Reflected. |
54
+ | `min` | `min` | `number` | `0` | Lowest selectable value. |
55
+ | `max` | `max` | `number` | `100` | Highest selectable value. |
56
+ | `step` | `step` | `number` | `1` | Increment between values. In `discrete` mode it also spaces the tick marks; in `continuous` mode the native input always moves in steps of 1. |
57
+ | `disabled` | `disabled` | `boolean` | `false` | Disables interaction and dims the track, thumb and ticks; the tooltip is hidden. |
58
+ | `track` | `track` | `"solid" \| "dotted"` | `"solid"` | Style of the filled part of the track: `solid` or a `dotted` pattern. |
59
+ | `showTickLabels` | `showticklabels` | `boolean` | `false` | Print the numeric value under every tick mark. Only has an effect in `discrete` mode. Reflected. |
60
+ | `showBubble` | `showbubble` | `boolean` | `true` | Show the value tooltip above the thumb(s). |
61
+ | `value` | `value` | `number` | `0` | Current value (the lower value in `range` mode). |
62
+ | `valueEnd` | `value-end` | `number` | `100` | Upper value when type="range" (attribute value-end). |
63
+ | `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. |
64
+
65
+ ## Events
66
+
67
+ | Event | Detail | Bubbles / composed | Description |
68
+ | --- | --- | --- | --- |
69
+ | `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. |
70
+
71
+ ## Slots
72
+
73
+ | Slot | Description |
74
+ | --- | --- |
75
+ | — | This element has no slots. |
76
+
77
+ ## CSS Parts
78
+
79
+ | Part | Description |
80
+ | --- | --- |
81
+ | `tooltip` | The value bubble + chevron above each thumb (only while `showBubble` is on) |
82
+ | `thumb` | The round grab handle (one per thumb in range mode) |
83
+ | `track` | The rail behind the thumb (the filled portion has no part) |
84
+
85
+ ## Tokens / CSS Variables
86
+
87
+ ### Component hooks
88
+
89
+ Set these on the host (or an ancestor) to customise the element without touching design tokens.
90
+
91
+ | Custom property | Default | Description |
92
+ | --- | --- | --- |
93
+ | `--rel-slider-bubble-radius` | `var(--bubble-radius)` | Corner radius of the value bubble; 8px for size sm, otherwise 10px |
94
+ | `--rel-slider-thumb-halo-color` | `var(--thumb-halo-color)` | Colour of the keyboard-focus ring; default `var(--rel-border-default)` |
95
+ | `--rel-slider-thumb-size` | `var(--thumb-size)` | Thumb diameter; 16 / 20 / 24px for size sm / md / lg |
96
+ | `--rel-slider-thumb-stroke` | `var(--thumb-stroke)` | Width of the hover / pressed / focus ring around the thumb; default 6px |
97
+ | `--rel-slider-tick-size` | `var(--tick-size)` | Tick-mark diameter in discrete mode; 4 / 5 / 6px for size sm / md / lg |
98
+ | `--rel-slider-track-height` | `var(--track-height)` | Rail thickness; 6 / 8 / 10px for size sm / md / lg |
99
+
100
+ <!-- readme-gen:end -->
101
+
102
+ ## Accessibility
103
+
104
+ - 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"`.
105
+ - `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).
106
+ - `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`.
107
+ - The keyboard-focus ring is drawn on the custom thumb via `:focus-visible` (`--rel-slider-thumb-halo-color`); mouse focus shows no ring.
108
+ - `disabled` disables the native inputs (removed from the tab order) and hides the tooltip.
109
+ - 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.
110
+ - `prefers-reduced-motion: reduce` removes the thumb and tick transitions.
111
+
112
+ Keys come from the native range input:
113
+
114
+ | Key | Action |
115
+ | --- | --- |
116
+ | `ArrowRight` / `ArrowUp` | Increase by one step (`step` in `discrete` mode, 1 otherwise). |
117
+ | `ArrowLeft` / `ArrowDown` | Decrease by one step. |
118
+ | `Home` | Jump to `min`. |
119
+ | `End` | Jump to `max`. |
120
+ | `PageUp` / `PageDown` | Larger jump (browser-defined). |
121
+
122
+ ## Notes / Edge Cases
123
+
124
+ - `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.
125
+ - Ticks are generated from `min` to `max` in `step` increments; if the range does not divide evenly a final tick is added at `max`. `showticklabels` only has an effect in `discrete` mode.
126
+ - In `range` mode the thumbs cannot cross: `value` is clamped to `≤ value-end` and `value-end` to `≥ value`. The default `value-end` is 100.
127
+ - `rel-change` fires for user interaction only; setting `value` / `valueEnd` programmatically updates the visuals but emits nothing.
128
+ - The element is `display: block` with a fixed 60px height that reserves room for the tooltip above the track.
129
+ - 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.
130
+ - 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.
131
+ - `registerOnChange`, `registerOnTouched` and `writeValue` exist for the Angular `ControlValueAccessor` wrapper and are not public API.
@@ -1,134 +1,168 @@
1
- # rel-snackbar
2
-
3
- ## Overview
4
- A bottom-anchored notification component for brief messages with optional action buttons. Supports single/double line layouts, configurable auto-dismiss duration, longer action mode (2x duration), and optional close icon. Features slide-up animation respecting user motion preferences.
5
-
6
- ## Usage
7
- ```html
8
- <!-- Basic snackbar -->
9
- <rel-snackbar message="File uploaded successfully"></rel-snackbar>
10
-
11
- <!-- With action button -->
12
- <rel-snackbar
13
- id="undoSnackbar"
14
- message="Item deleted"
15
- action="UNDO">
16
- </rel-snackbar>
17
- <script>
18
- const snackbar = document.getElementById('undoSnackbar');
19
- snackbar.addEventListener('actionClick', () => {
20
- console.log('Undo action clicked');
21
- // Perform undo logic
22
- });
23
- </script>
24
-
25
- <!-- Two-line layout -->
26
- <rel-snackbar
27
- message="Your message is too long to fit on a single line, so we'll use two."
28
- lines="double"
29
- action="DISMISS">
30
- </rel-snackbar>
31
-
32
- <!-- Longer action (2x duration) -->
33
- <rel-snackbar
34
- message="Changes saved"
35
- action="VIEW"
36
- longerAction>
37
- </rel-snackbar>
38
-
39
- <!-- Without close icon -->
40
- <rel-snackbar
41
- message="Processing..."
42
- iconClose="false"
43
- duration="0">
44
- </rel-snackbar>
45
-
46
- <!-- Custom duration (10 seconds) -->
47
- <rel-snackbar
48
- message="Important notification"
49
- duration="10000"
50
- action="GOT IT">
51
- </rel-snackbar>
52
-
53
- <!-- Listen for close event -->
54
- <rel-snackbar id="notif" message="Update available"></rel-snackbar>
55
- <script>
56
- const notif = document.getElementById('notif');
57
- notif.addEventListener('close', () => {
58
- console.log('Snackbar closed');
59
- });
60
- </script>
61
- ```
62
-
63
- ## API
64
-
65
- ### Attributes/Properties
66
- | Name | Type | Default | Description |
67
- |------|------|---------|-------------|
68
- | `message` | `string` | `"This is a snackbar message"` | Primary message text |
69
- | `action` | `string` | - | Optional action button label (e.g., "UNDO", "RETRY") |
70
- | `longerAction` | `boolean` | `false` | If true, doubles the auto-dismiss duration |
71
- | `iconClose` | `boolean` | `true` | Whether to show the close (✖) icon button |
72
- | `lines` | `"single" \| "double"` | `"single"` | Layout mode (single-line flex-row, double-line flex-column) |
73
- | `duration` | `number` | `4000` | Auto-dismiss duration in milliseconds (0 = no auto-dismiss) |
74
-
75
- ## Events
76
- | Event | Detail | Description |
77
- |-------|--------|-------------|
78
- | `actionClick` | None | Fired when the action button is clicked |
79
- | `close` | None | Fired when snackbar is closed (via action, close button, or auto-dismiss) |
80
-
81
- ## Slots
82
- Default slot not used.
83
-
84
- ## CSS Parts
85
- None exposed.
86
-
87
- ## Tokens / CSS Variables
88
-
89
- ### Semantic Tokens
90
- - `--rel-fonts-font-family` - Font family
91
- - `--rel-body-sm-regular-font-size` - Font size
92
- - `--rel-fonts-weight-body-semibold` - Action button font weight
93
- - `--rel-body-md-regular-line-height` - Message line height
94
-
95
- ### Spacing Tokens
96
- - `--rel-spacing-2xs` - Action button gap, close button padding
97
-
98
- ### Color Tokens
99
- - `--rel-text-default` - Background color
100
- - `--rel-bg-surface` - Text and focus outline color
101
- - `--rel-bg-success-light` - Action button text color
102
-
103
- ### Shadow Tokens
104
- - `--rel-shadows-shadow-300` - Drop shadow
105
-
106
- ### Border Tokens
107
- - `--rel-border-radius-sm` - Border radius
108
-
109
- ## Accessibility
110
- - Snackbars are informational and do not interrupt workflows
111
- - Close and action buttons have proper focus styles
112
- - Animation respects `prefers-reduced-motion` media query
113
-
114
- ### Keyboard Interactions
115
- - `Tab` - Focus action button or close button
116
- - `Space/Enter` - Activate focused button
117
-
118
- ### Focus Behavior
119
- - Buttons show 2px white outline with 2px offset when focused
120
- - Border radius applied to maintain visual consistency
121
-
122
- ## Notes / Edge Cases
123
- - Snackbar has a minimum width of `280px` and maximum width of `500px`
124
- - **Single-line mode** (`lines="single"`): message and actions are flex-row with `justify-content: space-between`
125
- - **Double-line mode** (`lines="double"`): layout switches to flex-column with actions aligned to the right
126
- - Auto-dismiss timer starts in `connectedCallback()` and resets when `duration` or `longerAction` changes
127
- - If `longerAction` is true, the effective duration is `duration * 2`
128
- - Setting `duration="0"` disables auto-dismiss
129
- - Clicking the action button automatically closes the snackbar after dispatching `actionClick`
130
- - Clicking the close icon dispatches `close` and hides the snackbar (`visible = false`)
131
- - When `visible` is false, `hidden` class applies `display: none`
132
- - The component includes a `slide-up` animation (50px translateY → 0) on appearance
133
- - Animation disabled when `prefers-reduced-motion: reduce` is set
134
- - Snackbar is `display: block` by default (should be positioned by parent or global styles)
1
+ # rel-snackbar
2
+
3
+ `<rel-snackbar>` is the snackbar of the Reliability Design System (Figma "Snackbar"): a dark, elevated message bar with a 4px tone accent and leading status icon for the success / warning / destructive tones, an optional action button and a close icon, in single-line and double-line (Figma Type=Longer Action) layouts. It is shown by setting `show` and hides itself after `duration` milliseconds. Unlike `<rel-toast>` it is **not** positioned — it is a `display: block` element you place yourself (in-flow, or fixed via your own CSS). Use it for brief feedback with one follow-up action ("Undo", "Retry"); use `<rel-alert>` for messages that must stay on the page.
4
+
5
+ ## Usage
6
+
7
+ ```html
8
+ <!-- Hidden until `show` is set -->
9
+ <rel-snackbar id="uploaded" message="File uploaded"></rel-snackbar>
10
+
11
+ <!-- Initially visible; neutral tone (no accent, no icon), auto-hides after 4000 ms -->
12
+ <rel-snackbar show message="Settings saved"></rel-snackbar>
13
+
14
+ <!-- Status tones: left accent + leading icon -->
15
+ <rel-snackbar show tone="success" message="Invitation sent"></rel-snackbar>
16
+ <rel-snackbar show tone="warning" message="Connection is unstable"></rel-snackbar>
17
+ <rel-snackbar show tone="destructive" message="Payment failed"></rel-snackbar>
18
+
19
+ <!-- Action button -->
20
+ <rel-snackbar id="deleted" message="Item deleted" action="Undo"></rel-snackbar>
21
+
22
+ <!-- Double-line layout with a longer (2 × duration) dismiss delay -->
23
+ <rel-snackbar
24
+ id="archived"
25
+ message="12 conversations were archived and will be deleted in 30 days"
26
+ action="Undo"
27
+ variant="longer-action"
28
+ ></rel-snackbar>
29
+
30
+ <!-- Deprecated aliases — both still work and both log a one-time console notice.
31
+ `lines="double"` sets the stacked layout but NOT the doubled delay; `longeraction`
32
+ doubles the delay but does not stack. `variant="longer-action"` above does both.
33
+ Note the attribute is lower-case `longeraction`, not `longer-action`. -->
34
+ <rel-snackbar message="Older markup" action="Undo" lines="double" longeraction></rel-snackbar>
35
+
36
+ <!-- Persistent, without the close icon (the boolean must be cleared from script — see the js block) -->
37
+ <rel-snackbar id="busy" message="Processing…" duration="0"></rel-snackbar>
38
+ ```
39
+
40
+ ```js
41
+ const uploaded = document.getElementById("uploaded");
42
+ uploaded.show = true; // starts the auto-dismiss timer and announces the message
43
+ uploaded.addEventListener("close", () => {
44
+ uploaded.show; // false — fired by the close icon, the action button and the timer
45
+ });
46
+
47
+ const deleted = document.getElementById("deleted");
48
+ deleted.addEventListener("actionClick", () => {
49
+ // undo the deletion… the snackbar dismisses itself right after (a `close` event follows)
50
+ });
51
+ deleted.show = true;
52
+
53
+ // A Lit boolean attribute is true whenever present, so iconclose="false" does NOT work.
54
+ const busy = document.getElementById("busy");
55
+ busy.iconClose = false;
56
+ busy.show = true;
57
+ busy.show = false; // hides silently — no `close` event when hidden from script
58
+ ```
59
+
60
+ ```css
61
+ /* The component is display: block; position it yourself */
62
+ rel-snackbar {
63
+ position: fixed;
64
+ bottom: 24px;
65
+ left: 50%;
66
+ transform: translateX(-50%);
67
+ }
68
+ ```
69
+
70
+ ### Deprecated aliases
71
+
72
+ ```html
73
+ <!-- type= is the deprecated alias of tone= (tone wins when both are set). Logs once per page:
74
+ [rel-snackbar] "type" is deprecated and will be removed in 3.0 — use "tone" instead. Note: tone="destructive" replaces type="error"; tone="neutral" replaces type="default". -->
75
+ <rel-snackbar type="error" message="Payment failed"></rel-snackbar>
76
+ <rel-snackbar type="default" message="Settings saved"></rel-snackbar>
77
+
78
+ <!-- tone="default" is the deprecated spelling of tone="neutral". Logs once:
79
+ [rel-snackbar] "tone="default"" is deprecated and will be removed in 3.0 — use "tone="neutral"" instead. -->
80
+ <rel-snackbar tone="default" message="Settings saved"></rel-snackbar>
81
+
82
+ <!-- tone="error" | "danger" | "critical" are deprecated spellings of tone="destructive". Logs once per spelling:
83
+ [rel-snackbar] "tone="error"" is deprecated and will be removed in 3.0 — use "tone="destructive"" instead. -->
84
+ <rel-snackbar tone="error" message="Payment failed"></rel-snackbar>
85
+ <rel-snackbar tone="critical" message="Payment failed"></rel-snackbar>
86
+ ```
87
+
88
+ <!-- readme-gen:start -->
89
+
90
+ <!-- Generated from rel-snackbar.ts — do not edit; run readme-generate.mjs -->
91
+
92
+ ## API
93
+
94
+ ### Attributes / Properties
95
+
96
+ | Property | Attribute | Type | Default | Description |
97
+ | --- | --- | --- | --- | --- |
98
+ | `message` | `message` | `string` | `"This is a snackbar message"` | Message text. Announced to screen readers through the shared live-region announcer when the snackbar is shown and whenever it changes while shown. The default is a placeholder — always set it. |
99
+ | `action` | `action` | `string` | `undefined` | Label of the optional action button (Figma trailing button, Static / Small); omitted when unset. Clicking it fires `actionClick` and then dismisses the snackbar. |
100
+ | `variant` | `variant` | `"default" \| "longer-action"` | `undefined` | Layout and timing (Figma "Type"): `"default"` (message and actions on one row) \| `"longer-action"` (message stacked above the actions, which align to the end, with the auto-dismiss delay doubled so there is time to use the action). Takes precedence over the deprecated `lines` and `longerAction` props. |
101
+ | `iconClose` | `iconclose` | `boolean` | `true` | Shows the trailing close icon button. Defaults to true; because it is a Lit boolean, `iconclose="false"` is still true — set the property to `false` from script to hide the button. |
102
+ | `duration` | `duration` | `number` | `4000` | Auto-dismiss delay in milliseconds (doubled by `variant="longer-action"`), started when `show` becomes true and restarted when `duration` or the layout changes while shown. `0` (or a negative value) disables auto-dismiss. |
103
+ | `tone` | `tone` | `"neutral" \| "success" \| "warning" \| "destructive" \| "default" \| "error" \| "danger" \| "critical"` | `undefined` | Semantic tone (Figma "Tone"): `"neutral"` (default: no accent, no icon) \| `"success"` \| `"warning"` \| `"destructive"` — the status tones add a 4px left accent and a leading icon (check-circle / warning / error) in the tone colour. `"default"` is a deprecated alias of `"neutral"`; `"error"`, `"danger"` and `"critical"` are deprecated aliases of `"destructive"`; each logs a one-time console notice. Takes precedence over the deprecated `type` prop. |
104
+ | `show` | `show` | `boolean` | `false` | Whether the snackbar is visible. Set it to true to show the snackbar and start the auto-dismiss timer; it is set back to false by the close icon, the action button and the timer. There is no open/close method — toggle this property. Reflected. |
105
+
106
+ #### Deprecated (still supported — removal targeted for 3.0)
107
+
108
+ | Property | Attribute | Type | Use instead |
109
+ | --- | --- | --- | --- |
110
+ | `longerAction` | `longeraction` | `boolean` | — use `variant="longer-action"`, which also sets the stacked layout. Doubles the auto-dismiss delay (`duration * 2`) on its own. Ignored when `variant` is set. Logs a one-time console notice. |
111
+ | `lines` | `lines` | `"single" \| "double"` | — use `variant`; `lines="double"` maps to `variant="longer-action"`. Sets the stacked layout on its own but not the doubled delay. Ignored when `variant` is set. Logs a one-time console notice. |
112
+ | `type` | `type` | `"neutral" \| "success" \| "warning" \| "destructive" \| "default" \| "error" \| "danger" \| "critical"` | Deprecated since 1.4.7 — alias of `tone`; use `tone`. Same values as `tone`; `type="error"` maps to `tone="destructive"` and `type="default"` to `tone="neutral"`. Ignored when `tone` is set. Logs a one-time console notice. |
113
+
114
+ ### Public fields / accessors
115
+
116
+ | Name | Type | Description |
117
+ | --- | --- | --- |
118
+ | `resolvedVariant` | `SnackbarVariant` | Read-only canonical layout actually rendered: explicit `variant` wins, else either deprecated prop (`lines="double"` or `longerAction`) promotes to `"longer-action"`, else `"default"`. |
119
+ | `resolvedTone` | `SnackbarTone` | Read-only canonical tone actually rendered: explicit `tone` wins, else `type`, else `"neutral"`; deprecated aliases are resolved to `"neutral"` / `"destructive"`. |
120
+
121
+ ## Events
122
+
123
+ | Event | Detail | Bubbles / composed | Description |
124
+ | --- | --- | --- | --- |
125
+ | `actionClick` | — | bubbles / composed | Fired when the action button is clicked, before the snackbar dismisses itself (a `close` event follows). No detail. |
126
+ | `close` | — | bubbles / composed | Fired whenever the snackbar dismisses itself — via the close icon, the action button or the auto-dismiss timer. Not fired when `show` is set to false from script. No detail. |
127
+
128
+ ## Slots
129
+
130
+ | Slot | Description |
131
+ | --- | --- |
132
+ | — | This element has no slots. |
133
+
134
+ ## CSS Parts
135
+
136
+ | Part | Description |
137
+ | --- | --- |
138
+ | `label` | The message text container |
139
+ | `action` | The action button; rendered only when `action` is set |
140
+ | `close-button` | The close icon button; rendered while `iconclose` is true |
141
+
142
+ <!-- readme-gen:end -->
143
+
144
+ ## Accessibility
145
+
146
+ - The bar is always in the shadow DOM and hidden with `display: none` while `show` is false. Its role follows the tone: `role="alert"` for `destructive` (implicitly assertive), `role="status"` for every other tone (implicitly polite); no explicit `aria-live` is set. Because toggling `display` is not reliably announced, the component also pushes `message` into the shared off-screen live-region announcer (`utils/announce`) when `show` becomes true and whenever `message` changes while shown — assertively for `destructive`, politely otherwise. Focus is never moved.
147
+ - The leading status icon and the close glyph are `<rel-icon>`s and render `aria-hidden="true"`; the close control is a native `<button>` with `aria-label="Close"`, the action button is labelled by `action`. Both are in the Tab order; the component registers no key handlers (there is no Escape-to-close):
148
+
149
+ | Key | Action |
150
+ | --- | --- |
151
+ | Tab / Shift + Tab | Move between the action button (if any) and the close button (if any) |
152
+ | Enter / Space | Activate the focused button: action fires `actionClick` then `close`; the close button fires `close` |
153
+
154
+ - Keyboard focus on either button is a 2px `--rel-text-static-light` outline with 2px offset (`:focus-visible` only); the close button adds `--rel-border-radius-xs` corners, the action button keeps its pill radius.
155
+ - The 0.3s slide-up animation is disabled under `prefers-reduced-motion: reduce`.
156
+ - A snackbar that auto-dismisses while one of its buttons has focus drops focus to `<body>`; use `duration="0"` (or `longeraction`) when the action matters.
157
+
158
+ ## Notes / Edge Cases
159
+
160
+ - Positioning is yours: the host is `display: block` and in flow. The bar itself is `min-width: 280px; max-width: 500px`.
161
+ - The auto-dismiss timer starts when `show` becomes true and restarts whenever `duration` or `longerAction` changes while visible; `longerAction` doubles the delay (`duration * 2`). `duration="0"` disables it.
162
+ - Setting `show = false` from script hides the bar **without** firing `close`; `close` fires only for the close icon, the action button and the timer. Setting `show = true` on an already visible snackbar is a no-op (the value did not change).
163
+ - Only `lines="double"` changes the layout (message stacked over end-aligned actions, 16px top padding); `longeraction` only affects timing — combine the two for the Figma Longer Action variant.
164
+ - The status icon is fixed per tone (`check-circle`, `warning`, `error`) and neutral has none; there are no slots, so the icon cannot be replaced.
165
+ - `message` defaults to the placeholder "This is a snackbar message" — a snackbar that shows that text has simply not been given a message.
166
+ - `iconClose` is a Lit boolean: any attribute value (including `"false"`) counts as true. Clear it as a property from script.
167
+ - Figma binds the success / destructive icon colours to dark-surface status text values that no light-mode semantic token resolves to; the component uses the status fill tokens (`--rel-bg-success` / `--rel-bg-danger` / `--rel-bg-warning`) for both the accent and the icon instead.
168
+ - `resolvedTone` is the tone actually rendered after alias resolution; use it (not `tone` / `type`) if you branch on tone in script.