@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,148 +1,165 @@
1
- # rel-toast
2
-
3
- ## Overview
4
- A fixed-position toast notification component for brief feedback messages. Features default and error type variants, optional action buttons, auto-dismiss functionality, and slide-up animation. Positioned at the bottom-center of the viewport with `z-index: 1000`.
5
-
6
- ## Usage
7
- ```html
8
- <!-- Basic toast (must be shown programmatically) -->
9
- <rel-toast id="toast1" message="File saved successfully" type="default"></rel-toast>
10
- <script>
11
- const toast = document.getElementById('toast1');
12
- toast.show(); // Show the toast
13
- </script>
14
-
15
- <!-- Error toast -->
16
- <rel-toast id="errorToast" message="Failed to upload file" type="error"></rel-toast>
17
- <script>
18
- document.getElementById('errorToast').show();
19
- </script>
20
-
21
- <!-- With action button -->
22
- <rel-toast
23
- id="actionToast"
24
- message="Connection lost"
25
- actionLabel="RETRY"
26
- type="default">
27
- </rel-toast>
28
- <script>
29
- const actionToast = document.getElementById('actionToast');
30
- actionToast.addEventListener('action', () => {
31
- console.log('Retry clicked');
32
- // Perform retry logic
33
- });
34
- actionToast.show();
35
- </script>
36
-
37
- <!-- Custom duration (7 seconds) -->
38
- <rel-toast
39
- id="customDuration"
40
- message="Download complete"
41
- duration="7000">
42
- </rel-toast>
43
- <script>
44
- document.getElementById('customDuration').show();
45
- </script>
46
-
47
- <!-- No auto-dismiss -->
48
- <rel-toast
49
- id="persist"
50
- message="Manual dismiss required"
51
- duration="0">
52
- </rel-toast>
53
- <script>
54
- const persist = document.getElementById('persist');
55
- persist.show();
56
- // Manually close later: persist.close();
57
- </script>
58
-
59
- <!-- Listen for dismiss -->
60
- <rel-toast id="notif" message="Update available"></rel-toast>
61
- <script>
62
- const notif = document.getElementById('notif');
63
- notif.addEventListener('dismissed', () => {
64
- console.log('Toast was dismissed');
65
- });
66
- notif.show();
67
- </script>
68
- ```
69
-
70
- ## API
71
-
72
- ### Attributes/Properties
73
- | Name | Type | Default | Description |
74
- |------|------|---------|-------------|
75
- | `message` | `string` | `""` | Toast message text |
76
- | `type` | `"default" \| "error"` | `"default"` | Visual style (default: dark gray, error: red) |
77
- | `actionLabel` | `string` | - | Optional action button label (e.g., "UNDO", "RETRY") |
78
- | `duration` | `number` | `4000` | Auto-dismiss duration in milliseconds (0 = no auto-dismiss) |
79
-
80
- ### Methods
81
- | Method | Description |
82
- |--------|-------------|
83
- | `show()` | Display the toast and start auto-dismiss timer |
84
- | `close()` | Manually dismiss the toast and clear timer |
85
-
86
- ## Events
87
- | Event | Detail | Description |
88
- |-------|--------|-------------|
89
- | `action` | None | Fired when the action button is clicked (toast auto-closes after) |
90
- | `dismissed` | None | Fired when toast is dismissed (via action, close button, or auto-dismiss) |
91
-
92
- ## Slots
93
- Default slot not used.
94
-
95
- ## CSS Parts
96
- None exposed.
97
-
98
- ## Tokens / CSS Variables
99
-
100
- ### Semantic Tokens
101
- - `--rel-fonts-font-family` - Font family
102
- - `--rel-body-md-regular-font-size` - Font size
103
-
104
- ### Spacing Tokens
105
- - `--rel-spacing-sm` - Gap between elements
106
- - `--rel-spacing-md` - Padding
107
- - `--rel-spacing-2xs` - Close button padding and margin
108
-
109
- ### Color Tokens
110
- - `--rel-bg-neutral-inverse-1` - Default background color (dark gray)
111
- - `--rel-text-danger` - Error background color
112
- - `--rel-bg-surface` - Text and focus outline color
113
- - `--rel-bg-brand` - Action button text color
114
-
115
- ### Shadow Tokens
116
- - `--rel-shadows-shadow-300` - Drop shadow
117
-
118
- ### Border Tokens
119
- - `--rel-border-radius-sm` - Border radius
120
-
121
- ## Accessibility
122
- - Uses `role="status"` and `aria-live="polite"` for screen reader announcements
123
- - Focus styles on action and close buttons
124
- - Animation respects `prefers-reduced-motion` media query
125
- - Close button has `aria-label="Dismiss"`
126
-
127
- ### Keyboard Interactions
128
- - `Tab` - Focus action button or close button
129
- - `Space/Enter` - Activate focused button
130
-
131
- ### Focus Behavior
132
- - Buttons show 2px white outline with 2px offset when focused
133
- - Border radius applied to maintain visual consistency
134
-
135
- ## Notes / Edge Cases
136
- - **Important:** Toasts are hidden by default; you must call `show()` to display them
137
- - The component uses `:host` with `position: fixed`, `bottom: 24px`, `left: 50%`, `transform: translateX(-50%)` for bottom-center positioning
138
- - `z-index: 1000` ensures toasts appear above most content
139
- - The toast container is `display: inline-flex` with `pointer-events: all` (while`:host` has `pointer-events: none`)
140
- - Auto-dismiss timer starts when `show()` is called
141
- - Calling `close()` sets `visible = false`, dispatches `dismissed`, and clears the timeout
142
- - Clicking the action button dispatches `action` then automatically calls `close()`
143
- - Setting `duration="0"` disables auto-dismiss
144
- - The component includes a `fadeInUp` animation (20px translateY → 0, opacity 0 → 1) on appearance
145
- - Animation disabled when `prefers-reduced-motion: reduce` is set
146
- - When `visible` is false, `hidden` class applies `display: none`
147
- - **Type variants**: `default` uses `--rel-bg-neutral-inverse-1`, `error` uses `--rel-text-danger`
148
- - The toast appears inline-flex, so it sizes to content width
1
+ # rel-toast
2
+
3
+ `<rel-toast>` is the transient notification of the Reliability Design System: a card anchored to one of six viewport positions (bottom centre by default) that shows a short message, an optional action button ("Undo", "Retry") and a dismiss button, then hides itself after `duration` milliseconds. It has two tones — `default` and `destructive` — and is driven by the `show` property (or `open()` / `close()`). Use it for brief confirmations that need no reply; use `<rel-snackbar>` when you need the status tones, a stacked layout or your own positioning, and `<rel-alert>` for messages that must stay on the page.
4
+
5
+ ## Usage
6
+
7
+ ```html
8
+ <!-- Hidden until `show` is set (or open() is called) -->
9
+ <rel-toast id="saved" message="File saved"></rel-toast>
10
+
11
+ <!-- Initially visible; auto-hides after the default 4000 ms -->
12
+ <rel-toast show message="Welcome back"></rel-toast>
13
+
14
+ <!-- Destructive tone: danger fill, announced assertively -->
15
+ <rel-toast id="failed" tone="destructive" message="Upload failed"></rel-toast>
16
+
17
+ <!-- Action button (attribute is lower-case: actionlabel) -->
18
+ <rel-toast id="deleted" message="Item deleted" actionlabel="Undo"></rel-toast>
19
+
20
+ <!-- Longer and persistent toasts -->
21
+ <rel-toast id="slow" message="Download complete" duration="7000"></rel-toast>
22
+ <rel-toast id="sticky" message="Reconnecting…" duration="0"></rel-toast>
23
+ ```
24
+
25
+ ```js
26
+ const saved = document.getElementById("saved");
27
+ saved.open(); // same as saved.show = true — starts the auto-dismiss timer
28
+ saved.addEventListener("dismissed", () => {
29
+ saved.show; // false — fired by close(), the ✕ button, the action button and the timer
30
+ });
31
+
32
+ const deleted = document.getElementById("deleted");
33
+ deleted.addEventListener("action", () => {
34
+ // undo the deletion… the toast closes itself right after (a `dismissed` event follows)
35
+ });
36
+ deleted.open();
37
+
38
+ const sticky = document.getElementById("sticky");
39
+ sticky.open();
40
+ sticky.close(); // the only way to hide a duration="0" toast from script
41
+ ```
42
+
43
+ ```css
44
+ /* Lift the toast above an open modal / drawer layer */
45
+ rel-toast { --rel-toast-z: 10000; }
46
+ ```
47
+
48
+ ### Deprecated aliases
49
+
50
+ ```html
51
+ <!-- type= is the deprecated alias of tone= (tone wins when both are set). Logs once per page:
52
+ [rel-toast] "type" is deprecated and will be removed in 3.0 — use "tone" instead. Note: tone="destructive" replaces type="error". -->
53
+ <rel-toast type="error" message="Upload failed"></rel-toast>
54
+
55
+ <!-- tone="error" | "danger" | "critical" are deprecated spellings of tone="destructive". Logs once per spelling:
56
+ [rel-toast] "tone="error"" is deprecated and will be removed in 3.0 — use "tone="destructive"" instead. -->
57
+ <rel-toast tone="error" message="Upload failed"></rel-toast>
58
+ <rel-toast tone="danger" message="Upload failed"></rel-toast>
59
+ ```
60
+
61
+ ```css
62
+ /* --rel-z-toast is the deprecated alias of --rel-toast-z; it is still read as the fallback (no console notice). */
63
+ rel-toast { --rel-z-toast: 10000; }
64
+ ```
65
+
66
+ <!-- readme-gen:start -->
67
+
68
+ <!-- Generated from rel-toast.ts — do not edit; run readme-generate.mjs -->
69
+
70
+ ## API
71
+
72
+ ### Attributes / Properties
73
+
74
+ | Property | Attribute | Type | Default | Description |
75
+ | --- | --- | --- | --- | --- |
76
+ | `message` | `message` | `string` | `""` | Text of the toast. It is also announced to screen readers through the shared live-region announcer each time `show` becomes true. |
77
+ | `tone` | `tone` | `"neutral" \| "destructive" \| "default" \| "error" \| "danger" \| "critical"` | `undefined` | Semantic tone (Figma "Tone"): `"neutral"` (default: neutral surface) \| `"destructive"` (danger fill, announced assertively). `"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. |
78
+ | `actionLabel` | `actionlabel` | `string` | `undefined` | Label of the optional action button rendered between the message and the dismiss button; the button is omitted when unset. Clicking it fires `action` and then closes the toast. |
79
+ | `duration` | `duration` | `number` | `4000` | Auto-dismiss delay in milliseconds, started each time `show` becomes true. `0` (or a negative value) disables auto-dismiss so the toast stays until `close()` or the dismiss button. Changing it while the toast is visible does not restart the running timer. |
80
+ | `show` | `show` | `boolean` | `false` | Whether the toast is visible. Set it to true (or call `open()`) to show the toast and start the auto-dismiss timer; it is set back to false by `close()`, the dismiss button, the action button and the timer. Reflected. |
81
+ | `dismissible` | `dismissible` | `boolean` | `true` | Shows the trailing dismiss button (Figma "Show Close Button"). Defaults to true; because it is a Lit boolean, `dismissible="false"` is still true — set the property to `false` from script to hide the button. |
82
+ | `position` | `position` | `"top-left" \| "top-center" \| "top-right" \| "bottom-left" \| "bottom-center" \| "bottom-right"` | `"bottom-center"` | Where the toast is anchored: `bottom-center` (default, unchanged from before this prop existed), `bottom-left`, `bottom-right`, `top-left`, `top-center` or `top-right`. Top anchors also animate in from the top edge rather than upward from the bottom. Figma's Toast has axes Content / Show Button / Show Close Button / Tone and no position, so this axis is ours. Reflected. |
83
+ | `size` | `size` | `"small" \| "medium" \| "large" \| "sm" \| "md" \| "lg"` | `"medium"` | Toast scale: `small`, `medium` (default, unchanged) or `large`. `sm` / `md` / `lg` are alternative spellings and stay supported — normalised to the full words, not deprecated. Scales the padding, the inner gap, the message type role and the close icon. Figma has no Size axis on Toast. Reflected. |
84
+ | `maxVisible` | `max-visible` | `number` | `3` | How many toasts may be on screen at once AT THIS POSITION. Further ones wait their turn rather than being dropped — a notification the user never saw is worse than a late one — and each toast's `duration` only starts once it actually becomes visible, so a queued message cannot expire unseen. Default 3; unbounded stacking just fills the viewport. |
85
+
86
+ #### Deprecated (still supported — removal targeted for 3.0)
87
+
88
+ | Property | Attribute | Type | Use instead |
89
+ | --- | --- | --- | --- |
90
+ | `type` | `type` | `"neutral" \| "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. |
91
+
92
+ ### Public fields / accessors
93
+
94
+ | Name | Type | Description |
95
+ | --- | --- | --- |
96
+ | `resolvedTone` | `ToastTone` | Read-only canonical tone actually rendered: explicit `tone` wins, else `type`, else `"neutral"`; deprecated aliases are resolved to `"neutral"` / `"destructive"`. |
97
+
98
+ ### Methods
99
+
100
+ | Method | Signature | Description |
101
+ | --- | --- | --- |
102
+ | `open` | `open()` | Shows the toast: sets `show = true`, which starts the auto-dismiss timer and announces `message`. |
103
+ | `close` | `close()` | Hides the toast, clears the auto-dismiss timer and fires `dismissed`. It fires `dismissed` even when the toast was already hidden. |
104
+
105
+ ## Events
106
+
107
+ | Event | Detail | Bubbles / composed | Description |
108
+ | --- | --- | --- | --- |
109
+ | `action` | — | bubbles / composed | Fired when the action button is clicked, before the toast closes itself (a `dismissed` event follows). No detail. |
110
+ | `dismissed` | — | bubbles / composed | Fired whenever the toast is closed — by `close()`, the dismiss button, the action button or the auto-dismiss timer. No detail. |
111
+
112
+ ## Slots
113
+
114
+ | Slot | Description |
115
+ | --- | --- |
116
+ | — | This element has no slots. |
117
+
118
+ ## CSS Parts
119
+
120
+ | Part | Description |
121
+ | --- | --- |
122
+ | `base` | The `role="status"` toast container that carries the tone class |
123
+ | `label` | The message text span |
124
+ | `action` | The action button; rendered only when `actionlabel` is set |
125
+ | `close-button` | The dismiss button; rendered while `dismissible` is true |
126
+
127
+ ## Tokens / CSS Variables
128
+
129
+ ### Component hooks
130
+
131
+ Set these on the host (or an ancestor) to customise the element without touching design tokens.
132
+
133
+ | Custom property | Default | Description |
134
+ | --- | --- | --- |
135
+ | `--rel-toast-z` | `var(--rel-z-toast, 9000)` | `z-index` of the fixed host (default `9000`); raise it when a modal or drawer layer covers the toast |
136
+
137
+ <!-- readme-gen:end -->
138
+
139
+ ## Accessibility
140
+
141
+ - The toast container (part `base`) is always in the shadow DOM with `role="status"`, `aria-live="polite"` and `aria-atomic="true"`; it is hidden with `display: none` while `show` is false. Because toggling `display` is not reliably announced, the component also pushes `message` into the shared off-screen live-region announcer (`utils/announce`) every time `show` becomes true — politely for `default`, assertively for `destructive`. Focus is never moved.
142
+ - Two native `<button>`s: the optional action button (labelled by `actionlabel`) and the dismiss button with `aria-label="Dismiss"`. Both are in the Tab order; the component registers no key handlers (there is no Escape-to-close):
143
+
144
+ | Key | Action |
145
+ | --- | --- |
146
+ | Tab / Shift + Tab | Move between the action button (if any) and the dismiss button; the toast sits in the Tab order at its DOM position, not at the end of the page |
147
+ | Enter / Space | Activate the focused button: action fires `action` then `dismissed`; dismiss fires `dismissed` |
148
+
149
+ - Keyboard focus on either button is a 2px `--rel-text-static-light` outline with 2px offset and `--rel-border-radius-xs` corners (`:focus-visible` only).
150
+ - The 0.25s fade-in-up animation is disabled under `prefers-reduced-motion: reduce`.
151
+ - A toast that auto-dismisses while a button inside it has focus drops focus to `<body>`; give important actions a `duration="0"` toast or a persistent control elsewhere.
152
+
153
+ ## Notes / Edge Cases
154
+
155
+ - `show` is a boolean **property**, not a method: `toast.show()` throws. Use `toast.show = true` or `toast.open()`; the old README's `show()` call was wrong.
156
+ - The host is a full-width `position: fixed` bar (`left: 0; right: 0`) pinned to the edge named by `position`, with `pointer-events: none` (the pill itself restores `pointer-events: all`), so it never blocks clicks around it. The corner positions add a 24px side inset so the toast does not sit flush against the viewport edge; the centred ones keep the full width to centre in, which is why `bottom-center` is unchanged from before the axis existed.
157
+ - Top-anchored toasts animate in from the top edge (`fadeInDown`) rather than sliding upward, which would have read as the toast escaping its own anchor.
158
+ - **Toasts at the same `position` stack automatically.** No wrapper element and no change to your markup: each `rel-toast` registers itself, and up to `max-visible` (default 3) show at once with the newest against the anchor edge. Dismissing one closes the gap for the rest, animated. The six positions are independent stacks, and a toast whose `position` changes while it is showing leaves one and joins the other.
159
+ - **Overflow waits; it is never dropped.** Beyond `max-visible`, further toasts queue in arrival order and appear as earlier ones dismiss. A toast's `duration` does not begin until it is actually on screen, so a queued message cannot expire before anyone has seen it. *Behaviour change*: five toasts at one position used to render on top of each other — now three show and two wait.
160
+ - A single toast is unaffected by any of this: the stack only writes a transform from the second card onward, so a lone toast renders exactly as it did before stacking existed.
161
+ - The auto-dismiss timer starts only when `show` changes to true; changing `duration` on a visible toast does not restart it. Re-showing a visible toast (setting `show = true` again) is a no-op because the value did not change — `close()` it first.
162
+ - `close()` always fires `dismissed`, even when the toast was already hidden.
163
+ - The action button's hover state swaps to `--rel-bg-neutral` / `--rel-text-default` at 75% opacity.
164
+ - Layering: the host's `z-index` is `--rel-toast-z` (default 9000; the pre-rename `--rel-z-toast` still works as its fallback). Raise it on the element or an ancestor if an overlay with a higher `z-index` covers the toast; anything rendered in the browser top layer (native `<dialog>` / Popover API content) always paints above it regardless of `z-index`.
165
+ - `resolvedTone` is the tone actually rendered after alias resolution; use it (not `tone` / `type`) if you branch on tone in script.
@@ -1,111 +1,119 @@
1
- # rel-tooltip
2
-
3
- ## Overview
4
- A simple tooltip component that displays contextual text on hover. Supports above/below positioning and optional tail (arrow pointer). Uses CSS opacity transitions for smooth fade-in/out effects. Content is provided via a `<slot>` for flexible trigger elements.
5
-
6
- ## Usage
7
- ```html
8
- <!-- Basic tooltip (above) -->
9
- <rel-tooltip text="This is a helpful tooltip">
10
- <button>Hover me</button>
11
- </rel-tooltip>
12
-
13
- <!-- Tooltip positioned below -->
14
- <rel-tooltip text="Information appears below" position="below">
15
- <span>Hover for info</span>
16
- </rel-tooltip>
17
-
18
- <!-- With tail/arrow -->
19
- <rel-tooltip text="Tooltip with pointer" position="above" showTail>
20
- <button>Hover me</button>
21
- </rel-tooltip>
22
-
23
- <!-- Tooltip on icon -->
24
- <rel-tooltip text="Edit item" showTail>
25
- <img src="edit-icon.svg" alt="Edit">
26
- </rel-tooltip>
27
-
28
- <!-- Multiple elements in trigger -->
29
- <rel-tooltip text="Profile options" position="below">
30
- <div class="user-avatar">
31
- <img src="avatar.jpg" alt="User">
32
- <span>John Doe</span>
33
- </div>
34
- </rel-tooltip>
35
- ```
36
-
37
- ## API
38
-
39
- ### Attributes/Properties
40
- | Name | Type | Default | Description |
41
- |------|------|---------|-------------|
42
- | `text` | `string` | `""` | Tooltip text content |
43
- | `position` | `"above" \| "below"` | `"above"` | Vertical position relative to trigger |
44
- | `showTail` | `boolean` | `false` | Whether to show the arrow/pointer |
45
-
46
- ## Events
47
- None.
48
-
49
- ## Slots
50
- | Slot | Description |
51
- |------|-------------|
52
- | (default) | Trigger element(s) that activate the tooltip on hover |
53
-
54
- ## CSS Parts
55
- None exposed.
56
-
57
- ## Tokens / CSS Variables
58
-
59
- ### Semantic Tokens
60
- - `--rel-fonts-font-family` - Font family
61
- - `--rel-body-sm-regular-font-size` - Font size
62
-
63
- ### Spacing Tokens
64
- - `--rel-spacing-xs` - Vertical padding
65
- - `--rel-spacing-sm` - Horizontal padding
66
-
67
- ### Color Tokens
68
- - `--rel-bg-neutral-inverse-2` - Background color (near-black in light theme, white in dark theme)
69
- - `--rel-text-inverse` - Text color (white in light theme, near-black in dark theme)
70
- - `--rel-colors-dark-alpha-3` - Elevation shadow color (Figma `shadow/sm`: 0 2px 4px at 10% black; applied via `drop-shadow` so the tail casts the same shadow as the bubble)
71
-
72
- ### Border Tokens
73
- - `--rel-border-radius-sm` - Border radius
74
-
75
- ### Theming
76
- Colors use inverse semantic tokens, so the tooltip adapts automatically when
77
- `data-theme="dark"` (or `.dark`) is set on an ancestor — no page refresh needed.
78
- Dark-theme rendering (white bubble, dark text) is unchanged by the elevation
79
- shadow, which is effectively invisible on dark backgrounds.
80
-
81
- ## Accessibility
82
- - Uses `role="tooltip"` on the tooltip bubble
83
- - `aria-hidden="true"` on tooltip (content is supplemental, not critical)
84
- - Tooltip does not receive focus (purely decorative on hover)
85
- - For critical information, consider alternative patterns (e.g., visible labels or expandable sections)
86
-
87
- ### Keyboard Interactions
88
- - Tooltip shows on `:focus-within` as well as hover, so keyboard users see it when the slotted trigger receives focus (ensure the trigger is focusable)
89
- - `Escape` dismisses the tooltip (APG); it re-arms once hover/focus leaves and returns
90
- - Keyboard-triggered tooltips use the same theme-aware styling as hover-triggered ones
91
-
92
- ### Focus Behavior
93
- - Tooltip activates on hover or focus within the trigger
94
- - Does not interfere with focus on slotted content
95
-
96
- ## Notes / Edge Cases
97
- - The tooltip appears on `:host(:hover)` via CSS `opacity: 1` transition
98
- - By default, tooltip has `opacity: 0` and `pointer-events: none`
99
- - **Position "above"**: tooltip is positioned at `bottom: calc(100% + 8px)` (8px gap above trigger)
100
- - **Position "below"**: tooltip is positioned at `top: calc(100% + 8px)` (8px gap below trigger)
101
- - The tooltip uses `left: 50%` and `transform: translateX(-50%)` for horizontal centering
102
- - `white-space: nowrap` prevents text wrapping (tooltip width adjusts to content)
103
- - **Tail/arrow** is a CSS triangle created with transparent borders:
104
- - Above pointer: 6px border-top, positioned at `bottom: -6px`
105
- - Below pointer: 6px border-bottom, positioned at `top: -6px`
106
- - Tail uses `left: 50%` and `transform: translateX(-50%)` for centering
107
- - The tooltip has `z-index: 1000` to appear above most content
108
- - The tooltip is `position: absolute` relative to `:host` (which is `position: relative`)
109
- - `:host` is `display: inline-block` to size to slotted content
110
- - Transition duration is `0.2s ease` for opacity changes
111
- - For very long tooltip text, consider wrapping or alternative UI patterns (max-width not set by default)
1
+ # rel-tooltip
2
+
3
+ Hover/focus tooltip implementing the Figma "Tooltip" component: wraps a trigger element and fades in a short inverse-coloured text bubble above, below, left or right of it, in the Figma `single-line` or `multi-line` **Type**, optionally with a pointing tail. Use it for brief supplementary hints on icon buttons and truncated labels. Do not put critical or interactive content in it — it is not reachable on touch, cannot be focused, and disappears on hover-out.
4
+
5
+ ## Usage
6
+
7
+ ```html
8
+ <!-- Default: above the trigger -->
9
+ <rel-tooltip text="Save your changes">
10
+ <rel-button variant="primary">Save</rel-button>
11
+ </rel-tooltip>
12
+
13
+ <!-- Positions -->
14
+ <rel-tooltip text="Appears below" position="below">
15
+ <rel-button variant="secondary">Below</rel-button>
16
+ </rel-tooltip>
17
+ <rel-tooltip text="Appears on the left" position="left">
18
+ <rel-button variant="secondary">Left</rel-button>
19
+ </rel-tooltip>
20
+ <rel-tooltip text="Appears on the right" position="right">
21
+ <rel-button variant="secondary">Right</rel-button>
22
+ </rel-tooltip>
23
+
24
+ <!-- With the pointing tail -->
25
+ <rel-tooltip text="Edit" show-tail>
26
+ <rel-button variant="ghost" icon-only aria-label="Edit">
27
+ <rel-icon name="edit"></rel-icon>
28
+ </rel-button>
29
+ </rel-tooltip>
30
+
31
+ <!-- Multi-line: wraps inside a 220px bubble -->
32
+ <rel-tooltip
33
+ type="multi-line"
34
+ position="below"
35
+ show-tail
36
+ text="Exports the current view as CSV. Filters and sorting are preserved."
37
+ >
38
+ <rel-button variant="secondary">Export</rel-button>
39
+ </rel-tooltip>
40
+
41
+ <!-- Restyle the bubble through its part -->
42
+ <style>
43
+ .wide::part(panel) {
44
+ max-width: 320px;
45
+ }
46
+ </style>
47
+ <rel-tooltip class="wide" type="multi-line" text="A longer explanation that needs more room than the default bubble.">
48
+ <rel-button variant="ghost">Details</rel-button>
49
+ </rel-tooltip>
50
+ ```
51
+
52
+ <!-- readme-gen:start -->
53
+
54
+ <!-- Generated from rel-tooltip.ts — do not edit; run readme-generate.mjs -->
55
+
56
+ ## API
57
+
58
+ ### Attributes / Properties
59
+
60
+ | Property | Attribute | Type | Default | Description |
61
+ | --- | --- | --- | --- | --- |
62
+ | `text` | `text` | `string` | `""` | Plain-text content of the bubble. Empty text still renders an (empty) bubble on hover, so always set it. |
63
+ | `position` | `position` | `"above" \| "below" \| "left" \| "right"` | `"above"` | Side of the trigger the bubble appears on, centred and 6px away (13px when `show-tail` is set, so the tail clears the trigger; override with `--rel-tooltip-offset`): `above`, `below`, `left` or `right`. No collision detection — pick a side with room in the viewport. |
64
+ | `showTail` | `show-tail` | `boolean` | `false` | Renders the triangular tail (`indicator` part) on the bubble's edge facing the trigger. |
65
+ | `type` | `type` | `"single-line" \| "multi-line"` | `"single-line"` | Figma "Type": `single-line` keeps the text on one line and sizes to content; `multi-line` wraps inside a 200px max-width bubble. Reflected. |
66
+ | `tone` | `tone` | `"inverse" \| "neutral"` | `"inverse"` | Bubble appearance: `inverse` (default) is the original inverse-surface bubble, unchanged; `neutral` is a light surface — `--rel-bg-neutral` with `--rel-text-default` and a 1px `--rel-border-default`, tail included. Figma has no such variant; this is a deliberate addition. Reflected. |
67
+
68
+ ## Events
69
+
70
+ | Event | Detail | Bubbles / composed | Description |
71
+ | --- | --- | --- | --- |
72
+ | — | — | — | This element emits no custom events. |
73
+
74
+ ## Slots
75
+
76
+ | Slot | Description |
77
+ | --- | --- |
78
+ | (default) | The trigger element (one focusable element such as a button or icon button). It receives `aria-describedby` pointing at the bubble. |
79
+
80
+ ## CSS Parts
81
+
82
+ | Part | Description |
83
+ | --- | --- |
84
+ | `panel` | The tooltip bubble (`role="tooltip"`): background, padding, radius, shadow and max-width. |
85
+ | `indicator` | The triangular tail pointing at the trigger, rendered only when `show-tail` is set. |
86
+
87
+ ## Tokens / CSS Variables
88
+
89
+ ### Component hooks
90
+
91
+ Set these on the host (or an ancestor) to customise the element without touching design tokens.
92
+
93
+ | Custom property | Default | Description |
94
+ | --- | --- | --- |
95
+ | `--rel-tooltip-offset` | `6px` | Gap between the trigger and the bubble; defaults to `6px`, or `13px` when `show-tail` is set so the tail clears the trigger. |
96
+
97
+ <!-- readme-gen:end -->
98
+
99
+ ## Accessibility
100
+
101
+ - The bubble is a `role="tooltip"` element with a stable generated `id`; the first slotted element is given `aria-describedby` pointing at it (re-linked on `slotchange`), so screen readers read the hint as the trigger's description.
102
+ - The bubble is shown while the host is hovered **or** has focus within (`:focus-within`), so keyboard users see it when the slotted trigger is focused. The trigger therefore must be focusable — wrap a button or link, not plain text.
103
+ - The bubble never takes focus and has `pointer-events: none`.
104
+
105
+ | Key | Action |
106
+ | --- | --- |
107
+ | `Tab` | Focus the slotted trigger; the tooltip appears |
108
+ | `Escape` | Dismiss the tooltip (APG pattern). The key is not swallowed, so an enclosing dialog may also react to it |
109
+
110
+ After `Escape` the tooltip stays hidden until the pointer leaves and returns or focus leaves and returns (`mouseleave` / `focusout` clear the dismissed state).
111
+
112
+ ## Notes / Edge Cases
113
+
114
+ - **Attribute spelling is `show-tail`** (kebab-case). `showTail="…"` as an HTML attribute does nothing; set the property in code.
115
+ - **Positioning is static.** The bubble is `position: absolute` relative to the host (which is `display: inline-block; position: relative`), 6px from the trigger, centred on it, with `z-index: 1000`. There is no flipping or viewport collision detection, and ancestors with `overflow: hidden` or their own stacking context will clip it — for popover-style panels use `rel-popover`.
116
+ - `single-line` bubbles use `white-space: nowrap` and grow with the text; `multi-line` wraps at a 220px `max-width` (override it via `::part(panel)`).
117
+ - The bubble's shadow is applied with `filter: drop-shadow` so the tail (`indicator` part) casts the same shadow as the panel.
118
+ - Colours use the inverse neutral tokens, so the tooltip flips automatically (dark bubble on light themes, light bubble under `data-theme="dark"` / `.dark`).
119
+ - The hint is read from `text` only; slotted content is the trigger, not the tooltip body.