All components (204)
Weekly schedule
Dates and time · WeeklySchedule · .amset-schedule
What it is and when to use it
The opening hours of a business: the seven days, each one open or closed, with as many slots as needed. Morning and afternoon are two slots, not a split schedule written in a text field.
When to use it
- Creating or changing the hours of a store, a workshop, a pickup point.
- "Copy to the rest" when Monday to Friday are the same: filling it in five times by hand is how a 10:00 slips in where a 09:00 belonged.
maxSlotsto limit how many slots a day admits (three by default).- To show it written out,
weekSummary(value)gives "Monday to Friday, 10:00–14:00 and 17:00–20:30. Saturday, 10:30–14:00. Sunday, closed."
When not to
- A single time:
TimeField. - Choosing an appointment among free slots:
SlotPicker.
Keyboard: Tab goes through each day in order: the switch (Space turns it on or off), the time fields of each slot (up and down arrows to change the segment, left and right to move to the next, or type the number), the button to remove the slot, "Add slot" and "Copy to the rest".
Accessibility: the block is a section with the name from label. Each switch is named by its day and each time field by its day and its slot ("Opens on Monday, slot 1"), with the label hidden from view: otherwise there would be fourteen fields all called "opens". The remove button says which slot it removes. A closing time before the opening time or two slots that overlap are stated in words below the slot, and that text describes its two time fields (aria-describedby), which are marked as invalid. When a slot is removed, focus moves to the remove button of the neighboring one, or to the day's switch if none is left (if focus has already been taken elsewhere meanwhile, it stays there). Opening, closing, adding and copying do not move focus, so they are announced in a status region ("Saturday, closed"), just like removing. With disabled the root carries aria-disabled and nothing enters the Tab sequence.
States: a slot with an error marks its two fields in red and writes below what is wrong, with its icon (not only the color). When disabled, everything goes gray: switches, times, buttons and the written summary of each day. The switches, the fields and the buttons bring their own states (hover, pressed, crisp 2 px focus).
Motion: when a day is opened its slots enter sliding down a little; a new slot enters the same way, and when removed it leaves (faster than it enters) and only at the end is it truly removed and focus moved. With reduced motion, the change is immediate.
Sizes: sm, md (default) and lg apply to everything that is touched at once, so that the row lines up: switches, time fields and buttons of 30, 36 or 44 px, with the paddings and the font of the summary to match. The add, remove and copy buttons are at least 24 × 24 px with a mouse and 44 with a finger. variant (outline, soft or ghost) applies to the time fields.
Fine-tuning: CSS variables on .amset-schedule: --amset-schedule-slot (between days), --amset-schedule-padding (inside each day), --amset-schedule-gap (between slots), --amset-schedule-description (the font of the summary and of the error), --amset-schedule-radius, --amset-schedule-background, --amset-schedule-border and --amset-schedule-divider (the line under the day header). The pieces, with their own: --amset-switch-*, --amset-field-* and --amset-button-*.
Context: it goes inside LocaleProvider (or AmsetProvider): the time fields appear in 24 hours because the language says so.
What it looks like
<WeeklySchedule
label="Business hours"
value={horario}
onChange={setHorario}
/>Props
Import it with import { WeeklySchedule } from '@amset/ui'. Required props are marked.
| Prop | Type | What it does |
|---|---|---|
labelrequired | string | What the schedule is about. Required: it names the whole block. |
onChangerequired | (schedule: WeekSchedule) => void | — |
valuerequired | WeekSchedule | — |
className | string | Merged with the library classes; it does not replace them. |
disabled | boolean | Everything disabled and out of the Tab order: switches, times and buttons. |
maxSlots | number | How many time slots are allowed per day. |
size | "sm" | "md" | "lg" | Height of everything that is touched, to match: switches, time fields and buttons of 30, 36 or 44 px (`sm`, `md`, `lg`). With a finger, nothing goes below 44. |
variant | FieldVariant | How the time fields are drawn: `outline` (default), `soft` or `ghost`. |
It also accepts the attributes of the element it renders: className, style, data-*, aria-* and its events.
CSS variables
These CSS variables are how you adapt it. Declare them on the component's selector, not on :root: the stylesheet redeclares them in the rule itself, and a declaration on the same element always wins.
| Variable | Default |
|---|---|
--amset-schedule-slot | var(--amset-space-2) |
--amset-schedule-padding | var(--amset-space-3) |
--amset-schedule-gap | var(--amset-space-3) |
--amset-schedule-description | var(--amset-text-sm) |
--amset-schedule-radius | var(--amset-radius) |
--amset-schedule-background | var(--amset-surface) |
--amset-schedule-border | var(--amset-border) |
--amset-schedule-divider | var(--amset-divider) |
How to change it
.amset-schedule {
--amset-schedule-slot: ...;
--amset-schedule-padding: ...;
}In the test bench
Every state and variant, to try one at a time, on its page at ui.amset.tech:
