WebberUI

Lunar / Gregorian Date Picker (React)

A React calendar component showing the Gregorian and lunar calendars side by side — every cell is annotated with the lunar day, the 24 solar terms, and traditional festivals, and one click switches the primary axis between lunar and Gregorian.

This is a WebberUI Pro component

Free during the launch campaign: sign up or sign in, then hit “Copy install command” in the preview above and it installs straight away — no payment, no credit card. The command below returns 401 while you are signed out.

How to install Pro components →See the plans →

A Gregorian / lunar comparison calendar: each cell shows the Gregorian date large with the lunar date small (the first day of a lunar month shows the month name), with solar terms and traditional festivals marked by color dots and tags. The header switches between the Gregorian and lunar views, and the selected day is shown in full at the bottom (for example 「丙午年(馬年)五月初五」). It ships with a full lookup table for 2026 (the 丙午 Year of the Horse) — zero dependencies, no lookup API needed.

Loading preview…
npx shadcn@latest add "https://webberui.com/r/lunar-date-picker.json?t=<install token>"

Playground

Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.

2
<LunarDatePicker />

Installation

npx shadcn@latest add "https://webberui.com/r/lunar-date-picker.json?t=<install token>"

Or, once registries are configured in components.json, install it as @webberui/lunar-date-picker.

Usage

import { LunarDatePicker } from "@/components/ui/lunar-date-picker";

const [date, setDate] = React.useState<Date | null>(new Date(2026, 5, 19));

<LunarDatePicker
  value={date}
  onChange={(d, lunar) => {
    setDate(d);
    console.log(lunar.ganzhi, lunar.month, lunar.day); // 丙午 五月 初五
  }}
/>;

You can also call the lookup function getLunarInfo2026(date) directly to get the lunar information for any date in 2026 (out-of-range dates return null).

Data range: the built-in lookup table only covers the Gregorian dates 2026-01-01 through 2026-12-31 (a Taipei-timezone almanac, including the 24 solar terms and the major festivals). For other years, extend the month-segment data in the same format as the source, or switch to a full calendar library such as lunar-javascript.

Props

PropTypeDefaultDescription
valueDate | nullnullThe currently selected date; it must fall within 2026, otherwise it counts as unselected
onChange(date: Date, lunar: LunarInfo) => voidCallback when a date is picked; lunar contains the sexagenary year, zodiac animal, lunar month and day, solar term, and festival
year20262026Lookup table year; the built-in data only covers 2026
defaultMonthnumber1Month shown by default when no value is provided (1–12)
classNamestringForwarded to the outer card container

LunarInfo fields: ganzhi (sexagenary year), zodiac (zodiac animal), month (lunar month name), day (lunar day name), dayIndex (day number 1–30), solarTerm? (solar term), festival? (festival).

Accessibility

  • Every date is a native button with a complete aria-label (Gregorian date plus lunar day plus festival and solar term), operable by keyboard with Tab / Enter
  • The view toggle and the selected day use aria-pressed to convey state; the month navigation buttons carry "previous month / next month" labels and are disabled at the year boundaries
  • When the user has "reduce motion" enabled at the system level, the month slide, the selection bounce, and the panel transitions are disabled and switching is instant
  • The "today" marker is only computed after mount, so SSR and client rendering match and there is no hydration error

On this page