| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165 |
- import React, { useState, useRef, useMemo, useCallback } from 'react';
- import {
- addDays,
- addWeeks,
- addMonths,
- isBefore,
- startOfMonth,
- endOfMonth,
- parseISO,
- startOfWeek,
- endOfWeek,
- } from 'date-fns';
- import { Space, ConfigProvider, InputGroup, InputNumber, Form, withField, Button, RadioGroup, Radio } 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';
- import { Checkbox } from '../../checkbox';
- import Typography from '../../typography/typography';
- import { IconClose, IconChevronDown } from '@douyinfe/semi-icons';
- import * as dateFns from 'date-fns';
- export {
- YearButton,
- PanelOpen,
- FixInputRangeFocus,
- InsetInput,
- InsetInputE2E,
- FixDefaultPickerValue,
- InputFormat,
- InputFormatDisabled,
- AutoFillTime,
- InputFormatConfirm,
- FixedTriggerRender,
- DisabledRange,
- FixDisabledMonth,
- FixRangePanelShift,
- InsetInputControlled,
- FeatInsetInputProps,
- FixMultiplePanelShift,
- FixTimeZone,
- FeatRefOpen,
- FeatRefFocus,
- FeatOnClickOutside,
- FeatRefClass,
- FixNeedConfirmInTabs,
- DynamicDisabledDate,
- FeatEtcGMT,
- FixDisabledDate
- } 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 = () => (
- <div style={{...demoDiv, height: '100vh'}}>
- <span>datePicker施工现场</span>
- <DatePicker
- insetLabel={<span>日期</span>}
- onChange={(str, date) => console.log(str)}
- onOpenChange={status => console.log(status)}
- placeholder="请选择日期"
- />
- <br />
- <span>datePicker默认显示</span>
- <DatePicker />
- <br />
- <span>defaultValue: 2019-07-09</span>
- <DatePicker defaultValue="2019-07-09" />
- <br />
- <span>defaultValue: 1569888000000</span>
- <DatePicker
- defaultValue={1569888000000}
- onChange={(input, value) => console.log({ input, value })}
- />
- <br />
- <span>defaultValue: new Date('2019-07-07')</span>
- <DatePicker
- defaultValue={new Date('2019-07-07')}
- onOpenChange={isOpen => console.log(isOpen)}
- defaultOpen
- motion={false}
- />
- </div>
- );
- DatePickerDefault.parameters = {
- chromatic: {
- disableSnapshot: false,
- delay: 300
- }
- };
- export const DatePickerCallbacks = () => {
- const printArgs = (...args) => console.log(...args);
- return (
- <div style={demoDiv}>
- <span>datePicker施工现场</span>
- <DatePicker onOpenChange={printArgs} />
- <br />
- <span>defaultValue: new Date('2019-07-07')</span>
- <DatePicker defaultValue={new Date('2019-07-07')} />
- <br />
- <span>defaultValue: 2019-07-09</span>
- <DatePicker defaultValue="2019-07-09" />
- <br />
- <span>defaultValue: 1569888000000</span>
- <DatePicker
- defaultValue={1569888000000}
- onChange={(input, value) => console.log(input, value)}
- />
- </div>
- );
- };
- export const DatePickerMultiple = () => <Multiple />;
- export const DateRangePicker = () => (
- <div style={demoDiv}>
- <div>dateRangePicker</div>
- <DatePicker type="dateRange" insetLabel="结束日期" prefix="test" validateStatus="error" />
- <br />
- <div>small dateRangePicker</div>
- <DatePicker type="dateRange" size="small" disabled prefix="test" />
- <br />
- <div>large dateRangePicker</div>
- <DatePicker type="dateRange" size="large" />
- <br />
- <div>compact dateRangePicker</div>
- <DatePicker type="dateRange" density="compact" validateStatus="warning" />
- <br />
- <div>dateRangePicker with offset</div>
- <DatePicker
- type="dateRange"
- startDateOffset={date => startOfWeek(date, { weekStartsOn: 1 })}
- endDateOffset={date => endOfWeek(date, { weekStartsOn: 1 })}
- />
- <br />
- <div>defaultValue:07/01-08/02</div>
- <DatePicker type="dateRange" defaultValue={[new Date('2019-07-01'), new Date('2019-08-02')]} />
- </div>
- );
- 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: 'Today After Tomorrow',
- start: addDays(new Date(), 2),
- end: addDays(new Date(), 2),
- },
- {
- 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: 'Next Bimonthly',
- start: startOfMonth(addMonths(new Date(), 1)),
- end: endOfMonth(addMonths(new Date(), 2)),
- },
- {
- text: 'Next Quarter',
- start: startOfMonth(addMonths(new Date(), 3)),
- end: endOfMonth(addMonths(new Date(), 3)),
- },
- ];
- export const DatePickerWithPresets = () => {
- const onPresetClick = (item, e) => {
- console.log('preset click', item, e);
- };
- const [presetPosition, setPresetPosition] = useState('right');
- const [insetInput, setInsetInput] = useState(false);
- const [presetArr, setPresetArr] = useState(presets);
- const BottomSlot = function(props) {
- const { style } = props;
- return (
- <div style={{ padding: '12px 20px', ...style }}>
- <div strong style={{ color: 'var(--semi-color-text-2)' }}>
- 定版前请阅读
- </div>
- <div link={{ href: 'https://semi.design/', target: '_blank' }}>发版须知</div>
- </div>
- );
- };
- return (
- <div style={demoDiv}>
- <span>带快捷选择的DatePicker</span>
- <br/>
- <br/>
- <RadioGroup onChange={e=>setPresetPosition(e.target.value)} value={presetPosition} aria-label="选择快捷选择面板位置" name="preset-radio-group">
- <Radio value={'left'}>left</Radio>
- <Radio value={'right'}>right</Radio>
- <Radio value={'top'}>top</Radio>
- <Radio value={'bottom'}>bottom</Radio>
- </RadioGroup>
- <Checkbox value={insetInput} onChange={e=>setInsetInput(e.target.checked)}>insetInput</Checkbox>
- <Checkbox value={presetArr} onChange={e=>setPresetArr(e.target.checked ? [...presets, ...presets, ...presets]:presets)}>more presets</Checkbox>
- <br/>
- <div>type="date"</div>
- <DatePicker
- type="date"
- presets={presetArr}
- insetInput={insetInput}
- presetPosition={presetPosition}
- onPresetClick={onPresetClick}
- onChange={(...args) => console.log(...args)}
- />
- <br/>
- <br/>
- <div>type="dateTime"</div>
- <DatePicker
- type="dateTime"
- insetInput={insetInput}
- needConfirm
- bottomSlot={<BottomSlot/>}
- presetPosition={presetPosition}
- presets={presetArr.map(preset => ({
- text: preset.text,
- start: preset.start,
- }))}
- onPresetClick={onPresetClick}
- onChange={(...args) => console.log(...args)}
- />
- <br/>
- <br/>
- <div>type="dateRange"</div>
- <DatePicker
- type="dateRange"
- presets={presetArr}
- insetInput={insetInput}
- presetPosition={presetPosition}
- onPresetClick={onPresetClick}
- onChange={(...args) => console.log(...args)}
- />
- <br/>
- <br/>
- <div>type="dateTimeRange"</div>
- <DatePicker
- type="dateTimeRange"
- presets={presetArr}
- insetInput={insetInput}
- presetPosition={presetPosition}
- onPresetClick={onPresetClick}
- onChange={(...args) => console.log(...args)}
- />
- <br/>
- <br/>
- <div>type="month"</div>
- <DatePicker
- type="month"
- insetInput={insetInput}
- presetPosition={presetPosition}
- presets={presetArr.map(preset => ({
- text: preset.text,
- start: preset.start,
- }))}
- onPresetClick={onPresetClick}
- onChange={(...args) => console.log(...args)}
- />
- {/* <br/>
- <br/>
- <div>type="monthRange"</div>
- <DatePicker
- type="monthRange"
- insetInput={insetInput}
- presetPosition={presetPosition}
- presets={presetArr.map(preset => ({
- text: preset.text,
- start: preset.start,
- }))}
- onPresetClick={onPresetClick}
- onChange={(...args) => console.log(...args)}
- /> */}
- <br/>
- <br/>
- <div>type="date" density="compact"</div>
- <DatePicker
- type="date"
- presets={presetArr}
- insetInput={insetInput}
- density="compact"
- presetPosition={presetPosition}
- onPresetClick={onPresetClick}
- onChange={(...args) => console.log(...args)}
- />
- <br/>
- <br/>
- <div>type="dateTime" density="compact"</div>
- <DatePicker
- type="dateTime"
- insetInput={insetInput}
- needConfirm
- density="compact"
- presetPosition={presetPosition}
- presets={presetArr.map(preset => ({
- text: preset.text,
- start: preset.start,
- }))}
- onPresetClick={onPresetClick}
- onChange={(...args) => console.log(...args)}
- />
- <br/>
- <br/>
- <div>type="dateRange" density="compact"</div>
- <DatePicker
- type="dateRange"
- presets={presetArr}
- density="compact"
- insetInput={insetInput}
- presetPosition={presetPosition}
- onPresetClick={onPresetClick}
- onChange={(...args) => console.log(...args)}
- />
- <br/>
- <br/>
- <div>type="dateTimeRange" density="compact"</div>
- <DatePicker
- type="dateTimeRange"
- density="compact"
- presets={presetArr}
- insetInput={insetInput}
- presetPosition={presetPosition}
- onPresetClick={onPresetClick}
- onChange={(...args) => console.log(...args)}
- />
- <br/>
- <br/>
- <div>type="month" density="compact"</div>
- <DatePicker
- type="month"
- insetInput={insetInput}
- presetPosition={presetPosition}
- presets={presetArr.map(preset => ({
- text: preset.text,
- start: preset.start,
- }))}
- density="compact"
- onPresetClick={onPresetClick}
- onChange={(...args) => console.log(...args)}
- />
- </div>
- );
- };
- function isDisabled(dayStr) {
- return isBefore(new Date(dayStr), new Date());
- }
- export const DatePickerDisabledDate = () => (
- <div style={demoDiv}>
- <span>不可选日期</span>
- <DatePicker type="dateRange" presets={presets} disabledDate={isDisabled} />
- </div>
- );
- export const DateTimePicker = () => (
- <div style={demoDiv}>
- <span>dateTimePicker</span>
- <DatePicker
- defaultPickerValue={parseISO('2020-02-20 20:00:00')}
- type="dateTime"
- onChange={(...args) => console.log('onChange: ', ...args)}
- />
- </div>
- );
- export const DateTimeRangePicker = () => (
- <div style={demoDiv}>
- <span>dateTimeRangePicker</span>
- <DatePicker type="dateTimeRange" defaultPickerValue={parseISO('2020-02-20 20:00:00')} />
- <br />
- <span>dateTimeRangePicker</span>
- <DatePicker type="dateTimeRange" presets={presets} />
- <br />
- <span>dateTimeRangePicker - multiple</span>
- <DatePicker type="dateTimeRange" multiple />
- <br />
- </div>
- );
- export const YearPicker = () => (
- <>
- <div>
- <span>Year Picker</span>
- <DatePicker type="dateTimeRange" />
- </div>
- <div>
- <span>Year Picker</span>
- <DatePicker type="dateTimeRange" presets={presets} />
- </div>
- </>
- );
- export const MonthPicker = () => {
- const Demo = () => {
- const [controlledValue, setControlledValue] = useState('2019-09');
- const _setControlledValue = value => setControlledValue(value);
- return (
- <>
- <div>
- <span>MonthPicker</span>
- <DatePicker type="month" />
- </div>
- <div>
- <span>MonthPicker with presets</span>
- <DatePicker type="month" presets={presets} />
- </div>
- <div>
- <span>MonthPicker with disabledDate</span>
- <DatePicker
- type="month"
- disabledDate={str => {
- const date = new Date(str);
- if (str.length <= 4) {
- return date.getFullYear() < 2015;
- }
- return date.getMonth() + 1 < 10;
- }}
- />
- </div>
- <div>
- <span>MonthPicker with presets</span>
- <DatePicker type="month" presets={presets} />
- </div>
- <div>
- <span>MonthPicker with controlledValue</span>
- <DatePicker type="month" value={controlledValue} onChange={_setControlledValue} />
- </div>
- </>
- );
- };
- return <Demo />;
- };
- export const MonthRangePicker = () => {
- const { Text } = Typography;
- const formatToken = 'yyyy-MM';
- const [controlledValue, setControlledValue] = useState(['2023-03', '2023-04']);
- const [triggerValue, setTriggerValue] = useState();
- const _setControlledValue = value => setControlledValue(value);
- const onChange = useCallback(date => {
- setTriggerValue(date);
- }, []);
- const onClear = useCallback(e => {
- e && e.stopPropagation();
- setTriggerValue(null);
- }, []);
- const closeIcon = useMemo(() => {
- return triggerValue ? <IconClose onClick={onClear} /> : <IconChevronDown />;
- }, [triggerValue]);
- const triggerContent = (placeholder) => {
- if (Array.isArray(triggerValue) && triggerValue.length) {
- return `${dateFns.format(triggerValue[0], formatToken)} ~ ${dateFns.format(triggerValue[1], formatToken)}`;
- } else {
- return '请选择年月时间范围';
- }
- };
- const TopSlot = function(props) {
- const { style } = props;
- return (
- <Space style={{ padding: '12px 20px', ...style }}>
- <Text strong style={{ color: 'var(--semi-color-text-2)' }}>
- 请选择月份范围
- </Text>
- </Space>
- );
- };
- const BottomSlot = function(props) {
- const { style } = props;
- return (
- <Space style={{ padding: '12px 20px', ...style }}>
- <Text strong style={{ color: 'var(--semi-color-text-2)' }}>
- 定版前请阅读
- </Text>
- <Text link={{ href: 'https://semi.design/', target: '_blank' }}>发版须知</Text>
- </Space>
- );
- };
- const disabledDate = date => {
- const deadDate = new Date('2023/3/1 00:00:00');
- return date.getTime() < deadDate.getTime();
- };
- return (
- <>
- <div>
- <div>default</div>
- <DatePicker type="monthRange" />
- <br />
- <br />
- <div>rangeSeparator 与 placeholder</div>
- <DatePicker type="monthRange" rangeSeparator={'➡️'} placeholder={['开始', '结束']} insetLabel='月份范围'/>
- <br />
- <br />
- <div>受控</div>
- <DatePicker type="monthRange" bottomSlot={<BottomSlot />} topSlot={<TopSlot />} value={controlledValue} onChange={_setControlledValue}/>
- <br />
- <br />
- <div>insetInput ➕ format</div>
- <div data-cy="monthRange">
- <DatePicker type="monthRange" insetInput format={'yyyy年MM月'} rangeSeparator={'到'} defaultValue={['2023-03', '2023-04']} style={{ width: 400 }}/>
- </div>
- <br />
- <div>triggerRender</div>
- <DatePicker
- type="monthRange"
- value={triggerValue}
- onChange={onChange}
- triggerRender={({ placeholder }) => (
- <Button theme={'light'} icon={closeIcon} iconPosition='right'>
- {triggerContent(placeholder)}
- </Button>
- )}
- />
- <br />
- <br />
- <div>年月禁用:禁用2023年3月前的所有年月</div>
- <DatePicker type="monthRange" disabledDate={disabledDate}/>
- <br />
- <br />
- <div>validateStatus</div>
- <DatePicker type="monthRange" validateStatus='warning' />
- <br />
- <DatePicker type="monthRange" validateStatus='error' />
- </div>
- </>
- );
- };
- export const PropTypesAndDefaultProps = () => (
- <div>
- <article>
- <p>{JSON.stringify(Object.keys(DatePicker.propTypes))}</p>
- <p>{JSON.stringify(DatePicker.defaultProps)}</p>
- </article>
- </div>
- );
- export const InputReadOnly = () => <DatePicker inputReadOnly={true} />;
- export const DropdownClassNameDropdownStyle = () => (
- <div>
- <h4>fontSize: 16,dropdownClassName: 'my-datePicker'</h4>
- <DatePicker
- dropdownStyle={{ fontSize: 16 }}
- dropdownClassName="my-datePicker"
- onChange={(date, dateString) => console.log(dateString)}
- />
- </div>
- );
- export const CustomPlaceholder = () => (
- <Space wrap>
- <DatePicker placeholder="请选择日期" insetLabel="默认" />
- <DatePicker placeholder={undefined} insetLabel="undefined" />
- <DatePicker placeholder="" insetLabel="空字符串" />
- <DatePicker placeholder={false} insetLabel="false" />
- <DatePicker placeholder={null} insetLabel="null" />
- <DatePicker placeholder="" type="dateRange" insetLabel="空字符串" />
- </Space>
- );
- 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 (
- <ConfigProvider timeZone={tz}>
- <InputGroup>
- <InputNumber defaultValue={0} onChange={setTz} hideButtons />
- <DatePicker type="dateTimeRange" value={value} onChange={withLog(setVal)} />
- <DatePicker
- type="dateTimeRange"
- needConfirm
- value={value2}
- onConfirm={withLog(setVal2)}
- />
- <DatePicker type="date" value={value3} onChange={withLog(setVal3)} />
- <DatePicker type="dateRange" value={value4} onChange={withLog(setVal4)} />
- </InputGroup>
- </ConfigProvider>
- );
- }
- return <Demo />;
- };
- 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 (
- <>
- <h4>dateRange type + disabled rangeStart and select rangeEnd</h4>
- <DatePicker {...props} disabledDate={disabledMonth} />
- <h4>date type + multiple select + given disabled defaultValue</h4>
- <DatePicker {...props} type="date" multiple disabledDate={disabledDate} />
- </>
- );
- };
- SelectNotDisabledDateV126.story = {
- name: 'select not disabled date(v1.26+)',
- };
- const CustomDatePicker = props => {
- const { fieldRef, ...rest } = props;
- return <DatePicker {...rest} ref={fieldRef} />;
- };
- 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 (
- <>
- <DatePicker
- type="date"
- presets={presets}
- open={open1}
- onPresetClick={() => {
- setOpen1(false);
- }}
- onFocus={() => {
- console.log('focus');
- setOpen1(true);
- }}
- onBlur={() => {
- console.log('blur');
- }}
- style={{ width: 300 }}
- />
- <br />
- <br />
- <DatePicker
- type="dateTimeRange"
- presets={presets}
- open={open2}
- onPresetClick={() => {
- 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}
- />
- <Form>
- <CustomFieldDatePicker
- type="dateTimeRange"
- field="a"
- label="Form.DatePicker"
- presets={presets}
- open={open3}
- onPresetClick={() => {
- 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}
- />
- </Form>
- </>
- );
- }
- return <FocusDemo />;
- };
- 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 (
- <>
- <strong>fix disabledTime callback parameter bug</strong>
- <DatePicker
- type="dateTimeRange"
- hideDisabledOptions={false}
- disabledTime={disabledTime2}
- defaultValue={['2021-09-08', '2021-10-03']}
- style={{ width: 400 }}
- />
- <DatePicker
- type="dateTime"
- hideDisabledOptions={false}
- defaultValue={'2021-09-08'}
- disabledTime={disabledTime2}
- style={{ width: 400 }}
- />
- </>
- );
- }
- return <Demo />;
- };
- FixDisabledTimeCallback1418.story = {
- name: 'fix disabledTime callback #1418',
- };
- export const RangeSeparator = () => (
- <Space wrap>
- <div>
- <div>custom rangeSeparator</div>
- <DatePicker
- type="dateRange"
- rangeSeparator="-"
- defaultValue={[new Date('2019-07-01'), new Date('2019-08-02')]}
- />
- <DatePicker
- type="dateTimeRange"
- rangeSeparator="-"
- defaultValue={[new Date('2019-07-01'), new Date('2019-08-02')]}
- />
- </div>
- <div>
- <div>default rangeSeparator</div>
- <DatePicker
- type="dateRange"
- defaultValue={[new Date('2019-07-01'), new Date('2019-08-02')]}
- />
- <DatePicker
- type="dateTimeRange"
- defaultValue={[new Date('2019-07-01'), new Date('2019-08-02')]}
- />
- </div>
- </Space>
- );
- /**
- * 修复输入 '20221-12-20' 类似这种年份的日期会崩溃问题
- * https://github.com/DouyinFE/semi-design/issues/422
- *
- * 非法日期的来源
- * - 用户输入
- * - 受控传入
- * @returns
- */
- export const FixParseISOBug = () => (
- <div>
- <label>
- <div>选择一个合法值,然后输入一个非法年份</div>
- <DatePicker defaultValue={'2021-12-20'} onChange={v => console.log('onChange', v)} />
- </label>
- <label>
- <div>defaultValue='20221-12-20'</div>
- <DatePicker defaultValue={'20221-12-20'} defaultOpen={true} motion={false} onChange={v => console.log('onChange', v)} />
- </label>
- </div>
- );
- 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 (
- <div>
- <div data-cy="1">
- <span>dateTime + needConfirm + defaultValue</span>
- <div>
- <DatePicker
- type="dateTime"
- defaultValue={defaultDate}
- {...props}
- />
- </div>
- </div>
- <div data-cy="2">
- <span>dateTime + needConfirm</span>
- <div>
- <DatePicker
- type="dateTime"
- {...props}
- />
- </div>
- </div>
- <div data-cy="3">
- <span>dateTimeRange + needConfirm + defaultValue</span>
- <div>
- <DatePicker
- type="dateTimeRange"
- defaultValue={defaultDateRange}
- {...props}
- />
- </div>
- </div>
- <div data-cy="4">
- <span>dateTimeRange + needConfirm</span>
- <div>
- <DatePicker
- type="dateTimeRange"
- {...props}
- />
- </div>
- </div>
- </div>
- )
- }
- 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 (
- <div>
- <div>
- <label>
- <span>不设置 needConfirm</span>
- <DatePicker onChange={console.log} type="dateRange" presets={presets} />
- </label>
- </div>
- <div>
- <label>
- <span>设置 needConfirm</span>
- <DatePicker needConfirm onChange={handleChange} onConfirm={handleConfirm} type="dateTimeRange" presets={presets} />
- </label>
- </div>
- </div>
- );
- };
- 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 (
- <Space>
- <DatePicker
- value={value}
- type="dateRange"
- onChange={handleChange}
- motion={false}
- triggerRender={({ placeholder }) => (
- <Button>
- {(value && formatValue(value)) || placeholder}
- </Button>
- )}
- />
- {showClear && (
- <Button onClick={() => setValue([])}>清除</Button>
- )}
- </Space>
- );
- };
- 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 (
- <Space vertical align='start' data-cy="space">
- <div data-cy="dateRange">
- <DatePicker
- value={rangeValue}
- type="dateRange"
- onChange={handleRangeChange}
- showClear
- />
- </div>
- <div data-cy="date">
- <DatePicker
- onChange={handleChange}
- showClear
- multiple
- />
- </div>
- </Space>
- );
- };
- A11yKeyboardDemo.storyName = "a11y keyboard demo";
- /**
- * test with cypress
- */
- export const NeedConfirmDelete = () => {
- return (
- <div data-cy="dateTimeRange">
- <DatePicker
- value={[new Date('2022-08-08 00:00'), new Date('2022-08-09 12:00')]}
- type="dateTimeRange"
- needConfirm
- />
- </div>
- );
- };
- NeedConfirmDelete.storyName = "cashedSelectedValue return to last selected when needConfirm & input invalid";
- /**
- * test with cypress
- */
- export const CashedSelectedValue = () => {
- return (
- <Space>
- <div data-cy="date">
- <DatePicker
- defaultValue={new Date('2022-08-08')}
- type="date"
- motion={false}
- />
- </div>
- <div data-cy="dateTime">
- <DatePicker
- defaultValue={new Date('2022-08-08 19:11:00')}
- type="dateTime"
- motion={false}
- />
- </div>
- <div data-cy="dateRange">
- <DatePicker
- defaultValue={[new Date('2022-08-08'), new Date('2022-08-09')]}
- type="dateRange"
- motion={false}
- />
- </div>
- </Space>
- );
- };
- CashedSelectedValue.storyName = "cashedSelectedValue";
|