DateTimePicker.stories.tsx 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import { useEffect, useState } from 'react';
  2. import type { Meta, StoryObj } from '@storybook/react-vite';
  3. import { Typography } from 'antd';
  4. import dayjs from 'dayjs';
  5. import type { Dayjs } from 'dayjs';
  6. import { setDatepicker } from '@/hooks/useDatepicker';
  7. import { ThemeProvider } from '@/hooks/useTheme';
  8. import DateTimePicker from './DateTimePicker';
  9. setDatepicker('gregorian');
  10. function ClientExpiryDemo() {
  11. const [value, setValue] = useState<Dayjs | null>(dayjs('2026-12-31 23:59:59'));
  12. return (
  13. <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
  14. <DateTimePicker value={value} onChange={setValue} placeholder="Expiry date" />
  15. <Typography.Text type="secondary">
  16. {value
  17. ? `user1@node-de expiryTime: ${value.valueOf()}`
  18. : 'user1@node-de expiryTime: 0 (never expires)'}
  19. </Typography.Text>
  20. </div>
  21. );
  22. }
  23. function JalaliDemo() {
  24. const [value, setValue] = useState<Dayjs | null>(dayjs('2026-12-31 23:59:59'));
  25. useEffect(() => {
  26. setDatepicker('jalalian');
  27. return () => setDatepicker('gregorian');
  28. }, []);
  29. return <DateTimePicker value={value} onChange={setValue} placeholder="Expiry date" />;
  30. }
  31. const meta = {
  32. title: 'Form/DateTimePicker',
  33. component: DateTimePicker,
  34. tags: ['autodocs'],
  35. parameters: {
  36. layout: 'padded',
  37. docs: {
  38. description: {
  39. component:
  40. 'Calendar-aware date/time picker used for client and inbound expiry dates. Renders an AntD DatePicker by default and switches to a Persian (Jalali) calendar — with theme-matched colors and an overlaid clear button — when the panel datepicker setting is jalalian.',
  41. },
  42. },
  43. },
  44. decorators: [
  45. (Story) => (
  46. <ThemeProvider>
  47. <Story />
  48. </ThemeProvider>
  49. ),
  50. ],
  51. argTypes: {
  52. value: { description: 'Selected moment as a Dayjs instance, or null when unset.' },
  53. onChange: { description: 'Called with the picked Dayjs value, or null when cleared.' },
  54. showTime: { description: 'Include an hour/minute/second selector alongside the date.' },
  55. format: { description: 'Display format for the Gregorian picker input.' },
  56. placeholder: { description: 'Input placeholder shown while no value is set.' },
  57. disabled: { description: 'Disables the input and hides the clear button.' },
  58. },
  59. } satisfies Meta<typeof DateTimePicker>;
  60. export default meta;
  61. type Story = StoryObj<typeof meta>;
  62. export const Empty: Story = {
  63. args: {
  64. value: null,
  65. onChange: () => undefined,
  66. placeholder: 'Leave blank to never expire',
  67. },
  68. };
  69. export const ClientExpiry: Story = {
  70. args: { value: null, onChange: () => undefined },
  71. render: () => <ClientExpiryDemo />,
  72. };
  73. export const DateOnly: Story = {
  74. args: {
  75. value: dayjs('2026-08-01'),
  76. onChange: () => undefined,
  77. showTime: false,
  78. format: 'YYYY-MM-DD',
  79. placeholder: 'Start date',
  80. },
  81. };
  82. export const JalaliCalendar: Story = {
  83. args: { value: null, onChange: () => undefined },
  84. parameters: { docs: { disable: true } },
  85. render: () => <JalaliDemo />,
  86. };