输入类

日期选择器

日期选择器用于帮助用户选择一个符合要求的、格式化的日期(时间)或日期(时间)范围

代码演示

如何引入

import { Button, ButtonGroup, DatePicker, Space, TabPane, Tabs, Tooltip, Typography } from '@fibrous/semi-ui-solid';

基本使用

代码
import { DatePicker } from '@fibrous/semi-ui-solid';

export default function DatePickerDemo() {
    return <DatePicker onChange={(_date, dateString) => console.log(dateString)} />;
}

小尺寸

使用 density 可以控制日期面板的尺寸,compact 为小尺寸,default 为默认尺寸。



~
代码
import { DatePicker } from '@fibrous/semi-ui-solid';

export default function DatePickerDemo() {
    return (
        <div>
            <DatePicker type="dateTime" density="compact" />
            <br />
            <br />
            <DatePicker type="dateRange" density="compact" style={{ width: '260px' }} />
        </div>
    );
}

多个日期选择

将 multiple 设为 true,可以多选日期

代码
import { DatePicker } from '@fibrous/semi-ui-solid';

export default function DatePickerDemo() {
    return <DatePicker multiple style={{ width: '240px' }} />;
}

日期与时间选择

将 type 设定为 dateTime,可以选择日期时间。
版本V2.22.0开始,我们将 TimePicker 内的 ScrollItem 的默认模式从 wheel 变更为了 normal, 若想应用回无限滚动的效果,可以通过 timePickerOpts 传入特定配置开启。

默认日期与时间选择



开启时间列表无限循环

代码
import { DatePicker } from '@fibrous/semi-ui-solid';

export default function DatePickerDemo() {
    return (
        <>
            <h4>默认日期与时间选择</h4>
            <DatePicker type="dateTime" />
            <br />
            <br />
            <h4>开启时间列表无限循环</h4>
            <DatePicker
                type="dateTime"
                timePickerOpts={{
                    scrollItemProps: { mode: 'wheel', cycled: true },
                }}
            />
        </>
    );
}

日期范围选择

将 type 设定为 dateRange,可以选择日期范围

~
代码
import { DatePicker } from '@fibrous/semi-ui-solid';

export default function DatePickerDemo() {
    return <DatePicker type="dateRange" style={{ width: '260px' }} onChange={(date) => console.log(date)} />;
}

日期范围时间选择

将 type 设定为 dateTimeRange, 可以选择日期时间范围
当未传入初始值或受控值时,底部面板默认时间为当前时间。如果你有特殊需求(如指定默认时分秒),可以通过 defaultPickerValue 指定

~
~
代码
import { DatePicker } from '@fibrous/semi-ui-solid';

const defaultPickerValue = [new Date('2022-08-08 00:00'), new Date('2022-08-09 12:00')];

export default function DatePickerDemo() {
    return (
        <>
            <DatePicker type="dateTimeRange" style={{ width: '400px', 'margin-bottom': '8px' }} onChange={(date) => console.log(date)} />
            <DatePicker type="dateTimeRange" style={{ width: '400px' }} defaultPickerValue={defaultPickerValue} onChange={(date) => console.log(date)} />
        </>
    );
}

内嵌输入框

使用 insetInput 可以控制日期面板是否展示内嵌输入框,默认为 false。v2.7.0 后支持。内嵌输入框适用于以下场景:

  • 日期时间选择,可以直接通过内嵌输入框单独修改时间,无须通过滚轮选择时间
  • 自定义触发器时 + 范围选择,使用内嵌输入框可以单独对开始和结束日期进行修改

insetInput 开启后包括以下功能:

  • 点击触发器后,面板默认在原有位置弹出。你可以通过 position 自定义弹出位置
  • 点击内嵌日期输入框,面板切换到日期选择;点击内嵌时间输入框,面板切换到时间选择
  • 和外部的输入框一致,如果输入了非法日期,面板关闭后日期会回到之前的合法日期




~


~








代码
import { DatePicker } from '@fibrous/semi-ui-solid';

export default function DatePickerDemo() {
    return (
        <div>
            <DatePicker type="date" insetInput />
            <br />
            <br />
            <DatePicker type="dateTime" insetInput />
            <br />
            <br />
            <DatePicker type="dateRange" insetInput style={{ width: '260px' }} />
            <br />
            <br />
            <DatePicker type="dateTimeRange" insetInput style={{ width: '400px' }} />
            <br />
            <br />
            <DatePicker type="month" placeholder="请选择年月" insetInput style={{ width: '140px' }} />
            <br />
            <br />
            <DatePicker type="monthRange" placeholder="请选择年月范围" insetInput style={{ width: '200px' }} />
            <br />
            <br />
            <DatePicker type="date" position="bottomLeft" insetInput />
            <br />
            <br />
            <DatePicker type="dateTime" format="yyyy-MM-dd HH:mm" insetInput />
        </div>
    );
}

同步切换双面板月份

在范围选择的场景中, 开启 syncSwitchMonth 则允许双面板同步切换。默认为 false。

Note:点击年份按钮也会同步切换两个面板,从滚轮里面切换年月不会同步切换面板,这保证了用户选择非固定间隔月份的能力。

~
代码
import { DatePicker } from '@fibrous/semi-ui-solid';

export default function DatePickerDemo() {
    return <DatePicker syncSwitchMonth type="dateTimeRange" style={{ width: '400px' }} />;
}

切换面板日期的回调

onPanelChange 回调函数会在面板的月份或年份切换改变时被调用。

~
代码
import { DatePicker } from '@fibrous/semi-ui-solid';

export default function DatePickerDemo() {
    return <DatePicker syncSwitchMonth type="dateTimeRange" style={{ width: '400px' }} onPanelChange={(date, dateString) => console.log(date, dateString)} />;
}

周选择

dateRange 搭配 startDateOffset 和 endDateOffset 可以进行单击范围选择,如周选择、双周选择。

选择自然周

~


选择双周

~


选择当前日和后6日

~


代码
import * as dateFns from 'date-fns';
import { DatePicker } from '@fibrous/semi-ui-solid';

export default function DatePickerDemo() {
    const handleChange = (date: Date | Date[]) => {
        console.log('date changed', date);
    };

    return (
        <div>
            <h4>选择自然周</h4>
            <DatePicker style={{ width: '260px' }} type="dateRange" weekStartsOn={1} startDateOffset={(date) => dateFns.startOfWeek(date, { weekStartsOn: 1 })} endDateOffset={(date) => dateFns.endOfWeek(date, { weekStartsOn: 1 })} onChange={handleChange} />
            <br />
            <br />
            <h4>选择双周</h4>
            <DatePicker style={{ width: '260px' }} type="dateRange" weekStartsOn={1} startDateOffset={(date) => dateFns.startOfWeek(date, { weekStartsOn: 1 })} endDateOffset={(date) => dateFns.add(dateFns.endOfWeek(date, { weekStartsOn: 1 }), { days: 7 })} onChange={handleChange} />
            <br />
            <br />
            <h4>选择当前日和后6日</h4>
            <DatePicker style={{ width: '260px' }} type="dateRange" weekStartsOn={1} endDateOffset={(date) => dateFns.add(date, { days: 6 })} onChange={handleChange} />
            <br />
            <br />
        </div>
    );
}

年月选择

将 type 设定为 month,可以进行年月选择。

代码
import { DatePicker } from '@fibrous/semi-ui-solid';

const defaultValue = new Date(2024, 4, 6, 12);

export default function DatePickerDemo() {
    return <DatePicker defaultValue={defaultValue} type="month" style={{ width: '140px' }} />;
}

年月范围选择

版本: >= 2.32.0

将 type 设定为 monthRange,可以进行年月范围选择。暂不支持小尺寸与快捷面板。

代码
import { DatePicker } from '@fibrous/semi-ui-solid';

export default function DatePickerDemo() {
    return <DatePicker type="monthRange" style={{ width: '200px' }} />;
}

年份选择

将 type 设定为 year,可以进行年份选择。面板只有一列年份,选中的值为该年 1 月 1 日,默认格式为 yyyy。disabledDate 以每年的 1 月 1 日判断该年是否可选。

代码
import { DatePicker } from '@fibrous/semi-ui-solid';

const defaultValue = new Date(2024, 4, 6, 12);

export default function DatePickerDemo() {
    return <DatePicker defaultValue={defaultValue} type="year" style={{ width: '140px' }} />;
}

确认日期时间选择

对于“日期时间”(type="dateTime")或“日期时间范围”(type="dateTimeRange")的选择,可以进行确认后才将值写入输入框内,你可以通过传递 needConfirm=true 来开启这种行为。

同时支持 “确认”(onConfirm) 和 “取消”(onCancel) 两个按钮的点击回调。

下面这个例子绑定了 onChange、onConfirm、onCancel 三种回调,你可以打开控制台查看打印信息的区别。

注意:开启确认选择时,需要点击取消按钮关闭面板,点击空白区域不再关闭面板(v2.2.0)

代码
import { DatePicker } from '@fibrous/semi-ui-solid';

export default function DatePickerDemo() {
    return (
        <DatePicker
            type="dateTime"
            needConfirm
            onConfirm={(...args) => {
                console.log('Confirmed: ', ...args);
            }}
            onCancel={(...args) => {
                console.log('Canceled: ', ...args);
            }}
            onChange={(...args) => {
                console.log('Changed: ', ...args);
            }}
        />
    );
}

带有快捷方式的日期时间选择

通过 presets 设定快捷日期选择

代码
import { DatePicker, type DatePickerPresetsType } from '@fibrous/semi-ui-solid';

const presets: DatePickerPresetsType = [
    {
        text: 'Today',
        start: () => new Date(),
        end: () => new Date(),
    },
    () => ({
        text: 'Tomorrow',
        start: new Date(new Date().valueOf() + 1000 * 3600 * 24),
        end: new Date(new Date().valueOf() + 1000 * 3600 * 24),
    }),
];

export default function DatePickerDemo() {
    return <DatePicker type="dateTime" presets={presets} presetPosition="left" />;
}

渲染顶部/底部额外区域

通过 topSlot 和 bottomSlot 可以自定义渲染顶部和底部额外区域,通过 leftSlot 和 rightSlot 可以自定义渲染左侧和右侧额外区域。









~


代码
import { createSignal, type JSX } from 'solid-js';
import { IconBulb } from '@fibrous/semi-icons-solid';
import { DatePicker, Typography, Tabs, TabPane, Space, type DatePickerDisabledDateType } from '@fibrous/semi-ui-solid';

const uedDisabledDate: DatePickerDisabledDateType = (currentDate) => !!currentDate && currentDate.getDate() > 10 && currentDate.getDate() < 15;
const testDisabledDate: DatePickerDisabledDateType = (currentDate) => !!currentDate && currentDate.getDate() > 15 && currentDate.getDate() < 25;

interface SlotProps {
    style?: JSX.CSSProperties;
}

interface TopSlotProps extends SlotProps {
    activeKey: string;
    onChange: (activeKey: string) => void;
}

function TopSlot(props: TopSlotProps) {
    return (
        <Tabs size="small" onChange={props.onChange} activeKey={props.activeKey} style={{ padding: '12px 20px 0', ...props.style }}>
            <TabPane tab="UED 排期" itemKey="1" />
            <TabPane tab="测试排期" itemKey="2" />
        </Tabs>
    );
}

function BottomSlot(props: SlotProps) {
    return (
        <Space style={{ padding: '12px 20px', ...props.style }}>
            <IconBulb style={{ color: 'var(--semi-amber-5)' }} />
            <Typography.Text strong style={{ color: 'var(--semi-color-text-2)' }}>
                定版前请阅读
            </Typography.Text>
            <Typography.Text link={{ href: 'https://semi.design/', target: '_blank' }}>发版须知</Typography.Text>
        </Space>
    );
}

function MonthBottomSlot(props: SlotProps) {
    return (
        <Space style={{ padding: '12px 20px', ...props.style }}>
            <IconBulb style={{ color: 'var(--semi-amber-5)' }} />
            <Typography.Text strong style={{ color: 'var(--semi-color-text-2)' }}>
                请阅读
            </Typography.Text>
            <Typography.Text link={{ href: 'https://semi.design/', target: '_blank' }}>须知</Typography.Text>
        </Space>
    );
}

export default function DatePickerDemo() {
    const [activeTab, setActiveTab] = createSignal('1');
    const [date, setDate] = createSignal<Date | Date[]>();

    const handleTabChange = (tab: string) => {
        setActiveTab(tab);
        setDate(undefined);
    };

    const handleDateChange = (value: Date | Date[]) => {
        setDate(value);
    };

    return (
        <div>
            <DatePicker topSlot={<TopSlot activeKey={activeTab()} onChange={handleTabChange} />} disabledDate={activeTab() === '1' ? uedDisabledDate : testDisabledDate} value={date()} onChange={handleDateChange} dropdownClassName="components-datepicker-demo-slot" placeholder="请选择排期" />
            <br />
            <br />
            <DatePicker bottomSlot={<BottomSlot />} placeholder="请选择发版时间" />
            <br />
            <br />
            <DatePicker type="month" bottomSlot={<MonthBottomSlot />} placeholder="请选择年月" />
            <br />
            <br />
            <DatePicker topSlot={<TopSlot activeKey={activeTab()} onChange={handleTabChange} style={{ padding: '8px 12px 0' }} />} bottomSlot={<BottomSlot style={{ padding: '8px 12px' }} />} density="compact" placeholder="小尺寸" dropdownClassName="components-datepicker-demo-slot" />
            <br />
            <br />
            <DatePicker type="dateTimeRange" bottomSlot={<BottomSlot />} style={{ width: '400px' }} placeholder="请选择时间范围" />
            <br />
            <br />
        </div>
    );
}
.components-datepicker-demo-slot {
    .semi-tabs-content {
        padding: 0;
    }

    .semi-tabs-bar-line.semi-tabs-bar-top {
        border-bottom: none;
    }
}

禁用日期选择

代码
import { DatePicker } from '@fibrous/semi-ui-solid';

const defaultValue = new Date(2024, 4, 6, 12);

export default function DatePickerDemo() {
    return <DatePicker disabled type="dateTime" defaultValue={defaultValue} />;
}

禁用部分日期或时间

传入 disabledDate 可以禁用指定日期,传入 disabledTime 可以禁用指定时间,配合 defaultPickerValue 可以指定面板打开时所处的年月。

disabledDate 和 disabledTime,接受的入参都为当前日期,前者返回一个 boolean 值,后者返回一个对象,将会透传给 TimePicker 组件。

禁用时间:禁用今天下午5-6点

禁用时间:两个面板禁用不同时间

~

禁用日期:禁用下个月28号之前的所有日期

~
代码
import * as dateFns from 'date-fns';
import { range } from 'es-toolkit';
import { DatePicker, type DatePickerDisabledDateType, type DatePickerDisabledTimeType } from '@fibrous/semi-ui-solid';

const today = () => new Date();

const nextValidMonth = () => {
    const nextValidDate = today();
    nextValidDate.setMonth((nextValidDate.getMonth() + 1) % 12);
    return nextValidDate;
};

const disabledTime: DatePickerDisabledTimeType = (date) =>
    // With type dateTime, date is a single Date
    dateFns.isToday(date as Date)
        ? {
              disabledHours: () => [17, 18],
              disabledMinutes: (hour) => (19 === hour ? range(0, 10, 1) : []),
              disabledSeconds: (hour, minute) => (hour === 20 && minute === 20 ? range(0, 20, 1) : []),
          }
        : {};

const disabledTime2: DatePickerDisabledTimeType = (_date, panelType) => {
    if (panelType === 'left') {
        return { disabledHours: () => [17, 18] };
    }
    return { disabledHours: () => [12, 13, 14, 15, 16, 17, 18] };
};

const disabledDate: DatePickerDisabledDateType = (date) => {
    const deadDate = today();
    const month = deadDate.getMonth();
    deadDate.setDate(28);
    deadDate.setMonth((month + 1) % 12);
    return !!date && date.getTime() < deadDate.getTime();
};

export default function DatePickerDemo() {
    return (
        <div>
            <div>
                <h4>禁用时间:禁用今天下午5-6点</h4>
                <DatePicker type="dateTime" hideDisabledOptions={false} disabledTime={disabledTime} />
            </div>
            <div>
                <h4>禁用时间:两个面板禁用不同时间</h4>
                <DatePicker type="dateTimeRange" hideDisabledOptions={false} disabledTime={disabledTime2} style={{ width: '400px' }} />
            </div>
            <div>
                <h4>禁用日期:禁用下个月28号之前的所有日期</h4>
                <DatePicker type="dateTimeRange" disabledDate={disabledDate} defaultPickerValue={nextValidMonth()} style={{ width: '400px' }} />
            </div>
        </div>
    );
}

在 type 包含 range 时,可以根据当前选择动态禁止日期。options 参数 1.9.0 后支持。

动态禁用日期:禁止选择之前的日期

~
代码
import * as dateFns from 'date-fns';
import { DatePicker } from '@fibrous/semi-ui-solid';

export default function DatePickerDemo() {
    return (
        <div>
            <h4>动态禁用日期:禁止选择之前的日期</h4>
            <DatePicker
                type="dateRange"
                disabledDate={(date, options) => {
                    if (!date || !options?.rangeStart) {
                        return false;
                    }
                    const startDate = dateFns.parseISO(options.rangeStart);
                    return dateFns.isBefore(date, startDate);
                }}
                style={{ width: '260px' }}
            />
        </div>
    );
}

范围选择时,可以根据 focus 状态禁用日期。focus 状态通过 options 中的 rangeInputFocus 参数传递。

开始日期禁用今天前2日和后2日,结束日期禁用今天前3天和后3天

~
代码
import * as dateFns from 'date-fns';
import { DatePicker, type DatePickerDisabledDateType } from '@fibrous/semi-ui-solid';

const today = new Date();

const disabledDate: DatePickerDisabledDateType = (date, options) => {
    if (!date) {
        return false;
    }
    const rangeInputFocus = options?.rangeInputFocus;
    const baseDate = dateFns.set(today, { hours: 0, minutes: 0, seconds: 0, milliseconds: 0 });
    if (rangeInputFocus === 'rangeStart') {
        const disabledStart = dateFns.subDays(baseDate, 2);
        const disabledEnd = dateFns.addDays(baseDate, 2);
        return disabledStart <= date && date <= disabledEnd;
    } else if (rangeInputFocus === 'rangeEnd') {
        const disabledStart = dateFns.subDays(baseDate, 3);
        const disabledEnd = dateFns.addDays(baseDate, 3);
        return disabledStart <= date && date <= disabledEnd;
    } else {
        return false;
    }
};

export default function DatePickerDemo() {
    return (
        <div>
            <h4>开始日期禁用今天前2日和后2日,结束日期禁用今天前3天和后3天</h4>
            <DatePicker motion={false} type="dateRange" disabledDate={disabledDate} defaultPickerValue={today} />
        </div>
    );
}

自定义显示格式

可以通过 format 自定义显示格式

代码
import { DatePicker } from '@fibrous/semi-ui-solid';

const defaultValue = new Date(2024, 4, 6, 12);

export default function DatePickerDemo() {
    return <DatePicker format="yyyy年MM月dd日 HH:mm" type="dateTime" defaultValue={defaultValue} />;
}

自定义触发器

默认情况下我们使用 Input 组件作为 DatePicker 组件的触发器,通过传递 triggerRender 方法你可以自定义这个触发器。

自定义触发器是对触发器的完全自定义,默认的清除按钮将不生效,如果你需要清除功能,请自定义一个清除按钮。

triggerRender 只调用一次,入参的每个属性都是响应式的,需要在返回的 JSX 中读取,不要解构。

代码
import { createSignal, Show } from 'solid-js';
import * as dateFns from 'date-fns';
import { IconClose, IconChevronDown } from '@fibrous/semi-icons-solid';
import { DatePicker, Button, ButtonGroup } from '@fibrous/semi-ui-solid';

const formatToken = 'yyyy-MM-dd';

export default function DatePickerDemo() {
    const [date, setDate] = createSignal<Date | undefined>(new Date(2024, 4, 6, 12));
    const dateText = () => {
        const value = date();
        return value ? dateFns.format(value, formatToken) : undefined;
    };
    const onChange = (value: Date | Date[]) => {
        setDate(value as Date);
    };
    const onClear = (e?: MouseEvent) => {
        e?.stopPropagation();
        setDate(undefined);
    };

    return (
        <DatePicker
            onChange={onChange}
            value={date()}
            format={formatToken}
            triggerRender={(triggerProps) => (
                // The clear button is a sibling of the trigger button: buttons cannot nest
                <ButtonGroup theme="light">
                    <Button icon={<IconChevronDown />} iconPosition="right">
                        {dateText() ?? triggerProps.placeholder}
                    </Button>
                    <Show when={date()}>
                        <Button icon={<IconClose />} aria-label="清除" onClick={onClear} />
                    </Show>
                </ButtonGroup>
            )}
        />
    );
}
代码
import { createSignal, Show } from 'solid-js';
import * as dateFns from 'date-fns';
import { IconClose, IconChevronDown } from '@fibrous/semi-icons-solid';
import { DatePicker, Button, ButtonGroup } from '@fibrous/semi-ui-solid';

const formatToken = 'yyyy-MM-dd HH:mm:ss';

export default function DatePickerDemo() {
    const [date, setDate] = createSignal<Date | Date[]>();
    const onChange = (value: Date | Date[]) => {
        setDate(value);
        console.log(value);
    };
    const onClear = (e?: MouseEvent) => {
        e?.stopPropagation();
        setDate(undefined);
    };

    const triggerContent = () => {
        const value = date();
        if (Array.isArray(value) && value.length) {
            return `${dateFns.format(value[0], formatToken)} ~ ${dateFns.format(value[1], formatToken)}`;
        }
        return '请选择日期时间范围';
    };

    return (
        <DatePicker
            type="dateTimeRange"
            onChange={onChange}
            value={date()}
            triggerRender={() => (
                // The clear button is a sibling of the trigger button: buttons cannot nest
                <ButtonGroup theme="light">
                    <Button icon={<IconChevronDown />} iconPosition="right">
                        {triggerContent()}
                    </Button>
                    <Show when={date()}>
                        <Button icon={<IconClose />} aria-label="清除" onClick={onClear} />
                    </Show>
                </ButtonGroup>
            )}
        />
    );
}

自定义日期显示内容

renderDate: (dayNumber?: number, fullDate?: string) => JSX.Element,自定义日期内容。

  • dayNumber:当前日。如 13。
  • fullDate:当前日的完整日期。如 2020-08-13。
代码
import { DatePicker, Tooltip } from '@fibrous/semi-ui-solid';

const dateStyle = {
    width: '100%',
    height: '100%',
    border: '1px solid var(--semi-color-primary)',
    display: 'flex',
    'justify-content': 'center',
    'align-items': 'center',
};

const renderDate = (dayNumber?: number) => {
    if (dayNumber === 1) {
        return (
            <Tooltip content="Always Day 1">
                <div style={dateStyle}>{dayNumber}</div>
            </Tooltip>
        );
    }
    return dayNumber;
};

export default function DatePickerDemo() {
    return <DatePicker renderDate={renderDate} />;
}

自定义日期格子渲染

renderFullDate: (dayNumber?: number, fullDate?: string, dayStatus?: DayStatusType) => JSX.Element,自定义日期格子的渲染内容。

dayStatus 表示当前格子的状态,包括的 key 有:

type DayStatusType = { isToday?: boolean; // 当前日 isSelected?: boolean; // 被选中 isDisabled?: boolean; // 被禁用 isSelectedStart?: boolean; // 选中开始 isSelectedEnd?: boolean; // 选中结束 isInRange?: boolean; // 范围选中日期内 isHover?: boolean; // 日期在选择项和hover日期之间 isOffsetRangeStart?: boolean; // 周选择开始 isOffsetRangeEnd?: boolean; // 周选择结束 isHoverInOffsetRange?: boolean; // hover在周选择内 };
~
代码
import clsx from 'clsx';
import { DatePicker, type DatePickerDayStatusType as DayStatusType } from '@fibrous/semi-ui-solid';

const prefix = 'components-datepicker-demo';

const dayStyle = {
    display: 'flex',
    'align-items': 'center',
    'justify-content': 'center',
    width: '80%',
    height: '80%',
    'border-radius': 'var(--semi-border-radius-circle)',
};

const renderFullDate = (dayNumber?: number, _fullDate?: string, dayStatus?: DayStatusType) => {
    const dateCls = clsx({
        [`${prefix}-day-inrange`]: dayStatus?.isInRange,
        [`${prefix}-day-hover`]: dayStatus?.isHover,
        [`${prefix}-day-selected`]: dayStatus?.isSelected,
        [`${prefix}-day-selected-start`]: dayStatus?.isSelectedStart,
        [`${prefix}-day-selected-end`]: dayStatus?.isSelectedEnd,
    });

    return (
        <div style={dayStyle} class={dateCls}>
            {dayNumber}
        </div>
    );
};

export default function DatePickerDemo() {
    return <DatePicker style={{ width: '260px' }} type="dateRange" renderFullDate={renderFullDate} />;
}
.components-datepicker-demo-day-inrange,
.components-datepicker-demo-day-hover {
    background: var(--semi-color-primary-light-hover);
}

.components-datepicker-demo-day-selected,
.components-datepicker-demo-day-selected-start,
.components-datepicker-demo-day-selected-end {
    color: var(--semi-color-bg-2);
    background: var(--semi-color-primary);
}

API 参考

Props

属性说明类型默认值
autoAdjustOverflow浮层被遮挡时是否自动调整方向。booleantrue
autofocus挂载后是否自动聚焦输入框。boolean-
autoSwitchDate通过面板上方的年月切换按钮或下拉菜单更改年月时,自动切换日期。仅对 date 类型生效。booleantrue
borderless无边框模式。booleanfalse
bottomSlot渲染底部额外区域,传入 JSX 元素。JSX.Element-
class根元素的类名。string-
clearIcon自定义清除按钮的图标,showClear 为 true 时有效。传入 JSX 元素。JSX.Element-
defaultOpen面板默认显示或隐藏。booleanfalse
defaultPickerValue默认面板日期。按内容比较,内容变化时面板回到该日期;每次渲染都传 new Date() 会被视为变化。ValueType-
defaultValue默认值。ValueType-
density面板的尺寸,可选值:default、compact。DensityType"default"
disabled是否禁用。boolean-
disabledDate日期禁止判断方法,返回 true 时禁止该日期。options 含范围选择已选的 rangeStart、rangeEnd 与当前聚焦的输入框 rangeInputFocus;type 为 year 时以每年的 1 月 1 日调用,返回 true 时禁止该年。DisabledDateTypeType() => false
disabledTime时间禁止配置,返回值会透传给 TimePicker 组件。DisabledTimeTypeType() => ({})
disabledTimePicker是否禁止时间选择。MonthsGridFoundationProps['disabledTimePicker']-
dropdownClassName下拉面板的类名。string-
dropdownStyle下拉面板的内联样式,可传对象(键为 kebab-case)或字符串。JSX.CSSProperties | string-
endDateOffsettype 为 dateRange 时,设置单击选择范围的结束日期。DateOffsetType-
endYear年份滚轮的结束年,需大于 startYear。默认为当前年后 100 年。number-
format输入框中展示的日期字符串格式,默认值随 type 变化,见下方「日期时间格式」。string-
hideDisabledOptions隐藏禁止选择的时间选项。MonthsGridFoundationProps['hideDisabledOptions']false
inputReadOnly文本框是否为只读(readonly)。booleanfalse
inputStyle输入框的样式,可传对象(键为 kebab-case)或字符串。JSX.CSSProperties | string-
insetInput面板中是否嵌入输入框。可传布尔值,或传入 InsetInputProps 对象配置内嵌输入框的 placeholder。DateInputFoundationProps['insetInput']false
insetLabel输入框内的标签,由 Form 字段注入;直接使用 DatePicker 时也会显示在输入框中。JSX.Element-
insetLabelId输入框内标签的元素 id,由 Form 字段注入,用于为输入框提供可访问名称。string-
leftSlot渲染左侧额外区域,传入 JSX 元素。JSX.Element-
maxmultiple 为 true 时最多可选的日期数量,不传或为 null、undefined 时不限制。number-
motion是否开启面板展开的动画。booleantrue
multiple是否可以多选,仅支持 type 为 date。booleanfalse
needConfirm是否需要“确认选择”,仅 type 为 dateTime 或 dateTimeRange 时有效。boolean-
onBlur面板关闭时的回调,范围选择时不推荐使用。只有点击外部关闭时 e 为原生 mousedown 事件,确认、选中日期、Esc 等其他关闭方式不传。Type(e?: MouseEvent) => void-
onCancel取消选择时的回调,入参为上次确认的值,仅 type 为 dateTime 或 dateTimeRange 且 needConfirm 为 true 时有效。OnCancelType-
onChange值变化时的回调。范围与多选时两个参数都是数组。Type(date: Date | Date[], dateString: string | string[]) => void-
onClear点击清除按钮时的回调。Type(e: MouseEvent) => void-
onClickOutSide弹出层展示时,在弹出层与触发器之外按下鼠标时的回调,参数为原生 mousedown 事件。Type(e: MouseEvent) => void-
onConfirm确认选择时的回调,入参为当前选择的值,仅 type 为 dateTime 或 dateTimeRange 且 needConfirm 为 true 时有效。OnConfirmType-
onFocus获得焦点时的回调,范围选择时不推荐使用。e 为输入框的 focus 事件,或聚焦范围起始的触发器点击、按键事件;rangeType 只在范围输入框聚焦时有值。Type(e: FocusEvent | MouseEvent | KeyboardEvent, rangeType?: RangeInput | false) => void-
onOpenChange面板显示或隐藏状态切换时的回调,入参为面板是否展开。Type(status: boolean) => void-
onPanelChange面板的年份或日期切换时的回调。OnPanelChangeType-
onPresetClick点击快捷选择按钮时的回调。Type(item: PresetType, e: MouseEvent) => void-
open面板显示或隐藏的受控属性,配合 onOpenChange 使用。boolean-
placeholder输入框的提示文字,范围类型可传数组。string | string[]-
position浮层位置,可选值与 Popover 的 position 相同。Position-
prefix输入框的前缀内容,传入 JSX 元素。JSX.Element-
prefixCls根元素与面板的类名前缀,一般无需修改。string"semi-datepicker"
presetPosition快捷选择面板的位置,可选值:left、right、top、bottom。PresetPosition"bottom"
presets日期时间快捷选择。start 与 end 可以是函数,函数每次打开面板时求值。PresetsType-
preventScroll指示浏览器是否应滚动文档以显示新聚焦的元素,作用于组件内的 focus 方法。boolean-
rangeSeparator范围类型输入框的日期分隔符,字符串解析同样使用它。string" ~ "
rangeSeparatorNode范围类型输入框分隔符的渲染节点,仅影响界面展示,字符串解析仍使用 rangeSeparator。JSX.Element-
ref根元素,携带 open、close、focus、blur 方法。TypeRef<DatePickerElement>-
renderDate自定义日期的显示内容,入参为日(数字)与完整日期字符串,返回 JSX 元素。Type(dayNumber?: number, fullDate?: string) => JSX.Element-
renderFullDate自定义整个日期格子的渲染内容,入参为日(数字)、完整日期字符串与日期状态。Type(dayNumber?: number, fullDate?: string, dayStatus?: DayStatusType) => JSX.Element-
rightSlot渲染右侧额外区域,传入 JSX 元素。JSX.Element-
showClear是否显示清除按钮。boolean-
size输入框的尺寸,可选值:small、default、large。InputSize"default"
spacing浮层与触发器之间的距离。number-
startDateOffsettype 为 dateRange 时,设置单击选择范围的开始日期。DateOffsetType-
startYear年份滚轮的开始年,默认为当前年前 100 年。number-
stopPropagation是否阻止弹出层上的点击事件冒泡。boolean | stringtrue
style根元素的样式,可传对象(键为 kebab-case)或字符串。JSX.CSSProperties | string-
syncSwitchMonth范围选择时,两个面板是否同步切换月份。booleanfalse
timePickerOpts传给时间面板的参数:use12Hours、hourStep、minuteStep、secondStep、defaultIsAM、scrollItemProps,含义见 TimePicker 的 API。格式、值和 onChange 由面板设置。DatePickerTimePickerOpts-
timeZone时区,值与面板日期按该时区解释和展示。字符串为 IANA 时区名,如 Asia/Shanghai;数字会原样传给 date-fns-tz 的 utcToZonedTime。string | number-
topSlot渲染顶部额外区域,传入 JSX 元素。JSX.Element-
triggerRender自定义触发器的渲染函数,只调用一次。入参为触发器属性,其中每个键都是响应式的,需在返回的 JSX 中读取。Type(props: TriggerRenderProps) => JSX.Element-
type类型,可选值:date、dateRange、dateTime、dateTimeRange、month、monthRange、year。Type"date"
validateStatus校验状态,仅影响展示样式,success 与 default 样式相同。ValidateStatus-
value受控的值。ValueType | null-
weekStartsOn以周几作为每周第一天,0 代表周日,1 代表周一,以此类推。WeekStartNumber0
yearAndMonthOpts透传给年月选择器的其他参数。list、onSelect、selectedIndex 与 type 由面板设置,不接受传入。YearAndMonthOpts-

Methods

方法说明类型
blur使输入框失焦。Type() => void
close关闭面板。受控的 open 优先,受控时 close 不改变面板的可见性。Type() => void
focus聚焦输入框。范围类型默认聚焦开始框,传入 'rangeEnd' 时聚焦结束框;开启 insetInput 且面板打开时聚焦面板内的输入框。Type(focusType?: RangeInput) => void
open展开面板。受控的 open 优先,受控时 open 不改变面板的可见性。Type() => void

class、style、ref 与未声明的原生属性和事件(如 id、title、data-*、aria-label、onClick)落在根元素上。aria-labelledby、aria-describedby、aria-errormessage、aria-invalid、aria-required 的落点:

  • 单输入框:都落在输入框上
  • 范围类型:根元素为 role="group",aria-labelledby 落在根元素上,aria-describedby、aria-errormessage、aria-invalid、aria-required 落在两个输入框上
  • triggerRender 渲染的内容没有可聚焦元素:aria-labelledby、aria-describedby、aria-errormessage、aria-invalid 落在 role 为 button 的外层,aria-required 不转发
  • triggerRender 渲染的内容自带可聚焦元素:都不转发,在渲染内容上自行设置

Methods

通过 ref 得到的根元素携带 open()、close()、focus(focusType?) 和 blur() 方法,说明见 API 参考中的 Methods 表。focus 聚焦输入框,范围类型默认聚焦开始框,传入 'rangeEnd' 时聚焦结束框;开启 insetInput 时聚焦面板内的输入框。

代码
import { Button, DatePicker, Space, type DatePickerElement } from '@fibrous/semi-ui-solid';

export default function DatePickerDemo() {
    let ref: DatePickerElement | undefined;

    const handleClickOutside = () => {
        console.log('click outside');
    };

    return (
        <Space vertical align="start">
            <Space>
                <Button onClick={() => ref?.open()}>open</Button>
                <Button onClick={() => ref?.close()}>close</Button>
                <Button onClick={() => ref?.focus()}>focus</Button>
                <Button onClick={() => ref?.blur()}>blur</Button>
            </Space>
            <div>
                <DatePicker type="dateTime" ref={(node) => (ref = node)} onClickOutSide={handleClickOutside} />
            </div>
        </Space>
    );
}

类型定义

type DatePickerBaseValueType = string | number | Date;
type DatePickerValueType = DatePickerBaseValueType | DatePickerBaseValueType[];
type DatePickerDayStatusType = {
    isToday?: boolean;
    isSelected?: boolean;
    isDisabled?: boolean;
    isSelectedStart?: boolean;
    isSelectedEnd?: boolean;
    isInRange?: boolean;
    isHover?: boolean;
    isOffsetRangeStart?: boolean;
    isOffsetRangeEnd?: boolean;
    isHoverInOffsetRange?: boolean;
};
type DatePickerDisabledDateOptions = {
    rangeStart?: string;
    rangeEnd?: string;
    rangeInputFocus?: 'rangeStart' | 'rangeEnd' | false;
};
type DatePickerDisabledDateType = (date: Date, options?: DatePickerDisabledDateOptions) => boolean;
type DatePickerPresetType = {
    start?: DatePickerBaseValueType | null | (() => DatePickerBaseValueType);
    end?: DatePickerBaseValueType | null | (() => DatePickerBaseValueType);
    text?: string;
};
type DatePickerPresetsType = Array<DatePickerPresetType | (() => DatePickerPresetType)>;
interface DatePickerTriggerRenderProps extends DateInputProps {
    componentProps: Omit<DatePickerProps, 'ref'>;
}
interface DatePickerHandle {
    open: () => void;
    close: () => void;
    focus: (focusType?: 'rangeStart' | 'rangeEnd') => void;
    blur: () => void;
}
type DatePickerElement = HTMLDivElement & DatePickerHandle;

Accessibility

ARIA

  • 输入框的 role 为 combobox,带 aria-haspopup="dialog"、随面板开关变化的 aria-expanded,aria-controls 指向面板;范围选择的两个输入框都是如此
  • 单输入框未选中日期时 aria-label 为 Choose date,选中日期时为 Change date(传入 aria-labelledby 时以它为准)
  • 自定义触发器(React 的 triggerRender,Vue 的 #trigger 插槽)渲染的内容没有可聚焦元素时,外层是 role 为 button 的焦点目标,名称同上
  • 日期面板中月的 role 为 grid,以面板顶部的年月标题命名,周的 role 设置为 row,日期格子设置为 gridcell
  • 年、月滚动列是 role 为 listbox 的列表,名称为「年」「月」
  • 日期和时间禁用时对应选项的 aria-disabled 为 true
  • 多选或范围选择时,月的 aria-multiselectable 为 true,选中时日期格子的 aria-selected 为 true
  • 面板中一些装饰作用的 icon,它们的 aria-hidden 为 true

键盘和焦点

  • 输入框聚焦时按 下箭头 打开面板;面板打开后再按 下箭头,焦点移入面板
  • 日期网格是一个 Tab 停靠点,方向键、Home、End、PageUp、PageDown(加 Shift 按年)移动当前日期,Enter 或 空格 选中
  • dateTime 面板底部的日期、时间切换是按钮,Enter 或 空格 切换
  • 范围选择有值时,Tab 可以到达结束输入框之后的清除按钮,Enter 或 空格 清空
  • 按 Esc 关闭面板;焦点在面板内时回到输入框,使用自定义触发器时回到该触发器
  • 自定义触发器渲染的内容没有可聚焦元素时,外层可以用 Tab 到达,Enter、空格 或 下箭头 打开面板

文案规范

  • 日期选择器建议搭配标签使用
  • 使用简洁的标签来表明日期选择所指的内容
  • 日期选择器中日期格式请参考日期与时间的规范

设计变量

下表是组件内部的 Sass 变量,不能覆写。定制样式请覆写 --semi-* CSS 变量(见 Design Token 页),或写不分层的 CSS 规则。
Sass 变量值用法
$width-datepicker_day36px日期格子及星期标题尺寸
$width-datepicker_day_main32px日期格子内容尺寸
$width-datepicker_month$width-datepicker_day * 7日期视图单月面板宽度
$width-datepicker_nav32px顶部导航栏高度
$height-datepicker_switch54px日期时间切换高度
$height-datepicker_timeType_yamcalc(100% - 54px)时间面板高度
$height-datepicker_timeType_tpkcalc(100% - 54px)时间面板高度
$height-datepicker_panel_yam_scrolllist266px年月选择列表滚动区域高度
$width-datepicker_monthPanel_max284px年月选择器最大宽度
$width-datepicker_monthRangePanel_max384px年月选择器最大宽度
$height-datepicker_timepicker_header_min24px年月选择面板顶部导航栏最小高度
$width-datepicker_navigation_button_min32px顶部导航栏按钮最小宽度
$height-datepicker_yamShowing_min378px日期时间选择器菜单最小高度
$width-datepicker_yamShowing_min284px选择器菜单最小宽度
$height-datepicker_dateType_yamShowing_min325px日期选择器菜单最小高度
$width-datepicker_panel_yam_scrolllist_li_min64px年月、时间滚动菜单项最小高度
$width-datepicker_presetPanel_left_and_right200px左右方位快捷选择面板宽度
$height-datepicker_presetPanel_top_and_bottom_max100px上下方位快捷选择面板最大高度
$width-datepicker_presetPanel_scroll_bar15px快捷选择面板scrollbar宽度
$width-datepicker-border$border-thickness-control年月选择面板顶部导航栏底部分割线宽度
$width-datepicker_yam_header-borderRadiusvar(--semi-border-radius-medium)年月选择面板顶部导航栏圆角
$width-datepicker_day_main-borderRadiusvar(--semi-border-radius-small)日期格子圆角
$width-datepicker_slot-border1px日期星期分割线宽度
$width-datepicker_range_input-border$border-thickness-control-focus
$width-datepicker_day_main-border1px
$height-datepicker_timeType_insetInput_yam100%时间面板高度 - 内嵌输入框
$height-datepicker_timeType_insetInput_tpk100%时间面板高度 - 内嵌输入框
$width-datepicker_insetInput_date_type_wrapper284px日期类型内嵌输入框宽度
$width-datepicker_insetInput_date_range_type_wrapper$width-datepicker_insetInput_date_type_wrapper * 2范围选择内嵌输入框宽度
$width-datepicker_insetInput_month_type_wrapper165px月份类型内嵌输入框宽度
$width-datepicker_insetInput_month_range_type_wrapper331px年月范围类型内嵌输入框宽度
$height-datepicker_insetInput_separator32px
$height-datepicker_month_grid_yearType_insetInput317px
$height-datepicker_month_grid_timeType_insetInput317px
$width-datepicker_range_trigger-border0px触发器边框宽度
$spacing-datepicker_day-marginX($width-datepicker_day - $width-datepicker_day_main) * 0.5日期格子水平外边距
$spacing-datepicker_yam_header-paddingX$spacing-base年月选择面板顶部导航栏水平内边距
$spacing-datepicker_yam_header-paddingY$spacing-base-tight年月选择面板顶部导航栏垂直内边距
$spacing-datepicker_scrolllist_header-padding$spacing-base时间选择 header 内边距
$spacing-datepicker_scrolllist_body-padding0时间选择滚动菜单内边距
$spacing-datepicker_footer-paddingTop10px确认选择 footer 顶部内边距
$spacing-datepicker_footer-paddingBottom10px确认选择 footer 底部内边距
$spacing-datepicker_footer-paddingRight8px确认选择 footer 右侧内边距
$spacing-datepicker_footer_cancel_button-marginRight12px确认选择 footer 取消按钮右外边距
$spacing-datepicker_footer_confirm_button-marginRight8px确认选择 footer 确认按钮右外边距
$spacing-datepicker_navigation-paddingY$spacing-base-tight年月切换 header 垂直内边距
$spacing-datepicker_navigation-paddingX$spacing-base年月切换 header 水平内边距
$spacing-datepicker_month-padding$spacing-base
$spacing-datepicker_switch_datetime-paddingTop$spacing-base日期时间切换顶部内边距
$spacing-datepicker_switch_datetime-paddingBottom$spacing-base日期时间切换底部内边距
$spacing-datepicker_switch_text-paddingLeft$spacing-tight日期时间切换左侧内边距
$spacing-datepicker_quick_control_header-paddingTop18px快捷预设面板标题区域上内边距
$spacing-datepicker_quick_control_top_and_bottom_content-paddingX$spacing-base-loose上下方位快捷操作面板, 左右内边距,默认20px
$spacing-datepicker_quick_control_content-paddingX12px快捷面板内容,左右内边距
$spacing-datepicker_quick_control_content-marginTop14px快捷面板内容,上边距
$spacing-datepicker_quick_control_item-margin$spacing-tight快捷操作面板按钮间距
$spacing-datepicker_range_input-paddingX8px
$spacing-datepicker_range_input_inputWrapper_input-paddingY2px
$spacing-datepicker_range_input_inputWrapper_input-paddingX4px
$spacing-datepicker_range_input_prefix-paddingLeft12px
$spacing-datepicker_range_input_prefix-paddingRight8px
$spacing-datepicker_range_input_suffix-paddingLeft8px
$spacing-datepicker_range_input_suffix-paddingRight12px
$spacing-datepicker_range_input_clearbtn-paddingLeft8px
$spacing-datepicker_range_input_clearbtn-paddingRight12px
$spacing-datepicker_navigation_insetInput-paddingY8px年月切换 header 垂直内边距 - 内嵌输入框
$spacing-datepicker_insetInput_wrapper-margin8px
$spacing-datepicker_insetInput_wrapper-paddingY12px
$spacing-datepicker_insetInput_wrapper-paddingX16px
$spacing-datepicker_insetInput_wrapper-paddingBottom0
$spacing-datepicker_insetInput_separator-paddingY0
$spacing-datepicker_insetInput_separator-paddingX4px
$color-datepicker_header-bg-defaultvar(--semi-color-bg-3)日期选择器 header 背景颜色
$color-datepicker_list-bg-defaultvar(--semi-color-bg-3)日期选择器滚动列表背景颜色
$color-datepicker_border-bg-defaultvar(--semi-color-border)日期选择器描边颜色
$color-datepicker_footer-bg-defaultvar(--semi-color-fill-0)日期选择器确认选择 footer 背景颜色
$color-datepicker_quick-bg-defaulttransparent日期选择器快捷操作背景颜色
$color-datepicker_quick_button-text-defaultvar(--semi-color-primary)日期选择器快捷操作按钮文字颜色
$color-datepicker_day-text-defaultvar(--semi-color-text-2)星期标题及日期时间切换按钮文字颜色 - 默认
$color-datepicker_day-text-activevar(--semi-color-text-0)日期时间切换文字颜色 - 选中
$color-datepicker_date-text-defaultvar(--semi-color-text-0)日期格子文字颜色 - 默认
$color-datepicker_date-bg-defaultvar(--semi-color-fill-0)日期格子背景颜色 - 默认
$color-datepicker_date-bg-hovervar(--semi-color-fill-0)日期格子背景颜色 - 悬浮
$color-datepicker_date-bg-activevar(--semi-color-fill-1)日期格子背景颜色 - 按下
$color-datepicker_date_selected-text-defaultvar(--semi-color-white)日期格子文字颜色 - 选中
$color-datepicker_date_selected-bg-defaultvar(--semi-color-primary)日期格子背景颜色 - 选中
$color-datepicker_date_disabled-text-defaultvar(--semi-color-disabled-text)禁用日期格子文字颜色
$color-datepicker_date_disabled-bg-defaultvar(--semi-color-disabled-fill)禁用日期格子背景颜色
$color-datepicker_date_today-text-defaultvar(--semi-color-primary)今日文字颜色
$color-datepicker_date_today_disabled-text-defaultvar(--semi-color-primary-disabled)今日文字颜色 - 禁用
$color-datepicker_date_inHover-bg-defaultvar(--semi-color-primary-light-default)范围选择日期格子颜色
$color-datepicker_date_inRangeHover-bg-defaultvar(--semi-color-fill-0)范围选择时悬停路径内的日期背景色
$color-datepicker_date_hoverDay-bg-defaultvar(--semi-color-fill-1)范围选择时日期格子背景色 - 悬停
$color-datepicker_date_selectedRange-bg-hovervar(--semi-color-primary-light-hover)范围选择日期格子颜色 - 悬浮
$color-datepicker_date_hoverday_range-bg-defaultvar(--semi-color-primary-light-active)
$color-datepicker_date_hoverday_around_single_selected-bg-defaultvar(--semi-color-primary-light-active)
$color-datepicker_nav_monthIcon-text-defaultvar(--semi-color-text-0)顶部导航栏年月文字颜色 - 默认
$color-datepicker_navIcon-text-defaultvar(--semi-color-text-2)日期选择器 header 左右箭头颜色
$color-datepicker_input_primary-text-defaultvar(--semi-color-primary)
$color-datepicker_range_input-text-defaultvar(--semi-color-text-2)
$color-datepicker_range_input-bg-defaultvar(--semi-color-fill-0)
$color-datepicker_range_input-bg-hovervar(--semi-color-fill-1)
$color-datepicker_range_input-border-defaulttransparent
$color-datepicker_range_input-border-activevar(--semi-color-focus-border)
$color-datepicker_range_input_warning-border-activevar(--semi-color-warning)
$color-datepicker_range_input_warning-bg-activevar(--semi-color-warning-light-hover)
$color-datepicker_range_input_warning-bg-defaultvar(--semi-color-warning-light-default)
$color-datepicker_range_input_warning-bg-hovervar(--semi-color-warning-light-hover)
$color-datepicker_range_input_warning-border-defaultvar(--semi-color-warning-light-default)
$color-datepicker_range_input_error-border-defaultvar(--semi-color-danger-light-default)
$color-datepicker_range_input_error-bg-hovervar(--semi-color-danger-light-hover)
$color-datepicker_range_input_error-border-activevar(--semi-color-danger)
$color-datepicker_range_input_error-bg-activevar(--semi-color-danger-light-hover)
$color-datepicker_range_input_disabled-text-defaultvar(--semi-color-disabled-text)
$color-datepicker_range_input_disabled-bg-defaultvar(--semi-color-disabled-fill)
$color-datepicker_range_input_disabled-bg-hovervar(--semi-color-disabled-fill)
$color-datepicker_range_input_clearbtn-icon-hovervar(--semi-color-primary-hover)
$color-datepicker_range_input_inputWrapper-border-defaulttransparent
$color-datepicker_range_input_inputWrapper-bg-defaulttransparent
$color-datepicker_range_input_inputWrapper-bg-focusvar(--semi-color-fill-1)
$color-datepicker_range_input_separator-text-activevar(--semi-color-text-0)
$color-datepicker_day_main-bordervar(--semi-color-primary-active)
$color-datepicker_insetInput_separatorvar(--semi-color-text-3)
$color-datepicker_range_trigger-bordertransparent范围日期选择模式触发器边框颜色
$color-datepicker_range_trigger-border-hovertransparent范围日期选择模式触发器边框颜色 - 悬浮
$color-datepicker_range_trigger-border-activetransparent范围日期选择模式触发器边框颜色 - 激活
$color-datepicker_range_trigger-border-focustransparent范围日期选择模式触发器边框颜色 - 聚焦
$font-datepicker_range_input_prefix_suffix_clearbtn-fontWeight600
$font-datepicker_preset_header-fontWeight600
$font-datepicker_range_input_prefix_suffix_clearbtn-fontSize14px
$font-datepicker_range_input_prefix_suffix_clearbtn-lineHeight20px
$font-datepicker_range_input_large-fontSize16px
$spacing-datepicker_month_compact-padding10px
$width-datepicker_day_compact28px
$width-datepicker_day_main_compact24px
$width-datepicker_day_compact-borderRadius4px
$width-datepicker_month_compact$width-datepicker_day_compact * 7 + $spacing-datepicker_month_compact-padding * 2
$width-datepicker_nav_compact24px
$width-datepicker_panel_compact216px
$height-datepicker_switch_compact32px
$height-datepicker_tpk_compact256px
$height-datepicker_yam_panel_compact256px
$height-datepicker_yam_li_compact32px
$height-datepicker_yam_panel_header_compact48px
$radius-datepicker_range_input_inputWrappervar(--semi-border-radius-small)
$height-datepicker_range_input-default32px
$height-datepicker_range_input-small24px
$height-datepicker_range_input-large40px
$width-datepicker_insetInput_date_type_wrapper_compact216px
$width-datepicker_insetInput_date_range_type_wrapper_compact$width-datepicker_insetInput_date_type_wrapper_compact * 2
$width-datepicker_insetInput_month_type_wrapper_compact195px
$height-datepicker_insetInput_tpk_compact100%
$height-datepicker_timeType_insetInput_yam_compact100%
$height-datepicker_insetInput_wrapper_compact28px
$lineHeight-datepicker_compact20px
$lineHeight-datepicker_weekday_item_compact28px
$height-datepicker_insetInput_compact26px
$fontSize-datepicker_insetInput_compact-fontSize12px
$spacing-datepicker_switch_compact-padding6px
$spacing-datepicker_day_compact-margin($width-datepicker_day_compact - $width-datepicker_day_main_compact) * 0.5
$spacing-datepicker_weeks_compact-padding10px
$spacing-datepicker_weeks_compact-paddingTop$spacing-tight - 2px
$spacing-datepicker_weekday_compact-paddingLeft10px
$spacing-datepicker_weekday_compact-paddingRight10px
$spacing-datepicker_weekday_compact-paddingBottom$spacing-tight
$spacing-datepicker_nav_compact-padding12px
$spacing-datepicker_yam_panel_header_compact-padding12px
$spacing-datepicker_footer_compact-paddintTop10px
$spacing-datepicker_footer_compact-paddintBottom10px
$spacing-datepicker_footer_compact-paddintRight8px
$spacing-datepicker_scrolllist_shade_pre_compact-marginTop-17px
$spacing-datepicker_scrolllist_shade_post_compact-marginTop17px
$spacing-datepicker_insetInput_wrapper_compact-margin4px
$spacing-datepicker_insetInput_wrapper_compact-paddingY8px
$spacing-datepicker_insetInput_wrapper_compact-paddingX8px
$spacing-datepicker_insetInput_wrapper_compact-paddingBottom0
$spacing-datepicker_insetInput_wrapper_rangeType_compact-paddingTop0
$spacing-datepicker_quick_control_header_compact-paddingTop16pxcompact, 快捷面板标题,上内边距
$spacing-datepicker_quick_control_content_compact-marginTop12pxcompact, 快捷面板内容,上边距
$spacing-datepicker_quick_control_left_and_right_content_compact-paddingX12pxcompact,左右方位,快捷面板内容,左右内边距
$spacing-datepicker_quick_control_top_and_bottom_content_compact-paddingX10pxcompact,上下方位,快捷面板内容,左右内边距
$radius-datepicker_range_inputvar(--semi-border-radius-small)
$transition-datepicker_range_inputbackground-color 0.16s ease-in-out
$width-datepicker_presetPanel_left_and_right_content$width-datepicker_presetPanel_left_and_right - $spacing-datepicker_quick_control_content-paddingX * 2左右方位快捷选择面板,内容宽度
$width-datepicker_presetPanel_top_and_bottom_content_date$width-datepicker_day * 7 + $spacing-datepicker_month-padding * 2 - $spacing-datepicker_quick_control_top_and_bottom_content-paddingX * 2date/dateTime下, 上下方位快捷选择面板内容宽度, 默认(284 - 40)px
$width-datepicker_presetPanel_top_and_bottom_content_range($width-datepicker_day * 7 + $spacing-datepicker_month-padding * 2) * 2 - $spacing-datepicker_quick_control_top_and_bottom_content-paddingX * 2dateRange/dateTimeRange下, 上下方位快捷选择内容面板宽度,默认528px
$width-datepicker_presetPanel_top_and_bottom_content_month165px - $spacing-datepicker_quick_control_top_and_bottom_content-paddingX * 2month下,上下方位快捷选择内容面板宽度, 默认154px
$height-datepicker_month_max$width-datepicker_day * 7 + 1px年月面板最大高度, 最多6 + 1行,再加上一个border宽度, 默认253px
$height-datepicker_month_max_compact$width-datepicker_day_compact * 7 + $spacing-datepicker_weeks_compact-paddingTop + $spacing-datepicker_weeks_compact-padding + $spacing-datepicker_weekday_compact-paddingBottom年月面板最大高度, 最多6 + 1行,再加上padding,默认220px
$height-datepicker_date_panel$height-datepicker_month_max + $spacing-datepicker_month-padding + $width-datepicker_nav + $spacing-datepicker_navigation-paddingY * 2date/dateRange,面板渲染最大高度,默认325px
$height-datepicker_date_time_panel$height-datepicker_date_panel + $height-datepicker_switch - 1pxdateTime/dateTImeRange 面板渲染最大高度. 默认378px
$height-datepicker_presetPanel_left_and_right_except_content20px + $spacing-datepicker_quick_control_header-paddingTop + $spacing-datepicker_quick_control_content-marginTop除去content以外的高度,默认52px
$width-datepicker_presetPanel_top_and_bottom_content_date_compact$width-datepicker_day_compact * 7 + $spacing-datepicker_weeks_compact-padding * 2 - $spacing-datepicker_quick_control_top_and_bottom_content_compact-paddingX * 2date/dateTime下, 上下方位快捷选择面板内容宽度, 默认(216 - 20)px
$width-datepicker_presetPanel_top_and_bottom_content_range_compact($width-datepicker_day_compact * 7 + $spacing-datepicker_weeks_compact-padding * 2) * 2 - $spacing-datepicker_quick_control_top_and_bottom_content_compact-paddingX * 2dateRange/dateTimeRange下, 上下方位快捷选择内容面板宽度,默认412px
$width-datepicker_presetPanel_top_and_bottom_content_month_compact165px - $spacing-datepicker_quick_control_top_and_bottom_content_compact-paddingX * 2month下,上下方位快捷选择内容面板宽度, 默认174px
$height-datepicker_date_panel_compact$height-datepicker_month_max_compact + $width-datepicker_nav_compact + $spacing-datepicker_nav_compact-paddingcompact,date/dateRange,面板渲染最大高度,默认256px
$height-datepicker_date_time_panel_compact$height-datepicker_date_panel_compact + $height-datepicker_switch_compactcompact,dateTime/dateTImeRange,面板渲染最大高度,默认288px
$height-datepicker_presetPanel_left_and_right_except_content_compact20px + $spacing-datepicker_quick_control_header_compact-paddingTop + $spacing-datepicker_quick_control_content_compact-marginTopcompact,除去content以外的高度,默认48px
$width-datepicker_presetPanel_left_and_right_two_col_button($width-datepicker_presetPanel_left_and_right_content - $spacing-datepicker_quick_control_item-margin) * 0.5左右方位快捷选择面板,固定两列,按钮宽度
$width-datepicker_presetPanel_top_and_bottom_three_col_button($width-datepicker_presetPanel_top_and_bottom_content_date - $spacing-datepicker_quick_control_item-margin * 2) * 0.333上下方位快捷选择面板,固定三列,按钮宽度
$width-datepicker_presetPanel_top_and_bottom_five_col_button($width-datepicker_presetPanel_top_and_bottom_content_range - $spacing-datepicker_quick_control_item-margin * 4) * 0.2上下方位快捷选择面板,固定五列,按钮宽度
$width-datepicker_presetPanel_top_and_bottom_two_col_button($width-datepicker_presetPanel_top_and_bottom_content_month - $spacing-datepicker_quick_control_item-margin) * 0.5上下方位快捷选择面板,固定两列,按钮宽度
$width-datepicker_presetPanel_top_and_bottom_three_col_button_compact($width-datepicker_presetPanel_top_and_bottom_content_date_compact - $spacing-datepicker_quick_control_item-margin * 2) * 0.333上下方位快捷选择面板,固定三列,按钮宽度
$width-datepicker_presetPanel_top_and_bottom_five_col_button_compact($width-datepicker_presetPanel_top_and_bottom_content_range_compact - $spacing-datepicker_quick_control_item-margin * 4) * 0.2上下方位快捷选择面板,固定五列,按钮宽度
$width-datepicker_presetPanel_top_and_bottom_two_col_button_compact($width-datepicker_presetPanel_top_and_bottom_content_month_compact - $spacing-datepicker_quick_control_item-margin) * 0.5上下方位快捷选择面板,固定两列,按钮宽度
$height-datepicker_inset_input32px + $spacing-datepicker_insetInput_wrapper-paddingY默认尺寸,insetInput高度
$height-datepicker_preset_panel_inset_input$height-datepicker_month_max + $spacing-datepicker_month-padding + $width-datepicker_nav + $spacing-datepicker_navigation_insetInput-paddingY * 2 + $height-datepicker_inset_inputinset_input下,非month面板渲染最大高度,默认361px
$height-datepicker_inset_input_compact28px + $spacing-datepicker_insetInput_wrapper_compact-paddingYcompact,insetInput高度, 默认36px
$height-datepicker_preset_panel_inset_input_compact$height-datepicker_month_max_compact + $width-datepicker_nav_compact + $spacing-datepicker_insetInput_wrapper_compact-paddingY * 2 + $height-datepicker_inset_input_compactinset_input下,非month面板渲染最大高度,默认296px

日期时间格式

semi-ui 组件库中采用 date-fns v4 作为日期时间引擎,格式化 token 含义如下:

  • "y" :年
  • "M" :月
  • "d" :日
  • "H" :小时
  • "m" :分钟
  • "s" :秒

下面以 new Date('2023-12-09 08:08:00') 和 [new Date('2023-12-09 08:08:00'), new Date('2023-12-10 10:08:00')] 为例说明不同 format 值对展示值的影响:

类型format展示值
dateyyyy-MM-dd2023-12-09
dateTimeyyyy-MM-dd HH:mm:ss2023-12-09 08:08:00
monthyyyy-MM2023-12
yearyyyy2023
dateRangeyyyy-MM-dd2023-12-09 ~ 2023-12-10
dateTimeRangeyyyy-MM-dd HH:mm:ss2023-12-09 08:08 ~ 2023-12-10 10:08

多个日期或时间默认使用 "," (英文逗号)分隔。

更多 token 可以查阅 date-fns 官网

FAQ

  • 日期时间选择器,时分秒选择时想要无限滚动效果如何实现?
    版本V2.22.0开始,我们将 TimePicker 内的 ScrollItem 的默认模式从 wheel 变更为了 normal, 若想应用回无限滚动的效果,可以通过 timePickerOpts 中的特定开关控制该行为。

    即 timePickerOpts={{ scrollItemProps: { mode: 'wheel', cycled: true } }}。

  • 如何设置面板打开时默认显示的时间?
    可通过 defaultPickerValue 属性。

  • 日期时间选择、范围日期选择,输入部分日期后,面板没有回显日期?

    输入框需要输入完整后才会回显到面板上。比如,日期时间选择,完整要求日期和时间都已输入。范围日期选择,完整要求开始日期和结束日期都已输入。

  • 日期时间选择面板底部的展示的时间是什么?

    未选择时间时,它为 defaultPickerValue 中时间的值,如果没有设置则是面板打开时的时间。选择时间后,它为已选择的时间。

    由于设计上它有隐含两层含义,可能会导致歧义,建议使用内嵌样式,通过 insetInput 打开。使用前推荐阅读相关 文档。

    日期时间选择面板底部的时间