ics-ui-kit 0.1.0-alpha.47 → 0.1.0-alpha.49

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 (198) hide show
  1. package/README.md +32 -32
  2. package/dist/AlertContext-CxjW1LVL.js.map +1 -1
  3. package/dist/AlertIcon-DQs4wtDT.js.map +1 -1
  4. package/dist/Button--ooZ8ALo.js.map +1 -1
  5. package/dist/ButtonBase-Sf-fcVor.js.map +1 -1
  6. package/dist/CarouselItem-DCAuGIKz.js.map +1 -1
  7. package/dist/{CheckboxField-DvsGq3kV.js → CheckboxField-BR2hWwTO.js} +2 -2
  8. package/dist/CheckboxField-BR2hWwTO.js.map +1 -0
  9. package/dist/{Command-BU9Ouar3.js → Command-C_iW2joV.js} +2 -2
  10. package/dist/Command-C_iW2joV.js.map +1 -0
  11. package/dist/ComponentVariantProvider-B0SFUaXB.js.map +1 -1
  12. package/dist/Description-BTPMlTT-.js.map +1 -1
  13. package/dist/Dialog-CkDUxZUj.js.map +1 -1
  14. package/dist/Divider-Dm2gjy8W.js.map +1 -1
  15. package/dist/EmptyState-DRKjscH-.js.map +1 -1
  16. package/dist/ErrorState-B26k67-z.js.map +1 -1
  17. package/dist/FeatureIcon-yM7FhAXa.js.map +1 -1
  18. package/dist/{Field-CdocNMjg.js → Field-DpbrZvvg.js} +2 -2
  19. package/dist/Field-DpbrZvvg.js.map +1 -0
  20. package/dist/{FieldLabel-DRwAhGMz.js → FieldLabel-saPDMPPr.js} +2 -2
  21. package/dist/FieldLabel-saPDMPPr.js.map +1 -0
  22. package/dist/FolderSvg-cw0DxNVy.js.map +1 -1
  23. package/dist/{FormFooterTemplate-1MNxzQ7J.js → FormFooterTemplate-DV4pN3b-.js} +2 -2
  24. package/dist/FormFooterTemplate-DV4pN3b-.js.map +1 -0
  25. package/dist/FormHeader-BA2dJOPS.js.map +1 -1
  26. package/dist/{FormStack-DbtLshF8.js → FormStack-D-0fK-Zy.js} +3 -3
  27. package/dist/FormStack-D-0fK-Zy.js.map +1 -0
  28. package/dist/HintState-BxrCAWqq.js.map +1 -1
  29. package/dist/Icon-DH3ev9GK.js.map +1 -1
  30. package/dist/IconButton-moydR8IU.js.map +1 -1
  31. package/dist/{IconTooltip-CibXkFmt.js → IconTooltip-BbswlF6Q.js} +3 -3
  32. package/dist/IconTooltip-BbswlF6Q.js.map +1 -0
  33. package/dist/ImagePlaceholder-B6mGYVx2.js.map +1 -1
  34. package/dist/ImagePreview-BIBDrLVV.js.map +1 -1
  35. package/dist/ImageUploader-C-_ZPptv.js.map +1 -1
  36. package/dist/Indicator-B75A1Vgp.js.map +1 -1
  37. package/dist/InputGroup-CmstXpkX.js.map +1 -1
  38. package/dist/InputOTP-B2e1nfSO.js.map +1 -1
  39. package/dist/Loader-BpHiL6W-.js.map +1 -1
  40. package/dist/MenuItem-pvsONHlh.js.map +1 -1
  41. package/dist/{MenuItemShortcut-CGbVYqRi.js → MenuItemShortcut-DK7VneTR.js} +2 -2
  42. package/dist/MenuItemShortcut-DK7VneTR.js.map +1 -0
  43. package/dist/MenuItemText-7uPl9P3z.js.map +1 -1
  44. package/dist/Overlay-CLw_hvAN.js.map +1 -1
  45. package/dist/{Popover-CkezMtEz.js → Popover-DmwXZwYd.js} +17 -17
  46. package/dist/Popover-DmwXZwYd.js.map +1 -0
  47. package/dist/RichButton-BuenN3bJ.js.map +1 -1
  48. package/dist/ScrollShadowContainer-ODG9ChxA.js.map +1 -1
  49. package/dist/{SearchSelectTag-D1bFK1ux.js → SearchSelectTag-Ce-Q9JGR.js} +2 -2
  50. package/dist/SearchSelectTag-Ce-Q9JGR.js.map +1 -0
  51. package/dist/{Select-Bfrb-J8s.js → Select-CWbLja8r.js} +195 -195
  52. package/dist/Select-CWbLja8r.js.map +1 -0
  53. package/dist/Sheet-Dx9mwcF6.js.map +1 -1
  54. package/dist/Shortcut-D8L15_ed.js +22 -0
  55. package/dist/Shortcut-D8L15_ed.js.map +1 -0
  56. package/dist/Skeleton-y6I-i9q5.js.map +1 -1
  57. package/dist/{Tag-DJuVSJh5.js → Tag-CofZF1d0.js} +6 -6
  58. package/dist/Tag-CofZF1d0.js.map +1 -0
  59. package/dist/Text-DeBE8AKl.js.map +1 -1
  60. package/dist/TextInput-DTzujp77.js.map +1 -1
  61. package/dist/{Toggle-CS29Nksd.js → Toggle-CCD2UHWr.js} +15 -13
  62. package/dist/Toggle-CCD2UHWr.js.map +1 -0
  63. package/dist/{Tooltip-Cm1-WEdA.js → Tooltip-BH_Jc6ub.js} +2 -2
  64. package/dist/Tooltip-BH_Jc6ub.js.map +1 -0
  65. package/dist/TriggerButton-a2ClSj7f.js +33 -0
  66. package/dist/TriggerButton-a2ClSj7f.js.map +1 -0
  67. package/dist/blocks/auth/otp-form.js +1 -1
  68. package/dist/blocks/auth/otp-form.js.map +1 -1
  69. package/dist/cn-dsXlqdJg.js.map +1 -1
  70. package/dist/components/alert-dialog.js.map +1 -1
  71. package/dist/components/alert.js.map +1 -1
  72. package/dist/components/avatar/Avatar.d.ts +1 -1
  73. package/dist/components/avatar/avatar-indicator/AvatarIndicator.d.ts +3 -1
  74. package/dist/components/avatar/avatar-label/AvatarLabel.d.ts +1 -1
  75. package/dist/components/avatar.js +110 -93
  76. package/dist/components/avatar.js.map +1 -1
  77. package/dist/components/badge.js.map +1 -1
  78. package/dist/components/breadcrumb.js.map +1 -1
  79. package/dist/components/button.js +1 -1
  80. package/dist/components/button.js.map +1 -1
  81. package/dist/components/calendar.js.map +1 -1
  82. package/dist/components/card.js.map +1 -1
  83. package/dist/components/carousel.js.map +1 -1
  84. package/dist/components/checkbox.js +1 -1
  85. package/dist/components/collapsible.js.map +1 -1
  86. package/dist/components/color-tile.js.map +1 -1
  87. package/dist/components/command.js +1 -1
  88. package/dist/components/container.js.map +1 -1
  89. package/dist/components/counter.js.map +1 -1
  90. package/dist/components/dialog.js +1 -1
  91. package/dist/components/dialog.js.map +1 -1
  92. package/dist/components/divider.js.map +1 -1
  93. package/dist/components/drawer.js +1 -1
  94. package/dist/components/drawer.js.map +1 -1
  95. package/dist/components/dropdown.js +2 -2
  96. package/dist/components/dropdown.js.map +1 -1
  97. package/dist/components/error-state.js.map +1 -1
  98. package/dist/components/field.js +1 -1
  99. package/dist/components/file-upload.js.map +1 -1
  100. package/dist/components/form.js +3 -3
  101. package/dist/components/form.js.map +1 -1
  102. package/dist/components/gallery.js.map +1 -1
  103. package/dist/components/icon-tooltip.js +1 -1
  104. package/dist/components/input.js.map +1 -1
  105. package/dist/components/label.js +1 -1
  106. package/dist/components/menu-item.js +1 -1
  107. package/dist/components/menu-item.js.map +1 -1
  108. package/dist/components/overflow-tooltip.js +1 -1
  109. package/dist/components/overflow-tooltip.js.map +1 -1
  110. package/dist/components/page-state.js.map +1 -1
  111. package/dist/components/popover.js +1 -1
  112. package/dist/components/portal-container.js.map +1 -1
  113. package/dist/components/progress-circle.js.map +1 -1
  114. package/dist/components/progress.js.map +1 -1
  115. package/dist/components/prose.js.map +1 -1
  116. package/dist/components/radio-group.js.map +1 -1
  117. package/dist/components/resizable.js.map +1 -1
  118. package/dist/components/scheduler.js +1 -1
  119. package/dist/components/scheduler.js.map +1 -1
  120. package/dist/components/search-select.js +4 -4
  121. package/dist/components/search-select.js.map +1 -1
  122. package/dist/components/select.js +1 -1
  123. package/dist/components/shortcut.js +1 -1
  124. package/dist/components/sidebar.js +71 -68
  125. package/dist/components/sidebar.js.map +1 -1
  126. package/dist/components/slider.js.map +1 -1
  127. package/dist/components/stepper.js.map +1 -1
  128. package/dist/components/switch.js +1 -1
  129. package/dist/components/switch.js.map +1 -1
  130. package/dist/components/system-state.js.map +1 -1
  131. package/dist/components/table.js.map +1 -1
  132. package/dist/components/tabs.js.map +1 -1
  133. package/dist/components/tag-input.js +2 -2
  134. package/dist/components/tag-input.js.map +1 -1
  135. package/dist/components/tag.js +1 -1
  136. package/dist/components/textarea.js.map +1 -1
  137. package/dist/components/toast.js.map +1 -1
  138. package/dist/components/toggle/Toggle.d.ts +8 -2
  139. package/dist/components/toggle-group.js +1 -1
  140. package/dist/components/toggle-group.js.map +1 -1
  141. package/dist/components/toggle.js +1 -1
  142. package/dist/components/toolbar.js.map +1 -1
  143. package/dist/components/tooltip.js +1 -1
  144. package/dist/downloadFile-yZV-aaO2.js.map +1 -1
  145. package/dist/font-inter.css +15 -15
  146. package/dist/font-menlo.css +15 -15
  147. package/dist/index-0ioNhtNM.js.map +1 -1
  148. package/dist/index-5Bhkapwi.js.map +1 -1
  149. package/dist/index-BGQepRFJ.js.map +1 -1
  150. package/dist/index-BGfrl8IX.js.map +1 -1
  151. package/dist/index-BNirMMl4.js.map +1 -1
  152. package/dist/index-BVqs-uqP.js.map +1 -1
  153. package/dist/index-BZPx6jYI.js.map +1 -1
  154. package/dist/index-BdXokVmb.js.map +1 -1
  155. package/dist/index-Bwf2hSw6.js.map +1 -1
  156. package/dist/index-C0UREtMP.js.map +1 -1
  157. package/dist/index-C3surxzg.js.map +1 -1
  158. package/dist/index-CCKe-Mpx.js.map +1 -1
  159. package/dist/index-CpDnqHCm.js.map +1 -1
  160. package/dist/index-DFZozV_h.js.map +1 -1
  161. package/dist/index-DG36Jang.js.map +1 -1
  162. package/dist/index-DfNPZZ8M.js.map +1 -1
  163. package/dist/index-DpXwz_9G.js.map +1 -1
  164. package/dist/index-Nzc5v6h6.js.map +1 -1
  165. package/dist/index-l1F44JQJ.js.map +1 -1
  166. package/dist/index.js.map +1 -1
  167. package/dist/inputBaseStyles-BZJgQP7O.js.map +1 -1
  168. package/dist/lib/utils.js.map +1 -1
  169. package/dist/styles-scoped.css +5846 -5832
  170. package/dist/styles.css +1949 -1935
  171. package/dist/types/css.d.ts +4 -4
  172. package/dist/useBreakpoints-wEcfJPHd.js.map +1 -1
  173. package/dist/useDebounce-BRah78CF.js.map +1 -1
  174. package/dist/useFileUpload-iDag0iqM.js.map +1 -1
  175. package/dist/useMergeRefs-qoKniYqT.js.map +1 -1
  176. package/dist/usePortalContainer-ae6EzS08.js.map +1 -1
  177. package/dist/vendors/tanstack/react-table.js.map +1 -1
  178. package/dist/zod-BMNoK3aM.js.map +1 -1
  179. package/package.json +172 -172
  180. package/dist/CheckboxField-DvsGq3kV.js.map +0 -1
  181. package/dist/Command-BU9Ouar3.js.map +0 -1
  182. package/dist/Field-CdocNMjg.js.map +0 -1
  183. package/dist/FieldLabel-DRwAhGMz.js.map +0 -1
  184. package/dist/FormFooterTemplate-1MNxzQ7J.js.map +0 -1
  185. package/dist/FormStack-DbtLshF8.js.map +0 -1
  186. package/dist/IconTooltip-CibXkFmt.js.map +0 -1
  187. package/dist/MenuItemShortcut-CGbVYqRi.js.map +0 -1
  188. package/dist/Popover-CkezMtEz.js.map +0 -1
  189. package/dist/SearchSelectTag-D1bFK1ux.js.map +0 -1
  190. package/dist/Select-Bfrb-J8s.js.map +0 -1
  191. package/dist/Shortcut-Cm4nUx2C.js +0 -22
  192. package/dist/Shortcut-Cm4nUx2C.js.map +0 -1
  193. package/dist/Tag-DJuVSJh5.js.map +0 -1
  194. package/dist/Toggle-CS29Nksd.js.map +0 -1
  195. package/dist/Tooltip-Cm1-WEdA.js.map +0 -1
  196. package/dist/TriggerButton-BzXO5wcQ.js +0 -33
  197. package/dist/TriggerButton-BzXO5wcQ.js.map +0 -1
  198. package/dist/design-tokens.source.json +0 -1
@@ -1,4 +1,4 @@
1
- declare module "*.css" {
2
- const content: { [className: string]: string };
3
- export default content;
4
- }
1
+ declare module "*.css" {
2
+ const content: { [className: string]: string };
3
+ export default content;
4
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"useBreakpoints-wEcfJPHd.js","sources":["../node_modules/.pnpm/@react-hook+media-query@1.1.1_react@18.3.1/node_modules/@react-hook/media-query/dist/module/index.js","../src/hooks/useBreakpoints.ts"],"sourcesContent":["import * as React from 'react';\n\nfunction queriesDidChange(prevQueries, nextQueries) {\n if (nextQueries === prevQueries) return false;\n const nextQueriesArr = Object.values(nextQueries);\n const prevQueriesArr = Object.values(prevQueries);\n if (nextQueriesArr.length !== prevQueriesArr.length) return true;\n if (nextQueriesArr.some((q, i) => q !== prevQueriesArr[i])) return true;\n const prevKeys = Object.keys(prevQueries);\n return Object.keys(nextQueries).some((n, i) => n !== prevKeys[i]);\n}\n\nfunction _ref(curr, key) {\n curr.matches[key] = false;\n curr.mediaQueries[key] = {};\n return curr;\n}\n\nfunction init(queries) {\n const queryKeys = Object.keys(queries);\n /* istanbul ignore next */\n\n if (typeof window === 'undefined') return queryKeys.reduce(_ref, {\n mediaQueries: {},\n matches: {}\n });\n return queryKeys.reduce((state, name) => {\n const mql = window.matchMedia(queries[name]);\n state.mediaQueries[name] = mql;\n state.matches[name] = mql.matches;\n return state;\n }, {\n mediaQueries: {},\n matches: {}\n });\n}\n\nfunction reducer(state, action) {\n function _ref2(prev, key) {\n prev[key] = state.mediaQueries[key].matches;\n return prev;\n }\n\n switch (action.type) {\n case 'updateMatches':\n return {\n matches: Object.keys(state.mediaQueries).reduce(_ref2, {}),\n mediaQueries: state.mediaQueries\n };\n\n case 'setQueries':\n return init(action.queries);\n }\n}\n/**\n * A hook that returns a [`MediaQueryMatches`](#mediaquerymatches) object which will\n * tell you if specific media queries matched, all media queries matched, or\n * any media queries matched. Matches in this hook will always return `false` when\n * rendering on the server.\n *\n * @param queryMap The media queries you want to match against e.g. `{screen: \"screen\", width: \"(min-width: 12em)\"}`\n */\n\n\nexport function useMediaQueries(queryMap) {\n const prevQueries = React.useRef(queryMap);\n const [state, dispatch] = React.useReducer(reducer, queryMap, init);\n React.useEffect(() => {\n if (queriesDidChange(queryMap, prevQueries.current)) {\n dispatch({\n type: 'setQueries',\n queries: queryMap\n });\n prevQueries.current = queryMap;\n }\n }, [queryMap]);\n\n function _ref3() {\n return dispatch({\n type: 'updateMatches'\n });\n }\n\n function _ref4(mq) {\n const callback = _ref3;\n if (typeof mq.addListener !== 'undefined') mq.addListener(callback);else mq.addEventListener('change', callback);\n return callback;\n }\n\n React.useEffect(() => {\n const queries = Object.values(state.mediaQueries);\n const callbacks = queries.map(_ref4);\n\n function _ref5(mq, i) {\n if (typeof mq.addListener !== 'undefined') mq.removeListener(callbacks[i]);else mq.removeEventListener('change', callbacks[i]);\n }\n\n return () => {\n queries.forEach(_ref5);\n };\n }, [state.mediaQueries]);\n const {\n matches\n } = state;\n const matchValues = React.useMemo(() => Object.values(matches), [matches]);\n return {\n matches,\n matchesAny: matchValues.some(Boolean),\n matchesAll: matchValues.length > 0 && matchValues.every(Boolean)\n };\n}\n/**\n * A hook that returns `true` if the media query matched and `false` if not. This\n * hook will always return `false` when rendering on the server.\n *\n * @param query The media query you want to match against e.g. `\"only screen and (min-width: 12em)\"`\n */\n\nexport function useMediaQuery(query) {\n return useMediaQueries(getObj(query)).matchesAll;\n}\nconst cache = {};\n\nfunction getObj(query) {\n if (cache[query] === void 0) cache[query] = {\n default: query\n };\n return cache[query];\n}","import { useMediaQuery } from \"@react-hook/media-query\";\r\n\r\n// Брейкпоинты Tailwind CSS\r\nconst breakpoints = {\r\n\tsm: \"640px\",\r\n\tmd: \"768px\",\r\n\tlg: \"1024px\",\r\n\txl: \"1280px\",\r\n\t\"2xl\": \"1536px\"\r\n} as const;\r\n\r\ntype Breakpoint = keyof typeof breakpoints;\r\n\r\n/** min-width: 640px */\r\nexport const useIsSm = () => useMediaQuery(`(min-width: ${breakpoints.sm})`);\r\n/** min-width: 768px */\r\nexport const useIsMd = () => useMediaQuery(`(min-width: ${breakpoints.md})`);\r\n/** min-width: 1024px */\r\nexport const useIsLg = () => useMediaQuery(`(min-width: ${breakpoints.lg})`);\r\n/** min-width: 1280px */\r\nexport const useIsXl = () => useMediaQuery(`(min-width: ${breakpoints.xl})`);\r\n/** min-width: 1536px */\r\nexport const useIs2Xl = () => useMediaQuery(`(min-width: ${breakpoints[\"2xl\"]})`);\r\n\r\n/** max-width: 1024px */\r\nexport const useIsMobile = () => !useIsLg();\r\n\r\nexport const useBreakpoint = (breakpoint: Breakpoint) => {\r\n\treturn useMediaQuery(`(min-width: ${breakpoints[breakpoint]})`);\r\n};\r\n\r\nexport const useActiveBreakpoint = (): Breakpoint | null => {\r\n\tconst is2Xl = useIs2Xl();\r\n\tconst isXl = useIsXl();\r\n\tconst isLg = useIsLg();\r\n\tconst isMd = useIsMd();\r\n\tconst isSm = useIsSm();\r\n\r\n\tif (is2Xl) return \"2xl\";\r\n\tif (isXl) return \"xl\";\r\n\tif (isLg) return \"lg\";\r\n\tif (isMd) return \"md\";\r\n\tif (isSm) return \"sm\";\r\n\treturn null;\r\n};\r\n"],"names":["queriesDidChange","prevQueries","nextQueries","nextQueriesArr","prevQueriesArr","q","i","prevKeys","n","_ref","curr","key","init","queries","queryKeys","state","name","mql","reducer","action","_ref2","prev","useMediaQueries","queryMap","React","dispatch","_ref3","_ref4","mq","callback","callbacks","_ref5","matches","matchValues","useMediaQuery","query","getObj","cache","breakpoints","useIsLg","useIsMobile"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"useBreakpoints-wEcfJPHd.js","sources":["../node_modules/.pnpm/@react-hook+media-query@1.1.1_react@18.3.1/node_modules/@react-hook/media-query/dist/module/index.js","../src/hooks/useBreakpoints.ts"],"sourcesContent":["import * as React from 'react';\n\nfunction queriesDidChange(prevQueries, nextQueries) {\n if (nextQueries === prevQueries) return false;\n const nextQueriesArr = Object.values(nextQueries);\n const prevQueriesArr = Object.values(prevQueries);\n if (nextQueriesArr.length !== prevQueriesArr.length) return true;\n if (nextQueriesArr.some((q, i) => q !== prevQueriesArr[i])) return true;\n const prevKeys = Object.keys(prevQueries);\n return Object.keys(nextQueries).some((n, i) => n !== prevKeys[i]);\n}\n\nfunction _ref(curr, key) {\n curr.matches[key] = false;\n curr.mediaQueries[key] = {};\n return curr;\n}\n\nfunction init(queries) {\n const queryKeys = Object.keys(queries);\n /* istanbul ignore next */\n\n if (typeof window === 'undefined') return queryKeys.reduce(_ref, {\n mediaQueries: {},\n matches: {}\n });\n return queryKeys.reduce((state, name) => {\n const mql = window.matchMedia(queries[name]);\n state.mediaQueries[name] = mql;\n state.matches[name] = mql.matches;\n return state;\n }, {\n mediaQueries: {},\n matches: {}\n });\n}\n\nfunction reducer(state, action) {\n function _ref2(prev, key) {\n prev[key] = state.mediaQueries[key].matches;\n return prev;\n }\n\n switch (action.type) {\n case 'updateMatches':\n return {\n matches: Object.keys(state.mediaQueries).reduce(_ref2, {}),\n mediaQueries: state.mediaQueries\n };\n\n case 'setQueries':\n return init(action.queries);\n }\n}\n/**\n * A hook that returns a [`MediaQueryMatches`](#mediaquerymatches) object which will\n * tell you if specific media queries matched, all media queries matched, or\n * any media queries matched. Matches in this hook will always return `false` when\n * rendering on the server.\n *\n * @param queryMap The media queries you want to match against e.g. `{screen: \"screen\", width: \"(min-width: 12em)\"}`\n */\n\n\nexport function useMediaQueries(queryMap) {\n const prevQueries = React.useRef(queryMap);\n const [state, dispatch] = React.useReducer(reducer, queryMap, init);\n React.useEffect(() => {\n if (queriesDidChange(queryMap, prevQueries.current)) {\n dispatch({\n type: 'setQueries',\n queries: queryMap\n });\n prevQueries.current = queryMap;\n }\n }, [queryMap]);\n\n function _ref3() {\n return dispatch({\n type: 'updateMatches'\n });\n }\n\n function _ref4(mq) {\n const callback = _ref3;\n if (typeof mq.addListener !== 'undefined') mq.addListener(callback);else mq.addEventListener('change', callback);\n return callback;\n }\n\n React.useEffect(() => {\n const queries = Object.values(state.mediaQueries);\n const callbacks = queries.map(_ref4);\n\n function _ref5(mq, i) {\n if (typeof mq.addListener !== 'undefined') mq.removeListener(callbacks[i]);else mq.removeEventListener('change', callbacks[i]);\n }\n\n return () => {\n queries.forEach(_ref5);\n };\n }, [state.mediaQueries]);\n const {\n matches\n } = state;\n const matchValues = React.useMemo(() => Object.values(matches), [matches]);\n return {\n matches,\n matchesAny: matchValues.some(Boolean),\n matchesAll: matchValues.length > 0 && matchValues.every(Boolean)\n };\n}\n/**\n * A hook that returns `true` if the media query matched and `false` if not. This\n * hook will always return `false` when rendering on the server.\n *\n * @param query The media query you want to match against e.g. `\"only screen and (min-width: 12em)\"`\n */\n\nexport function useMediaQuery(query) {\n return useMediaQueries(getObj(query)).matchesAll;\n}\nconst cache = {};\n\nfunction getObj(query) {\n if (cache[query] === void 0) cache[query] = {\n default: query\n };\n return cache[query];\n}","import { useMediaQuery } from \"@react-hook/media-query\";\n\n// Брейкпоинты Tailwind CSS\nconst breakpoints = {\n\tsm: \"640px\",\n\tmd: \"768px\",\n\tlg: \"1024px\",\n\txl: \"1280px\",\n\t\"2xl\": \"1536px\"\n} as const;\n\ntype Breakpoint = keyof typeof breakpoints;\n\n/** min-width: 640px */\nexport const useIsSm = () => useMediaQuery(`(min-width: ${breakpoints.sm})`);\n/** min-width: 768px */\nexport const useIsMd = () => useMediaQuery(`(min-width: ${breakpoints.md})`);\n/** min-width: 1024px */\nexport const useIsLg = () => useMediaQuery(`(min-width: ${breakpoints.lg})`);\n/** min-width: 1280px */\nexport const useIsXl = () => useMediaQuery(`(min-width: ${breakpoints.xl})`);\n/** min-width: 1536px */\nexport const useIs2Xl = () => useMediaQuery(`(min-width: ${breakpoints[\"2xl\"]})`);\n\n/** max-width: 1024px */\nexport const useIsMobile = () => !useIsLg();\n\nexport const useBreakpoint = (breakpoint: Breakpoint) => {\n\treturn useMediaQuery(`(min-width: ${breakpoints[breakpoint]})`);\n};\n\nexport const useActiveBreakpoint = (): Breakpoint | null => {\n\tconst is2Xl = useIs2Xl();\n\tconst isXl = useIsXl();\n\tconst isLg = useIsLg();\n\tconst isMd = useIsMd();\n\tconst isSm = useIsSm();\n\n\tif (is2Xl) return \"2xl\";\n\tif (isXl) return \"xl\";\n\tif (isLg) return \"lg\";\n\tif (isMd) return \"md\";\n\tif (isSm) return \"sm\";\n\treturn null;\n};\n"],"names":["queriesDidChange","prevQueries","nextQueries","nextQueriesArr","prevQueriesArr","q","i","prevKeys","n","_ref","curr","key","init","queries","queryKeys","state","name","mql","reducer","action","_ref2","prev","useMediaQueries","queryMap","React","dispatch","_ref3","_ref4","mq","callback","callbacks","_ref5","matches","matchValues","useMediaQuery","query","getObj","cache","breakpoints","useIsLg","useIsMobile"],"mappings":"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","x_google_ignoreList":[0]}
@@ -1 +1 @@
1
- {"version":3,"file":"useDebounce-BRah78CF.js","sources":["../src/hooks/useDebounce.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\r\n\r\n/**\r\n * Хук для дебаунса значения\r\n * @param value - значение для дебаунса\r\n * @param delay - задержка в миллисекундах\r\n * @returns дебаунсированное значение\r\n */\r\nexport function useDebounce<T>(value: T, delay: number): T {\r\n\tconst [debouncedValue, setDebouncedValue] = useState<T>(value);\r\n\r\n\tuseEffect(() => {\r\n\t\tconst timer = setTimeout(() => {\r\n\t\t\tsetDebouncedValue(value);\r\n\t\t}, delay);\r\n\r\n\t\treturn () => {\r\n\t\t\tclearTimeout(timer);\r\n\t\t};\r\n\t}, [value, delay]);\r\n\r\n\treturn debouncedValue;\r\n}\r\n"],"names":["useDebounce","value","delay","debouncedValue","setDebouncedValue","useState","useEffect","timer"],"mappings":";AAQgB,SAAAA,EAAeC,GAAUC,GAAkB;AAC1D,QAAM,CAACC,GAAgBC,CAAiB,IAAIC,EAAYJ,CAAK;AAE7D,SAAAK,EAAU,MAAM;AACT,UAAAC,IAAQ,WAAW,MAAM;AAC9B,MAAAH,EAAkBH,CAAK;AAAA,OACrBC,CAAK;AAER,WAAO,MAAM;AACZ,mBAAaK,CAAK;AAAA,IACnB;AAAA,EAAA,GACE,CAACN,GAAOC,CAAK,CAAC,GAEVC;AACR;"}
1
+ {"version":3,"file":"useDebounce-BRah78CF.js","sources":["../src/hooks/useDebounce.ts"],"sourcesContent":["import { useEffect, useState } from \"react\";\n\n/**\n * Хук для дебаунса значения\n * @param value - значение для дебаунса\n * @param delay - задержка в миллисекундах\n * @returns дебаунсированное значение\n */\nexport function useDebounce<T>(value: T, delay: number): T {\n\tconst [debouncedValue, setDebouncedValue] = useState<T>(value);\n\n\tuseEffect(() => {\n\t\tconst timer = setTimeout(() => {\n\t\t\tsetDebouncedValue(value);\n\t\t}, delay);\n\n\t\treturn () => {\n\t\t\tclearTimeout(timer);\n\t\t};\n\t}, [value, delay]);\n\n\treturn debouncedValue;\n}\n"],"names":["useDebounce","value","delay","debouncedValue","setDebouncedValue","useState","useEffect","timer"],"mappings":";AAQgB,SAAAA,EAAeC,GAAUC,GAAkB;AAC1D,QAAM,CAACC,GAAgBC,CAAiB,IAAIC,EAAYJ,CAAK;AAE7D,SAAAK,EAAU,MAAM;AACT,UAAAC,IAAQ,WAAW,MAAM;AAC9B,MAAAH,EAAkBH,CAAK;AAAA,OACrBC,CAAK;AAER,WAAO,MAAM;AACZ,mBAAaK,CAAK;AAAA,IACnB;AAAA,EAAA,GACE,CAACN,GAAOC,CAAK,CAAC,GAEVC;AACR;"}
@@ -1 +1 @@
1
- {"version":3,"file":"useFileUpload-iDag0iqM.js","sources":["../src/lib/utils/file/formatBytes.ts","../src/hooks/use-file-upload/errorMessages.ts","../src/hooks/use-file-upload/useFileUpload.ts"],"sourcesContent":["// Helper function to format bytes to human-readable format\r\nexport const formatBytes = (bytes: number, decimals = 2): string => {\r\n\tif (bytes === 0) return \"0 Bytes\";\r\n\r\n\tconst k = 1024;\r\n\tconst dm = decimals < 0 ? 0 : decimals;\r\n\tconst sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"];\r\n\r\n\tconst i = Math.floor(Math.log(bytes) / Math.log(k));\r\n\r\n\treturn Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + sizes[i];\r\n};\r\n","import { formatBytes } from \"@/lib/utils/file/formatBytes\";\r\n\r\n/**\r\n * Интерфейс для кастомизации сообщений об ошибках в useFileUpload\r\n */\r\nexport interface FileUploadErrorMessages {\r\n\t/**\r\n\t * Сообщение когда файл превышает максимальный размер\r\n\t * @param fileName - имя файла\r\n\t * @param maxSizeBytes - максимальный размер в байтах\r\n\t */\r\n\tfileTooLarge?: (fileName: string, maxSizeBytes: number) => string;\r\n\r\n\t/**\r\n\t * Сообщение когда тип файла не разрешен\r\n\t * @param fileName - имя файла\r\n\t */\r\n\tinvalidFileType?: (fileName: string) => string;\r\n\r\n\t/**\r\n\t * Сообщение когда превышено максимальное количество файлов\r\n\t * @param maxFiles - максимальное количество файлов\r\n\t */\r\n\ttooManyFiles?: (maxFiles: number) => string;\r\n\r\n\t/**\r\n\t * Сообщение когда некоторые файлы превышают максимальный размер (для множественной загрузки)\r\n\t * @param maxSizeBytes - максимальный размер в байтах\r\n\t */\r\n\tsomeFilesTooLarge?: (maxSizeBytes: number) => string;\r\n\r\n\t/**\r\n\t * Сообщение когда файл превышает максимальный размер (для одиночной загрузки)\r\n\t * @param maxSizeBytes - максимальный размер в байтах\r\n\t */\r\n\tsingleFileTooLarge?: (maxSizeBytes: number) => string;\r\n}\r\n\r\n/**\r\n * Сообщения об ошибках по умолчанию\r\n */\r\nexport const defaultErrorMessages: Required<FileUploadErrorMessages> = {\r\n\tfileTooLarge: (fileName, maxSizeBytes) =>\r\n\t\t`File \"${fileName}\" exceeds the maximum size of ${formatBytes(maxSizeBytes)}.`,\r\n\tinvalidFileType: (fileName) => `File \"${fileName}\" is not an accepted file type.`,\r\n\ttooManyFiles: (maxFiles) => `You can only upload a maximum of ${maxFiles} files.`,\r\n\tsomeFilesTooLarge: (maxSizeBytes) => `Some files exceed the maximum size of ${formatBytes(maxSizeBytes)}.`,\r\n\tsingleFileTooLarge: (maxSizeBytes) => `File exceeds the maximum size of ${formatBytes(maxSizeBytes)}.`\r\n};\r\n\r\n/**\r\n * Сообщения об ошибках на русском языке\r\n */\r\nexport const defaultErrorMessagesRu: Required<FileUploadErrorMessages> = {\r\n\tfileTooLarge: (fileName, maxSizeBytes) =>\r\n\t\t`Файл \"${fileName}\" превышает максимальный размер ${formatBytes(maxSizeBytes)}`,\r\n\tinvalidFileType: (fileName) => `Файл \"${fileName}\" имеет недопустимый тип`,\r\n\ttooManyFiles: (maxFiles) => `Можно загрузить максимум ${maxFiles} файлов`,\r\n\tsomeFilesTooLarge: (maxSizeBytes) => `Некоторые файлы превышают максимальный размер ${formatBytes(maxSizeBytes)}`,\r\n\tsingleFileTooLarge: (maxSizeBytes) => `Файл превышает максимальный размер ${formatBytes(maxSizeBytes)}`\r\n};\r\n","import {\r\n\tuseCallback,\r\n\tuseMemo,\r\n\tuseRef,\r\n\tuseState,\r\n\ttype ChangeEvent,\r\n\ttype DragEvent,\r\n\ttype InputHTMLAttributes\r\n} from \"react\";\r\nimport { defaultErrorMessages, type FileUploadErrorMessages } from \"./errorMessages\";\r\n\r\nexport type FileData = {\r\n\tname: string;\r\n\tsize: number;\r\n\ttype: string;\r\n\tid?: string;\r\n};\r\n\r\nexport type FileMetadata = FileData & {\r\n\turl: string;\r\n\tid: string;\r\n};\r\n\r\nexport type FileValue = File | FileData;\r\n\r\nexport type FileWithPreview = {\r\n\tfile: FileValue;\r\n\tid: string;\r\n\tpreview?: string;\r\n};\r\n\r\n/**\r\n * Ограничения для загрузки файлов\r\n */\r\nexport type FileUploadConstraints = {\r\n\t/**\r\n\t * Максимальное количество файлов\r\n\t * Используется только когда multiple=true\r\n\t * @default Infinity\r\n\t */\r\n\tmaxFiles?: number;\r\n\r\n\t/**\r\n\t * Максимальный размер файла в байтах\r\n\t * @default Infinity\r\n\t */\r\n\tmaxSize?: number;\r\n\r\n\t/**\r\n\t * Допустимые типы файлов (строка MIME-типов или расширений через запятую)\r\n\t * @example \"image/jpeg,image/png,.pdf,.doc\"\r\n\t * @example \"*.jpg,*.png\"\r\n\t * @example \"image/*\"\r\n\t * @default \"*\"\r\n\t */\r\n\taccept?: string;\r\n\r\n\t/**\r\n\t * Разрешить выбор нескольких файлов\r\n\t * @default false\r\n\t */\r\n\tmultiple?: boolean;\r\n};\r\n\r\nexport type FileUploadOptions = FileUploadConstraints & {\r\n\tinitialFiles?: FileMetadata[];\r\n\tonFilesChange?: (files: FileWithPreview[]) => void;\r\n\tonFilesAdded?: (addedFiles: FileWithPreview[]) => void;\r\n\t/**\r\n\t * Кастомные сообщения об ошибках\r\n\t * Можно переопределить только нужные сообщения\r\n\t */\r\n\terrorMessages?: Partial<FileUploadErrorMessages>;\r\n};\r\n\r\nexport type FileUploadState = {\r\n\tfiles: FileWithPreview[];\r\n\tisDragging: boolean;\r\n\terrors: string[];\r\n};\r\n\r\nexport type FileUploadActions = {\r\n\taddFiles: (files: FileList | File[]) => void;\r\n\tremoveFile: (id: string) => void;\r\n\tclearFiles: () => void;\r\n\tclearErrors: () => void;\r\n\thandleDragEnter: (e: DragEvent<HTMLElement>) => void;\r\n\thandleDragLeave: (e: DragEvent<HTMLElement>) => void;\r\n\thandleDragOver: (e: DragEvent<HTMLElement>) => void;\r\n\thandleDrop: (e: DragEvent<HTMLElement>) => void;\r\n\thandleFileChange: (e: ChangeEvent<HTMLInputElement>) => void;\r\n\topenFileDialog: () => void;\r\n\tgetInputProps: (props?: InputHTMLAttributes<HTMLInputElement>) => InputHTMLAttributes<HTMLInputElement> & {\r\n\t\tref: React.Ref<HTMLInputElement>;\r\n\t};\r\n};\r\n\r\n/** Хук был взять из библиотеки originui.\r\n * Код можно посмотреть по ссылке: https://github.com/origin-space/originui/blob/main/docs/use-file-upload.md\r\n */\r\nexport const useFileUpload = (options: FileUploadOptions = {}): [FileUploadState, FileUploadActions] => {\r\n\tconst {\r\n\t\tmaxFiles = Infinity,\r\n\t\tmaxSize = Infinity,\r\n\t\taccept = \"*\",\r\n\t\tmultiple = false,\r\n\t\tinitialFiles = [],\r\n\t\tonFilesChange,\r\n\t\tonFilesAdded,\r\n\t\terrorMessages: customErrorMessages\r\n\t} = options;\r\n\r\n\t// Объединяем дефолтные и кастомные сообщения\r\n\tconst errorMessages = useMemo(() => ({ ...defaultErrorMessages, ...customErrorMessages }), [customErrorMessages]);\r\n\r\n\tconst [state, setState] = useState<FileUploadState>({\r\n\t\tfiles: initialFiles.map((file) => ({\r\n\t\t\tfile,\r\n\t\t\tid: file.id,\r\n\t\t\tpreview: file.url\r\n\t\t})),\r\n\t\tisDragging: false,\r\n\t\terrors: []\r\n\t});\r\n\r\n\tconst inputRef = useRef<HTMLInputElement>(null);\r\n\r\n\tconst validateFile = useCallback(\r\n\t\t(file: FileValue): string | null => {\r\n\t\t\tconst fileName = file instanceof File ? file.name : file.name;\r\n\r\n\t\t\tif (file.size > maxSize) {\r\n\t\t\t\treturn errorMessages.fileTooLarge(fileName, maxSize);\r\n\t\t\t}\r\n\r\n\t\t\tif (accept !== \"*\") {\r\n\t\t\t\tconst acceptedTypes = accept.split(\",\").map((type) => type.trim());\r\n\t\t\t\tconst fileType = file instanceof File ? file.type || \"\" : file.type;\r\n\t\t\t\tconst fileExtension = `.${fileName.split(\".\").pop()}`;\r\n\r\n\t\t\t\tconst isAccepted = acceptedTypes.some((type) => {\r\n\t\t\t\t\tif (type.startsWith(\".\")) {\r\n\t\t\t\t\t\treturn fileExtension.toLowerCase() === type.toLowerCase();\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (type.endsWith(\"/*\")) {\r\n\t\t\t\t\t\tconst baseType = type.split(\"/\")[0];\r\n\t\t\t\t\t\treturn fileType.startsWith(`${baseType}/`);\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn fileType === type;\r\n\t\t\t\t});\r\n\r\n\t\t\t\tif (!isAccepted) {\r\n\t\t\t\t\treturn errorMessages.invalidFileType(fileName);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn null;\r\n\t\t},\r\n\t\t[accept, maxSize, errorMessages]\r\n\t);\r\n\r\n\tconst createPreview = useCallback((file: File | FileMetadata): string | undefined => {\r\n\t\tif (file instanceof File) {\r\n\t\t\treturn URL.createObjectURL(file);\r\n\t\t}\r\n\t\treturn file.url;\r\n\t}, []);\r\n\r\n\tconst generateUniqueId = useCallback((file: File | FileMetadata): string => {\r\n\t\tif (file instanceof File) {\r\n\t\t\treturn `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\r\n\t\t}\r\n\t\treturn file.id;\r\n\t}, []);\r\n\r\n\tconst clearFiles = useCallback(() => {\r\n\t\tsetState((prev) => {\r\n\t\t\t// Clean up object URLs\r\n\t\t\tprev.files.forEach((file) => {\r\n\t\t\t\tif (file.preview && file.file instanceof File && file.file.type.startsWith(\"image/\")) {\r\n\t\t\t\t\tURL.revokeObjectURL(file.preview);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\tif (inputRef.current) {\r\n\t\t\t\tinputRef.current.value = \"\";\r\n\t\t\t}\r\n\r\n\t\t\tconst newState = {\r\n\t\t\t\t...prev,\r\n\t\t\t\tfiles: [],\r\n\t\t\t\terrors: []\r\n\t\t\t};\r\n\r\n\t\t\tonFilesChange?.(newState.files);\r\n\t\t\treturn newState;\r\n\t\t});\r\n\t}, [onFilesChange]);\r\n\r\n\tconst addFiles = useCallback(\r\n\t\t(newFiles: FileList | File[]) => {\r\n\t\t\tif (!newFiles || newFiles.length === 0) return;\r\n\r\n\t\t\tconst newFilesArray = Array.from(newFiles);\r\n\t\t\tconst errors: string[] = [];\r\n\r\n\t\t\t// Clear existing errors when new files are uploaded\r\n\t\t\tsetState((prev) => ({ ...prev, errors: [] }));\r\n\r\n\t\t\t// In single file mode, clear existing files first\r\n\t\t\tif (!multiple) {\r\n\t\t\t\tclearFiles();\r\n\t\t\t}\r\n\r\n\t\t\t// Check if adding these files would exceed maxFiles (only in multiple mode)\r\n\t\t\tif (multiple && maxFiles !== Infinity && state.files.length + newFilesArray.length > maxFiles) {\r\n\t\t\t\terrors.push(errorMessages.tooManyFiles(maxFiles));\r\n\t\t\t\tsetState((prev) => ({ ...prev, errors }));\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tconst validFiles: FileWithPreview[] = [];\r\n\r\n\t\t\tnewFilesArray.forEach((file) => {\r\n\t\t\t\t// Only check for duplicates if multiple files are allowed\r\n\t\t\t\tif (multiple) {\r\n\t\t\t\t\tconst isDuplicate = state.files.some(\r\n\t\t\t\t\t\t(existingFile) => existingFile.file.name === file.name && existingFile.file.size === file.size\r\n\t\t\t\t\t);\r\n\r\n\t\t\t\t\t// Skip duplicate files silently\r\n\t\t\t\t\tif (isDuplicate) {\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Check file size\r\n\t\t\t\tif (file.size > maxSize) {\r\n\t\t\t\t\terrors.push(\r\n\t\t\t\t\t\tmultiple ? errorMessages.someFilesTooLarge(maxSize) : errorMessages.singleFileTooLarge(maxSize)\r\n\t\t\t\t\t);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst error = validateFile(file);\r\n\t\t\t\tif (error) {\r\n\t\t\t\t\terrors.push(error);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalidFiles.push({\r\n\t\t\t\t\t\tfile,\r\n\t\t\t\t\t\tid: generateUniqueId(file),\r\n\t\t\t\t\t\tpreview: createPreview(file)\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\t// Only update state if we have valid files to add\r\n\t\t\tif (validFiles.length > 0) {\r\n\t\t\t\t// Call the onFilesAdded callback with the newly added valid files\r\n\t\t\t\tonFilesAdded?.(validFiles);\r\n\r\n\t\t\t\tsetState((prev) => {\r\n\t\t\t\t\tconst newFiles = !multiple ? validFiles : [...prev.files, ...validFiles];\r\n\t\t\t\t\tonFilesChange?.(newFiles);\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\t...prev,\r\n\t\t\t\t\t\tfiles: newFiles,\r\n\t\t\t\t\t\terrors\r\n\t\t\t\t\t};\r\n\t\t\t\t});\r\n\t\t\t} else if (errors.length > 0) {\r\n\t\t\t\tsetState((prev) => ({\r\n\t\t\t\t\t...prev,\r\n\t\t\t\t\terrors\r\n\t\t\t\t}));\r\n\t\t\t}\r\n\r\n\t\t\t// Reset input value after handling files\r\n\t\t\tif (inputRef.current) {\r\n\t\t\t\tinputRef.current.value = \"\";\r\n\t\t\t}\r\n\t\t},\r\n\t\t[\r\n\t\t\tstate.files,\r\n\t\t\tmaxFiles,\r\n\t\t\tmultiple,\r\n\t\t\tmaxSize,\r\n\t\t\tvalidateFile,\r\n\t\t\tcreatePreview,\r\n\t\t\tgenerateUniqueId,\r\n\t\t\tclearFiles,\r\n\t\t\tonFilesChange,\r\n\t\t\tonFilesAdded,\r\n\t\t\terrorMessages\r\n\t\t]\r\n\t);\r\n\r\n\tconst removeFile = useCallback(\r\n\t\t(id: string) => {\r\n\t\t\tsetState((prev) => {\r\n\t\t\t\tconst fileToRemove = prev.files.find((file) => file.id === id);\r\n\t\t\t\tif (\r\n\t\t\t\t\tfileToRemove &&\r\n\t\t\t\t\tfileToRemove.preview &&\r\n\t\t\t\t\tfileToRemove.file instanceof File &&\r\n\t\t\t\t\tfileToRemove.file.type.startsWith(\"image/\")\r\n\t\t\t\t) {\r\n\t\t\t\t\tURL.revokeObjectURL(fileToRemove.preview);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst newFiles = prev.files.filter((file) => file.id !== id);\r\n\t\t\t\tonFilesChange?.(newFiles);\r\n\r\n\t\t\t\treturn {\r\n\t\t\t\t\t...prev,\r\n\t\t\t\t\tfiles: newFiles,\r\n\t\t\t\t\terrors: []\r\n\t\t\t\t};\r\n\t\t\t});\r\n\t\t},\r\n\t\t[onFilesChange]\r\n\t);\r\n\r\n\tconst clearErrors = useCallback(() => {\r\n\t\tsetState((prev) => ({\r\n\t\t\t...prev,\r\n\t\t\terrors: []\r\n\t\t}));\r\n\t}, []);\r\n\r\n\tconst handleDragEnter = useCallback((e: DragEvent<HTMLElement>) => {\r\n\t\te.preventDefault();\r\n\t\te.stopPropagation();\r\n\t\tsetState((prev) => ({ ...prev, isDragging: true }));\r\n\t}, []);\r\n\r\n\tconst handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\r\n\t\te.preventDefault();\r\n\t\te.stopPropagation();\r\n\r\n\t\tif (e.currentTarget.contains(e.relatedTarget as Node)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tsetState((prev) => ({ ...prev, isDragging: false }));\r\n\t}, []);\r\n\r\n\tconst handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\r\n\t\te.preventDefault();\r\n\t\te.stopPropagation();\r\n\t}, []);\r\n\r\n\tconst handleDrop = useCallback(\r\n\t\t(e: DragEvent<HTMLElement>) => {\r\n\t\t\te.preventDefault();\r\n\t\t\te.stopPropagation();\r\n\t\t\tsetState((prev) => ({ ...prev, isDragging: false }));\r\n\r\n\t\t\t// Don't process files if the input is disabled\r\n\t\t\tif (inputRef.current?.disabled) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tif (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\r\n\t\t\t\t// In single file mode, only use the first file\r\n\t\t\t\tif (!multiple) {\r\n\t\t\t\t\tconst file = e.dataTransfer.files[0];\r\n\t\t\t\t\taddFiles([file]);\r\n\t\t\t\t} else {\r\n\t\t\t\t\taddFiles(e.dataTransfer.files);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\t\t[addFiles, multiple]\r\n\t);\r\n\r\n\tconst handleFileChange = useCallback(\r\n\t\t(e: ChangeEvent<HTMLInputElement>) => {\r\n\t\t\tif (e.target.files && e.target.files.length > 0) {\r\n\t\t\t\taddFiles(e.target.files);\r\n\t\t\t}\r\n\t\t},\r\n\t\t[addFiles]\r\n\t);\r\n\r\n\tconst openFileDialog = useCallback(() => {\r\n\t\tif (inputRef.current) {\r\n\t\t\tinputRef.current.click();\r\n\t\t}\r\n\t}, []);\r\n\r\n\tconst getInputProps = useCallback(\r\n\t\t(props: InputHTMLAttributes<HTMLInputElement> = {}) => {\r\n\t\t\treturn {\r\n\t\t\t\t...props,\r\n\t\t\t\ttype: \"file\" as const,\r\n\t\t\t\tonChange: handleFileChange,\r\n\t\t\t\taccept: props.accept || accept,\r\n\t\t\t\tmultiple: props.multiple !== undefined ? props.multiple : multiple,\r\n\t\t\t\tref: inputRef\r\n\t\t\t};\r\n\t\t},\r\n\t\t[accept, multiple, handleFileChange]\r\n\t);\r\n\r\n\treturn [\r\n\t\tstate,\r\n\t\t{\r\n\t\t\taddFiles,\r\n\t\t\tremoveFile,\r\n\t\t\tclearFiles,\r\n\t\t\tclearErrors,\r\n\t\t\thandleDragEnter,\r\n\t\t\thandleDragLeave,\r\n\t\t\thandleDragOver,\r\n\t\t\thandleDrop,\r\n\t\t\thandleFileChange,\r\n\t\t\topenFileDialog,\r\n\t\t\tgetInputProps\r\n\t\t}\r\n\t];\r\n};\r\n"],"names":["formatBytes","bytes","decimals","k","dm","sizes","i","defaultErrorMessages","fileName","maxSizeBytes","maxFiles","defaultErrorMessagesRu","useFileUpload","options","maxSize","accept","multiple","initialFiles","onFilesChange","onFilesAdded","customErrorMessages","errorMessages","useMemo","state","setState","useState","file","inputRef","useRef","validateFile","useCallback","acceptedTypes","type","fileType","fileExtension","baseType","createPreview","generateUniqueId","clearFiles","prev","newState","addFiles","newFiles","newFilesArray","errors","validFiles","existingFile","error","removeFile","id","fileToRemove","clearErrors","handleDragEnter","handleDragLeave","handleDragOver","handleDrop","handleFileChange","openFileDialog","getInputProps","props"],"mappings":";AACO,MAAMA,IAAc,CAACC,GAAeC,IAAW,MAAc;AAC/D,MAAAD,MAAU,EAAU,QAAA;AAExB,QAAME,IAAI,MACJC,IAAKF,IAAW,IAAI,IAAIA,GACxBG,IAAQ,CAAC,SAAS,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,IAAI,GAEhEC,IAAI,KAAK,MAAM,KAAK,IAAIL,CAAK,IAAI,KAAK,IAAIE,CAAC,CAAC;AAElD,SAAO,OAAO,YAAYF,IAAQ,KAAK,IAAIE,GAAGG,CAAC,GAAG,QAAQF,CAAE,CAAC,IAAIC,EAAMC,CAAC;AACzE,GC8BaC,IAA0D;AAAA,EACtE,cAAc,CAACC,GAAUC,MACxB,SAASD,CAAQ,iCAAiCR,EAAYS,CAAY,CAAC;AAAA,EAC5E,iBAAiB,CAACD,MAAa,SAASA,CAAQ;AAAA,EAChD,cAAc,CAACE,MAAa,oCAAoCA,CAAQ;AAAA,EACxE,mBAAmB,CAACD,MAAiB,yCAAyCT,EAAYS,CAAY,CAAC;AAAA,EACvG,oBAAoB,CAACA,MAAiB,oCAAoCT,EAAYS,CAAY,CAAC;AACpG,GAKaE,IAA4D;AAAA,EACxE,cAAc,CAACH,GAAUC,MACxB,SAASD,CAAQ,mCAAmCR,EAAYS,CAAY,CAAC;AAAA,EAC9E,iBAAiB,CAACD,MAAa,SAASA,CAAQ;AAAA,EAChD,cAAc,CAACE,MAAa,4BAA4BA,CAAQ;AAAA,EAChE,mBAAmB,CAACD,MAAiB,iDAAiDT,EAAYS,CAAY,CAAC;AAAA,EAC/G,oBAAoB,CAACA,MAAiB,sCAAsCT,EAAYS,CAAY,CAAC;AACtG,GCwCaG,IAAgB,CAACC,IAA6B,OAA6C;AACjG,QAAA;AAAA,IACL,UAAAH,IAAW;AAAA,IACX,SAAAI,IAAU;AAAA,IACV,QAAAC,IAAS;AAAA,IACT,UAAAC,IAAW;AAAA,IACX,cAAAC,IAAe,CAAC;AAAA,IAChB,eAAAC;AAAA,IACA,cAAAC;AAAA,IACA,eAAeC;AAAA,EAAA,IACZP,GAGEQ,IAAgBC,EAAQ,OAAO,EAAE,GAAGf,GAAsB,GAAGa,EAAoB,IAAI,CAACA,CAAmB,CAAC,GAE1G,CAACG,GAAOC,CAAQ,IAAIC,EAA0B;AAAA,IACnD,OAAOR,EAAa,IAAI,CAACS,OAAU;AAAA,MAClC,MAAAA;AAAA,MACA,IAAIA,EAAK;AAAA,MACT,SAASA,EAAK;AAAA,IAAA,EACb;AAAA,IACF,YAAY;AAAA,IACZ,QAAQ,CAAA;AAAA,EAAC,CACT,GAEKC,IAAWC,EAAyB,IAAI,GAExCC,IAAeC;AAAA,IACpB,CAACJ,MAAmC;AACnC,YAAMlB,KAAWkB,aAAgB,MAAOA,EAAK;AAEzC,UAAAA,EAAK,OAAOZ;AACR,eAAAO,EAAc,aAAab,GAAUM,CAAO;AAGpD,UAAIC,MAAW,KAAK;AACb,cAAAgB,IAAgBhB,EAAO,MAAM,GAAG,EAAE,IAAI,CAACiB,MAASA,EAAK,MAAM,GAC3DC,IAAWP,aAAgB,OAAOA,EAAK,QAAQ,KAAKA,EAAK,MACzDQ,IAAgB,IAAI1B,EAAS,MAAM,GAAG,EAAE,KAAK;AAanD,YAAI,CAXeuB,EAAc,KAAK,CAACC,MAAS;AAC3C,cAAAA,EAAK,WAAW,GAAG;AACtB,mBAAOE,EAAc,kBAAkBF,EAAK,YAAY;AAErD,cAAAA,EAAK,SAAS,IAAI,GAAG;AACxB,kBAAMG,IAAWH,EAAK,MAAM,GAAG,EAAE,CAAC;AAClC,mBAAOC,EAAS,WAAW,GAAGE,CAAQ,GAAG;AAAA,UAAA;AAE1C,iBAAOF,MAAaD;AAAA,QAAA,CACpB;AAGO,iBAAAX,EAAc,gBAAgBb,CAAQ;AAAA,MAC9C;AAGM,aAAA;AAAA,IACR;AAAA,IACA,CAACO,GAAQD,GAASO,CAAa;AAAA,EAChC,GAEMe,IAAgBN,EAAY,CAACJ,MAC9BA,aAAgB,OACZ,IAAI,gBAAgBA,CAAI,IAEzBA,EAAK,KACV,EAAE,GAECW,IAAmBP,EAAY,CAACJ,MACjCA,aAAgB,OACZ,GAAGA,EAAK,IAAI,IAAI,KAAK,KAAK,IAAI,KAAK,OAAA,EAAS,SAAS,EAAE,EAAE,UAAU,GAAG,CAAC,CAAC,KAEzEA,EAAK,IACV,EAAE,GAECY,IAAaR,EAAY,MAAM;AACpC,IAAAN,EAAS,CAACe,MAAS;AAEb,MAAAA,EAAA,MAAM,QAAQ,CAACb,MAAS;AACxB,QAAAA,EAAK,WAAWA,EAAK,gBAAgB,QAAQA,EAAK,KAAK,KAAK,WAAW,QAAQ,KAC9E,IAAA,gBAAgBA,EAAK,OAAO;AAAA,MACjC,CACA,GAEGC,EAAS,YACZA,EAAS,QAAQ,QAAQ;AAG1B,YAAMa,IAAW;AAAA,QAChB,GAAGD;AAAA,QACH,OAAO,CAAC;AAAA,QACR,QAAQ,CAAA;AAAA,MACT;AAEA,aAAArB,IAAgBsB,EAAS,KAAK,GACvBA;AAAA,IAAA,CACP;AAAA,EAAA,GACC,CAACtB,CAAa,CAAC,GAEZuB,IAAWX;AAAA,IAChB,CAACY,MAAgC;AAChC,UAAI,CAACA,KAAYA,EAAS,WAAW,EAAG;AAElC,YAAAC,IAAgB,MAAM,KAAKD,CAAQ,GACnCE,IAAmB,CAAC;AAWtB,UARKpB,EAAA,CAACe,OAAU,EAAE,GAAGA,GAAM,QAAQ,KAAK,GAGvCvB,KACOsB,EAAA,GAIRtB,KAAYN,MAAa,SAAYa,EAAM,MAAM,SAASoB,EAAc,SAASjC,GAAU;AAC9F,QAAAkC,EAAO,KAAKvB,EAAc,aAAaX,CAAQ,CAAC,GAChDc,EAAS,CAACe,OAAU,EAAE,GAAGA,GAAM,QAAAK,EAAS,EAAA;AACxC;AAAA,MAAA;AAGD,YAAMC,IAAgC,CAAC;AAEzB,MAAAF,EAAA,QAAQ,CAACjB,MAAS;AAE/B,YAAIV,KACiBO,EAAM,MAAM;AAAA,UAC/B,CAACuB,MAAiBA,EAAa,KAAK,SAASpB,EAAK,QAAQoB,EAAa,KAAK,SAASpB,EAAK;AAAA,QAC3F;AAIC;AAKE,YAAAA,EAAK,OAAOZ,GAAS;AACjB,UAAA8B,EAAA;AAAA,YACN5B,IAAWK,EAAc,kBAAkBP,CAAO,IAAIO,EAAc,mBAAmBP,CAAO;AAAA,UAC/F;AACA;AAAA,QAAA;AAGK,cAAAiC,IAAQlB,EAAaH,CAAI;AAC/B,QAAIqB,IACHH,EAAO,KAAKG,CAAK,IAEjBF,EAAW,KAAK;AAAA,UACf,MAAAnB;AAAA,UACA,IAAIW,EAAiBX,CAAI;AAAA,UACzB,SAASU,EAAcV,CAAI;AAAA,QAAA,CAC3B;AAAA,MACF,CACA,GAGGmB,EAAW,SAAS,KAEvB1B,IAAe0B,CAAU,GAEzBrB,EAAS,CAACe,MAAS;AACZG,cAAAA,IAAY1B,IAAwB,CAAC,GAAGuB,EAAK,OAAO,GAAGM,CAAU,IAA1CA;AAC7B,eAAA3B,IAAgBwB,CAAQ,GACjB;AAAA,UACN,GAAGH;AAAA,UACH,OAAOG;AAAAA,UACP,QAAAE;AAAA,QACD;AAAA,MAAA,CACA,KACSA,EAAO,SAAS,KAC1BpB,EAAS,CAACe,OAAU;AAAA,QACnB,GAAGA;AAAA,QACH,QAAAK;AAAA,MAAA,EACC,GAICjB,EAAS,YACZA,EAAS,QAAQ,QAAQ;AAAA,IAE3B;AAAA,IACA;AAAA,MACCJ,EAAM;AAAA,MACNb;AAAA,MACAM;AAAA,MACAF;AAAA,MACAe;AAAA,MACAO;AAAA,MACAC;AAAA,MACAC;AAAA,MACApB;AAAA,MACAC;AAAA,MACAE;AAAA,IAAA;AAAA,EAEF,GAEM2B,IAAalB;AAAA,IAClB,CAACmB,MAAe;AACf,MAAAzB,EAAS,CAACe,MAAS;AACZ,cAAAW,IAAeX,EAAK,MAAM,KAAK,CAACb,MAASA,EAAK,OAAOuB,CAAE;AAE5D,QAAAC,KACAA,EAAa,WACbA,EAAa,gBAAgB,QAC7BA,EAAa,KAAK,KAAK,WAAW,QAAQ,KAEtC,IAAA,gBAAgBA,EAAa,OAAO;AAGnC,cAAAR,IAAWH,EAAK,MAAM,OAAO,CAACb,MAASA,EAAK,OAAOuB,CAAE;AAC3D,eAAA/B,IAAgBwB,CAAQ,GAEjB;AAAA,UACN,GAAGH;AAAA,UACH,OAAOG;AAAA,UACP,QAAQ,CAAA;AAAA,QACT;AAAA,MAAA,CACA;AAAA,IACF;AAAA,IACA,CAACxB,CAAa;AAAA,EACf,GAEMiC,IAAcrB,EAAY,MAAM;AACrC,IAAAN,EAAS,CAACe,OAAU;AAAA,MACnB,GAAGA;AAAA,MACH,QAAQ,CAAA;AAAA,IAAC,EACR;AAAA,EACH,GAAG,EAAE,GAECa,IAAkBtB,EAAY,CAAC,MAA8B;AAClE,MAAE,eAAe,GACjB,EAAE,gBAAgB,GAClBN,EAAS,CAACe,OAAU,EAAE,GAAGA,GAAM,YAAY,KAAO;AAAA,EACnD,GAAG,EAAE,GAECc,IAAkBvB,EAAY,CAAC,MAA8B;AAIlE,IAHA,EAAE,eAAe,GACjB,EAAE,gBAAgB,GAEd,GAAE,cAAc,SAAS,EAAE,aAAqB,KAIpDN,EAAS,CAACe,OAAU,EAAE,GAAGA,GAAM,YAAY,KAAQ;AAAA,EACpD,GAAG,EAAE,GAECe,IAAiBxB,EAAY,CAAC,MAA8B;AACjE,MAAE,eAAe,GACjB,EAAE,gBAAgB;AAAA,EACnB,GAAG,EAAE,GAECyB,IAAazB;AAAA,IAClB,CAAC,MAA8B;AAM1B,UALJ,EAAE,eAAe,GACjB,EAAE,gBAAgB,GAClBN,EAAS,CAACe,OAAU,EAAE,GAAGA,GAAM,YAAY,KAAQ,GAG/C,CAAAZ,EAAS,SAAS,YAIlB,EAAE,aAAa,SAAS,EAAE,aAAa,MAAM,SAAS;AAEzD,YAAKX;AAIK,UAAAyB,EAAA,EAAE,aAAa,KAAK;AAAA,aAJf;AACd,gBAAMf,IAAO,EAAE,aAAa,MAAM,CAAC;AAC1B,UAAAe,EAAA,CAACf,CAAI,CAAC;AAAA,QAAA;AAAA,IAKlB;AAAA,IACA,CAACe,GAAUzB,CAAQ;AAAA,EACpB,GAEMwC,IAAmB1B;AAAA,IACxB,CAAC,MAAqC;AACrC,MAAI,EAAE,OAAO,SAAS,EAAE,OAAO,MAAM,SAAS,KACpCW,EAAA,EAAE,OAAO,KAAK;AAAA,IAEzB;AAAA,IACA,CAACA,CAAQ;AAAA,EACV,GAEMgB,IAAiB3B,EAAY,MAAM;AACxC,IAAIH,EAAS,WACZA,EAAS,QAAQ,MAAM;AAAA,EAEzB,GAAG,EAAE,GAEC+B,IAAgB5B;AAAA,IACrB,CAAC6B,IAA+C,CAAA,OACxC;AAAA,MACN,GAAGA;AAAA,MACH,MAAM;AAAA,MACN,UAAUH;AAAA,MACV,QAAQG,EAAM,UAAU5C;AAAA,MACxB,UAAU4C,EAAM,aAAa,SAAYA,EAAM,WAAW3C;AAAA,MAC1D,KAAKW;AAAA,IACN;AAAA,IAED,CAACZ,GAAQC,GAAUwC,CAAgB;AAAA,EACpC;AAEO,SAAA;AAAA,IACNjC;AAAA,IACA;AAAA,MACC,UAAAkB;AAAA,MACA,YAAAO;AAAA,MACA,YAAAV;AAAA,MACA,aAAAa;AAAA,MACA,iBAAAC;AAAA,MACA,iBAAAC;AAAA,MACA,gBAAAC;AAAA,MACA,YAAAC;AAAA,MACA,kBAAAC;AAAA,MACA,gBAAAC;AAAA,MACA,eAAAC;AAAA,IAAA;AAAA,EAEF;AACD;"}
1
+ {"version":3,"file":"useFileUpload-iDag0iqM.js","sources":["../src/lib/utils/file/formatBytes.ts","../src/hooks/use-file-upload/errorMessages.ts","../src/hooks/use-file-upload/useFileUpload.ts"],"sourcesContent":["// Helper function to format bytes to human-readable format\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n\tif (bytes === 0) return \"0 Bytes\";\n\n\tconst k = 1024;\n\tconst dm = decimals < 0 ? 0 : decimals;\n\tconst sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"];\n\n\tconst i = Math.floor(Math.log(bytes) / Math.log(k));\n\n\treturn Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + sizes[i];\n};\n","import { formatBytes } from \"@/lib/utils/file/formatBytes\";\n\n/**\n * Интерфейс для кастомизации сообщений об ошибках в useFileUpload\n */\nexport interface FileUploadErrorMessages {\n\t/**\n\t * Сообщение когда файл превышает максимальный размер\n\t * @param fileName - имя файла\n\t * @param maxSizeBytes - максимальный размер в байтах\n\t */\n\tfileTooLarge?: (fileName: string, maxSizeBytes: number) => string;\n\n\t/**\n\t * Сообщение когда тип файла не разрешен\n\t * @param fileName - имя файла\n\t */\n\tinvalidFileType?: (fileName: string) => string;\n\n\t/**\n\t * Сообщение когда превышено максимальное количество файлов\n\t * @param maxFiles - максимальное количество файлов\n\t */\n\ttooManyFiles?: (maxFiles: number) => string;\n\n\t/**\n\t * Сообщение когда некоторые файлы превышают максимальный размер (для множественной загрузки)\n\t * @param maxSizeBytes - максимальный размер в байтах\n\t */\n\tsomeFilesTooLarge?: (maxSizeBytes: number) => string;\n\n\t/**\n\t * Сообщение когда файл превышает максимальный размер (для одиночной загрузки)\n\t * @param maxSizeBytes - максимальный размер в байтах\n\t */\n\tsingleFileTooLarge?: (maxSizeBytes: number) => string;\n}\n\n/**\n * Сообщения об ошибках по умолчанию\n */\nexport const defaultErrorMessages: Required<FileUploadErrorMessages> = {\n\tfileTooLarge: (fileName, maxSizeBytes) =>\n\t\t`File \"${fileName}\" exceeds the maximum size of ${formatBytes(maxSizeBytes)}.`,\n\tinvalidFileType: (fileName) => `File \"${fileName}\" is not an accepted file type.`,\n\ttooManyFiles: (maxFiles) => `You can only upload a maximum of ${maxFiles} files.`,\n\tsomeFilesTooLarge: (maxSizeBytes) => `Some files exceed the maximum size of ${formatBytes(maxSizeBytes)}.`,\n\tsingleFileTooLarge: (maxSizeBytes) => `File exceeds the maximum size of ${formatBytes(maxSizeBytes)}.`\n};\n\n/**\n * Сообщения об ошибках на русском языке\n */\nexport const defaultErrorMessagesRu: Required<FileUploadErrorMessages> = {\n\tfileTooLarge: (fileName, maxSizeBytes) =>\n\t\t`Файл \"${fileName}\" превышает максимальный размер ${formatBytes(maxSizeBytes)}`,\n\tinvalidFileType: (fileName) => `Файл \"${fileName}\" имеет недопустимый тип`,\n\ttooManyFiles: (maxFiles) => `Можно загрузить максимум ${maxFiles} файлов`,\n\tsomeFilesTooLarge: (maxSizeBytes) => `Некоторые файлы превышают максимальный размер ${formatBytes(maxSizeBytes)}`,\n\tsingleFileTooLarge: (maxSizeBytes) => `Файл превышает максимальный размер ${formatBytes(maxSizeBytes)}`\n};\n","import {\n\tuseCallback,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n\ttype ChangeEvent,\n\ttype DragEvent,\n\ttype InputHTMLAttributes\n} from \"react\";\nimport { defaultErrorMessages, type FileUploadErrorMessages } from \"./errorMessages\";\n\nexport type FileData = {\n\tname: string;\n\tsize: number;\n\ttype: string;\n\tid?: string;\n};\n\nexport type FileMetadata = FileData & {\n\turl: string;\n\tid: string;\n};\n\nexport type FileValue = File | FileData;\n\nexport type FileWithPreview = {\n\tfile: FileValue;\n\tid: string;\n\tpreview?: string;\n};\n\n/**\n * Ограничения для загрузки файлов\n */\nexport type FileUploadConstraints = {\n\t/**\n\t * Максимальное количество файлов\n\t * Используется только когда multiple=true\n\t * @default Infinity\n\t */\n\tmaxFiles?: number;\n\n\t/**\n\t * Максимальный размер файла в байтах\n\t * @default Infinity\n\t */\n\tmaxSize?: number;\n\n\t/**\n\t * Допустимые типы файлов (строка MIME-типов или расширений через запятую)\n\t * @example \"image/jpeg,image/png,.pdf,.doc\"\n\t * @example \"*.jpg,*.png\"\n\t * @example \"image/*\"\n\t * @default \"*\"\n\t */\n\taccept?: string;\n\n\t/**\n\t * Разрешить выбор нескольких файлов\n\t * @default false\n\t */\n\tmultiple?: boolean;\n};\n\nexport type FileUploadOptions = FileUploadConstraints & {\n\tinitialFiles?: FileMetadata[];\n\tonFilesChange?: (files: FileWithPreview[]) => void;\n\tonFilesAdded?: (addedFiles: FileWithPreview[]) => void;\n\t/**\n\t * Кастомные сообщения об ошибках\n\t * Можно переопределить только нужные сообщения\n\t */\n\terrorMessages?: Partial<FileUploadErrorMessages>;\n};\n\nexport type FileUploadState = {\n\tfiles: FileWithPreview[];\n\tisDragging: boolean;\n\terrors: string[];\n};\n\nexport type FileUploadActions = {\n\taddFiles: (files: FileList | File[]) => void;\n\tremoveFile: (id: string) => void;\n\tclearFiles: () => void;\n\tclearErrors: () => void;\n\thandleDragEnter: (e: DragEvent<HTMLElement>) => void;\n\thandleDragLeave: (e: DragEvent<HTMLElement>) => void;\n\thandleDragOver: (e: DragEvent<HTMLElement>) => void;\n\thandleDrop: (e: DragEvent<HTMLElement>) => void;\n\thandleFileChange: (e: ChangeEvent<HTMLInputElement>) => void;\n\topenFileDialog: () => void;\n\tgetInputProps: (props?: InputHTMLAttributes<HTMLInputElement>) => InputHTMLAttributes<HTMLInputElement> & {\n\t\tref: React.Ref<HTMLInputElement>;\n\t};\n};\n\n/** Хук был взять из библиотеки originui.\n * Код можно посмотреть по ссылке: https://github.com/origin-space/originui/blob/main/docs/use-file-upload.md\n */\nexport const useFileUpload = (options: FileUploadOptions = {}): [FileUploadState, FileUploadActions] => {\n\tconst {\n\t\tmaxFiles = Infinity,\n\t\tmaxSize = Infinity,\n\t\taccept = \"*\",\n\t\tmultiple = false,\n\t\tinitialFiles = [],\n\t\tonFilesChange,\n\t\tonFilesAdded,\n\t\terrorMessages: customErrorMessages\n\t} = options;\n\n\t// Объединяем дефолтные и кастомные сообщения\n\tconst errorMessages = useMemo(() => ({ ...defaultErrorMessages, ...customErrorMessages }), [customErrorMessages]);\n\n\tconst [state, setState] = useState<FileUploadState>({\n\t\tfiles: initialFiles.map((file) => ({\n\t\t\tfile,\n\t\t\tid: file.id,\n\t\t\tpreview: file.url\n\t\t})),\n\t\tisDragging: false,\n\t\terrors: []\n\t});\n\n\tconst inputRef = useRef<HTMLInputElement>(null);\n\n\tconst validateFile = useCallback(\n\t\t(file: FileValue): string | null => {\n\t\t\tconst fileName = file instanceof File ? file.name : file.name;\n\n\t\t\tif (file.size > maxSize) {\n\t\t\t\treturn errorMessages.fileTooLarge(fileName, maxSize);\n\t\t\t}\n\n\t\t\tif (accept !== \"*\") {\n\t\t\t\tconst acceptedTypes = accept.split(\",\").map((type) => type.trim());\n\t\t\t\tconst fileType = file instanceof File ? file.type || \"\" : file.type;\n\t\t\t\tconst fileExtension = `.${fileName.split(\".\").pop()}`;\n\n\t\t\t\tconst isAccepted = acceptedTypes.some((type) => {\n\t\t\t\t\tif (type.startsWith(\".\")) {\n\t\t\t\t\t\treturn fileExtension.toLowerCase() === type.toLowerCase();\n\t\t\t\t\t}\n\t\t\t\t\tif (type.endsWith(\"/*\")) {\n\t\t\t\t\t\tconst baseType = type.split(\"/\")[0];\n\t\t\t\t\t\treturn fileType.startsWith(`${baseType}/`);\n\t\t\t\t\t}\n\t\t\t\t\treturn fileType === type;\n\t\t\t\t});\n\n\t\t\t\tif (!isAccepted) {\n\t\t\t\t\treturn errorMessages.invalidFileType(fileName);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\t\t},\n\t\t[accept, maxSize, errorMessages]\n\t);\n\n\tconst createPreview = useCallback((file: File | FileMetadata): string | undefined => {\n\t\tif (file instanceof File) {\n\t\t\treturn URL.createObjectURL(file);\n\t\t}\n\t\treturn file.url;\n\t}, []);\n\n\tconst generateUniqueId = useCallback((file: File | FileMetadata): string => {\n\t\tif (file instanceof File) {\n\t\t\treturn `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\n\t\t}\n\t\treturn file.id;\n\t}, []);\n\n\tconst clearFiles = useCallback(() => {\n\t\tsetState((prev) => {\n\t\t\t// Clean up object URLs\n\t\t\tprev.files.forEach((file) => {\n\t\t\t\tif (file.preview && file.file instanceof File && file.file.type.startsWith(\"image/\")) {\n\t\t\t\t\tURL.revokeObjectURL(file.preview);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (inputRef.current) {\n\t\t\t\tinputRef.current.value = \"\";\n\t\t\t}\n\n\t\t\tconst newState = {\n\t\t\t\t...prev,\n\t\t\t\tfiles: [],\n\t\t\t\terrors: []\n\t\t\t};\n\n\t\t\tonFilesChange?.(newState.files);\n\t\t\treturn newState;\n\t\t});\n\t}, [onFilesChange]);\n\n\tconst addFiles = useCallback(\n\t\t(newFiles: FileList | File[]) => {\n\t\t\tif (!newFiles || newFiles.length === 0) return;\n\n\t\t\tconst newFilesArray = Array.from(newFiles);\n\t\t\tconst errors: string[] = [];\n\n\t\t\t// Clear existing errors when new files are uploaded\n\t\t\tsetState((prev) => ({ ...prev, errors: [] }));\n\n\t\t\t// In single file mode, clear existing files first\n\t\t\tif (!multiple) {\n\t\t\t\tclearFiles();\n\t\t\t}\n\n\t\t\t// Check if adding these files would exceed maxFiles (only in multiple mode)\n\t\t\tif (multiple && maxFiles !== Infinity && state.files.length + newFilesArray.length > maxFiles) {\n\t\t\t\terrors.push(errorMessages.tooManyFiles(maxFiles));\n\t\t\t\tsetState((prev) => ({ ...prev, errors }));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst validFiles: FileWithPreview[] = [];\n\n\t\t\tnewFilesArray.forEach((file) => {\n\t\t\t\t// Only check for duplicates if multiple files are allowed\n\t\t\t\tif (multiple) {\n\t\t\t\t\tconst isDuplicate = state.files.some(\n\t\t\t\t\t\t(existingFile) => existingFile.file.name === file.name && existingFile.file.size === file.size\n\t\t\t\t\t);\n\n\t\t\t\t\t// Skip duplicate files silently\n\t\t\t\t\tif (isDuplicate) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Check file size\n\t\t\t\tif (file.size > maxSize) {\n\t\t\t\t\terrors.push(\n\t\t\t\t\t\tmultiple ? errorMessages.someFilesTooLarge(maxSize) : errorMessages.singleFileTooLarge(maxSize)\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst error = validateFile(file);\n\t\t\t\tif (error) {\n\t\t\t\t\terrors.push(error);\n\t\t\t\t} else {\n\t\t\t\t\tvalidFiles.push({\n\t\t\t\t\t\tfile,\n\t\t\t\t\t\tid: generateUniqueId(file),\n\t\t\t\t\t\tpreview: createPreview(file)\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Only update state if we have valid files to add\n\t\t\tif (validFiles.length > 0) {\n\t\t\t\t// Call the onFilesAdded callback with the newly added valid files\n\t\t\t\tonFilesAdded?.(validFiles);\n\n\t\t\t\tsetState((prev) => {\n\t\t\t\t\tconst newFiles = !multiple ? validFiles : [...prev.files, ...validFiles];\n\t\t\t\t\tonFilesChange?.(newFiles);\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...prev,\n\t\t\t\t\t\tfiles: newFiles,\n\t\t\t\t\t\terrors\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t\t} else if (errors.length > 0) {\n\t\t\t\tsetState((prev) => ({\n\t\t\t\t\t...prev,\n\t\t\t\t\terrors\n\t\t\t\t}));\n\t\t\t}\n\n\t\t\t// Reset input value after handling files\n\t\t\tif (inputRef.current) {\n\t\t\t\tinputRef.current.value = \"\";\n\t\t\t}\n\t\t},\n\t\t[\n\t\t\tstate.files,\n\t\t\tmaxFiles,\n\t\t\tmultiple,\n\t\t\tmaxSize,\n\t\t\tvalidateFile,\n\t\t\tcreatePreview,\n\t\t\tgenerateUniqueId,\n\t\t\tclearFiles,\n\t\t\tonFilesChange,\n\t\t\tonFilesAdded,\n\t\t\terrorMessages\n\t\t]\n\t);\n\n\tconst removeFile = useCallback(\n\t\t(id: string) => {\n\t\t\tsetState((prev) => {\n\t\t\t\tconst fileToRemove = prev.files.find((file) => file.id === id);\n\t\t\t\tif (\n\t\t\t\t\tfileToRemove &&\n\t\t\t\t\tfileToRemove.preview &&\n\t\t\t\t\tfileToRemove.file instanceof File &&\n\t\t\t\t\tfileToRemove.file.type.startsWith(\"image/\")\n\t\t\t\t) {\n\t\t\t\t\tURL.revokeObjectURL(fileToRemove.preview);\n\t\t\t\t}\n\n\t\t\t\tconst newFiles = prev.files.filter((file) => file.id !== id);\n\t\t\t\tonFilesChange?.(newFiles);\n\n\t\t\t\treturn {\n\t\t\t\t\t...prev,\n\t\t\t\t\tfiles: newFiles,\n\t\t\t\t\terrors: []\n\t\t\t\t};\n\t\t\t});\n\t\t},\n\t\t[onFilesChange]\n\t);\n\n\tconst clearErrors = useCallback(() => {\n\t\tsetState((prev) => ({\n\t\t\t...prev,\n\t\t\terrors: []\n\t\t}));\n\t}, []);\n\n\tconst handleDragEnter = useCallback((e: DragEvent<HTMLElement>) => {\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\t\tsetState((prev) => ({ ...prev, isDragging: true }));\n\t}, []);\n\n\tconst handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\n\t\tif (e.currentTarget.contains(e.relatedTarget as Node)) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetState((prev) => ({ ...prev, isDragging: false }));\n\t}, []);\n\n\tconst handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\t}, []);\n\n\tconst handleDrop = useCallback(\n\t\t(e: DragEvent<HTMLElement>) => {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\tsetState((prev) => ({ ...prev, isDragging: false }));\n\n\t\t\t// Don't process files if the input is disabled\n\t\t\tif (inputRef.current?.disabled) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n\t\t\t\t// In single file mode, only use the first file\n\t\t\t\tif (!multiple) {\n\t\t\t\t\tconst file = e.dataTransfer.files[0];\n\t\t\t\t\taddFiles([file]);\n\t\t\t\t} else {\n\t\t\t\t\taddFiles(e.dataTransfer.files);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[addFiles, multiple]\n\t);\n\n\tconst handleFileChange = useCallback(\n\t\t(e: ChangeEvent<HTMLInputElement>) => {\n\t\t\tif (e.target.files && e.target.files.length > 0) {\n\t\t\t\taddFiles(e.target.files);\n\t\t\t}\n\t\t},\n\t\t[addFiles]\n\t);\n\n\tconst openFileDialog = useCallback(() => {\n\t\tif (inputRef.current) {\n\t\t\tinputRef.current.click();\n\t\t}\n\t}, []);\n\n\tconst getInputProps = useCallback(\n\t\t(props: InputHTMLAttributes<HTMLInputElement> = {}) => {\n\t\t\treturn {\n\t\t\t\t...props,\n\t\t\t\ttype: \"file\" as const,\n\t\t\t\tonChange: handleFileChange,\n\t\t\t\taccept: props.accept || accept,\n\t\t\t\tmultiple: props.multiple !== undefined ? props.multiple : multiple,\n\t\t\t\tref: inputRef\n\t\t\t};\n\t\t},\n\t\t[accept, multiple, handleFileChange]\n\t);\n\n\treturn [\n\t\tstate,\n\t\t{\n\t\t\taddFiles,\n\t\t\tremoveFile,\n\t\t\tclearFiles,\n\t\t\tclearErrors,\n\t\t\thandleDragEnter,\n\t\t\thandleDragLeave,\n\t\t\thandleDragOver,\n\t\t\thandleDrop,\n\t\t\thandleFileChange,\n\t\t\topenFileDialog,\n\t\t\tgetInputProps\n\t\t}\n\t];\n};\n"],"names":["formatBytes","bytes","decimals","k","dm","sizes","i","defaultErrorMessages","fileName","maxSizeBytes","maxFiles","defaultErrorMessagesRu","useFileUpload","options","maxSize","accept","multiple","initialFiles","onFilesChange","onFilesAdded","customErrorMessages","errorMessages","useMemo","state","setState","useState","file","inputRef","useRef","validateFile","useCallback","acceptedTypes","type","fileType","fileExtension","baseType","createPreview","generateUniqueId","clearFiles","prev","newState","addFiles","newFiles","newFilesArray","errors","validFiles","existingFile","error","removeFile","id","fileToRemove","clearErrors","handleDragEnter","handleDragLeave","handleDragOver","handleDrop","handleFileChange","openFileDialog","getInputProps","props"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"useMergeRefs-qoKniYqT.js","sources":["../src/hooks/useMergeRefs.ts"],"sourcesContent":["import { useCallback } from \"react\";\r\n\r\ntype ReactRef<T> = React.RefCallback<T> | React.RefObject<T> | null;\r\n\r\nfunction assignRef<T>(ref: ReactRef<T>, value: T | null) {\r\n\tif (typeof ref === \"function\") {\r\n\t\tref(value);\r\n\t} else if (ref !== null && \"current\" in ref) {\r\n\t\t(ref as React.MutableRefObject<T | null>).current = value;\r\n\t}\r\n}\r\n\r\nexport function useMergeRefs<T>(...refs: ReactRef<T>[]) {\r\n\treturn useCallback(\r\n\t\t(value: T | null) => {\r\n\t\t\trefs.forEach((ref) => {\r\n\t\t\t\tassignRef(ref, value);\r\n\t\t\t});\r\n\t\t},\r\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\r\n\t\t[...refs]\r\n\t);\r\n}\r\n"],"names":["assignRef","ref","value","useMergeRefs","refs","useCallback"],"mappings":";AAIA,SAASA,EAAaC,GAAkBC,GAAiB;AACpD,EAAA,OAAOD,KAAQ,aAClBA,EAAIC,CAAK,IACCD,MAAQ,QAAQ,aAAaA,MACtCA,EAAyC,UAAUC;AAEtD;AAEO,SAASC,KAAmBC,GAAqB;AAChD,SAAAC;AAAA,IACN,CAACH,MAAoB;AACf,MAAAE,EAAA,QAAQ,CAACH,MAAQ;AACrB,QAAAD,EAAUC,GAAKC,CAAK;AAAA,MAAA,CACpB;AAAA,IACF;AAAA;AAAA,IAEA,CAAC,GAAGE,CAAI;AAAA,EACT;AACD;"}
1
+ {"version":3,"file":"useMergeRefs-qoKniYqT.js","sources":["../src/hooks/useMergeRefs.ts"],"sourcesContent":["import { useCallback } from \"react\";\n\ntype ReactRef<T> = React.RefCallback<T> | React.RefObject<T> | null;\n\nfunction assignRef<T>(ref: ReactRef<T>, value: T | null) {\n\tif (typeof ref === \"function\") {\n\t\tref(value);\n\t} else if (ref !== null && \"current\" in ref) {\n\t\t(ref as React.MutableRefObject<T | null>).current = value;\n\t}\n}\n\nexport function useMergeRefs<T>(...refs: ReactRef<T>[]) {\n\treturn useCallback(\n\t\t(value: T | null) => {\n\t\t\trefs.forEach((ref) => {\n\t\t\t\tassignRef(ref, value);\n\t\t\t});\n\t\t},\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t[...refs]\n\t);\n}\n"],"names":["assignRef","ref","value","useMergeRefs","refs","useCallback"],"mappings":";AAIA,SAASA,EAAaC,GAAkBC,GAAiB;AACpD,EAAA,OAAOD,KAAQ,aAClBA,EAAIC,CAAK,IACCD,MAAQ,QAAQ,aAAaA,MACtCA,EAAyC,UAAUC;AAEtD;AAEO,SAASC,KAAmBC,GAAqB;AAChD,SAAAC;AAAA,IACN,CAACH,MAAoB;AACf,MAAAE,EAAA,QAAQ,CAACH,MAAQ;AACrB,QAAAD,EAAUC,GAAKC,CAAK;AAAA,MAAA,CACpB;AAAA,IACF;AAAA;AAAA,IAEA,CAAC,GAAGE,CAAI;AAAA,EACT;AACD;"}
@@ -1 +1 @@
1
- {"version":3,"file":"usePortalContainer-ae6EzS08.js","sources":["../src/components/portal-container/portalContainerEvents.ts","../src/lib/utils/styles.ts","../src/components/portal-container/usePortalContainer.ts"],"sourcesContent":["type Listener = (mount: boolean) => void;\r\n\r\n/**\r\n * Простой EventEmitter для синхронизации PortalContainer и usePortalContainer\r\n */\r\nclass PortalContainerEvents {\r\n\tprivate listeners = new Set<Listener>();\r\n\tisContainerMounted = false;\r\n\r\n\tsubscribe(listener: Listener) {\r\n\t\tthis.listeners.add(listener);\r\n\t\treturn () => {\r\n\t\t\tthis.listeners.delete(listener);\r\n\t\t};\r\n\t}\r\n\r\n\tnotify(mount: boolean = true) {\r\n\t\tif (mount && this.isContainerMounted) {\r\n\t\t\tthrow new Error(\r\n\t\t\t\t\"PortalContainer уже смонтирован. В приложении может быть только один экземпляр PortalContainer.\"\r\n\t\t\t);\r\n\t\t}\r\n\t\tthis.isContainerMounted = mount;\r\n\t\tthis.listeners.forEach((listener) => listener(mount));\r\n\t}\r\n}\r\n\r\nexport const portalContainerEvents = new PortalContainerEvents();\r\n","/**\r\n * Проверяет, подключены ли изолированные стили UI Kit.\r\n *\r\n * Проверяет наличие CSS-переменной --ui-kit-scoped-styles,\r\n * которая устанавливается в styles-scoped.css\r\n *\r\n * @returns true если изолированные стили подключены, иначе false\r\n */\r\nexport const isScopedStylesEnabled = (): boolean => {\r\n\ttry {\r\n\t\tconst scopedStylesValue = getComputedStyle(document.documentElement)\r\n\t\t\t.getPropertyValue(\"--ui-kit-scoped-styles\")\r\n\t\t\t.trim();\r\n\r\n\t\treturn scopedStylesValue === '\"enabled\"';\r\n\t} catch {\r\n\t\t// Если getComputedStyle недоступен (например, в SSR)\r\n\t\treturn false;\r\n\t}\r\n};\r\n","import { useCallback, useEffect, useState } from \"react\";\r\nimport { isScopedStylesEnabled } from \"@/lib/utils/styles\";\r\nimport { portalContainerEvents } from \"./portalContainerEvents\";\r\n\r\n/**\r\n * Хук для определения контейнера портала.\r\n *\r\n * Если передан customContainer, возвращает его.\r\n * Иначе проверяет наличие изолированных стилей и ищет элемент с атрибутом 'data-portal-container'.\r\n *\r\n * @param customContainer - Кастомный контейнер для портала\r\n * @returns HTMLElement для портала или undefined\r\n */\r\nexport const usePortalContainer = (customContainer?: HTMLElement | null) => {\r\n\tconst [isMounted, setIsMounted] = useState(portalContainerEvents.isContainerMounted);\r\n\r\n\tuseEffect(() => {\r\n\t\t// Подписываемся на события монтирования/размонтирования PortalContainer\r\n\t\tconst unsubscribe = portalContainerEvents.subscribe((mount) => {\r\n\t\t\tsetIsMounted(mount);\r\n\t\t});\r\n\t\treturn unsubscribe;\r\n\t}, []);\r\n\r\n\tconst findPortalContainer = useCallback((): HTMLElement | undefined => {\r\n\t\tif (customContainer !== undefined) {\r\n\t\t\treturn customContainer || undefined;\r\n\t\t}\r\n\t\tif (!isScopedStylesEnabled()) return undefined;\r\n\t\tif (isMounted === false) return undefined;\r\n\r\n\t\tconst portalContainer = document.querySelector(\"[data-portal-container]\") as HTMLElement;\r\n\t\treturn portalContainer || undefined;\r\n\t}, [customContainer, isMounted]);\r\n\r\n\treturn findPortalContainer();\r\n};\r\n"],"names":["PortalContainerEvents","__publicField","listener","mount","portalContainerEvents","isScopedStylesEnabled","usePortalContainer","customContainer","isMounted","setIsMounted","useState","useEffect","useCallback"],"mappings":";;;;AAKA,MAAMA,EAAsB;AAAA,EAA5B;AACS,IAAAC,EAAA,uCAAgB,IAAc;AACtC,IAAAA,EAAA,4BAAqB;AAAA;AAAA,EAErB,UAAUC,GAAoB;AACxB,gBAAA,UAAU,IAAIA,CAAQ,GACpB,MAAM;AACP,WAAA,UAAU,OAAOA,CAAQ;AAAA,IAC/B;AAAA,EAAA;AAAA,EAGD,OAAOC,IAAiB,IAAM;AACzB,QAAAA,KAAS,KAAK;AACjB,YAAM,IAAI;AAAA,QACT;AAAA,MACD;AAED,SAAK,qBAAqBA,GAC1B,KAAK,UAAU,QAAQ,CAACD,MAAaA,EAASC,CAAK,CAAC;AAAA,EAAA;AAEtD;AAEa,MAAAC,IAAwB,IAAIJ,EAAsB,GCnBlDK,IAAwB,MAAe;AAC/C,MAAA;AAKH,WAJ0B,iBAAiB,SAAS,eAAe,EACjE,iBAAiB,wBAAwB,EACzC,KAAK,MAEsB;AAAA,EAAA,QACtB;AAEA,WAAA;AAAA,EAAA;AAET,GCNaC,IAAqB,CAACC,MAAyC;AAC3E,QAAM,CAACC,GAAWC,CAAY,IAAIC,EAASN,EAAsB,kBAAkB;AAEnF,SAAAO,EAAU,MAEWP,EAAsB,UAAU,CAACD,MAAU;AAC9D,IAAAM,EAAaN,CAAK;AAAA,EAAA,CAClB,GAEC,EAAE,GAEuBS,EAAY,MACnCL,MAAoB,SAChBA,KAAmB,SAEvB,CAACF,EAAsB,KACvBG,MAAc,KAAc,SAER,SAAS,cAAc,yBAAyB,KAC9C,QACxB,CAACD,GAAiBC,CAAS,CAAC,EAEJ;AAC5B;"}
1
+ {"version":3,"file":"usePortalContainer-ae6EzS08.js","sources":["../src/components/portal-container/portalContainerEvents.ts","../src/lib/utils/styles.ts","../src/components/portal-container/usePortalContainer.ts"],"sourcesContent":["type Listener = (mount: boolean) => void;\n\n/**\n * Простой EventEmitter для синхронизации PortalContainer и usePortalContainer\n */\nclass PortalContainerEvents {\n\tprivate listeners = new Set<Listener>();\n\tisContainerMounted = false;\n\n\tsubscribe(listener: Listener) {\n\t\tthis.listeners.add(listener);\n\t\treturn () => {\n\t\t\tthis.listeners.delete(listener);\n\t\t};\n\t}\n\n\tnotify(mount: boolean = true) {\n\t\tif (mount && this.isContainerMounted) {\n\t\t\tthrow new Error(\n\t\t\t\t\"PortalContainer уже смонтирован. В приложении может быть только один экземпляр PortalContainer.\"\n\t\t\t);\n\t\t}\n\t\tthis.isContainerMounted = mount;\n\t\tthis.listeners.forEach((listener) => listener(mount));\n\t}\n}\n\nexport const portalContainerEvents = new PortalContainerEvents();\n","/**\n * Проверяет, подключены ли изолированные стили UI Kit.\n *\n * Проверяет наличие CSS-переменной --ui-kit-scoped-styles,\n * которая устанавливается в styles-scoped.css\n *\n * @returns true если изолированные стили подключены, иначе false\n */\nexport const isScopedStylesEnabled = (): boolean => {\n\ttry {\n\t\tconst scopedStylesValue = getComputedStyle(document.documentElement)\n\t\t\t.getPropertyValue(\"--ui-kit-scoped-styles\")\n\t\t\t.trim();\n\n\t\treturn scopedStylesValue === '\"enabled\"';\n\t} catch {\n\t\t// Если getComputedStyle недоступен (например, в SSR)\n\t\treturn false;\n\t}\n};\n","import { useCallback, useEffect, useState } from \"react\";\nimport { isScopedStylesEnabled } from \"@/lib/utils/styles\";\nimport { portalContainerEvents } from \"./portalContainerEvents\";\n\n/**\n * Хук для определения контейнера портала.\n *\n * Если передан customContainer, возвращает его.\n * Иначе проверяет наличие изолированных стилей и ищет элемент с атрибутом 'data-portal-container'.\n *\n * @param customContainer - Кастомный контейнер для портала\n * @returns HTMLElement для портала или undefined\n */\nexport const usePortalContainer = (customContainer?: HTMLElement | null) => {\n\tconst [isMounted, setIsMounted] = useState(portalContainerEvents.isContainerMounted);\n\n\tuseEffect(() => {\n\t\t// Подписываемся на события монтирования/размонтирования PortalContainer\n\t\tconst unsubscribe = portalContainerEvents.subscribe((mount) => {\n\t\t\tsetIsMounted(mount);\n\t\t});\n\t\treturn unsubscribe;\n\t}, []);\n\n\tconst findPortalContainer = useCallback((): HTMLElement | undefined => {\n\t\tif (customContainer !== undefined) {\n\t\t\treturn customContainer || undefined;\n\t\t}\n\t\tif (!isScopedStylesEnabled()) return undefined;\n\t\tif (isMounted === false) return undefined;\n\n\t\tconst portalContainer = document.querySelector(\"[data-portal-container]\") as HTMLElement;\n\t\treturn portalContainer || undefined;\n\t}, [customContainer, isMounted]);\n\n\treturn findPortalContainer();\n};\n"],"names":["PortalContainerEvents","__publicField","listener","mount","portalContainerEvents","isScopedStylesEnabled","usePortalContainer","customContainer","isMounted","setIsMounted","useState","useEffect","useCallback"],"mappings":";;;;AAKA,MAAMA,EAAsB;AAAA,EAA5B;AACS,IAAAC,EAAA,uCAAgB,IAAc;AACtC,IAAAA,EAAA,4BAAqB;AAAA;AAAA,EAErB,UAAUC,GAAoB;AACxB,gBAAA,UAAU,IAAIA,CAAQ,GACpB,MAAM;AACP,WAAA,UAAU,OAAOA,CAAQ;AAAA,IAC/B;AAAA,EAAA;AAAA,EAGD,OAAOC,IAAiB,IAAM;AACzB,QAAAA,KAAS,KAAK;AACjB,YAAM,IAAI;AAAA,QACT;AAAA,MACD;AAED,SAAK,qBAAqBA,GAC1B,KAAK,UAAU,QAAQ,CAACD,MAAaA,EAASC,CAAK,CAAC;AAAA,EAAA;AAEtD;AAEa,MAAAC,IAAwB,IAAIJ,EAAsB,GCnBlDK,IAAwB,MAAe;AAC/C,MAAA;AAKH,WAJ0B,iBAAiB,SAAS,eAAe,EACjE,iBAAiB,wBAAwB,EACzC,KAAK,MAEsB;AAAA,EAAA,QACtB;AAEA,WAAA;AAAA,EAAA;AAET,GCNaC,IAAqB,CAACC,MAAyC;AAC3E,QAAM,CAACC,GAAWC,CAAY,IAAIC,EAASN,EAAsB,kBAAkB;AAEnF,SAAAO,EAAU,MAEWP,EAAsB,UAAU,CAACD,MAAU;AAC9D,IAAAM,EAAaN,CAAK;AAAA,EAAA,CAClB,GAEC,EAAE,GAEuBS,EAAY,MACnCL,MAAoB,SAChBA,KAAmB,SAEvB,CAACF,EAAsB,KACvBG,MAAc,KAAc,SAER,SAAS,cAAc,yBAAyB,KAC9C,QACxB,CAACD,GAAiBC,CAAS,CAAC,EAEJ;AAC5B;"}