datePicker.stories.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900
  1. import React, { useState, useRef } from 'react';
  2. import {
  3. addDays,
  4. addWeeks,
  5. addMonths,
  6. isBefore,
  7. startOfMonth,
  8. endOfMonth,
  9. parseISO,
  10. startOfWeek,
  11. endOfWeek,
  12. } from 'date-fns';
  13. import { Space, ConfigProvider, InputGroup, InputNumber, Form, withField, Button } from '../../index';
  14. // stores
  15. import NeedConfirmDemo from './NeedConfirm';
  16. import RenderDate from './RenderDate';
  17. import RenderFullDate from './RenderFullDate';
  18. import DateOffset from './DateOffset';
  19. import AllTypesDemo from './AllTypes';
  20. import Callbacks from './Callbacks';
  21. import DatePicker from '../index';
  22. import ExceptionDemo from './ExceptionDemo';
  23. import ControlledDemo from './ControlledDemo';
  24. import DisabledDate from './DisabledDate';
  25. import CustomTrigger from './CustomTrigger';
  26. import OverPopover from './OverPopover';
  27. import OnChangeWithDateFirst from './OnChangeWithDateFirst';
  28. import Multiple from './Multiple';
  29. import Autofocus from './Autofocus';
  30. import CycledDatePicker from './Cycled';
  31. import AutoSwitchDate from './AutoSwitchDate';
  32. import TimepikcerOpts from './TimePickerOpts';
  33. import Density from './Density';
  34. import DatePickerSlot from './DatePickerSlot';
  35. import DatePickerTimeZone from './DatePickerTimeZone';
  36. import BetterRangePicker from './BetterRangePicker';
  37. import SyncSwitchMonth from './SyncSwitchMonth';
  38. export * from './v2';
  39. export default {
  40. title: 'DatePicker',
  41. parameters: {
  42. chromatic: { disableSnapshot: true },
  43. },
  44. }
  45. export {
  46. ControlledDemo,
  47. NeedConfirmDemo,
  48. ExceptionDemo,
  49. AllTypesDemo,
  50. Callbacks,
  51. DisabledDate,
  52. CustomTrigger,
  53. OverPopover,
  54. OnChangeWithDateFirst,
  55. RenderDate,
  56. RenderFullDate,
  57. Autofocus,
  58. DateOffset,
  59. CycledDatePicker,
  60. AutoSwitchDate,
  61. TimepikcerOpts,
  62. Density,
  63. DatePickerSlot,
  64. DatePickerTimeZone,
  65. BetterRangePicker,
  66. SyncSwitchMonth,
  67. }
  68. const demoDiv = {
  69. marginTop: '20px',
  70. marginLeft: '20px',
  71. };
  72. export const DatePickerDefault = () => (
  73. <div style={{...demoDiv, height: '100vh'}}>
  74. <span>datePicker施工现场</span>
  75. <DatePicker
  76. insetLabel={<span>日期</span>}
  77. onChange={(str, date) => console.log(str)}
  78. onOpenChange={status => console.log(status)}
  79. placeholder="请选择日期"
  80. />
  81. <br />
  82. <span>datePicker默认显示</span>
  83. <DatePicker />
  84. <br />
  85. <span>defaultValue: 2019-07-09</span>
  86. <DatePicker defaultValue="2019-07-09" />
  87. <br />
  88. <span>defaultValue: 1569888000000</span>
  89. <DatePicker
  90. defaultValue={1569888000000}
  91. onChange={(input, value) => console.log({ input, value })}
  92. />
  93. <br />
  94. <span>defaultValue: new Date('2019-07-07')</span>
  95. <DatePicker
  96. defaultValue={new Date('2019-07-07')}
  97. onOpenChange={isOpen => console.log(isOpen)}
  98. defaultOpen
  99. motion={false}
  100. />
  101. </div>
  102. );
  103. DatePickerDefault.parameters = {
  104. chromatic: {
  105. disableSnapshot: false,
  106. delay: 300
  107. }
  108. };
  109. export const DatePickerCallbacks = () => {
  110. const printArgs = (...args) => console.log(...args);
  111. return (
  112. <div style={demoDiv}>
  113. <span>datePicker施工现场</span>
  114. <DatePicker onOpenChange={printArgs} />
  115. <br />
  116. <span>defaultValue: new Date('2019-07-07')</span>
  117. <DatePicker defaultValue={new Date('2019-07-07')} />
  118. <br />
  119. <span>defaultValue: 2019-07-09</span>
  120. <DatePicker defaultValue="2019-07-09" />
  121. <br />
  122. <span>defaultValue: 1569888000000</span>
  123. <DatePicker
  124. defaultValue={1569888000000}
  125. onChange={(input, value) => console.log(input, value)}
  126. />
  127. </div>
  128. );
  129. };
  130. export const DatePickerMultiple = () => <Multiple />;
  131. export const DateRangePicker = () => (
  132. <div style={demoDiv}>
  133. <div>dateRangePicker</div>
  134. <DatePicker type="dateRange" insetLabel="结束日期" prefix="test" validateStatus="error" />
  135. <br />
  136. <div>small dateRangePicker</div>
  137. <DatePicker type="dateRange" size="small" disabled prefix="test" />
  138. <br />
  139. <div>large dateRangePicker</div>
  140. <DatePicker type="dateRange" size="large" />
  141. <br />
  142. <div>compact dateRangePicker</div>
  143. <DatePicker type="dateRange" density="compact" validateStatus="warning" />
  144. <br />
  145. <div>dateRangePicker with offset</div>
  146. <DatePicker
  147. type="dateRange"
  148. startDateOffset={date => startOfWeek(date, { weekStartsOn: 1 })}
  149. endDateOffset={date => endOfWeek(date, { weekStartsOn: 1 })}
  150. />
  151. <br />
  152. <div>defaultValue:07/01-08/02</div>
  153. <DatePicker type="dateRange" defaultValue={[new Date('2019-07-01'), new Date('2019-08-02')]} />
  154. </div>
  155. );
  156. DateRangePicker.parameters = {
  157. chromatic: { disableSnapshot: false },
  158. };
  159. const presets = [
  160. {
  161. text: 'Today',
  162. start: new Date(),
  163. end: new Date(),
  164. },
  165. {
  166. text: 'Tomorrow',
  167. start: addDays(new Date(), 1),
  168. end: addDays(new Date(), 1),
  169. },
  170. {
  171. text: 'Next Week',
  172. start: addWeeks(new Date(), 1),
  173. end: addWeeks(new Date(), 2),
  174. },
  175. {
  176. text: 'Next Month',
  177. start: startOfMonth(addMonths(new Date(), 1)),
  178. end: endOfMonth(addMonths(new Date(), 1)),
  179. },
  180. {
  181. text: 'Today',
  182. start: new Date(),
  183. end: new Date(),
  184. },
  185. {
  186. text: 'Tomorrow',
  187. start: addDays(new Date(), 1),
  188. end: addDays(new Date(), 1),
  189. },
  190. {
  191. text: 'Next Week',
  192. start: addWeeks(new Date(), 1),
  193. end: addWeeks(new Date(), 2),
  194. },
  195. {
  196. text: 'Next Month',
  197. start: startOfMonth(addMonths(new Date(), 1)),
  198. end: endOfMonth(addMonths(new Date(), 1)),
  199. },
  200. ];
  201. export const DatePickerWithPresets = () => {
  202. const onPresetClick = (item, e) => {
  203. console.log('preset click', item, e);
  204. };
  205. return (
  206. <div style={demoDiv}>
  207. <span>带快捷选择的DatePicker</span>
  208. <DatePicker
  209. type="dateRange"
  210. presets={presets}
  211. onPresetClick={onPresetClick}
  212. onChange={(...args) => console.log(...args)}
  213. />
  214. <DatePicker
  215. type="dateTime"
  216. presets={presets.map(preset => ({
  217. text: preset.text,
  218. start: preset.start,
  219. }))}
  220. onPresetClick={onPresetClick}
  221. onChange={(...args) => console.log(...args)}
  222. />
  223. <DatePicker
  224. type="dateTime"
  225. needConfirm
  226. presets={presets.map(preset => ({
  227. text: preset.text,
  228. start: preset.start,
  229. }))}
  230. onPresetClick={onPresetClick}
  231. onChange={(...args) => console.log(...args)}
  232. />
  233. <DatePicker
  234. type="month"
  235. presets={presets.map(preset => ({
  236. text: preset.text,
  237. start: preset.start,
  238. }))}
  239. onPresetClick={onPresetClick}
  240. onChange={(...args) => console.log(...args)}
  241. />
  242. </div>
  243. );
  244. };
  245. function isDisabled(dayStr) {
  246. return isBefore(new Date(dayStr), new Date());
  247. }
  248. export const DatePickerDisabledDate = () => (
  249. <div style={demoDiv}>
  250. <span>不可选日期</span>
  251. <DatePicker type="dateRange" presets={presets} disabledDate={isDisabled} />
  252. </div>
  253. );
  254. export const DateTimePicker = () => (
  255. <div style={demoDiv}>
  256. <span>dateTimePicker</span>
  257. <DatePicker
  258. defaultPickerValue={parseISO('2020-02-20 20:00:00')}
  259. type="dateTime"
  260. onChange={(...args) => console.log('onChange: ', ...args)}
  261. />
  262. </div>
  263. );
  264. export const DateTimeRangePicker = () => (
  265. <div style={demoDiv}>
  266. <span>dateTimeRangePicker</span>
  267. <DatePicker type="dateTimeRange" defaultPickerValue={parseISO('2020-02-20 20:00:00')} />
  268. <br />
  269. <span>dateTimeRangePicker</span>
  270. <DatePicker type="dateTimeRange" presets={presets} />
  271. <br />
  272. <span>dateTimeRangePicker - multiple</span>
  273. <DatePicker type="dateTimeRange" multiple />
  274. <br />
  275. </div>
  276. );
  277. export const YearPicker = () => (
  278. <>
  279. <div>
  280. <span>Year Picker</span>
  281. <DatePicker type="dateTimeRange" />
  282. </div>
  283. <div>
  284. <span>Year Picker</span>
  285. <DatePicker type="dateTimeRange" presets={presets} />
  286. </div>
  287. </>
  288. );
  289. export const MonthPicker = () => {
  290. const Demo = () => {
  291. const [controlledValue, setControlledValue] = useState('2019-09');
  292. const _setControlledValue = value => setControlledValue(value);
  293. return (
  294. <>
  295. <div>
  296. <span>MonthPicker</span>
  297. <DatePicker type="month" />
  298. </div>
  299. <div>
  300. <span>MonthPicker with presets</span>
  301. <DatePicker type="month" presets={presets} />
  302. </div>
  303. <div>
  304. <span>MonthPicker with disabledDate</span>
  305. <DatePicker
  306. type="month"
  307. disabledDate={str => {
  308. const date = new Date(str);
  309. if (str.length <= 4) {
  310. return date.getFullYear() < 2015;
  311. }
  312. return date.getMonth() + 1 < 10;
  313. }}
  314. />
  315. </div>
  316. <div>
  317. <span>MonthPicker with presets</span>
  318. <DatePicker type="month" presets={presets} />
  319. </div>
  320. <div>
  321. <span>MonthPicker with controlledValue</span>
  322. <DatePicker type="month" value={controlledValue} onChange={_setControlledValue} />
  323. </div>
  324. </>
  325. );
  326. };
  327. return <Demo />;
  328. };
  329. export const PropTypesAndDefaultProps = () => (
  330. <div>
  331. <article>
  332. <p>{JSON.stringify(Object.keys(DatePicker.propTypes))}</p>
  333. <p>{JSON.stringify(DatePicker.defaultProps)}</p>
  334. </article>
  335. </div>
  336. );
  337. export const InputReadOnly = () => <DatePicker inputReadOnly={true} />;
  338. export const DropdownClassNameDropdownStyle = () => (
  339. <div>
  340. <h4>fontSize: 16,dropdownClassName: 'my-datePicker'</h4>
  341. <DatePicker
  342. dropdownStyle={{ fontSize: 16 }}
  343. dropdownClassName="my-datePicker"
  344. onChange={(date, dateString) => console.log(dateString)}
  345. />
  346. </div>
  347. );
  348. export const CustomPlaceholder = () => (
  349. <Space wrap>
  350. <DatePicker placeholder="请选择日期" insetLabel="默认" />
  351. <DatePicker placeholder={undefined} insetLabel="undefined" />
  352. <DatePicker placeholder="" insetLabel="空字符串" />
  353. <DatePicker placeholder={false} insetLabel="false" />
  354. <DatePicker placeholder={null} insetLabel="null" />
  355. <DatePicker placeholder="" type="dateRange" insetLabel="空字符串" />
  356. </Space>
  357. );
  358. CustomPlaceholder.parameters = {
  359. chromatic: { disableSnapshot: false },
  360. };
  361. export const FixNotifyChange = () => {
  362. function Demo() {
  363. const [tz, setTz] = useState(0);
  364. const [value, setVal] = useState();
  365. const [value2, setVal2] = useState();
  366. const [value3, setVal3] = useState();
  367. const [value4, setVal4] = useState();
  368. const withLog = fn => {
  369. return val => {
  370. console.log('notifyChange', val);
  371. fn(val);
  372. };
  373. };
  374. return (
  375. <ConfigProvider timeZone={tz}>
  376. <InputGroup>
  377. <InputNumber defaultValue={0} onChange={setTz} hideButtons />
  378. <DatePicker type="dateTimeRange" value={value} onChange={withLog(setVal)} />
  379. <DatePicker
  380. type="dateTimeRange"
  381. needConfirm
  382. value={value2}
  383. onConfirm={withLog(setVal2)}
  384. />
  385. <DatePicker type="date" value={value3} onChange={withLog(setVal3)} />
  386. <DatePicker type="dateRange" value={value4} onChange={withLog(setVal4)} />
  387. </InputGroup>
  388. </ConfigProvider>
  389. );
  390. }
  391. return <Demo />;
  392. };
  393. export const SelectNotDisabledDateV126 = () => {
  394. const defaultValue = ['2021-08-06', '2021-08-15'];
  395. const disabledMonth = dateStr => {
  396. const date = new Date(dateStr);
  397. const month = date.getMonth();
  398. if (month === 7) {
  399. return true;
  400. }
  401. return false;
  402. };
  403. const disabledDate = dateStr => {
  404. const date = new Date(dateStr);
  405. const day = date.getDate();
  406. if (day > 20 && day < 25) {
  407. return true;
  408. }
  409. return false;
  410. };
  411. let props = {
  412. type: 'dateRange',
  413. motion: false,
  414. defaultValue,
  415. onChange: (...args) => console.log('changed', ...args),
  416. style: { width: 300 },
  417. };
  418. return (
  419. <>
  420. <h4>dateRange type + disabled rangeStart and select rangeEnd</h4>
  421. <DatePicker {...props} disabledDate={disabledMonth} />
  422. <h4>date type + multiple select + given disabled defaultValue</h4>
  423. <DatePicker {...props} type="date" multiple disabledDate={disabledDate} />
  424. </>
  425. );
  426. };
  427. SelectNotDisabledDateV126.story = {
  428. name: 'select not disabled date(v1.26+)',
  429. };
  430. const CustomDatePicker = props => {
  431. const { fieldRef, ...rest } = props;
  432. return <DatePicker {...rest} ref={fieldRef} />;
  433. };
  434. const CustomFieldDatePicker = withField(CustomDatePicker);
  435. export const FixOnFocus = () => {
  436. function FocusDemo() {
  437. const [open1, setOpen1] = useState(false);
  438. const [open2, setOpen2] = useState(false);
  439. const [open3, setOpen3] = useState(false);
  440. const ref = useRef();
  441. const ref2 = useRef();
  442. const presets = [
  443. {
  444. text: 'Today',
  445. start: new Date(),
  446. end: new Date(),
  447. },
  448. {
  449. text: 'Tomorrow',
  450. start: new Date(new Date().valueOf() + 1000 * 3600 * 24),
  451. end: new Date(new Date().valueOf() + 1000 * 3600 * 24),
  452. },
  453. ];
  454. return (
  455. <>
  456. <DatePicker
  457. type="date"
  458. presets={presets}
  459. open={open1}
  460. onPresetClick={() => {
  461. setOpen1(false);
  462. }}
  463. onFocus={() => {
  464. console.log('focus');
  465. setOpen1(true);
  466. }}
  467. onBlur={() => {
  468. console.log('blur');
  469. }}
  470. style={{ width: 300 }}
  471. />
  472. <br />
  473. <br />
  474. <DatePicker
  475. type="dateTimeRange"
  476. presets={presets}
  477. open={open2}
  478. onPresetClick={() => {
  479. console.log('click presets', ref);
  480. setOpen2(false);
  481. setTimeout(() => {
  482. ref.current.foundation.closePanel();
  483. console.log(ref);
  484. }, 0);
  485. }}
  486. onFocus={() => {
  487. console.log('focus');
  488. setOpen2(true);
  489. }}
  490. onBlur={() => {
  491. console.log('blur');
  492. }}
  493. style={{ width: 500 }}
  494. ref={ref}
  495. />
  496. <Form>
  497. <CustomFieldDatePicker
  498. type="dateTimeRange"
  499. field="a"
  500. label="Form.DatePicker"
  501. presets={presets}
  502. open={open3}
  503. onPresetClick={() => {
  504. console.log('click presets', ref2);
  505. setOpen3(false);
  506. setTimeout(() => {
  507. ref2.current && ref2.current.foundation.closePanel();
  508. }, 0);
  509. }}
  510. onFocus={() => {
  511. console.log('focus');
  512. setOpen3(true);
  513. }}
  514. onBlur={() => {
  515. console.log('blur');
  516. }}
  517. style={{ width: 500 }}
  518. fieldRef={ref2}
  519. />
  520. </Form>
  521. </>
  522. );
  523. }
  524. return <FocusDemo />;
  525. };
  526. FixOnFocus.story = {
  527. name: 'fix onFocus',
  528. };
  529. export const FixDisabledTimeCallback1418 = () => {
  530. function Demo() {
  531. const disabledTime2 = (date, panelType) => {
  532. console.log('disabledTime callback parameter: ', date, panelType);
  533. if (panelType === 'left') {
  534. return { disabledHours: () => [17, 18] };
  535. } else {
  536. return { disabledHours: () => [12, 13, 14, 15, 16, 17, 18] };
  537. }
  538. };
  539. return (
  540. <>
  541. <strong>fix disabledTime callback parameter bug</strong>
  542. <DatePicker
  543. type="dateTimeRange"
  544. hideDisabledOptions={false}
  545. disabledTime={disabledTime2}
  546. defaultValue={['2021-09-08', '2021-10-03']}
  547. style={{ width: 400 }}
  548. />
  549. <DatePicker
  550. type="dateTime"
  551. hideDisabledOptions={false}
  552. defaultValue={'2021-09-08'}
  553. disabledTime={disabledTime2}
  554. style={{ width: 400 }}
  555. />
  556. </>
  557. );
  558. }
  559. return <Demo />;
  560. };
  561. FixDisabledTimeCallback1418.story = {
  562. name: 'fix disabledTime callback #1418',
  563. };
  564. export const RangeSeparator = () => (
  565. <Space wrap>
  566. <div>
  567. <div>custom rangeSeparator</div>
  568. <DatePicker
  569. type="dateRange"
  570. rangeSeparator="-"
  571. defaultValue={[new Date('2019-07-01'), new Date('2019-08-02')]}
  572. />
  573. <DatePicker
  574. type="dateTimeRange"
  575. rangeSeparator="-"
  576. defaultValue={[new Date('2019-07-01'), new Date('2019-08-02')]}
  577. />
  578. </div>
  579. <div>
  580. <div>default rangeSeparator</div>
  581. <DatePicker
  582. type="dateRange"
  583. defaultValue={[new Date('2019-07-01'), new Date('2019-08-02')]}
  584. />
  585. <DatePicker
  586. type="dateTimeRange"
  587. defaultValue={[new Date('2019-07-01'), new Date('2019-08-02')]}
  588. />
  589. </div>
  590. </Space>
  591. );
  592. /**
  593. * 修复输入 '20221-12-20' 类似这种年份的日期会崩溃问题
  594. * https://github.com/DouyinFE/semi-design/issues/422
  595. *
  596. * 非法日期的来源
  597. * - 用户输入
  598. * - 受控传入
  599. * @returns
  600. */
  601. export const FixParseISOBug = () => (
  602. <div>
  603. <label>
  604. <div>选择一个合法值,然后输入一个非法年份</div>
  605. <DatePicker defaultValue={'2021-12-20'} onChange={v => console.log('onChange', v)} />
  606. </label>
  607. <label>
  608. <div>defaultValue='20221-12-20'</div>
  609. <DatePicker defaultValue={'20221-12-20'} defaultOpen={true} motion={false} onChange={v => console.log('onChange', v)} />
  610. </label>
  611. </div>
  612. );
  613. FixParseISOBug.storyName = '修复 parseISO bug';
  614. FixParseISOBug.parameters = {
  615. chromatic: { disableSnapshot: false },
  616. };
  617. export const FixNeedConfirm = () => {
  618. const defaultDate = '2021-12-27 10:37:13';
  619. const defaultDateRange = ['2021-12-27 10:37:13', '2022-01-28 10:37:13' ];
  620. const props = {
  621. needConfirm: true,
  622. onConfirm: (...args) => {
  623. console.log('Confirmed: ', ...args);
  624. },
  625. onChange: (...args) => {
  626. console.log('Changed: ', ...args);
  627. },
  628. onCancel: (...args) => {
  629. console.log('Canceled: ', ...args);
  630. },
  631. };
  632. return (
  633. <div>
  634. <div data-cy="1">
  635. <span>dateTime + needConfirm + defaultValue</span>
  636. <div>
  637. <DatePicker
  638. type="dateTime"
  639. defaultValue={defaultDate}
  640. {...props}
  641. />
  642. </div>
  643. </div>
  644. <div data-cy="2">
  645. <span>dateTime + needConfirm</span>
  646. <div>
  647. <DatePicker
  648. type="dateTime"
  649. {...props}
  650. />
  651. </div>
  652. </div>
  653. <div data-cy="3">
  654. <span>dateTimeRange + needConfirm + defaultValue</span>
  655. <div>
  656. <DatePicker
  657. type="dateTimeRange"
  658. defaultValue={defaultDateRange}
  659. {...props}
  660. />
  661. </div>
  662. </div>
  663. <div data-cy="4">
  664. <span>dateTimeRange + needConfirm</span>
  665. <div>
  666. <DatePicker
  667. type="dateTimeRange"
  668. {...props}
  669. />
  670. </div>
  671. </div>
  672. </div>
  673. )
  674. }
  675. FixNeedConfirm.storyName = '修复 needConfirm 取消后输入框显示错误';
  676. /**
  677. * fix https://github.com/DouyinFE/semi-design/issues/388
  678. */
  679. export const FixPresetsClick = () => {
  680. const presets = [
  681. {
  682. text: '清空',
  683. start: '',
  684. end: '',
  685. },
  686. {
  687. text: 'Tomorrow',
  688. start: new Date(new Date().valueOf() + 1000 * 3600 * 24),
  689. end: new Date(new Date().valueOf() + 1000 * 3600 * 24),
  690. },
  691. ];
  692. const handleChange = v => {
  693. console.log('change', v);
  694. };
  695. const handleConfirm = v => {
  696. console.log('confirm', v);
  697. }
  698. return (
  699. <div>
  700. <div>
  701. <label>
  702. <span>不设置 needConfirm</span>
  703. <DatePicker onChange={console.log} type="dateRange" presets={presets} />
  704. </label>
  705. </div>
  706. <div>
  707. <label>
  708. <span>设置 needConfirm</span>
  709. <DatePicker needConfirm onChange={handleChange} onConfirm={handleConfirm} type="dateTimeRange" presets={presets} />
  710. </label>
  711. </div>
  712. </div>
  713. );
  714. };
  715. FixPresetsClick.storyName = '修复 presets 点击后不收起问题';
  716. /**
  717. * fix https://github.com/DouyinFE/semi-design/issues/410
  718. */
  719. export const FixTriggerRenderClosePanel = () => {
  720. const [value, setValue] = useState([]);
  721. const handleChange = v => {
  722. console.log('change', v);
  723. setValue(v);
  724. };
  725. const formatValue = (dates) => {
  726. const dateStrs = dates.map(v => String(v));
  727. return dateStrs.join(' ~ ');
  728. };
  729. const showClear = Array.isArray(value) && value.length > 1;
  730. return (
  731. <Space>
  732. <DatePicker
  733. value={value}
  734. type="dateRange"
  735. onChange={handleChange}
  736. motion={false}
  737. triggerRender={({ placeholder }) => (
  738. <Button>
  739. {(value && formatValue(value)) || placeholder}
  740. </Button>
  741. )}
  742. />
  743. {showClear && (
  744. <Button onClick={() => setValue([])}>清除</Button>
  745. )}
  746. </Space>
  747. );
  748. };
  749. FixTriggerRenderClosePanel.storyName = "fix triggerRender close bug"
  750. export const A11yKeyboardDemo = () => {
  751. const [value, setValue] = useState(new Date('2022-08-08 00:00'));
  752. const [rangeValue, setRangeValue] = useState([new Date('2022-08-08 00:00'), new Date('2022-08-09 12:00')]);
  753. const handleChange = v => {
  754. console.log('change', v);
  755. setValue(v);
  756. };
  757. const handleRangeChange = v => {
  758. console.log('change', v);
  759. setRangeValue(v);
  760. };
  761. return (
  762. <Space vertical align='start' data-cy="space">
  763. <div data-cy="dateRange">
  764. <DatePicker
  765. value={rangeValue}
  766. type="dateRange"
  767. onChange={handleRangeChange}
  768. showClear
  769. />
  770. </div>
  771. <div data-cy="date">
  772. <DatePicker
  773. onChange={handleChange}
  774. showClear
  775. multiple
  776. />
  777. </div>
  778. </Space>
  779. );
  780. };
  781. A11yKeyboardDemo.storyName = "a11y keyboard demo";
  782. /**
  783. * test with cypress
  784. */
  785. export const NeedConfirmDelete = () => {
  786. return (
  787. <div data-cy="dateTimeRange">
  788. <DatePicker
  789. value={[new Date('2022-08-08 00:00'), new Date('2022-08-09 12:00')]}
  790. type="dateTimeRange"
  791. needConfirm
  792. />
  793. </div>
  794. );
  795. };
  796. NeedConfirmDelete.storyName = "cashedSelectedValue return to last selected when needConfirm & input invalid";
  797. /**
  798. * test with cypress
  799. */
  800. export const CashedSelectedValue = () => {
  801. return (
  802. <Space>
  803. <div data-cy="date">
  804. <DatePicker
  805. defaultValue={new Date('2022-08-08')}
  806. type="date"
  807. motion={false}
  808. />
  809. </div>
  810. <div data-cy="dateTime">
  811. <DatePicker
  812. defaultValue={new Date('2022-08-08 19:11:00')}
  813. type="dateTime"
  814. motion={false}
  815. />
  816. </div>
  817. <div data-cy="dateRange">
  818. <DatePicker
  819. defaultValue={[new Date('2022-08-08'), new Date('2022-08-09')]}
  820. type="dateRange"
  821. motion={false}
  822. />
  823. </div>
  824. </Space>
  825. );
  826. };
  827. CashedSelectedValue.storyName = "cashedSelectedValue";