@daryasidorovich/modsen-datepicker 1.0.0 → 1.0.1

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 (128) hide show
  1. package/.prettierrc +6 -6
  2. package/.storybook/main.js +93 -93
  3. package/.storybook/main.ts +16 -0
  4. package/.storybook/preview.js +26 -26
  5. package/.storybook/preview.tsx +18 -18
  6. package/README.md +5 -5
  7. package/commitlint.config.js +23 -23
  8. package/package.json +1 -1
  9. package/rollup.config.js +65 -65
  10. package/src/components/BaseCalendar/BaseCalendar.stories.tsx +77 -77
  11. package/src/components/BaseCalendar/index.tsx +63 -63
  12. package/src/components/BaseCalendar/styles.module.scss +15 -15
  13. package/src/components/Button/Button.stories.tsx +16 -0
  14. package/src/components/Button/Button.tsx +14 -0
  15. package/src/components/Button/index.ts +1 -0
  16. package/src/components/Button/styles.module.scss +3 -0
  17. package/src/components/CalendarGrid/CalendarGrid.stories.tsx +136 -136
  18. package/src/components/CalendarGrid/CalendarGridWithTasks/Tooltip/index.tsx +27 -27
  19. package/src/components/CalendarGrid/CalendarGridWithTasks/Tooltip/styles.module.scss +9 -9
  20. package/src/components/CalendarGrid/CalendarGridWithTasks/index.tsx +51 -51
  21. package/src/components/CalendarGrid/CalendarGridWithoutTasks/index.tsx +36 -36
  22. package/src/components/CalendarGrid/CalendarGridWithoutTasks/styles.module.scss +11 -11
  23. package/src/components/CalendarGrid/index.tsx +19 -19
  24. package/src/components/CalendarGrid/types.ts +26 -26
  25. package/src/components/Clear/Clear.stories.tsx +16 -16
  26. package/src/components/Clear/index.tsx +12 -12
  27. package/src/components/Clear/styles.module.scss +34 -34
  28. package/src/components/DatePicker/DatePicker.stories.tsx +127 -127
  29. package/src/components/DatePicker/index.tsx +72 -72
  30. package/src/components/DatePicker/styles.module.scss +10 -10
  31. package/src/components/Day/Day.stories.tsx +75 -75
  32. package/src/components/Day/index.tsx +95 -95
  33. package/src/components/Day/styles.module.scss +97 -97
  34. package/src/components/Input/Input.stories.tsx +37 -37
  35. package/src/components/Input/index.tsx +64 -64
  36. package/src/components/Input/styles.module.scss +79 -79
  37. package/src/components/Modal/CrudModal/index.tsx +43 -43
  38. package/src/components/Modal/CrudModal/styles.module.scss +44 -44
  39. package/src/components/Modal/index.tsx +66 -66
  40. package/src/components/Modal/styles.module.scss +40 -40
  41. package/src/components/Modal/types.ts +13 -13
  42. package/src/components/Month/Month.stories.tsx +19 -19
  43. package/src/components/Month/index.tsx +31 -31
  44. package/src/components/Month/styles.module.scss +30 -30
  45. package/src/components/RangePicker/RangePicker.stories.tsx +134 -134
  46. package/src/components/RangePicker/index.tsx +144 -144
  47. package/src/components/RangePicker/styles.module.scss +19 -19
  48. package/src/components/TasksManager/AddModal/index.tsx +62 -62
  49. package/src/components/TasksManager/DeleteModal/index.tsx +22 -22
  50. package/src/components/TasksManager/EditModal/index.tsx +96 -96
  51. package/src/components/TasksManager/index.tsx +112 -112
  52. package/src/components/TasksManager/styles.module.scss +62 -62
  53. package/src/components/Week/Week.stories.tsx +49 -49
  54. package/src/components/Week/index.tsx +68 -68
  55. package/src/components/Week/styles.module.scss +7 -7
  56. package/src/components/WeekDay/WeekDay.stories.tsx +38 -38
  57. package/src/components/WeekDay/index.tsx +35 -35
  58. package/src/components/WeekDay/styles.module.scss +19 -19
  59. package/src/constants/dateMask.ts +23 -23
  60. package/src/constants/firstDayOfWeek.ts +7 -7
  61. package/src/constants/holidays.ts +32 -32
  62. package/src/constants/modes.ts +6 -6
  63. package/src/constants/monthsNames.ts +14 -14
  64. package/src/constants/weekdaysNames.ts +1 -1
  65. package/src/hooks/useCalendar.ts +62 -62
  66. package/src/hooks/useLockBodyScroll.ts +19 -19
  67. package/src/hooks/useModal.ts +45 -45
  68. package/src/hooks/useTooltip.ts +41 -41
  69. package/src/hooks/useValidate.ts +80 -80
  70. package/src/index.ts +15 -15
  71. package/src/services/calendarService.ts +62 -62
  72. package/src/services/decorators/withHolidays.ts +12 -12
  73. package/src/services/decorators/withMinMax.test.ts +77 -77
  74. package/src/services/decorators/withMinMax.ts +19 -19
  75. package/src/services/holidayService.ts +56 -56
  76. package/src/store/localStorage.ts +33 -33
  77. package/src/store/tasksStore.tsx +146 -146
  78. package/src/store/types.ts +22 -22
  79. package/src/stories/Button.stories.ts +54 -0
  80. package/src/stories/Button.tsx +37 -0
  81. package/src/stories/Configure.mdx +388 -0
  82. package/src/stories/Header.stories.ts +34 -0
  83. package/src/stories/Header.tsx +56 -0
  84. package/src/stories/Page.stories.ts +33 -0
  85. package/src/stories/Page.tsx +73 -0
  86. package/src/stories/assets/accessibility.png +0 -0
  87. package/src/stories/assets/accessibility.svg +1 -0
  88. package/src/stories/assets/addon-library.png +0 -0
  89. package/src/stories/assets/assets.png +0 -0
  90. package/src/stories/assets/avif-test-image.avif +0 -0
  91. package/src/stories/assets/context.png +0 -0
  92. package/src/stories/assets/discord.svg +1 -0
  93. package/src/stories/assets/docs.png +0 -0
  94. package/src/stories/assets/figma-plugin.png +0 -0
  95. package/src/stories/assets/github.svg +1 -0
  96. package/src/stories/assets/share.png +0 -0
  97. package/src/stories/assets/styling.png +0 -0
  98. package/src/stories/assets/testing.png +0 -0
  99. package/src/stories/assets/theming.png +0 -0
  100. package/src/stories/assets/tutorials.svg +1 -0
  101. package/src/stories/assets/youtube.svg +1 -0
  102. package/src/stories/button.css +30 -0
  103. package/src/stories/header.css +32 -0
  104. package/src/stories/page.css +68 -0
  105. package/src/styles/_border.scss +9 -9
  106. package/src/styles/_colors.scss +53 -53
  107. package/src/styles/_gap.scss +4 -4
  108. package/src/styles/_globals.scss +61 -61
  109. package/src/styles/_grid.scss +9 -9
  110. package/src/styles/_mixins.scss +6 -6
  111. package/src/styles/_reset.scss +98 -98
  112. package/src/styles/_theme-mixins.scss +51 -51
  113. package/src/styles/_typography.scss +10 -10
  114. package/src/styles/_variables.scss +8 -8
  115. package/src/styles/main.scss +3 -3
  116. package/src/types/types.d.ts +15 -15
  117. package/src/utils/calendar.test.ts +154 -154
  118. package/src/utils/calendar.ts +82 -82
  119. package/src/utils/controlDate.ts +3 -3
  120. package/src/utils/dateChecks.test.ts +216 -216
  121. package/src/utils/dateChecks.ts +75 -75
  122. package/src/utils/formatDate.ts +27 -27
  123. package/src/utils/schema.test.ts +40 -40
  124. package/src/utils/schema.ts +8 -8
  125. package/src/utils/weekdayOrder.test.ts +11 -11
  126. package/src/utils/weekdayOrder.ts +7 -7
  127. package/vitest.config.ts +38 -38
  128. package/vitest.shims.d.ts +1 -1
@@ -1,32 +1,32 @@
1
- const HOLIDAYS_RULES = [
2
- { name: 'New Year', getDate: (year: number) => new Date(year, 0, 1) },
3
- { name: 'Christmas', getDate: (year: number) => new Date(year, 11, 25) },
4
- {
5
- name: 'Chinese New Year',
6
- getDate: (year: number) => new Date(year, 1, 17),
7
- },
8
- {
9
- name: "International Women's Day",
10
- getDate: (year: number) => new Date(year, 2, 8),
11
- },
12
- {
13
- name: 'Defender of the Fatherland Day',
14
- getDate: (year: number) => new Date(year, 1, 23),
15
- },
16
- { name: "Children's Day", getDate: (year: number) => new Date(year, 5, 1) },
17
- { name: 'Labor Day', getDate: (year: number) => new Date(year, 4, 1) },
18
- {
19
- name: 'Thanksgiving Day',
20
- getDate: (year: number) => new Date(year, 10, 26),
21
- },
22
- { name: 'Easter', getDate: (year: number) => new Date(year, 3, 5) },
23
- { name: 'Boxing Day', getDate: (year: number) => new Date(year, 11, 26) },
24
- { name: 'Eid al-Fitr', getDate: (year: number) => new Date(year, 2, 20) },
25
- { name: 'Eid al-Adha', getDate: (year: number) => new Date(year, 4, 27) },
26
- { name: 'Nowruz', getDate: (year: number) => new Date(year, 2, 21) },
27
- { name: 'Bastille Day', getDate: (year: number) => new Date(year, 6, 14) },
28
- ];
29
-
30
- export const getDefaultHolidays = (year: number): Date[] => {
31
- return HOLIDAYS_RULES.map((rule) => rule.getDate(year));
32
- };
1
+ const HOLIDAYS_RULES = [
2
+ { name: 'New Year', getDate: (year: number) => new Date(year, 0, 1) },
3
+ { name: 'Christmas', getDate: (year: number) => new Date(year, 11, 25) },
4
+ {
5
+ name: 'Chinese New Year',
6
+ getDate: (year: number) => new Date(year, 1, 17),
7
+ },
8
+ {
9
+ name: "International Women's Day",
10
+ getDate: (year: number) => new Date(year, 2, 8),
11
+ },
12
+ {
13
+ name: 'Defender of the Fatherland Day',
14
+ getDate: (year: number) => new Date(year, 1, 23),
15
+ },
16
+ { name: "Children's Day", getDate: (year: number) => new Date(year, 5, 1) },
17
+ { name: 'Labor Day', getDate: (year: number) => new Date(year, 4, 1) },
18
+ {
19
+ name: 'Thanksgiving Day',
20
+ getDate: (year: number) => new Date(year, 10, 26),
21
+ },
22
+ { name: 'Easter', getDate: (year: number) => new Date(year, 3, 5) },
23
+ { name: 'Boxing Day', getDate: (year: number) => new Date(year, 11, 26) },
24
+ { name: 'Eid al-Fitr', getDate: (year: number) => new Date(year, 2, 20) },
25
+ { name: 'Eid al-Adha', getDate: (year: number) => new Date(year, 4, 27) },
26
+ { name: 'Nowruz', getDate: (year: number) => new Date(year, 2, 21) },
27
+ { name: 'Bastille Day', getDate: (year: number) => new Date(year, 6, 14) },
28
+ ];
29
+
30
+ export const getDefaultHolidays = (year: number): Date[] => {
31
+ return HOLIDAYS_RULES.map((rule) => rule.getDate(year));
32
+ };
@@ -1,6 +1,6 @@
1
- export const MODES = {
2
- WEEK: 'week',
3
- MONTH: 'month',
4
- } as const;
5
-
6
- export type MODES_TYPES = (typeof MODES)[keyof typeof MODES];
1
+ export const MODES = {
2
+ WEEK: 'week',
3
+ MONTH: 'month',
4
+ } as const;
5
+
6
+ export type MODES_TYPES = (typeof MODES)[keyof typeof MODES];
@@ -1,14 +1,14 @@
1
- export const MONTHS_NAMES = [
2
- 'January',
3
- 'February',
4
- 'March',
5
- 'April',
6
- 'May',
7
- 'June',
8
- 'July',
9
- 'August',
10
- 'September',
11
- 'October',
12
- 'November',
13
- 'December',
14
- ];
1
+ export const MONTHS_NAMES = [
2
+ 'January',
3
+ 'February',
4
+ 'March',
5
+ 'April',
6
+ 'May',
7
+ 'June',
8
+ 'July',
9
+ 'August',
10
+ 'September',
11
+ 'October',
12
+ 'November',
13
+ 'December',
14
+ ];
@@ -1 +1 @@
1
- export const WEEKDAYS_NAMES = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
1
+ export const WEEKDAYS_NAMES = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
@@ -1,62 +1,62 @@
1
- import { useEffect, useState } from 'react';
2
-
3
- import { CalendarProps } from '@/components/Calendar/types';
4
- import { getDefaultHolidays } from '@/constants/holidays';
5
- import { CalendarService } from '@/services/calendarService';
6
- import { withHolidays } from '@/services/decorators/withHolidays';
7
- import { withMinMax } from '@/services/decorators/withMinMax';
8
- import { getHolidays } from '@/services/holidayService';
9
-
10
- export function useCalendar(props: CalendarProps) {
11
- const year = props.monthDate.getFullYear();
12
- const [holidays, setHolidays] = useState<Date[]>([]);
13
- const [loading, setLoading] = useState(false);
14
- const [error, setError] = useState('');
15
-
16
- useEffect(() => {
17
- const abortController = new AbortController();
18
-
19
- if (props.showHolidays) {
20
- setLoading(true);
21
- setError('');
22
- getHolidays(year, abortController.signal)
23
- .then((result) => {
24
- setHolidays(result);
25
- })
26
- .catch((err) => {
27
- if (err.name === 'AbortError') {
28
- return;
29
- }
30
- setHolidays(getDefaultHolidays(year));
31
- setError(err.message);
32
- })
33
- .finally(() => setLoading(false));
34
- }
35
- return () => {
36
- abortController.abort();
37
- };
38
- }, [props.showHolidays, year]);
39
-
40
- const calendar: CalendarService = new CalendarService(
41
- props.monthDate,
42
- props.firstDayOfWeek,
43
- props.selectedDate,
44
- props.mode,
45
- props.rangeStart,
46
- props.rangeEnd
47
- );
48
-
49
- if (props.hideWeekends) {
50
- calendar.setHideWeekends(true);
51
- }
52
-
53
- if (props.showHolidays && holidays.length > 0) {
54
- withHolidays(calendar, holidays);
55
- }
56
-
57
- if (props.minDate || props.maxDate) {
58
- withMinMax(calendar, props.minDate, props.maxDate);
59
- }
60
-
61
- return { calendar, loading, error };
62
- }
1
+ import { useEffect, useState } from 'react';
2
+
3
+ import { CalendarProps } from '@/components/Calendar/types';
4
+ import { getDefaultHolidays } from '@/constants/holidays';
5
+ import { CalendarService } from '@/services/calendarService';
6
+ import { withHolidays } from '@/services/decorators/withHolidays';
7
+ import { withMinMax } from '@/services/decorators/withMinMax';
8
+ import { getHolidays } from '@/services/holidayService';
9
+
10
+ export function useCalendar(props: CalendarProps) {
11
+ const year = props.monthDate.getFullYear();
12
+ const [holidays, setHolidays] = useState<Date[]>([]);
13
+ const [loading, setLoading] = useState(false);
14
+ const [error, setError] = useState('');
15
+
16
+ useEffect(() => {
17
+ const abortController = new AbortController();
18
+
19
+ if (props.showHolidays) {
20
+ setLoading(true);
21
+ setError('');
22
+ getHolidays(year, abortController.signal)
23
+ .then((result) => {
24
+ setHolidays(result);
25
+ })
26
+ .catch((err) => {
27
+ if (err.name === 'AbortError') {
28
+ return;
29
+ }
30
+ setHolidays(getDefaultHolidays(year));
31
+ setError(err.message);
32
+ })
33
+ .finally(() => setLoading(false));
34
+ }
35
+ return () => {
36
+ abortController.abort();
37
+ };
38
+ }, [props.showHolidays, year]);
39
+
40
+ const calendar: CalendarService = new CalendarService(
41
+ props.monthDate,
42
+ props.firstDayOfWeek,
43
+ props.selectedDate,
44
+ props.mode,
45
+ props.rangeStart,
46
+ props.rangeEnd
47
+ );
48
+
49
+ if (props.hideWeekends) {
50
+ calendar.setHideWeekends(true);
51
+ }
52
+
53
+ if (props.showHolidays && holidays.length > 0) {
54
+ withHolidays(calendar, holidays);
55
+ }
56
+
57
+ if (props.minDate || props.maxDate) {
58
+ withMinMax(calendar, props.minDate, props.maxDate);
59
+ }
60
+
61
+ return { calendar, loading, error };
62
+ }
@@ -1,19 +1,19 @@
1
- import { useEffect } from 'react';
2
-
3
- export const useLockBodyScroll = (isLocked: boolean) => {
4
- useEffect(() => {
5
- const originalOverflow = document.body.style.overflow;
6
-
7
- if (isLocked) {
8
- document.body.style.overflow = 'hidden';
9
- } else {
10
- document.body.style.overflow = 'unset';
11
- }
12
-
13
- return () => {
14
- document.body.style.overflow = originalOverflow;
15
- };
16
- }, [isLocked]);
17
- };
18
-
19
- export default useLockBodyScroll;
1
+ import { useEffect } from 'react';
2
+
3
+ export const useLockBodyScroll = (isLocked: boolean) => {
4
+ useEffect(() => {
5
+ const originalOverflow = document.body.style.overflow;
6
+
7
+ if (isLocked) {
8
+ document.body.style.overflow = 'hidden';
9
+ } else {
10
+ document.body.style.overflow = 'unset';
11
+ }
12
+
13
+ return () => {
14
+ document.body.style.overflow = originalOverflow;
15
+ };
16
+ }, [isLocked]);
17
+ };
18
+
19
+ export default useLockBodyScroll;
@@ -1,45 +1,45 @@
1
- import { useState } from 'react';
2
-
3
- interface UseModalOptions {
4
- initial?: boolean;
5
- onOpen?: () => void;
6
- onClose?: () => void;
7
- }
8
-
9
- export const useModal = (options: UseModalOptions = {}) => {
10
- const { initial = false, onOpen, onClose } = options;
11
- const [isOpen, setIsOpen] = useState(initial);
12
-
13
- const open = () => {
14
- onOpen?.();
15
- setIsOpen(true);
16
- };
17
-
18
- const close = () => {
19
- onClose?.();
20
- setIsOpen(false);
21
- };
22
-
23
- const toggle = () => {
24
- setIsOpen((prev) => {
25
- const newState = !prev;
26
- if (newState) {
27
- onOpen?.();
28
- } else {
29
- onClose?.();
30
- }
31
- return newState;
32
- });
33
- };
34
-
35
- const setOpen = (value: boolean) => {
36
- if (value) {
37
- onOpen?.();
38
- } else {
39
- onClose?.();
40
- }
41
- setIsOpen(value);
42
- };
43
-
44
- return { isOpen, open, close, toggle, setOpen };
45
- };
1
+ import { useState } from 'react';
2
+
3
+ interface UseModalOptions {
4
+ initial?: boolean;
5
+ onOpen?: () => void;
6
+ onClose?: () => void;
7
+ }
8
+
9
+ export const useModal = (options: UseModalOptions = {}) => {
10
+ const { initial = false, onOpen, onClose } = options;
11
+ const [isOpen, setIsOpen] = useState(initial);
12
+
13
+ const open = () => {
14
+ onOpen?.();
15
+ setIsOpen(true);
16
+ };
17
+
18
+ const close = () => {
19
+ onClose?.();
20
+ setIsOpen(false);
21
+ };
22
+
23
+ const toggle = () => {
24
+ setIsOpen((prev) => {
25
+ const newState = !prev;
26
+ if (newState) {
27
+ onOpen?.();
28
+ } else {
29
+ onClose?.();
30
+ }
31
+ return newState;
32
+ });
33
+ };
34
+
35
+ const setOpen = (value: boolean) => {
36
+ if (value) {
37
+ onOpen?.();
38
+ } else {
39
+ onClose?.();
40
+ }
41
+ setIsOpen(value);
42
+ };
43
+
44
+ return { isOpen, open, close, toggle, setOpen };
45
+ };
@@ -1,41 +1,41 @@
1
- import { useRef, useState } from 'react';
2
-
3
- export const useTooltip = () => {
4
- const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
5
-
6
- const [tooltip, setTooltip] = useState({
7
- isVisible: false,
8
- x: 0,
9
- y: 0,
10
- });
11
-
12
- const handleDayMouseEnter = (e: React.MouseEvent<HTMLButtonElement>) => {
13
- const rect = e.currentTarget.getBoundingClientRect();
14
- const coords = {
15
- x: rect.right - 5,
16
- y: rect.top - 10,
17
- };
18
-
19
- if (timeoutRef.current) {
20
- clearTimeout(timeoutRef.current);
21
- }
22
-
23
- timeoutRef.current = setTimeout(() => {
24
- setTooltip({
25
- isVisible: true,
26
- x: coords.x,
27
- y: coords.y,
28
- });
29
- }, 500);
30
- };
31
-
32
- const handleDayMouseLeave = () => {
33
- if (timeoutRef.current) {
34
- clearTimeout(timeoutRef.current);
35
- }
36
-
37
- setTooltip((prev) => ({ ...prev, isVisible: false }));
38
- };
39
-
40
- return { tooltip, handleDayMouseEnter, handleDayMouseLeave };
41
- };
1
+ import { useRef, useState } from 'react';
2
+
3
+ export const useTooltip = () => {
4
+ const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
5
+
6
+ const [tooltip, setTooltip] = useState({
7
+ isVisible: false,
8
+ x: 0,
9
+ y: 0,
10
+ });
11
+
12
+ const handleDayMouseEnter = (e: React.MouseEvent<HTMLButtonElement>) => {
13
+ const rect = e.currentTarget.getBoundingClientRect();
14
+ const coords = {
15
+ x: rect.right - 5,
16
+ y: rect.top - 10,
17
+ };
18
+
19
+ if (timeoutRef.current) {
20
+ clearTimeout(timeoutRef.current);
21
+ }
22
+
23
+ timeoutRef.current = setTimeout(() => {
24
+ setTooltip({
25
+ isVisible: true,
26
+ x: coords.x,
27
+ y: coords.y,
28
+ });
29
+ }, 500);
30
+ };
31
+
32
+ const handleDayMouseLeave = () => {
33
+ if (timeoutRef.current) {
34
+ clearTimeout(timeoutRef.current);
35
+ }
36
+
37
+ setTooltip((prev) => ({ ...prev, isVisible: false }));
38
+ };
39
+
40
+ return { tooltip, handleDayMouseEnter, handleDayMouseLeave };
41
+ };
@@ -1,80 +1,80 @@
1
- import { useEffect, useState } from 'react';
2
- import { useIMask } from 'react-imask';
3
-
4
- import { DATE_MASK } from '@/constants/dateMask';
5
- import { getRangeError } from '@/utils/dateChecks';
6
- import { formatDateForInput, parseDate } from '@/utils/formatDate';
7
-
8
- export function useValidate(selectedDate: Date | undefined) {
9
- const [currentDate, setCurrentDate] = useState(selectedDate);
10
- const [error, setError] = useState('');
11
- const { ref, value, setValue } = useIMask(DATE_MASK);
12
-
13
- useEffect(() => {
14
- setCurrentDate(selectedDate);
15
- if (selectedDate) {
16
- setValue(formatDateForInput(selectedDate));
17
- } else {
18
- setValue('');
19
- }
20
- }, [selectedDate, setValue]);
21
-
22
- const handleDateValidation = (
23
- value: string,
24
- startDate?: Date
25
- ): Date | undefined => {
26
- if (!value) {
27
- setError('');
28
- setCurrentDate(undefined);
29
- return;
30
- }
31
- const parsed = parseDate(value);
32
-
33
- if (!parsed) {
34
- setError('Invalid date');
35
- setCurrentDate(undefined);
36
- return;
37
- }
38
-
39
- if (startDate) {
40
- const rangeError = getRangeError(parsed, startDate);
41
- if (rangeError) {
42
- setError(rangeError);
43
- setCurrentDate(undefined);
44
- return;
45
- }
46
- }
47
-
48
- setError('');
49
- setCurrentDate(parsed);
50
- return parsed;
51
- };
52
-
53
- const handleClearInput = () => {
54
- setCurrentDate(undefined);
55
- setValue('');
56
- setError('');
57
- };
58
-
59
- const handleDateSelect = (date?: Date) => {
60
- setCurrentDate(date);
61
- if (!date) {
62
- setValue('');
63
- return;
64
- }
65
- setValue(formatDateForInput(date));
66
- setError('');
67
- };
68
-
69
- return {
70
- currentDate,
71
- setCurrentDate,
72
- handleDateValidation,
73
- handleClearInput,
74
- handleDateSelect,
75
- ref,
76
- value,
77
- setValue,
78
- error,
79
- };
80
- }
1
+ import { useEffect, useState } from 'react';
2
+ import { useIMask } from 'react-imask';
3
+
4
+ import { DATE_MASK } from '@/constants/dateMask';
5
+ import { getRangeError } from '@/utils/dateChecks';
6
+ import { formatDateForInput, parseDate } from '@/utils/formatDate';
7
+
8
+ export function useValidate(selectedDate: Date | undefined) {
9
+ const [currentDate, setCurrentDate] = useState(selectedDate);
10
+ const [error, setError] = useState('');
11
+ const { ref, value, setValue } = useIMask(DATE_MASK);
12
+
13
+ useEffect(() => {
14
+ setCurrentDate(selectedDate);
15
+ if (selectedDate) {
16
+ setValue(formatDateForInput(selectedDate));
17
+ } else {
18
+ setValue('');
19
+ }
20
+ }, [selectedDate, setValue]);
21
+
22
+ const handleDateValidation = (
23
+ value: string,
24
+ startDate?: Date
25
+ ): Date | undefined => {
26
+ if (!value) {
27
+ setError('');
28
+ setCurrentDate(undefined);
29
+ return;
30
+ }
31
+ const parsed = parseDate(value);
32
+
33
+ if (!parsed) {
34
+ setError('Invalid date');
35
+ setCurrentDate(undefined);
36
+ return;
37
+ }
38
+
39
+ if (startDate) {
40
+ const rangeError = getRangeError(parsed, startDate);
41
+ if (rangeError) {
42
+ setError(rangeError);
43
+ setCurrentDate(undefined);
44
+ return;
45
+ }
46
+ }
47
+
48
+ setError('');
49
+ setCurrentDate(parsed);
50
+ return parsed;
51
+ };
52
+
53
+ const handleClearInput = () => {
54
+ setCurrentDate(undefined);
55
+ setValue('');
56
+ setError('');
57
+ };
58
+
59
+ const handleDateSelect = (date?: Date) => {
60
+ setCurrentDate(date);
61
+ if (!date) {
62
+ setValue('');
63
+ return;
64
+ }
65
+ setValue(formatDateForInput(date));
66
+ setError('');
67
+ };
68
+
69
+ return {
70
+ currentDate,
71
+ setCurrentDate,
72
+ handleDateValidation,
73
+ handleClearInput,
74
+ handleDateSelect,
75
+ ref,
76
+ value,
77
+ setValue,
78
+ error,
79
+ };
80
+ }
package/src/index.ts CHANGED
@@ -1,15 +1,15 @@
1
- import { FIRST_DAY_OF_WEEK } from './constants/firstDayOfWeek';
2
- import { MODES } from './constants/modes';
3
-
4
- export { BaseCalendar } from './components/BaseCalendar';
5
- export type {
6
- BaseCalendarProps,
7
- CalendarProps,
8
- } from './components/Calendar/types';
9
- export type { DatePickerProps } from './components/DatePicker';
10
- export { DatePicker } from './components/DatePicker';
11
- export type { RangePickerProps } from './components/RangePicker';
12
- export { RangePicker } from './components/RangePicker';
13
- export type { FIRST_DAY_OF_WEEK_TYPES } from './constants/firstDayOfWeek';
14
- export type { MODES_TYPES } from './constants/modes';
15
- export { FIRST_DAY_OF_WEEK, MODES };
1
+ import { FIRST_DAY_OF_WEEK } from './constants/firstDayOfWeek';
2
+ import { MODES } from './constants/modes';
3
+
4
+ export { BaseCalendar } from './components/BaseCalendar';
5
+ export type {
6
+ BaseCalendarProps,
7
+ CalendarProps,
8
+ } from './components/Calendar/types';
9
+ export type { DatePickerProps } from './components/DatePicker';
10
+ export { DatePicker } from './components/DatePicker';
11
+ export type { RangePickerProps } from './components/RangePicker';
12
+ export { RangePicker } from './components/RangePicker';
13
+ export type { FIRST_DAY_OF_WEEK_TYPES } from './constants/firstDayOfWeek';
14
+ export type { MODES_TYPES } from './constants/modes';
15
+ export { FIRST_DAY_OF_WEEK, MODES };