@daryasidorovich/modsen-datepicker 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/README.md +302 -302
  2. package/package.json +111 -106
  3. package/.babelrc.json +0 -7
  4. package/.github/workflows/chromatic.yml +0 -25
  5. package/.github/workflows/ci.yml +0 -56
  6. package/.husky/commit-msg +0 -1
  7. package/.husky/pre-commit +0 -1
  8. package/.prettierignore +0 -16
  9. package/.prettierrc +0 -6
  10. package/.storybook/main.js +0 -93
  11. package/.storybook/preview-head.html +0 -6
  12. package/.storybook/preview.js +0 -26
  13. package/.storybook/preview.tsx +0 -18
  14. package/commitlint.config.js +0 -23
  15. package/eslint.config.ts +0 -80
  16. package/jest.config.json +0 -21
  17. package/rollup.config.js +0 -65
  18. package/src/assets/actions/Delete.svg +0 -4
  19. package/src/assets/actions/Edit.svg +0 -3
  20. package/src/assets/arrows/Next.svg +0 -4
  21. package/src/assets/arrows/Prev.svg +0 -4
  22. package/src/assets/input/Calendar.svg +0 -3
  23. package/src/assets/input/Clear.svg +0 -3
  24. package/src/components/BaseCalendar/BaseCalendar.stories.tsx +0 -77
  25. package/src/components/BaseCalendar/index.tsx +0 -63
  26. package/src/components/BaseCalendar/styles.module.scss +0 -15
  27. package/src/components/CalendarGrid/CalendarGrid.stories.tsx +0 -136
  28. package/src/components/CalendarGrid/CalendarGridWithTasks/Tooltip/index.tsx +0 -27
  29. package/src/components/CalendarGrid/CalendarGridWithTasks/Tooltip/styles.module.scss +0 -9
  30. package/src/components/CalendarGrid/CalendarGridWithTasks/index.tsx +0 -51
  31. package/src/components/CalendarGrid/CalendarGridWithoutTasks/CalendarGridWithoutTasks.test.tsx +0 -223
  32. package/src/components/CalendarGrid/CalendarGridWithoutTasks/index.tsx +0 -36
  33. package/src/components/CalendarGrid/CalendarGridWithoutTasks/styles.module.scss +0 -11
  34. package/src/components/CalendarGrid/index.tsx +0 -19
  35. package/src/components/CalendarGrid/types.ts +0 -26
  36. package/src/components/Clear/Clear.stories.tsx +0 -16
  37. package/src/components/Clear/index.tsx +0 -12
  38. package/src/components/Clear/styles.module.scss +0 -34
  39. package/src/components/DatePicker/DatePicker.stories.tsx +0 -127
  40. package/src/components/DatePicker/index.tsx +0 -72
  41. package/src/components/DatePicker/styles.module.scss +0 -10
  42. package/src/components/Day/Day.stories.tsx +0 -75
  43. package/src/components/Day/index.tsx +0 -95
  44. package/src/components/Day/styles.module.scss +0 -97
  45. package/src/components/Input/Input.stories.tsx +0 -37
  46. package/src/components/Input/index.tsx +0 -64
  47. package/src/components/Input/styles.module.scss +0 -79
  48. package/src/components/Modal/CrudModal/index.tsx +0 -43
  49. package/src/components/Modal/CrudModal/styles.module.scss +0 -44
  50. package/src/components/Modal/index.tsx +0 -66
  51. package/src/components/Modal/styles.module.scss +0 -40
  52. package/src/components/Modal/types.ts +0 -13
  53. package/src/components/Month/Month.stories.tsx +0 -19
  54. package/src/components/Month/index.tsx +0 -31
  55. package/src/components/Month/styles.module.scss +0 -30
  56. package/src/components/RangePicker/RangePicker.stories.tsx +0 -134
  57. package/src/components/RangePicker/index.tsx +0 -144
  58. package/src/components/RangePicker/styles.module.scss +0 -19
  59. package/src/components/TasksManager/AddModal/index.tsx +0 -62
  60. package/src/components/TasksManager/DeleteModal/index.tsx +0 -22
  61. package/src/components/TasksManager/EditModal/index.tsx +0 -96
  62. package/src/components/TasksManager/index.tsx +0 -112
  63. package/src/components/TasksManager/styles.module.scss +0 -62
  64. package/src/components/Week/Week.stories.tsx +0 -49
  65. package/src/components/Week/index.tsx +0 -68
  66. package/src/components/Week/styles.module.scss +0 -7
  67. package/src/components/WeekDay/WeekDay.stories.tsx +0 -38
  68. package/src/components/WeekDay/index.tsx +0 -35
  69. package/src/components/WeekDay/styles.module.scss +0 -19
  70. package/src/constants/dateMask.ts +0 -23
  71. package/src/constants/firstDayOfWeek.ts +0 -7
  72. package/src/constants/holidays.ts +0 -32
  73. package/src/constants/modes.ts +0 -6
  74. package/src/constants/monthsNames.ts +0 -14
  75. package/src/constants/weekdaysNames.ts +0 -1
  76. package/src/hooks/useCalendar.ts +0 -62
  77. package/src/hooks/useLockBodyScroll.ts +0 -19
  78. package/src/hooks/useModal.ts +0 -45
  79. package/src/hooks/useTooltip.ts +0 -41
  80. package/src/hooks/useValidate.ts +0 -80
  81. package/src/index.ts +0 -15
  82. package/src/services/calendarService.ts +0 -62
  83. package/src/services/decorators/withHolidays.test.ts +0 -64
  84. package/src/services/decorators/withHolidays.ts +0 -12
  85. package/src/services/decorators/withMinMax.test.ts +0 -77
  86. package/src/services/decorators/withMinMax.ts +0 -19
  87. package/src/services/holidayService.ts +0 -56
  88. package/src/setupTests.ts +0 -1
  89. package/src/store/localStorage.ts +0 -33
  90. package/src/store/tasksStore.test.tsx +0 -208
  91. package/src/store/tasksStore.tsx +0 -146
  92. package/src/store/types.ts +0 -22
  93. package/src/styles/_border.scss +0 -9
  94. package/src/styles/_colors.scss +0 -53
  95. package/src/styles/_gap.scss +0 -4
  96. package/src/styles/_globals.scss +0 -61
  97. package/src/styles/_grid.scss +0 -9
  98. package/src/styles/_mixins.scss +0 -6
  99. package/src/styles/_reset.scss +0 -98
  100. package/src/styles/_theme-mixins.scss +0 -51
  101. package/src/styles/_typography.scss +0 -10
  102. package/src/styles/_variables.scss +0 -8
  103. package/src/styles/main.scss +0 -3
  104. package/src/types/types.d.ts +0 -15
  105. package/src/utils/calendar.test.ts +0 -154
  106. package/src/utils/calendar.ts +0 -82
  107. package/src/utils/controlDate.ts +0 -3
  108. package/src/utils/dateChecks.test.ts +0 -216
  109. package/src/utils/dateChecks.ts +0 -75
  110. package/src/utils/formatDate.test.ts +0 -57
  111. package/src/utils/formatDate.ts +0 -27
  112. package/src/utils/schema.test.ts +0 -40
  113. package/src/utils/schema.ts +0 -8
  114. package/src/utils/weekdayOrder.test.ts +0 -11
  115. package/src/utils/weekdayOrder.ts +0 -7
  116. package/tsconfig.json +0 -31
  117. package/vitest.config.ts +0 -38
  118. package/vitest.shims.d.ts +0 -1
@@ -1,223 +0,0 @@
1
- import { render, screen, waitFor } from '@testing-library/react';
2
- import userEvent from '@testing-library/user-event';
3
- import { getHolidays } from '@/services/holidayService';
4
- import { getDefaultHolidays } from '@/constants/holidays';
5
- import { CalendarGridWithoutTasks } from '.';
6
-
7
- jest.mock('@/services/holidayService');
8
- jest.mock('@/constants/holidays');
9
-
10
- describe('CalendarWithoutTasks:', () => {
11
- const august2026 = new Date(2026, 7, 1);
12
- const mockHolidays = [new Date(2026, 7, 10)];
13
-
14
- beforeEach(() => {
15
- jest.clearAllMocks();
16
- });
17
-
18
- test('renders calendar with default props:', () => {
19
- render(
20
- <CalendarGridWithoutTasks monthDate={august2026} firstDayOfWeek={1} />
21
- );
22
-
23
- const days = screen.getAllByText('1');
24
- expect(days.length).toBeGreaterThan(0);
25
- const days31 = screen.getAllByText('31');
26
- expect(days31.length).toBeGreaterThan(0);
27
- });
28
-
29
- test('displays selected date correctly:', () => {
30
- render(
31
- <CalendarGridWithoutTasks
32
- monthDate={august2026}
33
- selectedDate={new Date(2026, 7, 15)}
34
- firstDayOfWeek={1}
35
- />
36
- );
37
-
38
- const day15 = screen.getByText('15');
39
- expect(day15).toBeInTheDocument();
40
- expect(day15.closest('button')).toHaveClass('selected');
41
- });
42
-
43
- test('handles hideWeekends option:', () => {
44
- render(
45
- <CalendarGridWithoutTasks
46
- monthDate={august2026}
47
- firstDayOfWeek={1}
48
- hideWeekends={true}
49
- />
50
- );
51
-
52
- expect(screen.queryByText('15')).not.toBeInTheDocument();
53
- expect(screen.queryByText('16')).not.toBeInTheDocument();
54
- expect(screen.getByText('7')).toBeInTheDocument();
55
- });
56
-
57
- test('displays holidays when showHolidays is true:', async () => {
58
- (getHolidays as jest.Mock).mockResolvedValue(mockHolidays);
59
-
60
- render(
61
- <CalendarGridWithoutTasks
62
- monthDate={august2026}
63
- firstDayOfWeek={1}
64
- showHolidays={true}
65
- />
66
- );
67
- await waitFor(() => {
68
- const day10 = screen.getByText('10');
69
- expect(day10).toBeInTheDocument();
70
- expect(day10.closest('button')).toHaveClass('holiday');
71
- });
72
- });
73
-
74
- test('shows loading state while fetching holidays:', async () => {
75
- (getHolidays as jest.Mock).mockResolvedValue(mockHolidays);
76
-
77
- render(
78
- <CalendarGridWithoutTasks
79
- monthDate={august2026}
80
- firstDayOfWeek={1}
81
- showHolidays={true}
82
- />
83
- );
84
-
85
- expect(screen.getByText('Loading...')).toBeInTheDocument();
86
-
87
- await waitFor(() => {
88
- expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
89
- });
90
- });
91
-
92
- test('handles holiday loading error:', async () => {
93
- const errorMessage = 'Failed to load holidays';
94
- (getHolidays as jest.Mock).mockRejectedValue(new Error(errorMessage));
95
- (getDefaultHolidays as jest.Mock).mockReturnValue(mockHolidays);
96
-
97
- render(
98
- <CalendarGridWithoutTasks
99
- monthDate={august2026}
100
- firstDayOfWeek={1}
101
- showHolidays={true}
102
- />
103
- );
104
-
105
- await waitFor(() => {
106
- expect(screen.getByText(errorMessage)).toBeInTheDocument();
107
- });
108
-
109
- const day10 = screen.getByText('10');
110
- expect(day10.closest('button')).toHaveClass('holiday');
111
- });
112
-
113
- test('applies min/max dates correctly:', () => {
114
- render(
115
- <CalendarGridWithoutTasks
116
- monthDate={august2026}
117
- firstDayOfWeek={1}
118
- minDate={new Date(2026, 7, 10)}
119
- maxDate={new Date(2026, 7, 20)}
120
- />
121
- );
122
-
123
- const day1 = screen.getByText('8');
124
- expect(day1.closest('button')).toBeDisabled();
125
-
126
- const day15 = screen.getByText('18');
127
- expect(day15.closest('button')).not.toBeDisabled();
128
-
129
- const day31 = screen.getByText('25');
130
- expect(day31.closest('button')).toBeDisabled();
131
- });
132
-
133
- test('handles week mode:', () => {
134
- render(
135
- <CalendarGridWithoutTasks
136
- monthDate={august2026}
137
- firstDayOfWeek={1}
138
- mode="week"
139
- />
140
- );
141
-
142
- const days = document.querySelectorAll('.day');
143
- expect(days.length).toBe(7);
144
- });
145
-
146
- test('handles day click', async () => {
147
- const handleDoubleClick = jest.fn();
148
- const handleClick = jest.fn();
149
-
150
- render(
151
- <CalendarGridWithoutTasks
152
- monthDate={august2026}
153
- firstDayOfWeek={1}
154
- onDateDoubleClick={handleDoubleClick}
155
- onDateClick={handleClick}
156
- enableTasks
157
- />
158
- );
159
-
160
- const day15 = screen.getByRole('button', { name: '15' });
161
- expect(day15).not.toBeDisabled();
162
-
163
- await userEvent.dblClick(day15);
164
-
165
- expect(handleClick).not.toHaveBeenCalled();
166
- expect(handleDoubleClick).toHaveBeenCalledTimes(1);
167
- });
168
-
169
- test('applies all decorators together:', async () => {
170
- (getHolidays as jest.Mock).mockResolvedValue(mockHolidays);
171
-
172
- render(
173
- <CalendarGridWithoutTasks
174
- monthDate={august2026}
175
- firstDayOfWeek={1}
176
- hideWeekends={true}
177
- showHolidays={true}
178
- minDate={new Date(2026, 7, 9)}
179
- maxDate={new Date(2026, 7, 25)}
180
- mode="month"
181
- />
182
- );
183
-
184
- expect(screen.queryByText('15')).not.toBeInTheDocument();
185
- expect(screen.queryByText('16')).not.toBeInTheDocument();
186
- await waitFor(() => {
187
- const day10 = screen.getByText('10');
188
- expect(day10.closest('button')).toHaveClass('holiday');
189
- });
190
- expect(screen.getByText('6').closest('button')).toHaveClass('disabled');
191
-
192
- const day18 = screen.getByText('18');
193
- expect(day18.closest('button')).not.toBeDisabled();
194
- });
195
-
196
- test('does not fetch holidays when showHolidays is false:', () => {
197
- render(
198
- <CalendarGridWithoutTasks
199
- monthDate={august2026}
200
- firstDayOfWeek={1}
201
- showHolidays={false}
202
- />
203
- );
204
-
205
- expect(getHolidays).not.toHaveBeenCalled();
206
- });
207
-
208
- test('handles different first day of week:', () => {
209
- const { rerender } = render(
210
- <CalendarGridWithoutTasks monthDate={august2026} firstDayOfWeek={0} />
211
- );
212
-
213
- const week = screen.getAllByRole('button');
214
- expect(week[0]).toHaveTextContent('26');
215
-
216
- rerender(
217
- <CalendarGridWithoutTasks monthDate={august2026} firstDayOfWeek={1} />
218
- );
219
-
220
- const week2 = screen.getAllByRole('button');
221
- expect(week2[0]).toHaveTextContent('27');
222
- });
223
- });
@@ -1,36 +0,0 @@
1
- import { Week } from '@/components/Week';
2
- import { useCalendar } from '@/hooks/useCalendar';
3
-
4
- import { CalendarProps } from '../types';
5
- import styles from './styles.module.scss';
6
-
7
- export const CalendarGridWithoutTasks = ({
8
- children,
9
- ...props
10
- }: CalendarProps & { children?: React.ReactNode }) => {
11
- const { calendar, loading, error } = useCalendar(props);
12
-
13
- const weeks = calendar.getWeeks();
14
-
15
- return (
16
- <div className={styles.calendar}>
17
- {weeks.map((weekDays) => (
18
- <Week
19
- key={weekDays[0].toISOString()}
20
- weekDays={weekDays}
21
- selectedDate={calendar.selectedDate}
22
- getIsDisabled={calendar.getIsDisabled}
23
- getIsCurrentMonth={calendar.getIsCurrentMonth}
24
- getIsHoliday={calendar.getIsHoliday}
25
- rangeStart={calendar.rangeStart}
26
- rangeEnd={calendar.rangeEnd}
27
- {...props}
28
- />
29
- ))}
30
-
31
- {error && <p className={styles.errorMessage}>{error}</p>}
32
- {loading && <div>Loading...</div>}
33
- {children}
34
- </div>
35
- );
36
- };
@@ -1,11 +0,0 @@
1
- .calendar {
2
- display: flex;
3
- flex-direction: column;
4
- gap: $gap-8;
5
- }
6
-
7
- .errorMessage {
8
- @include themify-modules($themes) {
9
- color: themed('accent');
10
- }
11
- }
@@ -1,19 +0,0 @@
1
- import { TasksProvider } from '@/store/tasksStore';
2
-
3
- import { CalendarGridWithoutTasks } from './CalendarGridWithoutTasks';
4
- import { CalendarGridWithTasks } from './CalendarGridWithTasks';
5
- import { CalendarProps } from './types';
6
-
7
- export const CalendarGrid = (props: CalendarProps) => {
8
- const { enableTasks } = props;
9
-
10
- if (enableTasks) {
11
- return (
12
- <TasksProvider>
13
- <CalendarGridWithTasks {...props} />
14
- </TasksProvider>
15
- );
16
- }
17
-
18
- return <CalendarGridWithoutTasks {...props} />;
19
- };
@@ -1,26 +0,0 @@
1
- import { FIRST_DAY_OF_WEEK_TYPES } from '@/constants/firstDayOfWeek';
2
- import { MODES_TYPES } from '@/constants/modes';
3
-
4
- export interface CalendarProps {
5
- minDate?: Date;
6
- maxDate?: Date;
7
- monthDate: Date;
8
- firstDayOfWeek?: FIRST_DAY_OF_WEEK_TYPES;
9
- selectedDate?: Date;
10
- mode?: MODES_TYPES;
11
- rangeStart?: Date;
12
- rangeEnd?: Date;
13
- hideWeekends?: boolean;
14
- showHolidays?: boolean;
15
- enableTasks?: boolean;
16
- hasTasks?: (date: Date) => boolean;
17
- onDateClick?: (e: React.MouseEvent<HTMLButtonElement>, date: Date) => void;
18
- onDateDoubleClick?: (date: Date) => void;
19
- onMouseEnter?: (e: React.MouseEvent<HTMLButtonElement>) => void;
20
- onMouseLeave?: () => void;
21
- }
22
-
23
- export type BaseCalendarProps = Omit<
24
- CalendarProps,
25
- 'hasTasks' | 'onDoubleDateClick' | 'onMouseEnter' | 'onMouseLeave'
26
- >;
@@ -1,16 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react';
2
- import { Clear } from '.';
3
-
4
- const meta: Meta<typeof Clear> = {
5
- component: Clear,
6
- };
7
-
8
- export default meta;
9
-
10
- type Story = StoryObj<typeof Clear>;
11
-
12
- export const Default: Story = {
13
- args: {
14
- onClick: () => console.log('Click'),
15
- },
16
- };
@@ -1,12 +0,0 @@
1
- import styles from './styles.module.scss';
2
-
3
- interface ClearProps {
4
- onClick: () => void;
5
- }
6
- export const Clear = ({ onClick }: ClearProps) => {
7
- return (
8
- <button className={styles.clear} type="button" onClick={onClick}>
9
- Clear
10
- </button>
11
- );
12
- };
@@ -1,34 +0,0 @@
1
- .clear {
2
- @include border;
3
-
4
- @include themify-modules($themes) {
5
- border-color: themed('border');
6
- background-color: themed('background');
7
- color: themed('text');
8
- }
9
-
10
- display: flex;
11
- justify-content: center;
12
- align-items: center;
13
- padding: $gap-10;
14
- width: 100%;
15
- font-weight: $font-weight-semibold;
16
- border-bottom-right-radius: $radius-8;
17
- border-bottom-left-radius: $radius-8;
18
-
19
- &:hover {
20
- @include themify-modules($themes) {
21
- background-color: themed('button-hover');
22
- color: themed('white-color');
23
- }
24
- }
25
-
26
- &:active {
27
- transform: scale(0.98);
28
-
29
- @include themify-modules($themes) {
30
- background-color: themed('selected');
31
- color: themed('white-color');
32
- }
33
- }
34
- }
@@ -1,127 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react';
2
- import { DatePicker } from './index';
3
- import { setControlDate } from '../../utils/controlDate';
4
-
5
- const meta: Meta<typeof DatePicker> = {
6
- component: DatePicker,
7
- parameters: {
8
- layout: 'centered',
9
- },
10
- argTypes: {
11
- monthDate: { control: 'date' },
12
- selectedDate: { control: 'date' },
13
- minDate: { control: 'date' },
14
- maxDate: { control: 'date' },
15
- firstDayOfWeek: {
16
- control: 'select',
17
- options: [0, 1],
18
- },
19
- },
20
- };
21
-
22
- export default meta;
23
- type Story = StoryObj<typeof DatePicker>;
24
-
25
- export const Default: Story = {
26
- args: {
27
- monthDate: new Date(2026, 7, 1),
28
- firstDayOfWeek: 1,
29
- selectedDate: new Date(2026, 7, 15),
30
- },
31
- render: (args) => (
32
- <DatePicker
33
- {...args}
34
- monthDate={new Date(args.monthDate)}
35
- selectedDate={setControlDate(args.selectedDate)}
36
- minDate={setControlDate(args.minDate)}
37
- maxDate={setControlDate(args.maxDate)}
38
- />
39
- ),
40
- };
41
-
42
- export const WithTasks: Story = {
43
- args: {
44
- monthDate: new Date(2026, 7, 25),
45
- firstDayOfWeek: 1,
46
- enableTasks: true,
47
- },
48
- render: (args) => (
49
- <DatePicker
50
- {...args}
51
- monthDate={new Date(args.monthDate)}
52
- selectedDate={setControlDate(args.selectedDate)}
53
- minDate={setControlDate(args.minDate)}
54
- maxDate={setControlDate(args.maxDate)}
55
- />
56
- ),
57
- };
58
-
59
- export const HideWeekends: Story = {
60
- args: {
61
- monthDate: new Date(2026, 8, 7),
62
- firstDayOfWeek: 1,
63
- hideWeekends: true,
64
- },
65
- render: (args) => (
66
- <DatePicker
67
- {...args}
68
- monthDate={new Date(args.monthDate)}
69
- selectedDate={setControlDate(args.selectedDate)}
70
- minDate={setControlDate(args.minDate)}
71
- maxDate={setControlDate(args.maxDate)}
72
- />
73
- ),
74
- };
75
-
76
- export const ShowHolidays: Story = {
77
- args: {
78
- monthDate: new Date(2025, 0, 3),
79
- firstDayOfWeek: 1,
80
- showHolidays: true,
81
- },
82
- render: (args) => (
83
- <DatePicker
84
- {...args}
85
- monthDate={new Date(args.monthDate)}
86
- selectedDate={setControlDate(args.selectedDate)}
87
- minDate={setControlDate(args.minDate)}
88
- maxDate={setControlDate(args.maxDate)}
89
- />
90
- ),
91
- };
92
-
93
- export const WeekMode: Story = {
94
- args: {
95
- monthDate: new Date(2025, 0, 31),
96
- firstDayOfWeek: 1,
97
- showHolidays: true,
98
- mode: 'week',
99
- },
100
- render: (args) => (
101
- <DatePicker
102
- {...args}
103
- monthDate={new Date(args.monthDate)}
104
- selectedDate={setControlDate(args.selectedDate)}
105
- minDate={setControlDate(args.minDate)}
106
- maxDate={setControlDate(args.maxDate)}
107
- />
108
- ),
109
- };
110
-
111
- export const WithMinMaxDates: Story = {
112
- args: {
113
- monthDate: new Date(2026, 7, 1),
114
- firstDayOfWeek: 1,
115
- minDate: new Date(2026, 7, 10),
116
- maxDate: new Date(2026, 7, 20),
117
- },
118
- render: (args) => (
119
- <DatePicker
120
- {...args}
121
- monthDate={new Date(args.monthDate)}
122
- selectedDate={setControlDate(args.selectedDate)}
123
- minDate={setControlDate(args.minDate)}
124
- maxDate={setControlDate(args.maxDate)}
125
- />
126
- ),
127
- };
@@ -1,72 +0,0 @@
1
- import { ChangeEvent, KeyboardEvent, Ref } from 'react';
2
-
3
- import { useValidate } from '@/hooks/useValidate';
4
-
5
- import { BaseCalendar } from '../BaseCalendar';
6
- import { BaseCalendarProps, CalendarProps } from '../CalendarGrid/types';
7
- import { Input } from '../Input';
8
- import styles from './styles.module.scss';
9
-
10
- export interface DatePickerProps
11
- extends BaseCalendarProps, Pick<CalendarProps, 'selectedDate'> {
12
- onChange?: (date: Date | undefined) => void;
13
- }
14
-
15
- export const DatePicker = ({
16
- selectedDate,
17
- monthDate = new Date(),
18
- onChange,
19
- ...props
20
- }: DatePickerProps) => {
21
- const {
22
- currentDate,
23
- value,
24
- handleDateSelect,
25
- error,
26
- ref,
27
- handleDateValidation,
28
- handleClearInput,
29
- } = useValidate(selectedDate);
30
-
31
- const handleDateSelectAndExternalUpdate = (
32
- e: React.MouseEvent<HTMLButtonElement>,
33
- date: Date
34
- ) => {
35
- handleDateSelect(date);
36
- if (onChange) {
37
- onChange(date);
38
- }
39
- };
40
-
41
- const handleDateChange = (e: ChangeEvent<HTMLInputElement>) => {
42
- handleDateValidation(e.target.value);
43
- };
44
-
45
- const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {
46
- if (e.key === 'Enter') {
47
- handleDateValidation(e.currentTarget.value);
48
- }
49
- };
50
-
51
- return (
52
- <div className={styles.datepicker}>
53
- <Input
54
- isDateInput
55
- label="Date"
56
- value={value}
57
- ref={ref as Ref<HTMLInputElement>}
58
- placeholder="dd/mm/yyyy"
59
- onBlur={handleDateChange}
60
- onReset={handleClearInput}
61
- onKeyDown={handleKeyDown}
62
- error={error}
63
- />
64
- <BaseCalendar
65
- selectedDate={currentDate}
66
- onDateClick={handleDateSelectAndExternalUpdate}
67
- monthDate={currentDate ?? monthDate}
68
- {...props}
69
- />
70
- </div>
71
- );
72
- };
@@ -1,10 +0,0 @@
1
- .datepicker {
2
- display: flex;
3
- flex-direction: column;
4
- gap: $gap-8;
5
- padding: $gap-8;
6
-
7
- @include themify-modules($themes) {
8
- background-color: themed('background');
9
- }
10
- }
@@ -1,75 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react';
2
- import { Day } from '.';
3
-
4
- const meta: Meta<typeof Day> = {
5
- component: Day,
6
- parameters: {
7
- layout: 'centered',
8
- },
9
- };
10
-
11
- export default meta;
12
-
13
- type Story = StoryObj<typeof Day>;
14
-
15
- export const Today: Story = {
16
- args: {
17
- date: new Date(),
18
- },
19
- };
20
-
21
- export const Selected: Story = {
22
- args: {
23
- date: new Date(2026, 7, 25),
24
- isSelected: true,
25
- },
26
- };
27
-
28
- export const Disabled: Story = {
29
- args: {
30
- date: new Date(2026, 7, 25),
31
- isDisabled: true,
32
- },
33
- };
34
-
35
- export const Holiday: Story = {
36
- args: {
37
- date: new Date(2026, 7, 25),
38
- isHoliday: true,
39
- },
40
- };
41
-
42
- export const HasTasks: Story = {
43
- args: {
44
- date: new Date(2026, 7, 25),
45
- hasTasks: true,
46
- },
47
- };
48
-
49
- export const RangeStart: Story = {
50
- args: {
51
- date: new Date(2026, 7, 25),
52
- isRangeStart: true,
53
- },
54
- };
55
-
56
- export const RangeMiddle: Story = {
57
- args: {
58
- date: new Date(2026, 7, 25),
59
- isRangeMiddle: true,
60
- },
61
- };
62
-
63
- export const RangeEnd: Story = {
64
- args: {
65
- date: new Date(2026, 7, 25),
66
- isRangeEnd: true,
67
- },
68
- };
69
-
70
- export const TodayAndHasTasks: Story = {
71
- args: {
72
- date: new Date(),
73
- hasTasks: true,
74
- },
75
- };