DateTimePicker.stories.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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 ? `user1@node-de expiryTime: ${value.valueOf()}` : 'user1@node-de expiryTime: 0 (never expires)'}
  17. </Typography.Text>
  18. </div>
  19. );
  20. }
  21. function JalaliDemo() {
  22. const [value, setValue] = useState<Dayjs | null>(dayjs('2026-12-31 23:59:59'));
  23. useEffect(() => {
  24. setDatepicker('jalalian');
  25. return () => setDatepicker('gregorian');
  26. }, []);
  27. return <DateTimePicker value={value} onChange={setValue} placeholder="Expiry date" />;
  28. }
  29. const meta = {
  30. title: 'Form/DateTimePicker',
  31. component: DateTimePicker,
  32. tags: ['autodocs'],
  33. parameters: {
  34. layout: 'padded',
  35. docs: {
  36. description: {
  37. component:
  38. '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.',
  39. },
  40. },
  41. },
  42. decorators: [
  43. (Story) => (
  44. <ThemeProvider>
  45. <Story />
  46. </ThemeProvider>
  47. ),
  48. ],
  49. argTypes: {
  50. value: { description: 'Selected moment as a Dayjs instance, or null when unset.' },
  51. onChange: { description: 'Called with the picked Dayjs value, or null when cleared.' },
  52. showTime: { description: 'Include an hour/minute/second selector alongside the date.' },
  53. format: { description: 'Display format for the Gregorian picker input.' },
  54. placeholder: { description: 'Input placeholder shown while no value is set.' },
  55. disabled: { description: 'Disables the input and hides the clear button.' },
  56. },
  57. } satisfies Meta<typeof DateTimePicker>;
  58. export default meta;
  59. type Story = StoryObj<typeof meta>;
  60. export const Empty: Story = {
  61. args: {
  62. value: null,
  63. onChange: () => undefined,
  64. placeholder: 'Leave blank to never expire',
  65. },
  66. };
  67. export const ClientExpiry: Story = {
  68. args: { value: null, onChange: () => undefined },
  69. render: () => <ClientExpiryDemo />,
  70. };
  71. export const DateOnly: Story = {
  72. args: {
  73. value: dayjs('2026-08-01'),
  74. onChange: () => undefined,
  75. showTime: false,
  76. format: 'YYYY-MM-DD',
  77. placeholder: 'Start date',
  78. },
  79. };
  80. export const JalaliCalendar: Story = {
  81. args: { value: null, onChange: () => undefined },
  82. parameters: { docs: { disable: true } },
  83. render: () => <JalaliDemo />,
  84. };