@scbt-ecom/ui 0.4.0 → 0.4.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 (298) hide show
  1. package/.env +3 -0
  2. package/.github/workflows/publish.yml +61 -0
  3. package/.github/workflows/setup-node/action.yml +22 -0
  4. package/.husky/pre-commit +1 -0
  5. package/.prettierignore +1 -0
  6. package/.prettierrc +20 -0
  7. package/.releaserc +18 -0
  8. package/.storybook/main.ts +44 -0
  9. package/.storybook/preview.tsx +37 -0
  10. package/chromatic.config.json +5 -0
  11. package/eslint.config.mjs +193 -0
  12. package/index.html +13 -0
  13. package/lib/client.ts +12 -0
  14. package/lib/configs/index.ts +2 -0
  15. package/lib/configs/tailwindConfigBase.ts +110 -0
  16. package/lib/configs/tailwindPresets/extendsPreset.ts +43 -0
  17. package/lib/configs/tailwindPresets/index.ts +2 -0
  18. package/lib/configs/tailwindPresets/resetPreset.ts +71 -0
  19. package/lib/hybrid.ts +25 -0
  20. package/lib/shared/constants/api.ts +2 -0
  21. package/lib/shared/constants/designSystem/colors.ts +121 -0
  22. package/lib/shared/constants/designSystem/index.ts +3 -0
  23. package/lib/shared/constants/designSystem/others.ts +30 -0
  24. package/lib/shared/constants/designSystem/typography.ts +88 -0
  25. package/lib/shared/constants/index.ts +2 -0
  26. package/lib/shared/hooks/index.ts +5 -0
  27. package/lib/shared/hooks/useBoolean.ts +12 -0
  28. package/lib/shared/hooks/useClickOutside.ts +22 -0
  29. package/lib/shared/hooks/useCombineRef.ts +23 -0
  30. package/lib/shared/hooks/useControlledForm.ts +16 -0
  31. package/lib/shared/hooks/useDebounce.ts +38 -0
  32. package/lib/shared/hooks/useMediaQuery.tsx +42 -0
  33. package/lib/shared/style.css +118 -0
  34. package/lib/shared/ui/Badge.tsx +20 -0
  35. package/lib/shared/ui/Breadcrumbs.tsx +57 -0
  36. package/lib/shared/ui/ButtonIcon.tsx +50 -0
  37. package/lib/shared/ui/CustomLink.tsx +76 -0
  38. package/lib/shared/ui/Document.tsx +51 -0
  39. package/lib/shared/ui/Heading.tsx +33 -0
  40. package/lib/shared/ui/Hint.tsx +72 -0
  41. package/lib/shared/ui/Loader.tsx +58 -0
  42. package/lib/shared/ui/PhoneView.tsx +23 -0
  43. package/lib/shared/ui/ProgressBar.tsx +43 -0
  44. package/lib/shared/ui/ResponsiveContainer.tsx +15 -0
  45. package/lib/shared/ui/Section.tsx +15 -0
  46. package/lib/shared/ui/Skeleton.tsx +9 -0
  47. package/lib/shared/ui/TabsSwitcher.tsx +87 -0
  48. package/lib/shared/ui/accordion/Accordion.tsx +36 -0
  49. package/lib/shared/ui/accordion/index.ts +1 -0
  50. package/lib/shared/ui/accordion/model/types.ts +20 -0
  51. package/lib/shared/ui/accordion/ui/AccordionHeader.tsx +35 -0
  52. package/lib/shared/ui/brandLogos.tsx +14 -0
  53. package/lib/shared/ui/button/Button.tsx +117 -0
  54. package/lib/shared/ui/button/index.ts +1 -0
  55. package/lib/shared/ui/button/model/helpers.ts +16 -0
  56. package/lib/shared/ui/formControlElements/CheckboxControl.tsx +92 -0
  57. package/lib/shared/ui/formControlElements/FormControl.tsx +5 -0
  58. package/lib/shared/ui/formControlElements/InputControlMask.tsx +90 -0
  59. package/lib/shared/ui/formControlElements/RadioControl.tsx +130 -0
  60. package/lib/shared/ui/formControlElements/SwitchControl.tsx +79 -0
  61. package/lib/shared/ui/formControlElements/TextareaControl.tsx +96 -0
  62. package/lib/shared/ui/formControlElements/calendarControl/CalendarControl.tsx +178 -0
  63. package/lib/shared/ui/formControlElements/calendarControl/hooks/index.ts +2 -0
  64. package/lib/shared/ui/formControlElements/calendarControl/hooks/useCalendar.tsx +86 -0
  65. package/lib/shared/ui/formControlElements/calendarControl/hooks/useCalendarDropdowns.ts +38 -0
  66. package/lib/shared/ui/formControlElements/calendarControl/index.ts +1 -0
  67. package/lib/shared/ui/formControlElements/calendarControl/model/helpers.ts +60 -0
  68. package/lib/shared/ui/formControlElements/calendarControl/model/types.ts +44 -0
  69. package/lib/shared/ui/formControlElements/calendarControl/ui/DaysOfMonth.tsx +53 -0
  70. package/lib/shared/ui/formControlElements/calendarControl/ui/DaysOfWeek.tsx +28 -0
  71. package/lib/shared/ui/formControlElements/calendarControl/ui/Dropdown.tsx +62 -0
  72. package/lib/shared/ui/formControlElements/calendarControl/ui/Header.tsx +51 -0
  73. package/lib/shared/ui/formControlElements/calendarControl/ui/Navigation.tsx +32 -0
  74. package/lib/shared/ui/formControlElements/calendarControl/ui/OptionsList.tsx +44 -0
  75. package/lib/shared/ui/formControlElements/calendarControl/ui/index.ts +4 -0
  76. package/lib/shared/ui/formControlElements/comboboxControl/ComboboxControl.tsx +134 -0
  77. package/lib/shared/ui/formControlElements/comboboxControl/index.ts +1 -0
  78. package/lib/shared/ui/formControlElements/comboboxControl/model/selectClassnames.ts +51 -0
  79. package/lib/shared/ui/formControlElements/comboboxControl/model/types.ts +42 -0
  80. package/lib/shared/ui/formControlElements/comboboxControl/ui/ComboboxOption.tsx +38 -0
  81. package/lib/shared/ui/formControlElements/comboboxControl/ui/DropdownIndicator.tsx +23 -0
  82. package/lib/shared/ui/formControlElements/comboboxControl/ui/MultiValueRemove.tsx +16 -0
  83. package/lib/shared/ui/formControlElements/comboboxControl/ui/index.ts +3 -0
  84. package/lib/shared/ui/formControlElements/dadata/DadataInputControl.tsx +137 -0
  85. package/lib/shared/ui/formControlElements/dadata/index.ts +1 -0
  86. package/lib/shared/ui/formControlElements/dadata/model/api.ts +25 -0
  87. package/lib/shared/ui/formControlElements/dadata/model/helpers.ts +76 -0
  88. package/lib/shared/ui/formControlElements/dadata/model/types.ts +52 -0
  89. package/lib/shared/ui/formControlElements/dadata/model/useDadata.ts +25 -0
  90. package/lib/shared/ui/formControlElements/editorControl/EditorControl.tsx +82 -0
  91. package/lib/shared/ui/formControlElements/editorControl/components/conrols.tsx +136 -0
  92. package/lib/shared/ui/formControlElements/editorControl/components/menu.tsx +107 -0
  93. package/lib/shared/ui/formControlElements/editorControl/index.ts +60 -0
  94. package/lib/shared/ui/formControlElements/editorControl/ui/RemoveBlockButton.tsx +23 -0
  95. package/lib/shared/ui/formControlElements/editorControl/ui/ResetBlockType.tsx +17 -0
  96. package/lib/shared/ui/formControlElements/index.ts +14 -0
  97. package/lib/shared/ui/formControlElements/inputControl/InputControl.tsx +87 -0
  98. package/lib/shared/ui/formControlElements/inputControl/index.ts +1 -0
  99. package/lib/shared/ui/formControlElements/inputControl/model/hooks.tsx +26 -0
  100. package/lib/shared/ui/formControlElements/inputControlUploader/InputControlUploader.tsx +47 -0
  101. package/lib/shared/ui/formControlElements/inputControlUploader/index.ts +1 -0
  102. package/lib/shared/ui/formControlElements/inputControlUploader/model/helpers.ts +18 -0
  103. package/lib/shared/ui/formControlElements/inputControlUploader/model/hooks/useUploader.tsx +66 -0
  104. package/lib/shared/ui/formControlElements/inputControlUploader/model/index.ts +1 -0
  105. package/lib/shared/ui/formControlElements/inputControlUploader/model/types.ts +22 -0
  106. package/lib/shared/ui/formControlElements/inputControlUploader/ui/File.tsx +35 -0
  107. package/lib/shared/ui/formControlElements/inputControlUploader/ui/Filename.tsx +40 -0
  108. package/lib/shared/ui/formControlElements/inputControlUploader/ui/Files.tsx +30 -0
  109. package/lib/shared/ui/formControlElements/inputControlUploader/ui/Input.tsx +48 -0
  110. package/lib/shared/ui/formControlElements/inputControlUploader/ui/Uploader.tsx +58 -0
  111. package/lib/shared/ui/formControlElements/inputControlUploader/ui/index.ts +3 -0
  112. package/lib/shared/ui/formControlElements/inputCurrencyControl/InputCurrencyControl.tsx +88 -0
  113. package/lib/shared/ui/formControlElements/inputCurrencyControl/index.ts +1 -0
  114. package/lib/shared/ui/formControlElements/inputCurrencyControl/model/helpers.ts +46 -0
  115. package/lib/shared/ui/formControlElements/inputCurrencyControl/model/useInputCurrency.tsx +33 -0
  116. package/lib/shared/ui/formControlElements/inputCurrencyControl/ui/MenuTrigger.tsx +20 -0
  117. package/lib/shared/ui/formControlElements/inputCurrencyControl/ui/OptionList.tsx +29 -0
  118. package/lib/shared/ui/formControlElements/inputCurrencyControl/ui/index.ts +2 -0
  119. package/lib/shared/ui/formControlElements/inputSliderControl/InputSliderControl.tsx +144 -0
  120. package/lib/shared/ui/formControlElements/inputSliderControl/index.ts +1 -0
  121. package/lib/shared/ui/formControlElements/inputSliderControl/model/helpers/dates/getEndWordMonth.ts +14 -0
  122. package/lib/shared/ui/formControlElements/inputSliderControl/model/helpers/dates/getYearEnding.ts +13 -0
  123. package/lib/shared/ui/formControlElements/inputSliderControl/model/helpers/dates/index.ts +2 -0
  124. package/lib/shared/ui/formControlElements/inputSliderControl/model/helpers/formatNumber.ts +6 -0
  125. package/lib/shared/ui/formControlElements/inputSliderControl/model/helpers/getInputSliderSuffix.ts +20 -0
  126. package/lib/shared/ui/formControlElements/inputSliderControl/model/helpers/getStepByVariant.ts +29 -0
  127. package/lib/shared/ui/formControlElements/inputSliderControl/model/helpers/index.ts +4 -0
  128. package/lib/shared/ui/formControlElements/inputSliderControl/model/types.ts +1 -0
  129. package/lib/shared/ui/formControlElements/inputSliderControl/model/useSlider.ts +26 -0
  130. package/lib/shared/ui/formControlElements/inputSliderControl/ui/SliderControl.tsx +47 -0
  131. package/lib/shared/ui/formControlElements/inputSliderControl/ui/index.ts +1 -0
  132. package/lib/shared/ui/formControlElements/model/classes-types.ts +22 -0
  133. package/lib/shared/ui/formControlElements/model/index.ts +2 -0
  134. package/lib/shared/ui/formControlElements/model/message-view-animation.ts +6 -0
  135. package/lib/shared/ui/formControlElements/model/props-types.ts +31 -0
  136. package/lib/shared/ui/formControlElements/ui/FieldAttachment.tsx +76 -0
  137. package/lib/shared/ui/formControlElements/ui/FieldContainer.tsx +37 -0
  138. package/lib/shared/ui/formControlElements/ui/FieldWrapper.tsx +33 -0
  139. package/lib/shared/ui/formControlElements/ui/Label.tsx +32 -0
  140. package/lib/shared/ui/formControlElements/ui/MessageView.tsx +41 -0
  141. package/lib/shared/ui/formControlElements/ui/index.ts +4 -0
  142. package/lib/shared/ui/icon/Icon.tsx +41 -0
  143. package/lib/shared/ui/icon/index.ts +2 -0
  144. package/lib/shared/ui/icon/sprite.gen.ts +177 -0
  145. package/lib/shared/ui/index.ts +68 -0
  146. package/lib/shared/ui/modal/Modal.tsx +68 -0
  147. package/lib/shared/ui/modal/index.ts +1 -0
  148. package/lib/shared/ui/modal/model/helpers.ts +13 -0
  149. package/lib/shared/ui/modal/ui/ModalHeader.tsx +33 -0
  150. package/lib/shared/ui/notification/Notification.tsx +31 -0
  151. package/lib/shared/ui/notification/index.ts +1 -0
  152. package/lib/shared/ui/notification/ui/CustomToast.tsx +42 -0
  153. package/lib/shared/ui/popover/Popover.tsx +74 -0
  154. package/lib/shared/ui/popover/index.ts +1 -0
  155. package/lib/shared/ui/providers/NotificationProvider.tsx +29 -0
  156. package/lib/shared/ui/providers/index.ts +1 -0
  157. package/lib/shared/ui/table/Table.tsx +144 -0
  158. package/lib/shared/ui/table/index.ts +1 -0
  159. package/lib/shared/ui/table/type.ts +30 -0
  160. package/lib/shared/utils/capitalize.ts +6 -0
  161. package/lib/shared/utils/cn.ts +6 -0
  162. package/lib/shared/utils/deepCompare.ts +1 -0
  163. package/lib/shared/utils/formatToDate.ts +5 -0
  164. package/lib/shared/utils/index.ts +5 -0
  165. package/lib/shared/utils/isClient.ts +1 -0
  166. package/lib/shared/validation/index.ts +3 -0
  167. package/lib/shared/validation/messages.ts +12 -0
  168. package/lib/shared/validation/regExp.ts +5 -0
  169. package/lib/shared/validation/zodValidation/calendar.ts +32 -0
  170. package/lib/shared/validation/zodValidation/dadataFio.ts +67 -0
  171. package/lib/shared/validation/zodValidation/index.ts +2 -0
  172. package/lib/vite-env.d.ts +2 -0
  173. package/lib/widgets/Advantages.tsx +45 -0
  174. package/lib/widgets/banner/Banner.tsx +74 -0
  175. package/lib/widgets/banner/index.ts +1 -0
  176. package/lib/widgets/banner/model/helpers.ts +159 -0
  177. package/lib/widgets/banner/money.png +0 -0
  178. package/lib/widgets/banner/saif.jpg +0 -0
  179. package/lib/widgets/banner/saifMob.jpg +0 -0
  180. package/lib/widgets/banner/seif.jpg +0 -0
  181. package/lib/widgets/banner/shield.jpg +0 -0
  182. package/lib/widgets/banner/shield.png +0 -0
  183. package/lib/widgets/banner/ui/BannerButtonsGroup.tsx +44 -0
  184. package/lib/widgets/banner/ui/banners/BannerImageFull.tsx +82 -0
  185. package/lib/widgets/banner/ui/banners/BannerWithSeparateImg.tsx +60 -0
  186. package/lib/widgets/banner/ui/banners/index.ts +1 -0
  187. package/lib/widgets/footer/Footer.tsx +95 -0
  188. package/lib/widgets/footer/index.ts +1 -0
  189. package/lib/widgets/footer/model/defaultValues.tsx +105 -0
  190. package/lib/widgets/footer/model/types.ts +19 -0
  191. package/lib/widgets/footer/ui/Copyright.tsx +15 -0
  192. package/lib/widgets/footer/ui/Ligal.tsx +50 -0
  193. package/lib/widgets/footer/ui/NavLinks.tsx +41 -0
  194. package/lib/widgets/footer/ui/PhonesBlock.tsx +34 -0
  195. package/lib/widgets/footer/ui/SocialLinks.tsx +30 -0
  196. package/lib/widgets/footer/ui/index.ts +5 -0
  197. package/lib/widgets/index.ts +5 -0
  198. package/lib/widgets/pageHeader/PageHeader.tsx +54 -0
  199. package/lib/widgets/pageHeader/index.ts +1 -0
  200. package/lib/widgets/stepper/Stepper.tsx +43 -0
  201. package/lib/widgets/stepper/index.ts +1 -0
  202. package/lib/widgets/stepper/ui/SingleStep.tsx +42 -0
  203. package/package.json +1 -4
  204. package/postcss.config.mjs +8 -0
  205. package/public/sprites/arrows.svg +1 -0
  206. package/public/sprites/brandLogos.svg +1 -0
  207. package/public/sprites/files.svg +1 -0
  208. package/public/sprites/general.svg +1 -0
  209. package/public/sprites/info.svg +1 -0
  210. package/public/sprites/social.svg +1 -0
  211. package/src/App.tsx +9 -0
  212. package/src/app/providers/RootProvider.tsx +11 -0
  213. package/src/app/providers/index.ts +1 -0
  214. package/src/app/providers/model/types.ts +5 -0
  215. package/src/configs/setup.ts +9 -0
  216. package/src/configs/storybook.config.ts +23 -0
  217. package/src/main.tsx +10 -0
  218. package/src/stories/primitives/Accordion.stories.tsx +66 -0
  219. package/src/stories/primitives/Badge.stories.tsx +28 -0
  220. package/src/stories/primitives/Breadcrumbs.stories.tsx +29 -0
  221. package/src/stories/primitives/Button/Button.stories.tsx +149 -0
  222. package/src/stories/primitives/Button/Button.test.tsx +150 -0
  223. package/src/stories/primitives/ButtonIcon.stories.tsx +75 -0
  224. package/src/stories/primitives/CustomLink.stories.tsx +64 -0
  225. package/src/stories/primitives/Document.stories.tsx +36 -0
  226. package/src/stories/primitives/Heading.stories.tsx +29 -0
  227. package/src/stories/primitives/Hint.stories.tsx +82 -0
  228. package/src/stories/primitives/Icon.stories.tsx +36 -0
  229. package/src/stories/primitives/Loader.stories.tsx +39 -0
  230. package/src/stories/primitives/Modal.stories.tsx +106 -0
  231. package/src/stories/primitives/Notification.stories.tsx +102 -0
  232. package/src/stories/primitives/PhoneView.stories.tsx +22 -0
  233. package/src/stories/primitives/Popover.stories.tsx +41 -0
  234. package/src/stories/primitives/ProgressBar.stories.tsx +68 -0
  235. package/src/stories/primitives/Skeleton.stories.tsx +21 -0
  236. package/src/stories/primitives/Table.stories.tsx +44 -0
  237. package/src/stories/primitives/TabsSwitcher.stories.tsx +45 -0
  238. package/src/stories/primitives/formControl/CalendarControl.stories.tsx +45 -0
  239. package/src/stories/primitives/formControl/CheckboxControl.stories.tsx +64 -0
  240. package/src/stories/primitives/formControl/ComboboxControl.stories.tsx +67 -0
  241. package/src/stories/primitives/formControl/DadataInputControl.stories.tsx +79 -0
  242. package/src/stories/primitives/formControl/EditorControl.stories.tsx +31 -0
  243. package/src/stories/primitives/formControl/FormControlAllFields.stories.tsx +25 -0
  244. package/src/stories/primitives/formControl/InputControl.stories.tsx +84 -0
  245. package/src/stories/primitives/formControl/InputControlPassword.stories.tsx +38 -0
  246. package/src/stories/primitives/formControl/InputControlUploader.stories.tsx +44 -0
  247. package/src/stories/primitives/formControl/InputCurrencyControl.stories.tsx +73 -0
  248. package/src/stories/primitives/formControl/InputSliderControl.stories.tsx +62 -0
  249. package/src/stories/primitives/formControl/RadioContol.stories.tsx +61 -0
  250. package/src/stories/primitives/formControl/SwitchControl.stories.tsx +51 -0
  251. package/src/stories/primitives/formControl/TextareaControl.stories.tsx +55 -0
  252. package/src/stories/primitives/formControl/inputControlMask.stories.tsx +67 -0
  253. package/src/stories/widgets/Advantages.stories.tsx +42 -0
  254. package/src/stories/widgets/Banner.stories.tsx +94 -0
  255. package/src/stories/widgets/Footer.stories.tsx +36 -0
  256. package/src/stories/widgets/PageHeader.stories.tsx +33 -0
  257. package/src/stories/widgets/Stepper.stories.tsx +24 -0
  258. package/src/storybookHelpers/actions.tsx +5 -0
  259. package/src/storybookHelpers/index.ts +2 -0
  260. package/src/storybookHelpers/reactHookForm/index.ts +3 -0
  261. package/src/storybookHelpers/reactHookForm/model/mockData.ts +19 -0
  262. package/src/storybookHelpers/reactHookForm/model/mocks.tsx +105 -0
  263. package/src/storybookHelpers/reactHookForm/model/renderFields.tsx +58 -0
  264. package/src/storybookHelpers/reactHookForm/model/types.ts +86 -0
  265. package/src/storybookHelpers/reactHookForm/ui/StorybookFieldsMapper.tsx +32 -0
  266. package/src/storybookHelpers/reactHookForm/ui/StorybookFormProvider.tsx +43 -0
  267. package/src/storybookHelpers/reactHookForm/ui/index.ts +2 -0
  268. package/src/storybookHelpers/table/utils/defaultValue.ts +51 -0
  269. package/static/arrows/arrowCircle.svg +18 -0
  270. package/static/arrows/arrowLink.svg +3 -0
  271. package/static/arrows/arrowRight.svg +3 -0
  272. package/static/brandLogos/logoBlack.svg +14 -0
  273. package/static/brandLogos/logoBusiness.svg +80 -0
  274. package/static/brandLogos/logoGray.svg +56 -0
  275. package/static/brandLogos/logoInsurance.svg +124 -0
  276. package/static/brandLogos/logoMain.svg +14 -0
  277. package/static/brandLogos/logoWhite.svg +56 -0
  278. package/static/files/border.svg +6 -0
  279. package/static/files/borderError.svg +6 -0
  280. package/static/files/documentFilled.svg +4 -0
  281. package/static/files/documentOutline.svg +4 -0
  282. package/static/files/upload.svg +3 -0
  283. package/static/general/calendar.svg +3 -0
  284. package/static/general/check.svg +6 -0
  285. package/static/general/close.svg +12 -0
  286. package/static/general/edit.svg +4 -0
  287. package/static/general/hiddenEye.svg +4 -0
  288. package/static/general/plus.svg +3 -0
  289. package/static/general/showEye.svg +4 -0
  290. package/static/info/warningCircle.svg +5 -0
  291. package/static/social/classmates.svg +3 -0
  292. package/static/social/telegram.svg +3 -0
  293. package/static/social/vk.svg +3 -0
  294. package/tailwind.config.ts +10 -0
  295. package/tsconfig.json +33 -0
  296. package/tsconfig.node.json +11 -0
  297. package/vite.config.ts +68 -0
  298. package/vitest.config.mjs +12 -0
@@ -0,0 +1,178 @@
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import { Controller, type FieldValues, type Path, type PathValue, type UseFormSetValue, type UseFormWatch } from 'react-hook-form'
5
+ import { PatternFormat } from 'react-number-format'
6
+ import { format } from 'date-fns'
7
+ import { AnimatePresence, motion } from 'framer-motion'
8
+ import { type TControlledInputProps } from '../model'
9
+ import { FieldAttachment, FieldContainer, FieldWrapper, MessageView } from '../ui'
10
+ import { useCalendar, useCalendarDropdowns } from './hooks'
11
+ import { calendarAnimation } from './model/helpers'
12
+ import type { TCalendarClasses } from './model/types'
13
+ import { DaysOfMonth, DaysOfWeek, Header, Navigation } from './ui'
14
+ import { useClickOutside } from '$/shared/hooks'
15
+ import { cn } from '$/shared/utils'
16
+
17
+ export interface ICalendarControlProps<T extends FieldValues> extends TControlledInputProps<T> {
18
+ maskFormat?: string
19
+ mask?: string | string[]
20
+ allowEmptyFormatting?: boolean
21
+ classes?: Partial<TCalendarClasses>
22
+ disabled?: boolean
23
+ onClickIcon?: (...args: unknown[]) => unknown
24
+ defaultValue?: string
25
+ setValue: UseFormSetValue<T>
26
+ watch: UseFormWatch<T>
27
+ }
28
+
29
+ const today = format(new Date(), 'dd.MM.yyyy')
30
+
31
+ export const CalendarControl = <T extends FieldValues>({
32
+ control,
33
+ classes,
34
+ label,
35
+ disabled,
36
+ maskFormat = '##.##.####',
37
+ allowEmptyFormatting = false,
38
+ mask = '',
39
+ size = 'full',
40
+ helperText,
41
+ icon,
42
+ badge,
43
+ swapPosition,
44
+ onClickIcon,
45
+ defaultValue = today,
46
+ watch,
47
+ setValue,
48
+ ...props
49
+ }: ICalendarControlProps<T>) => {
50
+ const inputId = React.useId()
51
+ const calendarValue = watch(props.name)
52
+
53
+ const calendarWrapperRef = React.useRef<HTMLDivElement | null>(null)
54
+ const {
55
+ memoDaysOfMonth,
56
+ firstDayOfMonth,
57
+ selectedDay,
58
+ selectedMonth,
59
+ selectedYear,
60
+ onSelectDay,
61
+ onSelectMonth,
62
+ onSelectYear,
63
+ onBlurInput,
64
+ onChangeMonth
65
+ } = useCalendar(defaultValue ?? calendarValue)
66
+ const { isCalendarOpen, toggleCalendar, calendarSetter, isMonthOpen, toggleMonthDropdown, isYearsOpen, toggleYearDropdown } =
67
+ useCalendarDropdowns()
68
+
69
+ useClickOutside(calendarWrapperRef, () => calendarSetter(false))
70
+
71
+ return (
72
+ <Controller
73
+ control={control}
74
+ name={props.name}
75
+ render={({ field: { onChange, value }, fieldState: { error } }) => {
76
+ return (
77
+ <div className={cn('relative w-full', classes?.rootWrapper)} ref={calendarWrapperRef}>
78
+ <AnimatePresence>
79
+ {isCalendarOpen && (
80
+ <motion.div
81
+ {...calendarAnimation}
82
+ className={cn(
83
+ 'invisible absolute bottom-[-370px] right-0 z-30 h-[368px] w-[312px] rounded-sm bg-color-white p-4 shadow-md',
84
+ { visible: isCalendarOpen },
85
+ classes?.calendarWrapper
86
+ )}
87
+ >
88
+ <div
89
+ className={cn(
90
+ 'flex items-center justify-between border-b border-solid border-blue-grey-500 pb-2',
91
+ classes?.calendarHeader
92
+ )}
93
+ >
94
+ <Header
95
+ isMonthOpen={isMonthOpen}
96
+ isYearsOpen={isYearsOpen}
97
+ month={selectedMonth}
98
+ year={selectedYear}
99
+ toggleMonthDropdown={toggleMonthDropdown}
100
+ toggleYearDropdown={toggleYearDropdown}
101
+ onSelectMonth={(month: number) => onSelectMonth(month, onChange)}
102
+ onSelectYear={(year: number) => onSelectYear(year, onChange)}
103
+ classes={classes}
104
+ />
105
+ <Navigation
106
+ onClickPrevMonth={(event) => onChangeMonth(event, onChange, 'prev')}
107
+ onClickNextMonth={(event) => onChangeMonth(event, onChange, 'next')}
108
+ classes={classes}
109
+ />
110
+ </div>
111
+ <DaysOfWeek classes={classes} />
112
+ <DaysOfMonth
113
+ daysList={memoDaysOfMonth}
114
+ firstDayOfMonth={firstDayOfMonth}
115
+ onSelectDay={(day) => onSelectDay(day, onChange)}
116
+ selectedDay={+selectedDay}
117
+ classes={classes}
118
+ />
119
+ </motion.div>
120
+ )}
121
+ </AnimatePresence>
122
+ <FieldContainer size={size} classes={classes}>
123
+ <FieldWrapper
124
+ fieldId={inputId}
125
+ label={label}
126
+ classes={classes}
127
+ disabled={disabled}
128
+ value={value}
129
+ error={!!error?.message}
130
+ >
131
+ <>
132
+ <PatternFormat
133
+ id={inputId}
134
+ value={value}
135
+ name={props.name}
136
+ format={maskFormat}
137
+ allowEmptyFormatting={allowEmptyFormatting}
138
+ mask={mask}
139
+ className={cn(
140
+ 'desk-body-regular-l h-[56px] w-full rounded-md bg-color-transparent px-4 pt-5 text-color-dark outline-none transition-all',
141
+ classes?.input
142
+ )}
143
+ onFocus={() => calendarSetter(true)}
144
+ onBlur={(event) => {
145
+ onBlurInput(event.target.value, onChange)
146
+ if (!event.target.value) {
147
+ setValue(props.name, '' as PathValue<T, Path<T>>)
148
+ }
149
+ }}
150
+ />
151
+ <FieldAttachment
152
+ badge={badge}
153
+ icon={icon}
154
+ error={!!error?.message}
155
+ classes={classes}
156
+ swapPosition={swapPosition}
157
+ onClickIcon={() => toggleCalendar(onClickIcon)}
158
+ onKeyDownIcon={(event) => {
159
+ if (event.key === 'Enter' || event.key === ' ') {
160
+ toggleCalendar()
161
+ }
162
+ }}
163
+ />
164
+ </>
165
+ </FieldWrapper>
166
+ <MessageView
167
+ className={cn(classes?.message)}
168
+ intent={error?.message ? 'error' : 'simple'}
169
+ text={error?.message || helperText}
170
+ disabled={disabled}
171
+ />
172
+ </FieldContainer>
173
+ </div>
174
+ )
175
+ }}
176
+ />
177
+ )
178
+ }
@@ -0,0 +1,2 @@
1
+ export { useCalendarDropdowns } from './useCalendarDropdowns'
2
+ export { useCalendar } from './useCalendar'
@@ -0,0 +1,86 @@
1
+ 'use client'
2
+
3
+ import { useMemo, useState } from 'react'
4
+ import { add, eachDayOfInterval, endOfMonth, endOfWeek, format, parse, startOfWeek } from 'date-fns'
5
+ import { ru } from 'date-fns/locale'
6
+
7
+ export const useCalendar = (calendarValue: string) => {
8
+ const [currentDate, setCurrentDate] = useState(calendarValue)
9
+ const [selectedDay, selectedMonth, selectedYear] = currentDate?.split('.') ?? ''
10
+
11
+ const formattedDate = format(new Date(+selectedYear, +selectedMonth - 1, +selectedDay), 'MMM-yyyy')
12
+ const firstDayOfMonth = parse(formattedDate, 'MMM-yyyy', new Date())
13
+
14
+ const daysOfMonth = eachDayOfInterval({
15
+ start: startOfWeek(firstDayOfMonth, { weekStartsOn: 1 }),
16
+ end: endOfWeek(endOfMonth(firstDayOfMonth))
17
+ })
18
+ const memoDaysOfMonth = useMemo(() => daysOfMonth, [daysOfMonth])
19
+
20
+ const formattedMonth = format(selectedMonth, 'MMMM', { locale: ru })
21
+
22
+ const onSelectDay = (day: Date, onChange: (...event: unknown[]) => void) => {
23
+ const updatedDate = format(day, 'dd.MM.yyyy')
24
+ onChange(updatedDate)
25
+ setCurrentDate(updatedDate)
26
+ }
27
+
28
+ const onSelectMonth = (month: number, onChange: (...event: unknown[]) => void) => {
29
+ const updatedDate = format(new Date(+selectedYear, +month, +selectedDay), 'dd.MM.yyyy')
30
+ onChange(updatedDate)
31
+ setCurrentDate(updatedDate)
32
+ }
33
+
34
+ const onSelectYear = (year: number, onChange: (...event: unknown[]) => void) => {
35
+ const updatedDate = format(new Date(+year, +selectedMonth - 1, +selectedDay), 'dd.MM.yyyy')
36
+ onChange(format(new Date(+year, +selectedMonth - 1, +selectedDay), 'dd.MM.yyyy'))
37
+ setCurrentDate(updatedDate)
38
+ }
39
+
40
+ const onChangeMonth = (
41
+ event: React.MouseEvent<HTMLButtonElement>,
42
+ onChange: (...event: unknown[]) => void,
43
+ mode: 'prev' | 'next'
44
+ ) => {
45
+ event.preventDefault()
46
+
47
+ switch (mode) {
48
+ case 'next':
49
+ const firstDayOfNextMonth = add(firstDayOfMonth, { months: 1 })
50
+ const updatedDateNext = format(firstDayOfNextMonth, 'dd.MM.yyyy')
51
+ onChange(updatedDateNext)
52
+ setCurrentDate(updatedDateNext)
53
+
54
+ break
55
+ case 'prev':
56
+ const firstDayOfPrevMonth = add(firstDayOfMonth, { months: -1 })
57
+ const updatedDatePrev = format(firstDayOfPrevMonth, 'dd.MM.yyyy')
58
+ onChange(updatedDatePrev)
59
+ setCurrentDate(updatedDatePrev)
60
+
61
+ break
62
+ default:
63
+ break
64
+ }
65
+ }
66
+
67
+ const onBlurInput = (inputValue: string, onChange: (...event: unknown[]) => void) => {
68
+ if (inputValue) {
69
+ onChange(inputValue)
70
+ }
71
+ }
72
+
73
+ return {
74
+ memoDaysOfMonth,
75
+ firstDayOfMonth,
76
+ selectedDay,
77
+ selectedMonth,
78
+ selectedYear,
79
+ formattedMonth,
80
+ onSelectDay,
81
+ onSelectMonth,
82
+ onSelectYear,
83
+ onBlurInput,
84
+ onChangeMonth
85
+ }
86
+ }
@@ -0,0 +1,38 @@
1
+ import { useBoolean } from '$/shared/hooks'
2
+
3
+ export const useCalendarDropdowns = () => {
4
+ const [isMonthOpen, monthsSetter] = useBoolean(false)
5
+ const [isYearsOpen, yearsSetter] = useBoolean(false)
6
+ const [isCalendarOpen, calendarSetter] = useBoolean(false)
7
+
8
+ const toggleCalendar = (onClickIcon?: (...args: unknown[]) => unknown) => {
9
+ calendarSetter()
10
+ if (onClickIcon) {
11
+ onClickIcon()
12
+ }
13
+ }
14
+
15
+ const toggleMonthDropdown = () => {
16
+ monthsSetter()
17
+ if (isYearsOpen) {
18
+ yearsSetter(false)
19
+ }
20
+ }
21
+
22
+ const toggleYearDropdown = () => {
23
+ yearsSetter()
24
+ if (isMonthOpen) {
25
+ monthsSetter(false)
26
+ }
27
+ }
28
+
29
+ return {
30
+ calendarSetter,
31
+ toggleCalendar,
32
+ isMonthOpen,
33
+ toggleMonthDropdown,
34
+ isYearsOpen,
35
+ toggleYearDropdown,
36
+ isCalendarOpen
37
+ }
38
+ }
@@ -0,0 +1 @@
1
+ export { CalendarControl, type ICalendarControlProps } from './CalendarControl'
@@ -0,0 +1,60 @@
1
+ import { type TDayOfWeek } from './types'
2
+
3
+ export const capitalizeFirstLetter = (query: string): string => {
4
+ return query.charAt(0).toUpperCase() + query.substring(1)
5
+ }
6
+
7
+ export const colStartClasses = [
8
+ 'col-start-1',
9
+ 'col-start-2',
10
+ 'col-start-3',
11
+ 'col-start-4',
12
+ 'col-start-5',
13
+ 'col-start-6',
14
+ 'col-start-7'
15
+ ]
16
+
17
+ export const calendarAnimation = {
18
+ initial: { opacity: 0, y: -40 },
19
+ animate: { opacity: 1, y: 0 },
20
+ exit: { opacity: 0, y: -40 },
21
+ transition: { duration: 0.4, ease: 'easeInOut' }
22
+ }
23
+
24
+ const getYearsFromCurrentTo = (endYear = 1950) => {
25
+ const currentYear = new Date().getFullYear()
26
+ const years = []
27
+
28
+ // eslint-disable-next-line no-plusplus
29
+ for (let year = currentYear; year >= endYear; year--) {
30
+ years.push(year)
31
+ }
32
+
33
+ return years
34
+ }
35
+ export const YEARS_OPTIONS = getYearsFromCurrentTo()
36
+
37
+ export const DAYS_OF_WEEK: TDayOfWeek[] = [
38
+ { day: 'Пн' },
39
+ { day: 'Вт' },
40
+ { day: 'Ср' },
41
+ { day: 'Чт' },
42
+ { day: 'Пт' },
43
+ { day: 'Сб', isWeekend: true },
44
+ { day: 'Вс', isWeekend: true }
45
+ ]
46
+
47
+ export const MONTHS_OPTIONS = [
48
+ 'Январь',
49
+ 'Февраль',
50
+ 'Март',
51
+ 'Апрель',
52
+ 'Май',
53
+ 'Июнь',
54
+ 'Июль',
55
+ 'Август',
56
+ 'Сентябрь',
57
+ 'Октябрь',
58
+ 'Ноябрь',
59
+ 'Декабрь'
60
+ ]
@@ -0,0 +1,44 @@
1
+ import { type TAdditionalInputClassesWithAttachment } from '../../model'
2
+
3
+ export type TDayOfWeek = {
4
+ day: string
5
+ isWeekend?: boolean
6
+ }
7
+
8
+ export type TDaysOfMonthClasses = {
9
+ monthWrapper: string
10
+ button: string
11
+ day: string
12
+ }
13
+
14
+ export type TDaysOfWeekClasses = {
15
+ weekWrapper: string
16
+ weekDay: string
17
+ }
18
+
19
+ export type TNavigationClasses = {
20
+ navigationWrapper: string
21
+ swipeButton: string
22
+ arrowIcon: string
23
+ }
24
+
25
+ export type TDropdownClasses = {
26
+ dropdownWrapper: string
27
+ dropdownTrigger: string
28
+ dropdownIcon: string
29
+ dropdownOverlay: string
30
+ dropdownOptions: string
31
+ dropdownOption: string
32
+ dropdowns: string
33
+ }
34
+
35
+ export type TCalendarClasses = Partial<TDayOfWeek> &
36
+ Partial<TDaysOfMonthClasses> &
37
+ Partial<TDaysOfWeekClasses> &
38
+ Partial<TNavigationClasses> &
39
+ Partial<TDropdownClasses> &
40
+ Partial<TAdditionalInputClassesWithAttachment> & {
41
+ rootWrapper: string
42
+ calendarWrapper: string
43
+ calendarHeader: string
44
+ }
@@ -0,0 +1,53 @@
1
+ import { format, getDay, isSameMonth, isToday } from 'date-fns'
2
+ import { colStartClasses } from '../model/helpers'
3
+ import { type TDaysOfMonthClasses } from '../model/types'
4
+ import { cn } from '$/shared/utils'
5
+
6
+ interface IDaysOfMonthProps {
7
+ daysList: Date[]
8
+ selectedDay: number
9
+ firstDayOfMonth: Date
10
+ onSelectDay: (day: Date) => void
11
+ classes?: Partial<TDaysOfMonthClasses>
12
+ }
13
+
14
+ export const DaysOfMonth = ({ daysList, firstDayOfMonth, selectedDay, onSelectDay, classes }: IDaysOfMonthProps) => {
15
+ return (
16
+ <div className={cn('grid grid-cols-7 place-items-center', classes?.monthWrapper)}>
17
+ {daysList?.map((day, idx) => {
18
+ const isCurrentMonth = isSameMonth(day, firstDayOfMonth)
19
+
20
+ return (
21
+ <div
22
+ // eslint-disable-next-line react/no-array-index-key
23
+ key={idx}
24
+ role='button'
25
+ tabIndex={0}
26
+ onKeyDown={() => onSelectDay(day)}
27
+ onClick={() => onSelectDay(day)}
28
+ className={cn(
29
+ 'flex size-10 cursor-pointer items-center justify-center',
30
+ colStartClasses[getDay(+day - 1)],
31
+ classes?.button
32
+ )}
33
+ >
34
+ <span
35
+ className={cn(
36
+ 'mob-body-regular-m flex h-full w-full items-center justify-center rounded-sm border border-solid border-transparent text-color-dark transition-colors hover:border-primary-default hover:bg-color-primary-tr-hover',
37
+ {
38
+ 'before:content-[" "] relative text-color-primary-default before:absolute before:bottom-1 before:left-1/2 before:h-[2px] before:w-4 before:-translate-x-1/2 before:rounded-[2px] before:bg-icon-primary-default':
39
+ isToday(day),
40
+ '!bg-color-primary-default !text-color-white': selectedDay === +format(day, 'dd') && isCurrentMonth,
41
+ 'text-color-disabled': !isCurrentMonth
42
+ },
43
+ classes?.day
44
+ )}
45
+ >
46
+ {format(day, 'd')}
47
+ </span>
48
+ </div>
49
+ )
50
+ })}
51
+ </div>
52
+ )
53
+ }
@@ -0,0 +1,28 @@
1
+ import { capitalizeFirstLetter, DAYS_OF_WEEK } from '../model/helpers'
2
+ import { type TDaysOfWeekClasses } from '../model/types'
3
+ import { cn } from '$/shared/utils'
4
+
5
+ interface IDaysOfWeekProps {
6
+ classes?: Partial<TDaysOfWeekClasses>
7
+ }
8
+
9
+ export const DaysOfWeek = ({ classes }: IDaysOfWeekProps) => {
10
+ return (
11
+ <div className={cn('grid grid-cols-7 pt-2', classes?.weekWrapper)}>
12
+ {DAYS_OF_WEEK?.map(({ day, isWeekend }) => {
13
+ return (
14
+ <span
15
+ key={day}
16
+ className={cn(
17
+ 'mob-body-medium-m flex size-10 items-center justify-center',
18
+ { 'text-color-negative': isWeekend },
19
+ classes?.weekDay
20
+ )}
21
+ >
22
+ {capitalizeFirstLetter(day)}
23
+ </span>
24
+ )
25
+ })}
26
+ </div>
27
+ )
28
+ }
@@ -0,0 +1,62 @@
1
+ import { type TDropdownClasses } from '../model/types'
2
+ import { OptionsList } from './OptionsList'
3
+ import { Icon } from '$/shared/ui'
4
+ import { cn } from '$/shared/utils'
5
+
6
+ export interface IDropdownProps<Value extends string | number> {
7
+ options: Value[]
8
+ selectedValue: string
9
+ isActive: boolean
10
+ onClickTrigger: () => void
11
+ onClickOption: (value: number) => void
12
+ variant?: 'months' | 'years'
13
+ classes?: Partial<TDropdownClasses>
14
+ }
15
+
16
+ export const Dropdown = <Value extends string | number>({
17
+ onClickTrigger,
18
+ isActive,
19
+ selectedValue,
20
+ options,
21
+ variant = 'months',
22
+ onClickOption,
23
+ classes
24
+ }: IDropdownProps<Value>) => {
25
+ return (
26
+ <div className={cn('z-10 w-full', classes?.dropdownWrapper)}>
27
+ <div
28
+ role='button'
29
+ tabIndex={0}
30
+ onKeyDown={onClickTrigger}
31
+ onClick={onClickTrigger}
32
+ className={cn(
33
+ 'desk-body-medium-l flex items-center gap-[2px] rounded-sm px-2 py-2 text-color-tetriary transition-colors hover:bg-color-primary-tr-hover',
34
+ { 'text-color-primary-default': isActive },
35
+ classes?.dropdownTrigger
36
+ )}
37
+ >
38
+ {selectedValue}
39
+ <Icon
40
+ name='arrows/arrowRight'
41
+ className={cn('rotate-90 text-icon-blue-grey-800', { 'text-icon-primary-default': isActive }, classes?.dropdownIcon)}
42
+ />
43
+ </div>
44
+
45
+ <div
46
+ className={cn(
47
+ 'invisible absolute bottom-3 left-1/2 z-10 flex h-[280px] w-full -translate-x-1/2 flex-col overflow-hidden px-4 opacity-0 transition-all',
48
+ { 'visible opacity-100': isActive },
49
+ classes?.dropdownOverlay
50
+ )}
51
+ >
52
+ <OptionsList
53
+ options={options}
54
+ selectedValue={selectedValue}
55
+ isActive={isActive}
56
+ onClickOption={onClickOption}
57
+ variant={variant}
58
+ />
59
+ </div>
60
+ </div>
61
+ )
62
+ }
@@ -0,0 +1,51 @@
1
+ import { MONTHS_OPTIONS, YEARS_OPTIONS } from '../model/helpers'
2
+ import { type TDropdownClasses } from '../model/types'
3
+ import { Dropdown } from './Dropdown'
4
+ import { cn } from '$/shared/utils'
5
+
6
+ interface IHeaderProps {
7
+ month: string
8
+ year: string
9
+ isYearsOpen: boolean
10
+ isMonthOpen: boolean
11
+ toggleMonthDropdown: () => void
12
+ toggleYearDropdown: () => void
13
+ onSelectMonth: (month: number) => void
14
+ onSelectYear: (year: number) => void
15
+ classes?: Partial<TDropdownClasses>
16
+ }
17
+
18
+ export const Header = ({
19
+ isMonthOpen,
20
+ isYearsOpen,
21
+ toggleMonthDropdown,
22
+ toggleYearDropdown,
23
+ onSelectMonth,
24
+ onSelectYear,
25
+ month,
26
+ year,
27
+ classes
28
+ }: IHeaderProps) => {
29
+ return (
30
+ <div className={cn('flex items-center', classes?.dropdowns)}>
31
+ <Dropdown
32
+ options={MONTHS_OPTIONS}
33
+ isActive={isMonthOpen}
34
+ selectedValue={MONTHS_OPTIONS[+month - 1]}
35
+ onClickTrigger={toggleMonthDropdown}
36
+ onClickOption={onSelectMonth}
37
+ classes={classes}
38
+ />
39
+
40
+ <Dropdown
41
+ options={YEARS_OPTIONS}
42
+ isActive={isYearsOpen}
43
+ selectedValue={year}
44
+ onClickTrigger={toggleYearDropdown}
45
+ onClickOption={onSelectYear}
46
+ variant='years'
47
+ classes={classes}
48
+ />
49
+ </div>
50
+ )
51
+ }
@@ -0,0 +1,32 @@
1
+ import type { MouseEventHandler } from 'react'
2
+ import { type TNavigationClasses } from '../model/types'
3
+ import { Icon } from '$/shared/ui'
4
+ import { cn } from '$/shared/utils'
5
+
6
+ interface INavigationProps {
7
+ onClickPrevMonth: MouseEventHandler<HTMLButtonElement>
8
+ onClickNextMonth: MouseEventHandler<HTMLButtonElement>
9
+ classes?: Partial<TNavigationClasses>
10
+ }
11
+
12
+ export const Navigation = ({ onClickPrevMonth, onClickNextMonth, classes }: INavigationProps) => {
13
+ return (
14
+ <div className={cn('flex items-center justify-evenly gap-6', classes?.navigationWrapper)}>
15
+ <button type='button' className={cn('h-6 w-6 cursor-pointer', classes?.swipeButton)} onClick={onClickPrevMonth}>
16
+ <Icon
17
+ name='arrows/arrowRight'
18
+ className={cn(
19
+ 'size-6 rotate-180 text-icon-blue-grey-800 transition-colors hover:text-icon-accent-hover',
20
+ classes?.arrowIcon
21
+ )}
22
+ />
23
+ </button>
24
+ <button type='button' className={cn('h-6 w-6 cursor-pointer', classes?.swipeButton)} onClick={onClickNextMonth}>
25
+ <Icon
26
+ name='arrows/arrowRight'
27
+ className={cn('size-6 text-icon-blue-grey-800 transition-colors hover:text-icon-accent-hover', classes?.arrowIcon)}
28
+ />
29
+ </button>
30
+ </div>
31
+ )
32
+ }
@@ -0,0 +1,44 @@
1
+ import type { IDropdownProps } from './Dropdown'
2
+ import { cn } from '$/shared/utils'
3
+
4
+ interface IOptionsListProps<Value extends string | number> extends Omit<IDropdownProps<Value>, 'onClickTrigger'> {}
5
+
6
+ export const OptionsList = <Value extends string | number>({
7
+ isActive,
8
+ variant,
9
+ options,
10
+ onClickOption,
11
+ selectedValue,
12
+ classes
13
+ }: IOptionsListProps<Value>) => {
14
+ const modeMonth = variant === 'months'
15
+ return (
16
+ <div
17
+ className={cn('customScrollbar-y overflow-y-auto overflow-x-hidden bg-color-white px-2', classes?.dropdownOptions)}
18
+ role='listbox'
19
+ aria-expanded={isActive ? 'true' : 'false'}
20
+ aria-label={variant === 'months' ? 'Выбор месяца' : 'Выбор года'}
21
+ >
22
+ {options?.map((option, index) => {
23
+ return (
24
+ <div
25
+ key={option}
26
+ role='button'
27
+ tabIndex={0}
28
+ onClick={() => onClickOption(modeMonth ? index : (option as number))}
29
+ onKeyDown={() => onClickOption(modeMonth ? index : (option as number))}
30
+ className={cn(
31
+ 'mob-body-regular-m cursor-pointer rounded-sm bg-color-white px-2 py-[10px] text-color-dark transition-colors hover:bg-color-primary-tr-hover hover:text-color-primary-hover',
32
+ {
33
+ '!bg-color-primary-default !text-color-white': modeMonth ? selectedValue === option : +selectedValue === option
34
+ },
35
+ classes?.dropdownOption
36
+ )}
37
+ >
38
+ {option}
39
+ </div>
40
+ )
41
+ })}
42
+ </div>
43
+ )
44
+ }