ics-ui-kit 0.1.18 → 1.0.0-alpha.0
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.
- package/README.md +36 -36
- package/dist/AlertContext-CxjW1LVL.js.map +1 -1
- package/dist/AlertIcon-BphnEYvV.js.map +1 -1
- package/dist/{Button-Dg89xRSi.js → Button-_qdP4hSf.js} +2 -2
- package/dist/Button-_qdP4hSf.js.map +1 -0
- package/dist/ButtonBase-CbWrYcx-.js +158 -0
- package/dist/ButtonBase-CbWrYcx-.js.map +1 -0
- package/dist/{CheckboxField-limFbMk2.js → CheckboxField-Ca48ZYoX.js} +32 -32
- package/dist/CheckboxField-Ca48ZYoX.js.map +1 -0
- package/dist/Combination-DeIugdgY.js.map +1 -1
- package/dist/{Command-B7ZRyW8w.js → Command-CsW4aK7M.js} +8 -8
- package/dist/Command-CsW4aK7M.js.map +1 -0
- package/dist/ComponentVariantProvider-brk0g-hm.js.map +1 -1
- package/dist/Description-BTPMlTT-.js.map +1 -1
- package/dist/{Dialog-CdnsGyJD.js → Dialog-BT_775Iz.js} +4 -4
- package/dist/Dialog-BT_775Iz.js.map +1 -0
- package/dist/Divider-DPW5ZhZ8.js.map +1 -1
- package/dist/EmptyState-DRKjscH-.js.map +1 -1
- package/dist/ErrorState-B26k67-z.js.map +1 -1
- package/dist/FeatureIcon-BGE0Orkc.js.map +1 -1
- package/dist/{Field-CP_-li9L.js → Field-BRPdaQ8D.js} +2 -2
- package/dist/Field-BRPdaQ8D.js.map +1 -0
- package/dist/{FieldLabel-eyKmeWRn.js → FieldLabel-ic0eq9Un.js} +2 -2
- package/dist/FieldLabel-ic0eq9Un.js.map +1 -0
- package/dist/FolderSvg-cw0DxNVy.js.map +1 -1
- package/dist/{FormFooterTemplate-BRrgrxAu.js → FormFooterTemplate-BIwnBQhL.js} +5 -5
- package/dist/FormFooterTemplate-BIwnBQhL.js.map +1 -0
- package/dist/{FormHeader--F6b2aRk.js → FormHeader-PE63OqG9.js} +3 -3
- package/dist/FormHeader-PE63OqG9.js.map +1 -0
- package/dist/{FormStack-Cc_ELdWL.js → FormStack-CxiZhx1n.js} +3 -3
- package/dist/FormStack-CxiZhx1n.js.map +1 -0
- package/dist/HintState-BxrCAWqq.js.map +1 -1
- package/dist/Icon-DH3ev9GK.js.map +1 -1
- package/dist/{IconButton-DwkpNgn3.js → IconButton-DAg1oMwz.js} +2 -2
- package/dist/IconButton-DAg1oMwz.js.map +1 -0
- package/dist/{IconTooltip-RSxvnBgH.js → IconTooltip-CgbefRXG.js} +2 -2
- package/dist/IconTooltip-CgbefRXG.js.map +1 -0
- package/dist/Indicator-AqxHWPA9.js.map +1 -1
- package/dist/{InputGroup-BcRWP-zL.js → InputGroup-CW55G5nE.js} +5 -5
- package/dist/InputGroup-CW55G5nE.js.map +1 -0
- package/dist/{InputOTP-B2e1nfSO.js → InputOTP-DkVh6bBz.js} +2 -2
- package/dist/InputOTP-DkVh6bBz.js.map +1 -0
- package/dist/Loader-BpHiL6W-.js.map +1 -1
- package/dist/{MenuItem-d19Ty84F.js → MenuItem-C51uFz3V.js} +11 -11
- package/dist/MenuItem-C51uFz3V.js.map +1 -0
- package/dist/MenuItemShortcut-D1faeIXp.js.map +1 -1
- package/dist/MenuItemText-CRpaPbvg.js.map +1 -1
- package/dist/{Overlay-CVt011mY.js → Overlay-E0UvxzIc.js} +2 -2
- package/dist/Overlay-E0UvxzIc.js.map +1 -0
- package/dist/{Popover-CRVD7AtB.js → Popover-Dz2eNsXh.js} +5 -5
- package/dist/Popover-Dz2eNsXh.js.map +1 -0
- package/dist/{RichButton-DuPTenmS.js → RichButton-Bt0yUShU.js} +2 -2
- package/dist/RichButton-Bt0yUShU.js.map +1 -0
- package/dist/ScrollArea-CuuTeDn3.js.map +1 -1
- package/dist/ScrollShadowContainer-DdrnF8qU.js.map +1 -1
- package/dist/{SearchSelectTag-CA7Ie3Nx.js → SearchSelectTag-Dp5_OvZp.js} +16 -16
- package/dist/SearchSelectTag-Dp5_OvZp.js.map +1 -0
- package/dist/{Select-D9juHX8o.js → Select-Bfbtj5zt.js} +7 -7
- package/dist/Select-Bfbtj5zt.js.map +1 -0
- package/dist/{Sheet-qTIXsqm0.js → Sheet-aLBPtE1k.js} +9 -9
- package/dist/Sheet-aLBPtE1k.js.map +1 -0
- package/dist/Shortcut-D8L15_ed.js.map +1 -1
- package/dist/Skeleton-y6I-i9q5.js.map +1 -1
- package/dist/{TableFillHandle-C_yvCTSl.js → TableFillHandle-CHHoUi6s.js} +7 -7
- package/dist/TableFillHandle-CHHoUi6s.js.map +1 -0
- package/dist/{Tag-DdHXTyKF.js → Tag-Cf6HftP-.js} +4 -4
- package/dist/Tag-Cf6HftP-.js.map +1 -0
- package/dist/Text-DeBE8AKl.js.map +1 -1
- package/dist/{TextInput-Db0ylY91.js → TextInput-CoL8nOyt.js} +3 -3
- package/dist/TextInput-CoL8nOyt.js.map +1 -0
- package/dist/{TextOverflowTooltip-B1I5qwAT.js → TextOverflowTooltip-BaNPKqnO.js} +2 -2
- package/dist/{TextOverflowTooltip-B1I5qwAT.js.map → TextOverflowTooltip-BaNPKqnO.js.map} +1 -1
- package/dist/{Toggle-v_HT3Gm2.js → Toggle-CmalMf4O.js} +2 -2
- package/dist/Toggle-CmalMf4O.js.map +1 -0
- package/dist/{Tooltip-7Duaau0S.js → Tooltip-DOgKy50D.js} +3 -3
- package/dist/Tooltip-DOgKy50D.js.map +1 -0
- package/dist/{TriggerButton-CfDObWP9.js → TriggerButton-CoAgB4lx.js} +2 -2
- package/dist/TriggerButton-CoAgB4lx.js.map +1 -0
- package/dist/blocks/auth/otp-form.js +4 -4
- package/dist/blocks/auth/otp-form.js.map +1 -1
- package/dist/cn-dsXlqdJg.js.map +1 -1
- package/dist/components/alert-dialog.js +3 -3
- package/dist/components/alert-dialog.js.map +1 -1
- package/dist/components/alert.js +1 -1
- package/dist/components/alert.js.map +1 -1
- package/dist/components/avatar.js.map +1 -1
- package/dist/components/background-pattern.js.map +1 -1
- package/dist/components/badge.js.map +1 -1
- package/dist/components/banner.js.map +1 -1
- package/dist/components/breadcrumb.js.map +1 -1
- package/dist/components/button.js +5 -5
- package/dist/components/button.js.map +1 -1
- package/dist/components/calendar.js +2 -2
- package/dist/components/calendar.js.map +1 -1
- package/dist/components/card.js +2 -2
- package/dist/components/card.js.map +1 -1
- package/dist/components/carousel.js +1 -1
- package/dist/components/carousel.js.map +1 -1
- package/dist/components/checkbox.js +1 -1
- package/dist/components/collapsible.js.map +1 -1
- package/dist/components/color-tile.js.map +1 -1
- package/dist/components/command.js +1 -1
- package/dist/components/container.js.map +1 -1
- package/dist/components/context-menu.js +6 -6
- package/dist/components/context-menu.js.map +1 -1
- package/dist/components/counter.js +1 -1
- package/dist/components/counter.js.map +1 -1
- package/dist/components/dialog.js +3 -3
- package/dist/components/dialog.js.map +1 -1
- package/dist/components/divider.js.map +1 -1
- package/dist/components/drawer.js +4 -4
- package/dist/components/drawer.js.map +1 -1
- package/dist/components/dropdown.js +9 -9
- package/dist/components/dropdown.js.map +1 -1
- package/dist/components/error-state.js +1 -1
- package/dist/components/error-state.js.map +1 -1
- package/dist/components/field.js +1 -1
- package/dist/components/file-upload.js +3 -3
- package/dist/components/file-upload.js.map +1 -1
- package/dist/components/form.js +5 -5
- package/dist/components/form.js.map +1 -1
- package/dist/components/glass-toolbar.js +6 -6
- package/dist/components/glass-toolbar.js.map +1 -1
- package/dist/components/icon-tooltip.js +1 -1
- package/dist/components/image-placeholder.js.map +1 -1
- package/dist/components/image-preview.js +2 -2
- package/dist/components/image-preview.js.map +1 -1
- package/dist/components/image-uploader.js +1 -1
- package/dist/components/image-uploader.js.map +1 -1
- package/dist/components/input-otp.js +1 -1
- package/dist/components/input.js +5 -5
- package/dist/components/input.js.map +1 -1
- package/dist/components/label.js +1 -1
- package/dist/components/menu-item.js +6 -6
- package/dist/components/menu-item.js.map +1 -1
- package/dist/components/overflow-tooltip.js +1 -1
- package/dist/components/overlay.js +1 -1
- package/dist/components/page-state.js +7 -7
- package/dist/components/page-state.js.map +1 -1
- package/dist/components/popover.js +1 -1
- package/dist/components/portal-container/usePortalContainer.d.ts +2 -1
- package/dist/components/portal-container.js +2 -2
- package/dist/components/portal-container.js.map +1 -1
- package/dist/components/progress-circle.js +1 -1
- package/dist/components/progress-circle.js.map +1 -1
- package/dist/components/progress.js +3 -3
- package/dist/components/progress.js.map +1 -1
- package/dist/components/prose.js.map +1 -1
- package/dist/components/radio-group.js +1 -1
- package/dist/components/radio-group.js.map +1 -1
- package/dist/components/resizable.js +1 -1
- package/dist/components/resizable.js.map +1 -1
- package/dist/components/scheduler.js +1 -1
- package/dist/components/scheduler.js.map +1 -1
- package/dist/components/search-select.js +4 -4
- package/dist/components/search-select.js.map +1 -1
- package/dist/components/select.js +1 -1
- package/dist/components/sheet.js +1 -1
- package/dist/components/sidebar.js +90 -90
- package/dist/components/sidebar.js.map +1 -1
- package/dist/components/slider.js +1 -1
- package/dist/components/slider.js.map +1 -1
- package/dist/components/stepper.js +1 -1
- package/dist/components/stepper.js.map +1 -1
- package/dist/components/switch.js +2 -2
- package/dist/components/switch.js.map +1 -1
- package/dist/components/system-state.js +1 -1
- package/dist/components/system-state.js.map +1 -1
- package/dist/components/table/editable/editableCell.d.ts +2 -2
- package/dist/components/table/editable.js +1 -1
- package/dist/components/table/tree.js +1 -1
- package/dist/components/table.js +2 -2
- package/dist/components/tabs.js +2 -2
- package/dist/components/tabs.js.map +1 -1
- package/dist/components/tag-input.js +5 -5
- package/dist/components/tag-input.js.map +1 -1
- package/dist/components/tag.js +1 -1
- package/dist/components/textarea.js +1 -1
- package/dist/components/textarea.js.map +1 -1
- package/dist/components/timer.js.map +1 -1
- package/dist/components/toast.js +6 -6
- package/dist/components/toast.js.map +1 -1
- package/dist/components/toggle-group.js +1 -1
- package/dist/components/toggle-group.js.map +1 -1
- package/dist/components/toggle.js +1 -1
- package/dist/components/toolbar.js +1 -1
- package/dist/components/toolbar.js.map +1 -1
- package/dist/components/tooltip.js +1 -1
- package/dist/design-tokens.source.json +1 -0
- package/dist/docs/tailwind-utilities/ScrollFade.stories.d.ts +28 -0
- package/dist/docs/tailwind-utilities/Shimmer.stories.d.ts +32 -0
- package/dist/floating-ui.react-dom-BwDfy92G.js.map +1 -1
- package/dist/font-smoothing.css +4 -0
- package/dist/formatBytes-C4QXq5lC.js.map +1 -1
- package/dist/index-0ioNhtNM.js.map +1 -1
- package/dist/index-1SnkxfPR.js.map +1 -1
- package/dist/index-437EL2iq.js.map +1 -1
- package/dist/index-BDrapWDv.js.map +1 -1
- package/dist/index-BGQepRFJ.js.map +1 -1
- package/dist/index-BVqs-uqP.js.map +1 -1
- package/dist/index-BZPx6jYI.js.map +1 -1
- package/dist/index-Bb23HztA.js.map +1 -1
- package/dist/index-BjtNfqNq.js.map +1 -1
- package/dist/index-BpWB3aFK.js.map +1 -1
- package/dist/index-ByaXH_ih.js.map +1 -1
- package/dist/index-CCKe-Mpx.js.map +1 -1
- package/dist/index-CFaU3UXv.js.map +1 -1
- package/dist/index-CLuiUUQ8.js.map +1 -1
- package/dist/index-CMxHunQ4.js.map +1 -1
- package/dist/index-CmBeyp2d.js.map +1 -1
- package/dist/index-DFZozV_h.js.map +1 -1
- package/dist/index-DHsfW5Rj.js.map +1 -1
- package/dist/index-DHyZ_0Ut.js.map +1 -1
- package/dist/index-DLcqcWxM.js.map +1 -1
- package/dist/index-DnnQs07z.js.map +1 -1
- package/dist/index-Uiy0Xwy2.js.map +1 -1
- package/dist/index-_ITz1IyW.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/{inputBaseStyles-BfZIWuQ6.js → inputBaseStyles-CZwQWSub.js} +7 -7
- package/dist/inputBaseStyles-CZwQWSub.js.map +1 -0
- package/dist/lib/utils.js.map +1 -1
- package/dist/opaqueCell-D95h1mFM.js.map +1 -1
- package/dist/styles.css +8929 -6508
- package/dist/tailwind.css +361 -0
- package/dist/theme.css +360 -360
- package/dist/{treeModel-BlJWP4sc.js → treeModel-CUO1A5s7.js} +11 -11
- package/dist/treeModel-CUO1A5s7.js.map +1 -0
- package/dist/types/css.d.ts +4 -4
- package/dist/useBreakpoints-DHvp74UL.js.map +1 -1
- package/dist/useDebounce-BRah78CF.js.map +1 -1
- package/dist/useFileUpload-Bnl3P8mP.js.map +1 -1
- package/dist/useItemsKeyboardNavigation-CmeOR30y.js.map +1 -1
- package/dist/useMergeRefs-qoKniYqT.js.map +1 -1
- package/dist/usePortalContainer-B1xla842.js +33 -0
- package/dist/usePortalContainer-B1xla842.js.map +1 -0
- package/dist/vendors/tanstack/react-table.js.map +1 -1
- package/dist/zod-BMNoK3aM.js.map +1 -1
- package/package.json +204 -207
- package/dist/Button-Dg89xRSi.js.map +0 -1
- package/dist/ButtonBase-e6qyv6mD.js +0 -158
- package/dist/ButtonBase-e6qyv6mD.js.map +0 -1
- package/dist/CheckboxField-limFbMk2.js.map +0 -1
- package/dist/Command-B7ZRyW8w.js.map +0 -1
- package/dist/Dialog-CdnsGyJD.js.map +0 -1
- package/dist/Field-CP_-li9L.js.map +0 -1
- package/dist/FieldLabel-eyKmeWRn.js.map +0 -1
- package/dist/FormFooterTemplate-BRrgrxAu.js.map +0 -1
- package/dist/FormHeader--F6b2aRk.js.map +0 -1
- package/dist/FormStack-Cc_ELdWL.js.map +0 -1
- package/dist/IconButton-DwkpNgn3.js.map +0 -1
- package/dist/IconTooltip-RSxvnBgH.js.map +0 -1
- package/dist/InputGroup-BcRWP-zL.js.map +0 -1
- package/dist/InputOTP-B2e1nfSO.js.map +0 -1
- package/dist/MenuItem-d19Ty84F.js.map +0 -1
- package/dist/Overlay-CVt011mY.js.map +0 -1
- package/dist/Popover-CRVD7AtB.js.map +0 -1
- package/dist/RichButton-DuPTenmS.js.map +0 -1
- package/dist/SearchSelectTag-CA7Ie3Nx.js.map +0 -1
- package/dist/Select-D9juHX8o.js.map +0 -1
- package/dist/Sheet-qTIXsqm0.js.map +0 -1
- package/dist/TableFillHandle-C_yvCTSl.js.map +0 -1
- package/dist/Tag-DdHXTyKF.js.map +0 -1
- package/dist/TextInput-Db0ylY91.js.map +0 -1
- package/dist/Toggle-v_HT3Gm2.js.map +0 -1
- package/dist/Tooltip-7Duaau0S.js.map +0 -1
- package/dist/TriggerButton-CfDObWP9.js.map +0 -1
- package/dist/inputBaseStyles-BfZIWuQ6.js.map +0 -1
- package/dist/lib/utils/styles.d.ts +0 -10
- package/dist/styles-scoped.css +0 -6654
- package/dist/styles-scoped.d.ts +0 -1
- package/dist/treeModel-BlJWP4sc.js.map +0 -1
- package/dist/usePortalContainer-BAIp0kSF.js +0 -44
- package/dist/usePortalContainer-BAIp0kSF.js.map +0 -1
- package/tailwind.preset.js +0 -452
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as t, jsxs as p } from "react/jsx-runtime";
|
|
2
2
|
import { c as n } from "./cn-dsXlqdJg.js";
|
|
3
|
-
import { a as u, T, b as g, c as m } from "./Tooltip-
|
|
3
|
+
import { a as u, T, b as g, c as m } from "./Tooltip-DOgKy50D.js";
|
|
4
4
|
import { useState as O, useRef as h, useCallback as d } from "react";
|
|
5
5
|
const w = (o) => o.scrollWidth > o.offsetWidth || o.scrollHeight > o.offsetHeight, x = () => {
|
|
6
6
|
const [o, r] = O(!1), e = h(null), s = d((l) => {
|
|
@@ -33,4 +33,4 @@ export {
|
|
|
33
33
|
v as T,
|
|
34
34
|
x as u
|
|
35
35
|
};
|
|
36
|
-
//# sourceMappingURL=TextOverflowTooltip-
|
|
36
|
+
//# sourceMappingURL=TextOverflowTooltip-BaNPKqnO.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextOverflowTooltip-B1I5qwAT.js","sources":["../src/lib/utils/dom.ts","../src/components/overflow-tooltip/useOverflowTooltip.ts","../src/components/overflow-tooltip/OverflowTooltip.tsx","../src/components/overflow-tooltip/TextOverflowTooltip.tsx"],"sourcesContent":["/**\n * Проверяет, переполнен ли элемент (дочерние элементы выходят за пределы родительского элемента)\n * @param element - HTML элемент для проверки\n * @returns true, если элемент переполнен по ширине или высоте\n *\n * @example\n * // подсказку показываем только там, где текст обрезан\n * const truncated = isElementOverflowing(labelRef.current);\n */\nexport const isElementOverflowing = (element: HTMLElement): boolean => {\n\treturn element.scrollWidth > element.offsetWidth || element.scrollHeight > element.offsetHeight;\n};\n\n/**\n * Canvas для измерения текста переиспользуется: на каждый вызов создавать его расточительно.\n *\n * Контекст один на все поля страницы, и это безопасно ровно до тех пор, пока каждое\n * измерение выставляет **все** влияющие на ширину свойства. Условное присваивание оставило бы\n * настройку от предыдущего поля: соседняя таблица со своим `letter-spacing` мерила бы текст\n * чужим трекингом. Поэтому свойства ниже пишутся всегда, а сам canvas остаётся приватным\n * для этого модуля — иначе инвариант незаметно нарушит следующий пользователь.\n */\nlet measureContext: CanvasRenderingContext2D | null | undefined;\n\nconst getMeasureContext = () => {\n\tif (measureContext === undefined) measureContext = document.createElement(\"canvas\").getContext(\"2d\");\n\treturn measureContext;\n};\n\n/**\n * Ставит каретку в `input`/`textarea` по горизонтальной координате указателя (`clientX`).\n *\n * Нужно там, где поле появляется по клику уже после самого клика — например, при переходе\n * ячейки таблицы в режим редактирования по двойному щелчку: без этого каретка встаёт\n * в начало или конец, а не туда, куда целился пользователь.\n *\n * `caretPositionFromPoint` / `caretRangeFromPoint` здесь бесполезны: содержимое `input`\n * не является частью DOM-дерева, и Range/Selection API до него не достаёт — вернётся сам\n * элемент, а не позиция в тексте. Поэтому индекс считается вручную: текст измеряется\n * на offscreen canvas тем же шрифтом, и выбирается ближайшая к точке граница символа.\n * Ширины префиксов монотонно растут, так что перебор обрывается, как только начал удаляться\n * от цели.\n *\n * Учитывается только горизонталь, поэтому для многострочного текста функция не годится —\n * там нужен `placeCaretAtClientPoint` по `contenteditable`.\n *\n * Возвращает `false`, если поставить каретку не удалось (поле пустое, тип поля не поддерживает\n * выделение или canvas недоступен) — вызывающему коду в этом случае стоит оставить поведение\n * по умолчанию.\n *\n * @example\n * // координата запоминается на dblclick, применяется, когда поле получило фокус\n * <input\n * autoFocus\n * onFocus={(event) => {\n * const input = event.currentTarget;\n * if (!placeCaretAtPoint(input, caretX)) placeCaretAtEnd(input);\n * }}\n * />\n */\nexport const placeCaretAtPoint = (element: HTMLInputElement | HTMLTextAreaElement, clientX: number): boolean => {\n\tconst value = element.value;\n\tif (!value) return false;\n\n\t// У `type=number|email|date|time|color` выделения нет, а `setSelectionRange` на них кидает\n\t// `InvalidStateError`. Тип полей задаёт прикладной код, поэтому проверяем, а не полагаемся.\n\tif (element.selectionStart === null) return false;\n\n\tconst context = getMeasureContext();\n\tif (!context) return false;\n\n\tconst style = window.getComputedStyle(element);\n\tcontext.font = `${style.fontStyle} ${style.fontWeight} ${style.fontSize} ${style.fontFamily}`;\n\t// `letterSpacing` у canvas принимает только длину: `normal` из вычисленных стилей его сломает.\n\t// Пишется на каждом вызове — иначе значение утечёт в следующее поле, см. `measureContext`.\n\tif (\"letterSpacing\" in context) {\n\t\tcontext.letterSpacing = style.letterSpacing.endsWith(\"px\") ? style.letterSpacing : \"0px\";\n\t}\n\n\tconst rect = element.getBoundingClientRect();\n\tconst borderLeft = parseFloat(style.borderLeftWidth) || 0;\n\tconst borderRight = parseFloat(style.borderRightWidth) || 0;\n\tconst paddingLeft = parseFloat(style.paddingLeft) || 0;\n\tconst paddingRight = parseFloat(style.paddingRight) || 0;\n\tconst contentLeft = rect.left + borderLeft + paddingLeft;\n\tconst contentWidth = rect.width - borderLeft - borderRight - paddingLeft - paddingRight;\n\n\t// Текст короче поля прижимается по `text-align`, и отсчитывать позицию от левого края\n\t// нельзя — у выровненного вправо поля это промах на всю свободную ширину.\n\tconst slack = contentWidth - context.measureText(value).width;\n\tlet originX = contentLeft - element.scrollLeft;\n\tif (slack > 0) {\n\t\tif (style.textAlign === \"right\" || style.textAlign === \"end\") originX += slack;\n\t\telse if (style.textAlign === \"center\") originX += slack / 2;\n\t}\n\n\tconst targetX = clientX - originX;\n\tlet bestIndex = 0;\n\tlet bestDistance = Infinity;\n\tfor (let index = 0; index <= value.length; index++) {\n\t\tconst distance = Math.abs(context.measureText(value.slice(0, index)).width - targetX);\n\t\tif (distance > bestDistance) break;\n\t\tbestDistance = distance;\n\t\tbestIndex = index;\n\t}\n\n\telement.setSelectionRange(bestIndex, bestIndex);\n\treturn true;\n};\n\n/**\n * Ставит каретку в `contenteditable` по точке указателя.\n *\n * В отличие от `input`, текст здесь — обычные узлы DOM, поэтому измерять ничего не нужно:\n * браузер сам отдаёт позицию по координатам. Работает и с переносами, так что это тот случай,\n * когда многострочная правка делается редактируемым `div`, а не `textarea`.\n *\n * Возвращает `false`, если точка не попала в текст элемента, — вызывающему коду стоит\n * поставить каретку в конец через `placeCaretAtEnd`.\n *\n * @example\n * const editor = event.currentTarget;\n * if (!placeCaretAtClientPoint(editor, event.clientX, event.clientY)) placeCaretAtEnd(editor);\n */\nexport const placeCaretAtClientPoint = (element: HTMLElement, clientX: number, clientY: number): boolean => {\n\tconst selection = window.getSelection();\n\tif (!selection) return false;\n\n\tconst range = caretRangeAtPoint(clientX, clientY);\n\t// Точка могла прийтись на отступ ячейки или на соседний узел: чужую позицию не ставим.\n\tif (!range || !element.contains(range.startContainer)) return false;\n\n\tselection.removeAllRanges();\n\tselection.addRange(range);\n\treturn true;\n};\n\n/**\n * Оба способа спросить у браузера позицию каретки по координатам — объявлены здесь сами.\n *\n * `caretPositionFromPoint` — стандартный, но в `lib.dom` TS 5.6 его ещё нет.\n * `caretRangeFromPoint` — легаси WebKit, в `lib.dom` он помечен `@deprecated`; берётся\n * только фолбэком для Safari до 17.4, где стандартного метода ещё не было. Объявление\n * собрано в одном месте намеренно: обращение идёт к нему, а не к устаревшему члену `Document`,\n * и причина использования легаси видна рядом, а не прячется за подавленной подсказкой.\n */\ntype DocumentWithCaretApi = Document & {\n\tcaretPositionFromPoint?: (x: number, y: number) => { offsetNode: Node; offset: number } | null;\n\tcaretRangeFromPoint?: (x: number, y: number) => Range | null;\n};\n\nconst caretRangeAtPoint = (clientX: number, clientY: number): Range | null => {\n\tconst doc = document as DocumentWithCaretApi;\n\n\tif (doc.caretPositionFromPoint) {\n\t\tconst position = doc.caretPositionFromPoint(clientX, clientY);\n\t\tif (!position) return null;\n\t\tconst range = document.createRange();\n\t\trange.setStart(position.offsetNode, position.offset);\n\t\trange.collapse(true);\n\t\treturn range;\n\t}\n\n\treturn doc.caretRangeFromPoint?.(clientX, clientY) ?? null;\n};\n\n/**\n * Ставит каретку в конец содержимого `contenteditable` — поведение F2 в Excel.\n *\n * @example\n * // F2 открывает правку с кареткой в конце\n * if (event.key === \"F2\") placeCaretAtEnd(editorRef.current);\n */\nexport const placeCaretAtEnd = (element: HTMLElement): void => {\n\tconst selection = window.getSelection();\n\tif (!selection) return;\n\n\tconst range = document.createRange();\n\trange.selectNodeContents(element);\n\trange.collapse(false);\n\tselection.removeAllRanges();\n\tselection.addRange(range);\n};\n\n/**\n * Вставляет текст в текущую позицию каретки внутри `contenteditable`, заменяя выделенное.\n *\n * Нужно на вставке из буфера: по умолчанию `contenteditable` принимает разметку, и в ячейку\n * приезжает чужое форматирование вместе с текстом.\n *\n * @example\n * onPaste={(event) => {\n * event.preventDefault();\n * insertTextAtCaret(event.currentTarget, event.clipboardData.getData(\"text/plain\"));\n * }}\n */\nexport const insertTextAtCaret = (element: HTMLElement, text: string): void => {\n\tconst selection = window.getSelection();\n\tif (!selection?.rangeCount) return;\n\n\tconst range = selection.getRangeAt(0);\n\tif (!element.contains(range.startContainer)) return;\n\n\trange.deleteContents();\n\tconst node = document.createTextNode(text);\n\trange.insertNode(node);\n\trange.setStartAfter(node);\n\trange.collapse(true);\n\tselection.removeAllRanges();\n\tselection.addRange(range);\n};\n","import { useCallback, useRef, useState } from \"react\";\nimport { isElementOverflowing } from \"../../lib/utils/dom\";\n\nexport const useOverflowTooltip = <T extends HTMLElement>() => {\n\tconst [open, setOpen] = useState(false);\n\tconst ref = useRef<T>(null);\n\n\tconst onOpenChange = useCallback((newOpen: boolean) => {\n\t\tif (newOpen === false) {\n\t\t\tsetOpen(false);\n\t\t\treturn;\n\t\t}\n\t\tif (!ref.current) return;\n\t\tif (isElementOverflowing(ref.current)) {\n\t\t\tsetOpen(true);\n\t\t}\n\t}, []);\n\n\treturn { open, onOpenChange, ref };\n};\n","import { cn } from \"@/lib/utils\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../tooltip\";\nimport { useOverflowTooltip } from \"./useOverflowTooltip\";\nimport React from \"react\";\n\ntype OverflowTooltipProps = {\n\tchildren: React.ReactNode;\n\t/**\n\t * HTML-элемент для обертки содержимого.\n\t * Используется для соблюдения правильной HTML-семантики.\n\t * Например:\n\t * - span (по умолчанию) для текста и инлайн-элементов\n\t * - div для блочного содержимого и сложных структур\n\t * @default span\n\t */\n\ttriggerTag?: React.ElementType;\n\t/**\n\t * Классы для обработки переполненного содержимого.\n\t * Например: \"truncate\", \"line-clamp-3\" и т.д.\n\t */\n\tclassName?: string;\n\t/**\n\t * Классы для содержимого тултипа.\n\t * С помощью них можно управлять стилями тултипа, например шириной, переносом текста и т.д.\n\t */\n\ttooltipClassName?: string;\n\tfocus?: \"high\";\n};\n\nexport const OverflowTooltip = ({ children, className, focus, triggerTag, tooltipClassName }: OverflowTooltipProps) => {\n\tconst { open, onOpenChange, ref } = useOverflowTooltip<HTMLDivElement>();\n\tconst TriggerTag = triggerTag || \"span\";\n\treturn (\n\t\t<TooltipProvider>\n\t\t\t<Tooltip open={open} onOpenChange={onOpenChange}>\n\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t<TriggerTag ref={ref} className={cn(className)}>\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</TriggerTag>\n\t\t\t\t</TooltipTrigger>\n\t\t\t\t<TooltipContent focus={focus} className={cn(\"max-w-xs\", tooltipClassName)}>\n\t\t\t\t\t{children}\n\t\t\t\t</TooltipContent>\n\t\t\t</Tooltip>\n\t\t</TooltipProvider>\n\t);\n};\n\nOverflowTooltip.displayName = \"OverflowTooltip\";\n","import { cn } from \"@/lib/utils\";\nimport React from \"react\";\nimport { OverflowTooltip } from \"./OverflowTooltip\";\n\ntype TextOverflowTooltipProps = {\n\tchildren?: React.ReactNode;\n\tclassName?: string;\n\ttooltipClassName?: string;\n};\n\nexport const TextOverflowTooltip = ({ children, className, tooltipClassName }: TextOverflowTooltipProps) => {\n\treturn (\n\t\t<OverflowTooltip\n\t\t\tclassName={cn(\"inline-block max-w-full truncate\", className)}\n\t\t\ttooltipClassName={tooltipClassName}\n\t\t>\n\t\t\t{children}\n\t\t</OverflowTooltip>\n\t);\n};\n\nTextOverflowTooltip.displayName = \"TextOverflowTooltip\";\n"],"names":["isElementOverflowing","element","useOverflowTooltip","open","setOpen","useState","ref","useRef","onOpenChange","useCallback","newOpen","OverflowTooltip","children","className","focus","triggerTag","tooltipClassName","jsx","TooltipProvider","jsxs","Tooltip","TooltipTrigger","cn","TooltipContent","TextOverflowTooltip"],"mappings":";;;;AASa,MAAAA,IAAuB,CAACC,MAC7BA,EAAQ,cAAcA,EAAQ,eAAeA,EAAQ,eAAeA,EAAQ,cCPvEC,IAAqB,MAA6B;AAC9D,QAAM,CAACC,GAAMC,CAAO,IAAIC,EAAS,EAAK,GAChCC,IAAMC,EAAU,IAAI,GAEpBC,IAAeC,EAAY,CAACC,MAAqB;AACtD,QAAIA,MAAY,IAAO;AACtB,MAAAN,EAAQ,EAAK;AACb;AAAA,IAAA;AAEG,IAACE,EAAI,WACLN,EAAqBM,EAAI,OAAO,KACnCF,EAAQ,EAAI;AAAA,EAEd,GAAG,EAAE;AAEE,SAAA,EAAE,MAAAD,GAAM,cAAAK,GAAc,KAAAF,EAAI;AAClC,GCUaK,IAAkB,CAAC,EAAE,UAAAC,GAAU,WAAAC,GAAW,OAAAC,GAAO,YAAAC,GAAY,kBAAAC,QAA6C;AACtH,QAAM,EAAE,MAAAb,GAAM,cAAAK,GAAc,KAAAF,EAAA,IAAQJ,EAAmC;AAEvE,SACE,gBAAAe,EAAAC,GAAA,EACA,UAAC,gBAAAC,EAAAC,GAAA,EAAQ,MAAAjB,GAAY,cAAAK,GACpB,UAAA;AAAA,IAAC,gBAAAS,EAAAI,GAAA,EAAe,SAAO,IACtB,UAAC,gBAAAJ,EALcF,KAAc,QAK5B,EAAW,KAAAT,GAAU,WAAWgB,EAAGT,CAAS,GAC3C,UAAAD,EACF,CAAA,GACD;AAAA,IACA,gBAAAK,EAACM,KAAe,OAAAT,GAAc,WAAWQ,EAAG,YAAYN,CAAgB,GACtE,UAAAJ,EACF,CAAA;AAAA,EAAA,EAAA,CACD,EACD,CAAA;AAEF;AAEAD,EAAgB,cAAc;ACtCvB,MAAMa,IAAsB,CAAC,EAAE,UAAAZ,GAAU,WAAAC,GAAW,kBAAAG,QAEzD,gBAAAC;AAAA,EAACN;AAAA,EAAA;AAAA,IACA,WAAWW,EAAG,oCAAoCT,CAAS;AAAA,IAC3D,kBAAAG;AAAA,IAEC,UAAAJ;AAAA,EAAA;AACF;AAIFY,EAAoB,cAAc;"}
|
|
1
|
+
{"version":3,"file":"TextOverflowTooltip-BaNPKqnO.js","sources":["../src/lib/utils/dom.ts","../src/components/overflow-tooltip/useOverflowTooltip.ts","../src/components/overflow-tooltip/OverflowTooltip.tsx","../src/components/overflow-tooltip/TextOverflowTooltip.tsx"],"sourcesContent":["/**\n * Проверяет, переполнен ли элемент (дочерние элементы выходят за пределы родительского элемента)\n * @param element - HTML элемент для проверки\n * @returns true, если элемент переполнен по ширине или высоте\n *\n * @example\n * // подсказку показываем только там, где текст обрезан\n * const truncated = isElementOverflowing(labelRef.current);\n */\nexport const isElementOverflowing = (element: HTMLElement): boolean => {\n\treturn element.scrollWidth > element.offsetWidth || element.scrollHeight > element.offsetHeight;\n};\n\n/**\n * Canvas для измерения текста переиспользуется: на каждый вызов создавать его расточительно.\n *\n * Контекст один на все поля страницы, и это безопасно ровно до тех пор, пока каждое\n * измерение выставляет **все** влияющие на ширину свойства. Условное присваивание оставило бы\n * настройку от предыдущего поля: соседняя таблица со своим `letter-spacing` мерила бы текст\n * чужим трекингом. Поэтому свойства ниже пишутся всегда, а сам canvas остаётся приватным\n * для этого модуля — иначе инвариант незаметно нарушит следующий пользователь.\n */\nlet measureContext: CanvasRenderingContext2D | null | undefined;\n\nconst getMeasureContext = () => {\n\tif (measureContext === undefined) measureContext = document.createElement(\"canvas\").getContext(\"2d\");\n\treturn measureContext;\n};\n\n/**\n * Ставит каретку в `input`/`textarea` по горизонтальной координате указателя (`clientX`).\n *\n * Нужно там, где поле появляется по клику уже после самого клика — например, при переходе\n * ячейки таблицы в режим редактирования по двойному щелчку: без этого каретка встаёт\n * в начало или конец, а не туда, куда целился пользователь.\n *\n * `caretPositionFromPoint` / `caretRangeFromPoint` здесь бесполезны: содержимое `input`\n * не является частью DOM-дерева, и Range/Selection API до него не достаёт — вернётся сам\n * элемент, а не позиция в тексте. Поэтому индекс считается вручную: текст измеряется\n * на offscreen canvas тем же шрифтом, и выбирается ближайшая к точке граница символа.\n * Ширины префиксов монотонно растут, так что перебор обрывается, как только начал удаляться\n * от цели.\n *\n * Учитывается только горизонталь, поэтому для многострочного текста функция не годится —\n * там нужен `placeCaretAtClientPoint` по `contenteditable`.\n *\n * Возвращает `false`, если поставить каретку не удалось (поле пустое, тип поля не поддерживает\n * выделение или canvas недоступен) — вызывающему коду в этом случае стоит оставить поведение\n * по умолчанию.\n *\n * @example\n * // координата запоминается на dblclick, применяется, когда поле получило фокус\n * <input\n * autoFocus\n * onFocus={(event) => {\n * const input = event.currentTarget;\n * if (!placeCaretAtPoint(input, caretX)) placeCaretAtEnd(input);\n * }}\n * />\n */\nexport const placeCaretAtPoint = (element: HTMLInputElement | HTMLTextAreaElement, clientX: number): boolean => {\n\tconst value = element.value;\n\tif (!value) return false;\n\n\t// У `type=number|email|date|time|color` выделения нет, а `setSelectionRange` на них кидает\n\t// `InvalidStateError`. Тип полей задаёт прикладной код, поэтому проверяем, а не полагаемся.\n\tif (element.selectionStart === null) return false;\n\n\tconst context = getMeasureContext();\n\tif (!context) return false;\n\n\tconst style = window.getComputedStyle(element);\n\tcontext.font = `${style.fontStyle} ${style.fontWeight} ${style.fontSize} ${style.fontFamily}`;\n\t// `letterSpacing` у canvas принимает только длину: `normal` из вычисленных стилей его сломает.\n\t// Пишется на каждом вызове — иначе значение утечёт в следующее поле, см. `measureContext`.\n\tif (\"letterSpacing\" in context) {\n\t\tcontext.letterSpacing = style.letterSpacing.endsWith(\"px\") ? style.letterSpacing : \"0px\";\n\t}\n\n\tconst rect = element.getBoundingClientRect();\n\tconst borderLeft = parseFloat(style.borderLeftWidth) || 0;\n\tconst borderRight = parseFloat(style.borderRightWidth) || 0;\n\tconst paddingLeft = parseFloat(style.paddingLeft) || 0;\n\tconst paddingRight = parseFloat(style.paddingRight) || 0;\n\tconst contentLeft = rect.left + borderLeft + paddingLeft;\n\tconst contentWidth = rect.width - borderLeft - borderRight - paddingLeft - paddingRight;\n\n\t// Текст короче поля прижимается по `text-align`, и отсчитывать позицию от левого края\n\t// нельзя — у выровненного вправо поля это промах на всю свободную ширину.\n\tconst slack = contentWidth - context.measureText(value).width;\n\tlet originX = contentLeft - element.scrollLeft;\n\tif (slack > 0) {\n\t\tif (style.textAlign === \"right\" || style.textAlign === \"end\") originX += slack;\n\t\telse if (style.textAlign === \"center\") originX += slack / 2;\n\t}\n\n\tconst targetX = clientX - originX;\n\tlet bestIndex = 0;\n\tlet bestDistance = Infinity;\n\tfor (let index = 0; index <= value.length; index++) {\n\t\tconst distance = Math.abs(context.measureText(value.slice(0, index)).width - targetX);\n\t\tif (distance > bestDistance) break;\n\t\tbestDistance = distance;\n\t\tbestIndex = index;\n\t}\n\n\telement.setSelectionRange(bestIndex, bestIndex);\n\treturn true;\n};\n\n/**\n * Ставит каретку в `contenteditable` по точке указателя.\n *\n * В отличие от `input`, текст здесь — обычные узлы DOM, поэтому измерять ничего не нужно:\n * браузер сам отдаёт позицию по координатам. Работает и с переносами, так что это тот случай,\n * когда многострочная правка делается редактируемым `div`, а не `textarea`.\n *\n * Возвращает `false`, если точка не попала в текст элемента, — вызывающему коду стоит\n * поставить каретку в конец через `placeCaretAtEnd`.\n *\n * @example\n * const editor = event.currentTarget;\n * if (!placeCaretAtClientPoint(editor, event.clientX, event.clientY)) placeCaretAtEnd(editor);\n */\nexport const placeCaretAtClientPoint = (element: HTMLElement, clientX: number, clientY: number): boolean => {\n\tconst selection = window.getSelection();\n\tif (!selection) return false;\n\n\tconst range = caretRangeAtPoint(clientX, clientY);\n\t// Точка могла прийтись на отступ ячейки или на соседний узел: чужую позицию не ставим.\n\tif (!range || !element.contains(range.startContainer)) return false;\n\n\tselection.removeAllRanges();\n\tselection.addRange(range);\n\treturn true;\n};\n\n/**\n * Оба способа спросить у браузера позицию каретки по координатам — объявлены здесь сами.\n *\n * `caretPositionFromPoint` — стандартный, но в `lib.dom` TS 5.6 его ещё нет.\n * `caretRangeFromPoint` — легаси WebKit, в `lib.dom` он помечен `@deprecated`; берётся\n * только фолбэком для Safari до 17.4, где стандартного метода ещё не было. Объявление\n * собрано в одном месте намеренно: обращение идёт к нему, а не к устаревшему члену `Document`,\n * и причина использования легаси видна рядом, а не прячется за подавленной подсказкой.\n */\ntype DocumentWithCaretApi = Document & {\n\tcaretPositionFromPoint?: (x: number, y: number) => { offsetNode: Node; offset: number } | null;\n\tcaretRangeFromPoint?: (x: number, y: number) => Range | null;\n};\n\nconst caretRangeAtPoint = (clientX: number, clientY: number): Range | null => {\n\tconst doc = document as DocumentWithCaretApi;\n\n\tif (doc.caretPositionFromPoint) {\n\t\tconst position = doc.caretPositionFromPoint(clientX, clientY);\n\t\tif (!position) return null;\n\t\tconst range = document.createRange();\n\t\trange.setStart(position.offsetNode, position.offset);\n\t\trange.collapse(true);\n\t\treturn range;\n\t}\n\n\treturn doc.caretRangeFromPoint?.(clientX, clientY) ?? null;\n};\n\n/**\n * Ставит каретку в конец содержимого `contenteditable` — поведение F2 в Excel.\n *\n * @example\n * // F2 открывает правку с кареткой в конце\n * if (event.key === \"F2\") placeCaretAtEnd(editorRef.current);\n */\nexport const placeCaretAtEnd = (element: HTMLElement): void => {\n\tconst selection = window.getSelection();\n\tif (!selection) return;\n\n\tconst range = document.createRange();\n\trange.selectNodeContents(element);\n\trange.collapse(false);\n\tselection.removeAllRanges();\n\tselection.addRange(range);\n};\n\n/**\n * Вставляет текст в текущую позицию каретки внутри `contenteditable`, заменяя выделенное.\n *\n * Нужно на вставке из буфера: по умолчанию `contenteditable` принимает разметку, и в ячейку\n * приезжает чужое форматирование вместе с текстом.\n *\n * @example\n * onPaste={(event) => {\n * event.preventDefault();\n * insertTextAtCaret(event.currentTarget, event.clipboardData.getData(\"text/plain\"));\n * }}\n */\nexport const insertTextAtCaret = (element: HTMLElement, text: string): void => {\n\tconst selection = window.getSelection();\n\tif (!selection?.rangeCount) return;\n\n\tconst range = selection.getRangeAt(0);\n\tif (!element.contains(range.startContainer)) return;\n\n\trange.deleteContents();\n\tconst node = document.createTextNode(text);\n\trange.insertNode(node);\n\trange.setStartAfter(node);\n\trange.collapse(true);\n\tselection.removeAllRanges();\n\tselection.addRange(range);\n};\n","import { useCallback, useRef, useState } from \"react\";\r\nimport { isElementOverflowing } from \"../../lib/utils/dom\";\r\n\r\nexport const useOverflowTooltip = <T extends HTMLElement>() => {\r\n\tconst [open, setOpen] = useState(false);\r\n\tconst ref = useRef<T>(null);\r\n\r\n\tconst onOpenChange = useCallback((newOpen: boolean) => {\r\n\t\tif (newOpen === false) {\r\n\t\t\tsetOpen(false);\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (!ref.current) return;\r\n\t\tif (isElementOverflowing(ref.current)) {\r\n\t\t\tsetOpen(true);\r\n\t\t}\r\n\t}, []);\r\n\r\n\treturn { open, onOpenChange, ref };\r\n};\r\n","import { cn } from \"@/lib/utils\";\r\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../tooltip\";\r\nimport { useOverflowTooltip } from \"./useOverflowTooltip\";\r\nimport React from \"react\";\r\n\r\ntype OverflowTooltipProps = {\r\n\tchildren: React.ReactNode;\r\n\t/**\r\n\t * HTML-элемент для обертки содержимого.\r\n\t * Используется для соблюдения правильной HTML-семантики.\r\n\t * Например:\r\n\t * - span (по умолчанию) для текста и инлайн-элементов\r\n\t * - div для блочного содержимого и сложных структур\r\n\t * @default span\r\n\t */\r\n\ttriggerTag?: React.ElementType;\r\n\t/**\r\n\t * Классы для обработки переполненного содержимого.\r\n\t * Например: \"truncate\", \"line-clamp-3\" и т.д.\r\n\t */\r\n\tclassName?: string;\r\n\t/**\r\n\t * Классы для содержимого тултипа.\r\n\t * С помощью них можно управлять стилями тултипа, например шириной, переносом текста и т.д.\r\n\t */\r\n\ttooltipClassName?: string;\r\n\tfocus?: \"high\";\r\n};\r\n\r\nexport const OverflowTooltip = ({ children, className, focus, triggerTag, tooltipClassName }: OverflowTooltipProps) => {\r\n\tconst { open, onOpenChange, ref } = useOverflowTooltip<HTMLDivElement>();\r\n\tconst TriggerTag = triggerTag || \"span\";\r\n\treturn (\r\n\t\t<TooltipProvider>\r\n\t\t\t<Tooltip open={open} onOpenChange={onOpenChange}>\r\n\t\t\t\t<TooltipTrigger asChild>\r\n\t\t\t\t\t<TriggerTag ref={ref} className={cn(className)}>\r\n\t\t\t\t\t\t{children}\r\n\t\t\t\t\t</TriggerTag>\r\n\t\t\t\t</TooltipTrigger>\r\n\t\t\t\t<TooltipContent focus={focus} className={cn(\"max-w-xs\", tooltipClassName)}>\r\n\t\t\t\t\t{children}\r\n\t\t\t\t</TooltipContent>\r\n\t\t\t</Tooltip>\r\n\t\t</TooltipProvider>\r\n\t);\r\n};\r\n\r\nOverflowTooltip.displayName = \"OverflowTooltip\";\r\n","import { cn } from \"@/lib/utils\";\r\nimport React from \"react\";\r\nimport { OverflowTooltip } from \"./OverflowTooltip\";\r\n\r\ntype TextOverflowTooltipProps = {\r\n\tchildren?: React.ReactNode;\r\n\tclassName?: string;\r\n\ttooltipClassName?: string;\r\n};\r\n\r\nexport const TextOverflowTooltip = ({ children, className, tooltipClassName }: TextOverflowTooltipProps) => {\r\n\treturn (\r\n\t\t<OverflowTooltip\r\n\t\t\tclassName={cn(\"inline-block max-w-full truncate\", className)}\r\n\t\t\ttooltipClassName={tooltipClassName}\r\n\t\t>\r\n\t\t\t{children}\r\n\t\t</OverflowTooltip>\r\n\t);\r\n};\r\n\r\nTextOverflowTooltip.displayName = \"TextOverflowTooltip\";\r\n"],"names":["isElementOverflowing","element","useOverflowTooltip","open","setOpen","useState","ref","useRef","onOpenChange","useCallback","newOpen","OverflowTooltip","children","className","focus","triggerTag","tooltipClassName","jsx","TooltipProvider","jsxs","Tooltip","TooltipTrigger","cn","TooltipContent","TextOverflowTooltip"],"mappings":";;;;AASa,MAAAA,IAAuB,CAACC,MAC7BA,EAAQ,cAAcA,EAAQ,eAAeA,EAAQ,eAAeA,EAAQ,cCPvEC,IAAqB,MAA6B;AAC9D,QAAM,CAACC,GAAMC,CAAO,IAAIC,EAAS,EAAK,GAChCC,IAAMC,EAAU,IAAI,GAEpBC,IAAeC,EAAY,CAACC,MAAqB;AACtD,QAAIA,MAAY,IAAO;AACtB,MAAAN,EAAQ,EAAK;AACb;AAAA,IAAA;AAEG,IAACE,EAAI,WACLN,EAAqBM,EAAI,OAAO,KACnCF,EAAQ,EAAI;AAAA,EAEd,GAAG,EAAE;AAEE,SAAA,EAAE,MAAAD,GAAM,cAAAK,GAAc,KAAAF,EAAI;AAClC,GCUaK,IAAkB,CAAC,EAAE,UAAAC,GAAU,WAAAC,GAAW,OAAAC,GAAO,YAAAC,GAAY,kBAAAC,QAA6C;AACtH,QAAM,EAAE,MAAAb,GAAM,cAAAK,GAAc,KAAAF,EAAA,IAAQJ,EAAmC;AAEvE,SACE,gBAAAe,EAAAC,GAAA,EACA,UAAC,gBAAAC,EAAAC,GAAA,EAAQ,MAAAjB,GAAY,cAAAK,GACpB,UAAA;AAAA,IAAC,gBAAAS,EAAAI,GAAA,EAAe,SAAO,IACtB,UAAC,gBAAAJ,EALcF,KAAc,QAK5B,EAAW,KAAAT,GAAU,WAAWgB,EAAGT,CAAS,GAC3C,UAAAD,EACF,CAAA,GACD;AAAA,IACA,gBAAAK,EAACM,KAAe,OAAAT,GAAc,WAAWQ,EAAG,YAAYN,CAAgB,GACtE,UAAAJ,EACF,CAAA;AAAA,EAAA,EAAA,CACD,EACD,CAAA;AAEF;AAEAD,EAAgB,cAAc;ACtCvB,MAAMa,IAAsB,CAAC,EAAE,UAAAZ,GAAU,WAAAC,GAAW,kBAAAG,QAEzD,gBAAAC;AAAA,EAACN;AAAA,EAAA;AAAA,IACA,WAAWW,EAAG,oCAAoCT,CAAS;AAAA,IAC3D,kBAAAG;AAAA,IAEC,UAAAJ;AAAA,EAAA;AACF;AAIFY,EAAoB,cAAc;"}
|
|
@@ -7,7 +7,7 @@ const p = m({
|
|
|
7
7
|
base: [
|
|
8
8
|
"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium leading-none text-primary-fg transition-colors",
|
|
9
9
|
"hover:bg-secondary-bg-hover hover:text-muted",
|
|
10
|
-
"focus-visible:border-secondary-border focus-visible:shadow-focus focus-visible:outline-
|
|
10
|
+
"focus-visible:border-secondary-border focus-visible:shadow-focus focus-visible:outline-hidden",
|
|
11
11
|
"disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
|
|
12
12
|
"data-[state=on]:bg-primary-bg-hover data-[state=on]:text-primary-fg",
|
|
13
13
|
"[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0"
|
|
@@ -37,4 +37,4 @@ export {
|
|
|
37
37
|
g as T,
|
|
38
38
|
p as t
|
|
39
39
|
};
|
|
40
|
-
//# sourceMappingURL=Toggle-
|
|
40
|
+
//# sourceMappingURL=Toggle-CmalMf4O.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Toggle-CmalMf4O.js","sources":["../src/components/toggle/Toggle.tsx"],"sourcesContent":["import * as React from \"react\";\r\nimport * as TogglePrimitive from \"@radix-ui/react-toggle\";\r\nimport { cn } from \"@/lib/utils\";\r\nimport { tv } from \"tailwind-variants\";\r\nimport { VariantsConfig } from \"@/lib/utils/variants\";\r\n\r\nexport interface ToggleVariants {\r\n\tvariant?: \"default\" | \"outline\" | \"ghost\";\r\n\tsize?: \"2xs\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\r\n}\r\n\r\nconst toggleStyles = tv({\r\n\tbase: [\r\n\t\t\"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium leading-none text-primary-fg transition-colors\",\r\n\t\t\"hover:bg-secondary-bg-hover hover:text-muted\",\r\n\t\t\"focus-visible:border-secondary-border focus-visible:shadow-focus focus-visible:outline-hidden\",\r\n\t\t\"disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50\",\r\n\t\t\"data-[state=on]:bg-primary-bg-hover data-[state=on]:text-primary-fg\",\r\n\t\t\"[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\"\r\n\t],\r\n\tvariants: {\r\n\t\tvariant: {\r\n\t\t\tdefault: \"bg-transparent\",\r\n\t\t\toutline:\r\n\t\t\t\t\"border border-secondary-border bg-secondary-bg shadow-soft-sm data-[state=on]:border-primary-border\",\r\n\t\t\tghost: \"bg-transparent hover:text-primary-fg hover:opacity-65 data-[state=on]:bg-secondary-bg-hover\"\r\n\t\t},\r\n\t\tsize: {\r\n\t\t\t\"2xs\": \"h-6 min-w-6 gap-1 rounded-sm p-1\",\r\n\t\t\txs: \"h-7 min-w-7 gap-1.5 rounded-sm p-1.5\",\r\n\t\t\tsm: \"h-8 min-w-8 rounded-sm p-2\",\r\n\t\t\tmd: \"h-9 min-w-9 p-2.5\",\r\n\t\t\tlg: \"h-10 min-w-10 px-3 py-2\",\r\n\t\t\txl: \"h-11 min-w-11 px-4 py-3 text-base leading-none [&_svg]:size-5\"\r\n\t\t}\r\n\t} satisfies VariantsConfig<ToggleVariants>,\r\n\tdefaultVariants: {\r\n\t\tvariant: \"default\",\r\n\t\tsize: \"md\"\r\n\t}\r\n});\r\n\r\nconst Toggle = React.forwardRef<\r\n\tReact.ElementRef<typeof TogglePrimitive.Root>,\r\n\tReact.ComponentPropsWithoutRef<typeof TogglePrimitive.Root> & ToggleVariants\r\n>(({ className, variant, size, ...props }, ref) => (\r\n\t<TogglePrimitive.Root ref={ref} className={cn(toggleStyles({ variant, size, className }))} {...props} />\r\n));\r\n\r\nToggle.displayName = TogglePrimitive.Root.displayName;\r\n\r\nexport { Toggle, toggleStyles as toggleVariants };\r\n"],"names":["toggleStyles","tv","Toggle","React","className","variant","size","props","ref","jsx","TogglePrimitive.Root","cn"],"mappings":";;;;;AAWA,MAAMA,IAAeC,EAAG;AAAA,EACvB,MAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AAAA,EACA,UAAU;AAAA,IACT,SAAS;AAAA,MACR,SAAS;AAAA,MACT,SACC;AAAA,MACD,OAAO;AAAA,IACR;AAAA,IACA,MAAM;AAAA,MACL,OAAO;AAAA,MACP,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,IAAA;AAAA,EAEN;AAAA,EACA,iBAAiB;AAAA,IAChB,SAAS;AAAA,IACT,MAAM;AAAA,EAAA;AAER,CAAC,GAEKC,IAASC,EAAM,WAGnB,CAAC,EAAE,WAAAC,GAAW,SAAAC,GAAS,MAAAC,GAAM,GAAGC,KAASC,MACzC,gBAAAC,EAAAC,GAAA,EAAqB,KAAAF,GAAU,WAAWG,EAAGX,EAAa,EAAE,SAAAK,GAAS,MAAAC,GAAM,WAAAF,EAAW,CAAA,CAAC,GAAI,GAAGG,GAAO,CACtG;AAEDL,EAAO,cAAcQ,EAAqB;"}
|
|
@@ -12,7 +12,7 @@ import { R as me } from "./index-Uiy0Xwy2.js";
|
|
|
12
12
|
import { T as w } from "./index-BVqs-uqP.js";
|
|
13
13
|
import { I as ve } from "./Icon-DH3ev9GK.js";
|
|
14
14
|
import { S as Te } from "./Shortcut-D8L15_ed.js";
|
|
15
|
-
import { u as ge } from "./usePortalContainer-
|
|
15
|
+
import { u as ge } from "./usePortalContainer-B1xla842.js";
|
|
16
16
|
import { T as xe } from "./Text-DeBE8AKl.js";
|
|
17
17
|
var [L, ye] = ae("Tooltip", [
|
|
18
18
|
X
|
|
@@ -433,7 +433,7 @@ const Fe = w({
|
|
|
433
433
|
});
|
|
434
434
|
Be.displayName = "TooltipText";
|
|
435
435
|
const Ue = w({
|
|
436
|
-
base: "
|
|
436
|
+
base: "shrink-0 text-xs text-primary-fg",
|
|
437
437
|
variants: {
|
|
438
438
|
focus: {
|
|
439
439
|
high: "text-inverse-primary-fg"
|
|
@@ -470,4 +470,4 @@ export {
|
|
|
470
470
|
ct as j,
|
|
471
471
|
N as u
|
|
472
472
|
};
|
|
473
|
-
//# sourceMappingURL=Tooltip-
|
|
473
|
+
//# sourceMappingURL=Tooltip-DOgKy50D.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tooltip-DOgKy50D.js","sources":["../node_modules/.pnpm/@radix-ui+react-tooltip@1.2_c0a573e5fee67df1b7628ac6f2833e9e/node_modules/@radix-ui/react-tooltip/dist/index.mjs","../src/components/tooltip/useTooltipContext.ts","../src/components/tooltip/Tooltip.tsx"],"sourcesContent":["\"use client\";\n\n// src/tooltip.tsx\nimport * as React from \"react\";\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { createContextScope } from \"@radix-ui/react-context\";\nimport { DismissableLayer } from \"@radix-ui/react-dismissable-layer\";\nimport { useId } from \"@radix-ui/react-id\";\nimport * as PopperPrimitive from \"@radix-ui/react-popper\";\nimport { createPopperScope } from \"@radix-ui/react-popper\";\nimport { Portal as PortalPrimitive } from \"@radix-ui/react-portal\";\nimport { Presence } from \"@radix-ui/react-presence\";\nimport { Primitive } from \"@radix-ui/react-primitive\";\nimport { createSlottable } from \"@radix-ui/react-slot\";\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport * as VisuallyHiddenPrimitive from \"@radix-ui/react-visually-hidden\";\nimport { jsx, jsxs } from \"react/jsx-runtime\";\nvar [createTooltipContext, createTooltipScope] = createContextScope(\"Tooltip\", [\n createPopperScope\n]);\nvar usePopperScope = createPopperScope();\nvar PROVIDER_NAME = \"TooltipProvider\";\nvar DEFAULT_DELAY_DURATION = 700;\nvar TOOLTIP_OPEN = \"tooltip.open\";\nvar [TooltipProviderContextProvider, useTooltipProviderContext] = createTooltipContext(PROVIDER_NAME);\nvar TooltipProvider = (props) => {\n const {\n __scopeTooltip,\n delayDuration = DEFAULT_DELAY_DURATION,\n skipDelayDuration = 300,\n disableHoverableContent = false,\n children\n } = props;\n const isOpenDelayedRef = React.useRef(true);\n const isPointerInTransitRef = React.useRef(false);\n const skipDelayTimerRef = React.useRef(0);\n React.useEffect(() => {\n const skipDelayTimer = skipDelayTimerRef.current;\n return () => window.clearTimeout(skipDelayTimer);\n }, []);\n return /* @__PURE__ */ jsx(\n TooltipProviderContextProvider,\n {\n scope: __scopeTooltip,\n isOpenDelayedRef,\n delayDuration,\n onOpen: React.useCallback(() => {\n window.clearTimeout(skipDelayTimerRef.current);\n isOpenDelayedRef.current = false;\n }, []),\n onClose: React.useCallback(() => {\n window.clearTimeout(skipDelayTimerRef.current);\n skipDelayTimerRef.current = window.setTimeout(\n () => isOpenDelayedRef.current = true,\n skipDelayDuration\n );\n }, [skipDelayDuration]),\n isPointerInTransitRef,\n onPointerInTransitChange: React.useCallback((inTransit) => {\n isPointerInTransitRef.current = inTransit;\n }, []),\n disableHoverableContent,\n children\n }\n );\n};\nTooltipProvider.displayName = PROVIDER_NAME;\nvar TOOLTIP_NAME = \"Tooltip\";\nvar [TooltipContextProvider, useTooltipContext] = createTooltipContext(TOOLTIP_NAME);\nvar Tooltip = (props) => {\n const {\n __scopeTooltip,\n children,\n open: openProp,\n defaultOpen,\n onOpenChange,\n disableHoverableContent: disableHoverableContentProp,\n delayDuration: delayDurationProp\n } = props;\n const providerContext = useTooltipProviderContext(TOOLTIP_NAME, props.__scopeTooltip);\n const popperScope = usePopperScope(__scopeTooltip);\n const [trigger, setTrigger] = React.useState(null);\n const contentId = useId();\n const openTimerRef = React.useRef(0);\n const disableHoverableContent = disableHoverableContentProp ?? providerContext.disableHoverableContent;\n const delayDuration = delayDurationProp ?? providerContext.delayDuration;\n const wasOpenDelayedRef = React.useRef(false);\n const [open, setOpen] = useControllableState({\n prop: openProp,\n defaultProp: defaultOpen ?? false,\n onChange: (open2) => {\n if (open2) {\n providerContext.onOpen();\n document.dispatchEvent(new CustomEvent(TOOLTIP_OPEN));\n } else {\n providerContext.onClose();\n }\n onOpenChange?.(open2);\n },\n caller: TOOLTIP_NAME\n });\n const stateAttribute = React.useMemo(() => {\n return open ? wasOpenDelayedRef.current ? \"delayed-open\" : \"instant-open\" : \"closed\";\n }, [open]);\n const handleOpen = React.useCallback(() => {\n window.clearTimeout(openTimerRef.current);\n openTimerRef.current = 0;\n wasOpenDelayedRef.current = false;\n setOpen(true);\n }, [setOpen]);\n const handleClose = React.useCallback(() => {\n window.clearTimeout(openTimerRef.current);\n openTimerRef.current = 0;\n setOpen(false);\n }, [setOpen]);\n const handleDelayedOpen = React.useCallback(() => {\n window.clearTimeout(openTimerRef.current);\n openTimerRef.current = window.setTimeout(() => {\n wasOpenDelayedRef.current = true;\n setOpen(true);\n openTimerRef.current = 0;\n }, delayDuration);\n }, [delayDuration, setOpen]);\n React.useEffect(() => {\n return () => {\n if (openTimerRef.current) {\n window.clearTimeout(openTimerRef.current);\n openTimerRef.current = 0;\n }\n };\n }, []);\n return /* @__PURE__ */ jsx(PopperPrimitive.Root, { ...popperScope, children: /* @__PURE__ */ jsx(\n TooltipContextProvider,\n {\n scope: __scopeTooltip,\n contentId,\n open,\n stateAttribute,\n trigger,\n onTriggerChange: setTrigger,\n onTriggerEnter: React.useCallback(() => {\n if (providerContext.isOpenDelayedRef.current) handleDelayedOpen();\n else handleOpen();\n }, [providerContext.isOpenDelayedRef, handleDelayedOpen, handleOpen]),\n onTriggerLeave: React.useCallback(() => {\n if (disableHoverableContent) {\n handleClose();\n } else {\n window.clearTimeout(openTimerRef.current);\n openTimerRef.current = 0;\n }\n }, [handleClose, disableHoverableContent]),\n onOpen: handleOpen,\n onClose: handleClose,\n disableHoverableContent,\n children\n }\n ) });\n};\nTooltip.displayName = TOOLTIP_NAME;\nvar TRIGGER_NAME = \"TooltipTrigger\";\nvar TooltipTrigger = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeTooltip, ...triggerProps } = props;\n const context = useTooltipContext(TRIGGER_NAME, __scopeTooltip);\n const providerContext = useTooltipProviderContext(TRIGGER_NAME, __scopeTooltip);\n const popperScope = usePopperScope(__scopeTooltip);\n const ref = React.useRef(null);\n const composedRefs = useComposedRefs(forwardedRef, ref, context.onTriggerChange);\n const isPointerDownRef = React.useRef(false);\n const hasPointerMoveOpenedRef = React.useRef(false);\n const handlePointerUp = React.useCallback(() => isPointerDownRef.current = false, []);\n React.useEffect(() => {\n return () => document.removeEventListener(\"pointerup\", handlePointerUp);\n }, [handlePointerUp]);\n return /* @__PURE__ */ jsx(PopperPrimitive.Anchor, { asChild: true, ...popperScope, children: /* @__PURE__ */ jsx(\n Primitive.button,\n {\n \"aria-describedby\": context.open ? context.contentId : void 0,\n \"data-state\": context.stateAttribute,\n ...triggerProps,\n ref: composedRefs,\n onPointerMove: composeEventHandlers(props.onPointerMove, (event) => {\n if (event.pointerType === \"touch\") return;\n if (!hasPointerMoveOpenedRef.current && !providerContext.isPointerInTransitRef.current) {\n context.onTriggerEnter();\n hasPointerMoveOpenedRef.current = true;\n }\n }),\n onPointerLeave: composeEventHandlers(props.onPointerLeave, () => {\n context.onTriggerLeave();\n hasPointerMoveOpenedRef.current = false;\n }),\n onPointerDown: composeEventHandlers(props.onPointerDown, () => {\n if (context.open) {\n context.onClose();\n }\n isPointerDownRef.current = true;\n document.addEventListener(\"pointerup\", handlePointerUp, { once: true });\n }),\n onFocus: composeEventHandlers(props.onFocus, () => {\n if (!isPointerDownRef.current) context.onOpen();\n }),\n onBlur: composeEventHandlers(props.onBlur, context.onClose),\n onClick: composeEventHandlers(props.onClick, context.onClose)\n }\n ) });\n }\n);\nTooltipTrigger.displayName = TRIGGER_NAME;\nvar PORTAL_NAME = \"TooltipPortal\";\nvar [PortalProvider, usePortalContext] = createTooltipContext(PORTAL_NAME, {\n forceMount: void 0\n});\nvar TooltipPortal = (props) => {\n const { __scopeTooltip, forceMount, children, container } = props;\n const context = useTooltipContext(PORTAL_NAME, __scopeTooltip);\n return /* @__PURE__ */ jsx(PortalProvider, { scope: __scopeTooltip, forceMount, children: /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(PortalPrimitive, { asChild: true, container, children }) }) });\n};\nTooltipPortal.displayName = PORTAL_NAME;\nvar CONTENT_NAME = \"TooltipContent\";\nvar TooltipContent = React.forwardRef(\n (props, forwardedRef) => {\n const portalContext = usePortalContext(CONTENT_NAME, props.__scopeTooltip);\n const { forceMount = portalContext.forceMount, side = \"top\", ...contentProps } = props;\n const context = useTooltipContext(CONTENT_NAME, props.__scopeTooltip);\n return /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: context.disableHoverableContent ? /* @__PURE__ */ jsx(TooltipContentImpl, { side, ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx(TooltipContentHoverable, { side, ...contentProps, ref: forwardedRef }) });\n }\n);\nvar TooltipContentHoverable = React.forwardRef((props, forwardedRef) => {\n const context = useTooltipContext(CONTENT_NAME, props.__scopeTooltip);\n const providerContext = useTooltipProviderContext(CONTENT_NAME, props.__scopeTooltip);\n const ref = React.useRef(null);\n const composedRefs = useComposedRefs(forwardedRef, ref);\n const [pointerGraceArea, setPointerGraceArea] = React.useState(null);\n const { trigger, onClose } = context;\n const content = ref.current;\n const { onPointerInTransitChange } = providerContext;\n const handleRemoveGraceArea = React.useCallback(() => {\n setPointerGraceArea(null);\n onPointerInTransitChange(false);\n }, [onPointerInTransitChange]);\n const handleCreateGraceArea = React.useCallback(\n (event, hoverTarget) => {\n const currentTarget = event.currentTarget;\n const exitPoint = { x: event.clientX, y: event.clientY };\n const exitSide = getExitSideFromRect(exitPoint, currentTarget.getBoundingClientRect());\n const paddedExitPoints = getPaddedExitPoints(exitPoint, exitSide);\n const hoverTargetPoints = getPointsFromRect(hoverTarget.getBoundingClientRect());\n const graceArea = getHull([...paddedExitPoints, ...hoverTargetPoints]);\n setPointerGraceArea(graceArea);\n onPointerInTransitChange(true);\n },\n [onPointerInTransitChange]\n );\n React.useEffect(() => {\n return () => handleRemoveGraceArea();\n }, [handleRemoveGraceArea]);\n React.useEffect(() => {\n if (trigger && content) {\n const handleTriggerLeave = (event) => handleCreateGraceArea(event, content);\n const handleContentLeave = (event) => handleCreateGraceArea(event, trigger);\n trigger.addEventListener(\"pointerleave\", handleTriggerLeave);\n content.addEventListener(\"pointerleave\", handleContentLeave);\n return () => {\n trigger.removeEventListener(\"pointerleave\", handleTriggerLeave);\n content.removeEventListener(\"pointerleave\", handleContentLeave);\n };\n }\n }, [trigger, content, handleCreateGraceArea, handleRemoveGraceArea]);\n React.useEffect(() => {\n if (pointerGraceArea) {\n const handleTrackPointerGrace = (event) => {\n const target = event.target;\n const pointerPosition = { x: event.clientX, y: event.clientY };\n const hasEnteredTarget = trigger?.contains(target) || content?.contains(target);\n const isPointerOutsideGraceArea = !isPointInPolygon(pointerPosition, pointerGraceArea);\n if (hasEnteredTarget) {\n handleRemoveGraceArea();\n } else if (isPointerOutsideGraceArea) {\n handleRemoveGraceArea();\n onClose();\n }\n };\n document.addEventListener(\"pointermove\", handleTrackPointerGrace);\n return () => document.removeEventListener(\"pointermove\", handleTrackPointerGrace);\n }\n }, [trigger, content, pointerGraceArea, onClose, handleRemoveGraceArea]);\n return /* @__PURE__ */ jsx(TooltipContentImpl, { ...props, ref: composedRefs });\n});\nvar [VisuallyHiddenContentContextProvider, useVisuallyHiddenContentContext] = createTooltipContext(TOOLTIP_NAME, { isInside: false });\nvar Slottable = createSlottable(\"TooltipContent\");\nvar TooltipContentImpl = React.forwardRef(\n (props, forwardedRef) => {\n const {\n __scopeTooltip,\n children,\n \"aria-label\": ariaLabel,\n onEscapeKeyDown,\n onPointerDownOutside,\n ...contentProps\n } = props;\n const context = useTooltipContext(CONTENT_NAME, __scopeTooltip);\n const popperScope = usePopperScope(__scopeTooltip);\n const { onClose } = context;\n React.useEffect(() => {\n document.addEventListener(TOOLTIP_OPEN, onClose);\n return () => document.removeEventListener(TOOLTIP_OPEN, onClose);\n }, [onClose]);\n React.useEffect(() => {\n if (context.trigger) {\n const handleScroll = (event) => {\n const target = event.target;\n if (target?.contains(context.trigger)) onClose();\n };\n window.addEventListener(\"scroll\", handleScroll, { capture: true });\n return () => window.removeEventListener(\"scroll\", handleScroll, { capture: true });\n }\n }, [context.trigger, onClose]);\n return /* @__PURE__ */ jsx(\n DismissableLayer,\n {\n asChild: true,\n disableOutsidePointerEvents: false,\n onEscapeKeyDown,\n onPointerDownOutside,\n onFocusOutside: (event) => event.preventDefault(),\n onDismiss: onClose,\n children: /* @__PURE__ */ jsxs(\n PopperPrimitive.Content,\n {\n \"data-state\": context.stateAttribute,\n ...popperScope,\n ...contentProps,\n ref: forwardedRef,\n style: {\n ...contentProps.style,\n // re-namespace exposed content custom properties\n ...{\n \"--radix-tooltip-content-transform-origin\": \"var(--radix-popper-transform-origin)\",\n \"--radix-tooltip-content-available-width\": \"var(--radix-popper-available-width)\",\n \"--radix-tooltip-content-available-height\": \"var(--radix-popper-available-height)\",\n \"--radix-tooltip-trigger-width\": \"var(--radix-popper-anchor-width)\",\n \"--radix-tooltip-trigger-height\": \"var(--radix-popper-anchor-height)\"\n }\n },\n children: [\n /* @__PURE__ */ jsx(Slottable, { children }),\n /* @__PURE__ */ jsx(VisuallyHiddenContentContextProvider, { scope: __scopeTooltip, isInside: true, children: /* @__PURE__ */ jsx(VisuallyHiddenPrimitive.Root, { id: context.contentId, role: \"tooltip\", children: ariaLabel || children }) })\n ]\n }\n )\n }\n );\n }\n);\nTooltipContent.displayName = CONTENT_NAME;\nvar ARROW_NAME = \"TooltipArrow\";\nvar TooltipArrow = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeTooltip, ...arrowProps } = props;\n const popperScope = usePopperScope(__scopeTooltip);\n const visuallyHiddenContentContext = useVisuallyHiddenContentContext(\n ARROW_NAME,\n __scopeTooltip\n );\n return visuallyHiddenContentContext.isInside ? null : /* @__PURE__ */ jsx(PopperPrimitive.Arrow, { ...popperScope, ...arrowProps, ref: forwardedRef });\n }\n);\nTooltipArrow.displayName = ARROW_NAME;\nfunction getExitSideFromRect(point, rect) {\n const top = Math.abs(rect.top - point.y);\n const bottom = Math.abs(rect.bottom - point.y);\n const right = Math.abs(rect.right - point.x);\n const left = Math.abs(rect.left - point.x);\n switch (Math.min(top, bottom, right, left)) {\n case left:\n return \"left\";\n case right:\n return \"right\";\n case top:\n return \"top\";\n case bottom:\n return \"bottom\";\n default:\n throw new Error(\"unreachable\");\n }\n}\nfunction getPaddedExitPoints(exitPoint, exitSide, padding = 5) {\n const paddedExitPoints = [];\n switch (exitSide) {\n case \"top\":\n paddedExitPoints.push(\n { x: exitPoint.x - padding, y: exitPoint.y + padding },\n { x: exitPoint.x + padding, y: exitPoint.y + padding }\n );\n break;\n case \"bottom\":\n paddedExitPoints.push(\n { x: exitPoint.x - padding, y: exitPoint.y - padding },\n { x: exitPoint.x + padding, y: exitPoint.y - padding }\n );\n break;\n case \"left\":\n paddedExitPoints.push(\n { x: exitPoint.x + padding, y: exitPoint.y - padding },\n { x: exitPoint.x + padding, y: exitPoint.y + padding }\n );\n break;\n case \"right\":\n paddedExitPoints.push(\n { x: exitPoint.x - padding, y: exitPoint.y - padding },\n { x: exitPoint.x - padding, y: exitPoint.y + padding }\n );\n break;\n }\n return paddedExitPoints;\n}\nfunction getPointsFromRect(rect) {\n const { top, right, bottom, left } = rect;\n return [\n { x: left, y: top },\n { x: right, y: top },\n { x: right, y: bottom },\n { x: left, y: bottom }\n ];\n}\nfunction isPointInPolygon(point, polygon) {\n const { x, y } = point;\n let inside = false;\n for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n const ii = polygon[i];\n const jj = polygon[j];\n const xi = ii.x;\n const yi = ii.y;\n const xj = jj.x;\n const yj = jj.y;\n const intersect = yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi) + xi;\n if (intersect) inside = !inside;\n }\n return inside;\n}\nfunction getHull(points) {\n const newPoints = points.slice();\n newPoints.sort((a, b) => {\n if (a.x < b.x) return -1;\n else if (a.x > b.x) return 1;\n else if (a.y < b.y) return -1;\n else if (a.y > b.y) return 1;\n else return 0;\n });\n return getHullPresorted(newPoints);\n}\nfunction getHullPresorted(points) {\n if (points.length <= 1) return points.slice();\n const upperHull = [];\n for (let i = 0; i < points.length; i++) {\n const p = points[i];\n while (upperHull.length >= 2) {\n const q = upperHull[upperHull.length - 1];\n const r = upperHull[upperHull.length - 2];\n if ((q.x - r.x) * (p.y - r.y) >= (q.y - r.y) * (p.x - r.x)) upperHull.pop();\n else break;\n }\n upperHull.push(p);\n }\n upperHull.pop();\n const lowerHull = [];\n for (let i = points.length - 1; i >= 0; i--) {\n const p = points[i];\n while (lowerHull.length >= 2) {\n const q = lowerHull[lowerHull.length - 1];\n const r = lowerHull[lowerHull.length - 2];\n if ((q.x - r.x) * (p.y - r.y) >= (q.y - r.y) * (p.x - r.x)) lowerHull.pop();\n else break;\n }\n lowerHull.push(p);\n }\n lowerHull.pop();\n if (upperHull.length === 1 && lowerHull.length === 1 && upperHull[0].x === lowerHull[0].x && upperHull[0].y === lowerHull[0].y) {\n return upperHull;\n } else {\n return upperHull.concat(lowerHull);\n }\n}\nvar Provider = TooltipProvider;\nvar Root3 = Tooltip;\nvar Trigger = TooltipTrigger;\nvar Portal = TooltipPortal;\nvar Content2 = TooltipContent;\nvar Arrow2 = TooltipArrow;\nexport {\n Arrow2 as Arrow,\n Content2 as Content,\n Portal,\n Provider,\n Root3 as Root,\n Tooltip,\n TooltipArrow,\n TooltipContent,\n TooltipPortal,\n TooltipProvider,\n TooltipTrigger,\n Trigger,\n createTooltipScope\n};\n//# sourceMappingURL=index.mjs.map\n","import * as React from \"react\";\r\n\r\nexport type TooltipVariants = {\r\n\tfocus?: \"high\";\r\n};\r\n\r\nexport const TooltipContext = React.createContext<TooltipVariants>({});\r\n\r\nexport const useTooltipContext = () => {\r\n\tconst context = React.useContext(TooltipContext);\r\n\treturn context;\r\n};\r\n","import * as React from \"react\";\r\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\";\r\nimport { tv } from \"tailwind-variants\";\r\nimport { Icon, IconProps } from \"../icon/Icon\";\r\nimport { Shortcut } from \"../shortcut\";\r\nimport { usePortalContainer } from \"../portal-container\";\r\nimport { VariantsConfig } from \"@/lib/utils/variants\";\r\nimport { TooltipContext, TooltipVariants, useTooltipContext } from \"./useTooltipContext\";\r\nimport { Text } from \"@/components/text\";\r\n\r\nconst TooltipProvider = TooltipPrimitive.Provider;\r\n\r\nconst Tooltip = TooltipPrimitive.Root;\r\n\r\nconst TooltipTrigger = TooltipPrimitive.Trigger;\r\n\r\nconst tooltipArrowStyles = tv({\r\n\tslots: {\r\n\t\tfill: \"fill-status-neutral-fg\",\r\n\t\tstroke: \"stroke-primary-border stroke-[0.5px]\",\r\n\t\tsvg: \"rotate-180\"\r\n\t},\r\n\tvariants: {\r\n\t\tfocus: {\r\n\t\t\thigh: {\r\n\t\t\t\tfill: \"fill-alpha-high-20\",\r\n\t\t\t\tstroke: \"stroke-none\"\r\n\t\t\t}\r\n\t\t}\r\n\t} satisfies VariantsConfig<TooltipVariants>\r\n});\r\n\r\ntype TooltipArrowProps = React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Arrow>;\r\n\r\nconst TooltipArrow = React.forwardRef<React.ElementRef<typeof TooltipPrimitive.Arrow>, TooltipArrowProps>(\r\n\t({ width, height, className, ...props }, ref) => {\r\n\t\tconst { focus } = useTooltipContext();\r\n\t\tconst styles = tooltipArrowStyles({ focus });\r\n\r\n\t\treturn (\r\n\t\t\t<TooltipPrimitive.Arrow ref={ref} asChild {...props}>\r\n\t\t\t\t<svg\r\n\t\t\t\t\twidth={width || \"10\"}\r\n\t\t\t\t\theight={height || \"5\"}\r\n\t\t\t\t\tviewBox=\"0 0 10 5\"\r\n\t\t\t\t\tfill=\"none\"\r\n\t\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\r\n\t\t\t\t\tclassName={styles.svg({ className })}\r\n\t\t\t\t>\r\n\t\t\t\t\t<path d=\"M5.00082 0.248638L10 5.99523L0 6.00001L5.00082 0.248638Z\" className={styles.fill()} />\r\n\t\t\t\t\t<path\r\n\t\t\t\t\t\td=\"M9.57422 5.25L5.37732 0.433047C5.17793 0.204195 4.82228 0.204345 4.62308 0.433365L0.433594 5.25\"\r\n\t\t\t\t\t\tclassName={styles.stroke()}\r\n\t\t\t\t\t\tstrokeLinecap=\"round\"\r\n\t\t\t\t\t/>\r\n\t\t\t\t</svg>\r\n\t\t\t</TooltipPrimitive.Arrow>\r\n\t\t);\r\n\t}\r\n);\r\n\r\nTooltipArrow.displayName = TooltipPrimitive.Arrow.displayName;\r\n\r\nconst tooltipContentStyles = tv({\r\n\tbase: [\r\n\t\t\"z-50 rounded-lg border-[0.5px] px-2 py-1.5 text-xs backdrop-blur animate-in fade-in-0 zoom-in-95\",\r\n\t\t\"border-primary-border bg-alpha-30 text-primary-fg shadow-soft-sm\",\r\n\t\t\"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95\",\r\n\t\t\"data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\"\r\n\t],\r\n\tvariants: {\r\n\t\tfocus: {\r\n\t\t\thigh: \"border-0 bg-alpha-high-20 text-inverse-primary-fg shadow-soft-base\"\r\n\t\t}\r\n\t} satisfies VariantsConfig<TooltipVariants>\r\n});\r\n\r\nexport type TooltipContentProps = React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content> &\r\n\tTooltipVariants & {\r\n\t\t/**\r\n\t\t * Контейнер для портала. Если не указан, используется хук usePortalContainer\r\n\t\t * для поиска PortalContainer\r\n\t\t */\r\n\t\tportalContainer?: HTMLElement;\r\n\t};\r\n\r\nconst TooltipContent = React.forwardRef<React.ElementRef<typeof TooltipPrimitive.Content>, TooltipContentProps>(\r\n\t({ className, sideOffset = 8, portalContainer, focus, ...props }, ref) => {\r\n\t\tconst container = usePortalContainer(portalContainer);\r\n\r\n\t\treturn (\r\n\t\t\t<TooltipContext.Provider value={{ focus }}>\r\n\t\t\t\t<TooltipPrimitive.Portal container={container}>\r\n\t\t\t\t\t<TooltipPrimitive.Content\r\n\t\t\t\t\t\tref={ref}\r\n\t\t\t\t\t\tsideOffset={sideOffset}\r\n\t\t\t\t\t\tclassName={tooltipContentStyles({ className, focus })}\r\n\t\t\t\t\t\t{...props}\r\n\t\t\t\t\t/>\r\n\t\t\t\t</TooltipPrimitive.Portal>\r\n\t\t\t</TooltipContext.Provider>\r\n\t\t);\r\n\t}\r\n);\r\nTooltipContent.displayName = TooltipPrimitive.Content.displayName;\r\n\r\nconst tooltipTitleStyles = tv({\r\n\tbase: \"text-sm font-medium text-primary-fg\",\r\n\tvariants: {\r\n\t\tfocus: {\r\n\t\t\thigh: \"text-inverse-primary-fg\"\r\n\t\t}\r\n\t} satisfies VariantsConfig<TooltipVariants>\r\n});\r\n\r\ntype TooltipTitleProps = React.HTMLAttributes<HTMLDivElement>;\r\n\r\nconst TooltipTitle = React.forwardRef<HTMLDivElement, TooltipTitleProps>(({ className, children, ...props }, ref) => {\r\n\tconst { focus } = useTooltipContext();\r\n\treturn (\r\n\t\t<div ref={ref} className={tooltipTitleStyles({ className, focus })} {...props}>\r\n\t\t\t{children}\r\n\t\t</div>\r\n\t);\r\n});\r\nTooltipTitle.displayName = \"TooltipTitle\";\r\n\r\nconst tooltipTextStyles = tv({\r\n\tbase: \"\",\r\n\tvariants: {\r\n\t\tfocus: {\r\n\t\t\thigh: \"text-inverse-secondary-fg\"\r\n\t\t}\r\n\t} satisfies VariantsConfig<TooltipVariants>\r\n});\r\n\r\ntype TooltipTextProps = React.HTMLAttributes<HTMLDivElement>;\r\n\r\nconst TooltipText = React.forwardRef<HTMLDivElement, TooltipTextProps>(({ className, children, ...props }, ref) => {\r\n\tconst { focus } = useTooltipContext();\r\n\treturn (\r\n\t\t<Text ref={ref} size=\"xs\" className={tooltipTextStyles({ className, focus })} {...props}>\r\n\t\t\t{children}\r\n\t\t</Text>\r\n\t);\r\n});\r\nTooltipText.displayName = \"TooltipText\";\r\n\r\nconst tooltipIconStyles = tv({\r\n\tbase: \"shrink-0 text-xs text-primary-fg\",\r\n\tvariants: {\r\n\t\tfocus: {\r\n\t\t\thigh: \"text-inverse-primary-fg\"\r\n\t\t}\r\n\t} satisfies VariantsConfig<TooltipVariants>\r\n});\r\n\r\ntype TooltipIconProps = IconProps;\r\n\r\nconst TooltipIcon = React.forwardRef<SVGSVGElement, TooltipIconProps>(({ className, ...props }, ref) => {\r\n\tconst { focus } = useTooltipContext();\r\n\treturn <Icon size=\"lg\" className={tooltipIconStyles({ className, focus })} ref={ref} {...props} />;\r\n});\r\nTooltipIcon.displayName = \"TooltipIcon\";\r\n\r\nconst tooltipShortcutStyles = tv({\r\n\tbase: \"h-auto p-0 text-xs text-muted\",\r\n\tvariants: {\r\n\t\tfocus: {\r\n\t\t\thigh: \"text-inverse-secondary-fg opacity-70\"\r\n\t\t}\r\n\t} satisfies VariantsConfig<TooltipVariants>\r\n});\r\n\r\ntype TooltipShortcutProps = React.HTMLAttributes<HTMLDivElement>;\r\n\r\nconst TooltipShortcut = React.forwardRef<HTMLDivElement, TooltipShortcutProps>(({ className, ...props }, ref) => {\r\n\tconst { focus } = useTooltipContext();\r\n\treturn <Shortcut variant=\"ghost\" className={tooltipShortcutStyles({ className, focus })} ref={ref} {...props} />;\r\n});\r\nTooltipShortcut.displayName = \"TooltipShortcut\";\r\n\r\nexport {\r\n\tTooltip,\r\n\tTooltipTrigger,\r\n\tTooltipContent,\r\n\tTooltipArrow,\r\n\tTooltipProvider,\r\n\tTooltipTitle,\r\n\tTooltipText,\r\n\tTooltipIcon,\r\n\tTooltipShortcut\r\n};\r\n"],"names":["createTooltipContext","createTooltipScope","createContextScope","createPopperScope","usePopperScope","PROVIDER_NAME","DEFAULT_DELAY_DURATION","TOOLTIP_OPEN","TooltipProviderContextProvider","useTooltipProviderContext","TooltipProvider","props","__scopeTooltip","delayDuration","skipDelayDuration","disableHoverableContent","children","isOpenDelayedRef","React","isPointerInTransitRef","skipDelayTimerRef","skipDelayTimer","jsx","inTransit","TOOLTIP_NAME","TooltipContextProvider","useTooltipContext","Tooltip","openProp","defaultOpen","onOpenChange","disableHoverableContentProp","delayDurationProp","providerContext","popperScope","trigger","setTrigger","contentId","useId","openTimerRef","wasOpenDelayedRef","open","setOpen","useControllableState","open2","stateAttribute","handleOpen","handleClose","handleDelayedOpen","PopperPrimitive.Root","TRIGGER_NAME","TooltipTrigger","forwardedRef","triggerProps","context","ref","composedRefs","useComposedRefs","isPointerDownRef","hasPointerMoveOpenedRef","handlePointerUp","PopperPrimitive.Anchor","Primitive","composeEventHandlers","event","PORTAL_NAME","PortalProvider","usePortalContext","TooltipPortal","forceMount","container","Presence","PortalPrimitive","CONTENT_NAME","TooltipContent","portalContext","side","contentProps","TooltipContentImpl","TooltipContentHoverable","pointerGraceArea","setPointerGraceArea","onClose","content","onPointerInTransitChange","handleRemoveGraceArea","handleCreateGraceArea","hoverTarget","currentTarget","exitPoint","exitSide","getExitSideFromRect","paddedExitPoints","getPaddedExitPoints","hoverTargetPoints","getPointsFromRect","graceArea","getHull","handleTriggerLeave","handleContentLeave","handleTrackPointerGrace","target","pointerPosition","hasEnteredTarget","isPointerOutsideGraceArea","isPointInPolygon","VisuallyHiddenContentContextProvider","useVisuallyHiddenContentContext","Slottable","createSlottable","ariaLabel","onEscapeKeyDown","onPointerDownOutside","handleScroll","DismissableLayer","jsxs","PopperPrimitive.Content","VisuallyHiddenPrimitive.Root","ARROW_NAME","TooltipArrow","arrowProps","PopperPrimitive.Arrow","point","rect","top","bottom","right","left","padding","polygon","x","y","inside","j","ii","jj","xi","yi","xj","yj","points","newPoints","a","b","getHullPresorted","upperHull","i","p","q","r","lowerHull","Provider","Root3","Trigger","Portal","Content2","Arrow2","TooltipContext","TooltipPrimitive.Provider","TooltipPrimitive.Root","TooltipPrimitive.Trigger","tooltipArrowStyles","tv","width","height","className","focus","styles","TooltipPrimitive.Arrow","tooltipContentStyles","sideOffset","portalContainer","usePortalContainer","TooltipPrimitive.Portal","TooltipPrimitive.Content","tooltipTitleStyles","TooltipTitle","tooltipTextStyles","TooltipText","Text","tooltipIconStyles","TooltipIcon","Icon","tooltipShortcutStyles","TooltipShortcut","Shortcut"],"mappings":";;;;;;;;;;;;;;;;AAkBA,IAAI,CAACA,GAAsBC,EAAkB,IAAIC,GAAmB,WAAW;AAAA,EAC7EC;AACF,CAAC,GACGC,IAAiBD,EAAmB,GACpCE,IAAgB,mBAChBC,KAAyB,KACzBC,IAAe,gBACf,CAACC,IAAgCC,CAAyB,IAAIT,EAAqBK,CAAa,GAChGK,IAAkB,CAACC,MAAU;AAC/B,QAAM;AAAA,IACJ,gBAAAC;AAAA,IACA,eAAAC,IAAgBP;AAAA,IAChB,mBAAAQ,IAAoB;AAAA,IACpB,yBAAAC,IAA0B;AAAA,IAC1B,UAAAC;AAAA,EACJ,IAAML,GACEM,IAAmBC,EAAM,OAAO,EAAI,GACpCC,IAAwBD,EAAM,OAAO,EAAK,GAC1CE,IAAoBF,EAAM,OAAO,CAAC;AACxC,SAAAA,EAAM,UAAU,MAAM;AACpB,UAAMG,IAAiBD,EAAkB;AACzC,WAAO,MAAM,OAAO,aAAaC,CAAc;AAAA,EAChD,GAAE,EAAE,GACkB,gBAAAC;AAAA,IACrBd;AAAA,IACA;AAAA,MACE,OAAOI;AAAA,MACP,kBAAAK;AAAA,MACA,eAAAJ;AAAA,MACA,QAAQK,EAAM,YAAY,MAAM;AAC9B,eAAO,aAAaE,EAAkB,OAAO,GAC7CH,EAAiB,UAAU;AAAA,MAC5B,GAAE,EAAE;AAAA,MACL,SAASC,EAAM,YAAY,MAAM;AAC/B,eAAO,aAAaE,EAAkB,OAAO,GAC7CA,EAAkB,UAAU,OAAO;AAAA,UACjC,MAAMH,EAAiB,UAAU;AAAA,UACjCH;AAAA,QACD;AAAA,MACT,GAAS,CAACA,CAAiB,CAAC;AAAA,MACtB,uBAAAK;AAAA,MACA,0BAA0BD,EAAM,YAAY,CAACK,MAAc;AACzD,QAAAJ,EAAsB,UAAUI;AAAA,MACjC,GAAE,EAAE;AAAA,MACL,yBAAAR;AAAA,MACA,UAAAC;AAAA,IACN;AAAA,EACG;AACH;AACAN,EAAgB,cAAcL;AAC9B,IAAImB,IAAe,WACf,CAACC,IAAwBC,CAAiB,IAAI1B,EAAqBwB,CAAY,GAC/EG,IAAU,CAAChB,MAAU;AACvB,QAAM;AAAA,IACJ,gBAAAC;AAAA,IACA,UAAAI;AAAA,IACA,MAAMY;AAAA,IACN,aAAAC;AAAA,IACA,cAAAC;AAAA,IACA,yBAAyBC;AAAA,IACzB,eAAeC;AAAA,EACnB,IAAMrB,GACEsB,IAAkBxB,EAA0Be,GAAcb,EAAM,cAAc,GAC9EuB,IAAc9B,EAAeQ,CAAc,GAC3C,CAACuB,GAASC,CAAU,IAAIlB,EAAM,SAAS,IAAI,GAC3CmB,IAAYC,GAAO,GACnBC,IAAerB,EAAM,OAAO,CAAC,GAC7BH,IAA0BgB,KAA+BE,EAAgB,yBACzEpB,IAAgBmB,KAAqBC,EAAgB,eACrDO,IAAoBtB,EAAM,OAAO,EAAK,GACtC,CAACuB,GAAMC,CAAO,IAAIC,GAAqB;AAAA,IAC3C,MAAMf;AAAA,IACN,aAAaC,KAAe;AAAA,IAC5B,UAAU,CAACe,MAAU;AACnB,MAAIA,KACFX,EAAgB,OAAQ,GACxB,SAAS,cAAc,IAAI,YAAY1B,CAAY,CAAC,KAEpD0B,EAAgB,QAAS,GAE3BH,IAAec,CAAK;AAAA,IACrB;AAAA,IACD,QAAQpB;AAAA,EACZ,CAAG,GACKqB,IAAiB3B,EAAM,QAAQ,MAC5BuB,IAAOD,EAAkB,UAAU,iBAAiB,iBAAiB,UAC3E,CAACC,CAAI,CAAC,GACHK,IAAa5B,EAAM,YAAY,MAAM;AACzC,WAAO,aAAaqB,EAAa,OAAO,GACxCA,EAAa,UAAU,GACvBC,EAAkB,UAAU,IAC5BE,EAAQ,EAAI;AAAA,EAChB,GAAK,CAACA,CAAO,CAAC,GACNK,IAAc7B,EAAM,YAAY,MAAM;AAC1C,WAAO,aAAaqB,EAAa,OAAO,GACxCA,EAAa,UAAU,GACvBG,EAAQ,EAAK;AAAA,EACjB,GAAK,CAACA,CAAO,CAAC,GACNM,IAAoB9B,EAAM,YAAY,MAAM;AAChD,WAAO,aAAaqB,EAAa,OAAO,GACxCA,EAAa,UAAU,OAAO,WAAW,MAAM;AAC7C,MAAAC,EAAkB,UAAU,IAC5BE,EAAQ,EAAI,GACZH,EAAa,UAAU;AAAA,IACxB,GAAE1B,CAAa;AAAA,EACpB,GAAK,CAACA,GAAe6B,CAAO,CAAC;AAC3B,SAAAxB,EAAM,UAAU,MACP,MAAM;AACX,IAAIqB,EAAa,YACf,OAAO,aAAaA,EAAa,OAAO,GACxCA,EAAa,UAAU;AAAA,EAE1B,GACA,EAAE,GACkB,gBAAAjB,EAAI2B,IAAsB,EAAE,GAAGf,GAAa,UAA0B,gBAAAZ;AAAA,IAC3FG;AAAA,IACA;AAAA,MACE,OAAOb;AAAA,MACP,WAAAyB;AAAA,MACA,MAAAI;AAAA,MACA,gBAAAI;AAAA,MACA,SAAAV;AAAA,MACA,iBAAiBC;AAAA,MACjB,gBAAgBlB,EAAM,YAAY,MAAM;AACtC,QAAIe,EAAgB,iBAAiB,UAASe,EAAmB,IAC5DF,EAAY;AAAA,MAClB,GAAE,CAACb,EAAgB,kBAAkBe,GAAmBF,CAAU,CAAC;AAAA,MACpE,gBAAgB5B,EAAM,YAAY,MAAM;AACtC,QAAIH,IACFgC,EAAa,KAEb,OAAO,aAAaR,EAAa,OAAO,GACxCA,EAAa,UAAU;AAAA,MAEjC,GAAS,CAACQ,GAAahC,CAAuB,CAAC;AAAA,MACzC,QAAQ+B;AAAA,MACR,SAASC;AAAA,MACT,yBAAAhC;AAAA,MACA,UAAAC;AAAA,IACN;AAAA,EACA,GAAK;AACL;AACAW,EAAQ,cAAcH;AACtB,IAAI0B,IAAe,kBACfC,IAAiBjC,EAAM;AAAA,EACzB,CAACP,GAAOyC,MAAiB;AACvB,UAAM,EAAE,gBAAAxC,GAAgB,GAAGyC,EAAY,IAAK1C,GACtC2C,IAAU5B,EAAkBwB,GAActC,CAAc,GACxDqB,IAAkBxB,EAA0ByC,GAActC,CAAc,GACxEsB,IAAc9B,EAAeQ,CAAc,GAC3C2C,IAAMrC,EAAM,OAAO,IAAI,GACvBsC,IAAeC,EAAgBL,GAAcG,GAAKD,EAAQ,eAAe,GACzEI,IAAmBxC,EAAM,OAAO,EAAK,GACrCyC,IAA0BzC,EAAM,OAAO,EAAK,GAC5C0C,IAAkB1C,EAAM,YAAY,MAAMwC,EAAiB,UAAU,IAAO,EAAE;AACpF,WAAAxC,EAAM,UAAU,MACP,MAAM,SAAS,oBAAoB,aAAa0C,CAAe,GACrE,CAACA,CAAe,CAAC,GACG,gBAAAtC,EAAIuC,IAAwB,EAAE,SAAS,IAAM,GAAG3B,GAAa,UAA0B,gBAAAZ;AAAA,MAC5GwC,GAAU;AAAA,MACV;AAAA,QACE,oBAAoBR,EAAQ,OAAOA,EAAQ,YAAY;AAAA,QACvD,cAAcA,EAAQ;AAAA,QACtB,GAAGD;AAAA,QACH,KAAKG;AAAA,QACL,eAAeO,EAAqBpD,EAAM,eAAe,CAACqD,MAAU;AAClE,UAAIA,EAAM,gBAAgB,WACtB,CAACL,EAAwB,WAAW,CAAC1B,EAAgB,sBAAsB,YAC7EqB,EAAQ,eAAgB,GACxBK,EAAwB,UAAU;AAAA,QAE9C,CAAS;AAAA,QACD,gBAAgBI,EAAqBpD,EAAM,gBAAgB,MAAM;AAC/D,UAAA2C,EAAQ,eAAgB,GACxBK,EAAwB,UAAU;AAAA,QAC5C,CAAS;AAAA,QACD,eAAeI,EAAqBpD,EAAM,eAAe,MAAM;AAC7D,UAAI2C,EAAQ,QACVA,EAAQ,QAAS,GAEnBI,EAAiB,UAAU,IAC3B,SAAS,iBAAiB,aAAaE,GAAiB,EAAE,MAAM,IAAM;AAAA,QAChF,CAAS;AAAA,QACD,SAASG,EAAqBpD,EAAM,SAAS,MAAM;AACjD,UAAK+C,EAAiB,WAASJ,EAAQ,OAAQ;AAAA,QACzD,CAAS;AAAA,QACD,QAAQS,EAAqBpD,EAAM,QAAQ2C,EAAQ,OAAO;AAAA,QAC1D,SAASS,EAAqBpD,EAAM,SAAS2C,EAAQ,OAAO;AAAA,MACpE;AAAA,IACA,GAAO;AAAA,EACP;AACA;AACAH,EAAe,cAAcD;AAC7B,IAAIe,IAAc,iBACd,CAACC,IAAgBC,EAAgB,IAAInE,EAAqBiE,GAAa;AAAA,EACzE,YAAY;AACd,CAAC,GACGG,IAAgB,CAACzD,MAAU;AAC7B,QAAM,EAAE,gBAAAC,GAAgB,YAAAyD,GAAY,UAAArD,GAAU,WAAAsD,EAAW,IAAG3D,GACtD2C,IAAU5B,EAAkBuC,GAAarD,CAAc;AAC7D,SAAuB,gBAAAU,EAAI4C,IAAgB,EAAE,OAAOtD,GAAgB,YAAAyD,GAAY,UAA0B,gBAAA/C,EAAIiD,GAAU,EAAE,SAASF,KAAcf,EAAQ,MAAM,UAA0B,gBAAAhC,EAAIkD,IAAiB,EAAE,SAAS,IAAM,WAAAF,GAAW,UAAAtD,GAAU,EAAC,CAAE,EAAC,CAAE;AAC5P;AACAoD,EAAc,cAAcH;AAC5B,IAAIQ,IAAe,kBACfC,IAAiBxD,EAAM;AAAA,EACzB,CAACP,GAAOyC,MAAiB;AACvB,UAAMuB,IAAgBR,GAAiBM,GAAc9D,EAAM,cAAc,GACnE,EAAE,YAAA0D,IAAaM,EAAc,YAAY,MAAAC,IAAO,OAAO,GAAGC,EAAY,IAAKlE,GAC3E2C,IAAU5B,EAAkB+C,GAAc9D,EAAM,cAAc;AACpE,WAAuB,gBAAAW,EAAIiD,GAAU,EAAE,SAASF,KAAcf,EAAQ,MAAM,UAAUA,EAAQ,0BAA0C,gBAAAhC,EAAIwD,GAAoB,EAAE,MAAAF,GAAM,GAAGC,GAAc,KAAKzB,GAAc,IAAoB,gBAAA9B,EAAIyD,IAAyB,EAAE,MAAAH,GAAM,GAAGC,GAAc,KAAKzB,EAAY,CAAE,EAAC,CAAE;AAAA,EAChT;AACA,GACI2B,KAA0B7D,EAAM,WAAW,CAACP,GAAOyC,MAAiB;AACtE,QAAME,IAAU5B,EAAkB+C,GAAc9D,EAAM,cAAc,GAC9DsB,IAAkBxB,EAA0BgE,GAAc9D,EAAM,cAAc,GAC9E4C,IAAMrC,EAAM,OAAO,IAAI,GACvBsC,IAAeC,EAAgBL,GAAcG,CAAG,GAChD,CAACyB,GAAkBC,CAAmB,IAAI/D,EAAM,SAAS,IAAI,GAC7D,EAAE,SAAAiB,GAAS,SAAA+C,EAAO,IAAK5B,GACvB6B,IAAU5B,EAAI,SACd,EAAE,0BAAA6B,EAAwB,IAAKnD,GAC/BoD,IAAwBnE,EAAM,YAAY,MAAM;AACpD,IAAA+D,EAAoB,IAAI,GACxBG,EAAyB,EAAK;AAAA,EAClC,GAAK,CAACA,CAAwB,CAAC,GACvBE,IAAwBpE,EAAM;AAAA,IAClC,CAAC8C,GAAOuB,MAAgB;AACtB,YAAMC,IAAgBxB,EAAM,eACtByB,IAAY,EAAE,GAAGzB,EAAM,SAAS,GAAGA,EAAM,QAAS,GAClD0B,IAAWC,GAAoBF,GAAWD,EAAc,sBAAqB,CAAE,GAC/EI,IAAmBC,GAAoBJ,GAAWC,CAAQ,GAC1DI,IAAoBC,GAAkBR,EAAY,sBAAqB,CAAE,GACzES,IAAYC,GAAQ,CAAC,GAAGL,GAAkB,GAAGE,CAAiB,CAAC;AACrE,MAAAb,EAAoBe,CAAS,GAC7BZ,EAAyB,EAAI;AAAA,IAC9B;AAAA,IACD,CAACA,CAAwB;AAAA,EAC1B;AACD,SAAAlE,EAAM,UAAU,MACP,MAAMmE,EAAuB,GACnC,CAACA,CAAqB,CAAC,GAC1BnE,EAAM,UAAU,MAAM;AACpB,QAAIiB,KAAWgD,GAAS;AACtB,YAAMe,IAAqB,CAAClC,MAAUsB,EAAsBtB,GAAOmB,CAAO,GACpEgB,IAAqB,CAACnC,MAAUsB,EAAsBtB,GAAO7B,CAAO;AAC1E,aAAAA,EAAQ,iBAAiB,gBAAgB+D,CAAkB,GAC3Df,EAAQ,iBAAiB,gBAAgBgB,CAAkB,GACpD,MAAM;AACX,QAAAhE,EAAQ,oBAAoB,gBAAgB+D,CAAkB,GAC9Df,EAAQ,oBAAoB,gBAAgBgB,CAAkB;AAAA,MAC/D;AAAA,IACP;AAAA,EACG,GAAE,CAAChE,GAASgD,GAASG,GAAuBD,CAAqB,CAAC,GACnEnE,EAAM,UAAU,MAAM;AACpB,QAAI8D,GAAkB;AACpB,YAAMoB,IAA0B,CAACpC,MAAU;AACzC,cAAMqC,IAASrC,EAAM,QACfsC,IAAkB,EAAE,GAAGtC,EAAM,SAAS,GAAGA,EAAM,QAAS,GACxDuC,IAAmBpE,GAAS,SAASkE,CAAM,KAAKlB,GAAS,SAASkB,CAAM,GACxEG,IAA4B,CAACC,GAAiBH,GAAiBtB,CAAgB;AACrF,QAAIuB,IACFlB,EAAuB,IACdmB,MACTnB,EAAuB,GACvBH,EAAS;AAAA,MAEZ;AACD,sBAAS,iBAAiB,eAAekB,CAAuB,GACzD,MAAM,SAAS,oBAAoB,eAAeA,CAAuB;AAAA,IACtF;AAAA,EACA,GAAK,CAACjE,GAASgD,GAASH,GAAkBE,GAASG,CAAqB,CAAC,GAChD,gBAAA/D,EAAIwD,GAAoB,EAAE,GAAGnE,GAAO,KAAK6C,GAAc;AAChF,CAAC,GACG,CAACkD,IAAsCC,EAA+B,IAAI3G,EAAqBwB,GAAc,EAAE,UAAU,IAAO,GAChIoF,KAAYC,GAAgB,gBAAgB,GAC5C/B,IAAqB5D,EAAM;AAAA,EAC7B,CAACP,GAAOyC,MAAiB;AACvB,UAAM;AAAA,MACJ,gBAAAxC;AAAA,MACA,UAAAI;AAAA,MACA,cAAc8F;AAAA,MACd,iBAAAC;AAAA,MACA,sBAAAC;AAAA,MACA,GAAGnC;AAAA,IACT,IAAQlE,GACE2C,IAAU5B,EAAkB+C,GAAc7D,CAAc,GACxDsB,IAAc9B,EAAeQ,CAAc,GAC3C,EAAE,SAAAsE,EAAO,IAAK5B;AACpB,WAAApC,EAAM,UAAU,OACd,SAAS,iBAAiBX,GAAc2E,CAAO,GACxC,MAAM,SAAS,oBAAoB3E,GAAc2E,CAAO,IAC9D,CAACA,CAAO,CAAC,GACZhE,EAAM,UAAU,MAAM;AACpB,UAAIoC,EAAQ,SAAS;AACnB,cAAM2D,IAAe,CAACjD,MAAU;AAE9B,UADeA,EAAM,QACT,SAASV,EAAQ,OAAO,KAAG4B,EAAS;AAAA,QACjD;AACD,sBAAO,iBAAiB,UAAU+B,GAAc,EAAE,SAAS,IAAM,GAC1D,MAAM,OAAO,oBAAoB,UAAUA,GAAc,EAAE,SAAS,IAAM;AAAA,MACzF;AAAA,IACK,GAAE,CAAC3D,EAAQ,SAAS4B,CAAO,CAAC,GACN,gBAAA5D;AAAA,MACrB4F;AAAA,MACA;AAAA,QACE,SAAS;AAAA,QACT,6BAA6B;AAAA,QAC7B,iBAAAH;AAAA,QACA,sBAAAC;AAAA,QACA,gBAAgB,CAAChD,MAAUA,EAAM,eAAgB;AAAA,QACjD,WAAWkB;AAAA,QACX,UAA0B,gBAAAiC;AAAA,UACxBC;AAAAA,UACA;AAAA,YACE,cAAc9D,EAAQ;AAAA,YACtB,GAAGpB;AAAA,YACH,GAAG2C;AAAA,YACH,KAAKzB;AAAA,YACL,OAAO;AAAA,cACL,GAAGyB,EAAa;AAAA,cAGd,4CAA4C;AAAA,cAC5C,2CAA2C;AAAA,cAC3C,4CAA4C;AAAA,cAC5C,iCAAiC;AAAA,cACjC,kCAAkC;AAAA,YAErC;AAAA,YACD,UAAU;AAAA,cACQ,gBAAAvD,EAAIsF,IAAW,EAAE,UAAA5F,GAAU;AAAA,cAC3B,gBAAAM,EAAIoF,IAAsC,EAAE,OAAO9F,GAAgB,UAAU,IAAM,UAA0B,gBAAAU,EAAI+F,IAA8B,EAAE,IAAI/D,EAAQ,WAAW,MAAM,WAAW,UAAUwD,KAAa9F,EAAQ,CAAE,EAAG,CAAA;AAAA,YAC3P;AAAA,UACA;AAAA,QACA;AAAA,MACA;AAAA,IACK;AAAA,EACL;AACA;AACA0D,EAAe,cAAcD;AAC7B,IAAI6C,IAAa,gBACbC,IAAerG,EAAM;AAAA,EACvB,CAACP,GAAOyC,MAAiB;AACvB,UAAM,EAAE,gBAAAxC,GAAgB,GAAG4G,EAAU,IAAK7G,GACpCuB,IAAc9B,EAAeQ,CAAc;AAKjD,WAJqC+F;AAAA,MACnCW;AAAA,MACA1G;AAAA,IACD,EACmC,WAAW,OAAuB,gBAAAU,EAAImG,IAAuB,EAAE,GAAGvF,GAAa,GAAGsF,GAAY,KAAKpE,EAAY,CAAE;AAAA,EACzJ;AACA;AACAmE,EAAa,cAAcD;AAC3B,SAAS3B,GAAoB+B,GAAOC,GAAM;AACxC,QAAMC,IAAM,KAAK,IAAID,EAAK,MAAMD,EAAM,CAAC,GACjCG,IAAS,KAAK,IAAIF,EAAK,SAASD,EAAM,CAAC,GACvCI,IAAQ,KAAK,IAAIH,EAAK,QAAQD,EAAM,CAAC,GACrCK,IAAO,KAAK,IAAIJ,EAAK,OAAOD,EAAM,CAAC;AACzC,UAAQ,KAAK,IAAIE,GAAKC,GAAQC,GAAOC,CAAI,GAAC;AAAA,IACxC,KAAKA;AACH,aAAO;AAAA,IACT,KAAKD;AACH,aAAO;AAAA,IACT,KAAKF;AACH,aAAO;AAAA,IACT,KAAKC;AACH,aAAO;AAAA,IACT;AACE,YAAM,IAAI,MAAM,aAAa;AAAA,EACnC;AACA;AACA,SAAShC,GAAoBJ,GAAWC,GAAUsC,IAAU,GAAG;AAC7D,QAAMpC,IAAmB,CAAE;AAC3B,UAAQF,GAAQ;AAAA,IACd,KAAK;AACH,MAAAE,EAAiB;AAAA,QACf,EAAE,GAAGH,EAAU,IAAIuC,GAAS,GAAGvC,EAAU,IAAIuC,EAAS;AAAA,QACtD,EAAE,GAAGvC,EAAU,IAAIuC,GAAS,GAAGvC,EAAU,IAAIuC,EAAO;AAAA,MACrD;AACD;AAAA,IACF,KAAK;AACH,MAAApC,EAAiB;AAAA,QACf,EAAE,GAAGH,EAAU,IAAIuC,GAAS,GAAGvC,EAAU,IAAIuC,EAAS;AAAA,QACtD,EAAE,GAAGvC,EAAU,IAAIuC,GAAS,GAAGvC,EAAU,IAAIuC,EAAO;AAAA,MACrD;AACD;AAAA,IACF,KAAK;AACH,MAAApC,EAAiB;AAAA,QACf,EAAE,GAAGH,EAAU,IAAIuC,GAAS,GAAGvC,EAAU,IAAIuC,EAAS;AAAA,QACtD,EAAE,GAAGvC,EAAU,IAAIuC,GAAS,GAAGvC,EAAU,IAAIuC,EAAO;AAAA,MACrD;AACD;AAAA,IACF,KAAK;AACH,MAAApC,EAAiB;AAAA,QACf,EAAE,GAAGH,EAAU,IAAIuC,GAAS,GAAGvC,EAAU,IAAIuC,EAAS;AAAA,QACtD,EAAE,GAAGvC,EAAU,IAAIuC,GAAS,GAAGvC,EAAU,IAAIuC,EAAO;AAAA,MACrD;AACD;AAAA,EACN;AACE,SAAOpC;AACT;AACA,SAASG,GAAkB4B,GAAM;AAC/B,QAAM,EAAE,KAAAC,GAAK,OAAAE,GAAO,QAAAD,GAAQ,MAAAE,EAAM,IAAGJ;AACrC,SAAO;AAAA,IACL,EAAE,GAAGI,GAAM,GAAGH,EAAK;AAAA,IACnB,EAAE,GAAGE,GAAO,GAAGF,EAAK;AAAA,IACpB,EAAE,GAAGE,GAAO,GAAGD,EAAQ;AAAA,IACvB,EAAE,GAAGE,GAAM,GAAGF,EAAM;AAAA,EACrB;AACH;AACA,SAASpB,GAAiBiB,GAAOO,GAAS;AACxC,QAAM,EAAE,GAAAC,GAAG,GAAAC,EAAC,IAAKT;AACjB,MAAIU,IAAS;AACb,WAAS,IAAI,GAAGC,IAAIJ,EAAQ,SAAS,GAAG,IAAIA,EAAQ,QAAQI,IAAI,KAAK;AACnE,UAAMC,IAAKL,EAAQ,CAAC,GACdM,IAAKN,EAAQI,CAAC,GACdG,IAAKF,EAAG,GACRG,IAAKH,EAAG,GACRI,IAAKH,EAAG,GACRI,IAAKJ,EAAG;AAEd,IADkBE,IAAKN,KAAMQ,IAAKR,KAAKD,KAAKQ,IAAKF,MAAOL,IAAIM,MAAOE,IAAKF,KAAMD,MAC/DJ,IAAS,CAACA;AAAA,EAC7B;AACE,SAAOA;AACT;AACA,SAASnC,GAAQ2C,GAAQ;AACvB,QAAMC,IAAYD,EAAO,MAAO;AAChC,SAAAC,EAAU,KAAK,CAACC,GAAGC,MACbD,EAAE,IAAIC,EAAE,IAAU,KACbD,EAAE,IAAIC,EAAE,IAAU,IAClBD,EAAE,IAAIC,EAAE,IAAU,KAClBD,EAAE,IAAIC,EAAE,IAAU,IACf,CACb,GACMC,GAAiBH,CAAS;AACnC;AACA,SAASG,GAAiBJ,GAAQ;AAChC,MAAIA,EAAO,UAAU,EAAG,QAAOA,EAAO,MAAO;AAC7C,QAAMK,IAAY,CAAE;AACpB,WAASC,IAAI,GAAGA,IAAIN,EAAO,QAAQM,KAAK;AACtC,UAAMC,IAAIP,EAAOM,CAAC;AAClB,WAAOD,EAAU,UAAU,KAAG;AAC5B,YAAMG,IAAIH,EAAUA,EAAU,SAAS,CAAC,GAClCI,IAAIJ,EAAUA,EAAU,SAAS,CAAC;AACxC,WAAKG,EAAE,IAAIC,EAAE,MAAMF,EAAE,IAAIE,EAAE,OAAOD,EAAE,IAAIC,EAAE,MAAMF,EAAE,IAAIE,EAAE,GAAI,CAAAJ,EAAU,IAAK;AAAA,UACtE;AAAA,IACX;AACI,IAAAA,EAAU,KAAKE,CAAC;AAAA,EACpB;AACE,EAAAF,EAAU,IAAK;AACf,QAAMK,IAAY,CAAE;AACpB,WAASJ,IAAIN,EAAO,SAAS,GAAGM,KAAK,GAAGA,KAAK;AAC3C,UAAMC,IAAIP,EAAOM,CAAC;AAClB,WAAOI,EAAU,UAAU,KAAG;AAC5B,YAAMF,IAAIE,EAAUA,EAAU,SAAS,CAAC,GAClCD,IAAIC,EAAUA,EAAU,SAAS,CAAC;AACxC,WAAKF,EAAE,IAAIC,EAAE,MAAMF,EAAE,IAAIE,EAAE,OAAOD,EAAE,IAAIC,EAAE,MAAMF,EAAE,IAAIE,EAAE,GAAI,CAAAC,EAAU,IAAK;AAAA,UACtE;AAAA,IACX;AACI,IAAAA,EAAU,KAAKH,CAAC;AAAA,EACpB;AAEE,SADAG,EAAU,IAAK,GACXL,EAAU,WAAW,KAAKK,EAAU,WAAW,KAAKL,EAAU,CAAC,EAAE,MAAMK,EAAU,CAAC,EAAE,KAAKL,EAAU,CAAC,EAAE,MAAMK,EAAU,CAAC,EAAE,IACpHL,IAEAA,EAAU,OAAOK,CAAS;AAErC;AACA,IAAIC,IAAW7I,GACX8I,KAAQ7H,GACR8H,KAAUtG,GACVuG,KAAStF,GACTuF,IAAWjF,GACXkF,IAASrC;;;;;;;;;;;;;;;;8CCreAsC,KAAiB3I,EAAM,cAA+B,CAAE,CAAA,GAExDQ,IAAoB,MAChBR,EAAM,WAAW2I,EAAc,GCC1CnJ,KAAkBoJ,GAElBnI,KAAUoI,IAEV5G,KAAiB6G,IAEjBC,KAAqBC,EAAG;AAAA,EAC7B,OAAO;AAAA,IACN,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,KAAK;AAAA,EACN;AAAA,EACA,UAAU;AAAA,IACT,OAAO;AAAA,MACN,MAAM;AAAA,QACL,MAAM;AAAA,QACN,QAAQ;AAAA,MAAA;AAAA,IACT;AAAA,EACD;AAEF,CAAC,GAIK3C,KAAerG,EAAM;AAAA,EAC1B,CAAC,EAAE,OAAAiJ,GAAO,QAAAC,GAAQ,WAAAC,GAAW,GAAG1J,KAAS4C,MAAQ;AAC1C,UAAA,EAAE,OAAA+G,EAAM,IAAI5I,EAAkB,GAC9B6I,IAASN,GAAmB,EAAE,OAAAK,GAAO;AAG1C,WAAA,gBAAAhJ,EAACkJ,GAAA,EAAuB,KAAAjH,GAAU,SAAO,IAAE,GAAG5C,GAC7C,UAAA,gBAAAwG;AAAA,MAAC;AAAA,MAAA;AAAA,QACA,OAAOgD,KAAS;AAAA,QAChB,QAAQC,KAAU;AAAA,QAClB,SAAQ;AAAA,QACR,MAAK;AAAA,QACL,OAAM;AAAA,QACN,WAAWG,EAAO,IAAI,EAAE,WAAAF,GAAW;AAAA,QAEnC,UAAA;AAAA,UAAA,gBAAA/I,EAAC,UAAK,GAAE,4DAA2D,WAAWiJ,EAAO,QAAQ;AAAA,UAC7F,gBAAAjJ;AAAA,YAAC;AAAA,YAAA;AAAA,cACA,GAAE;AAAA,cACF,WAAWiJ,EAAO,OAAO;AAAA,cACzB,eAAc;AAAA,YAAA;AAAA,UAAA;AAAA,QACf;AAAA,MAAA;AAAA,IAAA,GAEF;AAAA,EAAA;AAGH;AAEAhD,GAAa,cAAciD,EAAuB;AAElD,MAAMC,KAAuBP,EAAG;AAAA,EAC/B,MAAM;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AAAA,EACA,UAAU;AAAA,IACT,OAAO;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,EACP;AAEF,CAAC,GAWKxF,KAAiBxD,EAAM;AAAA,EAC5B,CAAC,EAAE,WAAAmJ,GAAW,YAAAK,IAAa,GAAG,iBAAAC,GAAiB,OAAAL,GAAO,GAAG3J,EAAM,GAAG4C,MAAQ;AACnE,UAAAe,IAAYsG,GAAmBD,CAAe;AAEpD,WACE,gBAAArJ,EAAAuI,GAAe,UAAf,EAAwB,OAAO,EAAE,OAAAS,KACjC,UAAC,gBAAAhJ,EAAAuJ,IAAA,EAAwB,WAAAvG,GACxB,UAAA,gBAAAhD;AAAA,MAACwJ;AAAAA,MAAA;AAAA,QACA,KAAAvH;AAAA,QACA,YAAAmH;AAAA,QACA,WAAWD,GAAqB,EAAE,WAAAJ,GAAW,OAAAC,GAAO;AAAA,QACnD,GAAG3J;AAAA,MAAA;AAAA,OAEN,EACD,CAAA;AAAA,EAAA;AAGH;AACA+D,GAAe,cAAcoG,EAAyB;AAEtD,MAAMC,KAAqBb,EAAG;AAAA,EAC7B,MAAM;AAAA,EACN,UAAU;AAAA,IACT,OAAO;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,EACP;AAEF,CAAC,GAIKc,KAAe9J,EAAM,WAA8C,CAAC,EAAE,WAAAmJ,GAAW,UAAArJ,GAAU,GAAGL,EAAM,GAAG4C,MAAQ;AAC9G,QAAA,EAAE,OAAA+G,EAAM,IAAI5I,EAAkB;AACpC,SACE,gBAAAJ,EAAA,OAAA,EAAI,KAAAiC,GAAU,WAAWwH,GAAmB,EAAE,WAAAV,GAAW,OAAAC,EAAA,CAAO,GAAI,GAAG3J,GACtE,UAAAK,EACF,CAAA;AAEF,CAAC;AACDgK,GAAa,cAAc;AAE3B,MAAMC,KAAoBf,EAAG;AAAA,EAC5B,MAAM;AAAA,EACN,UAAU;AAAA,IACT,OAAO;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,EACP;AAEF,CAAC,GAIKgB,KAAchK,EAAM,WAA6C,CAAC,EAAE,WAAAmJ,GAAW,UAAArJ,GAAU,GAAGL,EAAM,GAAG4C,MAAQ;AAC5G,QAAA,EAAE,OAAA+G,EAAM,IAAI5I,EAAkB;AACpC,SACE,gBAAAJ,EAAA6J,IAAA,EAAK,KAAA5H,GAAU,MAAK,MAAK,WAAW0H,GAAkB,EAAE,WAAAZ,GAAW,OAAAC,EAAO,CAAA,GAAI,GAAG3J,GAChF,UAAAK,EACF,CAAA;AAEF,CAAC;AACDkK,GAAY,cAAc;AAE1B,MAAME,KAAoBlB,EAAG;AAAA,EAC5B,MAAM;AAAA,EACN,UAAU;AAAA,IACT,OAAO;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,EACP;AAEF,CAAC,GAIKmB,KAAcnK,EAAM,WAA4C,CAAC,EAAE,WAAAmJ,GAAW,GAAG1J,EAAM,GAAG4C,MAAQ;AACjG,QAAA,EAAE,OAAA+G,EAAM,IAAI5I,EAAkB;AACpC,SAAQ,gBAAAJ,EAAAgK,IAAA,EAAK,MAAK,MAAK,WAAWF,GAAkB,EAAE,WAAAf,GAAW,OAAAC,EAAO,CAAA,GAAG,KAAA/G,GAAW,GAAG5C,EAAO,CAAA;AACjG,CAAC;AACD0K,GAAY,cAAc;AAE1B,MAAME,KAAwBrB,EAAG;AAAA,EAChC,MAAM;AAAA,EACN,UAAU;AAAA,IACT,OAAO;AAAA,MACN,MAAM;AAAA,IAAA;AAAA,EACP;AAEF,CAAC,GAIKsB,KAAkBtK,EAAM,WAAiD,CAAC,EAAE,WAAAmJ,GAAW,GAAG1J,EAAM,GAAG4C,MAAQ;AAC1G,QAAA,EAAE,OAAA+G,EAAM,IAAI5I,EAAkB;AACpC,SAAQ,gBAAAJ,EAAAmK,IAAA,EAAS,SAAQ,SAAQ,WAAWF,GAAsB,EAAE,WAAAlB,GAAW,OAAAC,EAAO,CAAA,GAAG,KAAA/G,GAAW,GAAG5C,EAAO,CAAA;AAC/G,CAAC;AACD6K,GAAgB,cAAc;","x_google_ignoreList":[0]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as n } from "react/jsx-runtime";
|
|
2
2
|
import s from "react";
|
|
3
3
|
import { T as d } from "./index-BVqs-uqP.js";
|
|
4
|
-
import { B as g } from "./Button-
|
|
4
|
+
import { B as g } from "./Button-_qdP4hSf.js";
|
|
5
5
|
const i = d({
|
|
6
6
|
base: "",
|
|
7
7
|
variants: {
|
|
@@ -30,4 +30,4 @@ p.displayName = "TriggerButton";
|
|
|
30
30
|
export {
|
|
31
31
|
p as T
|
|
32
32
|
};
|
|
33
|
-
//# sourceMappingURL=TriggerButton-
|
|
33
|
+
//# sourceMappingURL=TriggerButton-CoAgB4lx.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TriggerButton-CoAgB4lx.js","sources":["../src/components/button/trigger-button/TriggerButton.tsx"],"sourcesContent":["import React, { PropsWithChildren } from \"react\";\r\nimport { tv } from \"tailwind-variants\";\r\nimport { VariantsConfig } from \"@/lib/utils/variants\";\r\nimport { Button, ButtonProps } from \"../button/Button\";\r\n\r\nexport interface TriggerButtonVariants {\r\n\tvariant?: \"outline\" | \"ghost\" | \"text\";\r\n}\r\n\r\nconst triggerButtonVariants = tv({\r\n\tbase: \"\",\r\n\tvariants: {\r\n\t\tvariant: {\r\n\t\t\toutline:\r\n\t\t\t\t\"data-[state=open]:bg-secondary-bg-hover data-[state=open]:shadow-none active:data-[state=open]:bg-secondary-bg-hover lg:hover:data-[state=open]:bg-secondary-bg-hover\",\r\n\t\t\tghost:\r\n\t\t\t\t\"data-[state=open]:bg-secondary-bg-hover data-[state=open]:shadow-none active:data-[state=open]:bg-secondary-bg-hover lg:hover:data-[state=open]:bg-secondary-bg-hover\",\r\n\t\t\ttext: \"data-[state=open]:text-secondary-fg\"\r\n\t\t}\r\n\t} satisfies VariantsConfig<TriggerButtonVariants>,\r\n\tdefaultVariants: {\r\n\t\tvariant: \"outline\"\r\n\t}\r\n});\r\n\r\nexport type TriggerButtonProps = Omit<ButtonProps, \"variant\" | \"status\"> &\r\n\tTriggerButtonVariants & {\r\n\t\t\"data-state\"?: \"open\" | \"closed\";\r\n\t};\r\n\r\nexport const TriggerButton = React.forwardRef<HTMLButtonElement, PropsWithChildren<TriggerButtonProps>>(\r\n\t({ className, children, variant, ...props }, ref) => {\r\n\t\treturn (\r\n\t\t\t<Button\r\n\t\t\t\tvariant={variant || \"outline\"}\r\n\t\t\t\tclassName={triggerButtonVariants({ className, variant })}\r\n\t\t\t\tref={ref}\r\n\t\t\t\t{...props}\r\n\t\t\t>\r\n\t\t\t\t{children}\r\n\t\t\t</Button>\r\n\t\t);\r\n\t}\r\n);\r\n\r\nTriggerButton.displayName = \"TriggerButton\";\r\n"],"names":["triggerButtonVariants","tv","TriggerButton","React","className","children","variant","props","ref","jsx","Button"],"mappings":";;;;AASA,MAAMA,IAAwBC,EAAG;AAAA,EAChC,MAAM;AAAA,EACN,UAAU;AAAA,IACT,SAAS;AAAA,MACR,SACC;AAAA,MACD,OACC;AAAA,MACD,MAAM;AAAA,IAAA;AAAA,EAER;AAAA,EACA,iBAAiB;AAAA,IAChB,SAAS;AAAA,EAAA;AAEX,CAAC,GAOYC,IAAgBC,EAAM;AAAA,EAClC,CAAC,EAAE,WAAAC,GAAW,UAAAC,GAAU,SAAAC,GAAS,GAAGC,KAASC,MAE3C,gBAAAC;AAAA,IAACC;AAAA,IAAA;AAAA,MACA,SAASJ,KAAW;AAAA,MACpB,WAAWN,EAAsB,EAAE,WAAAI,GAAW,SAAAE,GAAS;AAAA,MACvD,KAAAE;AAAA,MACC,GAAGD;AAAA,MAEH,UAAAF;AAAA,IAAA;AAAA,EACF;AAGH;AAEAH,EAAc,cAAc;"}
|
|
@@ -3,16 +3,16 @@ var z = (t, o, n) => o in t ? $(t, o, { enumerable: !0, configurable: !0, writab
|
|
|
3
3
|
var P = (t, o, n) => z(t, typeof o != "symbol" ? o + "" : o, n);
|
|
4
4
|
import { jsx as a, jsxs as x } from "react/jsx-runtime";
|
|
5
5
|
import S, { useMemo as N, useState as O, useCallback as B } from "react";
|
|
6
|
-
import { a as D, F as L, g as R } from "../../FormStack-
|
|
6
|
+
import { a as D, F as L, g as R } from "../../FormStack-CxiZhx1n.js";
|
|
7
7
|
import { s as G } from "../../zod-BMNoK3aM.js";
|
|
8
8
|
import { e as V } from "../../index.esm-CXA6i4d7.js";
|
|
9
9
|
import { z as v } from "../../vendors/zod.js";
|
|
10
|
-
import { B as E } from "../../Button-
|
|
11
|
-
import { T as A } from "../../TextInput-
|
|
10
|
+
import { B as E } from "../../Button-_qdP4hSf.js";
|
|
11
|
+
import { T as A } from "../../TextInput-CoL8nOyt.js";
|
|
12
12
|
import { c as j } from "../../cn-dsXlqdJg.js";
|
|
13
13
|
import { T as I } from "../../index-BVqs-uqP.js";
|
|
14
14
|
import { L as k } from "../../loader-circle-D1YXTEGq.js";
|
|
15
|
-
import { c as q, I as H, a as J, b as K } from "../../InputOTP-
|
|
15
|
+
import { c as q, I as H, a as J, b as K } from "../../InputOTP-DkVh6bBz.js";
|
|
16
16
|
class w extends Error {
|
|
17
17
|
constructor(n, r = "invalid_code") {
|
|
18
18
|
super(n);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"otp-form.js","sources":["../../../src/blocks/auth/otp-form/utils/OTPError.ts","../../../src/blocks/auth/otp-form/components/EmailForm.tsx","../../../src/blocks/auth/otp-form/components/OTPInputForm.tsx","../../../src/blocks/auth/otp-form/components/ResendButton.tsx","../../../src/blocks/auth/otp-form/OTPForm.tsx"],"sourcesContent":["type OTPErrorType = \"invalid_code\" | \"invalid_email\";\n\nexport class OTPError extends Error {\n\tpublic readonly type: OTPErrorType;\n\n\tconstructor(message: string, type: OTPErrorType = \"invalid_code\") {\n\t\tsuper(message);\n\t\tthis.type = type;\n\t\tthis.name = \"OTPError\";\n\n\t\t// Необходимо для правильного instanceof в TypeScript\n\t\tObject.setPrototypeOf(this, OTPError.prototype);\n\t}\n\n\t// Factory методы для удобства\n\tstatic invalidCode(message: string = \"Неверный код подтверждения\"): OTPError {\n\t\treturn new OTPError(message, \"invalid_code\");\n\t}\n\n\tstatic invalidEmail(message: string = \"Неверный email\"): OTPError {\n\t\treturn new OTPError(message, \"invalid_email\");\n\t}\n}\n","import { zodResolver } from \"@hookform/resolvers/zod\";\nimport React from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { z } from \"zod\";\n\nimport { Button } from \"@/components/button/button/Button\";\nimport { Form, FormField, FormStack } from \"@/components/form\";\nimport { TextInput } from \"@/components/input/text-input/TextInput\";\nimport { LoaderCircle } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { tv } from \"tailwind-variants\";\nimport { OTPError } from \"../utils/OTPError\";\n\ntype EmailFormData = {\n\temail: string;\n};\n\nexport interface EmailFormProps {\n\t/** Предустановленный email */\n\tdefaultEmail?: string;\n\t/** Плейсхолдер для email поля */\n\temailPlaceholder?: string;\n\t/** Лейбл для email поля */\n\temailLabel?: string;\n\t/** Описание email поля */\n\temailDescription?: string;\n\t/** Текст кнопки отправки */\n\tsendButtonText?: string;\n\t/** Колбек отправки кода. Вызывается при нажатии на кнопку \"Отправить\", если email валидный. */\n\tonSendCode?: (email: string) => Promise<void> | void;\n\t/** Колбек изменения email */\n\tonEmailChange?: (email: string) => void;\n\t/** Показывать ли кнопку отправки */\n\tshowSendButton?: boolean;\n\t/** Классы для лейбла */\n\tlabelClassName?: string;\n\t/** Схема валидации для email поля */\n\temailValidation?: z.ZodString;\n}\n\nconst emailFormStyles = tv({\n\tslots: {\n\t\tbutton: \"w-full\",\n\t\ticonButton: \"animate-spin\"\n\t}\n});\n\nexport const EmailForm = React.forwardRef<HTMLFormElement, EmailFormProps>((props, ref) => {\n\tconst {\n\t\tdefaultEmail,\n\t\temailPlaceholder = \"you@company.com\",\n\t\temailLabel = \"Email\",\n\t\temailDescription,\n\t\tsendButtonText = \"Отправить\",\n\t\tonSendCode,\n\t\tonEmailChange,\n\t\tshowSendButton = true,\n\t\tlabelClassName,\n\t\temailValidation\n\t} = props;\n\n\tconst [isLoading, setIsLoading] = React.useState(false);\n\tconst styles = emailFormStyles();\n\n\tconst validationSchema = z.object({\n\t\temail: emailValidation || z.string().email(\"Введите корректный email\")\n\t});\n\n\tconst form = useForm<EmailFormData>({\n\t\tresolver: zodResolver(validationSchema),\n\t\tdefaultValues: {\n\t\t\temail: defaultEmail || \"\"\n\t\t}\n\t});\n\n\tconst onSubmit = async (data: EmailFormData) => {\n\t\tsetIsLoading(true);\n\t\ttry {\n\t\t\tawait onSendCode?.(data.email);\n\t\t} catch (error) {\n\t\t\tif (error instanceof OTPError && error.type === \"invalid_email\") {\n\t\t\t\tform.setError(\"email\", {\n\t\t\t\t\ttype: \"manual\",\n\t\t\t\t\tmessage: error.message\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tsetIsLoading(false);\n\t\t}\n\t};\n\n\treturn (\n\t\t<Form asChild {...form}>\n\t\t\t<form ref={ref} onSubmit={form.handleSubmit(onSubmit)} noValidate>\n\t\t\t\t<FormStack>\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tname=\"email\"\n\t\t\t\t\t\ttitle={emailLabel}\n\t\t\t\t\t\tdescription={emailDescription}\n\t\t\t\t\t\tlabelClassName={labelClassName}\n\t\t\t\t\t\tcontrol={({ field }) => (\n\t\t\t\t\t\t\t<TextInput\n\t\t\t\t\t\t\t\ttype={emailValidation ? \"text\" : \"email\"}\n\t\t\t\t\t\t\t\tplaceholder={emailPlaceholder}\n\t\t\t\t\t\t\t\tshowClearIcon={true}\n\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\tonChange={(value) => {\n\t\t\t\t\t\t\t\t\tfield.onChange(value);\n\t\t\t\t\t\t\t\t\tonEmailChange?.(value || \"\");\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t{showSendButton && (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\tdisabled={!form.getValues(\"email\") || isLoading}\n\t\t\t\t\t\t\tstartIcon={isLoading ? LoaderCircle : undefined}\n\t\t\t\t\t\t\tclassName={styles.button()}\n\t\t\t\t\t\t\ticonClassName={cn(isLoading && styles.iconButton())}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{sendButtonText}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\t\t\t\t</FormStack>\n\t\t\t</form>\n\t\t</Form>\n\t);\n});\n\nEmailForm.displayName = \"EmailForm\";\n","import React, { useMemo } from \"react\";\nimport { ControllerRenderProps, FieldValues, useForm } from \"react-hook-form\";\n\nimport { Button } from \"@/components/button/button/Button\";\nimport { Form, FormField, FormStack } from \"@/components/form\";\nimport { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot } from \"@/components/input-otp\";\nimport { cn } from \"@/lib/utils\";\nimport { LoaderCircle } from \"lucide-react\";\nimport { OTPError } from \"../utils/OTPError\";\nimport { tv } from \"tailwind-variants\";\n\nexport type OTPRenderFunction = (field: ControllerRenderProps<FieldValues, string>) => React.ReactNode;\n\nexport interface OTPInputFormProps {\n\t/**\n\t * Формат группировки OTP кода\n\t * Примеры: \"3-3\" (XXX-XXX), \"4-4\" (XXXX-XXXX), \"6\" (XXXXXX)\n\t */\n\totpFormat?: string;\n\t/** Функция для обработки вставленного текста */\n\tpasteTransformer?: (text: string) => string;\n\t/** Автоотправка при заполнении OTP */\n\tautoSubmit?: boolean;\n\t/** Лейбл для OTP поля */\n\totpLabel?: string;\n\t/** Описание OTP поля */\n\totpDescription?: string;\n\t/** Текст кнопки подтверждения */\n\tconfirmButtonText?: string;\n\t/** Колбек подтверждения OTP */\n\tonConfirmCode?: (otp: string) => Promise<void> | void;\n\t/** Показывать ли кнопку подтверждения */\n\tshowConfirmButton?: boolean;\n\t/** Классы для лейбла */\n\tlabelClassName?: string;\n}\n\nconst defaultProps: Required<Pick<OTPInputFormProps, \"otpLabel\" | \"confirmButtonText\" | \"showConfirmButton\">> = {\n\totpLabel: \"Код доступа\",\n\tconfirmButtonText: \"Подтвердить\",\n\tshowConfirmButton: true\n};\n\ntype OTPFormData = {\n\totp: string;\n};\n\nconst OTPInputFormStyles = tv({\n\tslots: {\n\t\tbutton: \"w-full\",\n\t\ticonButton: \"animate-spin\"\n\t}\n});\n\nexport const OTPInputForm = (props: OTPInputFormProps) => {\n\tconst {\n\t\totpFormat = \"3-3\",\n\t\tautoSubmit = true,\n\t\totpLabel = defaultProps.otpLabel,\n\t\totpDescription,\n\t\tconfirmButtonText = defaultProps.confirmButtonText,\n\t\tonConfirmCode,\n\t\tshowConfirmButton = defaultProps.showConfirmButton,\n\t\tlabelClassName\n\t} = props;\n\n\tconst otpGrouping = useMemo(() => parseOTPFormat(otpFormat), [otpFormat]);\n\tconst otpLength = useMemo(() => otpGrouping.reduce((acc, curr) => acc + curr, 0), [otpGrouping]);\n\tconst styles = OTPInputFormStyles();\n\n\tconst [isLoading, setIsLoading] = React.useState(false);\n\n\tconst form = useForm<OTPFormData>();\n\n\tconst onSubmit = async (data: OTPFormData) => {\n\t\tif (!onConfirmCode) return;\n\n\t\tsetIsLoading(true);\n\t\ttry {\n\t\t\tawait onConfirmCode(data.otp);\n\t\t} catch (error) {\n\t\t\t// Если это ошибка неправильного кода, показываем ошибку в поле\n\t\t\tif (error instanceof OTPError && error.type === \"invalid_code\") {\n\t\t\t\tform.setError(\"otp\", {\n\t\t\t\t\ttype: \"manual\",\n\t\t\t\t\tmessage: error.message\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tsetIsLoading(false);\n\t\t}\n\t};\n\n\tconst handleOTPChange = (value: string) => {\n\t\t// Очищаем ошибки при изменении поля\n\t\tform.clearErrors(\"otp\");\n\n\t\tform.setValue(\"otp\", value);\n\t\tif (value.length === otpLength && autoSubmit) {\n\t\t\tform.handleSubmit(onSubmit)();\n\t\t}\n\t};\n\n\treturn (\n\t\t<Form asChild {...form}>\n\t\t\t<form onSubmit={form.handleSubmit(onSubmit)} noValidate>\n\t\t\t\t<FormStack>\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tname=\"otp\"\n\t\t\t\t\t\ttitle={otpLabel}\n\t\t\t\t\t\tdescription={otpDescription}\n\t\t\t\t\t\tlabelClassName={labelClassName}\n\t\t\t\t\t\tcontrol={({ field }) => {\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<InputOTP autoFocus={true} maxLength={otpLength} {...field} onChange={handleOTPChange}>\n\t\t\t\t\t\t\t\t\t{generateOTPSlots(otpGrouping)}\n\t\t\t\t\t\t\t\t</InputOTP>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\n\t\t\t\t\t{showConfirmButton && (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\tdisabled={isLoading || form.getValues(\"otp\")?.length !== otpLength}\n\t\t\t\t\t\t\tstartIcon={isLoading ? LoaderCircle : undefined}\n\t\t\t\t\t\t\tclassName={styles.button()}\n\t\t\t\t\t\t\ticonClassName={cn(isLoading && styles.iconButton())}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{confirmButtonText}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\t\t\t\t</FormStack>\n\t\t\t</form>\n\t\t</Form>\n\t);\n};\n\nconst parseOTPFormat = (format: string, fallback: number[] = [3, 3], onError?: (error: string) => void): number[] => {\n\tif (!format.includes(\"-\")) {\n\t\t// Одна группа: \"6\" -> [6]\n\t\tconst length = parseInt(format, 10);\n\t\tif (isNaN(length) || length <= 0) {\n\t\t\tonError?.(`Неверный формат OTP: \"${format}\"`);\n\t\t\treturn fallback;\n\t\t}\n\t\treturn [length];\n\t}\n\n\t// Несколько групп: \"3-3\" -> [3, 3]\n\tconst groups = format.split(\"-\").map((group) => {\n\t\tconst size = parseInt(group, 10);\n\t\tif (isNaN(size) || size <= 0) {\n\t\t\tonError?.(`Неверный размер группы: \"${group}\" в формате \"${format}\"`);\n\t\t\treturn 1;\n\t\t}\n\t\treturn size;\n\t});\n\n\treturn groups;\n};\n\nconst generateOTPSlots = (grouping: number[]): React.ReactNode => {\n\tlet currentIndex = 0;\n\n\treturn grouping.map((groupSize, groupIndex) => {\n\t\tconst slots = Array.from({ length: groupSize }, () => (\n\t\t\t<InputOTPSlot key={currentIndex} index={currentIndex++} />\n\t\t));\n\n\t\tconst group = <InputOTPGroup key={`group-${groupIndex}`}>{slots}</InputOTPGroup>;\n\n\t\t// Добавляем разделитель между группами (кроме последней)\n\t\tif (groupIndex < grouping.length - 1) {\n\t\t\treturn (\n\t\t\t\t<React.Fragment key={`fragment-${groupIndex}`}>\n\t\t\t\t\t{group}\n\t\t\t\t\t<InputOTPSeparator />\n\t\t\t\t</React.Fragment>\n\t\t\t);\n\t\t}\n\n\t\treturn group;\n\t});\n};\n","import React from \"react\";\nimport { Button } from \"@/components/button/button/Button\";\nimport { tv } from \"tailwind-variants\";\n\nexport interface ResendButtonProps {\n\t/** Время последней отправки кода (timestamp) */\n\tlastSentTime?: number | null;\n\t/** Время задержки для повторной отправки в секундах */\n\tresendDelay?: number;\n\t/** Текст кнопки повторной отправки */\n\tresendButtonText?: string;\n\t/** Шаблон текста обратного отсчета */\n\tresendCountdownText?: (seconds: number) => string;\n\t/** Колбек повторной отправки кода */\n\tonResend?: () => Promise<void> | void;\n}\n\nconst resendButtonStyles = tv({\n\tslots: {\n\t\tbutton: \"w-full\"\n\t}\n});\n\nexport const ResendButton = React.forwardRef<HTMLButtonElement, ResendButtonProps>((props, ref) => {\n\tconst {\n\t\tlastSentTime,\n\t\tresendDelay = 60,\n\t\tresendButtonText = \"Отправить код повторно\",\n\t\tresendCountdownText = (seconds) => `Отправить код повторно через ${seconds} сек.`,\n\t\tonResend\n\t} = props;\n\n\tconst [remainingSeconds, setRemainingSeconds] = React.useState(0);\n\tconst [isLoading, setIsLoading] = React.useState(false);\n\n\tconst styles = resendButtonStyles();\n\n\t// Таймер обратного отсчета\n\tReact.useEffect(() => {\n\t\tif (!lastSentTime) {\n\t\t\tsetRemainingSeconds(0);\n\t\t\treturn;\n\t\t}\n\n\t\tconst updateCountdown = () => {\n\t\t\tconst elapsedSeconds = Math.floor((Date.now() - lastSentTime) / 1000);\n\t\t\tconst remaining = Math.max(0, resendDelay - elapsedSeconds);\n\t\t\tsetRemainingSeconds(remaining);\n\t\t};\n\n\t\tupdateCountdown();\n\t\tconst timer = setInterval(updateCountdown, 1000);\n\t\treturn () => clearInterval(timer);\n\t}, [lastSentTime, resendDelay]);\n\n\tconst handleResend = async () => {\n\t\tif (remainingSeconds > 0) return;\n\t\tsetIsLoading(true);\n\t\ttry {\n\t\t\tawait onResend?.();\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Error resending code:\", error);\n\t\t} finally {\n\t\t\tsetIsLoading(false);\n\t\t}\n\t};\n\n\tconst isDisabled = remainingSeconds > 0 || isLoading;\n\tconst buttonText = remainingSeconds > 0 ? resendCountdownText(remainingSeconds) : resendButtonText;\n\n\treturn (\n\t\t<Button\n\t\t\tref={ref}\n\t\t\tonClick={handleResend}\n\t\t\tdisabled={isDisabled}\n\t\t\tvariant=\"link\"\n\t\t\ttype=\"button\"\n\t\t\tclassName={styles.button()}\n\t\t>\n\t\t\t{buttonText}\n\t\t</Button>\n\t);\n});\n\nResendButton.displayName = \"ResendButton\";\n","import React, { useCallback, useState } from \"react\";\nimport { FormStack } from \"@/components/form\";\nimport { EmailForm } from \"./components/EmailForm\";\nimport { OTPInputForm } from \"./components/OTPInputForm\";\nimport { ResendButton } from \"./components/ResendButton\";\nimport { z } from \"zod\";\n\nexport interface OTPFormProps {\n\t/**\n\t * Формат группировки OTP кода\n\t * Примеры: \"3-3\" (XXX-XXX), \"4-4\" (XXXX-XXXX), \"6\" (XXXXXX)\n\t */\n\totpFormat?: string;\n\t/** Автоотправка при заполнении OTP */\n\tautoSubmit?: boolean;\n\t/** Функция для обработки вставленного текста */\n\tpasteTransformer?: (text: string) => string;\n\t/** Время задержки для повторной отправки в секундах */\n\tresendDelay?: number;\n\t/** Плейсхолдер для email поля */\n\temailPlaceholder?: string;\n\t/** Лейбл для email поля */\n\temailLabel?: string;\n\t/** Описание email поля */\n\temailDescription?: string;\n\t/** Лейбл для OTP поля */\n\totpLabel?: string;\n\t/** Описание OTP поля */\n\totpDescription?: string;\n\t/** Текст кнопки отправки */\n\tsendButtonText?: string;\n\t/** Текст кнопки подтверждения */\n\tconfirmButtonText?: string;\n\t/** Текст кнопки повторной отправки */\n\tresendButtonText?: string;\n\t/** Шаблон текста обратного отсчета */\n\tresendCountdownText?: (seconds: number) => string;\n\t/** Предустановленный email */\n\tdefaultEmail?: string;\n\t/** Колбек отправки/повторной отправки кода */\n\tonSendCode?: (email: string, isResend?: boolean) => Promise<void> | void;\n\t/** Колбек подтверждения OTP */\n\tonConfirmCode?: (data: { email: string; otp: string }) => Promise<void> | void;\n\t/** CSS классы для стилизации лейбла. Позволяет настроить внешний вид лейбла, например ограничить ширину: \"w-24\" */\n\tlabelClassName?: string;\n\t/** Схема валидации для email поля */\n\temailValidation?: z.ZodString;\n}\n\nexport const OTPForm: React.FC<OTPFormProps> = (props) => {\n\tconst { onSendCode, onConfirmCode } = props;\n\tconst { labelClassName = \"w-24\" } = props;\n\n\t// Email адрес, на который был отправлен OTP код\n\tconst [targetEmail, setTargetEmail] = useState<string | null>(null);\n\tconst [lastSentTime, setLastSentTime] = useState<number | null>(null);\n\n\tconst onEmailChange = useCallback(\n\t\t(email: string) => {\n\t\t\t// Если email изменился, то сбрасываем состояние форм\n\t\t\tif (targetEmail && email !== targetEmail) {\n\t\t\t\tsetTargetEmail(null);\n\t\t\t}\n\t\t},\n\t\t[targetEmail]\n\t);\n\n\t// Обработчик отправки кода из EmailForm\n\tconst handleSendCode = useCallback(\n\t\tasync (email: string, isResend = false) => {\n\t\t\ttry {\n\t\t\t\tawait onSendCode?.(email, isResend);\n\t\t\t\tsetLastSentTime(Date.now());\n\t\t\t\t// Сохраняем email как активный адрес для OTP операций\n\t\t\t\tsetTargetEmail(email);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Error sending code:\", error);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\t\t[onSendCode]\n\t);\n\n\tconst handleResendCode = useCallback(async () => {\n\t\tif (targetEmail) {\n\t\t\tawait handleSendCode(targetEmail, true);\n\t\t}\n\t}, [handleSendCode, targetEmail]);\n\n\tconst handleOTPConfirm = useCallback(\n\t\tasync (otp: string) => {\n\t\t\tawait onConfirmCode?.({ email: targetEmail!, otp });\n\t\t},\n\t\t[onConfirmCode, targetEmail]\n\t);\n\n\treturn (\n\t\t<FormStack>\n\t\t\t<EmailForm\n\t\t\t\tdefaultEmail={props.defaultEmail}\n\t\t\t\temailPlaceholder={props.emailPlaceholder}\n\t\t\t\temailLabel={props.emailLabel}\n\t\t\t\temailDescription={props.emailDescription}\n\t\t\t\tonEmailChange={onEmailChange}\n\t\t\t\tsendButtonText={props.sendButtonText}\n\t\t\t\tonSendCode={handleSendCode}\n\t\t\t\tshowSendButton={!targetEmail}\n\t\t\t\tlabelClassName={labelClassName}\n\t\t\t\temailValidation={props.emailValidation}\n\t\t\t/>\n\n\t\t\t{targetEmail && (\n\t\t\t\t<OTPInputForm\n\t\t\t\t\t// key для пересоздания компонента, чтобы очистить поле и сфокусироваться на нём\n\t\t\t\t\tkey={lastSentTime}\n\t\t\t\t\totpFormat={props.otpFormat}\n\t\t\t\t\tautoSubmit={props.autoSubmit}\n\t\t\t\t\tpasteTransformer={props.pasteTransformer}\n\t\t\t\t\totpLabel={props.otpLabel}\n\t\t\t\t\totpDescription={props.otpDescription}\n\t\t\t\t\tconfirmButtonText={props.confirmButtonText}\n\t\t\t\t\tonConfirmCode={handleOTPConfirm}\n\t\t\t\t\tlabelClassName={labelClassName}\n\t\t\t\t/>\n\t\t\t)}\n\n\t\t\t{targetEmail && (\n\t\t\t\t<ResendButton\n\t\t\t\t\tresendDelay={props.resendDelay}\n\t\t\t\t\tresendButtonText={props.resendButtonText}\n\t\t\t\t\tresendCountdownText={props.resendCountdownText}\n\t\t\t\t\tonResend={handleResendCode}\n\t\t\t\t\tlastSentTime={lastSentTime}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</FormStack>\n\t);\n};\n\nOTPForm.displayName = \"OTPForm\";\n"],"names":["OTPError","message","type","__publicField","emailFormStyles","tv","EmailForm","React","props","ref","defaultEmail","emailPlaceholder","emailLabel","emailDescription","sendButtonText","onSendCode","onEmailChange","showSendButton","labelClassName","emailValidation","isLoading","setIsLoading","styles","validationSchema","z","form","useForm","zodResolver","onSubmit","data","error","Form","jsx","FormStack","FormField","field","TextInput","value","Button","LoaderCircle","cn","defaultProps","OTPInputFormStyles","OTPInputForm","otpFormat","autoSubmit","otpLabel","otpDescription","confirmButtonText","onConfirmCode","showConfirmButton","otpGrouping","useMemo","parseOTPFormat","otpLength","acc","curr","handleOTPChange","InputOTP","generateOTPSlots","format","fallback","onError","length","group","size","grouping","currentIndex","groupSize","groupIndex","slots","InputOTPSlot","InputOTPGroup","jsxs","InputOTPSeparator","resendButtonStyles","ResendButton","lastSentTime","resendDelay","resendButtonText","resendCountdownText","seconds","onResend","remainingSeconds","setRemainingSeconds","updateCountdown","elapsedSeconds","remaining","timer","handleResend","isDisabled","buttonText","OTPForm","targetEmail","setTargetEmail","useState","setLastSentTime","useCallback","email","handleSendCode","isResend","handleResendCode","handleOTPConfirm","otp"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"otp-form.js","sources":["../../../src/blocks/auth/otp-form/utils/OTPError.ts","../../../src/blocks/auth/otp-form/components/EmailForm.tsx","../../../src/blocks/auth/otp-form/components/OTPInputForm.tsx","../../../src/blocks/auth/otp-form/components/ResendButton.tsx","../../../src/blocks/auth/otp-form/OTPForm.tsx"],"sourcesContent":["type OTPErrorType = \"invalid_code\" | \"invalid_email\";\r\n\r\nexport class OTPError extends Error {\r\n\tpublic readonly type: OTPErrorType;\r\n\r\n\tconstructor(message: string, type: OTPErrorType = \"invalid_code\") {\r\n\t\tsuper(message);\r\n\t\tthis.type = type;\r\n\t\tthis.name = \"OTPError\";\r\n\r\n\t\t// Необходимо для правильного instanceof в TypeScript\r\n\t\tObject.setPrototypeOf(this, OTPError.prototype);\r\n\t}\r\n\r\n\t// Factory методы для удобства\r\n\tstatic invalidCode(message: string = \"Неверный код подтверждения\"): OTPError {\r\n\t\treturn new OTPError(message, \"invalid_code\");\r\n\t}\r\n\r\n\tstatic invalidEmail(message: string = \"Неверный email\"): OTPError {\r\n\t\treturn new OTPError(message, \"invalid_email\");\r\n\t}\r\n}\r\n","import { zodResolver } from \"@hookform/resolvers/zod\";\r\nimport React from \"react\";\r\nimport { useForm } from \"react-hook-form\";\r\nimport { z } from \"zod\";\r\n\r\nimport { Button } from \"@/components/button/button/Button\";\r\nimport { Form, FormField, FormStack } from \"@/components/form\";\r\nimport { TextInput } from \"@/components/input/text-input/TextInput\";\r\nimport { LoaderCircle } from \"lucide-react\";\r\nimport { cn } from \"@/lib/utils\";\r\nimport { tv } from \"tailwind-variants\";\r\nimport { OTPError } from \"../utils/OTPError\";\r\n\r\ntype EmailFormData = {\r\n\temail: string;\r\n};\r\n\r\nexport interface EmailFormProps {\r\n\t/** Предустановленный email */\r\n\tdefaultEmail?: string;\r\n\t/** Плейсхолдер для email поля */\r\n\temailPlaceholder?: string;\r\n\t/** Лейбл для email поля */\r\n\temailLabel?: string;\r\n\t/** Описание email поля */\r\n\temailDescription?: string;\r\n\t/** Текст кнопки отправки */\r\n\tsendButtonText?: string;\r\n\t/** Колбек отправки кода. Вызывается при нажатии на кнопку \"Отправить\", если email валидный. */\r\n\tonSendCode?: (email: string) => Promise<void> | void;\r\n\t/** Колбек изменения email */\r\n\tonEmailChange?: (email: string) => void;\r\n\t/** Показывать ли кнопку отправки */\r\n\tshowSendButton?: boolean;\r\n\t/** Классы для лейбла */\r\n\tlabelClassName?: string;\r\n\t/** Схема валидации для email поля */\r\n\temailValidation?: z.ZodString;\r\n}\r\n\r\nconst emailFormStyles = tv({\r\n\tslots: {\r\n\t\tbutton: \"w-full\",\r\n\t\ticonButton: \"animate-spin\"\r\n\t}\r\n});\r\n\r\nexport const EmailForm = React.forwardRef<HTMLFormElement, EmailFormProps>((props, ref) => {\r\n\tconst {\r\n\t\tdefaultEmail,\r\n\t\temailPlaceholder = \"you@company.com\",\r\n\t\temailLabel = \"Email\",\r\n\t\temailDescription,\r\n\t\tsendButtonText = \"Отправить\",\r\n\t\tonSendCode,\r\n\t\tonEmailChange,\r\n\t\tshowSendButton = true,\r\n\t\tlabelClassName,\r\n\t\temailValidation\r\n\t} = props;\r\n\r\n\tconst [isLoading, setIsLoading] = React.useState(false);\r\n\tconst styles = emailFormStyles();\r\n\r\n\tconst validationSchema = z.object({\r\n\t\temail: emailValidation || z.string().email(\"Введите корректный email\")\r\n\t});\r\n\r\n\tconst form = useForm<EmailFormData>({\r\n\t\tresolver: zodResolver(validationSchema),\r\n\t\tdefaultValues: {\r\n\t\t\temail: defaultEmail || \"\"\r\n\t\t}\r\n\t});\r\n\r\n\tconst onSubmit = async (data: EmailFormData) => {\r\n\t\tsetIsLoading(true);\r\n\t\ttry {\r\n\t\t\tawait onSendCode?.(data.email);\r\n\t\t} catch (error) {\r\n\t\t\tif (error instanceof OTPError && error.type === \"invalid_email\") {\r\n\t\t\t\tform.setError(\"email\", {\r\n\t\t\t\t\ttype: \"manual\",\r\n\t\t\t\t\tmessage: error.message\r\n\t\t\t\t});\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tthrow error;\r\n\t\t} finally {\r\n\t\t\tsetIsLoading(false);\r\n\t\t}\r\n\t};\r\n\r\n\treturn (\r\n\t\t<Form asChild {...form}>\r\n\t\t\t<form ref={ref} onSubmit={form.handleSubmit(onSubmit)} noValidate>\r\n\t\t\t\t<FormStack>\r\n\t\t\t\t\t<FormField\r\n\t\t\t\t\t\tname=\"email\"\r\n\t\t\t\t\t\ttitle={emailLabel}\r\n\t\t\t\t\t\tdescription={emailDescription}\r\n\t\t\t\t\t\tlabelClassName={labelClassName}\r\n\t\t\t\t\t\tcontrol={({ field }) => (\r\n\t\t\t\t\t\t\t<TextInput\r\n\t\t\t\t\t\t\t\ttype={emailValidation ? \"text\" : \"email\"}\r\n\t\t\t\t\t\t\t\tplaceholder={emailPlaceholder}\r\n\t\t\t\t\t\t\t\tshowClearIcon={true}\r\n\t\t\t\t\t\t\t\t{...field}\r\n\t\t\t\t\t\t\t\tonChange={(value) => {\r\n\t\t\t\t\t\t\t\t\tfield.onChange(value);\r\n\t\t\t\t\t\t\t\t\tonEmailChange?.(value || \"\");\r\n\t\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t)}\r\n\t\t\t\t\t/>\r\n\r\n\t\t\t\t\t{showSendButton && (\r\n\t\t\t\t\t\t<Button\r\n\t\t\t\t\t\t\ttype=\"submit\"\r\n\t\t\t\t\t\t\tdisabled={!form.getValues(\"email\") || isLoading}\r\n\t\t\t\t\t\t\tstartIcon={isLoading ? LoaderCircle : undefined}\r\n\t\t\t\t\t\t\tclassName={styles.button()}\r\n\t\t\t\t\t\t\ticonClassName={cn(isLoading && styles.iconButton())}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t{sendButtonText}\r\n\t\t\t\t\t\t</Button>\r\n\t\t\t\t\t)}\r\n\t\t\t\t</FormStack>\r\n\t\t\t</form>\r\n\t\t</Form>\r\n\t);\r\n});\r\n\r\nEmailForm.displayName = \"EmailForm\";\r\n","import React, { useMemo } from \"react\";\r\nimport { ControllerRenderProps, FieldValues, useForm } from \"react-hook-form\";\r\n\r\nimport { Button } from \"@/components/button/button/Button\";\r\nimport { Form, FormField, FormStack } from \"@/components/form\";\r\nimport { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot } from \"@/components/input-otp\";\r\nimport { cn } from \"@/lib/utils\";\r\nimport { LoaderCircle } from \"lucide-react\";\r\nimport { OTPError } from \"../utils/OTPError\";\r\nimport { tv } from \"tailwind-variants\";\r\n\r\nexport type OTPRenderFunction = (field: ControllerRenderProps<FieldValues, string>) => React.ReactNode;\r\n\r\nexport interface OTPInputFormProps {\r\n\t/**\r\n\t * Формат группировки OTP кода\r\n\t * Примеры: \"3-3\" (XXX-XXX), \"4-4\" (XXXX-XXXX), \"6\" (XXXXXX)\r\n\t */\r\n\totpFormat?: string;\r\n\t/** Функция для обработки вставленного текста */\r\n\tpasteTransformer?: (text: string) => string;\r\n\t/** Автоотправка при заполнении OTP */\r\n\tautoSubmit?: boolean;\r\n\t/** Лейбл для OTP поля */\r\n\totpLabel?: string;\r\n\t/** Описание OTP поля */\r\n\totpDescription?: string;\r\n\t/** Текст кнопки подтверждения */\r\n\tconfirmButtonText?: string;\r\n\t/** Колбек подтверждения OTP */\r\n\tonConfirmCode?: (otp: string) => Promise<void> | void;\r\n\t/** Показывать ли кнопку подтверждения */\r\n\tshowConfirmButton?: boolean;\r\n\t/** Классы для лейбла */\r\n\tlabelClassName?: string;\r\n}\r\n\r\nconst defaultProps: Required<Pick<OTPInputFormProps, \"otpLabel\" | \"confirmButtonText\" | \"showConfirmButton\">> = {\r\n\totpLabel: \"Код доступа\",\r\n\tconfirmButtonText: \"Подтвердить\",\r\n\tshowConfirmButton: true\r\n};\r\n\r\ntype OTPFormData = {\r\n\totp: string;\r\n};\r\n\r\nconst OTPInputFormStyles = tv({\r\n\tslots: {\r\n\t\tbutton: \"w-full\",\r\n\t\ticonButton: \"animate-spin\"\r\n\t}\r\n});\r\n\r\nexport const OTPInputForm = (props: OTPInputFormProps) => {\r\n\tconst {\r\n\t\totpFormat = \"3-3\",\r\n\t\tautoSubmit = true,\r\n\t\totpLabel = defaultProps.otpLabel,\r\n\t\totpDescription,\r\n\t\tconfirmButtonText = defaultProps.confirmButtonText,\r\n\t\tonConfirmCode,\r\n\t\tshowConfirmButton = defaultProps.showConfirmButton,\r\n\t\tlabelClassName\r\n\t} = props;\r\n\r\n\tconst otpGrouping = useMemo(() => parseOTPFormat(otpFormat), [otpFormat]);\r\n\tconst otpLength = useMemo(() => otpGrouping.reduce((acc, curr) => acc + curr, 0), [otpGrouping]);\r\n\tconst styles = OTPInputFormStyles();\r\n\r\n\tconst [isLoading, setIsLoading] = React.useState(false);\r\n\r\n\tconst form = useForm<OTPFormData>();\r\n\r\n\tconst onSubmit = async (data: OTPFormData) => {\r\n\t\tif (!onConfirmCode) return;\r\n\r\n\t\tsetIsLoading(true);\r\n\t\ttry {\r\n\t\t\tawait onConfirmCode(data.otp);\r\n\t\t} catch (error) {\r\n\t\t\t// Если это ошибка неправильного кода, показываем ошибку в поле\r\n\t\t\tif (error instanceof OTPError && error.type === \"invalid_code\") {\r\n\t\t\t\tform.setError(\"otp\", {\r\n\t\t\t\t\ttype: \"manual\",\r\n\t\t\t\t\tmessage: error.message\r\n\t\t\t\t});\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tthrow error;\r\n\t\t} finally {\r\n\t\t\tsetIsLoading(false);\r\n\t\t}\r\n\t};\r\n\r\n\tconst handleOTPChange = (value: string) => {\r\n\t\t// Очищаем ошибки при изменении поля\r\n\t\tform.clearErrors(\"otp\");\r\n\r\n\t\tform.setValue(\"otp\", value);\r\n\t\tif (value.length === otpLength && autoSubmit) {\r\n\t\t\tform.handleSubmit(onSubmit)();\r\n\t\t}\r\n\t};\r\n\r\n\treturn (\r\n\t\t<Form asChild {...form}>\r\n\t\t\t<form onSubmit={form.handleSubmit(onSubmit)} noValidate>\r\n\t\t\t\t<FormStack>\r\n\t\t\t\t\t<FormField\r\n\t\t\t\t\t\tname=\"otp\"\r\n\t\t\t\t\t\ttitle={otpLabel}\r\n\t\t\t\t\t\tdescription={otpDescription}\r\n\t\t\t\t\t\tlabelClassName={labelClassName}\r\n\t\t\t\t\t\tcontrol={({ field }) => {\r\n\t\t\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\t\t<InputOTP autoFocus={true} maxLength={otpLength} {...field} onChange={handleOTPChange}>\r\n\t\t\t\t\t\t\t\t\t{generateOTPSlots(otpGrouping)}\r\n\t\t\t\t\t\t\t\t</InputOTP>\r\n\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t}}\r\n\t\t\t\t\t/>\r\n\r\n\t\t\t\t\t{showConfirmButton && (\r\n\t\t\t\t\t\t<Button\r\n\t\t\t\t\t\t\ttype=\"submit\"\r\n\t\t\t\t\t\t\tdisabled={isLoading || form.getValues(\"otp\")?.length !== otpLength}\r\n\t\t\t\t\t\t\tstartIcon={isLoading ? LoaderCircle : undefined}\r\n\t\t\t\t\t\t\tclassName={styles.button()}\r\n\t\t\t\t\t\t\ticonClassName={cn(isLoading && styles.iconButton())}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t{confirmButtonText}\r\n\t\t\t\t\t\t</Button>\r\n\t\t\t\t\t)}\r\n\t\t\t\t</FormStack>\r\n\t\t\t</form>\r\n\t\t</Form>\r\n\t);\r\n};\r\n\r\nconst parseOTPFormat = (format: string, fallback: number[] = [3, 3], onError?: (error: string) => void): number[] => {\r\n\tif (!format.includes(\"-\")) {\r\n\t\t// Одна группа: \"6\" -> [6]\r\n\t\tconst length = parseInt(format, 10);\r\n\t\tif (isNaN(length) || length <= 0) {\r\n\t\t\tonError?.(`Неверный формат OTP: \"${format}\"`);\r\n\t\t\treturn fallback;\r\n\t\t}\r\n\t\treturn [length];\r\n\t}\r\n\r\n\t// Несколько групп: \"3-3\" -> [3, 3]\r\n\tconst groups = format.split(\"-\").map((group) => {\r\n\t\tconst size = parseInt(group, 10);\r\n\t\tif (isNaN(size) || size <= 0) {\r\n\t\t\tonError?.(`Неверный размер группы: \"${group}\" в формате \"${format}\"`);\r\n\t\t\treturn 1;\r\n\t\t}\r\n\t\treturn size;\r\n\t});\r\n\r\n\treturn groups;\r\n};\r\n\r\nconst generateOTPSlots = (grouping: number[]): React.ReactNode => {\r\n\tlet currentIndex = 0;\r\n\r\n\treturn grouping.map((groupSize, groupIndex) => {\r\n\t\tconst slots = Array.from({ length: groupSize }, () => (\r\n\t\t\t<InputOTPSlot key={currentIndex} index={currentIndex++} />\r\n\t\t));\r\n\r\n\t\tconst group = <InputOTPGroup key={`group-${groupIndex}`}>{slots}</InputOTPGroup>;\r\n\r\n\t\t// Добавляем разделитель между группами (кроме последней)\r\n\t\tif (groupIndex < grouping.length - 1) {\r\n\t\t\treturn (\r\n\t\t\t\t<React.Fragment key={`fragment-${groupIndex}`}>\r\n\t\t\t\t\t{group}\r\n\t\t\t\t\t<InputOTPSeparator />\r\n\t\t\t\t</React.Fragment>\r\n\t\t\t);\r\n\t\t}\r\n\r\n\t\treturn group;\r\n\t});\r\n};\r\n","import React from \"react\";\r\nimport { Button } from \"@/components/button/button/Button\";\r\nimport { tv } from \"tailwind-variants\";\r\n\r\nexport interface ResendButtonProps {\r\n\t/** Время последней отправки кода (timestamp) */\r\n\tlastSentTime?: number | null;\r\n\t/** Время задержки для повторной отправки в секундах */\r\n\tresendDelay?: number;\r\n\t/** Текст кнопки повторной отправки */\r\n\tresendButtonText?: string;\r\n\t/** Шаблон текста обратного отсчета */\r\n\tresendCountdownText?: (seconds: number) => string;\r\n\t/** Колбек повторной отправки кода */\r\n\tonResend?: () => Promise<void> | void;\r\n}\r\n\r\nconst resendButtonStyles = tv({\r\n\tslots: {\r\n\t\tbutton: \"w-full\"\r\n\t}\r\n});\r\n\r\nexport const ResendButton = React.forwardRef<HTMLButtonElement, ResendButtonProps>((props, ref) => {\r\n\tconst {\r\n\t\tlastSentTime,\r\n\t\tresendDelay = 60,\r\n\t\tresendButtonText = \"Отправить код повторно\",\r\n\t\tresendCountdownText = (seconds) => `Отправить код повторно через ${seconds} сек.`,\r\n\t\tonResend\r\n\t} = props;\r\n\r\n\tconst [remainingSeconds, setRemainingSeconds] = React.useState(0);\r\n\tconst [isLoading, setIsLoading] = React.useState(false);\r\n\r\n\tconst styles = resendButtonStyles();\r\n\r\n\t// Таймер обратного отсчета\r\n\tReact.useEffect(() => {\r\n\t\tif (!lastSentTime) {\r\n\t\t\tsetRemainingSeconds(0);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tconst updateCountdown = () => {\r\n\t\t\tconst elapsedSeconds = Math.floor((Date.now() - lastSentTime) / 1000);\r\n\t\t\tconst remaining = Math.max(0, resendDelay - elapsedSeconds);\r\n\t\t\tsetRemainingSeconds(remaining);\r\n\t\t};\r\n\r\n\t\tupdateCountdown();\r\n\t\tconst timer = setInterval(updateCountdown, 1000);\r\n\t\treturn () => clearInterval(timer);\r\n\t}, [lastSentTime, resendDelay]);\r\n\r\n\tconst handleResend = async () => {\r\n\t\tif (remainingSeconds > 0) return;\r\n\t\tsetIsLoading(true);\r\n\t\ttry {\r\n\t\t\tawait onResend?.();\r\n\t\t} catch (error) {\r\n\t\t\tconsole.error(\"Error resending code:\", error);\r\n\t\t} finally {\r\n\t\t\tsetIsLoading(false);\r\n\t\t}\r\n\t};\r\n\r\n\tconst isDisabled = remainingSeconds > 0 || isLoading;\r\n\tconst buttonText = remainingSeconds > 0 ? resendCountdownText(remainingSeconds) : resendButtonText;\r\n\r\n\treturn (\r\n\t\t<Button\r\n\t\t\tref={ref}\r\n\t\t\tonClick={handleResend}\r\n\t\t\tdisabled={isDisabled}\r\n\t\t\tvariant=\"link\"\r\n\t\t\ttype=\"button\"\r\n\t\t\tclassName={styles.button()}\r\n\t\t>\r\n\t\t\t{buttonText}\r\n\t\t</Button>\r\n\t);\r\n});\r\n\r\nResendButton.displayName = \"ResendButton\";\r\n","import React, { useCallback, useState } from \"react\";\r\nimport { FormStack } from \"@/components/form\";\r\nimport { EmailForm } from \"./components/EmailForm\";\r\nimport { OTPInputForm } from \"./components/OTPInputForm\";\r\nimport { ResendButton } from \"./components/ResendButton\";\r\nimport { z } from \"zod\";\r\n\r\nexport interface OTPFormProps {\r\n\t/**\r\n\t * Формат группировки OTP кода\r\n\t * Примеры: \"3-3\" (XXX-XXX), \"4-4\" (XXXX-XXXX), \"6\" (XXXXXX)\r\n\t */\r\n\totpFormat?: string;\r\n\t/** Автоотправка при заполнении OTP */\r\n\tautoSubmit?: boolean;\r\n\t/** Функция для обработки вставленного текста */\r\n\tpasteTransformer?: (text: string) => string;\r\n\t/** Время задержки для повторной отправки в секундах */\r\n\tresendDelay?: number;\r\n\t/** Плейсхолдер для email поля */\r\n\temailPlaceholder?: string;\r\n\t/** Лейбл для email поля */\r\n\temailLabel?: string;\r\n\t/** Описание email поля */\r\n\temailDescription?: string;\r\n\t/** Лейбл для OTP поля */\r\n\totpLabel?: string;\r\n\t/** Описание OTP поля */\r\n\totpDescription?: string;\r\n\t/** Текст кнопки отправки */\r\n\tsendButtonText?: string;\r\n\t/** Текст кнопки подтверждения */\r\n\tconfirmButtonText?: string;\r\n\t/** Текст кнопки повторной отправки */\r\n\tresendButtonText?: string;\r\n\t/** Шаблон текста обратного отсчета */\r\n\tresendCountdownText?: (seconds: number) => string;\r\n\t/** Предустановленный email */\r\n\tdefaultEmail?: string;\r\n\t/** Колбек отправки/повторной отправки кода */\r\n\tonSendCode?: (email: string, isResend?: boolean) => Promise<void> | void;\r\n\t/** Колбек подтверждения OTP */\r\n\tonConfirmCode?: (data: { email: string; otp: string }) => Promise<void> | void;\r\n\t/** CSS классы для стилизации лейбла. Позволяет настроить внешний вид лейбла, например ограничить ширину: \"w-24\" */\r\n\tlabelClassName?: string;\r\n\t/** Схема валидации для email поля */\r\n\temailValidation?: z.ZodString;\r\n}\r\n\r\nexport const OTPForm: React.FC<OTPFormProps> = (props) => {\r\n\tconst { onSendCode, onConfirmCode } = props;\r\n\tconst { labelClassName = \"w-24\" } = props;\r\n\r\n\t// Email адрес, на который был отправлен OTP код\r\n\tconst [targetEmail, setTargetEmail] = useState<string | null>(null);\r\n\tconst [lastSentTime, setLastSentTime] = useState<number | null>(null);\r\n\r\n\tconst onEmailChange = useCallback(\r\n\t\t(email: string) => {\r\n\t\t\t// Если email изменился, то сбрасываем состояние форм\r\n\t\t\tif (targetEmail && email !== targetEmail) {\r\n\t\t\t\tsetTargetEmail(null);\r\n\t\t\t}\r\n\t\t},\r\n\t\t[targetEmail]\r\n\t);\r\n\r\n\t// Обработчик отправки кода из EmailForm\r\n\tconst handleSendCode = useCallback(\r\n\t\tasync (email: string, isResend = false) => {\r\n\t\t\ttry {\r\n\t\t\t\tawait onSendCode?.(email, isResend);\r\n\t\t\t\tsetLastSentTime(Date.now());\r\n\t\t\t\t// Сохраняем email как активный адрес для OTP операций\r\n\t\t\t\tsetTargetEmail(email);\r\n\t\t\t} catch (error) {\r\n\t\t\t\tconsole.error(\"Error sending code:\", error);\r\n\t\t\t\tthrow error;\r\n\t\t\t}\r\n\t\t},\r\n\t\t[onSendCode]\r\n\t);\r\n\r\n\tconst handleResendCode = useCallback(async () => {\r\n\t\tif (targetEmail) {\r\n\t\t\tawait handleSendCode(targetEmail, true);\r\n\t\t}\r\n\t}, [handleSendCode, targetEmail]);\r\n\r\n\tconst handleOTPConfirm = useCallback(\r\n\t\tasync (otp: string) => {\r\n\t\t\tawait onConfirmCode?.({ email: targetEmail!, otp });\r\n\t\t},\r\n\t\t[onConfirmCode, targetEmail]\r\n\t);\r\n\r\n\treturn (\r\n\t\t<FormStack>\r\n\t\t\t<EmailForm\r\n\t\t\t\tdefaultEmail={props.defaultEmail}\r\n\t\t\t\temailPlaceholder={props.emailPlaceholder}\r\n\t\t\t\temailLabel={props.emailLabel}\r\n\t\t\t\temailDescription={props.emailDescription}\r\n\t\t\t\tonEmailChange={onEmailChange}\r\n\t\t\t\tsendButtonText={props.sendButtonText}\r\n\t\t\t\tonSendCode={handleSendCode}\r\n\t\t\t\tshowSendButton={!targetEmail}\r\n\t\t\t\tlabelClassName={labelClassName}\r\n\t\t\t\temailValidation={props.emailValidation}\r\n\t\t\t/>\r\n\r\n\t\t\t{targetEmail && (\r\n\t\t\t\t<OTPInputForm\r\n\t\t\t\t\t// key для пересоздания компонента, чтобы очистить поле и сфокусироваться на нём\r\n\t\t\t\t\tkey={lastSentTime}\r\n\t\t\t\t\totpFormat={props.otpFormat}\r\n\t\t\t\t\tautoSubmit={props.autoSubmit}\r\n\t\t\t\t\tpasteTransformer={props.pasteTransformer}\r\n\t\t\t\t\totpLabel={props.otpLabel}\r\n\t\t\t\t\totpDescription={props.otpDescription}\r\n\t\t\t\t\tconfirmButtonText={props.confirmButtonText}\r\n\t\t\t\t\tonConfirmCode={handleOTPConfirm}\r\n\t\t\t\t\tlabelClassName={labelClassName}\r\n\t\t\t\t/>\r\n\t\t\t)}\r\n\r\n\t\t\t{targetEmail && (\r\n\t\t\t\t<ResendButton\r\n\t\t\t\t\tresendDelay={props.resendDelay}\r\n\t\t\t\t\tresendButtonText={props.resendButtonText}\r\n\t\t\t\t\tresendCountdownText={props.resendCountdownText}\r\n\t\t\t\t\tonResend={handleResendCode}\r\n\t\t\t\t\tlastSentTime={lastSentTime}\r\n\t\t\t\t/>\r\n\t\t\t)}\r\n\t\t</FormStack>\r\n\t);\r\n};\r\n\r\nOTPForm.displayName = \"OTPForm\";\r\n"],"names":["OTPError","message","type","__publicField","emailFormStyles","tv","EmailForm","React","props","ref","defaultEmail","emailPlaceholder","emailLabel","emailDescription","sendButtonText","onSendCode","onEmailChange","showSendButton","labelClassName","emailValidation","isLoading","setIsLoading","styles","validationSchema","z","form","useForm","zodResolver","onSubmit","data","error","Form","jsx","FormStack","FormField","field","TextInput","value","Button","LoaderCircle","cn","defaultProps","OTPInputFormStyles","OTPInputForm","otpFormat","autoSubmit","otpLabel","otpDescription","confirmButtonText","onConfirmCode","showConfirmButton","otpGrouping","useMemo","parseOTPFormat","otpLength","acc","curr","handleOTPChange","InputOTP","generateOTPSlots","format","fallback","onError","length","group","size","grouping","currentIndex","groupSize","groupIndex","slots","InputOTPSlot","InputOTPGroup","jsxs","InputOTPSeparator","resendButtonStyles","ResendButton","lastSentTime","resendDelay","resendButtonText","resendCountdownText","seconds","onResend","remainingSeconds","setRemainingSeconds","updateCountdown","elapsedSeconds","remaining","timer","handleResend","isDisabled","buttonText","OTPForm","targetEmail","setTargetEmail","useState","setLastSentTime","useCallback","email","handleSendCode","isResend","handleResendCode","handleOTPConfirm","otp"],"mappings":"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"}
|
package/dist/cn-dsXlqdJg.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cn-dsXlqdJg.js","sources":["../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs","../src/lib/utils/cn.ts"],"sourcesContent":["function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=\" \"),n+=f)}else for(f in e)e[f]&&(n&&(n+=\" \"),n+=f);return n}export function clsx(){for(var e,t,f=0,n=\"\",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=\" \"),n+=t);return n}export default clsx;","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n"],"names":["r","e","t","f","n","o","clsx","cn","inputs","twMerge"],"mappings":";AAAA,SAASA,EAAEC,GAAE;AAAC,MAAIC,GAAEC,GAAEC,IAAE;AAAG,MAAa,OAAOH,KAAjB,YAA8B,OAAOA,KAAjB,SAAmB,CAAAG,KAAGH;AAAA,WAAoB,OAAOA,KAAjB,SAAmB,KAAG,MAAM,QAAQA,CAAC,GAAE;AAAC,QAAII,IAAEJ,EAAE;AAAO,SAAIC,IAAE,GAAEA,IAAEG,GAAEH,IAAI,CAAAD,EAAEC,CAAC,MAAIC,IAAEH,EAAEC,EAAEC,CAAC,CAAC,OAAKE,MAAIA,KAAG,MAAKA,KAAGD;AAAA,EAAE,MAAM,MAAIA,KAAKF,EAAE,CAAAA,EAAEE,CAAC,MAAIC,MAAIA,KAAG,MAAKA,KAAGD;AAAG,SAAOC;AAAC;AAAQ,SAASE,IAAM;AAAC,WAAQL,GAAEC,GAAEC,IAAE,GAAEC,IAAE,IAAGC,IAAE,UAAU,QAAOF,IAAEE,GAAEF,IAAI,EAACF,IAAE,UAAUE,CAAC,OAAKD,IAAEF,EAAEC,CAAC,OAAKG,MAAIA,KAAG,MAAKA,KAAGF;AAAG,SAAOE;AAAC;ACGxW,SAASG,KAAMC,GAAsB;AACpC,SAAAC,EAAQH,EAAKE,CAAM,CAAC;AAC5B;","x_google_ignoreList":[0]}
|
|
1
|
+
{"version":3,"file":"cn-dsXlqdJg.js","sources":["../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs","../src/lib/utils/cn.ts"],"sourcesContent":["function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=\" \"),n+=f)}else for(f in e)e[f]&&(n&&(n+=\" \"),n+=f);return n}export function clsx(){for(var e,t,f=0,n=\"\",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=\" \"),n+=t);return n}export default clsx;","import { clsx, type ClassValue } from \"clsx\";\r\nimport { twMerge } from \"tailwind-merge\";\r\n\r\nexport function cn(...inputs: ClassValue[]) {\r\n\treturn twMerge(clsx(inputs));\r\n}\r\n"],"names":["r","e","t","f","n","o","clsx","cn","inputs","twMerge"],"mappings":";AAAA,SAASA,EAAEC,GAAE;AAAC,MAAIC,GAAEC,GAAEC,IAAE;AAAG,MAAa,OAAOH,KAAjB,YAA8B,OAAOA,KAAjB,SAAmB,CAAAG,KAAGH;AAAA,WAAoB,OAAOA,KAAjB,SAAmB,KAAG,MAAM,QAAQA,CAAC,GAAE;AAAC,QAAII,IAAEJ,EAAE;AAAO,SAAIC,IAAE,GAAEA,IAAEG,GAAEH,IAAI,CAAAD,EAAEC,CAAC,MAAIC,IAAEH,EAAEC,EAAEC,CAAC,CAAC,OAAKE,MAAIA,KAAG,MAAKA,KAAGD;AAAA,EAAE,MAAM,MAAIA,KAAKF,EAAE,CAAAA,EAAEE,CAAC,MAAIC,MAAIA,KAAG,MAAKA,KAAGD;AAAG,SAAOC;AAAC;AAAQ,SAASE,IAAM;AAAC,WAAQL,GAAEC,GAAEC,IAAE,GAAEC,IAAE,IAAGC,IAAE,UAAU,QAAOF,IAAEE,GAAEF,IAAI,EAACF,IAAE,UAAUE,CAAC,OAAKD,IAAEF,EAAEC,CAAC,OAAKG,MAAIA,KAAG,MAAKA,KAAGF;AAAG,SAAOE;AAAC;ACGxW,SAASG,KAAMC,GAAsB;AACpC,SAAAC,EAAQH,EAAKE,CAAM,CAAC;AAC5B;","x_google_ignoreList":[0]}
|
|
@@ -5,9 +5,9 @@ import { u as y } from "../index-DLcqcWxM.js";
|
|
|
5
5
|
import { c as b, R as W, P as Y, T as q, O as k, W as J, a as K, b as Q, D as U, C as x } from "../index-CMxHunQ4.js";
|
|
6
6
|
import { c as X, b as Z } from "../index-CFaU3UXv.js";
|
|
7
7
|
import { T as d } from "../index-BVqs-uqP.js";
|
|
8
|
-
import { u as ee } from "../usePortalContainer-
|
|
9
|
-
import { o as te } from "../Overlay-
|
|
10
|
-
import { B as N } from "../Button-
|
|
8
|
+
import { u as ee } from "../usePortalContainer-B1xla842.js";
|
|
9
|
+
import { o as te } from "../Overlay-E0UvxzIc.js";
|
|
10
|
+
import { B as N } from "../Button-_qdP4hSf.js";
|
|
11
11
|
import { A as ae, u as f } from "../AlertContext-CxjW1LVL.js";
|
|
12
12
|
import { I as oe } from "../Icon-DH3ev9GK.js";
|
|
13
13
|
import { e as w } from "../useBreakpoints-DHvp74UL.js";
|