Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Cron Schedule Command Menu Block for React Aria

A job scheduler's command menu shown open over a drawn jobs table: eight presets or a typed cron expression read into plain English, the next three runs in UTC from a fixed instant, and a message naming the field that is wrong.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Write a schedule and see when it will run with this cron command menu for React with React Aria. It opens from the jobs page of Ticklane, a job scheduler, whose header holds an outline field with its ⌘ K cap, and the table is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The menu is the catalog Command: the field takes a cron expression of five fields, minute, hour, day of month, month and weekday, written with stars, steps, lists and ranges, or the name of a preset such as "Weekdays at 09:00", and the list shows the presets and, above them, the expression you typed. A band under the list reads the highlighted schedule in plain English, "At 09:00 on weekdays", and lists its next three runs in UTC, stacked on a phone, counted from a fixed instant (Wed 14 Oct 2026, 08:30 UTC) and never from the clock. A field that cannot be read is named, "Minute: 61 is outside 0 to 59". Enter sets the schedule on the table's Invoice export job. For preview the menu is drawn open in place when the page loads; the field, or Ctrl or ⌘ K while focus is in the block, opens the real command dialog with the same schedules and query. For job runners, CI settings and any form that asks for a cron string.

FAQ

Why is the menu already open, and what do I keep?

So you can see it without a click. On load the menu is the Command drawn inline over a picture of a jobs table, in a plain shell that is not modal, so nothing is trapped, hidden or focused and the page around the preview keeps working. The header's field opens the real command dialog, modal, with its focus trap, Escape and focus return, and the inline copy stays closed until a reload. Both show the same Palette and share the block's state, so a search or a typed expression in the copy is in the dialog. In your app keep the dialog and drop the copy: the "in-place" state, the scrim with its shell and the Escape and blur effects.

Which cron syntax does it read?

Five space-separated fields. Each field takes *, a number, a range such as 1-5, a step such as */15 or 10-40/10, and comma lists of those. Months are 1 to 12, weekdays 0 to 7 with Sunday as 0 or 7, and days of the month 1 to 31. Names such as MON or JAN and nonstandard shortcuts such as @daily are not read, and the message says which field is outside its range or which part is not a number. When both the day of the month and the weekday are set, a day matches if either does, as in standard cron.

How are the next three runs worked out?

nextRuns starts at a fixed instant, AS_OF, steps through the days after it (up to eight years, which covers a 29 February), keeps the days whose month, day and weekday match, and lists the matching times of those days that come after the instant. Everything is in UTC and uses Date.UTC, so it does not depend on the visitor's time zone or the clock, and the band always reads the same.

How does the plain-English line work?

describe joins a phrase for the time (every n minutes, at 09:00 and 17:00, between 09:00 and 17:59) to a phrase for the days (every day, on weekdays, on the 1st of the month, in Jan, Apr, Jul and Oct). Common shapes read naturally; an odd one falls back to lists such as "At minutes 0, 20 and 40 of every hour". The line has a reserved height of two lines, so typing never moves the list.

What stays local, and how do I wire it?

All of it. The presets, the table and the fixed instant are typed constants, and choosing a schedule only changes the table's first row. In your app set AS_OF to the current time when the menu opens, send the schedule to your scheduler in pick, and have your scheduler remain the authority on the next runs, since its time zone and its handling of daylight saving may differ from UTC.

Is it accessible from the keyboard?

Yes. Type to search or to write an expression, the arrow keys move through the rows and the band follows, and Enter sets the schedule. Escape closes the menu with focus on the field, and Ctrl or ⌘ K opens the dialog while focus is inside the block, and only then. The rows and the empty state are menuitems of a React Aria menu inside an autocomplete; nothing is highlighted until you press an arrow key. React Aria has no highlight event, so the block reads the input's aria-activedescendant and the hovered row.