SchedulerBuilder
Complex recurrence, plain words.
About
Builds a recurring schedule from start, repeat and end rows on a sui-config-list, restates it as one sentence, previews the next five runs and hands back portable JSON. Cadences run from every few minutes to yearly, with weekday scopes, nth weekdays and business-day rules. Reach for it wherever a user sets when a job runs.
Built from
Usage
Basic
A daily run at 9:00 PM that never ends. The sentence and the next-runs list are polite live regions, so every edit is announced, and each field is a group named by its own small label.
Business-day rule
Nov 15, 2026 lands on a Sunday, so the next-runs preview moves that run to Friday the 13th. The Business days row appears only for day, month and year cadences.
Nth weekday, no JSON
Monthly can also mean the third Friday. hide-json drops the raw config, which a product screen does not need, and leaves the sentence and next runs in the side column.
Compact with a window
Every 30 minutes between 8:00 AM and 6:00 PM on weekdays. A minute or hour cadence trades the start time for the window and the weekday scope, and the compact variant folds the JSON behind a toggle.
Disabled
disabled is the running job you do not own. Every composed control takes its own disabled state while the sentence, the preview and the JSON stay readable, and the copy button stays live because copying is not editing.
Events
suiChange fires once after load and after every edit with { config, sentence }. The composed inputs keep their own events to themselves, so this is the only change event a consumer sees, and getConfig() reads the same contract on demand.
Data contract
The suiChange detail carries { config, sentence }. Config is versioned JSON: start { date, time }, repeat { every, unit, weekdays, window, monthly, annual }, businessDays { rule }, end { type, date | count }. Store it as-is; any system can replay it.
Keyboard
| Key | Action |
|---|---|
| Tab | Moves through the fields in reading order: the start date and time, the repeat count and unit, the weekday or monthly controls the unit reveals, the business-day rule, the end rule and its date or count, then the JSON toggle in the compact variant unless hide-json is set. Each field is the ShineUI control it names and takes the keys of that control. |
| Enter Space | Commits the focused control as that control does; every commit emits suiChange with the config and the sentence. On the JSON toggle, shows or hides the configuration pane. |
| ArrowDown ArrowUp | On a select, opens it and moves through its options; on a number field, steps the value; on the date picker, moves through the days once it is open. |
API
<sui-scheduler-builder>
Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
config | property only | SuiScheduleSeedSuiScheduleSeed | undefined | Seed mechanics (the reference defaultConfig), typed as SuiScheduleSeed. Property, not attribute. Mutable: after every edit the element writes the current mechanics back in seed form, so reading it returns the live state. Missing fields take the reference defaults. The mechanics: minute and hour cadences with a time window and a weekday scope; daily; weekly weekday sets; monthly on a day of the month or an ordinal weekday (first to fourth, last); yearly month and day; a business-day rule for runs that land on a weekend (as scheduled, previous, next, skip); ends never, on a date or after N runs. | |
disabled | disabled | boolean | false | Disables every composed control, so the schedule reads but does not edit: the sentence, the next-runs preview and the JSON all stay legible while nothing can be changed. This is the screen for a running job you do not own. The copy button on the JSON and the compact variant's JSON toggle stay live, because they read the schedule and do not edit it. Reflected. |
hideJson | hide-json | boolean | false | Hides the configuration JSON, which the builder shows in a sui-code-block by default. Raw config is a developer affordance, so a product screen drops it: desktop then leaves the sentence and next runs in the side column, and compact drops the toggle row with it. Reflected. |
label | label | stringstring | undefined | Heading above the builder, e.g. "Nightly export". Empty string hides it. | |
timezone | timezone | stringstring | undefined | IANA zone the schedule is written in. Defaults to the reader's own, from Intl.DateTimeFormat().resolvedOptions().timeZone, falling back to UTC where the runtime does not report one. It used to default to America/Kentucky/Louisville, which is one customer's office and is wrong for everybody else who installs this library. A schedule is written in a zone whether or not the author names one, so the honest default is the zone the reader is actually in rather than a constant somebody has to notice and override. | |
todayDate | today-date | Date | string | undefined | Pins "today" for the date pickers and the default start date (demos and tests), e.g. "2026-08-17". | |
variant | variant | "compact" | "desktop" | 'desktop' | desktop = config list beside a 300px column with the sentence, next runs and JSON; compact = everything stacked on the mobile config list, with the JSON folded behind a toggle. |
Events
| Event | Detail | React | Vue | Description |
|---|---|---|---|---|
suiChange | SuiScheduleChangeDetail | onSuiChange | @sui-change | Fires after every edit (and once after load) with { config, sentence }: the version-2 contract and its restatement in the page's language. The composed inputs' own suiChange and suiInput events stop at this element, so this is the only change event a consumer sees. The builder is a value control: Vue's v-model and Angular's ngModel bind the config prop through this event, so the model holds the seed form the element writes back. |
Methods
| Method | Signature | Description |
|---|---|---|
getConfig() | getConfig() => Promise<SuiScheduleConfig> | The full version-2 config for the current mechanics, the same contract suiChange carries. |
setFocus() | setFocus() => Promise<void> | Moves keyboard focus to the first control, the start date, as host.focus() does, so a form that focuses its first invalid field lands in the builder. |
Types
SuiBusinessDayRule typeWhat happens when a run lands on a weekend. | |||
|---|---|---|---|
| No members. |
SuiScheduleChangeDetail interfacesuiChange detail: the resolved config and its one-sentence restatement in the page's language. | |||
|---|---|---|---|
config | SuiScheduleConfig | ||
sentence | string | ||
SuiScheduleConfig interfacePortable schedule contract (version 2): { version, timezone, start, repeat, businessDays, end }, the storage and interop shape other systems interpret. sui-scheduler-builder produces it in suiChange and from getConfig(). | |||
|---|---|---|---|
version | 2 | ||
timezone | string | ||
start | { date: string; time: string; } | ||
repeat | { every: number; unit: SuiScheduleUnit; /** Full weekday names ("Monday"); weekly sets, or the weekday scope of a minute/hour cadence. */ weekdays?: string[]; /** Active time window of a minute/hour cadence, as display times ("8:00 AM"). */ window?: { from: string; to: string; }; monthly?: { mode: 'dayOfMonth'; day: number; } | { mode: 'nthWeekday'; ordinal: string; weekday: string; }; annual?: { month: string; day: number; }; } | ||
businessDays | { rule: SuiBusinessDayRule; } | ||
end | { type: 'never'; } | { type: 'onDate'; date: string | null; } | { type: 'afterRuns'; count: number; } | ||
SuiScheduleSeed interfaceLoose seed the builder's config property accepts (the reference defaultConfig): startDate, startTime, every, unit, weekdays (two-letter codes), monthlyMode, dayOfMonth, ordinal, weekday, month (0-based), day, windowFrom, windowTo, businessDays, endType, endDate, endCount. Every field is optional. | |||
|---|---|---|---|
startDate? | string | ISO YYYY-MM-DD. Defaults to today. | |
startTime? | string | Display time, e.g. "9:00 AM". | |
every? | number | ||
unit? | string | ||
weekdays? | string[] | Two-letter weekday codes: Mo Tu We Th Fr Sa Su. | |
monthlyMode? | 'day' | 'nth' | ||
dayOfMonth? | number | ||
ordinal? | string | ||
weekday? | string | ||
month? | number | Zero-based month for the yearly cadence. | |
day? | number | Day of month for the yearly cadence. | |
windowFrom? | string | ||
windowTo? | string | ||
businessDays? | string | ||
endType? | 'never' | 'on' | 'after' | ||
endDate? | string | ISO YYYY-MM-DD. | |
endCount? | number | ||
SuiScheduleUnit typeCadence unit. | |||
|---|---|---|---|
| No members. |
Theming
Every design token this element can render with, read from its own stylesheets and the ones it imports. Set a token on :root or on any ancestor and every use below follows it. The values shown are the ones in the theme you are viewing. The list is read per stylesheet, so an element that imports a shared drawing module lists that module's tokens too, whether or not it paints with all of them.
Color10
Typography2
Radius2
Elevation1
Motion2
Every name above is listed with its value and its role in Foundations.