Calendar
支持单选、范围与多选的月历面板
日历(Calendar)以月为单位展示日期网格,支持单选、日期范围与多选三种模式,可选带时间选择。组件基于 react-native-ui-datepicker 封装,本层只做两件事:套上面板容器样式(圆角、底色、内边距),以及把 classNames 按 slot 逐个合并而不是整段替换。
第三方默认类名用的就是 bg-primary / text-primary-foreground / text-muted-foreground / bg-accent 这套语义 token,与本仓库 tailwind-plugin 生成的变量同名,所以配色天然跟随主题,不需要额外翻译一遍。
import { Calendar } from '@skyroc/native-ui';
import type { DateType } from '@skyroc/native-ui';基础用法
mode 是必填的,它决定用哪一组数据属性。single 模式下用 date + onChange 受控,回调参数是 { date }。
import { Calendar, Text } from '@skyroc/native-ui';
import type { DateType } from '@skyroc/native-ui';
import { useState } from 'react';
import { View } from 'react-native';
/** 示例统一从当天零点开始,避免时分秒影响边界判断 */
const TODAY = new Date(new Date().setHours(0, 0, 0, 0));
/** 把 DateType 格式化成 YYYY-MM-DD */
function formatDate(date: DateType): string {
if (!date) return '未选择';
const parsed = new Date(date as Date | number | string);
const month = String(parsed.getMonth() + 1).padStart(2, '0');
const day = String(parsed.getDate()).padStart(2, '0');
return `${parsed.getFullYear()}-${month}-${day}`;
}
const CalendarBasic = () => {
const [singleDate, setSingleDate] = useState<DateType>(TODAY);
return (
<View className="bg-background">
<Calendar
date={singleDate}
locale="zh"
mode="single"
onChange={({ date }) => setSingleDate(date)}
/>
<Text className="px-4 pb-4 text-sm text-muted-foreground">当前选中:{formatDate(singleDate)}</Text>
</View>
);
};
export { CalendarBasic };组件本身不持有选中值:不接 onChange 回写 state,点击不会有任何视觉变化。
何时使用
- 需要在一整屏日期网格里挑日子——请假、预订、日程——用
Calendar。 - 只是在表单里填一个日期,且不需要看到整月上下文时,用滚轮式的
DatePicker,它更省空间也更符合移动端输入习惯。 - 需要连续区间(入住 / 退房)时用
mode="range",不要用两个独立的单选日历——范围模式内置了跨度约束与区间高亮。
日期范围
mode="range" 用 startDate / endDate 两个值受控,回调参数是 { startDate, endDate }。min / max 限制区间跨度,按夜数(起止相差的天数)计算:max={7} 允许最长跨 8 个自然日的区间。
import { Calendar, Text } from '@skyroc/native-ui';
import type { DateType } from '@skyroc/native-ui';
import { useState } from 'react';
import { View } from 'react-native';
/** 把 DateType 格式化成 YYYY-MM-DD */
function formatDate(date: DateType): string {
if (!date) return '未选择';
const parsed = new Date(date as Date | number | string);
const month = String(parsed.getMonth() + 1).padStart(2, '0');
const day = String(parsed.getDate()).padStart(2, '0');
return `${parsed.getFullYear()}-${month}-${day}`;
}
const CalendarRange = () => {
const [rangeStart, setRangeStart] = useState<DateType>();
const [rangeEnd, setRangeEnd] = useState<DateType>();
const rangeLabel = `${formatDate(rangeStart)} 至 ${formatDate(rangeEnd)}`;
return (
<View className="bg-background">
<Calendar
allowRangeReset
endDate={rangeEnd}
locale="zh"
max={7}
min={2}
mode="range"
startDate={rangeStart}
onChange={({ endDate, startDate }) => {
setRangeStart(startDate);
setRangeEnd(endDate);
}}
/>
<Text className="px-4 pb-4 text-sm text-muted-foreground">当前:{rangeLabel}</Text>
</View>
);
};
export { CalendarRange };几个容易踩的点:
- 越界时不会报错,而是把刚点的日期当成新的起点重新开始选。
- 点击区间起点那一天:设了
min/max时会把区间整个清空(回调收到两个undefined),否则是把终点收回到起点、变成单日区间;单日区间上再点同一天同样清空。 - 默认情况下区间选满之后再点日期会调整端点;加上
allowRangeReset则任意一次点击都直接开始新区间。
多选与数量限制
mode="multiple" 用 dates 数组受控,回调参数是 { dates, datePressed, change },change 为 'added' / 'removed' / 'updated'。max 限制最多选几天,到上限后继续点击直接被忽略——不会触发 onChange,也不会替换掉最早选中的那天。
import { Calendar, Text } from '@skyroc/native-ui';
import type { DateType } from '@skyroc/native-ui';
import { useState } from 'react';
import { View } from 'react-native';
const CalendarMultiple = () => {
const [multiDates, setMultiDates] = useState<DateType[]>([]);
return (
<View className="bg-background">
<Calendar
dates={multiDates}
locale="zh"
max={3}
mode="multiple"
onChange={({ dates }) => setMultiDates(dates)}
/>
<Text className="px-4 pb-4 text-sm text-muted-foreground">已选 {multiDates.length} 天</Text>
</View>
);
};
export { CalendarMultiple };回调给的 dates 是排好序的完整结果,直接整份写回 state 即可;点已选中的日期即取消选择。min 在多选模式下不生效。多选时如果希望连续几天渲染成一条连续的区间条,打开 multiRangeMode。
禁用日期
disabledDates 接受日期数组或判断函数(返回 true 表示禁用)。反过来也可以用 enabledDates 走白名单,它的优先级高于 disabledDates。
import { Calendar, Text } from '@skyroc/native-ui';
import type { DateType } from '@skyroc/native-ui';
import { useState } from 'react';
import { View } from 'react-native';
/** 示例统一从当天零点开始,避免时分秒影响边界判断 */
const TODAY = new Date(new Date().setHours(0, 0, 0, 0));
/** 把 DateType 格式化成 YYYY-MM-DD */
function formatDate(date: DateType): string {
if (!date) return '未选择';
const parsed = new Date(date as Date | number | string);
const month = String(parsed.getMonth() + 1).padStart(2, '0');
const day = String(parsed.getDate()).padStart(2, '0');
return `${parsed.getFullYear()}-${month}-${day}`;
}
/** 周六、周日不可选 */
function isWeekend(date: DateType): boolean {
if (!date) return false;
const day = new Date(date as Date | number | string).getDay();
return day === 0 || day === 6;
}
const CalendarDisabledDates = () => {
const [disabledDate, setDisabledDate] = useState<DateType>(TODAY);
return (
<View className="bg-background">
<Calendar
date={disabledDate}
disabledDates={isWeekend}
locale="zh"
mode="single"
onChange={({ date }) => setDisabledDate(date)}
/>
<Text className="px-4 pb-4 text-sm text-muted-foreground">当前:{formatDate(disabledDate)}</Text>
</View>
);
};
export { CalendarDisabledDates };判断函数每渲染一格日期就会被调用一次,别在里面做重活;示例里的"周末不可选"就是最典型的用法。
可选区间
minDate / maxDate 约束整体可选边界,超出的日期直接置灰。它和 disabledDates 可以叠加使用。
import { Calendar, Text } from '@skyroc/native-ui';
import type { DateType } from '@skyroc/native-ui';
import { useState } from 'react';
import { View } from 'react-native';
/** 一天的毫秒数,用于构造稳定、易读的相对日期示例 */
const DAY_IN_MS = 24 * 60 * 60 * 1000;
/** 示例统一从当天零点开始,避免时分秒影响边界判断 */
const TODAY = new Date(new Date().setHours(0, 0, 0, 0));
/** 给日期增加指定天数 */
function addDays(date: Date, amount: number): Date {
return new Date(date.getTime() + amount * DAY_IN_MS);
}
/** 把 DateType 格式化成 YYYY-MM-DD */
function formatDate(date: DateType): string {
if (!date) return '未选择';
const parsed = new Date(date as Date | number | string);
const month = String(parsed.getMonth() + 1).padStart(2, '0');
const day = String(parsed.getDate()).padStart(2, '0');
return `${parsed.getFullYear()}-${month}-${day}`;
}
const CalendarMinMax = () => {
const [limitedDate, setLimitedDate] = useState<DateType>(TODAY);
return (
<View className="bg-background">
<Calendar
date={limitedDate}
locale="zh"
maxDate={addDays(TODAY, 30)}
minDate={TODAY}
mode="single"
onChange={({ date }) => setLimitedDate(date)}
/>
<Text className="px-4 pb-4 text-sm text-muted-foreground">当前:{formatDate(limitedDate)}</Text>
</View>
);
};
export { CalendarMinMax };边界判断带时分秒,minDate 传 new Date() 会让"今天"因为已过零点而不可选。示例里统一用 new Date(new Date().setHours(0, 0, 0, 0)) 归零到当天零点。
周与导航布局
| 属性 | 说明 |
|---|---|
firstDayOfWeek | 一周从周几开始,0(周日,默认)到 6(周六) |
showOutsideDays | 是否补齐上下月的日期格,默认 false |
navigationPosition | 上/下月按钮的位置:around(默认)、left、right |
weekdaysFormat | 星期名格式:min(默认)、short、full |
hideWeekdays | 隐藏星期行 |
hideHeader | 隐藏内置头部(月份、年份、翻页按钮整块) |
import { Calendar } from '@skyroc/native-ui';
import type { DateType } from '@skyroc/native-ui';
import { useState } from 'react';
import { View } from 'react-native';
/** 示例统一从当天零点开始,避免时分秒影响边界判断 */
const TODAY = new Date(new Date().setHours(0, 0, 0, 0));
const CalendarLayout = () => {
const [layoutDate, setLayoutDate] = useState<DateType>(TODAY);
return (
<View className="bg-background">
<Calendar
showOutsideDays={false}
date={layoutDate}
firstDayOfWeek={1}
locale="zh"
mode="single"
navigationPosition="right"
weekdaysFormat="short"
onChange={({ date }) => setLayoutDate(date)}
/>
</View>
);
};
export { CalendarLayout };firstDayOfWeek 只接受 1–6,传 0 或非法值都回落到周日开头。
日期与时间
timePicker 在头部加一个时间入口,点进去切到时分选择视图;use12Hours 换成 12 小时制(AM / PM)。想一进来就停在时间视图,配合 initialView="time"。
import { Calendar, Text } from '@skyroc/native-ui';
import type { DateType } from '@skyroc/native-ui';
import { useState } from 'react';
import { View } from 'react-native';
/** 示例统一从当天零点开始,避免时分秒影响边界判断 */
const TODAY = new Date(new Date().setHours(0, 0, 0, 0));
/** 把 DateType 格式化成 YYYY-MM-DD */
function formatDate(date: DateType): string {
if (!date) return '未选择';
const parsed = new Date(date as Date | number | string);
const month = String(parsed.getMonth() + 1).padStart(2, '0');
const day = String(parsed.getDate()).padStart(2, '0');
return `${parsed.getFullYear()}-${month}-${day}`;
}
const CalendarTimePicker = () => {
const [dateTime, setDateTime] = useState<DateType>(TODAY);
return (
<View className="bg-background">
<Calendar
timePicker
use12Hours
date={dateTime}
locale="zh"
mode="single"
onChange={({ date }) => setDateTime(date)}
/>
<Text className="px-4 pb-4 text-sm text-muted-foreground">当前:{formatDate(dateTime)}</Text>
</View>
);
};
export { CalendarTimePicker };时间是选中日期的一部分,仍然从同一个 date 里读写,不会多给一个字段。
外部控制月份
month / year 让外部决定当前显示哪个月,配合 onMonthChange / onYearChange 同步内部翻页。它们控制的是"显示到哪一屏",与选中值无关。
import { Button, Calendar, Text } from '@skyroc/native-ui';
import { useState } from 'react';
import { View } from 'react-native';
/** 示例统一从当天零点开始,避免时分秒影响边界判断 */
const TODAY = new Date(new Date().setHours(0, 0, 0, 0));
const CalendarControlledMonth = () => {
const [visibleMonth, setVisibleMonth] = useState(TODAY.getMonth());
const [visibleYear, setVisibleYear] = useState(TODAY.getFullYear());
const visibleMonthLabel = `${visibleYear} 年 ${visibleMonth + 1} 月`;
function moveVisibleMonth(offset: number) {
const nextDate = new Date(visibleYear, visibleMonth + offset, 1);
setVisibleMonth(nextDate.getMonth());
setVisibleYear(nextDate.getFullYear());
}
return (
<View className="bg-background">
<View className="flex-row items-center justify-between gap-3 px-4 pt-4">
<Button
size="sm"
variant="outline"
onPress={() => moveVisibleMonth(-1)}
>
上个月
</Button>
<Text className="font-medium text-foreground">{visibleMonthLabel}</Text>
<Button
size="sm"
variant="outline"
onPress={() => moveVisibleMonth(1)}
>
下个月
</Button>
</View>
<Calendar
hideHeader
locale="zh"
mode="single"
month={visibleMonth}
year={visibleYear}
onMonthChange={setVisibleMonth}
onYearChange={setVisibleYear}
/>
</View>
);
};
export { CalendarControlledMonth };自己在外面做翻页按钮时,通常配 hideHeader 把内置头部关掉,避免出现两套导航。注意 month 是 0 起算的(0 表示一月)。
自定义内容与样式
components 可以替换日期格、月份格、年份格、星期名与翻页图标;components.Day 拿到的 CalendarDay 携带 isSelected / isToday / isDisabled / inRange 等状态,接管之后这些状态样式全部由你自己表达——包括选中态,第三方不会再补一层。
classNames 按 slot 覆盖,值会和默认类名合并(冲突的工具类由 tailwind-merge 决定胜负),只想改圆角不必把排版重抄一遍。className 追加在面板容器上,可用来覆盖本层的 rounded-2xl bg-background p-4。
import { Calendar, Text } from '@skyroc/native-ui';
import type { CalendarComponents, CalendarDay, DateType } from '@skyroc/native-ui';
import type { ReactNode } from 'react';
import { useState } from 'react';
import { View } from 'react-native';
/** 示例统一从当天零点开始,避免时分秒影响边界判断 */
const TODAY = new Date(new Date().setHours(0, 0, 0, 0));
/** 按日期格状态返回完整类名,避免动态拼接导致 Uniwind 漏扫 */
function getDayLabelClassName(day: CalendarDay): string {
if (day.isSelected) return 'text-sm font-semibold text-primary-foreground';
if (day.isDisabled) return 'text-sm text-muted-foreground opacity-50';
if (day.isToday) return 'text-sm font-semibold text-primary';
return 'text-sm text-foreground';
}
/** 自定义日期格需要自行表达交互状态,完整类名可被 Uniwind 静态扫描 */
function getDayContainerClassName(day: CalendarDay): string {
if (day.isSelected) return 'h-full w-full items-center justify-center gap-0.5 rounded-full bg-success';
if (day.isToday) return 'h-full w-full items-center justify-center gap-0.5 rounded-full bg-warning/20';
return 'h-full w-full items-center justify-center gap-0.5 rounded-full';
}
/** 自定义日期格:保留选中、今天、禁用等状态,并给 5 的倍数加提示点 */
function renderMarkedDay(day: CalendarDay): ReactNode {
const containerClassName = getDayContainerClassName(day);
const labelClassName = getDayLabelClassName(day);
return (
<View className={containerClassName}>
<Text className={labelClassName}>{day.text}</Text>
{day.number % 5 === 0 ? (
<View
className={day.isSelected ? 'size-1 rounded-full bg-primary-foreground' : 'size-1 rounded-full bg-info'}
/>
) : null}
</View>
);
}
const CUSTOM_COMPONENTS: CalendarComponents = {
Day: renderMarkedDay
};
const CalendarCustom = () => {
const [customDate, setCustomDate] = useState<DateType>(TODAY);
return (
<View className="overflow-hidden rounded-3xl border border-border bg-muted/30">
<Calendar
date={customDate}
locale="zh"
mode="single"
className="bg-transparent"
classNames={{
header: 'rounded-xl bg-muted px-2',
weekday_label: 'font-semibold text-info'
}}
components={CUSTOM_COMPONENTS}
onChange={({ date }) => setCustomDate(date)}
/>
</View>
);
};
export { CalendarCustom };自定义日期格时,类名要写成完整字符串而不是拼接出来的——Uniwind 是静态扫描的,`bg-${color}` 这类动态类名扫不到。常用 slot:
| slot | 作用位置 |
|---|---|
header | 头部整块 |
weekday_label | 星期名文字 |
day | 日期格容器 |
day_label | 日期文字 |
selected | 选中态的日期格 |
today_label | 今天的日期文字 |
range_fill | 区间中间段的填充背景 |
全部 50 个 slot 名见下方 CalendarClassNames。
本地化
locale 接受 dayjs 的 locale 名('zh'、'en'、'fa' 等),包内已预置 45 种语言包,不需要额外 import。另外三个相关属性:
<Calendar
calendar="jalali" // 历法:'gregory'(默认)| 'jalali'
locale="fa" // 语言:月份名、星期名
mode="single"
numerals="arabext" // 数字系统:'latn'(默认)、'arab'、'deva' 等 12 种
timeZone="Asia/Shanghai" // 时区,走 dayjs.tz
/>面板尺寸
日期网格区域是固定高度的:containerHeight 默认 300,星期行 weekdaysHeight 默认 25。不同月份的行数不同(4–6 行),固定高度是为了避免翻月时面板高度跳动。需要更紧凑或更宽松的面板就改 containerHeight,只改外层 padding 不会改变网格区高度。
未实现的透传属性
CalendarProps 直接取自第三方的 props 类型,其中 startYear / endYear 在 3.3.0 版本里声明了但没有接线(源码中被注释掉),传了不会有任何效果。年份视图的可选范围目前无法配置。
API
Calendar
Calendar 透传 react-native-ui-datepicker 的全部属性,下表按用途分组列出。className 与 classNames 由本层接管:前者追加到面板容器,后者与默认类名逐 slot 合并。
模式与选中值
mode 决定其余数据属性的形态,三组不能混用。
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| mode* | 选择模式,决定用哪一组数据属性与回调签名;类型上必填,运行时缺省按 single 处理 | 'single' | 'range' | 'multiple' | - |
| date | single:当前选中日期 | DateType | - |
| startDate | range:区间起点 | DateType | - |
| endDate | range:区间终点 | DateType | - |
| dates | multiple:已选中的全部日期 | DateType[] | - |
| onChange | 选中值变化。single 收到 { date };range 收到 { startDate, endDate };multiple 收到 { dates, datePressed, change },change 为 added / removed / updated | (params) => void | - |
| min | range:区间最短夜数(起止相差的天数),其它模式不生效 | number | - |
| max | range:区间最长夜数;multiple:最多可选天数,达到上限后点击被忽略 | number | - |
| allowRangeReset | range:区间选满后,任意一次点击都直接以该日期开始新区间 | boolean | false |
| multiRangeMode | multiple:连续选中的日期渲染成一条连续的区间条 | boolean | - |
可选范围
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| minDate | 最早可选日期,边界判断带时分秒 | DateType | - |
| maxDate | 最晚可选日期,边界判断带时分秒 | DateType | - |
| disabledDates | 禁用的日期数组,或返回 true 表示禁用的判断函数 | DateType[] | ((date: DateType) => boolean) | - |
| enabledDates | 允许选择的日期白名单,优先级高于 disabledDates | DateType[] | ((date: DateType) => boolean) | - |
显示与布局
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| firstDayOfWeek | 一周的起始日,1–6 生效,其余值回落到周日 | number | 0 |
| showOutsideDays | 是否补齐上下月的日期格 | boolean | false |
| navigationPosition | 上/下月翻页按钮的位置 | 'around' | 'right' | 'left' | 'around' |
| weekdaysFormat | 星期名格式 | 'min' | 'short' | 'full' | 'min' |
| monthsFormat | 月份选择视图里的月份名格式 | 'short' | 'full' | 'full' |
| monthCaptionFormat | 头部月份标题的格式 | 'short' | 'full' | 'full' |
| hideHeader | 隐藏内置头部 | boolean | - |
| hideWeekdays | 隐藏星期行 | boolean | - |
| showMonthSelector | true 时年份视图里也显示月份选择器,false 时始终隐藏;不传则除年份视图外都显示 | boolean | - |
| disableMonthPicker | 禁用月份选择视图 | boolean | - |
| disableYearPicker | 禁用年份选择视图 | boolean | - |
| initialView | 初始视图,time 需要同时开启 timePicker | 'day' | 'month' | 'year' | 'time' | 'day' |
| containerHeight | 日期网格区域的固定高度 | number | 300 |
| weekdaysHeight | 星期行高度 | number | 25 |
时间与本地化
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| timePicker | 开启时间选择视图 | boolean | false |
| use12Hours | 时间选择使用 12 小时制(AM / PM) | boolean | - |
| locale | dayjs locale 名,包内已预置 45 种语言包 | string | 'en' |
| calendar | 历法 | 'gregory' | 'jalali' | 'gregory' |
| numerals | 数字系统,如 latn(阿拉伯数字)、arab、arabext、deva 等 12 种 | string | 'latn' |
| timeZone | 时区名,走 dayjs.tz | string | - |
显示月份控制
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| month | 当前显示的月份,0 起算(0 表示一月) | number | - |
| year | 当前显示的年份 | number | - |
| onMonthChange | 内部翻月时触发 | (month: number) => void | - |
| onYearChange | 内部翻年时触发 | (year: number) => void | - |
| startYear | 年份视图的起始年份;3.3.0 中声明了但未接线,传了无效 | number | - |
| endYear | 年份视图的结束年份;3.3.0 中声明了但未接线,传了无效 | number | - |
自定义与样式
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| components | 替换日期格、月份格、年份格、星期名与翻页图标 | CalendarComponents | - |
| classNames | 按 slot 覆盖类名,与第三方默认类名逐 slot 合并而非整段替换 | CalendarClassNames | - |
| className | 面板容器类名,追加在本层的 rounded-2xl bg-background p-4 之后 | string | - |
| styles | 按 slot 覆盖 RN 样式对象,slot 名与 classNames 相同;该类型未从 @skyroc/native-ui 导出 | { [slot]: ViewStyle | TextStyle | ImageStyle } | - |
| style | 面板容器(头部 + 主体)的样式 | ViewStyle | - |
| containerStyle | 日期/月份/年份/时间视图主体的样式,不会覆盖 containerHeight | ViewStyle | - |
类型
import type {
CalendarClassNames,
CalendarComponents,
CalendarDay,
CalendarMode,
CalendarMonth,
CalendarProps,
CalendarSlots,
CalendarWeek,
CalendarYear,
DateType
} from '@skyroc/native-ui';CalendarProps 是三种模式各自 props 的联合(mode: 'single' / 'range' / 'multiple'),所以 TypeScript 能按 mode 收窄出对应的 onChange 签名;写公共封装时需要自己分支处理,不能只声明一个宽泛的回调。
CalendarMode
选择模式,决定数据属性与回调签名。
DateType
日期值,可以是 Date、时间戳、可解析的字符串或 dayjs 对象;回调回传的一律是 Date。
CalendarSlots
本层面板容器变体的 slot 名,只有一个 root;它与 classNames 用的第三方 slot 名(见 CalendarClassNames)不是一回事。
CalendarComponents
自定义渲染函数,全部可选;接管之后选中、今天、禁用等状态样式需要自行表达。
| 字段 | 类型 | 说明 |
|---|---|---|
| Day | (day: CalendarDay) => ReactNode | 日期格内容。 |
| Month | (month: CalendarMonth) => ReactNode | 月份选择视图里的月份格。 |
| Year | (year: CalendarYear) => ReactNode | 年份选择视图里的年份格。 |
| Weekday | (weekday: CalendarWeek) => ReactNode | 头部的星期名。 |
| IconPrev | ReactNode | 上一月 / 上一年按钮的图标。 |
| IconNext | ReactNode | 下一月 / 下一年按钮的图标。 |
| MonthSelector | (props: { text: string; isOpen: boolean; onPress: () => void }) => ReactNode | 整体替换头部的月份选择按钮。 |
| YearSelector | (props: { year: string; yearRange: string; isOpen: boolean; onPress: () => void }) => ReactNode | 整体替换头部的年份选择按钮。 |
CalendarDay
components.Day 收到的日期格数据。
| 字段 | 类型 | 说明 |
|---|---|---|
| number | number | 日期数字,如 15。 |
| text | string | 按 locale 与 numerals 格式化后的日期文本。 |
| date | string | 该格对应的日期字符串。 |
| isCurrentMonth | boolean | 是否属于当前显示的月份。 |
| isToday | boolean | 是否是今天。 |
| isSelected | boolean | 是否被选中。 |
| isDisabled | boolean | 是否不可选。 |
| inRange | boolean | 是否落在已选区间内(range 模式)。 |
| rangeStart | boolean | 是否是区间起点。 |
| rangeEnd | boolean | 是否是区间终点。 |
| inMiddle | boolean | 是否是区间的中间段(两侧都不裁切)。 |
| leftCrop | boolean | 区间背景在左侧收口。 |
| rightCrop | boolean | 区间背景在右侧收口。 |
| isCrop | boolean | 区间背景只在单侧收口。 |
| isStartOfWeek | boolean | 是否是一周的第一天。 |
| isEndOfWeek | boolean | 是否是一周的最后一天。 |
| dayOfMonth | number | 该格在本月中的序号,可选。 |
CalendarWeek
components.Weekday 收到的星期数据。
| 字段 | 类型 | 说明 |
|---|---|---|
| index | number | 星期序号,0 为周日。 |
| name | { full: string; short: string; min: string } | 三种长度的星期名,与 weekdaysFormat 的取值对应。 |
CalendarMonth
components.Month 收到的月份数据。
| 字段 | 类型 | 说明 |
|---|---|---|
| index | number | 月份序号,0 表示一月。 |
| name | { full: string; short: string } | 两种长度的月份名。 |
| isSelected | boolean | 是否是当前月份。 |
CalendarYear
components.Year 收到的年份数据。
| 字段 | 类型 | 说明 |
|---|---|---|
| number | number | 年份数字。 |
| text | string | 格式化后的年份文本。 |
| isSelected | boolean | 是否是选中值所在的年份。 |
| isActivated | boolean | 是否是当前显示的年份(未选中但处于激活态)。 |
CalendarClassNames
全部 slot 的类名映射,每一项都可选(等价于 Partial<Record<Slot, string>>)。传入的值会与第三方默认类名合并,冲突的工具类由 tailwind-merge 决定胜负。
| 字段 | 类型 | 说明 |
|---|---|---|
| header | string | 头部整块。 |
| button_prev | string | 上一月/上一年按钮。 |
| button_next | string | 下一月/下一年按钮。 |
| button_prev_image | string | 上一月/上一年按钮的图标。 |
| button_next_image | string | 下一月/下一年按钮的图标。 |
| month_selector | string | 头部的月份选择按钮。 |
| month_selector_label | string | 头部月份选择按钮的文字。 |
| year_selector | string | 头部的年份选择按钮。 |
| year_selector_label | string | 头部年份选择按钮的文字。 |
| time_selector | string | 头部的时间选择按钮。 |
| time_selector_label | string | 头部时间选择按钮的文字。 |
| weekdays | string | 星期行。 |
| weekday | string | 单个星期格。 |
| weekday_label | string | 星期名文字。 |
| days | string | 日期网格容器。 |
| day_cell | string | 日期格的外层包装。 |
| day | string | 日期格。 |
| day_label | string | 日期文字。 |
| today | string | 今天的日期格。 |
| today_label | string | 今天的日期文字。 |
| outside | string | 非当前月份的日期格。 |
| outside_label | string | 非当前月份的日期文字。 |
| hidden | string | 被隐藏的日期格。 |
| selected | string | 选中的日期格。 |
| selected_label | string | 选中的日期文字。 |
| range_start | string | 区间起点的日期格。 |
| range_start_label | string | 区间起点的日期文字。 |
| range_middle | string | 区间中间段的日期格。 |
| range_middle_label | string | 区间中间段的日期文字。 |
| range_end | string | 区间终点的日期格。 |
| range_end_label | string | 区间终点的日期文字。 |
| range_fill | string | 区间的填充背景。 |
| range_fill_weekstart | string | 区间中每周第一天的填充背景。 |
| range_fill_weekend | string | 区间中每周最后一天的填充背景。 |
| months | string | 月份选择视图的容器。 |
| month | string | 月份格。 |
| month_label | string | 月份文字。 |
| selected_month | string | 选中的月份格。 |
| selected_month_label | string | 选中的月份文字。 |
| years | string | 年份选择视图的容器。 |
| year | string | 年份格。 |
| year_label | string | 年份文字。 |
| selected_year | string | 选中的年份格。 |
| selected_year_label | string | 选中的年份文字。 |
| active_year | string | 当前显示但未选中的年份格。 |
| active_year_label | string | 当前显示但未选中的年份文字。 |
| disabled | string | 禁用的日期/月份/年份格。 |
| disabled_label | string | 禁用项的文字。 |
| time_label | string | 时间选择视图里的时分文字。 |
| time_selected_indicator | string | 时间选择视图里选中项的指示条。 |