import React from "react"; import { type DayPickerProps, dateLib, defaultDateLib, type Numerals, } from "react-day-picker"; import { enUS as enUSBuddhist, th as thBuddhist, } from "react-day-picker/buddhist"; import { amET as amETEthiopic, enUS as enUSEthiopic, } from "react-day-picker/ethiopic"; import { enUS as enUSHebrew, he as heHebrew } from "react-day-picker/hebrew"; import * as locales from "react-day-picker/locale"; import { enUS as enUSPersian, faIR as faIRPersian, } from "react-day-picker/persian"; import styles from "./styles.module.css"; import type { DayPickerPropsWithCalendar } from "./useQueryStringSync"; const timeZones = [ "UTC", "Africa/Cairo", "Africa/Johannesburg", "Africa/Lagos", "America/Buenos_Aires", "America/Chicago", "America/Denver", "America/Los_Angeles", "America/Mexico_City", "America/New_York", "America/Sao_Paulo", "America/Toronto", "America/Vancouver", "Antarctica/Palmer", "Asia/Dubai", "Asia/Hong_Kong", "Asia/Kolkata", "Asia/Saigon", "Asia/Seoul", "Asia/Shanghai", "Asia/Singapore", "Asia/Tokyo", "Australia/Brisbane", "Australia/Melbourne", "Australia/Sydney", "Europe/Berlin", "Europe/London", "Europe/Madrid", "Europe/Moscow", "Europe/Paris", "Europe/Rome", "Pacific/Auckland", "Pacific/Honolulu", ]; const numerals: { value: Numerals; label: string }[] = [ { value: "latn", label: "Latin (Western Arabic)" }, { value: "arab", label: "Arabic-Indic" }, { value: "arabext", label: "Eastern Arabic-Indic (persian)" }, { value: "deva", label: "Devanagari" }, { value: "beng", label: "Bengali" }, { value: "guru", label: "Gurmukhi" }, { value: "gujr", label: "Gujarati" }, { value: "orya", label: "Oriya" }, { value: "tamldec", label: "Tamil" }, { value: "telu", label: "Telugu" }, { value: "knda", label: "Kannada" }, { value: "mlym", label: "Malayalam" }, // Ethiopic digits { value: "geez" as Numerals, label: "Ge'ez (Ethiopic)" }, // Thai digits { value: "thai" as Numerals, label: "Thai" }, { value: "mymr", label: "Myanmar" }, { value: "khmr", label: "Khmer" }, { value: "laoo", label: "Lao" }, { value: "tibt", label: "Tibetan" }, ]; const calendars: ( | "persian" | "ethiopic" | "buddhist" | "gregorian" | "hebrew" )[] = ["gregorian", "persian", "ethiopic", "buddhist", "hebrew"]; const persianLocales = { faIR: faIRPersian, enUS: enUSPersian }; const ethiopicLocales = { amET: amETEthiopic, enUS: enUSEthiopic }; const buddhistLocales = { th: thBuddhist, enUS: enUSBuddhist }; const hebrewLocales = { he: heHebrew, enUS: enUSHebrew }; type CalendarType = NonNullable; const allLocales = Object.values(locales) as DayPickerProps["locale"][]; const calendarLocales: Record = { gregorian: allLocales, persian: Object.values(persianLocales), ethiopic: Object.values(ethiopicLocales), buddhist: Object.values(buddhistLocales), hebrew: Object.values(hebrewLocales), }; const calendarDefaults: Partial< Record< CalendarType, { locale?: DayPickerProps["locale"]; dir?: DayPickerPropsWithCalendar["dir"]; numerals?: Numerals; } > > = { persian: { locale: faIRPersian, dir: "rtl" }, ethiopic: { locale: amETEthiopic, numerals: "geez" as Numerals }, buddhist: { locale: thBuddhist, numerals: "thai" as Numerals }, hebrew: { numerals: "latn" as Numerals }, }; function getLocalesForCalendar( calendar?: DayPickerPropsWithCalendar["calendar"], ) { if (!calendar) { return allLocales; } return calendarLocales[calendar as CalendarType] ?? allLocales; } interface LocalizationFieldsetProps { props: DayPickerPropsWithCalendar; setProps: React.Dispatch>; currentTimeZone: string; } export function LocalizationFieldset({ props, setProps, currentTimeZone, }: LocalizationFieldsetProps) { const availableLocales = React.useMemo( () => getLocalesForCalendar(props.calendar), [props.calendar], ); const handleCalendarChange = ( event: React.ChangeEvent, ) => { const rawValue = event.target.value as CalendarType | ""; const calendar = ( rawValue === "" ? undefined : rawValue ) as DayPickerPropsWithCalendar["calendar"]; const defaults = calendar ? calendarDefaults[calendar as CalendarType] : undefined; const nextProps: DayPickerPropsWithCalendar = { ...props, calendar, locale: calendar ? (defaults?.locale ?? undefined) : undefined, dir: calendar ? (defaults?.dir ?? undefined) : undefined, }; if (defaults?.numerals) { nextProps.numerals = defaults.numerals; } setProps(nextProps); }; const handleLocaleChange = (event: React.ChangeEvent) => { const { value } = event.target; if (!value) { setProps({ ...props, locale: undefined }); return; } const locale = availableLocales.find((item) => item?.code === value); setProps({ ...props, locale }); }; const handleNumeralsChange = ( event: React.ChangeEvent, ) => { const { value } = event.target; if (!value) { setProps({ ...props, numerals: undefined }); return; } setProps({ ...props, numerals: value as Numerals }); }; const handleWeekStartsOnChange = ( event: React.ChangeEvent, ) => { const { value } = event.target; const nextProps: DayPickerPropsWithCalendar = { ...props }; if (!value) { nextProps.weekStartsOn = undefined; } else { nextProps.weekStartsOn = Number(value) as DayPickerProps["weekStartsOn"]; } setProps(nextProps); }; const handleFirstWeekContainsDateChange = ( event: React.ChangeEvent, ) => { const { value } = event.target; const nextProps: DayPickerPropsWithCalendar = { ...props }; if (!value) { nextProps.firstWeekContainsDate = undefined; } else { nextProps.firstWeekContainsDate = Number( value, ) as DayPickerProps["firstWeekContainsDate"]; } setProps(nextProps); }; const handleDirectionChange = ( event: React.ChangeEvent, ) => { const { checked } = event.target; const nextProps: DayPickerPropsWithCalendar = { ...props }; if (checked) { nextProps.dir = "rtl"; } else { nextProps.dir = undefined; } setProps(nextProps); }; const handleBroadcastCalendarChange = ( event: React.ChangeEvent, ) => { const { checked } = event.target; const nextProps: DayPickerPropsWithCalendar = { ...props, broadcastCalendar: checked, }; if (checked) { nextProps.showOutsideDays = true; } setProps(nextProps); }; return (
Localization{" "}
{props.timeZone ? ( ) : null}
); }