@scbt-ecom/ui 0.4.1 → 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 (299) 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
  299. package/dist/scbt-ecom-ui-0.4.1.tgz +0 -0
@@ -0,0 +1,82 @@
1
+ import { useEffect } from 'react'
2
+ import Bold from '@tiptap/extension-bold'
3
+ import Code from '@tiptap/extension-code'
4
+ import Document from '@tiptap/extension-document'
5
+ import History from '@tiptap/extension-history'
6
+ import Italic from '@tiptap/extension-italic'
7
+ import Paragraph from '@tiptap/extension-paragraph'
8
+ import Placeholder from '@tiptap/extension-placeholder'
9
+ import Strike from '@tiptap/extension-strike'
10
+ import Subscript from '@tiptap/extension-subscript'
11
+ import Superscript from '@tiptap/extension-superscript'
12
+ import Text from '@tiptap/extension-text'
13
+ import Underline from '@tiptap/extension-underline'
14
+ import { EditorContent, useEditor } from '@tiptap/react'
15
+ import { Controls } from './components/conrols'
16
+ import { Menu } from './components/menu'
17
+ import { cn } from '$/shared/utils'
18
+
19
+ export interface IEditorControlProps {
20
+ value: string
21
+ setValue: (value: string) => void
22
+ placeholder?: string
23
+ className?: string
24
+ }
25
+
26
+ export const EditorControl = ({ value, setValue, placeholder, className }: IEditorControlProps) => {
27
+ const editor = useEditor({
28
+ extensions: [
29
+ Document,
30
+ Paragraph,
31
+ Text,
32
+ Placeholder.configure({
33
+ placeholder,
34
+ emptyNodeClass:
35
+ 'first:before:text-grey first:before:float-left first:before:h-0 first:before:content-[attr(data-placeholder)] first:before:pointer-events-none'
36
+ }),
37
+ Bold,
38
+ Italic,
39
+ Underline,
40
+ Strike,
41
+ Subscript,
42
+ Superscript,
43
+ Code,
44
+ History
45
+ ],
46
+ editorProps: {
47
+ attributes: {
48
+ class: 'h-full flex flex-col gap-8 outline-none rounded p-4'
49
+ }
50
+ },
51
+ autofocus: true,
52
+ onUpdate: ({ editor }) => {
53
+ setValue(editor.getHTML())
54
+ },
55
+ content: value || '',
56
+ immediatelyRender: false
57
+ })
58
+
59
+ useEffect(() => {
60
+ if (editor && value !== undefined && value !== editor.getHTML()) {
61
+ editor.commands.setContent(value || '')
62
+ }
63
+ }, [editor, value])
64
+
65
+ if (!editor) {
66
+ return <div className='grow px-24'>NO EDITOR</div>
67
+ }
68
+
69
+ return (
70
+ <div
71
+ className={cn(
72
+ 'relative mt-10 flex h-[700px] grow cursor-text flex-col rounded-md border border-transparent transition-colors hover:border-blue-grey-700',
73
+ { 'border-blue-grey-700': editor.isFocused },
74
+ className
75
+ )}
76
+ >
77
+ {editor && <Menu editor={editor} />}
78
+ <EditorContent editor={editor} className='flex-1 px-4' />
79
+ <Controls editor={editor} />
80
+ </div>
81
+ )
82
+ }
@@ -0,0 +1,136 @@
1
+ import { type Editor } from '@tiptap/core'
2
+ import { Icon } from '$/shared/ui'
3
+ import { cn } from '$/shared/utils'
4
+
5
+ type Props = {
6
+ editor: Editor
7
+ }
8
+
9
+ export const Controls = ({ editor }: Props) => {
10
+ return (
11
+ <div
12
+ onMouseDown={(event) => event.preventDefault()}
13
+ onClick={() => editor.commands.focus()}
14
+ className={cn(
15
+ 'divide-grey/20 rounded-7 bg-white mt-auto flex h-[40px] w-full cursor-text items-center divide-x p-4 opacity-0 transition-opacity',
16
+ { 'cursor-default opacity-100': editor.isFocused }
17
+ )}
18
+ >
19
+ {editor.isFocused && (
20
+ <>
21
+ <div className='flex items-center gap-2 px-8 first:pl-0 last:pr-0'>
22
+ <section title='Отменить'>
23
+ <span className='size-32'>
24
+ <button
25
+ type='button'
26
+ onClick={() => editor.chain().focus().undo().run()}
27
+ disabled={!editor.can().undo()}
28
+ className={cn('rounded-7 text-grey pointer-events-none size-32 p-4 transition-colors', {
29
+ 'text-main hover:bg-grey/20 pointer-events-auto': editor.can().undo()
30
+ })}
31
+ >
32
+ <Icon name='arrows/arrowRight' className='size-full scale-y-[-1]' />
33
+ </button>
34
+ </span>
35
+ </section>
36
+ <section title='Вернуть'>
37
+ <span className='size-32'>
38
+ <button
39
+ type='button'
40
+ onClick={() => editor.chain().focus().redo().run()}
41
+ disabled={!editor.can().redo()}
42
+ className={cn('rounded-7 text-grey pointer-events-none size-32 p-4 transition-colors', {
43
+ 'text-main hover:bg-grey/20 pointer-events-auto': editor.can().redo()
44
+ })}
45
+ >
46
+ <Icon name='arrows/arrowRight' className='size-full scale-[-1]' />
47
+ </button>
48
+ </span>
49
+ </section>
50
+ </div>
51
+ <div className='flex items-center gap-2 px-8 first:pl-0 last:pr-0'>
52
+ <section title='Полужирный'>
53
+ <button
54
+ type='button'
55
+ onClick={() => editor.chain().focus().toggleBold().run()}
56
+ className={cn('rounded-7 text-grey hover:bg-grey/20 hover:text-main size-32 p-4 transition-colors', {
57
+ 'bg-grey/20 text-main': editor.isActive('bold')
58
+ })}
59
+ >
60
+ <Icon name='arrows/arrowRight' className='size-4' />
61
+ </button>
62
+ </section>
63
+ <section title='Курсив'>
64
+ <button
65
+ type='button'
66
+ onClick={() => editor.chain().focus().toggleItalic().run()}
67
+ className={cn('rounded-7 text-grey hover:bg-grey/20 hover:text-main size-32 p-4 transition-colors', {
68
+ 'bg-grey/20 text-main': editor.isActive('italic')
69
+ })}
70
+ >
71
+ <Icon name='arrows/arrowRight' className='size-4' />
72
+ </button>
73
+ </section>
74
+ <section title='Подчеркнутый'>
75
+ <button
76
+ type='button'
77
+ onClick={() => editor.chain().focus().toggleUnderline().run()}
78
+ className={cn('rounded-7 text-grey hover:bg-grey/20 hover:text-main size-32 p-4 transition-colors', {
79
+ 'bg-grey/20 text-main': editor.isActive('underline')
80
+ })}
81
+ >
82
+ <Icon name='arrows/arrowRight' className='size-4' />
83
+ </button>
84
+ </section>
85
+ </div>
86
+ <div className='flex items-center gap-2 px-8 first:pl-0 last:pr-0'>
87
+ <section title='Зачеркнутый'>
88
+ <button
89
+ type='button'
90
+ onClick={() => editor.chain().focus().toggleStrike().run()}
91
+ className={cn('rounded-7 text-grey hover:bg-grey/20 hover:text-main size-32 p-4 transition-colors', {
92
+ 'bg-grey/20 text-main': editor.isActive('strike')
93
+ })}
94
+ >
95
+ <Icon name='arrows/arrowRight' className='size-4' />
96
+ </button>
97
+ </section>
98
+ <section title='Нижний регистр'>
99
+ <button
100
+ type='button'
101
+ onClick={() => editor.chain().focus().toggleSubscript().run()}
102
+ className={cn('rounded-7 text-grey hover:bg-grey/20 hover:text-main size-32 p-4 transition-colors', {
103
+ 'bg-grey/20 text-main': editor.isActive('subscript')
104
+ })}
105
+ >
106
+ <Icon name='arrows/arrowRight' className='size-4' />
107
+ </button>
108
+ </section>
109
+ <section title='Верхний регистр'>
110
+ <button
111
+ type='button'
112
+ onClick={() => editor.chain().focus().toggleSuperscript().run()}
113
+ className={cn('rounded-7 text-grey hover:bg-grey/20 hover:text-main size-32 p-4 transition-colors', {
114
+ 'bg-grey/20 text-main': editor.isActive('superscript')
115
+ })}
116
+ >
117
+ <Icon name='arrows/arrowRight' className='size-4' />
118
+ </button>
119
+ </section>
120
+ <section title='Код'>
121
+ <button
122
+ type='button'
123
+ onClick={() => editor.chain().focus().toggleCode().run()}
124
+ className={cn('rounded-7 text-grey hover:bg-grey/20 hover:text-main size-32 p-4 transition-colors', {
125
+ 'bg-grey/20 text-main': editor.isActive('code')
126
+ })}
127
+ >
128
+ <Icon name='arrows/arrowRight' className='size-4' />
129
+ </button>
130
+ </section>
131
+ </div>
132
+ </>
133
+ )}
134
+ </div>
135
+ )
136
+ }
@@ -0,0 +1,107 @@
1
+ import { BubbleMenu, type Editor } from '@tiptap/react'
2
+ import { Icon } from '$/shared/ui'
3
+ import { cn } from '$/shared/utils'
4
+
5
+ type Props = {
6
+ editor: Editor
7
+ }
8
+
9
+ export const Menu = ({ editor }: Props) => {
10
+ return (
11
+ <BubbleMenu
12
+ editor={editor}
13
+ tippyOptions={{ duration: 100 }}
14
+ className='bg-white flex items-center rounded-md border border-blue-grey-700 p-2'
15
+ >
16
+ <div className='flex items-center gap-2 px-2 first:pl-0 last:pr-0'>
17
+ <button
18
+ type='button'
19
+ onClick={() => editor.chain().focus().undo().run()}
20
+ disabled={!editor.can().undo()}
21
+ className={cn('text-grey size-24 rounded-sm p-2 transition-colors', {
22
+ 'text-main hover:bg-grey/20': editor.can().undo()
23
+ })}
24
+ >
25
+ <Icon name='arrows/arrowRight' className='size-full scale-y-[-1]' />
26
+ </button>
27
+ <button
28
+ type='button'
29
+ onClick={() => editor.chain().focus().redo().run()}
30
+ disabled={!editor.can().redo()}
31
+ className={cn('text-grey size-24 rounded-sm p-2 transition-colors', {
32
+ 'text-main hover:bg-grey/20': editor.can().redo()
33
+ })}
34
+ >
35
+ <Icon name='arrows/arrowRight' className='size-full scale-[-1]' />
36
+ </button>
37
+ </div>
38
+ <div className='flex items-center gap-2 px-2 first:pl-0 last:pr-0'>
39
+ <button
40
+ type='button'
41
+ onClick={() => editor.chain().focus().toggleBold().run()}
42
+ className={cn('text-grey hover:bg-grey/20 hover:text-main size-24 rounded-sm p-2 transition-colors', {
43
+ 'bg-grey/20 text-main': editor.isActive('bold')
44
+ })}
45
+ >
46
+ <Icon name='arrows/arrowRight' className='size-4' />
47
+ </button>
48
+ <button
49
+ type='button'
50
+ onClick={() => editor.chain().focus().toggleItalic().run()}
51
+ className={cn('text-grey hover:bg-grey/20 hover:text-main size-24 rounded-sm p-2 transition-colors', {
52
+ 'bg-grey/20 text-main': editor.isActive('italic')
53
+ })}
54
+ >
55
+ <Icon name='arrows/arrowRight' className='size-4' />
56
+ </button>
57
+ <button
58
+ type='button'
59
+ onClick={() => editor.chain().focus().toggleUnderline().run()}
60
+ className={cn('text-grey hover:bg-grey/20 hover:text-main size-24 rounded-sm p-2 transition-colors', {
61
+ 'bg-grey/20 text-main': editor.isActive('underline')
62
+ })}
63
+ >
64
+ <Icon name='arrows/arrowRight' className='size-4' />
65
+ </button>
66
+ </div>
67
+ <div className='flex items-center gap-2 px-2 first:pl-0 last:pr-0'>
68
+ <button
69
+ type='button'
70
+ onClick={() => editor.chain().focus().toggleStrike().run()}
71
+ className={cn('text-grey hover:bg-grey/20 hover:text-main size-24 rounded-sm p-2 transition-colors', {
72
+ 'bg-grey/20 text-main': editor.isActive('strike')
73
+ })}
74
+ >
75
+ <Icon name='arrows/arrowRight' className='size-4' />
76
+ </button>
77
+ <button
78
+ type='button'
79
+ onClick={() => editor.chain().focus().toggleSubscript().run()}
80
+ className={cn('text-grey hover:bg-grey/20 hover:text-main size-24 rounded-sm p-2 transition-colors', {
81
+ 'bg-grey/20 text-main': editor.isActive('subscript')
82
+ })}
83
+ >
84
+ <Icon name='arrows/arrowRight' className='size-4' />
85
+ </button>
86
+ <button
87
+ type='button'
88
+ onClick={() => editor.chain().focus().toggleSuperscript().run()}
89
+ className={cn('text-grey hover:bg-grey/20 hover:text-main size-24 rounded-sm p-2 transition-colors', {
90
+ 'bg-grey/20 text-main': editor.isActive('superscript')
91
+ })}
92
+ >
93
+ <Icon name='arrows/arrowRight' className='size-4' />
94
+ </button>
95
+ <button
96
+ type='button'
97
+ onClick={() => editor.chain().focus().toggleCode().run()}
98
+ className={cn('text-grey hover:bg-grey/20 hover:text-main size-24 rounded-sm p-2 transition-colors', {
99
+ 'bg-grey/20 text-main': editor.isActive('code')
100
+ })}
101
+ >
102
+ <Icon name='arrows/arrowRight' className='size-4' />
103
+ </button>
104
+ </div>
105
+ </BubbleMenu>
106
+ )
107
+ }
@@ -0,0 +1,60 @@
1
+ export { EditorControl, type IEditorControlProps } from './EditorControl'
2
+ // 'use client'
3
+
4
+ // /* eslint-disable react/no-unstable-nested-components */
5
+ // import { Controller, type FieldValues } from 'react-hook-form'
6
+ // import { BlockNoteView } from '@blocknote/mantine'
7
+ // import { useCreateBlockNote } from '@blocknote/react'
8
+ // import '@blocknote/core/fonts/inter.css'
9
+ // import '@blocknote/mantine/style.css'
10
+ // import type { TControlledInputProps } from '../model'
11
+ // import { FieldContainer } from '../ui'
12
+
13
+ // export interface IEditorControlProps<T extends FieldValues> extends TControlledInputProps<T> {
14
+ // classes?: any
15
+ // }
16
+
17
+ // export const EditorControl = <T extends FieldValues>({ control, classes, size = 'full', ...props }: IEditorControlProps<T>) => {
18
+ // const editor = useCreateBlockNote({
19
+ // initialContent: [
20
+ // {
21
+ // type: 'paragraph',
22
+ // content: 'Welcome to this demo!'
23
+ // },
24
+ // {
25
+ // type: 'paragraph'
26
+ // },
27
+ // {
28
+ // type: 'bulletListItem',
29
+ // content: 'Link'
30
+ // }
31
+ // ]
32
+ // })
33
+
34
+ // console.log(editor, '@editor')
35
+
36
+ // const changeFn = async (change) => {
37
+ // // Converts the editor's contents from Block objects to HTML and store to state.
38
+ // const html = await editor.blocksToHTMLLossy(editor.document)
39
+ // change(html)
40
+ // }
41
+
42
+ // return (
43
+ // <Controller
44
+ // control={control}
45
+ // name={props.name}
46
+ // render={({ field: { onChange, ref: controlledRef, value }, fieldState: { error } }) => {
47
+ // console.log(value, '@value')
48
+
49
+ // return (
50
+ // <FieldContainer size={size} classes={classes}>
51
+ // <div className='mt-10 w-[600px] rounded-md border border-warm-grey-200 px-3 py-4'>
52
+ // <BlockNoteView theme='light' editor={editor} onChange={() => changeFn(onChange)} ref={controlledRef} />
53
+ // </div>
54
+ // <div>{value}</div>
55
+ // </FieldContainer>
56
+ // )
57
+ // }}
58
+ // />
59
+ // )
60
+ // }
@@ -0,0 +1,23 @@
1
+ import { type SideMenuProps, useBlockNoteEditor, useComponentsContext } from '@blocknote/react'
2
+ import { Icon } from '$/shared/ui'
3
+
4
+ export const RemoveBlockButton = (props: SideMenuProps) => {
5
+ const editor = useBlockNoteEditor()
6
+
7
+ const Components = useComponentsContext()!
8
+
9
+ return (
10
+ <Components.SideMenu.Button
11
+ label='Remove block'
12
+ icon={
13
+ <Icon
14
+ name='general/close'
15
+ className='text-icon-negative-default'
16
+ onClick={() => {
17
+ editor.removeBlocks([props.block])
18
+ }}
19
+ />
20
+ }
21
+ />
22
+ )
23
+ }
@@ -0,0 +1,17 @@
1
+ import { type DragHandleMenuProps, useBlockNoteEditor, useComponentsContext } from '@blocknote/react'
2
+
3
+ export function ResetBlockTypeItem(props: DragHandleMenuProps) {
4
+ const editor = useBlockNoteEditor()
5
+
6
+ const Components = useComponentsContext()!
7
+
8
+ return (
9
+ <Components.Generic.Menu.Item
10
+ onClick={() => {
11
+ editor.updateBlock(props.block, { type: 'paragraph' })
12
+ }}
13
+ >
14
+ Reset Type
15
+ </Components.Generic.Menu.Item>
16
+ )
17
+ }
@@ -0,0 +1,14 @@
1
+ export { InputControl, type InputControlProps } from './inputControl'
2
+ export { InputControlMask, type InputControlMaskProps } from './InputControlMask'
3
+ export { FormControl } from './FormControl'
4
+ export { DadataInputControl, type IDadataInputControlProps } from './dadata'
5
+ export { CheckboxControl, type ICheckboxControlProps } from './CheckboxControl'
6
+ export { RadioControl, type IRadioControlProps, type IRadioGroupOption } from './RadioControl'
7
+ export { SwitchControl, type ISwitchControlProps } from './SwitchControl'
8
+ export { InputSliderControl, type InputSliderControlProps } from './inputSliderControl'
9
+ export { TextareaControl, type ITextareaControlProps } from './TextareaControl'
10
+ export { CalendarControl, type ICalendarControlProps } from './calendarControl'
11
+ export { InputControlUploader, type IInputControlUploaderProps } from './inputControlUploader'
12
+ export { ComboboxControl, type IComboboxControlProps } from './comboboxControl'
13
+ export { EditorControl, type IEditorControlProps } from './editorControl'
14
+ export { InputCurrencyControl, type InputCurrencyControlProps } from './inputCurrencyControl'
@@ -0,0 +1,87 @@
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import { Controller, type FieldValues } from 'react-hook-form'
5
+ import type { TAdditionalInputClassesWithAttachment, TControlledInputProps, TInputCommonProps } from '../model'
6
+ import { FieldAttachment, FieldContainer, FieldWrapper, MessageView } from '../ui'
7
+ import { useInputPassword } from './model/hooks'
8
+ import { cn } from '$/shared/utils'
9
+
10
+ export interface InputControlProps<T extends FieldValues> extends TControlledInputProps<T>, TInputCommonProps {
11
+ classes?: Partial<TAdditionalInputClassesWithAttachment>
12
+ variant?: 'base' | 'password'
13
+ }
14
+
15
+ export const InputControl = <T extends FieldValues>({
16
+ label,
17
+ size = 'full',
18
+ helperText,
19
+ control,
20
+ classes,
21
+ badge,
22
+ icon,
23
+ swapPosition,
24
+ disabled,
25
+ variant,
26
+ onClickIcon,
27
+ onKeyDownIcon,
28
+ ...props
29
+ }: InputControlProps<T>) => {
30
+ const inputId = React.useId()
31
+ const isPassport = variant === 'password'
32
+ const { displayPasswordIcon, passportIsVisible, handleShowPassword } = useInputPassword(onClickIcon)
33
+
34
+ return (
35
+ <Controller
36
+ control={control}
37
+ name={props.name}
38
+ render={({ field: { onChange, ref: controlledRef, value }, fieldState: { error } }) => {
39
+ return (
40
+ <FieldContainer size={size} classes={classes}>
41
+ <FieldWrapper
42
+ fieldId={inputId}
43
+ label={label}
44
+ classes={classes}
45
+ disabled={disabled}
46
+ value={value}
47
+ error={!!error?.message}
48
+ >
49
+ <>
50
+ <input
51
+ ref={controlledRef}
52
+ aria-invalid={error?.message ? 'true' : 'false'}
53
+ type={isPassport && !passportIsVisible ? 'password' : 'text'}
54
+ className={cn(
55
+ 'desk-body-regular-l h-[56px] w-full rounded-md bg-color-transparent px-4 pt-5 text-color-dark outline-none transition-all',
56
+ classes?.input
57
+ )}
58
+ id={inputId}
59
+ value={value}
60
+ onChange={onChange}
61
+ disabled={disabled}
62
+ {...props}
63
+ />
64
+ <FieldAttachment
65
+ onClickIcon={isPassport ? handleShowPassword : onClickIcon}
66
+ onKeyDownIcon={onKeyDownIcon}
67
+ badge={badge}
68
+ icon={isPassport ? displayPasswordIcon() : icon}
69
+ error={!!error?.message}
70
+ classes={classes}
71
+ swapPosition={swapPosition}
72
+ />
73
+ </>
74
+ </FieldWrapper>
75
+
76
+ <MessageView
77
+ className={cn(classes?.message)}
78
+ intent={error?.message ? 'error' : 'simple'}
79
+ text={error?.message || helperText}
80
+ disabled={disabled}
81
+ />
82
+ </FieldContainer>
83
+ )
84
+ }}
85
+ />
86
+ )
87
+ }
@@ -0,0 +1 @@
1
+ export { InputControl, type InputControlProps } from './InputControl'
@@ -0,0 +1,26 @@
1
+ import * as React from 'react'
2
+ import { Icon } from '../../../icon/Icon'
3
+
4
+ export const useInputPassword = (onClickIcon?: (...args: unknown[]) => unknown) => {
5
+ const [passportIsVisible, setPassportIsVisible] = React.useState(false)
6
+
7
+ const handleShowPassword = () => {
8
+ setPassportIsVisible((prev) => !prev)
9
+ if (onClickIcon) {
10
+ onClickIcon()
11
+ }
12
+ }
13
+
14
+ const displayPasswordIcon = React.useCallback(() => {
15
+ switch (passportIsVisible) {
16
+ case true:
17
+ return <Icon name='general/hiddenEye' className='size-5 text-icon-blue-grey-600' />
18
+ case false:
19
+ return <Icon name='general/showEye' className='size-5 text-icon-blue-grey-600' />
20
+ default:
21
+ return <Icon name='general/hiddenEye' className='size-5 text-icon-blue-grey-600' />
22
+ }
23
+ }, [passportIsVisible])
24
+
25
+ return { passportIsVisible, handleShowPassword, displayPasswordIcon }
26
+ }
@@ -0,0 +1,47 @@
1
+ 'use client'
2
+
3
+ import { type DropzoneOptions } from 'react-dropzone'
4
+ import { Controller, type FieldValues } from 'react-hook-form'
5
+ import { type TControlledInputProps } from '../model'
6
+ import { defaultDropzoneOptions } from './model'
7
+ import { type TClassesUploader } from './model/types'
8
+ import { Uploader } from './ui'
9
+
10
+ export interface IInputControlUploaderProps<T extends FieldValues> extends TControlledInputProps<T> {
11
+ dropzoneOptions?: DropzoneOptions
12
+ disabled?: boolean
13
+ classes?: Partial<TClassesUploader>
14
+ }
15
+
16
+ export const InputControlUploader = <T extends FieldValues>({
17
+ control,
18
+ disabled,
19
+ helperText,
20
+ classes,
21
+ dropzoneOptions = defaultDropzoneOptions,
22
+ ...props
23
+ }: IInputControlUploaderProps<T>) => {
24
+ return (
25
+ <Controller
26
+ control={control}
27
+ name={props.name}
28
+ render={({ field: { onChange, ref, value: controlledFiles }, fieldState: { error } }) => {
29
+ return (
30
+ <Uploader
31
+ error={error}
32
+ helperText={helperText}
33
+ disabled={disabled}
34
+ classes={classes}
35
+ ref={ref}
36
+ controlledFiles={controlledFiles}
37
+ onValueChange={(file) => {
38
+ onChange(file)
39
+ }}
40
+ dropzoneOptions={dropzoneOptions}
41
+ {...props}
42
+ />
43
+ )
44
+ }}
45
+ />
46
+ )
47
+ }
@@ -0,0 +1 @@
1
+ export { InputControlUploader, type IInputControlUploaderProps } from './InputControlUploader'
@@ -0,0 +1,18 @@
1
+ import { type DropzoneOptions } from 'react-dropzone'
2
+
3
+ export const defaultDropzoneOptions: DropzoneOptions = {
4
+ maxSize: 4 * 1024 * 1024,
5
+ multiple: true,
6
+ accept: {
7
+ 'image/jpeg': [],
8
+ 'image/png': [],
9
+ 'application/pdf': []
10
+ }
11
+ }
12
+
13
+ export const FilesErrorCode = {
14
+ FileInvalidType: 'file-invalid-type',
15
+ FileTooLarge: 'file-too-large',
16
+ FileTooSmall: 'file-too-small',
17
+ TooManyFiles: 'too-many-files'
18
+ } as const