@antadesign/anta 0.3.34 → 0.3.35
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/LICENSE.md +14 -1
- package/README.md +9 -0
- package/dist/anta_helpers.d.ts +46 -30
- package/dist/anta_helpers.js +66 -25
- package/dist/bundle.css +1 -1
- package/dist/bundle.js +2 -1333
- package/dist/components/Banner.d.ts +25 -40
- package/dist/components/Banner.js +15 -17
- package/dist/components/Button.js +1 -0
- package/dist/components/ButtonCopy.js +3 -2
- package/dist/components/Calendar.js +13 -13
- package/dist/components/Card.d.ts +9 -17
- package/dist/components/Card.js +50 -46
- package/dist/components/Dialog.d.ts +1 -0
- package/dist/components/Dialog.js +16 -10
- package/dist/components/Expander.d.ts +6 -21
- package/dist/components/Expander.js +24 -23
- package/dist/components/Icon.d.ts +8 -14
- package/dist/components/Input.d.ts +77 -96
- package/dist/components/Input.js +23 -27
- package/dist/components/InputAutocomplete.d.ts +29 -10
- package/dist/components/InputAutocomplete.js +25 -8
- package/dist/components/InputDate.js +2 -2
- package/dist/components/InputTime.d.ts +10 -4
- package/dist/components/InputTime.js +20 -16
- package/dist/components/Loader.d.ts +2 -2
- package/dist/components/Menu.d.ts +5 -4
- package/dist/components/Menu.js +13 -8
- package/dist/components/MenuItem.js +1 -14
- package/dist/components/MenuItemCopy.js +2 -2
- package/dist/components/Panel.d.ts +3 -1
- package/dist/components/Panel.js +17 -11
- package/dist/components/Progress.d.ts +21 -23
- package/dist/components/Progress.js +13 -9
- package/dist/components/RadioGroup.js +6 -8
- package/dist/components/{select-parts.css → Select.css} +1 -1
- package/dist/components/Select.d.ts +53 -35
- package/dist/components/Select.js +53 -97
- package/dist/components/SelectFaceted.d.ts +7 -3
- package/dist/components/SelectFaceted.js +21 -9
- package/dist/components/Slider.d.ts +28 -11
- package/dist/components/Slider.js +20 -20
- package/dist/components/Steps.css +1 -1
- package/dist/components/Steps.js +1 -11
- package/dist/components/Tabs.d.ts +17 -20
- package/dist/components/Tabs.js +5 -8
- package/dist/components/Text.d.ts +55 -36
- package/dist/components/Text.js +35 -22
- package/dist/components/Title.d.ts +16 -26
- package/dist/components/Title.js +2 -1
- package/dist/components/Toaster.js +9 -2
- package/dist/components/Tooltip.d.ts +10 -15
- package/dist/components/copy-props.d.ts +14 -3
- package/dist/components/copy-props.js +14 -3
- package/dist/components/select-tree.d.ts +24 -0
- package/dist/components/select-tree.js +35 -0
- package/dist/element-base.d.ts +10 -0
- package/dist/element-base.js +15 -0
- package/dist/elements/a-banner.css +1 -1
- package/dist/elements/a-banner.d.ts +4 -1
- package/dist/elements/a-banner.js +22 -112
- package/dist/elements/a-button.d.ts +2 -1
- package/dist/elements/a-button.js +18 -1
- package/dist/elements/a-calendar.d.ts +14 -13
- package/dist/elements/a-calendar.js +29 -24
- package/dist/elements/a-card.css +1 -1
- package/dist/elements/a-card.d.ts +0 -9
- package/dist/elements/a-card.js +0 -184
- package/dist/elements/a-checkbox.css +1 -1
- package/dist/elements/a-copy.css +1 -1
- package/dist/elements/a-copy.d.ts +1 -5
- package/dist/elements/a-copy.js +129 -108
- package/dist/elements/a-dialog.css +1 -1
- package/dist/elements/a-dialog.d.ts +1 -1
- package/dist/elements/a-dialog.js +66 -194
- package/dist/elements/a-expander.css +1 -1
- package/dist/elements/a-expander.d.ts +4 -30
- package/dist/elements/a-expander.js +85 -344
- package/dist/elements/a-icon.d.ts +5 -23
- package/dist/elements/a-icon.js +1 -2
- package/dist/elements/a-input-time.css +1 -1
- package/dist/elements/a-input-time.d.ts +2 -1
- package/dist/elements/a-input-time.js +101 -168
- package/dist/elements/a-input.css +1 -1
- package/dist/elements/a-input.d.ts +10 -8
- package/dist/elements/a-input.js +155 -230
- package/dist/elements/a-loader.d.ts +5 -8
- package/dist/elements/a-loader.js +1 -2
- package/dist/elements/a-menu-item.css +1 -1
- package/dist/elements/a-menu-item.d.ts +5 -3
- package/dist/elements/a-menu-item.js +5 -1
- package/dist/elements/a-menu.css +1 -1
- package/dist/elements/a-menu.d.ts +5 -7
- package/dist/elements/a-menu.js +383 -299
- package/dist/elements/a-panel.css +1 -1
- package/dist/elements/a-panel.js +19 -37
- package/dist/elements/a-progress.css +1 -1
- package/dist/elements/a-progress.d.ts +0 -22
- package/dist/elements/a-progress.js +0 -100
- package/dist/elements/a-radio-group.d.ts +1 -1
- package/dist/elements/a-radio-group.js +6 -4
- package/dist/elements/a-select-faceted.d.ts +1 -1
- package/dist/elements/a-select-faceted.js +1 -1
- package/dist/elements/a-select.d.ts +1 -1
- package/dist/elements/a-select.js +1 -1
- package/dist/elements/a-slider.css +1 -1
- package/dist/elements/a-slider.d.ts +11 -3
- package/dist/elements/a-slider.js +244 -242
- package/dist/elements/a-switch.css +1 -1
- package/dist/elements/a-tab.css +1 -1
- package/dist/elements/a-tabs.css +1 -1
- package/dist/elements/a-tabs.d.ts +1 -1
- package/dist/elements/a-tabs.js +6 -4
- package/dist/elements/a-tag.css +1 -1
- package/dist/elements/a-text.css +1 -1
- package/dist/elements/a-text.d.ts +6 -43
- package/dist/elements/a-text.js +110 -193
- package/dist/elements/a-title.css +1 -1
- package/dist/elements/a-toast.css +1 -1
- package/dist/elements/a-toast.d.ts +10 -45
- package/dist/elements/a-toast.js +80 -66
- package/dist/elements/a-toaster.css +1 -1
- package/dist/elements/a-toaster.js +9 -44
- package/dist/elements/a-tooltip.css +1 -1
- package/dist/elements/a-tooltip.d.ts +1 -1
- package/dist/elements/a-tooltip.js +142 -136
- package/dist/elements/copy-behavior.d.ts +1 -1
- package/dist/elements/copy-behavior.js +21 -21
- package/dist/elements/index.d.ts +3 -3
- package/dist/elements/index.js +3 -7
- package/dist/elements/input-focus-modality.d.ts +15 -0
- package/dist/elements/input-focus-modality.js +44 -0
- package/dist/elements/input-trailing-actions.d.ts +5 -0
- package/dist/elements/input-trailing-actions.js +38 -0
- package/dist/elements/shadow-aria.d.ts +2 -0
- package/dist/elements/shadow-aria.js +2 -1
- package/dist/elements/value-input.d.ts +3 -0
- package/dist/elements/value-input.js +12 -0
- package/dist/general_types.d.ts +103 -96
- package/dist/index.d.ts +1 -1
- package/dist/input-events.d.ts +4 -0
- package/dist/input-events.js +15 -0
- package/dist/jsx-runtime.d.ts +70 -23
- package/dist/jsx-runtime.js +26 -19
- package/dist/native-event-props.d.ts +2 -0
- package/dist/native-event-props.js +10 -0
- package/dist/reset.css +1 -1
- package/dist/theme-antithesis.css +10 -1
- package/dist/theme-antune.css +1 -1
- package/docs/accessibility.md +17 -3
- package/docs/changelog.md +348 -2
- package/docs/comparison.md +2 -2
- package/docs/components/avatar.md +5 -0
- package/docs/components/banner.md +117 -187
- package/docs/components/button.md +22 -0
- package/docs/components/card.md +74 -28
- package/docs/components/checkbox.md +9 -10
- package/docs/components/dialog.md +83 -32
- package/docs/components/expander.md +198 -435
- package/docs/components/icon.md +11 -17
- package/docs/components/input-autocomplete.md +152 -52
- package/docs/components/input-date.md +175 -148
- package/docs/components/input-time.md +81 -38
- package/docs/components/input.md +343 -349
- package/docs/components/loader.md +2 -1
- package/docs/components/menu.md +35 -6
- package/docs/components/panel.md +18 -0
- package/docs/components/progress.md +83 -49
- package/docs/components/radio.md +39 -43
- package/docs/components/select-faceted.md +54 -7
- package/docs/components/select.md +390 -386
- package/docs/components/slider.md +136 -19
- package/docs/components/steps.md +2 -1
- package/docs/components/switch.md +8 -9
- package/docs/components/tabs.md +110 -104
- package/docs/components/text.md +110 -86
- package/docs/components/title.md +47 -33
- package/docs/components/toaster.md +242 -84
- package/docs/components/tooltip.md +204 -113
- package/docs/install-config.md +183 -26
- package/docs/packages/plot.md +170 -148
- package/docs/theming.md +7 -0
- package/package.json +41 -3
- package/theme-antithesis-license.md +66 -0
|
@@ -1,49 +1,46 @@
|
|
|
1
1
|
# InputDate
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
`time
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
month names, and run-together digits, then rewrites the entry to the canonical
|
|
12
|
-
format. An unrecognized entry marks the field until you fix it. The value is an ISO
|
|
13
|
-
`YYYY-MM-DD` string, never a `Date`; it works controlled (`value` + `onValueChange`)
|
|
14
|
-
or uncontrolled (`defaultValue`), and submits under `name`.
|
|
3
|
+
Use InputDate to enter a date by typing or choosing a day from a calendar.
|
|
4
|
+
Add `time` when the task also needs a time of day. Use [Calendar](#calendar)
|
|
5
|
+
directly when the month grid should stay visible without a field.
|
|
6
|
+
|
|
7
|
+
Render InputDate and Calendar only on the client. Their current date and locale
|
|
8
|
+
can differ between server and browser rendering. In Astro, use `client:only`.
|
|
9
|
+
See [Server and worker rendering](../install-config.md#server-and-worker-rendering) for
|
|
10
|
+
setup guidance.
|
|
15
11
|
|
|
16
12
|
## The date field
|
|
17
13
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
14
|
+
Enter a date and press Enter or leave the field to confirm it.
|
|
15
|
+
InputDate accepts the locale's date order, month names, and dates without
|
|
16
|
+
separators, then formats the result. An unrecognized entry stays visible and
|
|
17
|
+
marks the field invalid so it can be corrected.
|
|
18
|
+
|
|
19
|
+
Select the field to open its calendar while keeping focus in the text.
|
|
20
|
+
Press ↓ to open the calendar and focus a day. Press Esc
|
|
21
|
+
to close it and return focus to the field. While you type, the calendar previews
|
|
22
|
+
recognized dates. Pressing Enter confirms the date and closes the
|
|
23
|
+
calendar. An unrecognized entry keeps the calendar open.
|
|
26
24
|
|
|
27
25
|
```tsx
|
|
28
26
|
<InputDate label="Due date" defaultValue="2026-06-15" onValueChange={(v) => save(v)} />
|
|
29
27
|
```
|
|
30
28
|
|
|
31
|
-
|
|
32
|
-
`
|
|
33
|
-
|
|
29
|
+
Set `locale` to choose the date format. For example, `06/07/2026` means June 7
|
|
30
|
+
in `en-US` and July 6 in `de-DE`. The placeholder shows the expected format.
|
|
31
|
+
Use `min` and `max` to limit both typed dates and calendar choices.
|
|
34
32
|
|
|
35
33
|
```tsx
|
|
36
34
|
<InputDate label="US English" locale="en-US" defaultValue="2026-06-15" />
|
|
37
35
|
<InputDate label="German" locale="de-DE" defaultValue="2026-06-15" />
|
|
38
36
|
```
|
|
39
37
|
|
|
40
|
-
`time`
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
field converts it (18 → 6 PM).
|
|
38
|
+
Pass `time` to add a time field and confirmation button to the calendar.
|
|
39
|
+
Choosing a day keeps the calendar open so the time can be entered before
|
|
40
|
+
confirming. The clock follows the locale. Use `hour12` to override it.
|
|
41
|
+
|
|
42
|
+
You can also type a date and time together, such as `06/15/2026 2:30pm` or
|
|
43
|
+
`06/15/2026 14:30`. In a 12-hour time field, entering `18` converts to `6 PM`.
|
|
47
44
|
|
|
48
45
|
```tsx
|
|
49
46
|
{/* `size` scales the calendar, the time inputs, the AM/PM toggle, and the buttons together. */}
|
|
@@ -52,6 +49,19 @@ field converts it (18 → 6 PM).
|
|
|
52
49
|
<InputDate size="large" label="Large" time defaultValue="2026-06-15T09:00" />
|
|
53
50
|
```
|
|
54
51
|
|
|
52
|
+
### Manage the value
|
|
53
|
+
|
|
54
|
+
Use `defaultValue` for an initial date, or pair `value` with `onValueChange`
|
|
55
|
+
to control it. InputDate reports an ISO string: `YYYY-MM-DD`, or
|
|
56
|
+
`YYYY-MM-DDTHH:mm` with `time`. An empty field reports `''`. Add `name` to
|
|
57
|
+
submit that value with a form.
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
const [date, setDate] = useState('2026-06-15')
|
|
61
|
+
|
|
62
|
+
<InputDate label="Due date" name="due-date" value={date} onValueChange={setDate} />
|
|
63
|
+
```
|
|
64
|
+
|
|
55
65
|
## InputDate props
|
|
56
66
|
|
|
57
67
|
| Prop | Type | Default | Description |
|
|
@@ -79,35 +89,18 @@ field converts it (18 → 6 PM).
|
|
|
79
89
|
|
|
80
90
|
## Calendar
|
|
81
91
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
[Temporal API](https://tc39.es/proposal-temporal/docs/) through
|
|
89
|
-
`temporal-polyfill`.
|
|
90
|
-
|
|
91
|
-
For a raw grid, import `buildMonth` from `@antadesign/anta`. It returns
|
|
92
|
-
localized weekday headers and day records with ISO values, accessible labels,
|
|
93
|
-
and selected, disabled, today, and outside-month state. It does not manage
|
|
94
|
-
navigation, roving focus, selection, or rendering. The value is an ISO
|
|
95
|
-
`YYYY-MM-DD` string, never a `Date`. Use `value` with `onStateChange` to
|
|
96
|
-
control it, or `defaultValue` for uncontrolled use. It participates in forms
|
|
97
|
-
under `name`.
|
|
98
|
-
|
|
99
|
-
**Not SSR-safe.** `Calendar` (and `InputDate`, which embeds it) reads the current
|
|
100
|
-
date (`Temporal.Now`) and locale (`navigator.language`) at render, so a server
|
|
101
|
-
render disagrees with the client on the highlighted "today" and on localized
|
|
102
|
-
labels, and the page hydrates with a mismatch. Render it client-side only: Astro
|
|
103
|
-
`client:only`, or a dynamic import inside `useEffect`. Every demo on this page uses
|
|
104
|
-
`client:only` for that reason.
|
|
92
|
+
Use Calendar for an inline date picker, such as a booking form with a month
|
|
93
|
+
always in view. It provides day selection, month navigation, keyboard access,
|
|
94
|
+
and form submission.
|
|
95
|
+
|
|
96
|
+
Like InputDate, Calendar must render only on the client. The examples use
|
|
97
|
+
Astro's `client:only` directive.
|
|
105
98
|
|
|
106
99
|
## Selecting a date
|
|
107
100
|
|
|
108
|
-
|
|
109
|
-
selected day
|
|
110
|
-
|
|
101
|
+
Select a day, or focus it and press Enter or Space.
|
|
102
|
+
The selected day has a brand-colored fill and ring. Today's date has a subtle
|
|
103
|
+
fill when it is not selected.
|
|
111
104
|
|
|
112
105
|
```tsx
|
|
113
106
|
<Calendar defaultValue="2026-06-12" />
|
|
@@ -160,9 +153,8 @@ button are disabled, and only the in-range days stay selectable.
|
|
|
160
153
|
|
|
161
154
|
## Locale
|
|
162
155
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
info (never hard-coded to Sunday), and the weekday and month names are localized.
|
|
156
|
+
Calendar uses the browser's locale by default. Pass a locale tag such as
|
|
157
|
+
`en-US`, `fr-FR`, or `ja-JP` to choose the language and first day of the week.
|
|
166
158
|
|
|
167
159
|
```tsx
|
|
168
160
|
<Calendar defaultValue="2026-06-28" locale="en-US" /> {/* week starts Sunday */}
|
|
@@ -200,9 +192,9 @@ vetoes it (uncontrolled). A controlled calendar with no `onStateChange` is read-
|
|
|
200
192
|
|
|
201
193
|
## Forms
|
|
202
194
|
|
|
203
|
-
`
|
|
204
|
-
|
|
205
|
-
|
|
195
|
+
Add `name` to submit the selected ISO date with a form. An uncontrolled Calendar
|
|
196
|
+
returns to `defaultValue` on form reset. For a controlled Calendar, handle the
|
|
197
|
+
reset request in `onStateChange` and update `value` as needed.
|
|
206
198
|
|
|
207
199
|
```tsx
|
|
208
200
|
<form>
|
|
@@ -212,19 +204,13 @@ the standard constraint-validation pipeline.
|
|
|
212
204
|
|
|
213
205
|
## Accessibility
|
|
214
206
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
collisions. An explicitly authored relationship on a raw Anta Input takes
|
|
219
|
-
precedence.
|
|
207
|
+
InputDate identifies its calendar as a dialog associated with the field.
|
|
208
|
+
Opening it with ↓ moves focus into the calendar. Closing it with
|
|
209
|
+
Esc returns focus to the field.
|
|
220
210
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
including weekday ("Sunday, June 28, 2026"), with `aria-pressed` on the selected day
|
|
225
|
-
and `aria-current="date"` on today. The decorative weekday headers are `aria-hidden`,
|
|
226
|
-
since each day already names its weekday. A roving `tabindex` keeps a single tab
|
|
227
|
-
stop, and an `aria-live` region announces the month when it changes.
|
|
211
|
+
Calendar announces the displayed month and gives each day its full date,
|
|
212
|
+
including the weekday. Screen readers can identify the selected day and today's
|
|
213
|
+
date. The day grid has one Tab stop, and changing months announces the new month.
|
|
228
214
|
|
|
229
215
|
| Key | Moves focus |
|
|
230
216
|
|---|---|
|
|
@@ -237,53 +223,38 @@ stop, and an `aria-live` region announces the month when it changes.
|
|
|
237
223
|
|
|
238
224
|
## Customization
|
|
239
225
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
226
|
+
Use the InputDate and Calendar wrappers for the complete date-entry interface.
|
|
227
|
+
For custom calendar rendering, `buildMonth` supplies localized weekday headers
|
|
228
|
+
and day records with ISO values, accessible labels, and selection and range
|
|
229
|
+
states. Your application supplies rendering and navigation.
|
|
244
230
|
|
|
245
231
|
### Build it from elements
|
|
246
232
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
framework-agnostic and does not track a current month, `min`, or `max`.
|
|
264
|
-
|
|
265
|
-
The JSX wrapper renders the controls above the grid as siblings of
|
|
266
|
-
`<a-calendar>`. The previous/next arrows are `<Button>`s. The month/year picker
|
|
267
|
-
is a `<Button>` that opens a `<Menu>` of year `MenuItem`s, each with a month
|
|
268
|
-
submenu. The wrapper stores the displayed-month cursor in state and derives day
|
|
269
|
-
cells and the arrows' `disabled` states from `min` and `max`. A click on an
|
|
270
|
-
arrow, a menu selection, or a `navigate` event updates the cursor and re-renders
|
|
271
|
-
the grid. The wrapper enforces the range. The element only ignores a day that
|
|
272
|
-
was rendered with `disabled`.
|
|
273
|
-
|
|
274
|
-
The element has no `min` or `max` because the wrapper provides the surrounding
|
|
275
|
-
controls. Without React, render the grid with `buildMonth` and add the
|
|
276
|
-
navigation behavior shown below:
|
|
233
|
+
InputDate combines Input, Menu, and Calendar. There is no separate InputDate host
|
|
234
|
+
element. Recreating it requires text parsing, date formatting, popup behavior,
|
|
235
|
+
and focus management. For a form that can use the browser's picker, consider
|
|
236
|
+
[Native HTML date input](#native-html-date-input).
|
|
237
|
+
|
|
238
|
+
For a custom month grid, use `<a-calendar>` with day buttons marked
|
|
239
|
+
`data-part="day-cell"` and `data-date="YYYY-MM-DD"`. It provides keyboard
|
|
240
|
+
navigation, selection requests, and form submission. Render the surrounding
|
|
241
|
+
month controls yourself and handle `navigate` when focus moves to another date.
|
|
242
|
+
|
|
243
|
+
`buildMonth` returns the month heading, weekdays, and day records. Pass `min`
|
|
244
|
+
and `max` to it when building a bounded grid, render out-of-range dates with
|
|
245
|
+
`disabled`, and limit your month controls to that range.
|
|
246
|
+
|
|
247
|
+
This example supplies previous and next month controls and a controlled
|
|
248
|
+
selection:
|
|
277
249
|
|
|
278
250
|
```html
|
|
279
251
|
<!-- `.calendar` scopes this example. Use an application selector instead. -->
|
|
280
252
|
<div class="calendar" style="display: inline-flex; flex-direction: column; gap: 6px">
|
|
281
253
|
<div style="display: flex; align-items: center">
|
|
282
|
-
<a-button priority="tertiary" data-prev aria-label="Previous month"><a-icon shape="chevron-left"></a-icon></a-button>
|
|
283
|
-
<
|
|
284
|
-
<a-button priority="tertiary" data-next aria-label="Next month"><a-icon shape="chevron-right"></a-icon></a-button>
|
|
254
|
+
<a-button role="button" tabindex="0" priority="tertiary" data-prev aria-label="Previous month"><a-icon shape="chevron-left" aria-hidden="true"></a-icon></a-button>
|
|
255
|
+
<span data-heading style="flex: 1; text-align: center"></span>
|
|
256
|
+
<a-button role="button" tabindex="0" priority="tertiary" data-next aria-label="Next month"><a-icon shape="chevron-right" aria-hidden="true"></a-icon></a-button>
|
|
285
257
|
</div>
|
|
286
|
-
<!-- The element provides selection, keyboard behavior, form value, and events. -->
|
|
287
258
|
<a-calendar role="group" name="date"></a-calendar>
|
|
288
259
|
</div>
|
|
289
260
|
<script type="module">
|
|
@@ -295,40 +266,99 @@ navigation behavior shown below:
|
|
|
295
266
|
const grid = root.querySelector('a-calendar')
|
|
296
267
|
const heading = root.querySelector('[data-heading]')
|
|
297
268
|
let cursor = Temporal.Now.plainDateISO()
|
|
269
|
+
grid.value = cursor.toString()
|
|
270
|
+
|
|
271
|
+
function focusDate(iso) {
|
|
272
|
+
grid.querySelector(`[data-date="${iso}"]`)?.focus()
|
|
273
|
+
}
|
|
298
274
|
|
|
299
275
|
function render() {
|
|
300
|
-
const
|
|
301
|
-
|
|
276
|
+
const month = buildMonth({
|
|
277
|
+
anchor: cursor,
|
|
278
|
+
locale: navigator.language,
|
|
279
|
+
selected: parseISODate(grid.value),
|
|
280
|
+
})
|
|
281
|
+
heading.textContent = month.heading
|
|
282
|
+
grid.setAttribute('aria-label', month.heading)
|
|
302
283
|
grid.replaceChildren()
|
|
303
|
-
for (const
|
|
304
|
-
const
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
grid.append(
|
|
284
|
+
for (const weekday of month.weekdays) {
|
|
285
|
+
const label = Object.assign(document.createElement('span'), { textContent: weekday.narrow })
|
|
286
|
+
label.setAttribute('data-part', 'weekday')
|
|
287
|
+
label.setAttribute('aria-hidden', 'true')
|
|
288
|
+
grid.append(label)
|
|
308
289
|
}
|
|
309
|
-
for (const
|
|
310
|
-
const
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
290
|
+
for (const day of month.weeks.flat()) {
|
|
291
|
+
const button = document.createElement('a-button')
|
|
292
|
+
const label = Object.assign(document.createElement('a-button-label'), { textContent: String(day.day) })
|
|
293
|
+
button.append(label)
|
|
294
|
+
button.setAttribute('role', 'button')
|
|
295
|
+
button.setAttribute('priority', day.today && !day.selected ? 'secondary' : 'tertiary')
|
|
296
|
+
button.setAttribute('data-part', 'day-cell')
|
|
297
|
+
button.setAttribute('data-date', day.iso)
|
|
298
|
+
button.setAttribute('aria-label', day.label)
|
|
299
|
+
button.setAttribute('aria-pressed', String(day.selected))
|
|
300
|
+
button.tabIndex = day.iso === cursor.toString() ? 0 : -1
|
|
301
|
+
if (day.selected) {
|
|
302
|
+
button.setAttribute('selected', '')
|
|
303
|
+
button.setAttribute('tone', 'brand')
|
|
304
|
+
}
|
|
305
|
+
if (day.disabled) button.setAttribute('disabled', '')
|
|
306
|
+
if (day.today) {
|
|
307
|
+
button.setAttribute('data-today', '')
|
|
308
|
+
button.setAttribute('aria-current', 'date')
|
|
309
|
+
}
|
|
310
|
+
if (day.outside) button.setAttribute('data-outside', '')
|
|
311
|
+
grid.append(button)
|
|
318
312
|
}
|
|
319
313
|
}
|
|
320
314
|
|
|
321
|
-
root.querySelector('[data-prev]').addEventListener('click', () => {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
315
|
+
root.querySelector('[data-prev]').addEventListener('click', () => {
|
|
316
|
+
cursor = cursor.subtract({ months: 1 })
|
|
317
|
+
render()
|
|
318
|
+
})
|
|
319
|
+
root.querySelector('[data-next]').addEventListener('click', () => {
|
|
320
|
+
cursor = cursor.add({ months: 1 })
|
|
321
|
+
render()
|
|
322
|
+
})
|
|
323
|
+
grid.addEventListener('statechange', (event) => {
|
|
324
|
+
grid.value = event.detail.next ?? ''
|
|
325
|
+
cursor = parseISODate(grid.value) ?? cursor
|
|
326
|
+
render()
|
|
327
|
+
focusDate(cursor.toString())
|
|
328
|
+
})
|
|
329
|
+
grid.addEventListener('navigate', (event) => {
|
|
330
|
+
cursor = parseISODate(event.detail.date) ?? cursor
|
|
331
|
+
render()
|
|
332
|
+
focusDate(cursor.toString())
|
|
333
|
+
})
|
|
325
334
|
render()
|
|
326
335
|
</script>
|
|
327
336
|
```
|
|
328
337
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
338
|
+
Use the Calendar wrapper when you also need its year/month jump menu and
|
|
339
|
+
range-aware controls.
|
|
340
|
+
|
|
341
|
+
### Raw Calendar value and form API
|
|
342
|
+
|
|
343
|
+
Use `value` for controlled selection or `defaultvalue` for an uncontrolled
|
|
344
|
+
initial and reset date. The `.value` property returns the applied ISO date, or
|
|
345
|
+
`null` when empty. The `.defaultValue` property returns the authored reset date,
|
|
346
|
+
or `null` when unset.
|
|
347
|
+
|
|
348
|
+
Assigning a string to `.value` supplies controlled input. An empty `value=""`
|
|
349
|
+
keeps the calendar controlled and empty. Remove `value`, or assign `null` or
|
|
350
|
+
`undefined` to `.value`, to release control while retaining the applied date.
|
|
351
|
+
Uncontrolled picks, reset, and restoration leave those input attributes unchanged.
|
|
352
|
+
|
|
353
|
+
Accept controlled picks from `statechange` by updating `value`. `change` reports
|
|
354
|
+
applied selection. `navigate` requests a new focus date. The application renders
|
|
355
|
+
the requested month and focuses that day. Author the month label and each day
|
|
356
|
+
button's accessible name. Calendar does not generate those labels.
|
|
357
|
+
|
|
358
|
+
For Preact, prefer the Calendar wrapper. Raw `<a-calendar value={...}>` bindings
|
|
359
|
+
can retain the old value when assigned `undefined`, or write `value=""` when the
|
|
360
|
+
prop is omitted. Release a raw instance by removing its `value` attribute or
|
|
361
|
+
assigning `null` to `.value`.
|
|
332
362
|
|
|
333
363
|
## Calendar props
|
|
334
364
|
|
|
@@ -350,11 +380,8 @@ which uses the same `Menu` composition shown on the [Menu](./menu.md) page.
|
|
|
350
380
|
|
|
351
381
|
## Web Component
|
|
352
382
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
in vanilla JavaScript is significant work, even with Anta's `buildMonth` and
|
|
356
|
-
`parseISODate` helpers. Use the `InputDate` wrapper when React or Preact is an
|
|
357
|
-
option. Otherwise, a native HTML date input is the practical baseline.
|
|
383
|
+
Use a native date input when the browser's picker fits your form. To build a
|
|
384
|
+
custom picker without JSX, see [Build it from elements](#build-it-from-elements).
|
|
358
385
|
|
|
359
386
|
### Native HTML date input
|
|
360
387
|
|
|
@@ -377,12 +404,12 @@ field treatments.
|
|
|
377
404
|
|
|
378
405
|
## Styling
|
|
379
406
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
407
|
+
Use ordinary CSS to style the calendar and its day buttons. `className` applies
|
|
408
|
+
to the outer `.anta-calendar` container. Unlayered consumer rules override Anta's
|
|
409
|
+
defaults. Replace the example classes with your own selectors.
|
|
410
|
+
|
|
411
|
+
Set `--calendar-cell-width` and `--calendar-cell-height` to make day targets
|
|
412
|
+
larger, then use `border-radius` to shape them:
|
|
386
413
|
|
|
387
414
|
```css
|
|
388
415
|
/* Bigger, circular day cells. `className` lands on the outer .anta-calendar
|
|
@@ -413,5 +440,5 @@ brand dot and one is flagged in the critical color.
|
|
|
413
440
|
}
|
|
414
441
|
```
|
|
415
442
|
|
|
416
|
-
|
|
417
|
-
|
|
443
|
+
For a custom month layout, use the exported `buildMonth` and `firstDayOfWeek`
|
|
444
|
+
helpers. See [Build it from elements](#build-it-from-elements).
|
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
# InputTime
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
`a` / `p`.
|
|
11
|
-
|
|
12
|
-
A leading clock icon marks the affordance (change it with `icon`). Unlike a text
|
|
13
|
-
`Input` (which fills its container), the field **sizes to its content** — a time
|
|
14
|
-
is a small, fixed control — so set a `width` (e.g. `style={{ width: '100%' }}`) if
|
|
15
|
-
you want it to fill. The value is a 24-hour `"HH:mm"` string (`''` until both hour
|
|
16
|
-
and minute are set), never a `Date`. It works controlled (`value` + `onValueChange`)
|
|
17
|
-
or uncontrolled (`defaultValue`), and submits under `name` via the native form APIs.
|
|
3
|
+
Use InputTime for a time of day, such as a meeting start or office hours.
|
|
4
|
+
The field provides hour and minute sections, with AM/PM in 12-hour locales.
|
|
5
|
+
Enter digits or use the arrow keys to adjust each section.
|
|
6
|
+
|
|
7
|
+
The value is a 24-hour `HH:mm` string, or `''` while the time is incomplete.
|
|
8
|
+
Use `defaultValue` for an initial time, or pair `value` with `onValueChange`
|
|
9
|
+
to control it. Add `name` to submit the value with a form.
|
|
18
10
|
|
|
19
11
|
## The field
|
|
20
12
|
|
|
21
|
-
Focus a section and
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
13
|
+
Focus a section and enter digits. The caret advances when the section is
|
|
14
|
+
complete. For example, entering `9`, `3`, and `0` produces `09:30`.
|
|
15
|
+
In a 12-hour field, entering `18` sets `6 PM`. The period section accepts its
|
|
16
|
+
localized text or `a` and `p`.
|
|
17
|
+
|
|
18
|
+
Use the keyboard to adjust or move between sections:
|
|
19
|
+
|
|
20
|
+
- ↑ and ↓ step the value, wrapping at its limits.
|
|
21
|
+
- ← and → move between sections at the caret boundary.
|
|
22
|
+
- PageUp and PageDown make larger minute adjustments.
|
|
23
|
+
- Backspace in an empty section selects the previous section.
|
|
24
|
+
|
|
25
|
+
Home, End, selection, deletion, and paste keep their native text-field behavior.
|
|
26
|
+
When one digit cannot grow into a valid two-digit value, the field confirms
|
|
27
|
+
that section and advances. Entering `6` in minutes, for example, sets `06`.
|
|
28
|
+
|
|
29
|
+
The field sizes to its content. Set `width` when it should fill its container.
|
|
30
|
+
Use `icon` to replace the leading clock, or `icon={false}` to remove it.
|
|
31
31
|
|
|
32
32
|
```tsx
|
|
33
33
|
<InputTime label="Start time" defaultValue="09:30" onValueChange={(_, { value }) => save(value)} />
|
|
@@ -35,12 +35,13 @@ reads as one field while preserving native caret behavior. In a
|
|
|
35
35
|
|
|
36
36
|
## Locale
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
Set `locale` to choose the clock format, section order, separator, and AM/PM
|
|
39
|
+
text. For example, `en-US` uses a 12-hour clock and `de-DE` uses a 24-hour clock.
|
|
40
|
+
Japanese can place the period first, and Finnish uses a dot separator.
|
|
41
|
+
Pass `hour12` or `hour12={false}` to override the locale's clock format.
|
|
42
|
+
|
|
43
|
+
The period section reserves enough space for either label, so switching AM/PM
|
|
44
|
+
does not change the field's width.
|
|
44
45
|
|
|
45
46
|
```tsx
|
|
46
47
|
<InputTime label="US English" locale="en-US" defaultValue="14:05" /> {/* 12-hour: 02 : 05 PM */}
|
|
@@ -54,7 +55,7 @@ with a dot (`14.05`), and 24-hour locales drop the AM/PM section entirely. Set
|
|
|
54
55
|
`size` (`small` / `medium` / `large`) matches the other inputs' scale; `status`
|
|
55
56
|
recolors the box and hint (only `critical` marks it invalid); `clearable` adds a
|
|
56
57
|
clear button once a value is set — clearing empties every section back to the
|
|
57
|
-
placeholder dashes. `disabled`
|
|
58
|
+
placeholder dashes. `disabled` prevents focus and editing. `readOnly` keeps the time selectable and focusable while preventing edits.
|
|
58
59
|
|
|
59
60
|
`min` and `max` (24-hour `"HH:mm"`) bound the value: a complete time outside the
|
|
60
61
|
range is clamped to the nearest bound as you step or leave the field, and flags
|
|
@@ -66,6 +67,25 @@ range is clamped to the nearest bound as you step or leave the field, and flags
|
|
|
66
67
|
<InputTime label="Office hours" size="large" min="09:00" max="17:00" defaultValue="09:30" />
|
|
67
68
|
```
|
|
68
69
|
|
|
70
|
+
## Controlled values and clearing
|
|
71
|
+
|
|
72
|
+
Update `value` from `onValueChange` to control the time. An incomplete time reports
|
|
73
|
+
an empty string while the native segments retain the text being edited. Call
|
|
74
|
+
`preventDefault()` in `onClearClick` to keep a value when clearing is disallowed.
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
const [value, setValue] = useState('09:30')
|
|
78
|
+
const [keep, setKeep] = useState(false)
|
|
79
|
+
|
|
80
|
+
<InputTime label="Meeting" locale="en-US" value={value} clearable
|
|
81
|
+
onValueChange={(_, attrs) => setValue(attrs.value)}
|
|
82
|
+
onClearClick={event => { if (keep) event.preventDefault() }} />
|
|
83
|
+
<Checkbox checked={keep} onStateChange={(_, { next }) => setKeep(next === true)}>
|
|
84
|
+
Keep the value when clearing
|
|
85
|
+
</Checkbox>
|
|
86
|
+
<Tag>{value || 'Incomplete time'}</Tag>
|
|
87
|
+
```
|
|
88
|
+
|
|
69
89
|
## InputTime props
|
|
70
90
|
|
|
71
91
|
| Prop | Type | Default | Description |
|
|
@@ -85,9 +105,11 @@ range is clamped to the nearest bound as you step or leave the field, and flags
|
|
|
85
105
|
| `min?` | string | — | Earliest allowed time, 24-hour `"HH:mm"`. A complete value below it is clamped up (on step / blur) and flagged `rangeUnderflow` for form validity. |
|
|
86
106
|
| `name?` | string | — | Form field name — the 24-hour value submits under this key. |
|
|
87
107
|
| `onBlur?` | (e) => void | — | Fires when the field loses focus. |
|
|
108
|
+
| `onClearClick?` | (e) => void | — | Fires before clearing. Call `preventDefault()` synchronously to keep the value. |
|
|
88
109
|
| `onClearInput?` | (e) => void | — | Fires after the built-in clear button has cleared the field. |
|
|
89
110
|
| `onFocus?` | (e) => void | — | Fires when the field gains focus. |
|
|
90
|
-
| `onValueChange?` | (event, attrs) => void | — | Fires on every edit (`input`), with the native event + an `attrs` snapshot (`value`, `name`, `empty`, `valid`, `validationMessage`). Also fires on `change` (blur) and on clear. |
|
|
111
|
+
| `onValueChange?` | (event, attrs) => void | — | Fires on every edit (`input`), with the native event + an `attrs` snapshot (`value`, `name`, `empty`, `valid`, `validationMessage`). Also fires on `change` (blur) and on clear. Read-only blur is silent unless committing an edit made before the field became read-only. |
|
|
112
|
+
| `readOnly?` | boolean | — | Keep the time selectable and focusable while preventing edits. Blur emits `change` only if an edit was pending when the field became read-only. |
|
|
91
113
|
| `required?` | boolean | — | Mark the field required (drives native validity). |
|
|
92
114
|
| `round?` | boolean \| number \| string | — | Fully-round the field, or a custom radius (`number` px / CSS length). |
|
|
93
115
|
| `size?` | 'small' \| 'medium' \| 'large' | medium | Size variant. small=24px, medium=28px, large=32px tall. |
|
|
@@ -99,9 +121,28 @@ range is clamped to the nearest bound as you step or leave the field, and flags
|
|
|
99
121
|
|
|
100
122
|
## Web Component
|
|
101
123
|
|
|
102
|
-
Use
|
|
124
|
+
Use `<a-input-time>` directly outside JSX. Its `label`, `leading`, `clear`,
|
|
125
|
+
`trailing`, and `hint` slots accept field content. Use the `hour`, `minute`, and
|
|
126
|
+
`period` parts to style sections independently of their locale order.
|
|
127
|
+
|
|
128
|
+
If existing selectors target JSX grouping spans, update them to the
|
|
129
|
+
`a-input-time-label`, `a-input-time-leading`, `a-input-time-clear`,
|
|
130
|
+
`a-input-time-trailing`, and `a-input-time-hint` tags or their slot attributes.
|
|
131
|
+
Raw HTML can keep its existing slot markup.
|
|
103
132
|
|
|
104
|
-
|
|
133
|
+
For styles and renderer setup, follow [Install and configure](../install-config.md).
|
|
134
|
+
Custom colors and dimensions may require external CSS under a strict
|
|
135
|
+
[Content Security Policy](../install-config.md#content-security-policy).
|
|
136
|
+
|
|
137
|
+
The canonical value remains `HH:mm`, or an empty string for an incomplete time.
|
|
138
|
+
`input` bubbles and is composed; `change` bubbles on commit. A clear action first
|
|
139
|
+
fires cancelable, bubbling `clearclick`, then `input`, `change`, and `clearinput`
|
|
140
|
+
when accepted. Cancel `clearclick` synchronously to retain the value.
|
|
141
|
+
|
|
142
|
+
A read-only field emits `change` on blur only for an edit made before it became
|
|
143
|
+
read-only. Partial digits remain visible, with an empty canonical value until
|
|
144
|
+
editing resumes and completes the time. Removing the field while blur settles
|
|
145
|
+
still completes a pending commit, including range clamping on an editable field.
|
|
105
146
|
|
|
106
147
|
```html
|
|
107
148
|
<a-input-time name="start-time" defaultvalue="09:30">
|
|
@@ -125,9 +166,9 @@ field treatments.
|
|
|
125
166
|
|
|
126
167
|
## Styling
|
|
127
168
|
|
|
128
|
-
`
|
|
129
|
-
|
|
130
|
-
|
|
169
|
+
Use `status` for feedback color and `tone` for a custom accent. Style the host
|
|
170
|
+
with ordinary CSS and its sections with `::part()`. Unlayered consumer rules
|
|
171
|
+
override Anta's defaults. `segment` targets every editable input. `hour`,
|
|
131
172
|
`minute`, and `period` target one segment type regardless of locale order. `literal`
|
|
132
173
|
targets the localized separator. The element also exposes `field`, `segments`,
|
|
133
174
|
`leading`, `label`, `hint`, `clear`, and `trailing`. Don't override the internal
|
|
@@ -142,6 +183,8 @@ targets the localized separator. The element also exposes `field`, `segments`,
|
|
|
142
183
|
.my-time::part(literal) { color: var(--text-4); }
|
|
143
184
|
```
|
|
144
185
|
|
|
186
|
+
The example classes are consumer selectors; replace them with your own.
|
|
187
|
+
|
|
145
188
|
Drop the clock icon with the `icon={false}` prop, and point the `segments` part at
|
|
146
189
|
a monospaced family for fixed-width digits — a small `padding-top` re-centers the
|
|
147
190
|
tighter `1em` line:
|