@reliability-design/web 1.4.5 → 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 -135
- 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 -103
- package/dist/components/rel-upload/README.md +220 -0
- package/dist/index.d.mts +1387 -350
- package/dist/index.d.ts +1387 -350
- package/dist/index.js +5863 -3600
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5864 -3592
- 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 +4 -3
- 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 -689
- package/dist/components/rel-avatar/rel-avatar.ts +0 -142
- package/dist/components/rel-badge/rel-badge.ts +0 -170
- 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 -519
- 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 -700
- 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 -472
- 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/index.ts +0 -1
- package/dist/components/rel-date-picker/rel-date-picker.ts +0 -1237
- 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 -604
- 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 -535
- 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 -517
- package/dist/components/rel-pagination/index.ts +0 -1
- package/dist/components/rel-pagination/rel-pagination.ts +0 -509
- 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 -444
- package/dist/components/rel-progress/rel-progress.ts +0 -225
- package/dist/components/rel-radio/rel-radio.ts +0 -305
- package/dist/components/rel-range-picker/rel-range-picker.ts +0 -1331
- 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 -213
- package/dist/components/rel-select/rel-select.ts +0 -1385
- package/dist/components/rel-sheet/rel-sheet.ts +0 -465
- package/dist/components/rel-sidebar/README.md +0 -209
- package/dist/components/rel-sidebar/rel-sidebar.ts +0 -1185
- package/dist/components/rel-skeleton/rel-skeleton.ts +0 -134
- package/dist/components/rel-slider/rel-slider.ts +0 -670
- package/dist/components/rel-snackbar/rel-snackbar.ts +0 -325
- package/dist/components/rel-stepper/rel-stepper.ts +0 -565
- package/dist/components/rel-switch/rel-switch.ts +0 -197
- 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 -866
- package/dist/components/rel-time-picker/rel-time-picker.ts +0 -1126
- package/dist/components/rel-toast/rel-toast.ts +0 -204
- package/dist/components/rel-tooltip/rel-tooltip.ts +0 -190
- 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 -943
|
@@ -1,289 +1,200 @@
|
|
|
1
|
-
# rel-date-picker
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
-
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
<rel-date-picker label="
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
###
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
picker
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
|
91
|
-
|
|
92
|
-
| `
|
|
93
|
-
| `
|
|
94
|
-
| `
|
|
95
|
-
| `
|
|
96
|
-
| `
|
|
97
|
-
| `
|
|
98
|
-
| `
|
|
99
|
-
| `
|
|
100
|
-
| `
|
|
101
|
-
| `
|
|
102
|
-
| `
|
|
103
|
-
| `
|
|
104
|
-
| `
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
|
140
|
-
|
|
|
141
|
-
| `
|
|
142
|
-
| `
|
|
143
|
-
| `
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
##
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
picker.isDateDisabled = (date) => {
|
|
202
|
-
const iso = date.toISOString().split('T')[0];
|
|
203
|
-
return blackoutDates.includes(iso);
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
// Disable dates before today
|
|
207
|
-
picker.isDateDisabled = (date) => {
|
|
208
|
-
const today = new Date();
|
|
209
|
-
today.setHours(0, 0, 0, 0);
|
|
210
|
-
return date < today;
|
|
211
|
-
};
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
## Complete Example
|
|
215
|
-
|
|
216
|
-
```html
|
|
217
|
-
<rel-date-picker
|
|
218
|
-
id="appointment-picker"
|
|
219
|
-
label="Appointment Date"
|
|
220
|
-
placeholder="Choose a date"
|
|
221
|
-
min="2026-01-01"
|
|
222
|
-
max="2026-12-31"
|
|
223
|
-
clearable
|
|
224
|
-
required
|
|
225
|
-
></rel-date-picker>
|
|
226
|
-
|
|
227
|
-
<script>
|
|
228
|
-
const picker = document.getElementById('appointment-picker');
|
|
229
|
-
|
|
230
|
-
// Disable weekends
|
|
231
|
-
picker.isDateDisabled = (date) => {
|
|
232
|
-
const day = date.getDay();
|
|
233
|
-
return day === 0 || day === 6;
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
// Handle selection
|
|
237
|
-
picker.addEventListener('rel-change', (e) => {
|
|
238
|
-
if (e.detail.value) {
|
|
239
|
-
console.log('Appointment scheduled for:', e.detail.value);
|
|
240
|
-
} else {
|
|
241
|
-
console.log('Appointment cleared');
|
|
242
|
-
}
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
// Handle popover state
|
|
246
|
-
picker.addEventListener('rel-open-change', (e) => {
|
|
247
|
-
console.log('Calendar', e.detail.open ? 'opened' : 'closed');
|
|
248
|
-
});
|
|
249
|
-
</script>
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
## Accessibility
|
|
253
|
-
|
|
254
|
-
- Trigger button has proper `aria-haspopup`, `aria-expanded`, and `aria-label`
|
|
255
|
-
- Calendar popover uses `role="dialog"`
|
|
256
|
-
- Day buttons use `role="gridcell"` with proper `aria-label` and `aria-selected`
|
|
257
|
-
- All interactive elements are keyboard accessible
|
|
258
|
-
- Focus management:
|
|
259
|
-
- Opening popover focuses first day
|
|
260
|
-
- Closing popover returns focus to trigger
|
|
261
|
-
- Visible focus rings on all interactive elements
|
|
262
|
-
- Respects user's locale for month names and date formatting
|
|
263
|
-
|
|
264
|
-
## Styling
|
|
265
|
-
|
|
266
|
-
The component uses design tokens from the Reliability Design System. All colors, spacing, and typography are inherited from CSS variables.
|
|
267
|
-
|
|
268
|
-
Key tokens used:
|
|
269
|
-
- `--rel-bg-*` / `--rel-text-*` / `--rel-border-*` semantic colors
|
|
270
|
-
- `--rel-spacing-*` for spacing
|
|
271
|
-
- `--rel-body-*` composite typography roles
|
|
272
|
-
- `--rel-border-*` / `--rel-border-radius-*` tokens
|
|
273
|
-
- `--rel-shadows-*` for popover shadow
|
|
274
|
-
- Selected date: `--rel-bg-brand`
|
|
275
|
-
- Today indicator: `--rel-bg-info`
|
|
276
|
-
- Focus rings: `--rel-bg-info`
|
|
277
|
-
|
|
278
|
-
## Date Format
|
|
279
|
-
|
|
280
|
-
- **Input/Output**: ISO 8601 format (YYYY-MM-DD)
|
|
281
|
-
- **Display**: Localized format based on `locale` attribute
|
|
282
|
-
- **Example**:
|
|
283
|
-
- Value: `"2026-01-16"`
|
|
284
|
-
- Display (en-US): `"January 16, 2026"`
|
|
285
|
-
- Display (es-ES): `"16 de enero de 2026"`
|
|
286
|
-
|
|
287
|
-
## Browser Support
|
|
288
|
-
|
|
289
|
-
Works in all modern browsers with ES2020 support and native Web Components.
|
|
1
|
+
# rel-date-picker
|
|
2
|
+
|
|
3
|
+
`<rel-date-picker>` is the single-date form field of the Reliability Design System (Figma "Date Picker"). It is a text field you can type a date into, with a popover calendar whose header pills drill into month and year grids, above Today / Tomorrow / Yesterday shortcut chips. The committed `value` is always an ISO `YYYY-MM-DD` string; the visible text follows `locale`, `display-format` or a `formatDate` callback. Use it wherever a form needs one date. For a from/to range use `<rel-range-picker>`, for an always-visible grid use `<rel-calendar>`, for a time of day use `<rel-time-picker>`.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```html
|
|
8
|
+
<!-- Basic labelled field -->
|
|
9
|
+
<rel-date-picker label="Start date"></rel-date-picker>
|
|
10
|
+
|
|
11
|
+
<!-- Preselected, clearable, required (adds * to the label and aria-required) -->
|
|
12
|
+
<rel-date-picker label="Appointment" value="2026-01-16" clearable required></rel-date-picker>
|
|
13
|
+
|
|
14
|
+
<!-- Bounded to 2026, Monday-first grid -->
|
|
15
|
+
<rel-date-picker label="Delivery" min-date="2026-01-01" max-date="2026-12-31" week-start="mon"></rel-date-picker>
|
|
16
|
+
|
|
17
|
+
<!-- Field heights 32 / 40 / 48; fullwidth fills the parent -->
|
|
18
|
+
<rel-date-picker size="small" label="Small"></rel-date-picker>
|
|
19
|
+
<rel-date-picker size="medium" label="Medium" variant="outlined"></rel-date-picker>
|
|
20
|
+
<rel-date-picker size="large" label="Large" fullwidth></rel-date-picker>
|
|
21
|
+
|
|
22
|
+
<!-- Hide the Today / Tomorrow / Yesterday chip row (on by default) -->
|
|
23
|
+
<rel-date-picker label="Due" show-shortcuts="false"></rel-date-picker>
|
|
24
|
+
|
|
25
|
+
<!-- Helper and error text below the field -->
|
|
26
|
+
<rel-date-picker label="Due" helper-text="Defaults to the next business day"></rel-date-picker>
|
|
27
|
+
<rel-date-picker label="Due" error error-message="Pick a date after today"></rel-date-picker>
|
|
28
|
+
|
|
29
|
+
<!-- Fixed display format and locale (value stays ISO) -->
|
|
30
|
+
<rel-date-picker value="2026-07-21" display-format="DD/MM/YYYY"></rel-date-picker>
|
|
31
|
+
<rel-date-picker value="2026-07-21" locale="es-ES"></rel-date-picker>
|
|
32
|
+
|
|
33
|
+
<!-- Read-only, disabled, and native form submission via a hidden input -->
|
|
34
|
+
<rel-date-picker label="Created" value="2026-01-16" readonly></rel-date-picker>
|
|
35
|
+
<rel-date-picker label="Archived" value="2026-01-16" disabled></rel-date-picker>
|
|
36
|
+
<rel-date-picker name="start" label="Start" placeholder="YYYY-MM-DD"></rel-date-picker>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
```js
|
|
40
|
+
const picker = document.querySelector("rel-date-picker");
|
|
41
|
+
|
|
42
|
+
// Disable individual days on top of min-date/max-date (property only)
|
|
43
|
+
picker.isDateDisabled = (date) => date.getDay() === 0 || date.getDay() === 6;
|
|
44
|
+
|
|
45
|
+
// Full control of the visible text; wins over display-format
|
|
46
|
+
picker.formatDate = (date) => `Q${Math.floor(date.getMonth() / 3) + 1} ${date.getFullYear()}`;
|
|
47
|
+
|
|
48
|
+
// Keep the popover open after a pick (a boolean attribute cannot be set to false in markup)
|
|
49
|
+
picker.closeOnSelect = false;
|
|
50
|
+
|
|
51
|
+
picker.addEventListener("rel-change", (e) => {
|
|
52
|
+
e.detail.value; // "2026-01-16" or null when cleared
|
|
53
|
+
e.detail.date; // Date at local midnight, or null
|
|
54
|
+
});
|
|
55
|
+
picker.addEventListener("rel-open-change", (e) => e.detail.open);
|
|
56
|
+
picker.addEventListener("rel-blur", () => {/* run validation */});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Typed entry
|
|
60
|
+
|
|
61
|
+
The field is editable. Typed text is committed on Enter or when focus leaves the component; the parser (`date-parse.ts`) accepts ISO `2026-07-21`, numeric `21/7/2026` / `7/21/26`, month names `21 Jul 2026` / `July 21, 2026`, partial `21/7` (current year) or `21` (current month), and `20260721`. Two-digit years map to `20YY`. When day/month order is ambiguous (`3/4`), the order in `display-format` decides, else the locale's default numeric order. Shortcuts `t` / `today`, `t+7`, `t-3` resolve relative to today. Unparseable text shows "Invalid date", a date outside `min-date`/`max-date`/`isDateDisabled` shows "Date not available" — in both cases the text stays for correction and `value` is untouched; Escape reverts the text. Committing an empty field clears the value like the clear button does.
|
|
62
|
+
|
|
63
|
+
### Display format
|
|
64
|
+
|
|
65
|
+
Without `display-format` or `formatDate` the field shows the locale long date (`July 21, 2026`, `21 de julio de 2026` for `es-ES`). `display-format` tokens (`date-format.ts`), matched longest-first with other characters passed through and literal text in `[ ]`: `YYYY` 2026 · `YY` 26 · `MMMM` July · `MMM` Jul · `MM` 07 · `M` 7 · `DD` 21 · `D` 21. Named-month tokens follow `locale`.
|
|
66
|
+
|
|
67
|
+
### Deprecated aliases
|
|
68
|
+
|
|
69
|
+
```html
|
|
70
|
+
<!-- min / max → min-date / max-date. Both still work; min-date/max-date win when both are set. No console notice is logged. -->
|
|
71
|
+
<rel-date-picker min="2026-01-01" max="2026-12-31"></rel-date-picker>
|
|
72
|
+
<!-- canonical -->
|
|
73
|
+
<rel-date-picker min-date="2026-01-01" max-date="2026-12-31"></rel-date-picker>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
<!-- readme-gen:start -->
|
|
77
|
+
|
|
78
|
+
<!-- Generated from rel-date-picker.ts — do not edit; run readme-generate.mjs -->
|
|
79
|
+
|
|
80
|
+
## API
|
|
81
|
+
|
|
82
|
+
### Attributes / Properties
|
|
83
|
+
|
|
84
|
+
| Property | Attribute | Type | Default | Description |
|
|
85
|
+
| --- | --- | --- | --- | --- |
|
|
86
|
+
| `value` | `value` | `string \| null` | `null` | Selected date as an ISO `YYYY-MM-DD` string, or `null` when empty; setting it also moves the popover to that month. Reflected. |
|
|
87
|
+
| `placeholder` | `placeholder` | `string` | `"Select date"` | Placeholder text shown while the field is empty (visual only; the accessible name comes from `label`, or "Select date" when unset). |
|
|
88
|
+
| `label` | `label` | `string \| null` | `null` | Visible label rendered above the field and wired to the input via `aria-labelledby`; `null` renders no label. |
|
|
89
|
+
| `disabled` | `disabled` | `boolean` | `false` | Disables the field, the icons and the popover; the host dims to 60% opacity. Reflected. |
|
|
90
|
+
| `required` | `required` | `boolean` | `false` | Appends a `*` to the label and sets `aria-required`; no validation is performed. |
|
|
91
|
+
| `readonly` | `readonly` | `boolean` | `false` | Makes the input read-only and stops the field, icon, Enter and ArrowDown from opening the popover. Reflected. |
|
|
92
|
+
| `minDate` | `min-date` | `string \| null` | `null` | Earliest selectable date (ISO `YYYY-MM-DD`); earlier days are disabled and typed dates before it are rejected. Wins over the deprecated `min`. |
|
|
93
|
+
| `maxDate` | `max-date` | `string \| null` | `null` | Latest selectable date (ISO `YYYY-MM-DD`); later days are disabled and typed dates after it are rejected. Wins over the deprecated `max`. |
|
|
94
|
+
| `weekStart` | `week-start` | `"sun" \| "mon"` | `"sun"` | First column of the calendar grid: `"sun"` (default) or `"mon"`. |
|
|
95
|
+
| `locale` | `locale` | `string` | `"en-US"` | BCP 47 locale for weekday/month names, the default long-date display, and day/month order when parsing ambiguous typed input. |
|
|
96
|
+
| `displayFormat` | `display-format` | `string \| null` | `null` | Token pattern for the displayed value (`YYYY`, `YY`, `MMMM`, `MMM`, `MM`, `M`, `DD`, `D`; literal text in `[ ]`), e.g. `DD/MM/YYYY`. Unset → the locale long date. Affects only the visible text, never `value`. |
|
|
97
|
+
| `formatDate` | — | `(date: Date) => string` | `undefined` | Callback with full control over the displayed value; wins over `displayFormat`. Assign it from JavaScript; it stays reactive so setting it after render re-renders the field. The Date it receives is at local midnight. Property only. |
|
|
98
|
+
| `open` | `open` | `boolean` | `false` | Whether the calendar popover is open; set it directly to open/close programmatically (focus then moves into the grid). Reflected. |
|
|
99
|
+
| `closeOnSelect` | `close-on-select` | `boolean` | `true` | Closes the popover after a day is picked in the grid (default `true`). |
|
|
100
|
+
| `clearable` | `clearable` | `boolean` | `false` | Shows a clear (×) icon while a value is set; clearing fires `rel-change` with `value: null`. |
|
|
101
|
+
| `showShortcuts` | `show-shortcuts` | `boolean` | `true` | Figma ".Date Picker Calendar" Show Shortcuts: renders the Today / Tomorrow / Yesterday chip row and its divider at the top of the popover. On by default — write `show-shortcuts="false"` to hide both (a plain boolean attribute could not express a default of `true`). The typed `T` / `T±N` shortcuts and the in-panel `T` key keep working either way. |
|
|
102
|
+
| `error` | `error` | `boolean` | `false` | Forces the error style (danger border, `aria-invalid`) and shows `errorMessage` below the field. Typed-entry parse errors set the same style on their own. |
|
|
103
|
+
| `errorMessage` | `error-message` | `string` | `undefined` | Text shown below the field while `error` is set (or a typed date failed to parse); falls back to `helperText`. |
|
|
104
|
+
| `helperText` | `helper-text` | `string` | `undefined` | Supporting text shown below the field when there is no error. |
|
|
105
|
+
| `name` | `name` | `string` | `undefined` | When set, renders a hidden `<input name>` carrying the ISO value so the picker submits with a native form. |
|
|
106
|
+
| `size` | `size` | `"small" \| "medium" \| "large"` | `"medium"` | Field height scale shared with rel-textfield / rel-select: `small` 32px, `medium` 40px (default), `large` 48px. |
|
|
107
|
+
| `variant` | `variant` | `"outlined"` | `"outlined"` | Visual style of the field; `outlined` is the only variant today. Reflected. |
|
|
108
|
+
| `fullWidth` | `fullwidth` | `boolean` | `false` | Stretches the host to fill its parent's width (attribute `fullwidth`); off by default so the field keeps its intrinsic inline width. Reflected. |
|
|
109
|
+
|
|
110
|
+
#### Deprecated (still supported — removal targeted for 3.0)
|
|
111
|
+
|
|
112
|
+
| Property | Attribute | Type | Use instead |
|
|
113
|
+
| --- | --- | --- | --- |
|
|
114
|
+
| `min` | `min` | `string \| null` | use minDate |
|
|
115
|
+
| `max` | `max` | `string \| null` | use maxDate |
|
|
116
|
+
|
|
117
|
+
### Public fields / accessors
|
|
118
|
+
|
|
119
|
+
| Name | Type | Description |
|
|
120
|
+
| --- | --- | --- |
|
|
121
|
+
| `isDateDisabled` | `(date: Date) => boolean` | Custom predicate that disables individual days (return `true` to disable); applied on top of `minDate`/`maxDate` and also rejects typed input. Property only — assign it from JavaScript. |
|
|
122
|
+
|
|
123
|
+
## Events
|
|
124
|
+
|
|
125
|
+
| Event | Detail | Bubbles / composed | Description |
|
|
126
|
+
| --- | --- | --- | --- |
|
|
127
|
+
| `rel-blur` | — | bubbles / composed | Fired when the text input loses focus (before any typed text is committed). No detail. |
|
|
128
|
+
| `rel-change` | `{ value: newValue, date: new Date(date), } / { value: null, date: null, } / { value: null, date: null }` | bubbles / composed | Fired when the value changes — grid pick, typed entry, shortcut, or clear. Detail: `{ value: string \| null, date: Date \| null }` (ISO `YYYY-MM-DD` and a local-midnight Date; both `null` when cleared). |
|
|
129
|
+
| `rel-open-change` | `{ open: this.open } / { open: false }` | bubbles / composed | Fired when the calendar popover opens or closes. Detail: `{ open: boolean }`. |
|
|
130
|
+
|
|
131
|
+
## Slots
|
|
132
|
+
|
|
133
|
+
| Slot | Description |
|
|
134
|
+
| --- | --- |
|
|
135
|
+
| — | This element has no slots. |
|
|
136
|
+
|
|
137
|
+
## CSS Parts
|
|
138
|
+
|
|
139
|
+
| Part | Description |
|
|
140
|
+
| --- | --- |
|
|
141
|
+
| `base` | Outer wrapper carrying the size class (`small` / `medium` / `large`) |
|
|
142
|
+
| `label` | The visible field label (rendered only when `label` is set) |
|
|
143
|
+
| `trigger` | The field box that wraps the text input and the clear/calendar icons |
|
|
144
|
+
| `value` | The editable text input inside the trigger |
|
|
145
|
+
| `shortcuts` | The Today / Tomorrow / Yesterday chip row at the top of the popover |
|
|
146
|
+
|
|
147
|
+
<!-- readme-gen:end -->
|
|
148
|
+
|
|
149
|
+
## Accessibility
|
|
150
|
+
|
|
151
|
+
- The text input is a `role="combobox"` with `aria-haspopup="dialog"`, `aria-expanded`, `aria-controls` pointing at the panel, `aria-required` from `required`, `aria-invalid` when `error` is set or typed text failed to parse, and `aria-describedby` pointing at the helper/error line. Its name is the `label` (via `aria-labelledby`) or the fixed string "Select date" when no label is set; the required `*` is `aria-hidden`.
|
|
152
|
+
- The icons are real buttons: "Clear date" (only while `clearable` and a value is set) and "Open calendar" (carries `aria-expanded`).
|
|
153
|
+
- The popover is a `role="dialog"` named "Choose date". While it is open, Tab and Shift+Tab are trapped inside it (`trapTabKey`), and Escape closes it from anywhere in the document.
|
|
154
|
+
- The month and year pills are buttons carrying `aria-expanded`; pressing one swaps the panel body for a `role="grid"` of `role="gridcell"` cells ("Select month" / "Select year") with `aria-selected` on the current value. Every view is 252 px tall, so the panel never resizes as the user drills in.
|
|
155
|
+
- The day grid is `role="grid"` named "<Month> <Year>"; weeks are `role="row"`; each day is a `<button role="gridcell">` with the full long date as `aria-label`, `aria-selected`, `aria-current="date"` on today and native `disabled` for unavailable days. Only one cell is a Tab stop (last arrowed date → selected → today → first enabled).
|
|
156
|
+
- Focus: opening from the calendar icon, Enter, ArrowDown or by setting `open` moves focus into the grid (onto that Tab-stop cell) after 100 ms; opening by clicking into the text keeps focus in the input so typing keeps working. Closing via Escape, a pick or a shortcut returns focus to the input; an outside click closes without refocusing.
|
|
157
|
+
- Screen readers hear "<Month> <Year>" through the shared `announce()` region (`utils/announce.ts`) on every month/year change (chevrons, a month or year cell, PageUp/PageDown, arrowing across a month boundary), and the first and last year of the page (e.g. "2020 to 2031") when the years page changes. The helper/error line is a persistent `aria-live="polite"` region, so parse errors are read as they appear.
|
|
158
|
+
|
|
159
|
+
| Key (in the field) | Action |
|
|
160
|
+
| --- | --- |
|
|
161
|
+
| Enter | Nothing typed: open the popover. Text typed: commit it |
|
|
162
|
+
| ArrowDown | Open the popover; if already open, move focus into the grid |
|
|
163
|
+
| Escape | Revert uncommitted text and close the popover |
|
|
164
|
+
| Tab (popover open) | Cycle through the popover's controls |
|
|
165
|
+
|
|
166
|
+
| Key (in the grid) | Action |
|
|
167
|
+
| --- | --- |
|
|
168
|
+
| ArrowLeft / ArrowRight | Previous / next day (switches month at the edge) |
|
|
169
|
+
| ArrowUp / ArrowDown | Same weekday one week earlier / later |
|
|
170
|
+
| Home / End | First / last cell of the row |
|
|
171
|
+
| PageUp / PageDown | Previous / next month |
|
|
172
|
+
| Shift + PageUp / Shift + PageDown | Previous / next year |
|
|
173
|
+
| Enter / Space | Select the day; closes the popover unless `closeOnSelect` is false |
|
|
174
|
+
| T (anywhere in the popover, no modifier) | Select today |
|
|
175
|
+
| Escape | Close and return focus to the input |
|
|
176
|
+
|
|
177
|
+
| Key (month / year grid) | Action |
|
|
178
|
+
| --- | --- |
|
|
179
|
+
| Enter / Space on a pill | Open that grid; press the same pill again to return to the days |
|
|
180
|
+
| ArrowLeft / ArrowRight | Previous / next cell |
|
|
181
|
+
| ArrowUp / ArrowDown | Same column, one row up / down |
|
|
182
|
+
| Home / End | First / last cell of the grid |
|
|
183
|
+
| Enter / Space | Choose the cell — a year drills into the months, a month returns to the days |
|
|
184
|
+
| Escape | Back to the days grid, keeping the popover open |
|
|
185
|
+
|
|
186
|
+
## Notes / Edge Cases
|
|
187
|
+
|
|
188
|
+
- `value` is always ISO `YYYY-MM-DD`; `display-format` and `formatDate` change only the visible text. The `Date` given to `formatDate`, `isDateDisabled` and `rel-change` is at local midnight — read it with `getFullYear()`/`getMonth()`/`getDate()`, never `toISOString()` (which can shift the day by the UTC offset). For a plain ISO display use `display-format="YYYY-MM-DD"`.
|
|
189
|
+
- `min`/`max` are deprecated aliases of `min-date`/`max-date`; when both spellings are present the canonical one wins. No runtime notice is logged.
|
|
190
|
+
- Leading and trailing cells of adjacent months are rendered but never selectable (unlike `rel-calendar`).
|
|
191
|
+
- The years grid shows one 12-year page at a time, anchored so the year in view sits in the seventh cell; the chevrons page by 12. In the months grid the chevrons step a year, and in the days grid a month. A month or year cell is disabled only when *every* day it covers falls outside `min-date`/`max-date`.
|
|
192
|
+
- The panel always reopens on the days grid, whichever view was showing when it closed.
|
|
193
|
+
- The field is Figma's TextField instance: `border-radius: xs` (4 px), 12 px inline padding at `medium`, a 4 px label gap and an 18 px suffix icon — the same geometry `rel-textfield` uses, so the two line up in a shared form row. Icon and inline padding step with `size` (16/18/20 px and 8/12/16 px).
|
|
194
|
+
- The panel is promoted to the browser top layer (`popover="manual"`), so it renders above `rel-modal` / `rel-drawer` and transformed or `overflow: hidden` ancestors, and it repositions on scroll/resize. It flips above the trigger when there is no room below, stays 8 px inside the viewport, is capped at 600 px tall (scrolls) and never wider than the viewport.
|
|
195
|
+
- Below-field text resolves as `errorMessage ?? typed-entry error ?? helperText` while in error, else `helperText`. A typed-entry error styles the field like `error` without setting the property.
|
|
196
|
+
- `readonly` and `disabled` both stop the popover from opening (field click, icon, Enter, ArrowDown); `disabled` also blocks all pointer events.
|
|
197
|
+
- `closeOnSelect` is a boolean attribute: it can only be turned off from JavaScript (`picker.closeOnSelect = false`). It affects grid picks only — typed entry and shortcuts always close the popover.
|
|
198
|
+
- The `name` hidden input submits an empty string while `value` is null.
|
|
199
|
+
- `size` is applied as a class on part `base` (not reflected); `variant` currently has the single value `outlined`.
|
|
200
|
+
- The host is `inline-block` with an intrinsic width (min 200 px) by default; `fullwidth` switches it to a block that fills the parent.
|