Skip to content

shadcn.io is an independent project built on shadcn/ui

Free

Calendar with Month and Year Selector for Solid

A calendar whose caption is a month dropdown and a year dropdown, with the previous and next arrows removed.

UI library: Ark UI

The caption is two dropdowns, one for the month and one for the year. The previous and next arrows are gone. A day in the grid can still be selected.

Use it when people jump across years, not just to the next month. Keep the arrows if they only move one month at a time. A field that opens this caption is a Date Picker. In Solid, Ark UI does not jump to a year on its own.

Preview

Preview width

Installation

MCP · Pro
Make your AI a shadcn expert
Your agent installs components, builds pages and restyles your app from one prompt, in Claude Code, Cursor or VS Code.
Part of Pro

Anatomy

Calendar anatomy: prev trigger, month select, year select, next trigger, table, table cell

Usage

<Calendar class="rounded-md border" focusedValue={focusedValue()} onFocusChange={handleFocusChange} onValueChange={handleValueChange} value={value()}>
      <CalendarViewControl class="gap-2">
        <Select class="flex-1" collection={monthCollection} onValueChange={handleMonthChange} value={[String(focusedValue().month)]}>
          <SelectTrigger aria-label="Month" class="w-full">
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            <SelectGroup>
              {monthCollection.items.map(item => <SelectItem item={item}>
                  {item.label}
                </SelectItem>)}
            </SelectGroup>
          </SelectContent>
        </Select>
        <Select class="shrink-0" collection={yearCollection} onValueChange={handleYearChange} value={[String(focusedValue().year)]}>
          <SelectTrigger aria-label="Year">
            <SelectValue />
          </SelectTrigger>
          <SelectContent>
            <SelectGroup>
              {yearCollection.items.map(item => <SelectItem item={item}>
                  {item.label}
                </SelectItem>)}
            </SelectGroup>
          </SelectContent>
        </Select>
      </CalendarViewControl>
      <CalendarTable>
        <CalendarWeekDays />
        <CalendarTableDays />
      </CalendarTable>
    </Calendar>

FAQ

How do the month and year dropdowns work?

The control row is two Selects in CalendarViewControl. The month select calls focusedValue.set({ month }), the year select calls focusedValue.set({ year }), and focusedValue with onFocusChange moves the grid.

How do I read the selected date?

value is a list holding the selected date, and onValueChange receives { value }. This demo starts the list from parseDate(new Date()).

Which years are in the year dropdown?

The year Select lists 101 years, from 100 years ago through the current year. Choosing one calls focusedValue.set({ year }).

How are the dropdowns named for assistive tech?

The month SelectTrigger has aria-label Month, and the year trigger has aria-label Year. The month select uses flex-1, and the year select uses shrink-0.

Can the visible month differ from the selected date?

Yes. value is the selected date, and focusedValue is the month on screen. Changing a dropdown updates focusedValue only.

Where did the previous and next buttons go?

This control row renders the two Selects and no CalendarPrevTrigger or CalendarNextTrigger.

API Reference

Calendar

Sets focusedValue={focusedValue()}, onFocusChange={handleFocusChange}, onValueChange={handleValueChange} and value={value()}. The rest is on the Calendar page.

Select

Sets collection={monthCollection}, onValueChange={handleMonthChange}, value={[String(focusedValue().month)]}, aria-label="Month", item={item} and collection={yearCollection}. The rest is on the Select page.