@reliability-design/web 1.4.6 → 1.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +211 -49
- package/dist/components/rel-accordion/README.md +132 -132
- package/dist/components/rel-alert/README.md +145 -141
- package/dist/components/rel-autocomplete/README.md +156 -61
- package/dist/components/rel-avatar/README.md +116 -130
- package/dist/components/rel-badge/README.md +98 -93
- package/dist/components/rel-breadcrumb/README.md +96 -102
- package/dist/components/rel-button/README.md +160 -130
- package/dist/components/rel-calendar/README.md +109 -109
- package/dist/components/rel-card/README.md +75 -94
- package/dist/components/rel-cardmedia/README.md +100 -127
- package/dist/components/rel-carousel/README.md +184 -166
- package/dist/components/rel-checkbox/README.md +93 -75
- package/dist/components/rel-chip/README.md +132 -121
- package/dist/components/rel-container/README.md +107 -99
- package/dist/components/rel-date-picker/README.md +200 -289
- package/dist/components/rel-divider/README.md +78 -100
- package/dist/components/rel-drawer/README.md +187 -200
- package/dist/components/rel-kbd/README.md +141 -151
- package/dist/components/rel-menu/README.md +178 -151
- package/dist/components/rel-menubar/README.md +218 -329
- package/dist/components/rel-otp/README.md +170 -440
- package/dist/components/rel-pagination/README.md +100 -424
- package/dist/components/rel-popover/README.md +203 -568
- package/dist/components/rel-progress/README.md +88 -110
- package/dist/components/rel-radio/README.md +131 -138
- package/dist/components/rel-range-picker/README.md +162 -0
- package/dist/components/rel-resizable/README.md +199 -140
- package/dist/components/rel-segmented-button/README.md +155 -141
- package/dist/components/rel-select/README.md +154 -93
- package/dist/components/rel-sheet/README.md +168 -224
- package/dist/components/rel-skeleton/README.md +103 -0
- package/dist/components/rel-slider/README.md +130 -135
- package/dist/components/rel-snackbar/README.md +162 -134
- package/dist/components/rel-stepper/README.md +158 -160
- package/dist/components/rel-switch/README.md +108 -102
- package/dist/components/rel-tab/README.md +171 -163
- package/dist/components/rel-textfield/README.md +159 -69
- package/dist/components/rel-time-picker/README.md +122 -157
- package/dist/components/rel-toast/README.md +157 -148
- package/dist/components/rel-tooltip/README.md +108 -111
- package/dist/components/rel-upload/README.md +220 -0
- package/dist/index.d.mts +1147 -340
- package/dist/index.d.ts +1147 -340
- package/dist/index.js +3451 -3163
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3416 -3118
- package/dist/index.mjs.map +1 -1
- package/dist/styles/vars.css +877 -866
- package/dist/{vars-XNMTSRVN.css → vars-JHTUGNRG.css} +877 -866
- package/package.json +3 -2
- package/dist/components/rel-accordion/rel-accordion.ts +0 -336
- package/dist/components/rel-alert/rel-alert.ts +0 -305
- package/dist/components/rel-autocomplete/rel-autocomplete.ts +0 -720
- package/dist/components/rel-avatar/rel-avatar.ts +0 -142
- package/dist/components/rel-badge/rel-badge.ts +0 -175
- package/dist/components/rel-breadcrumb/rel-breadcrumb.ts +0 -106
- package/dist/components/rel-button/rel-button.ts +0 -560
- package/dist/components/rel-calendar/index.ts +0 -1
- package/dist/components/rel-calendar/rel-calendar.ts +0 -565
- package/dist/components/rel-card/rel-card.ts +0 -88
- package/dist/components/rel-cardmedia/rel-cardmedia.ts +0 -88
- package/dist/components/rel-carousel/index.ts +0 -1
- package/dist/components/rel-carousel/rel-carousel.ts +0 -723
- package/dist/components/rel-chart/README.md +0 -286
- package/dist/components/rel-chart/index.ts +0 -1
- package/dist/components/rel-chart/rel-chart.ts +0 -754
- package/dist/components/rel-checkbox/rel-checkbox.ts +0 -382
- package/dist/components/rel-chip/rel-chip.ts +0 -483
- package/dist/components/rel-container/rel-container.ts +0 -95
- package/dist/components/rel-date-picker/date-format.test.ts +0 -43
- package/dist/components/rel-date-picker/date-format.ts +0 -47
- package/dist/components/rel-date-picker/date-parse.test.ts +0 -116
- package/dist/components/rel-date-picker/date-parse.ts +0 -178
- package/dist/components/rel-date-picker/index.ts +0 -1
- package/dist/components/rel-date-picker/rel-date-picker.ts +0 -1676
- package/dist/components/rel-divider/rel-divider.ts +0 -54
- package/dist/components/rel-drawer/index.ts +0 -1
- package/dist/components/rel-drawer/rel-drawer-footer.ts +0 -27
- package/dist/components/rel-drawer/rel-drawer.ts +0 -607
- package/dist/components/rel-kbd/rel-kbd.ts +0 -188
- package/dist/components/rel-layout/rel-layout.ts +0 -49
- package/dist/components/rel-menu/rel-menu.ts +0 -541
- package/dist/components/rel-menubar/index.ts +0 -2
- package/dist/components/rel-menubar/rel-menubar-menu.css +0 -3
- package/dist/components/rel-menubar/rel-menubar-menu.ts +0 -17
- package/dist/components/rel-menubar/rel-menubar.ts +0 -777
- package/dist/components/rel-nav-menu/README.md +0 -289
- package/dist/components/rel-nav-menu/index.ts +0 -3
- package/dist/components/rel-nav-menu/rel-nav-menu-item.ts +0 -243
- package/dist/components/rel-nav-menu/rel-nav-menu-panel.ts +0 -72
- package/dist/components/rel-nav-menu/rel-nav-menu.ts +0 -270
- package/dist/components/rel-navbar/README.md +0 -126
- package/dist/components/rel-navbar/rel-navbar.ts +0 -105
- package/dist/components/rel-otp/index.ts +0 -1
- package/dist/components/rel-otp/rel-otp.ts +0 -527
- package/dist/components/rel-pagination/index.ts +0 -1
- package/dist/components/rel-pagination/rel-pagination.ts +0 -522
- package/dist/components/rel-popover/index.ts +0 -2
- package/dist/components/rel-popover/rel-popover-content.ts +0 -81
- package/dist/components/rel-popover/rel-popover.ts +0 -475
- package/dist/components/rel-progress/rel-progress.ts +0 -234
- package/dist/components/rel-radio/rel-radio.ts +0 -481
- package/dist/components/rel-range-picker/rel-range-picker.ts +0 -1688
- package/dist/components/rel-resizable/index.ts +0 -3
- package/dist/components/rel-resizable/rel-resizable-group.ts +0 -405
- package/dist/components/rel-resizable/rel-resizable-handle.ts +0 -150
- package/dist/components/rel-resizable/rel-resizable-panel.ts +0 -58
- package/dist/components/rel-segmented-button/rel-segmented-button.ts +0 -217
- package/dist/components/rel-select/rel-select.ts +0 -1416
- package/dist/components/rel-sheet/rel-sheet.ts +0 -610
- package/dist/components/rel-sidebar/README.md +0 -209
- package/dist/components/rel-sidebar/rel-sidebar.ts +0 -1191
- package/dist/components/rel-skeleton/rel-skeleton.ts +0 -143
- package/dist/components/rel-slider/rel-slider.ts +0 -673
- package/dist/components/rel-snackbar/rel-snackbar.ts +0 -329
- package/dist/components/rel-stepper/rel-stepper.ts +0 -567
- package/dist/components/rel-switch/rel-switch.ts +0 -199
- package/dist/components/rel-tab/rel-tab.ts +0 -264
- package/dist/components/rel-table/README.md +0 -178
- package/dist/components/rel-table/rel-table-body.ts +0 -22
- package/dist/components/rel-table/rel-table-caption.ts +0 -30
- package/dist/components/rel-table/rel-table-cell.ts +0 -43
- package/dist/components/rel-table/rel-table-footer.ts +0 -24
- package/dist/components/rel-table/rel-table-head.ts +0 -47
- package/dist/components/rel-table/rel-table-header.ts +0 -22
- package/dist/components/rel-table/rel-table-row.ts +0 -37
- package/dist/components/rel-table/rel-table.ts +0 -62
- package/dist/components/rel-textfield/rel-textfield.ts +0 -1054
- package/dist/components/rel-time-picker/rel-time-picker.ts +0 -1482
- package/dist/components/rel-time-picker/time-parse.test.ts +0 -67
- package/dist/components/rel-time-picker/time-parse.ts +0 -85
- package/dist/components/rel-toast/rel-toast.ts +0 -206
- package/dist/components/rel-tooltip/rel-tooltip.ts +0 -193
- package/dist/components/rel-topbar/rel-topbar-actions.ts +0 -27
- package/dist/components/rel-topbar/rel-topbar-brand.ts +0 -54
- package/dist/components/rel-topbar/rel-topbar-dropdown-item.ts +0 -69
- package/dist/components/rel-topbar/rel-topbar-dropdown.ts +0 -31
- package/dist/components/rel-topbar/rel-topbar-item.ts +0 -324
- package/dist/components/rel-topbar/rel-topbar-mobile-panel.ts +0 -27
- package/dist/components/rel-topbar/rel-topbar-profile.ts +0 -243
- package/dist/components/rel-topbar/rel-topbar-utilities.ts +0 -27
- package/dist/components/rel-topbar/rel-topbar.ts +0 -446
- package/dist/components/rel-upload/UPLOAD-DESIGN-CHANGES.md +0 -134
- package/dist/components/rel-upload/rel-upload-actions.ts +0 -163
- package/dist/components/rel-upload/rel-upload.ts +0 -968
|
@@ -1,141 +1,145 @@
|
|
|
1
|
-
# rel-alert
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
```html
|
|
8
|
-
<!--
|
|
9
|
-
<rel-alert
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
<rel-alert
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
<!--
|
|
22
|
-
<rel-alert
|
|
23
|
-
|
|
24
|
-
message1="
|
|
25
|
-
message2="
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
<rel-alert
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
|
74
|
-
|
|
|
75
|
-
| `
|
|
76
|
-
| `
|
|
77
|
-
| `
|
|
78
|
-
| `
|
|
79
|
-
| `
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
-
|
|
119
|
-
|
|
120
|
-
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
- `
|
|
125
|
-
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
-
|
|
135
|
-
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
- `
|
|
140
|
-
- The
|
|
141
|
-
-
|
|
1
|
+
# rel-alert
|
|
2
|
+
|
|
3
|
+
`<rel-alert>` is the inline status banner of the Reliability Design System (Figma "Alert"). It renders a tone-coloured box with a leading status icon, a bold title (`message1`), optional supporting text (`message2`), an optional inline link and an optional dismiss button, in the Figma Tone (neutral / info / success / warning / destructive) and Style (subtle / solid / outline) variants. Use it for persistent, in-flow messages about a page or section — form-level validation, degraded-service notices, onboarding hints. For transient feedback that disappears on its own use `<rel-toast>` or `<rel-snackbar>`; for blocking decisions use `<rel-modal>`.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```html
|
|
8
|
+
<!-- Neutral (default tone, subtle appearance) -->
|
|
9
|
+
<rel-alert message1="Scheduled maintenance on Sunday 02:00–04:00 UTC"></rel-alert>
|
|
10
|
+
|
|
11
|
+
<!-- Tones -->
|
|
12
|
+
<rel-alert tone="info" message1="Update available" message2="Version 2.3 adds offline mode."></rel-alert>
|
|
13
|
+
<rel-alert tone="success" message1="Changes saved" message2="Your profile is up to date."></rel-alert>
|
|
14
|
+
<rel-alert tone="warning" message1="Storage almost full" message2="You have used 95% of your quota."></rel-alert>
|
|
15
|
+
<rel-alert tone="destructive" message1="Upload failed" message2="The file exceeds the 25 MB limit."></rel-alert>
|
|
16
|
+
|
|
17
|
+
<!-- Appearance: subtle (default) | solid | outline -->
|
|
18
|
+
<rel-alert tone="info" appearance="solid" message1="Solid alert"></rel-alert>
|
|
19
|
+
<rel-alert tone="info" appearance="outline" message1="Outline alert"></rel-alert>
|
|
20
|
+
|
|
21
|
+
<!-- Inline link: both url-text and url-href are required for it to render -->
|
|
22
|
+
<rel-alert
|
|
23
|
+
tone="info"
|
|
24
|
+
message1="Release notes"
|
|
25
|
+
message2="See what changed in this version."
|
|
26
|
+
url-text="Read more"
|
|
27
|
+
url-href="https://example.com/release-notes"
|
|
28
|
+
></rel-alert>
|
|
29
|
+
|
|
30
|
+
<!-- Non-dismissible: the boolean must be cleared from script (see the js block) -->
|
|
31
|
+
<rel-alert id="locked" tone="warning" message1="Action required"></rel-alert>
|
|
32
|
+
|
|
33
|
+
<!-- Listen for dismissal -->
|
|
34
|
+
<rel-alert id="saved" tone="success" message1="Saved"></rel-alert>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
```js
|
|
38
|
+
// A Lit boolean attribute is true whenever present, so dismissible="false" does NOT work.
|
|
39
|
+
document.getElementById("locked").dismissible = false;
|
|
40
|
+
|
|
41
|
+
const saved = document.getElementById("saved");
|
|
42
|
+
saved.addEventListener("dismiss", () => {
|
|
43
|
+
saved.dismissed; // true — the host is now display: none
|
|
44
|
+
});
|
|
45
|
+
// Show it again later:
|
|
46
|
+
saved.dismissed = false;
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Deprecated aliases
|
|
50
|
+
|
|
51
|
+
```html
|
|
52
|
+
<!-- type= is the deprecated alias of tone= (tone wins when both are set). Logs once per page:
|
|
53
|
+
[rel-alert] "type" is deprecated and will be removed in 3.0 — use "tone" instead. Note: tone="destructive" replaces type="error". -->
|
|
54
|
+
<rel-alert type="error" message1="Upload failed"></rel-alert>
|
|
55
|
+
|
|
56
|
+
<!-- tone="error" | "danger" | "critical" are deprecated spellings of tone="destructive". Logs once per spelling:
|
|
57
|
+
[rel-alert] "tone="error"" is deprecated and will be removed in 3.0 — use "tone="destructive"" instead. -->
|
|
58
|
+
<rel-alert tone="error" message1="Upload failed"></rel-alert>
|
|
59
|
+
<rel-alert tone="critical" message1="Upload failed"></rel-alert>
|
|
60
|
+
|
|
61
|
+
<!-- appearance="filled" is the deprecated alias of appearance="solid" (no console notice). -->
|
|
62
|
+
<rel-alert tone="info" appearance="filled" message1="Solid alert"></rel-alert>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
<!-- readme-gen:start -->
|
|
66
|
+
|
|
67
|
+
<!-- Generated from rel-alert.ts — do not edit; run readme-generate.mjs -->
|
|
68
|
+
|
|
69
|
+
## API
|
|
70
|
+
|
|
71
|
+
### Attributes / Properties
|
|
72
|
+
|
|
73
|
+
| Property | Attribute | Type | Default | Description |
|
|
74
|
+
| --- | --- | --- | --- | --- |
|
|
75
|
+
| `tone` | `tone` | `"neutral" \| "info" \| "success" \| "warning" \| "destructive" \| "error" \| "danger" \| "critical"` | `undefined` | Semantic tone (Figma "Tone"): `"neutral"` (default) \| `"info"` \| `"success"` \| `"warning"` \| `"destructive"`. Drives the fill/border colour, the title colour and the leading icon (info, check-circle, alert-circle, error). `"error"`, `"danger"` and `"critical"` are deprecated aliases of `"destructive"` and log a one-time console notice. Takes precedence over the deprecated `type` prop. |
|
|
76
|
+
| `appearance` | `appearance` | `"solid" \| "subtle" \| "outline" \| "filled"` | `"subtle"` | Visual treatment (Figma "Style"): `"subtle"` (default: tone-light fill, no border) \| `"solid"` (tone fill, inverse text, `--rel-shadows-md` elevation) \| `"outline"` (transparent fill, tone border). `"filled"` is a deprecated alias of `"solid"` (no console notice). Reflected. |
|
|
77
|
+
| `message1` | `message1` | `string` | `""` | Primary message (title), rendered in body-lg medium weight in the tone colour. |
|
|
78
|
+
| `message2` | `message2` | `string` | `undefined` | Optional secondary message rendered under the title in body-md at 90% opacity; omitted when unset. |
|
|
79
|
+
| `urlText` | `url-text` | `string` | `undefined` | Text of the inline link rendered under the messages. The link appears only when both `urlText` and `urlHref` are set. |
|
|
80
|
+
| `urlHref` | `url-href` | `string` | `undefined` | `href` of the inline link. The link appears only when both `urlText` and `urlHref` are set. |
|
|
81
|
+
| `dismissible` | `dismissible` | `boolean` | `true` | Shows the dismiss (✕) 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
|
+
| `dismissed` | `dismissed` | `boolean` | `false` | True once the alert has been dismissed; hides the host via `:host([dismissed]) { display: none }`. Set it back to `false` to show the alert again. Reflected. |
|
|
83
|
+
|
|
84
|
+
#### Deprecated (still supported — removal targeted for 3.0)
|
|
85
|
+
|
|
86
|
+
| Property | Attribute | Type | Use instead |
|
|
87
|
+
| --- | --- | --- | --- |
|
|
88
|
+
| `type` | `type` | `"neutral" \| "info" \| "success" \| "warning" \| "destructive" \| "error" \| "danger" \| "critical"` | Deprecated since 1.4.7 — alias of `tone`; use `tone`. Same values as `tone`; `type="error"` maps to `tone="destructive"`. Ignored when `tone` is set. Logs a one-time console notice. |
|
|
89
|
+
|
|
90
|
+
### Public fields / accessors
|
|
91
|
+
|
|
92
|
+
| Name | Type | Description |
|
|
93
|
+
| --- | --- | --- |
|
|
94
|
+
| `resolvedTone` | `AlertTone` | Read-only canonical tone actually rendered: explicit `tone` wins, else `type`, else `"neutral"`; deprecated aliases are resolved to `"destructive"`. |
|
|
95
|
+
|
|
96
|
+
## Events
|
|
97
|
+
|
|
98
|
+
| Event | Detail | Bubbles / composed | Description |
|
|
99
|
+
| --- | --- | --- | --- |
|
|
100
|
+
| `dismiss` | — | bubbles / composed | Fired when the user clicks the dismiss button, after `dismissed` has been set to true. No detail. |
|
|
101
|
+
|
|
102
|
+
## Slots
|
|
103
|
+
|
|
104
|
+
| Slot | Description |
|
|
105
|
+
| --- | --- |
|
|
106
|
+
| — | This element has no slots. |
|
|
107
|
+
|
|
108
|
+
## CSS Parts
|
|
109
|
+
|
|
110
|
+
| Part | Description |
|
|
111
|
+
| --- | --- |
|
|
112
|
+
| `base` | The `role="alert"` container that carries the tone and appearance styling |
|
|
113
|
+
| `icon` | Wrapper around the leading status `<rel-icon>` |
|
|
114
|
+
| `content` | Column that stacks the title, helper text and link |
|
|
115
|
+
| `label` | The primary message (`message1`) paragraph |
|
|
116
|
+
| `helper` | The secondary message (`message2`) paragraph; rendered only when `message2` is set |
|
|
117
|
+
| `action` | The inline link; rendered only when both `url-text` and `url-href` are set |
|
|
118
|
+
| `close-button` | The dismiss (✕) button; rendered only while `dismissible` is true |
|
|
119
|
+
|
|
120
|
+
<!-- readme-gen:end -->
|
|
121
|
+
|
|
122
|
+
## Accessibility
|
|
123
|
+
|
|
124
|
+
- The container (part `base`) has `role="alert"` and `aria-atomic="true"`, so screen readers announce the whole message assertively when the element enters the DOM or its text changes. Because of that, reserve it for messages that warrant an interruption; render a `<rel-alert>` only when there is something to say rather than keeping an empty one mounted.
|
|
125
|
+
- The leading status `<rel-icon>` renders `aria-hidden="true"`; the tone is not conveyed to assistive technology except through the text, so put the meaning in `message1` / `message2`.
|
|
126
|
+
- The dismiss control is a native `<button>` with `aria-label="Dismiss"`. The inline link is a plain `<a href>`. Both are in the Tab order; the component adds no key handlers of its own:
|
|
127
|
+
|
|
128
|
+
| Key | Action |
|
|
129
|
+
| --- | --- |
|
|
130
|
+
| Tab / Shift + Tab | Move between the inline link (if any) and the dismiss button (if any) |
|
|
131
|
+
| Enter / Space | Activate the focused dismiss button (fires `dismiss`, sets `dismissed`) |
|
|
132
|
+
| Enter | Follow the focused link |
|
|
133
|
+
|
|
134
|
+
- Keyboard focus on the dismiss button is a 2px `currentColor` outline with 2px offset (`:focus-visible` only).
|
|
135
|
+
- Dismissing hides the host with `display: none`; focus is not moved, so if the dismiss button had focus the browser drops focus to `<body>`. Move focus yourself in the `dismiss` handler when the alert sits in the middle of a form.
|
|
136
|
+
|
|
137
|
+
## Notes / Edge Cases
|
|
138
|
+
|
|
139
|
+
- `tone` and `appearance` are independent axes; every tone renders in every appearance. Solid uses inverse text and carries the `--rel-shadows-md` elevation; subtle and outline have no shadow.
|
|
140
|
+
- The status icon is fixed per tone (`info` for neutral and info, `check-circle`, `alert-circle`, `error`) and cannot be replaced or removed — there are no slots.
|
|
141
|
+
- The alert has `min-width: 360px`; it stretches to its container (`display: block`) but never shrinks below that.
|
|
142
|
+
- The link renders only when both `url-text` and `url-href` are set; it opens in the same tab (no `target`).
|
|
143
|
+
- `dismissible` and `dismissed` are Lit booleans: any attribute value (including `"false"`) counts as true. Toggle them as properties from script.
|
|
144
|
+
- `dismissed` only hides the host; the element stays in the DOM and keeps its state. Resetting `dismissed = false` shows it again without re-firing `dismiss`.
|
|
145
|
+
- `resolvedTone` is the tone actually rendered after alias resolution; use it (not `tone` / `type`) if you branch on tone in script.
|
|
@@ -1,97 +1,192 @@
|
|
|
1
1
|
# rel-autocomplete
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
A searchable single-select type-ahead field ("autocomplete") for searchable-dropdown and searchbar scenarios. Composes `rel-textfield` for all field chrome (label, sizes, variants, states, icons) and adds a suggestion panel with keyboard navigation, loading / no-results states, and clear/reset.
|
|
6
|
-
|
|
7
|
-
Two data modes:
|
|
8
|
-
|
|
9
|
-
- **Local** — provide `items`; typing filters them client-side (`filter` mode).
|
|
10
|
-
- **Remote** — provide a `searchFn`; input is debounced (`debounce-ms`), queries are latest-wins (stale responses are discarded), and local filtering is bypassed (results arrive pre-filtered).
|
|
3
|
+
`<rel-autocomplete>` is a searchable single-select type-ahead field. It composes `rel-textfield` for all field chrome (label, sizes, variants, states, prefix icon, helper / error text) and adds a suggestion panel with keyboard navigation, loading and no-results rows, and an optional clear affordance. Two data modes: **local** — set `items` and typing filters them client-side (`filter`); **remote** — set `searchFn` and input is debounced (`debounce-ms`), queries are latest-wins and local filtering is bypassed. Use it for searchable dropdowns and search bars over lists too long for `rel-select`; for a short fixed list use `rel-select`, and for plain free text use `rel-textfield`.
|
|
11
4
|
|
|
12
5
|
## Usage
|
|
13
6
|
|
|
14
7
|
```html
|
|
15
8
|
<!-- Local items (strings) -->
|
|
16
|
-
<rel-autocomplete id="carrier" label="Carrier" prefix-icon="search" clearable></rel-autocomplete>
|
|
9
|
+
<rel-autocomplete id="carrier" label="Carrier" prefix-icon="search" placeholder="Start typing" clearable></rel-autocomplete>
|
|
17
10
|
<script>
|
|
18
11
|
const ac = document.getElementById("carrier");
|
|
19
12
|
ac.items = ["FedEx Freight", "UPS Freight", "XPO Logistics", "Estes Express"];
|
|
20
13
|
ac.addEventListener("changed", (e) => console.log(e.detail.value, e.detail.item));
|
|
14
|
+
ac.addEventListener("rel-change", (e) => console.log("typed:", e.detail));
|
|
21
15
|
</script>
|
|
22
16
|
|
|
23
|
-
<!-- Object items with icons -->
|
|
17
|
+
<!-- Object items with icons, read through display-field / value-field -->
|
|
18
|
+
<rel-autocomplete id="mode" label="Mode" display-field="name" value-field="id"></rel-autocomplete>
|
|
24
19
|
<script>
|
|
25
|
-
|
|
26
|
-
{
|
|
27
|
-
{
|
|
20
|
+
document.getElementById("mode").items = [
|
|
21
|
+
{ id: "air", name: "Air", icon: "air" },
|
|
22
|
+
{ id: "sea", name: "Sea", icon: "ship" },
|
|
23
|
+
// dulled, skipped by arrow keys, ignores clicks
|
|
24
|
+
{ id: "rail", name: "Rail", icon: "intermodal", disabled: true },
|
|
28
25
|
];
|
|
29
26
|
</script>
|
|
30
27
|
|
|
31
|
-
<!--
|
|
32
|
-
<rel-autocomplete
|
|
28
|
+
<!-- Filtering and limits -->
|
|
29
|
+
<rel-autocomplete label="City" filter="starts-with" max-suggestions="8" min-search-length="2"></rel-autocomplete>
|
|
33
30
|
|
|
34
|
-
<!-- Remote data -->
|
|
31
|
+
<!-- Remote data: debounced, latest-wins -->
|
|
32
|
+
<rel-autocomplete id="remote" label="Customer" debounce-ms="250" loading-text="Searching…" no-results-text="No customers match"></rel-autocomplete>
|
|
35
33
|
<script>
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
const remote = document.getElementById("remote");
|
|
35
|
+
remote.searchFn = async (query) => {
|
|
36
|
+
const res = await fetch(`/api/customers?q=${encodeURIComponent(query)}`);
|
|
38
37
|
return res.json(); // (string | object)[]
|
|
39
38
|
};
|
|
39
|
+
remote.addEventListener("rel-search-error", (e) => console.warn(e.detail.query, e.detail.error));
|
|
40
40
|
</script>
|
|
41
|
+
|
|
42
|
+
<!-- Field chrome passthroughs -->
|
|
43
|
+
<rel-autocomplete label="Small underline" size="small" variant="underline"></rel-autocomplete>
|
|
44
|
+
<rel-autocomplete label="Floating label" label-style="floating" helper-text="Pick a carrier"></rel-autocomplete>
|
|
45
|
+
<rel-autocomplete label-style="none" placeholder="Search orders" field-aria-label="Search orders"></rel-autocomplete>
|
|
46
|
+
<rel-autocomplete label="Required" required error error-message="Choose a carrier from the list"></rel-autocomplete>
|
|
47
|
+
<rel-autocomplete label="Read only" value="UPS Freight" readonly></rel-autocomplete>
|
|
48
|
+
<rel-autocomplete label="Disabled" disabled></rel-autocomplete>
|
|
49
|
+
<rel-autocomplete label="Inline width" full-width name="carrier"></rel-autocomplete>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Deprecated aliases
|
|
53
|
+
|
|
54
|
+
```html
|
|
55
|
+
<!-- floating-label → label-style="floating" (kept permanently as an alias; no console notice) -->
|
|
56
|
+
<rel-autocomplete label="Old spelling" floating-label></rel-autocomplete>
|
|
57
|
+
<rel-autocomplete label="Canonical" label-style="floating"></rel-autocomplete>
|
|
41
58
|
```
|
|
42
59
|
|
|
60
|
+
<!-- readme-gen:start -->
|
|
61
|
+
|
|
62
|
+
<!-- Generated from rel-autocomplete.ts — do not edit; run readme-generate.mjs -->
|
|
63
|
+
|
|
43
64
|
## API
|
|
44
65
|
|
|
45
|
-
### Attributes/Properties
|
|
46
|
-
|
|
47
|
-
|
|
|
48
|
-
|
|
49
|
-
| `items` | `(string \|
|
|
50
|
-
| `value` | `string` | `""` | Committed value — the selected item's
|
|
51
|
-
| `display-field` | `string` | `"label"` | Object key
|
|
52
|
-
| `value-field` | `string` | `"value"` | Object key
|
|
53
|
-
| `filter` | `"contains" \| "starts-with" \| "none"` | `"contains"` | Local filtering mode.
|
|
54
|
-
| `searchFn` | `(query: string) => Promise<
|
|
55
|
-
| `debounce-ms` | `number` | `300` | Debounce
|
|
56
|
-
| `min-search-length` | `number` | `1` | Minimum typed characters before the panel opens /
|
|
57
|
-
| `max-suggestions` | `number` | `Infinity` | Optional cap on rendered
|
|
58
|
-
| `clearable` | `boolean` | `false` |
|
|
59
|
-
| `loading` | `boolean` | `false` | Externally-controlled loading
|
|
60
|
-
| `no-results-text` | `string` | `"No results found"` | Row shown when a query yields nothing |
|
|
61
|
-
| `loading-text` | `string` | `"Loading…"` | Text next to the
|
|
62
|
-
| `label
|
|
63
|
-
| `
|
|
66
|
+
### Attributes / Properties
|
|
67
|
+
|
|
68
|
+
| Property | Attribute | Type | Default | Description |
|
|
69
|
+
| --- | --- | --- | --- | --- |
|
|
70
|
+
| `items` | `items` | `(string \| Record<string, unknown>)[]` | `[]` | Local (or fallback initial) suggestion list. Ignored while searchFn drives results. Object items read two keys directly whatever `display-field` / `value-field` are set to: `icon` (a `rel-icon` name shown before the label) and `disabled` (`true` dulls the row and makes it unselectable by click or keyboard). |
|
|
71
|
+
| `value` | `value` | `string` | `""` | Committed value — the selected item's valueField string ("" = none). |
|
|
72
|
+
| `displayField` | `display-field` | `string` | `"label"` | Object key read for the row label when items are objects. |
|
|
73
|
+
| `valueField` | `value-field` | `string` | `"value"` | Object key read for the committed value when items are objects. |
|
|
74
|
+
| `filter` | `filter` | `"contains" \| "starts-with" \| "none"` | `"contains"` | Local filtering mode. Ignored when searchFn is set (results arrive pre-filtered). |
|
|
75
|
+
| `searchFn` | — | `(query: string) => Promise<AutocompleteItem[]>` | `undefined` | Async data source. When set, local filtering is bypassed entirely. Property only. |
|
|
76
|
+
| `debounceMs` | `debounce-ms` | `number` | `300` | Debounce for searchFn calls, in ms. |
|
|
77
|
+
| `minSearchLength` | `min-search-length` | `number` | `1` | Minimum typed characters before the panel opens / searchFn fires. 0 = open on focus. |
|
|
78
|
+
| `maxSuggestions` | `max-suggestions` | `number` | `Infinity` | Optional cap on rendered suggestions (panel scrolls regardless). |
|
|
79
|
+
| `clearable` | `clearable` | `boolean` | `false` | Shows a trailing ✕ that clears the text and the committed value. |
|
|
80
|
+
| `loading` | `loading` | `boolean` | `false` | Externally-controlled loading state (internal searchFn loading is automatic). |
|
|
81
|
+
| `noResultsText` | `no-results-text` | `string` | `"No results found"` | Row shown when a query yields nothing. |
|
|
82
|
+
| `loadingText` | `loading-text` | `string` | `"Loading…"` | Text shown next to the spinner while suggestions load. |
|
|
83
|
+
| `label` | `label` | `string` | `undefined` | Visible label, forwarded to the inner `rel-textfield`. Also names the suggestion panel. |
|
|
84
|
+
| `placeholder` | `placeholder` | `string` | `""` | Placeholder of the input, forwarded to the inner `rel-textfield`. |
|
|
85
|
+
| `size` | `size` | `"small" \| "medium" \| "large"` | `"medium"` | Field height — `small` 32px, `medium` 40px, `large` 48px — forwarded to the inner `rel-textfield`. |
|
|
86
|
+
| `variant` | `variant` | `"default" \| "underline" \| "legend"` | `"default"` | Field chrome (`default` outlined, `underline`, `legend` notched outline), forwarded to the inner `rel-textfield`. |
|
|
87
|
+
| `labelStyle` | `label-style` | `"default" \| "floating" \| "none"` | `undefined` | Label presentation (`default` / `floating` / `none`), forwarded to the inner field. Left `undefined`, the deprecated `floatingLabel` decides. Reflected. |
|
|
88
|
+
| `fieldAriaLabel` | `field-aria-label` | `string` | `undefined` | Accessible name for the input. Required when `labelStyle="none"`. |
|
|
89
|
+
| `fieldAriaLabelledby` | `field-aria-labelledby` | `string` | `undefined` | IDREF list of external element(s) naming the input. Wins over `fieldAriaLabel`. |
|
|
90
|
+
| `prefixIcon` | `prefix-icon` | `string` | `undefined` | Leading `rel-icon` name in the field's prefix block, e.g. `search`. |
|
|
91
|
+
| `disabled` | `disabled` | `boolean` | `false` | Disables the field; the panel never opens and the clear affordance is hidden. |
|
|
92
|
+
| `readonly` | `readonly` | `boolean` | `false` | Read-only field: focusable but not editable; the panel never opens and the clear affordance is hidden. |
|
|
93
|
+
| `required` | `required` | `boolean` | `false` | Marks the input required (native `required` / `aria-required`, asterisk on the label). |
|
|
94
|
+
| `error` | `error` | `boolean` | `false` | Puts the field in the error state (danger border, `aria-invalid`); pair with `errorMessage`. |
|
|
95
|
+
| `errorMessage` | `error-message` | `string` | `undefined` | Text shown below the field instead of `helperText` while `error` is set. |
|
|
96
|
+
| `helperText` | `helper-text` | `string` | `undefined` | Helper line below the field, linked to the input via `aria-describedby`. |
|
|
97
|
+
| `name` | `name` | `string` | `undefined` | Form field name forwarded to the native input. |
|
|
98
|
+
| `fullWidth` | `full-width` | `boolean` | `true` | Fills the parent width as a block element (default). Unset it to render inline at the content's natural width. |
|
|
99
|
+
|
|
100
|
+
#### Deprecated (still supported — removal targeted for 3.0)
|
|
101
|
+
|
|
102
|
+
| Property | Attribute | Type | Use instead |
|
|
103
|
+
| --- | --- | --- | --- |
|
|
104
|
+
| `floatingLabel` | `floating-label` | `boolean` | Use `labelStyle="floating"`. Kept permanently as an alias. |
|
|
105
|
+
|
|
106
|
+
### Methods
|
|
107
|
+
|
|
108
|
+
| Method | Signature | Description |
|
|
109
|
+
| --- | --- | --- |
|
|
110
|
+
| `focus` | `focus()` | Delegates focus to the inner textfield. |
|
|
64
111
|
|
|
65
112
|
## Events
|
|
66
113
|
|
|
67
|
-
| Event | Detail | Description |
|
|
68
|
-
|
|
69
|
-
| `changed` | `{ value:
|
|
70
|
-
| `rel-change` | `
|
|
71
|
-
| `rel-clear` | — |
|
|
72
|
-
| `rel-search-error` | `{ query, error }` | `searchFn`
|
|
114
|
+
| Event | Detail | Bubbles / composed | Description |
|
|
115
|
+
| --- | --- | --- | --- |
|
|
116
|
+
| `changed` | `{ value: this.value, item: item ? item.item : null }` | bubbles / composed | Fired when the committed value changes — an item was selected (click, Enter, or an exact text match on Enter / Tab / blur) or the field was cleared. Detail: `{ value, item }`, where `item` is the original string or object, or `null` after a clear. |
|
|
117
|
+
| `rel-change` | `inputText / ""` | bubbles / composed | Fired on every keystroke with the raw input text as the detail (and with `""` after a clear). The committed `value` does not change until an item is selected. |
|
|
118
|
+
| `rel-clear` | — | bubbles / composed | Fired when the clear icon empties a non-empty field (followed by `changed` and `rel-change`). No detail. |
|
|
119
|
+
| `rel-search-error` | `{ query, error: err }` | bubbles / composed | Fired when `searchFn` rejects; the panel then shows the no-results row. Detail: `{ query, error }`. |
|
|
120
|
+
|
|
121
|
+
## Slots
|
|
122
|
+
|
|
123
|
+
| Slot | Description |
|
|
124
|
+
| --- | --- |
|
|
125
|
+
| — | This element has no slots. |
|
|
126
|
+
|
|
127
|
+
## CSS Parts
|
|
128
|
+
|
|
129
|
+
| Part | Description |
|
|
130
|
+
| --- | --- |
|
|
131
|
+
| `panel` | The suggestion listbox container (same node as `list`) |
|
|
132
|
+
| `list` | Alias of `panel` |
|
|
133
|
+
| `option` | A suggestion row |
|
|
134
|
+
| `label` | The inner field's label (re-exported from `rel-textfield`) |
|
|
135
|
+
| `control` | The inner field's bordered control box (re-exported from `rel-textfield`) |
|
|
136
|
+
| `input` | The inner native input (re-exported from `rel-textfield`) |
|
|
137
|
+
| `helper` | The inner field's helper / error line (re-exported from `rel-textfield`) |
|
|
138
|
+
| `right-icon` | The clear icon shown when `clearable` (re-exported from `rel-textfield`) |
|
|
139
|
+
|
|
140
|
+
## Tokens / CSS Variables
|
|
141
|
+
|
|
142
|
+
### Component hooks
|
|
143
|
+
|
|
144
|
+
Set these on the host (or an ancestor) to customise the element without touching design tokens.
|
|
145
|
+
|
|
146
|
+
| Custom property | Default | Description |
|
|
147
|
+
| --- | --- | --- |
|
|
148
|
+
| `--rel-autocomplete-bg` | `var(--rel-bg-neutral)` | Panel and row background |
|
|
149
|
+
| `--rel-autocomplete-divider` | `var(--rel-border-subtle)` | Hairline between rows |
|
|
150
|
+
| `--rel-autocomplete-icon-color` | `var(--rel-text-default)` | Colour of a row's leading `icon` |
|
|
151
|
+
| `--rel-autocomplete-menu-border` | `var(--rel-border-default)` | Panel border colour. The panel is borderless by design and only draws this on dark surfaces, where its shadow alone can't separate it from the page. |
|
|
152
|
+
| `--rel-autocomplete-menu-radius` | `var(--rel-border-radius-xs)` | Panel corner radius |
|
|
153
|
+
| `--rel-autocomplete-menu-shadow` | `var(--rel-shadows-md)` | Panel box-shadow |
|
|
154
|
+
| `--rel-autocomplete-option-hover` | `var(--rel-action-overlay-hover)` | Background of the hovered / keyboard-highlighted / selected row |
|
|
155
|
+
| `--rel-autocomplete-option-pressed` | `var(--rel-action-overlay-pressed)` | Background of a row while it is being pressed |
|
|
156
|
+
| `--rel-autocomplete-status-color` | `var(--rel-text-body)` | Colour of the loading / no-results status rows |
|
|
157
|
+
| `--rel-autocomplete-value-color` | `var(--rel-text-default)` | Suggestion label colour |
|
|
158
|
+
|
|
159
|
+
<!-- readme-gen:end -->
|
|
73
160
|
|
|
74
|
-
##
|
|
161
|
+
## Accessibility
|
|
75
162
|
|
|
76
|
-
-
|
|
77
|
-
- `
|
|
78
|
-
- `
|
|
79
|
-
- `
|
|
80
|
-
- `
|
|
163
|
+
- Combobox pattern: a wrapper around the inner field carries `role="combobox"`, `aria-haspopup="listbox"`, `aria-expanded`, `aria-controls` and `aria-activedescendant` (the highlighted row). The role sits on the wrapper rather than the `<input>` because the input lives in `rel-textfield`'s nested shadow root, which `aria-activedescendant` cannot reference across — the pragmatic pattern for composed shadow components.
|
|
164
|
+
- The panel is `role="listbox"` named by the visible `label` (or `field-aria-label` under `label-style="none"`, falling back to "Suggestions"); rows are `role="option"` with `aria-selected` on the committed value. The loading row is `role="status"`.
|
|
165
|
+
- Field-level semantics come from `rel-textfield`: `<label for>`, `aria-required`, `aria-invalid`, `aria-describedby` on the helper / error line. With `label-style="none"` the inner field logs a console warning once if neither `field-aria-label` nor `field-aria-labelledby` is set.
|
|
166
|
+
- The clear affordance (`clearable`) is the inner field's clickable trailing icon: `role="button"`, focusable, labelled "Clear".
|
|
167
|
+
- Screen-reader announcements via the shared `announce()` helper: `"Loading suggestions"` when the loading row appears, `"{label}, i of n"` while arrowing through rows, `"N results available"` when results change, and the `no-results-text` when a query yields nothing.
|
|
168
|
+
- Disabled and read-only fields never open the panel and hide the clear icon.
|
|
81
169
|
|
|
82
|
-
|
|
170
|
+
| Key | Action |
|
|
171
|
+
|-----|--------|
|
|
172
|
+
| Typing | Filters local items or queries `searchFn`, and opens the panel once the query reaches `min-search-length` |
|
|
173
|
+
| `ArrowDown` | Open the panel (if the query is long enough) or move the highlight down |
|
|
174
|
+
| `ArrowUp` | Move the highlight up |
|
|
175
|
+
| `Enter` | Select the highlighted row; with no highlight, commit an exact label / value match, otherwise keep the free text and close |
|
|
176
|
+
| `Escape` | Close the panel without touching the text |
|
|
177
|
+
| `Tab` | Commit an exact match (if any), close, and move focus on |
|
|
83
178
|
|
|
84
|
-
|
|
85
|
-
- Known limitation: the combobox role sits on a wrapper around the field rather than on the `<input>` itself — the input lives in `rel-textfield`'s nested shadow root, which `aria-activedescendant` cannot reference across. This is the standard pragmatic pattern for composed shadow components
|
|
86
|
-
- Loading row uses `role="status"`; disabled/readonly never open the panel
|
|
87
|
-
- With `label-style="none"` no `<label>` renders, so `field-aria-label` (or `field-aria-labelledby`) must supply the accessible name — it also names the suggestion panel. A placeholder is not a valid naming mechanism; the inner field logs a console warning when both are missing
|
|
179
|
+
Focus: `focus()` on the host delegates to the inner field. Focusing the field with `min-search-length="0"` (or with a query already long enough and matching items) opens the panel. Focus leaving the component commits an exact match and closes the panel; the same happens on an outside pointerdown. After a clear, focus returns to the field.
|
|
88
180
|
|
|
89
181
|
## Notes / Edge Cases
|
|
90
182
|
|
|
91
|
-
-
|
|
92
|
-
- `value`
|
|
93
|
-
-
|
|
94
|
-
-
|
|
95
|
-
-
|
|
96
|
-
-
|
|
97
|
-
-
|
|
183
|
+
- `value` and the visible text are separate: typing only emits `rel-change`; `value` (and `changed`) update when a row is picked, or when the text exactly matches an item's label or value (case-insensitive) on Enter, Tab, blur or outside click. Free text that matches nothing stays in the field but never becomes `value`.
|
|
184
|
+
- Setting `value` externally (attribute, property, Angular `writeValue`) shows the matching item's label, or the raw string when no item matches (common with remote data on init) — provide the item in `items` to show its label.
|
|
185
|
+
- Clearing emits, in order, `rel-clear`, `changed` (`value: ""`, `item: null`) and `rel-change` (`""`), and only when the field actually had text or a value.
|
|
186
|
+
- Remote mode: `items` is ignored while `searchFn` has produced results; a shorter-than-minimum query cancels any in-flight request and closes the panel; stale responses are discarded (latest-wins); a rejected `searchFn` is treated as an empty result plus `rel-search-error` — the component never throws into the app.
|
|
187
|
+
- `loading` is an external flag layered on top of the automatic `searchFn` loading state; the loading row is shown while either is true.
|
|
188
|
+
- `max-suggestions` caps rendered rows only; the panel scrolls (360px max height) regardless. The matched substring in each row renders bold.
|
|
189
|
+
- Validation is displayed (`error`, `error-message`, `required`) but not performed; validity logic belongs to the form layer.
|
|
190
|
+
- `full-width` layout is keyed off the **attribute** (`:host(:not([full-width]))` renders inline-block) even though the property defaults to `true` and is not reflected — add the `full-width` attribute in markup when you need the block layout. This differs from `rel-textfield`, whose `fullwidth` attribute is reflected.
|
|
191
|
+
- The suggestion panel mirrors `rel-select`'s listbox (same tokens, radius, shadow, row styling) and is promoted to the browser top layer (native Popover API, `popover="manual"`), so it renders correctly inside transformed or `overflow: hidden` containers such as a centered `rel-modal` or a `rel-drawer`; engines without the Popover API fall back to `position: fixed` with a measure-and-cancel correction. It matches the field width, flips above when short on space, and closes on outside pointerdown or outside scroll.
|
|
192
|
+
- Only `label`, `control`, `input`, `helper` and `right-icon` are re-exported from the inner `rel-textfield`; its `prefix` / `suffix` parts and slots are not exposed.
|