import React, { useState, useRef } from 'react'; import { addDays, addWeeks, addMonths, isBefore, startOfMonth, endOfMonth, parseISO, startOfWeek, endOfWeek, } from 'date-fns'; import { Space, ConfigProvider, InputGroup, InputNumber, Form, withField, Button } from '../../index'; // stores import NeedConfirmDemo from './NeedConfirm'; import RenderDate from './RenderDate'; import RenderFullDate from './RenderFullDate'; import DateOffset from './DateOffset'; import AllTypesDemo from './AllTypes'; import Callbacks from './Callbacks'; import DatePicker from '../index'; import ExceptionDemo from './ExceptionDemo'; import ControlledDemo from './ControlledDemo'; import DisabledDate from './DisabledDate'; import CustomTrigger from './CustomTrigger'; import OverPopover from './OverPopover'; import OnChangeWithDateFirst from './OnChangeWithDateFirst'; import Multiple from './Multiple'; import Autofocus from './Autofocus'; import CycledDatePicker from './Cycled'; import AutoSwitchDate from './AutoSwitchDate'; import TimepikcerOpts from './TimePickerOpts'; import Density from './Density'; import DatePickerSlot from './DatePickerSlot'; import DatePickerTimeZone from './DatePickerTimeZone'; import BetterRangePicker from './BetterRangePicker'; import SyncSwitchMonth from './SyncSwitchMonth'; export * from './v2'; export default { title: 'DatePicker', parameters: { chromatic: { disableSnapshot: true }, }, } export { ControlledDemo, NeedConfirmDemo, ExceptionDemo, AllTypesDemo, Callbacks, DisabledDate, CustomTrigger, OverPopover, OnChangeWithDateFirst, RenderDate, RenderFullDate, Autofocus, DateOffset, CycledDatePicker, AutoSwitchDate, TimepikcerOpts, Density, DatePickerSlot, DatePickerTimeZone, BetterRangePicker, SyncSwitchMonth, } const demoDiv = { marginTop: '20px', marginLeft: '20px', }; export const DatePickerDefault = () => (
datePicker施工现场 日期} onChange={(str, date) => console.log(str)} onOpenChange={status => console.log(status)} placeholder="请选择日期" />
datePicker默认显示
defaultValue: 2019-07-09
defaultValue: 1569888000000 console.log({ input, value })} />
defaultValue: new Date('2019-07-07') console.log(isOpen)} defaultOpen motion={false} />
); DatePickerDefault.parameters = { chromatic: { disableSnapshot: false, delay: 300 } }; export const DatePickerCallbacks = () => { const printArgs = (...args) => console.log(...args); return (
datePicker施工现场
defaultValue: new Date('2019-07-07')
defaultValue: 2019-07-09
defaultValue: 1569888000000 console.log(input, value)} />
); }; export const DatePickerMultiple = () => ; export const DateRangePicker = () => (
dateRangePicker

small dateRangePicker

large dateRangePicker

compact dateRangePicker

dateRangePicker with offset
startOfWeek(date, { weekStartsOn: 1 })} endDateOffset={date => endOfWeek(date, { weekStartsOn: 1 })} />
defaultValue:07/01-08/02
); DateRangePicker.parameters = { chromatic: { disableSnapshot: false }, }; const presets = [ { text: 'Today', start: new Date(), end: new Date(), }, { text: 'Tomorrow', start: addDays(new Date(), 1), end: addDays(new Date(), 1), }, { text: 'Next Week', start: addWeeks(new Date(), 1), end: addWeeks(new Date(), 2), }, { text: 'Next Month', start: startOfMonth(addMonths(new Date(), 1)), end: endOfMonth(addMonths(new Date(), 1)), }, { text: 'Today', start: new Date(), end: new Date(), }, { text: 'Tomorrow', start: addDays(new Date(), 1), end: addDays(new Date(), 1), }, { text: 'Next Week', start: addWeeks(new Date(), 1), end: addWeeks(new Date(), 2), }, { text: 'Next Month', start: startOfMonth(addMonths(new Date(), 1)), end: endOfMonth(addMonths(new Date(), 1)), }, ]; export const DatePickerWithPresets = () => { const onPresetClick = (item, e) => { console.log('preset click', item, e); }; return (
带快捷选择的DatePicker console.log(...args)} /> ({ text: preset.text, start: preset.start, }))} onPresetClick={onPresetClick} onChange={(...args) => console.log(...args)} /> ({ text: preset.text, start: preset.start, }))} onPresetClick={onPresetClick} onChange={(...args) => console.log(...args)} /> ({ text: preset.text, start: preset.start, }))} onPresetClick={onPresetClick} onChange={(...args) => console.log(...args)} />
); }; function isDisabled(dayStr) { return isBefore(new Date(dayStr), new Date()); } export const DatePickerDisabledDate = () => (
不可选日期
); export const DateTimePicker = () => (
dateTimePicker console.log('onChange: ', ...args)} />
); export const DateTimeRangePicker = () => (
dateTimeRangePicker
dateTimeRangePicker
dateTimeRangePicker - multiple
); export const YearPicker = () => ( <>
Year Picker
Year Picker
); export const MonthPicker = () => { const Demo = () => { const [controlledValue, setControlledValue] = useState('2019-09'); const _setControlledValue = value => setControlledValue(value); return ( <>
MonthPicker
MonthPicker with presets
MonthPicker with disabledDate { const date = new Date(str); if (str.length <= 4) { return date.getFullYear() < 2015; } return date.getMonth() + 1 < 10; }} />
MonthPicker with presets
MonthPicker with controlledValue
); }; return ; }; export const PropTypesAndDefaultProps = () => (

{JSON.stringify(Object.keys(DatePicker.propTypes))}

{JSON.stringify(DatePicker.defaultProps)}

); export const InputReadOnly = () => ; export const DropdownClassNameDropdownStyle = () => (

fontSize: 16,dropdownClassName: 'my-datePicker'

console.log(dateString)} />
); export const CustomPlaceholder = () => ( ); CustomPlaceholder.parameters = { chromatic: { disableSnapshot: false }, }; export const FixNotifyChange = () => { function Demo() { const [tz, setTz] = useState(0); const [value, setVal] = useState(); const [value2, setVal2] = useState(); const [value3, setVal3] = useState(); const [value4, setVal4] = useState(); const withLog = fn => { return val => { console.log('notifyChange', val); fn(val); }; }; return ( ); } return ; }; export const SelectNotDisabledDateV126 = () => { const defaultValue = ['2021-08-06', '2021-08-15']; const disabledMonth = dateStr => { const date = new Date(dateStr); const month = date.getMonth(); if (month === 7) { return true; } return false; }; const disabledDate = dateStr => { const date = new Date(dateStr); const day = date.getDate(); if (day > 20 && day < 25) { return true; } return false; }; let props = { type: 'dateRange', motion: false, defaultValue, onChange: (...args) => console.log('changed', ...args), style: { width: 300 }, }; return ( <>

dateRange type + disabled rangeStart and select rangeEnd

date type + multiple select + given disabled defaultValue

); }; SelectNotDisabledDateV126.story = { name: 'select not disabled date(v1.26+)', }; const CustomDatePicker = props => { const { fieldRef, ...rest } = props; return ; }; const CustomFieldDatePicker = withField(CustomDatePicker); export const FixOnFocus = () => { function FocusDemo() { const [open1, setOpen1] = useState(false); const [open2, setOpen2] = useState(false); const [open3, setOpen3] = useState(false); const ref = useRef(); const ref2 = useRef(); const presets = [ { 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), }, ]; return ( <> { setOpen1(false); }} onFocus={() => { console.log('focus'); setOpen1(true); }} onBlur={() => { console.log('blur'); }} style={{ width: 300 }} />

{ console.log('click presets', ref); setOpen2(false); setTimeout(() => { ref.current.foundation.closePanel(); console.log(ref); }, 0); }} onFocus={() => { console.log('focus'); setOpen2(true); }} onBlur={() => { console.log('blur'); }} style={{ width: 500 }} ref={ref} />
{ console.log('click presets', ref2); setOpen3(false); setTimeout(() => { ref2.current && ref2.current.foundation.closePanel(); }, 0); }} onFocus={() => { console.log('focus'); setOpen3(true); }} onBlur={() => { console.log('blur'); }} style={{ width: 500 }} fieldRef={ref2} /> ); } return ; }; FixOnFocus.story = { name: 'fix onFocus', }; export const FixDisabledTimeCallback1418 = () => { function Demo() { const disabledTime2 = (date, panelType) => { console.log('disabledTime callback parameter: ', date, panelType); if (panelType === 'left') { return { disabledHours: () => [17, 18] }; } else { return { disabledHours: () => [12, 13, 14, 15, 16, 17, 18] }; } }; return ( <> fix disabledTime callback parameter bug ); } return ; }; FixDisabledTimeCallback1418.story = { name: 'fix disabledTime callback #1418', }; export const RangeSeparator = () => (
custom rangeSeparator
default rangeSeparator
); /** * 修复输入 '20221-12-20' 类似这种年份的日期会崩溃问题 * https://github.com/DouyinFE/semi-design/issues/422 * * 非法日期的来源 * - 用户输入 * - 受控传入 * @returns */ export const FixParseISOBug = () => (
); FixParseISOBug.storyName = '修复 parseISO bug'; FixParseISOBug.parameters = { chromatic: { disableSnapshot: false }, }; export const FixNeedConfirm = () => { const defaultDate = '2021-12-27 10:37:13'; const defaultDateRange = ['2021-12-27 10:37:13', '2022-01-28 10:37:13' ]; const props = { needConfirm: true, onConfirm: (...args) => { console.log('Confirmed: ', ...args); }, onChange: (...args) => { console.log('Changed: ', ...args); }, onCancel: (...args) => { console.log('Canceled: ', ...args); }, }; return (
dateTime + needConfirm + defaultValue
dateTime + needConfirm
dateTimeRange + needConfirm + defaultValue
dateTimeRange + needConfirm
) } FixNeedConfirm.storyName = '修复 needConfirm 取消后输入框显示错误'; /** * fix https://github.com/DouyinFE/semi-design/issues/388 */ export const FixPresetsClick = () => { const presets = [ { text: '清空', start: '', end: '', }, { text: 'Tomorrow', start: new Date(new Date().valueOf() + 1000 * 3600 * 24), end: new Date(new Date().valueOf() + 1000 * 3600 * 24), }, ]; const handleChange = v => { console.log('change', v); }; const handleConfirm = v => { console.log('confirm', v); } return (
); }; FixPresetsClick.storyName = '修复 presets 点击后不收起问题'; /** * fix https://github.com/DouyinFE/semi-design/issues/410 */ export const FixTriggerRenderClosePanel = () => { const [value, setValue] = useState([]); const handleChange = v => { console.log('change', v); setValue(v); }; const formatValue = (dates) => { const dateStrs = dates.map(v => String(v)); return dateStrs.join(' ~ '); }; const showClear = Array.isArray(value) && value.length > 1; return ( ( )} /> {showClear && ( )} ); }; FixTriggerRenderClosePanel.storyName = "fix triggerRender close bug" export const A11yKeyboardDemo = () => { const [value, setValue] = useState(new Date('2022-08-08 00:00')); const [rangeValue, setRangeValue] = useState([new Date('2022-08-08 00:00'), new Date('2022-08-09 12:00')]); const handleChange = v => { console.log('change', v); setValue(v); }; const handleRangeChange = v => { console.log('change', v); setRangeValue(v); }; return (
); }; A11yKeyboardDemo.storyName = "a11y keyboard demo"; /** * test with cypress */ export const NeedConfirmDelete = () => { return (
); }; NeedConfirmDelete.storyName = "cashedSelectedValue return to last selected when needConfirm & input invalid"; /** * test with cypress */ export const CashedSelectedValue = () => { return (
); }; CashedSelectedValue.storyName = "cashedSelectedValue";