@ryuzaki13/react-foundation-ui 0.1.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/badge/Badge.d.ts.map +1 -1
- package/dist/badge/index.js +1 -1
- package/dist/badge/stories/Badge.stories.js +1 -1
- package/dist/base-table/index.js +1 -1
- package/dist/base-table/lib/columnPinning.d.ts.map +1 -1
- package/dist/base-table/model/useTableColumnOrder.d.ts +1 -1
- package/dist/base-table/model/useTableColumnOrder.d.ts.map +1 -1
- package/dist/base-table/model/useTableColumnSizing.d.ts +1 -1
- package/dist/base-table/model/useTableColumnSizing.d.ts.map +1 -1
- package/dist/base-table/ui/BaseTable.d.ts +2 -2
- package/dist/base-table/ui/BaseTable.d.ts.map +1 -1
- package/dist/base-table/ui/BaseTableHeaderCell.d.ts.map +1 -1
- package/dist/base-table/ui/FormattedTableCell.d.ts.map +1 -1
- package/dist/check-box/CheckBox.d.ts.map +1 -1
- package/dist/check-box/index.js +1 -1
- package/dist/check-box/stories/CheckBox.stories.js +1 -1
- package/dist/chunks/{BadgeList-DHW_Ktr3.js → BadgeList-6qL9oNAp.js} +5 -5
- package/dist/chunks/BadgeList-6qL9oNAp.js.map +1 -0
- package/dist/chunks/{CalendarView-B75faWIU.js → CalendarView-DjShdvRD.js} +42 -42
- package/dist/chunks/{CalendarView-B75faWIU.js.map → CalendarView-DjShdvRD.js.map} +1 -1
- package/dist/chunks/{CheckBox-Cck5w1Ud.js → CheckBox-CulnjNvJ.js} +9 -9
- package/dist/chunks/CheckBox-CulnjNvJ.js.map +1 -0
- package/dist/chunks/{DateInput-CINDYueM.js → DateInput-LSSvObtg.js} +3 -3
- package/dist/chunks/DateInput-LSSvObtg.js.map +1 -0
- package/dist/chunks/Dialog-BPS4BeWZ.js.map +1 -1
- package/dist/chunks/{DisclosureGroup-0BtaXO54.js → DisclosureGroup-Plk2M_Vl.js} +9 -9
- package/dist/chunks/DisclosureGroup-Plk2M_Vl.js.map +1 -0
- package/dist/chunks/{DropZone-hf7Em__0.js → DropZone-DPGTpHI6.js} +7 -7
- package/dist/chunks/DropZone-DPGTpHI6.js.map +1 -0
- package/dist/chunks/DropdownMenu-Ds-trH4M.js.map +1 -1
- package/dist/chunks/Flex-DbBdq336.js.map +1 -1
- package/dist/chunks/Grid-ByIIytjh.js.map +1 -1
- package/dist/chunks/{Input-Ce2HXBUc.js → Input-Wrew1puH.js} +30 -30
- package/dist/chunks/Input-Wrew1puH.js.map +1 -0
- package/dist/chunks/{InputDateTime-DPtY_4Od.js → InputDateTime-2PCX8an8.js} +2 -2
- package/dist/chunks/{InputDateTime-DPtY_4Od.js.map → InputDateTime-2PCX8an8.js.map} +1 -1
- package/dist/chunks/{InputFile-ga5yJmdZ.js → InputFile-Ca-bRo93.js} +2 -2
- package/dist/chunks/InputFile-Ca-bRo93.js.map +1 -0
- package/dist/chunks/{InputFiles-Or2Nvfgk.js → InputFiles-pI9rQXOI.js} +22 -22
- package/dist/chunks/InputFiles-pI9rQXOI.js.map +1 -0
- package/dist/chunks/{InputImage-BeA5WJz1.js → InputImage-B522AQzl.js} +2 -2
- package/dist/chunks/{InputImage-BeA5WJz1.js.map → InputImage-B522AQzl.js.map} +1 -1
- package/dist/chunks/{LabeledExpandableActionPanel-Bx-DWmYz.js → LabeledExpandableActionPanel-CWmOSWeS.js} +12 -12
- package/dist/chunks/LabeledExpandableActionPanel-CWmOSWeS.js.map +1 -0
- package/dist/chunks/{Listbox-CY1wQOCP.js → Listbox-B6F_IKQv.js} +22 -22
- package/dist/chunks/Listbox-B6F_IKQv.js.map +1 -0
- package/dist/chunks/{MultiSelect-CBqTylqO.js → MultiSelect-CUXA8gx-.js} +12 -12
- package/dist/chunks/{MultiSelect-CBqTylqO.js.map → MultiSelect-CUXA8gx-.js.map} +1 -1
- package/dist/chunks/{NotificationsHost-BQc-zOr2.js → NotificationsHost-Bnq7xFKO.js} +24 -24
- package/dist/chunks/NotificationsHost-Bnq7xFKO.js.map +1 -0
- package/dist/chunks/{PresetRangeDateInput-YBQm_4Fb.js → PresetRangeDateInput-B_8jsilZ.js} +2 -2
- package/dist/chunks/{PresetRangeDateInput-YBQm_4Fb.js.map → PresetRangeDateInput-B_8jsilZ.js.map} +1 -1
- package/dist/chunks/{RadioButton-DJp31HFR.js → RadioButton-D5vPW4Yr.js} +8 -8
- package/dist/chunks/RadioButton-D5vPW4Yr.js.map +1 -0
- package/dist/chunks/{Select-B7k_8_Lf.js → Select-CoAYWNOn.js} +10 -10
- package/dist/chunks/Select-CoAYWNOn.js.map +1 -0
- package/dist/chunks/{SerializableSelect-53uNCqdE.js → SerializableSelect-awBOWKTj.js} +2 -2
- package/dist/chunks/{SerializableSelect-53uNCqdE.js.map → SerializableSelect-awBOWKTj.js.map} +1 -1
- package/dist/chunks/{SingleDateTimeInput-CwvIbwje.js → SingleDateTimeInput-o44Vlwdk.js} +19 -19
- package/dist/chunks/SingleDateTimeInput-o44Vlwdk.js.map +1 -0
- package/dist/chunks/{StateSelect-D0wuUdT9.js → StateSelect-abZq176J.js} +2 -2
- package/dist/chunks/{StateSelect-D0wuUdT9.js.map → StateSelect-abZq176J.js.map} +1 -1
- package/dist/chunks/{Switch-B476FBUD.js → Switch-DHMnZVmN.js} +9 -9
- package/dist/chunks/Switch-DHMnZVmN.js.map +1 -0
- package/dist/chunks/{TextEditorLexicalClient-DcixYuo4.js → TextEditorLexicalClient-Dt4eaPA3.js} +4 -4
- package/dist/chunks/{TextEditorLexicalClient-DcixYuo4.js.map → TextEditorLexicalClient-Dt4eaPA3.js.map} +1 -1
- package/dist/chunks/{Textarea-DeJJjjkI.js → Textarea-DOVrPH4I.js} +2 -2
- package/dist/chunks/{Textarea-DeJJjjkI.js.map → Textarea-DOVrPH4I.js.map} +1 -1
- package/dist/chunks/TimePanel-_kF2RtHk.js.map +1 -1
- package/dist/chunks/{TreeMultiSelect-DRYNx7u5.js → TreeMultiSelect-C76RYavo.js} +2 -2
- package/dist/chunks/{TreeMultiSelect-DRYNx7u5.js.map → TreeMultiSelect-C76RYavo.js.map} +1 -1
- package/dist/chunks/{TreePickerBase-DYzTsSBQ.js → TreePickerBase-qNHIWbYL.js} +155 -155
- package/dist/chunks/TreePickerBase-qNHIWbYL.js.map +1 -0
- package/dist/chunks/{TreeSelect-DGLDu6qc.js → TreeSelect-LEhNdPCX.js} +2 -2
- package/dist/chunks/{TreeSelect-DGLDu6qc.js.map → TreeSelect-LEhNdPCX.js.map} +1 -1
- package/dist/chunks/{base-table-DVje02Zi.js → base-table-ij2guVMB.js} +3 -3
- package/dist/chunks/base-table-ij2guVMB.js.map +1 -0
- package/dist/chunks/{layout-picker-BA9vA8JI.js → layout-picker-CzZ8Xzkk.js} +9 -9
- package/dist/chunks/layout-picker-CzZ8Xzkk.js.map +1 -0
- package/dist/chunks/{misc-DrmMj8GO.js → misc-Bj0y3ERC.js} +54 -54
- package/dist/chunks/misc-Bj0y3ERC.js.map +1 -0
- package/dist/chunks/{modal-DqVcZws_.js → modal-B4ivQb2h.js} +10 -10
- package/dist/chunks/modal-B4ivQb2h.js.map +1 -0
- package/dist/chunks/{picker-Cj4RnJh6.js → picker-gIUs0nE_.js} +13 -13
- package/dist/chunks/picker-gIUs0nE_.js.map +1 -0
- package/dist/chunks/popover-C79P5bm2.js.map +1 -1
- package/dist/chunks/{slider-34wxzKkG.js → slider-CigVo4Ju.js} +3 -3
- package/dist/chunks/slider-CigVo4Ju.js.map +1 -0
- package/dist/chunks/{sortable-CwDHC3CA.js → sortable-BZqnZ_LA.js} +10 -10
- package/dist/chunks/sortable-BZqnZ_LA.js.map +1 -0
- package/dist/chunks/{table-BYA0hCj7.js → table-CK-CM2zD.js} +2 -2
- package/dist/chunks/table-CK-CM2zD.js.map +1 -0
- package/dist/chunks/table-column-interactions-DPyJDD7P.js.map +1 -1
- package/dist/chunks/{tabs-CjU2KCgs.js → tabs-D5ikIIng.js} +2 -2
- package/dist/chunks/{tabs-CjU2KCgs.js.map → tabs-D5ikIIng.js.map} +1 -1
- package/dist/chunks/ui.module-BisoTevy.js.map +1 -1
- package/dist/context-menu/components/MenuContent.d.ts.map +1 -1
- package/dist/context-menu/components/MenuContext.d.ts.map +1 -1
- package/dist/context-menu/components/MenuRoot.d.ts.map +1 -1
- package/dist/context-menu/components/RadialMenuContent.d.ts.map +1 -1
- package/dist/date-input/index.js +2 -2
- package/dist/date-input/lib/types.d.ts.map +1 -1
- package/dist/date-input/stories/DateInput.stories.js +2 -2
- package/dist/date-input/ui/CalendarView.d.ts.map +1 -1
- package/dist/date-input/ui/DateInput.d.ts.map +1 -1
- package/dist/date-range-preset-select/stories/DateRangePresetSelect.stories.js +1 -1
- package/dist/date-time-input/index.js +1 -1
- package/dist/date-time-input/lib/dateTimeValue.d.ts.map +1 -1
- package/dist/date-time-input/stories/SingleDateTimeInput.stories.js +1 -1
- package/dist/date-time-input/ui/SingleDateTimeInput.d.ts.map +1 -1
- package/dist/dialog/Dialog.d.ts.map +1 -1
- package/dist/disclosure/Disclosure.d.ts.map +1 -1
- package/dist/disclosure/index.js +1 -1
- package/dist/disclosure/stories/Disclosure.stories.js +1 -1
- package/dist/drop-zone/DropZone.d.ts.map +1 -1
- package/dist/drop-zone/index.js +1 -1
- package/dist/drop-zone/stories/DropZone.stories.d.ts.map +1 -1
- package/dist/drop-zone/stories/DropZone.stories.js +1 -1
- package/dist/drop-zone/stories/DropZone.stories.js.map +1 -1
- package/dist/errors/ErrorDisplay.d.ts.map +1 -1
- package/dist/errors/index.js.map +1 -1
- package/dist/expandable-action-panel/ExpandableActionPanel.d.ts.map +1 -1
- package/dist/expandable-action-panel/index.js +1 -1
- package/dist/expandable-action-panel/stories/ExpandableActionPanel.stories.js +4 -4
- package/dist/image/index.js +3 -3
- package/dist/image/index.js.map +1 -1
- package/dist/image/ui/ImageSelection.d.ts.map +1 -1
- package/dist/input/Input.d.ts.map +1 -1
- package/dist/input/index.js +1 -1
- package/dist/input/stories/Input.stories.js +1 -1
- package/dist/input-date-time/index.js +1 -1
- package/dist/input-date-time/stories/InputDateTime.stories.js +1 -1
- package/dist/input-file/InputFile.d.ts.map +1 -1
- package/dist/input-file/index.js +1 -1
- package/dist/input-file/stories/InputFile.stories.d.ts.map +1 -1
- package/dist/input-file/stories/InputFile.stories.js +1 -1
- package/dist/input-file/stories/InputFile.stories.js.map +1 -1
- package/dist/input-files/InputFilesList.d.ts.map +1 -1
- package/dist/input-files/index.js +1 -1
- package/dist/input-files/stories/InputFiles.stories.d.ts +1 -1
- package/dist/input-files/stories/InputFiles.stories.d.ts.map +1 -1
- package/dist/input-files/stories/InputFiles.stories.js +1 -1
- package/dist/input-files/stories/InputFiles.stories.js.map +1 -1
- package/dist/input-image/index.js +1 -1
- package/dist/input-image/stories/InputImage.stories.d.ts.map +1 -1
- package/dist/input-image/stories/InputImage.stories.js +1 -1
- package/dist/input-image/stories/InputImage.stories.js.map +1 -1
- package/dist/input-search/index.js +1 -1
- package/dist/layout-picker/index.js +1 -1
- package/dist/layout-picker/stories/LayoutPicker.stories.js +1 -1
- package/dist/layout-picker/ui/LayoutPicker.d.ts.map +1 -1
- package/dist/list/List.d.ts.map +1 -1
- package/dist/list/index.js +5 -5
- package/dist/list/index.js.map +1 -1
- package/dist/listbox/Listbox.d.ts.map +1 -1
- package/dist/listbox/index.js +1 -1
- package/dist/listbox/stories/Listbox.stories.js +1 -1
- package/dist/misc/CopyTextWrapper.d.ts.map +1 -1
- package/dist/misc/OneStepScroller.d.ts.map +1 -1
- package/dist/misc/StateIcon.d.ts.map +1 -1
- package/dist/misc/index.js +1 -1
- package/dist/modal/Modal.d.ts +5 -1
- package/dist/modal/Modal.d.ts.map +1 -1
- package/dist/modal/index.js +1 -1
- package/dist/modal/stories/Modal.stories.js +2 -2
- package/dist/multi-select/index.js +1130 -24
- package/dist/multi-select/index.js.map +1 -1
- package/dist/multi-select/model/useODataMultiSelect.d.ts +23 -0
- package/dist/multi-select/model/useODataMultiSelect.d.ts.map +1 -0
- package/dist/multi-select/ui/MultiSelect.d.ts +1 -1
- package/dist/multi-select/ui/MultiSelect.d.ts.map +1 -1
- package/dist/multi-select/ui/ODataDependentMultiSelect.d.ts +20 -0
- package/dist/multi-select/ui/ODataDependentMultiSelect.d.ts.map +1 -0
- package/dist/multi-select/ui/ODataDependentSegmentMultiSelect.d.ts +21 -0
- package/dist/multi-select/ui/ODataDependentSegmentMultiSelect.d.ts.map +1 -0
- package/dist/multi-select/ui/ODataMultiSelect.d.ts +7 -0
- package/dist/multi-select/ui/ODataMultiSelect.d.ts.map +1 -0
- package/dist/multi-select/ui/SerializableMultiSelect.d.ts.map +1 -1
- package/dist/multi-select/ui/index.d.ts +3 -0
- package/dist/multi-select/ui/index.d.ts.map +1 -1
- package/dist/multi-select/ui/stories/MultiSelect.stories.js +1 -1
- package/dist/multi-select/ui/stories/ODataMultiSelect.stories.d.ts +44 -0
- package/dist/multi-select/ui/stories/ODataMultiSelect.stories.d.ts.map +1 -0
- package/dist/notifications/index.js +1 -1
- package/dist/notifications/model/NotificationsProvider.d.ts.map +1 -1
- package/dist/notifications/ui/NotificationsHost.d.ts.map +1 -1
- package/dist/notifications/ui/stories/NotificationsHost.stories.js +1 -1
- package/dist/period-select/PeriodSelect.d.ts +1 -1
- package/dist/period-select/PeriodSelect.d.ts.map +1 -1
- package/dist/period-select/index.js.map +1 -1
- package/dist/period-select/lib/periodSelect.d.ts.map +1 -1
- package/dist/period-select/stories/PeriodSelect.stories.d.ts.map +1 -1
- package/dist/period-select/stories/PeriodSelect.stories.js +1 -1
- package/dist/period-select/stories/PeriodSelect.stories.js.map +1 -1
- package/dist/picker/PickerPopup.d.ts.map +1 -1
- package/dist/picker/PickerTriggerActions.d.ts.map +1 -1
- package/dist/picker/index.js +1 -1
- package/dist/picker/model/usePickerFloatingListbox.d.ts.map +1 -1
- package/dist/popover/FloatingPopover.d.ts.map +1 -1
- package/dist/popover/components/PopoverContent.d.ts.map +1 -1
- package/dist/popover/components/PopoverContext.d.ts.map +1 -1
- package/dist/popover/stories/Popover.stories.js +1 -1
- package/dist/preset-range-date-input/index.js +1 -1
- package/dist/preset-range-date-input/ui/stories/PresetRangeDateInput.stories.js +1 -1
- package/dist/preset-select/index.js +1 -1
- package/dist/radio-button/RadioButton.d.ts.map +1 -1
- package/dist/radio-button/index.js +1 -1
- package/dist/radio-button/stories/RadioButton.stories.js +1 -1
- package/dist/select/ODataSelect.d.ts +9 -0
- package/dist/select/ODataSelect.d.ts.map +1 -0
- package/dist/select/Select.d.ts.map +1 -1
- package/dist/select/index.js +2 -2
- package/dist/select/model/useODataSelect.d.ts +25 -0
- package/dist/select/model/useODataSelect.d.ts.map +1 -0
- package/dist/select/model/useODataSelectBase.d.ts +24 -0
- package/dist/select/model/useODataSelectBase.d.ts.map +1 -0
- package/dist/select/stories/ODataSelect.stories.d.ts +46 -0
- package/dist/select/stories/ODataSelect.stories.d.ts.map +1 -0
- package/dist/select/stories/Select.stories.js +1 -1
- package/dist/select/stories/SerializableSelect.stories.js +1 -1
- package/dist/select/stories/odataStoryCollection.d.ts +2 -0
- package/dist/select/stories/odataStoryCollection.d.ts.map +1 -0
- package/dist/select/stories/odataStoryFixtures.d.ts +35 -0
- package/dist/select/stories/odataStoryFixtures.d.ts.map +1 -0
- package/dist/simple-table/index.js +1 -1
- package/dist/simple-table/index.js.map +1 -1
- package/dist/slider/Slider.d.ts.map +1 -1
- package/dist/slider/index.js +1 -1
- package/dist/slider/stories/Slider.stories.js +1 -1
- package/dist/slider/stories/SliderInput.stories.js +1 -1
- package/dist/sortable/Sortable.d.ts.map +1 -1
- package/dist/sortable/SortableDragHandle.d.ts.map +1 -1
- package/dist/sortable/index.js +1 -1
- package/dist/sortable/stories/Sortable.stories.js +1 -1
- package/dist/state-select/index.js +1 -1
- package/dist/state-select/stories/StateSelect.stories.d.ts.map +1 -1
- package/dist/state-select/stories/StateSelect.stories.js +1 -1
- package/dist/state-select/stories/StateSelect.stories.js.map +1 -1
- package/dist/switch/Switch.d.ts.map +1 -1
- package/dist/switch/index.js +1 -1
- package/dist/switch/stories/Switch.stories.js +1 -1
- package/dist/table/Table.d.ts +1 -1
- package/dist/table/Table.d.ts.map +1 -1
- package/dist/table/index.js +1 -1
- package/dist/table/stories/Table.stories.d.ts +155 -0
- package/dist/table/stories/Table.stories.d.ts.map +1 -0
- package/dist/table-column-interactions/TableHeaderInteractionCell.d.ts.map +1 -1
- package/dist/tabs/index.js +1 -1
- package/dist/tabs/stories/Tabs.stories.d.ts.map +1 -1
- package/dist/tabs/stories/Tabs.stories.js +2 -2
- package/dist/tabs/stories/Tabs.stories.js.map +1 -1
- package/dist/text/TextOverflow.d.ts.map +1 -1
- package/dist/text/index.js.map +1 -1
- package/dist/text-editor/TextEditorLexicalClient.d.ts.map +1 -1
- package/dist/text-editor/index.js +2 -2
- package/dist/textarea/index.js +1 -1
- package/dist/textarea/stories/Textarea.stories.js +1 -1
- package/dist/tree-select/ODataTreeMultiSelect.d.ts +12 -0
- package/dist/tree-select/ODataTreeMultiSelect.d.ts.map +1 -0
- package/dist/tree-select/ODataTreeSelect.d.ts +13 -0
- package/dist/tree-select/ODataTreeSelect.d.ts.map +1 -0
- package/dist/tree-select/TreeNodeContent.d.ts.map +1 -1
- package/dist/tree-select/TreePickerBase.d.ts.map +1 -1
- package/dist/tree-select/index.js +2 -2
- package/dist/tree-select/model/buildODataTreeNodes.d.ts +12 -0
- package/dist/tree-select/model/buildODataTreeNodes.d.ts.map +1 -0
- package/dist/tree-select/model/resolveOrderedTreeSegmentItems.d.ts +4 -0
- package/dist/tree-select/model/resolveOrderedTreeSegmentItems.d.ts.map +1 -0
- package/dist/tree-select/model/useODataTreeData.d.ts +11 -0
- package/dist/tree-select/model/useODataTreeData.d.ts.map +1 -0
- package/dist/tree-select/stories/ODataTreeMultiSelect.stories.d.ts +55 -0
- package/dist/tree-select/stories/ODataTreeMultiSelect.stories.d.ts.map +1 -0
- package/dist/tree-select/stories/ODataTreeSelect.stories.d.ts +54 -0
- package/dist/tree-select/stories/ODataTreeSelect.stories.d.ts.map +1 -0
- package/dist/tree-select/stories/TreeMultiSelect.stories.js +1 -1
- package/dist/tree-select/stories/TreeSelect.stories.js +1 -1
- package/dist/tree-table/TreeTable.d.ts +1 -1
- package/dist/tree-table/TreeTable.d.ts.map +1 -1
- package/dist/tree-table/index.js +2 -2
- package/dist/tree-table/index.js.map +1 -1
- package/dist/tree-table/stories/TreeTable.stories.d.ts +158 -0
- package/dist/tree-table/stories/TreeTable.stories.d.ts.map +1 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +0 -0
- package/package.json +15 -7
- package/dist/chunks/BadgeList-DHW_Ktr3.js.map +0 -1
- package/dist/chunks/CheckBox-Cck5w1Ud.js.map +0 -1
- package/dist/chunks/DateInput-CINDYueM.js.map +0 -1
- package/dist/chunks/DisclosureGroup-0BtaXO54.js.map +0 -1
- package/dist/chunks/DropZone-hf7Em__0.js.map +0 -1
- package/dist/chunks/Input-Ce2HXBUc.js.map +0 -1
- package/dist/chunks/InputFile-ga5yJmdZ.js.map +0 -1
- package/dist/chunks/InputFiles-Or2Nvfgk.js.map +0 -1
- package/dist/chunks/LabeledExpandableActionPanel-Bx-DWmYz.js.map +0 -1
- package/dist/chunks/Listbox-CY1wQOCP.js.map +0 -1
- package/dist/chunks/NotificationsHost-BQc-zOr2.js.map +0 -1
- package/dist/chunks/RadioButton-DJp31HFR.js.map +0 -1
- package/dist/chunks/Select-B7k_8_Lf.js.map +0 -1
- package/dist/chunks/SingleDateTimeInput-CwvIbwje.js.map +0 -1
- package/dist/chunks/Switch-B476FBUD.js.map +0 -1
- package/dist/chunks/TreePickerBase-DYzTsSBQ.js.map +0 -1
- package/dist/chunks/base-table-DVje02Zi.js.map +0 -1
- package/dist/chunks/layout-picker-BA9vA8JI.js.map +0 -1
- package/dist/chunks/misc-DrmMj8GO.js.map +0 -1
- package/dist/chunks/modal-DqVcZws_.js.map +0 -1
- package/dist/chunks/picker-Cj4RnJh6.js.map +0 -1
- package/dist/chunks/slider-34wxzKkG.js.map +0 -1
- package/dist/chunks/sortable-CwDHC3CA.js.map +0 -1
- package/dist/chunks/table-BYA0hCj7.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextEditorLexicalClient-DcixYuo4.js","names":[],"sources":["../../src/text-editor/lib/serialization/createLexicalRaw.ts","../../src/text-editor/lib/semantic/getSemanticTagDepth.ts","../../src/text-editor/nodes/AccessibleLinkNode.ts","../../src/text-editor/nodes/SemanticTagNode.ts","../../src/text-editor/model/hooks/useTextEditorLexicalActions.ts","../../src/text-editor/TextEditor.module.scss","../../src/text-editor/EmailDialog.tsx","../../src/text-editor/LinkDialog.tsx","../../src/text-editor/PhoneDialog.tsx","../../src/text-editor/SemanticDialog.tsx","../../src/text-editor/semanticTagConfigs.tsx","../../src/text-editor/TimeDialog.tsx","../../src/text-editor/TextEditorDialogs.tsx","../../src/text-editor/TextEditorLexicalClient.tsx"],"sourcesContent":["import { EditorState as LexicalEditorState } from \"lexical\";\n\nimport type { TextEditorLexicalRaw } from \"../../editorModel\";\n\nexport const createLexicalRaw = (editorState: LexicalEditorState): TextEditorLexicalRaw => {\n\treturn {\n\t\tformat: \"lexical\",\n\t\tversion: 1,\n\t\teditorState: editorState.toJSON() as unknown as Record<string, unknown>\n\t};\n};\n","import type { LexicalNode } from \"lexical\";\n\nexport const getSemanticTagDepth = (node: LexicalNode): number => {\n\tlet depth = 0;\n\tlet current: LexicalNode | null = node;\n\n\twhile (current) {\n\t\tdepth += 1;\n\t\tcurrent = current.getParent();\n\t}\n\n\treturn depth;\n};\n","import { LinkAttributes, LinkNode, SerializedLinkNode } from \"@lexical/link\";\nimport {\n\t$applyNodeReplacement,\n\tDOMConversionMap,\n\tDOMConversionOutput,\n\tEditorConfig,\n\tElementNode,\n\tLexicalNode,\n\tLexicalUpdateJSON,\n\tNodeKey,\n\tRangeSelection,\n\tSpread\n} from \"lexical\";\n\nexport type AccessibleLinkAttributes = LinkAttributes & {\n\tariaLabel?: null | string;\n\tqrCode?: boolean;\n\tadd?: null | string;\n\ttext?: null | string;\n};\n\nexport type SerializedAccessibleLinkNode = Spread<\n\t{\n\t\tariaLabel: null | string;\n\t\tqrCode: boolean;\n\t\tadd: null | string;\n\t\ttext: null | string;\n\t},\n\tSerializedLinkNode\n>;\n\nconst convertAccessibleLinkElement = (domNode: Node): DOMConversionOutput => {\n\tif (!(domNode instanceof HTMLAnchorElement)) {\n\t\treturn { node: null };\n\t}\n\n\tconst textContent = domNode.textContent;\n\tif ((textContent === null || textContent === \"\") && domNode.children.length === 0) {\n\t\treturn { node: null };\n\t}\n\n\treturn {\n\t\tnode: $createAccessibleLinkNode(domNode.getAttribute(\"href\") || \"\", {\n\t\t\trel: domNode.getAttribute(\"rel\"),\n\t\t\ttarget: domNode.getAttribute(\"target\"),\n\t\t\ttitle: domNode.getAttribute(\"title\"),\n\t\t\tariaLabel: domNode.getAttribute(\"aria-label\"),\n\t\t\tqrCode: domNode.getAttribute(\"data-qr-code\") === \"true\",\n\t\t\tadd: null,\n\t\t\ttext: textContent\n\t\t})\n\t};\n};\n\nexport class AccessibleLinkNode extends LinkNode {\n\t__ariaLabel: null | string;\n\t__qrCode: boolean;\n\t__add: null | string;\n\t__text: null | string;\n\n\tstatic getType(): string {\n\t\treturn \"accessible-link\";\n\t}\n\n\tstatic clone(node: AccessibleLinkNode): AccessibleLinkNode {\n\t\treturn new AccessibleLinkNode(\n\t\t\tnode.__url,\n\t\t\t{\n\t\t\t\trel: node.__rel,\n\t\t\t\ttarget: node.__target,\n\t\t\t\ttitle: node.__title,\n\t\t\t\tariaLabel: node.__ariaLabel,\n\t\t\t\tqrCode: node.__qrCode,\n\t\t\t\tadd: node.__add,\n\t\t\t\ttext: node.__text\n\t\t\t},\n\t\t\tnode.__key\n\t\t);\n\t}\n\n\tconstructor(url = \"\", attributes: AccessibleLinkAttributes = {}, key?: NodeKey) {\n\t\tsuper(url, attributes, key);\n\n\t\tconst { ariaLabel = null, qrCode = false, add = null, text = null } = attributes;\n\t\tthis.__ariaLabel = ariaLabel;\n\t\tthis.__qrCode = qrCode;\n\t\tthis.__add = add;\n\t\tthis.__text = text;\n\t}\n\n\tstatic importDOM(): DOMConversionMap | null {\n\t\treturn {\n\t\t\ta: () => ({\n\t\t\t\tconversion: convertAccessibleLinkElement,\n\t\t\t\tpriority: 2\n\t\t\t})\n\t\t};\n\t}\n\n\tstatic importJSON(serializedNode: SerializedAccessibleLinkNode): AccessibleLinkNode {\n\t\treturn $createAccessibleLinkNode().updateFromJSON(serializedNode);\n\t}\n\n\tupdateFromJSON(serializedNode: LexicalUpdateJSON<SerializedAccessibleLinkNode>): this {\n\t\treturn super\n\t\t\t.updateFromJSON(serializedNode)\n\t\t\t.setAriaLabel(serializedNode.ariaLabel || null)\n\t\t\t.setQrCode(!!serializedNode.qrCode)\n\t\t\t.setAdd(serializedNode.add || null)\n\t\t\t.setText(serializedNode.text || null);\n\t}\n\n\texportJSON(): SerializedAccessibleLinkNode {\n\t\treturn {\n\t\t\t...super.exportJSON(),\n\t\t\ttype: \"accessible-link\",\n\t\t\tversion: 1,\n\t\t\tariaLabel: this.getAriaLabel(),\n\t\t\tqrCode: this.getQrCode(),\n\t\t\tadd: this.getAdd(),\n\t\t\ttext: this.getText()\n\t\t} as SerializedAccessibleLinkNode;\n\t}\n\n\tcreateDOM(config: EditorConfig): HTMLElement {\n\t\tconst dom = super.createDOM(config) as HTMLElement;\n\t\tthis.applyAccessibleAttributes(null, dom);\n\t\treturn dom;\n\t}\n\n\tupdateDOM(prevNode: this, anchor: HTMLElement, config: EditorConfig): boolean {\n\t\tconst isUpdated = super.updateDOM(prevNode, anchor as never, config);\n\t\tthis.applyAccessibleAttributes(prevNode, anchor);\n\t\treturn isUpdated;\n\t}\n\n\tapplyAccessibleAttributes(prevNode: this | null, anchor: HTMLElement): void {\n\t\tif (!(anchor instanceof HTMLAnchorElement)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!prevNode || prevNode.__ariaLabel !== this.__ariaLabel) {\n\t\t\tif (this.__ariaLabel) {\n\t\t\t\tanchor.setAttribute(\"aria-label\", this.__ariaLabel);\n\t\t\t} else {\n\t\t\t\tanchor.removeAttribute(\"aria-label\");\n\t\t\t}\n\t\t}\n\n\t\tif (!prevNode || prevNode.__qrCode !== this.__qrCode) {\n\t\t\tanchor.setAttribute(\"data-qr-code\", this.__qrCode ? \"true\" : \"false\");\n\t\t}\n\t}\n\n\tinsertNewAfter(_selection: RangeSelection, restoreSelection = true): null | ElementNode {\n\t\tconst linkNode = $createAccessibleLinkNode(this.__url, {\n\t\t\trel: this.__rel,\n\t\t\ttarget: this.__target,\n\t\t\ttitle: this.__title,\n\t\t\tariaLabel: this.__ariaLabel,\n\t\t\tqrCode: this.__qrCode,\n\t\t\tadd: this.__add,\n\t\t\ttext: this.__text\n\t\t});\n\t\tthis.insertAfter(linkNode, restoreSelection);\n\t\treturn linkNode;\n\t}\n\n\tgetAriaLabel(): null | string {\n\t\treturn this.getLatest().__ariaLabel;\n\t}\n\n\tsetAriaLabel(ariaLabel: null | string): this {\n\t\tconst writable = this.getWritable();\n\t\twritable.__ariaLabel = ariaLabel;\n\t\treturn this;\n\t}\n\n\tgetQrCode(): boolean {\n\t\treturn this.getLatest().__qrCode;\n\t}\n\n\tsetQrCode(qrCode: boolean): this {\n\t\tconst writable = this.getWritable();\n\t\twritable.__qrCode = qrCode;\n\t\treturn this;\n\t}\n\n\tgetAdd(): null | string {\n\t\treturn this.getLatest().__add;\n\t}\n\n\tsetAdd(add: null | string): this {\n\t\tconst writable = this.getWritable();\n\t\twritable.__add = add;\n\t\treturn this;\n\t}\n\n\tgetText(): null | string {\n\t\treturn this.getLatest().__text;\n\t}\n\n\tsetText(text: null | string): this {\n\t\tconst writable = this.getWritable();\n\t\twritable.__text = text;\n\t\treturn this;\n\t}\n}\n\nexport const $createAccessibleLinkNode = (url = \"\", attributes?: AccessibleLinkAttributes): AccessibleLinkNode => {\n\treturn $applyNodeReplacement(new AccessibleLinkNode(url, attributes));\n};\n\nexport const $isAccessibleLinkNode = (node: LexicalNode | null | undefined): node is AccessibleLinkNode => {\n\treturn node instanceof AccessibleLinkNode;\n};\n","import {\n\t$applyNodeReplacement,\n\tDOMConversionMap,\n\tDOMConversionOutput,\n\tEditorConfig,\n\tElementNode,\n\tLexicalNode,\n\tLexicalUpdateJSON,\n\tNodeKey,\n\tRangeSelection,\n\tSerializedElementNode,\n\tSpread\n} from \"lexical\";\n\nexport type SemanticTagAttributes = Record<string, string>;\n\nexport type SerializedSemanticTagNode = Spread<\n\t{\n\t\ttag: string;\n\t\tattributes: SemanticTagAttributes;\n\t\ttext: null | string;\n\t},\n\tSerializedElementNode\n>;\n\nconst getAttributesFromElement = (element: HTMLElement): SemanticTagAttributes => {\n\tconst attributes: SemanticTagAttributes = {};\n\tArray.from(element.attributes).forEach((attr) => {\n\t\tif (attr.name === \"class\") return;\n\t\tattributes[attr.name] = attr.value;\n\t});\n\treturn attributes;\n};\n\nconst convertSemanticTagElement = (domNode: Node): DOMConversionOutput => {\n\tif (!(domNode instanceof HTMLElement)) {\n\t\treturn { node: null };\n\t}\n\n\tconst tag = domNode.tagName.toLowerCase();\n\tif (![\"abbr\", \"span\", \"time\", \"cite\", \"del\", \"ins\"].includes(tag)) {\n\t\treturn { node: null };\n\t}\n\n\tconst text = domNode.textContent;\n\tif ((text === null || text === \"\") && domNode.children.length === 0) {\n\t\treturn { node: null };\n\t}\n\n\treturn {\n\t\tnode: $createSemanticTagNode(tag, getAttributesFromElement(domNode), text)\n\t};\n};\n\nexport class SemanticTagNode extends ElementNode {\n\t__tag: string;\n\t__attributes: SemanticTagAttributes;\n\t__text: null | string;\n\n\tstatic getType(): string {\n\t\treturn \"semantic-tag\";\n\t}\n\n\tstatic clone(node: SemanticTagNode): SemanticTagNode {\n\t\treturn new SemanticTagNode(node.__tag, node.__attributes, node.__text, node.__key);\n\t}\n\n\tconstructor(tag = \"span\", attributes: SemanticTagAttributes = {}, text: null | string = null, key?: NodeKey) {\n\t\tsuper(key);\n\t\tthis.__tag = tag;\n\t\tthis.__attributes = attributes;\n\t\tthis.__text = text;\n\t}\n\n\tstatic importDOM(): DOMConversionMap | null {\n\t\treturn {\n\t\t\tabbr: () => ({ conversion: convertSemanticTagElement, priority: 2 }),\n\t\t\tspan: () => ({ conversion: convertSemanticTagElement, priority: 2 }),\n\t\t\ttime: () => ({ conversion: convertSemanticTagElement, priority: 2 }),\n\t\t\tcite: () => ({ conversion: convertSemanticTagElement, priority: 2 }),\n\t\t\tdel: () => ({ conversion: convertSemanticTagElement, priority: 2 }),\n\t\t\tins: () => ({ conversion: convertSemanticTagElement, priority: 2 })\n\t\t};\n\t}\n\n\tstatic importJSON(serializedNode: SerializedSemanticTagNode): SemanticTagNode {\n\t\treturn $createSemanticTagNode(serializedNode.tag, serializedNode.attributes, serializedNode.text).updateFromJSON(serializedNode);\n\t}\n\n\tupdateFromJSON(serializedNode: LexicalUpdateJSON<SerializedSemanticTagNode>): this {\n\t\treturn super\n\t\t\t.updateFromJSON(serializedNode)\n\t\t\t.setTag(serializedNode.tag)\n\t\t\t.setAttributes(serializedNode.attributes || {})\n\t\t\t.setText(serializedNode.text || null);\n\t}\n\n\texportJSON(): SerializedSemanticTagNode {\n\t\treturn {\n\t\t\t...super.exportJSON(),\n\t\t\ttype: \"semantic-tag\",\n\t\t\tversion: 1,\n\t\t\ttag: this.getTag(),\n\t\t\tattributes: this.getAttributes(),\n\t\t\ttext: this.getText()\n\t\t};\n\t}\n\n\tcreateDOM(config: EditorConfig): HTMLElement {\n\t\tvoid config;\n\t\tconst element = document.createElement(this.__tag);\n\t\tthis.applyEditorAttributes(element);\n\t\treturn element;\n\t}\n\n\tupdateDOM(prevNode: this, dom: HTMLElement): boolean {\n\t\tif (prevNode.__tag !== this.__tag) {\n\t\t\treturn true;\n\t\t}\n\n\t\tthis.applyEditorAttributes(dom);\n\t\treturn false;\n\t}\n\n\texportDOM(): { element: HTMLElement } {\n\t\tconst element = document.createElement(this.__tag);\n\t\tObject.entries(this.__attributes).forEach(([key, value]) => {\n\t\t\telement.setAttribute(key, value);\n\t\t});\n\t\treturn { element };\n\t}\n\n\tapplyEditorAttributes(dom: HTMLElement): void {\n\t\tdom.classList.add(\"custom-tag-highlight\");\n\t\tArray.from(dom.attributes).forEach((attr) => {\n\t\t\tif (attr.name === \"class\") return;\n\t\t\tdom.removeAttribute(attr.name);\n\t\t});\n\t\tObject.entries(this.__attributes).forEach(([key, value]) => {\n\t\t\tdom.setAttribute(key, value);\n\t\t});\n\t}\n\n\tinsertNewAfter(_selection: RangeSelection, restoreSelection = true): null | ElementNode {\n\t\tconst node = $createSemanticTagNode(this.__tag, this.__attributes, this.__text);\n\t\tthis.insertAfter(node, restoreSelection);\n\t\treturn node;\n\t}\n\n\tcanInsertTextBefore(): boolean {\n\t\treturn false;\n\t}\n\n\tcanInsertTextAfter(): boolean {\n\t\treturn false;\n\t}\n\n\tcanBeEmpty(): boolean {\n\t\treturn false;\n\t}\n\n\tisInline(): boolean {\n\t\treturn true;\n\t}\n\n\tgetTag(): string {\n\t\treturn this.getLatest().__tag;\n\t}\n\n\tsetTag(tag: string): this {\n\t\tconst writable = this.getWritable();\n\t\twritable.__tag = tag;\n\t\treturn this;\n\t}\n\n\tgetAttributes(): SemanticTagAttributes {\n\t\treturn this.getLatest().__attributes;\n\t}\n\n\tsetAttributes(attributes: SemanticTagAttributes): this {\n\t\tconst writable = this.getWritable();\n\t\twritable.__attributes = attributes;\n\t\treturn this;\n\t}\n\n\tgetText(): null | string {\n\t\treturn this.getLatest().__text;\n\t}\n\n\tsetText(text: null | string): this {\n\t\tconst writable = this.getWritable();\n\t\twritable.__text = text;\n\t\treturn this;\n\t}\n}\n\nexport const $createSemanticTagNode = (\n\ttag: string,\n\tattributes: SemanticTagAttributes = {},\n\ttext: null | string = null\n): SemanticTagNode => {\n\treturn $applyNodeReplacement(new SemanticTagNode(tag, attributes, text));\n};\n\nexport const $isSemanticTagNode = (node: LexicalNode | null | undefined): node is SemanticTagNode => {\n\treturn node instanceof SemanticTagNode;\n};\n","import { useCallback } from \"react\";\n\nimport { $isLinkNode } from \"@lexical/link\";\nimport { INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND, REMOVE_LIST_COMMAND } from \"@lexical/list\";\nimport { $createHeadingNode, $createQuoteNode } from \"@lexical/rich-text\";\nimport { $setBlocksType } from \"@lexical/selection\";\nimport { $findMatchingParent } from \"@lexical/utils\";\nimport {\n\t$createParagraphNode,\n\t$createTextNode,\n\t$getSelection,\n\t$isRangeSelection,\n\tElementFormatType,\n\tFORMAT_ELEMENT_COMMAND,\n\tFORMAT_TEXT_COMMAND,\n\ttype LexicalEditor,\n\ttype LexicalNode,\n\tREDO_COMMAND,\n\tUNDO_COMMAND\n} from \"lexical\";\n\nimport { getSemanticTagDepth } from \"../../lib/semantic/getSemanticTagDepth\";\nimport { getHeadingTagByStyle, getLexicalInlineStyle } from \"../../lib/toolbar/styleMappers\";\nimport { $createAccessibleLinkNode, $isAccessibleLinkNode } from \"../../nodes/AccessibleLinkNode\";\nimport { $createSemanticTagNode, $isSemanticTagNode, type SemanticTagNode } from \"../../nodes/SemanticTagNode\";\nimport { LinkTypes, TagTypes } from \"../../toolbar\";\nimport { type LexicalToolbarState, type LinkType, type TextAlignment } from \"../textEditorTypes\";\n\ninterface InsertLinkPayload {\n\turl: string;\n\ttext: string;\n\tadd: string;\n\tariaLabel: string;\n\tqrCode: boolean;\n}\n\ninterface UseTextEditorLexicalActionsParams {\n\teditor: LexicalEditor | null;\n\ttoolbarState: LexicalToolbarState;\n\thasLocalLinkDialog: boolean;\n\tonOpenLinkDialog: (type: LinkTypes) => void;\n\tonOpenTagDialog: (type: TagTypes) => void;\n}\n\nexport function useTextEditorLexicalActions({\n\teditor,\n\ttoolbarState,\n\thasLocalLinkDialog,\n\tonOpenLinkDialog,\n\tonOpenTagDialog\n}: UseTextEditorLexicalActionsParams) {\n\tconst handleBlockStyleToggle = useCallback(\n\t\t(style: string) => {\n\t\t\tif (!editor) return;\n\n\t\t\tif (style === \"unordered-list-item\") {\n\t\t\t\tif (toolbarState.blockType === \"unordered-list-item\") {\n\t\t\t\t\teditor.dispatchCommand(REMOVE_LIST_COMMAND, undefined);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\teditor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, undefined);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (style === \"ordered-list-item\") {\n\t\t\t\tif (toolbarState.blockType === \"ordered-list-item\") {\n\t\t\t\t\teditor.dispatchCommand(REMOVE_LIST_COMMAND, undefined);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\teditor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, undefined);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\teditor.update(() => {\n\t\t\t\tconst selection = $getSelection();\n\t\t\t\tif (!$isRangeSelection(selection)) return;\n\n\t\t\t\tif (style === \"unstyled\" || style === \"paragraph\") {\n\t\t\t\t\t$setBlocksType(selection, () => $createParagraphNode());\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (style === \"blockquote\") {\n\t\t\t\t\t$setBlocksType(selection, () => $createQuoteNode());\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst headingTag = getHeadingTagByStyle(style);\n\t\t\t\tif (headingTag) {\n\t\t\t\t\t$setBlocksType(selection, () => $createHeadingNode(headingTag));\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t\t[editor, toolbarState.blockType]\n\t);\n\n\tconst handleInlineStyleToggle = useCallback(\n\t\t(style: string) => {\n\t\t\tif (!editor) return;\n\n\t\t\tconst lexicalStyle = getLexicalInlineStyle(style);\n\t\t\tif (!lexicalStyle) return;\n\n\t\t\teditor.dispatchCommand(FORMAT_TEXT_COMMAND, lexicalStyle as never);\n\t\t},\n\t\t[editor]\n\t);\n\n\tconst handleAlignmentChange = useCallback(\n\t\t(alignment: TextAlignment) => {\n\t\t\tif (!editor) return;\n\t\t\teditor.dispatchCommand(FORMAT_ELEMENT_COMMAND, alignment as ElementFormatType);\n\t\t},\n\t\t[editor]\n\t);\n\n\tconst handleUndo = useCallback(() => {\n\t\tif (!editor) return;\n\t\teditor.dispatchCommand(UNDO_COMMAND, undefined);\n\t}, [editor]);\n\n\tconst handleRedo = useCallback(() => {\n\t\tif (!editor) return;\n\t\teditor.dispatchCommand(REDO_COMMAND, undefined);\n\t}, [editor]);\n\n\tconst getCurrentSelectionText = useCallback((): string => {\n\t\tif (!editor) return \"\";\n\n\t\tlet text = \"\";\n\t\teditor.getEditorState().read(() => {\n\t\t\tconst selection = $getSelection();\n\t\t\tif (!$isRangeSelection(selection)) return;\n\t\t\ttext = selection.getTextContent();\n\t\t});\n\n\t\treturn text;\n\t}, [editor]);\n\n\tconst insertLinkAtSelection = useCallback(\n\t\t(payload: InsertLinkPayload) => {\n\t\t\tif (!editor) return;\n\n\t\t\teditor.update(() => {\n\t\t\t\tconst selection = $getSelection();\n\t\t\t\tif (!$isRangeSelection(selection)) return;\n\n\t\t\t\tconst selectionText = selection.getTextContent();\n\t\t\t\tconst finalText = payload.text.length > 0 ? payload.text : selectionText;\n\t\t\t\tif (!finalText.trim()) return;\n\n\t\t\t\tconst linkNode = $createAccessibleLinkNode(payload.url, {\n\t\t\t\t\ttarget: \"_blank\",\n\t\t\t\t\trel: \"noopener noreferrer\",\n\t\t\t\t\tariaLabel: payload.ariaLabel || selectionText || finalText,\n\t\t\t\t\tqrCode: payload.qrCode,\n\t\t\t\t\tadd: payload.add || null,\n\t\t\t\t\ttext: finalText\n\t\t\t\t});\n\n\t\t\t\tconst textNode = $createTextNode(finalText);\n\t\t\t\tlinkNode.append(textNode);\n\t\t\t\tselection.insertNodes([linkNode]);\n\t\t\t});\n\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\teditor.focus();\n\t\t\t});\n\t\t},\n\t\t[editor]\n\t);\n\n\tconst handleAddLink = useCallback(\n\t\t(url: string, text: string, add: string, ariaLabel: string, showQrCode: boolean) => {\n\t\t\tinsertLinkAtSelection({\n\t\t\t\turl,\n\t\t\t\ttext,\n\t\t\t\tadd,\n\t\t\t\tariaLabel,\n\t\t\t\tqrCode: showQrCode\n\t\t\t});\n\t\t},\n\t\t[insertLinkAtSelection]\n\t);\n\n\tconst handleAddLocalLink = useCallback(\n\t\t(url: string, caption: string) => {\n\t\t\tinsertLinkAtSelection({\n\t\t\t\turl,\n\t\t\t\ttext: caption,\n\t\t\t\tadd: \"\",\n\t\t\t\tariaLabel: \"Внутренняя ссылка на статью: \" + caption,\n\t\t\t\tqrCode: false\n\t\t\t});\n\t\t},\n\t\t[insertLinkAtSelection]\n\t);\n\n\tconst getSelectedLinkState = useCallback((): LinkType => {\n\t\tif (!editor) return \"\";\n\n\t\tlet state: LinkType = \"\";\n\t\teditor.getEditorState().read(() => {\n\t\t\tconst selection = $getSelection();\n\t\t\tif (!$isRangeSelection(selection)) {\n\t\t\t\tstate = \"\";\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst selectionText = selection.getTextContent();\n\t\t\tconst anchorNode = selection.anchor.getNode();\n\t\t\tconst linkNode = $findMatchingParent(anchorNode, (node) => $isAccessibleLinkNode(node) || $isLinkNode(node));\n\n\t\t\tif ($isAccessibleLinkNode(linkNode)) {\n\t\t\t\tstate = {\n\t\t\t\t\turl: linkNode.getURL(),\n\t\t\t\t\tariaLabel: linkNode.getAriaLabel() || \"\",\n\t\t\t\t\ttext: linkNode.getText() || selectionText,\n\t\t\t\t\tadd: linkNode.getAdd() || \"\",\n\t\t\t\t\tqrCode: linkNode.getQrCode()\n\t\t\t\t};\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ($isLinkNode(linkNode)) {\n\t\t\t\tstate = {\n\t\t\t\t\turl: linkNode.getURL(),\n\t\t\t\t\tariaLabel: \"\",\n\t\t\t\t\ttext: selectionText,\n\t\t\t\t\tadd: \"\",\n\t\t\t\t\tqrCode: false\n\t\t\t\t};\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tstate = selectionText;\n\t\t});\n\n\t\treturn state;\n\t}, [editor]);\n\n\tconst handleLinkClick = useCallback(\n\t\t(type: LinkTypes) => {\n\t\t\tif (type === LinkTypes.LOCAL_LINK && !hasLocalLinkDialog) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tonOpenLinkDialog(type);\n\t\t},\n\t\t[hasLocalLinkDialog, onOpenLinkDialog]\n\t);\n\n\tconst insertSemanticTagAtSelection = useCallback(\n\t\t(tag: string, text: string, attributes: Record<string, string>) => {\n\t\t\tif (!editor) return;\n\n\t\t\teditor.update(() => {\n\t\t\t\tconst selection = $getSelection();\n\t\t\t\tif (!$isRangeSelection(selection)) return;\n\n\t\t\t\tconst selectionText = selection.getTextContent().trim();\n\t\t\t\tconst finalText =\n\t\t\t\t\ttext || selectionText || attributes[\"title\"] || attributes[\"aria-label\"] || Object.values(attributes).join(\" \") || tag;\n\n\t\t\t\tif (!finalText.trim()) return;\n\n\t\t\t\tconst node = $createSemanticTagNode(tag, attributes, finalText);\n\t\t\t\tnode.append($createTextNode(finalText));\n\t\t\t\tselection.insertNodes([node]);\n\t\t\t});\n\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\teditor.focus();\n\t\t\t});\n\t\t},\n\t\t[editor]\n\t);\n\n\tconst handleCleanSemanticTag = useCallback(() => {\n\t\tif (!editor) return;\n\n\t\teditor.update(() => {\n\t\t\tconst selection = $getSelection();\n\t\t\tif (!$isRangeSelection(selection) || selection.isCollapsed()) return;\n\n\t\t\tconst selectedNodes = selection.getNodes();\n\t\t\tconst semanticNodes = new Set<SemanticTagNode>();\n\n\t\t\tselectedNodes.forEach((node) => {\n\t\t\t\tlet current: LexicalNode | null = node;\n\t\t\t\twhile (current) {\n\t\t\t\t\tif ($isSemanticTagNode(current)) {\n\t\t\t\t\t\tsemanticNodes.add(current);\n\t\t\t\t\t}\n\t\t\t\t\tcurrent = current.getParent();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tconst sortedNodes = Array.from(semanticNodes).sort((a, b) => getSemanticTagDepth(b) - getSemanticTagDepth(a));\n\t\t\tsortedNodes.forEach((node) => {\n\t\t\t\tif (!node.isAttached()) return;\n\t\t\t\tconst children = node.getChildren();\n\t\t\t\tchildren.forEach((child) => node.insertBefore(child));\n\t\t\t\tnode.remove();\n\t\t\t});\n\t\t});\n\t}, [editor]);\n\n\tconst handleTagClick = useCallback(\n\t\t(type: TagTypes) => {\n\t\t\tonOpenTagDialog(type);\n\t\t},\n\t\t[onOpenTagDialog]\n\t);\n\n\treturn {\n\t\thandleAddLink,\n\t\thandleAddLocalLink,\n\t\thandleAlignmentChange,\n\t\thandleBlockStyleToggle,\n\t\thandleCleanSemanticTag,\n\t\thandleInlineStyleToggle,\n\t\thandleLinkClick,\n\t\thandleRedo,\n\t\thandleTagClick,\n\t\thandleUndo,\n\t\tgetCurrentSelectionText,\n\t\tgetSelectedLinkState,\n\t\tinsertSemanticTagAtSelection\n\t};\n}\n","@use \"@/styles/mixins/mixin\" as *;\n\n.textEditor {\n\tfont-size: inherit;\n}\n\n.textEditorContent {\n\tposition: relative;\n\tpadding: var(--space-md);\n\tborder-radius: var(--radius-md);\n\tbackground-color: var(--surface-secondary);\n\tborder: var(--border);\n\n\t&.focused {\n\t\tborder-color: var(--brand-primary);\n\t}\n}\n\n.wrapper {\n\tfont-size: inherit;\n}\n","import { type MouseEvent, useEffect, useState } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { isSafe } from \"@ryuzaki13/react-foundation-lib/validators\";\n\nimport { Button } from \"../button\";\nimport { Input } from \"../input\";\nimport { Modal, ModalContent, ModalFooter } from \"../modal\";\n\nimport { LinkType } from \"./linkTypes\";\n\ninterface EmailDialogProps {\n\tisOpen: boolean;\n\tonClose: () => void;\n\tonConfirm: (url: string, text: string, add: string, ariaLabel: string, showQrCode: boolean) => void;\n\tinitialState?: LinkType;\n}\n\n/**\n * Диалог вставки или редактирования email-ссылки в текстовом редакторе.\n */\nexport function EmailDialog({ isOpen, onClose, onConfirm, initialState }: EmailDialogProps) {\n\tconst [email, setEmail] = useState(\"\");\n\tconst [ariaLabel, setAriaLabel] = useState(\"\");\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [state] = useState(() => {\n\t\tif (isSafe(initialState) && typeof initialState === \"string\") {\n\t\t\treturn { text: \"\", add: \"\", ariaLabel: \"\", url: initialState };\n\t\t}\n\n\t\treturn initialState;\n\t});\n\n\tuseEffect(() => {\n\t\tif (isOpen) {\n\t\t\tif (isSafe(state)) {\n\t\t\t\tsetEmail(state.url ?? \"\");\n\t\t\t\tsetAriaLabel(state.ariaLabel ?? \"\");\n\t\t\t}\n\t\t}\n\t}, [isOpen, state]);\n\n\tconst validateEmail = (email: string): boolean => {\n\t\tconst emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\t\tif (!emailRegex.test(email)) {\n\t\t\tsetError(\"Некорректный email адрес\");\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t};\n\n\tconst handleConfirm = (e: MouseEvent) => {\n\t\te.preventDefault();\n\n\t\tif (!validateEmail(email)) return;\n\t\tif (!ariaLabel) {\n\t\t\tsetError(\"Добавьте описание для email\");\n\t\t\treturn;\n\t\t}\n\n\t\tonConfirm(`mailto:${email}`, \"\", \"\", ariaLabel, false);\n\t\thandleClose();\n\t};\n\n\tconst handleClose = () => {\n\t\tsetEmail(\"\");\n\t\tsetAriaLabel(\"\");\n\t\tsetError(null);\n\t\tonClose();\n\t};\n\n\treturn (\n\t\t<Modal isOpen={isOpen} onClose={handleClose} title=\"Ссылка на email\" size=\"md\">\n\t\t\t<ModalContent>\n\t\t\t\t<div className={cn(\"flexColumn\", \"gapMd\")}>\n\t\t\t\t\t<Input label=\"Email адрес\" value={email} onChange={setEmail} placeholder=\"some_email@mail.ru\" />\n\n\t\t\t\t\t{error && (\n\t\t\t\t\t\t<div className=\"textColorDanger\">\n\t\t\t\t\t\t\t<strong>Ошибка ввода:</strong> <span className=\"fontItalic\">{error}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<Input\n\t\t\t\t\t\tlabel=\"Текст для экранных читалок\"\n\t\t\t\t\t\tvalue={ariaLabel}\n\t\t\t\t\t\tonChange={setAriaLabel}\n\t\t\t\t\t\tplaceholder=\"Электронная почта руководителя городской думмы\"\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t</ModalContent>\n\t\t\t<ModalFooter>\n\t\t\t\t<Button appearance=\"outline\" tone=\"error\" onClick={handleClose}>\n\t\t\t\t\tОтмена\n\t\t\t\t</Button>\n\t\t\t\t<Button appearance=\"outline\" tone=\"success\" onClick={handleConfirm} disabled={!email || !ariaLabel}>\n\t\t\t\t\tПодтвердить\n\t\t\t\t</Button>\n\t\t\t</ModalFooter>\n\t\t</Modal>\n\t);\n}\n","import { type MouseEvent, useEffect, useState } from \"react\";\n\nimport { isSafe, validateUrl } from \"@ryuzaki13/react-foundation-lib/validators\";\n\nimport { Button } from \"../button\";\nimport { CheckBox } from \"../check-box\";\nimport { GridContainer } from \"../grid\";\nimport { Input } from \"../input\";\nimport { Modal, ModalContent, ModalFooter } from \"../modal\";\n\nimport { LinkType } from \"./linkTypes\";\n\ninterface LinkDialogProps {\n\tisOpen: boolean;\n\tonClose: () => void;\n\tonConfirm: (url: string, text: string, add: string, ariaLabel: string, showQrCode: boolean) => void;\n\tinitialState?: LinkType;\n}\n\n/**\n * Диалог вставки или редактирования ссылки в текстовом редакторе.\n */\nexport function LinkDialog({ isOpen, onClose, onConfirm, initialState }: LinkDialogProps) {\n\tconst [url, setUrl] = useState(\"\");\n\tconst [ariaLabel, setAriaLabel] = useState(\"\");\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [showQrCode, setShowQrCode] = useState(false);\n\tconst [state] = useState(() => {\n\t\tif (isSafe(initialState)) {\n\t\t\tif (typeof initialState === \"string\") {\n\t\t\t\treturn { text: \"\", add: \"\", ariaLabel: \"\", url: initialState };\n\t\t\t}\n\t\t}\n\t\treturn initialState;\n\t});\n\n\tuseEffect(() => {\n\t\tif (isOpen) {\n\t\t\tif (isSafe(state)) {\n\t\t\t\tsetUrl(state.url ?? \"\");\n\t\t\t\tsetAriaLabel(state.ariaLabel ?? \"\");\n\t\t\t}\n\t\t}\n\t}, [isOpen, state]);\n\n\tconst handleUrlChange = (value: string) => {\n\t\tsetUrl(value);\n\n\t\t// Очищаем ошибку при изменении URL\n\t\tif (error) {\n\t\t\tsetError(null);\n\t\t}\n\t};\n\n\tconst handleConfirm = (e: MouseEvent) => {\n\t\te.preventDefault();\n\n\t\tconst validation = validateUrl(url);\n\t\tif (!validation.isValid) {\n\t\t\tsetError(validation.error);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!ariaLabel) {\n\t\t\tsetError(\"добавьте описание для ссылки\");\n\t\t\treturn;\n\t\t}\n\n\t\t// Добавляем протокол, если его нет\n\t\tconst finalUrl = url.startsWith(\"http\") ? url : `https://${url}`;\n\t\tonConfirm(finalUrl, \"\", \"\", ariaLabel, showQrCode);\n\t\thandleClose();\n\t};\n\n\tconst handleClose = () => {\n\t\tsetUrl(\"\");\n\t\tsetAriaLabel(\"\");\n\t\tsetError(null);\n\t\tonClose();\n\t};\n\n\treturn (\n\t\t<Modal isOpen={isOpen} onClose={handleClose} title=\"Ссылка на внешний url\" size=\"md\">\n\t\t\t<ModalContent>\n\t\t\t\t<GridContainer gap=\"md\">\n\t\t\t\t\t<Input label=\"Полный URL адрес\" value={url} onChange={handleUrlChange} placeholder=\"https://somesite.ru\" />\n\n\t\t\t\t\t{error && (\n\t\t\t\t\t\t<div className=\"textColorDanger\">\n\t\t\t\t\t\t\t<strong>Ошибка ввода:</strong> <span className=\"fontItalic\">{error}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<Input\n\t\t\t\t\t\tlabel=\"Текст для экранных читалок\"\n\t\t\t\t\t\tvalue={ariaLabel}\n\t\t\t\t\t\tonChange={setAriaLabel}\n\t\t\t\t\t\tplaceholder=\"Ссылка на официальный сайт городской думмы\"\n\t\t\t\t\t/>\n\n\t\t\t\t\t<CheckBox title=\"Показать кнопку для генерации QR кода ссылки\" value={showQrCode} onChange={setShowQrCode} />\n\t\t\t\t</GridContainer>\n\t\t\t</ModalContent>\n\t\t\t<ModalFooter>\n\t\t\t\t<Button appearance=\"outline\" tone=\"error\" onClick={handleClose}>\n\t\t\t\t\tОтмена\n\t\t\t\t</Button>\n\t\t\t\t<Button appearance=\"outline\" tone=\"success\" onClick={handleConfirm} disabled={!url || !ariaLabel}>\n\t\t\t\t\tПодтвердить\n\t\t\t\t</Button>\n\t\t\t</ModalFooter>\n\t\t</Modal>\n\t);\n}\n","import { type MouseEvent, useEffect, useState } from \"react\";\n\nimport { formatPhone } from \"@ryuzaki13/react-foundation-lib/formatters\";\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { isSafe } from \"@ryuzaki13/react-foundation-lib/validators\";\n\nimport { Button } from \"../button\";\nimport { GridContainer } from \"../grid\";\nimport { Input } from \"../input\";\nimport { Modal, ModalContent, ModalFooter } from \"../modal\";\n\nimport { LinkType } from \"./linkTypes\";\n\ninterface PhoneDialogProps {\n\tisOpen: boolean;\n\tonClose: () => void;\n\tonConfirm: (url: string, text: string, add: string, ariaLabel: string, showQrCode: boolean) => void;\n\tinitialState?: LinkType;\n}\n\n/**\n * Диалог вставки или редактирования телефонной ссылки в текстовом редакторе.\n */\nexport function PhoneDialog({ isOpen, onClose, onConfirm, initialState }: PhoneDialogProps) {\n\tconst [phone, setPhone] = useState(\"\");\n\tconst [phoneAdd, setPhoneAdd] = useState(\"\");\n\tconst [ariaLabel, setAriaLabel] = useState(\"\");\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [state] = useState(() => {\n\t\tif (isSafe(initialState) && typeof initialState === \"string\") {\n\t\t\treturn { text: \"\", add: \"\", ariaLabel: \"\", url: initialState };\n\t\t}\n\n\t\treturn initialState;\n\t});\n\n\tuseEffect(() => {\n\t\tif (isOpen) {\n\t\t\tif (isSafe(state)) {\n\t\t\t\tsetPhone((state.url ?? \"\").replace(/\\D/g, \"\").slice(0, 11).replace(/^7/, \"\"));\n\n\t\t\t\tif (!state.add) {\n\t\t\t\t\tsetPhoneAdd((state.url ?? \"\").replace(/\\D/g, \"\").slice(11));\n\t\t\t\t} else {\n\t\t\t\t\tsetPhoneAdd((state.add ?? \"\").replace(/\\D/g, \"\"));\n\t\t\t\t}\n\n\t\t\t\tsetAriaLabel(state.ariaLabel ?? \"\");\n\t\t\t}\n\t\t}\n\t}, [isOpen, state]);\n\n\tconst handlePhoneChange = (value: string) => {\n\t\tvalue = value.replace(/\\D/g, \"\");\n\t\tif (value.length <= 10) {\n\t\t\tsetPhone(value);\n\t\t\tsetError(null);\n\t\t} else {\n\t\t\tsetError(\"нельзя ввести более 10 цифр\");\n\t\t}\n\t};\n\n\tconst validatePhone = (phone: string): boolean => {\n\t\tif (phone.length !== 10) {\n\t\t\tsetError(\"номер телефона должен содержать 10 цифр\");\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t};\n\n\tconst handleConfirm = (e: MouseEvent) => {\n\t\te.preventDefault();\n\n\t\tif (!validatePhone(phone)) return;\n\t\tif (!ariaLabel) {\n\t\t\tsetError(\"добавьте описание для телефона\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst formattedPhone = formatPhone(phone);\n\t\tconst fullPhone = `+7${phone}`;\n\t\tonConfirm(`tel:${fullPhone}`, phoneAdd ? `${formattedPhone} доб. ${phoneAdd}` : formattedPhone, phoneAdd, ariaLabel, false);\n\t\thandleClose();\n\t};\n\n\tconst handleClose = () => {\n\t\tsetPhone(\"\");\n\t\tsetAriaLabel(\"\");\n\t\tsetError(null);\n\t\tonClose();\n\t};\n\n\treturn (\n\t\t<Modal isOpen={isOpen} onClose={handleClose} title=\"Ссылка на телефон\" size=\"md\">\n\t\t\t<ModalContent>\n\t\t\t\t<GridContainer gap=\"md\">\n\t\t\t\t\t<div className={cn(\"flex\", \"alignItemsEnd\", \"gapSm\")}>\n\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\tlabel=\"Номер телефона без 7-ки\"\n\t\t\t\t\t\t\tdescription=\"Вводится только номер (10) цифр без каких-либо дополнительных символов. Ссылка будет привязана к текущему выделенному фрагменту текста. Поэтому текст самой ссылки можно оформить грамотно, например: +7 (3522) 12-34-56 доб. 100\"\n\t\t\t\t\t\t\tvalue={phone}\n\t\t\t\t\t\t\tonChange={handlePhoneChange}\n\t\t\t\t\t\t\tplaceholder=\"3522123456\"\n\t\t\t\t\t\t\tclassName=\"flex1\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<Input label=\"Добавочный номер\" value={phoneAdd} onChange={setPhoneAdd} placeholder=\"100\" />\n\t\t\t\t\t</div>\n\t\t\t\t\t{error && (\n\t\t\t\t\t\t<div className=\"textColorDanger\">\n\t\t\t\t\t\t\t<strong>Ошибка ввода:</strong> <span className=\"fontItalic\">{error}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<Input\n\t\t\t\t\t\tlabel=\"Текст для экранных читалок\"\n\t\t\t\t\t\tdescription=\"Обязательное поле для организации доступности ссылки для лиц с ОВЗ, использующих скринридеры\"\n\t\t\t\t\t\tvalue={ariaLabel}\n\t\t\t\t\t\tonChange={setAriaLabel}\n\t\t\t\t\t\tplaceholder=\"Контактный телефон директора\"\n\t\t\t\t\t/>\n\t\t\t\t</GridContainer>\n\t\t\t</ModalContent>\n\t\t\t<ModalFooter>\n\t\t\t\t<Button appearance=\"solid\" tone=\"error\" onClick={handleClose}>\n\t\t\t\t\tОтмена\n\t\t\t\t</Button>\n\t\t\t\t<Button appearance=\"solid\" tone=\"success\" onClick={handleConfirm} disabled={!phone || !ariaLabel}>\n\t\t\t\t\tПодтвердить\n\t\t\t\t</Button>\n\t\t\t</ModalFooter>\n\t\t</Modal>\n\t);\n}\n","import { type ReactNode, useEffect, useState } from \"react\";\n\nimport { Button } from \"../button\";\nimport { GridContainer } from \"../grid\";\nimport { Input } from \"../input\";\nimport { Modal, ModalContent, ModalFooter } from \"../modal\";\n\nexport interface AttributeField {\n\tname: string;\n\tlabel: string;\n\tdescription?: string;\n\tplaceholder?: string;\n\trequired?: boolean;\n\tvalidate?: (value: string) => string | null;\n}\n\nexport interface SemanticTagConfig {\n\ttagName: string;\n\ttitle: string;\n\tdescription: string;\n\texample: ReactNode;\n\tfields: AttributeField[];\n}\n\ninterface SemanticDialogProps {\n\tisOpen: boolean;\n\tonClose: () => void;\n\tonConfirm: (tagName: string, text: string, attributes: Record<string, string>) => void;\n\tconfig: SemanticTagConfig;\n\tinitialState?: Record<string, string>;\n\tinitialText?: string;\n}\n\n/**\n * Диалог настройки семантического тега и его атрибутов в текстовом редакторе.\n */\nexport function SemanticDialog({ isOpen, onClose, onConfirm, config, initialText = \"\", initialState = {} }: SemanticDialogProps) {\n\tconst [text, setText] = useState(initialText);\n\tconst [values, setValues] = useState<Record<string, string>>({});\n\tconst [errors, setErrors] = useState<Record<string, string | null>>({});\n\tconst [initialized, setInitialized] = useState(false);\n\n\tuseEffect(() => {\n\t\tif (isOpen && !initialized) {\n\t\t\tconst initial = config.fields.reduce(\n\t\t\t\t(acc, field) => {\n\t\t\t\t\tacc[field.name] = initialState[field.name] ?? \"\";\n\t\t\t\t\treturn acc;\n\t\t\t\t},\n\t\t\t\t{} as Record<string, string>\n\t\t\t);\n\t\t\tsetValues(initial);\n\t\t\tsetErrors({});\n\t\t\tsetInitialized(true);\n\t\t} else if (!isOpen && initialized) {\n\t\t\tsetInitialized(false); // сбрасываем при закрытии\n\t\t}\n\t}, [isOpen, config.fields, initialState, initialized]);\n\n\tconst handleChange = (name: string, value: string) => {\n\t\tsetValues((prev) => ({ ...prev, [name]: value }));\n\t\tsetErrors((prev) => ({ ...prev, [name]: null }));\n\t};\n\n\tconst validate = (): boolean => {\n\t\tconst newErrors: Record<string, string | null> = {};\n\t\tlet isValid = true;\n\n\t\tif (!text.trim()) {\n\t\t\tnewErrors[\"text\"] = \"Обязательное поле\";\n\t\t\tisValid = false;\n\t\t}\n\n\t\tfor (const field of config.fields) {\n\t\t\tconst value = values[field.name]?.trim();\n\t\t\tif (field.required && !value) {\n\t\t\t\tnewErrors[field.name] = \"Обязательное поле\";\n\t\t\t\tisValid = false;\n\t\t\t} else if (field.validate) {\n\t\t\t\tconst err = field.validate(value);\n\t\t\t\tif (err) {\n\t\t\t\t\tnewErrors[field.name] = err;\n\t\t\t\t\tisValid = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tsetErrors(newErrors);\n\t\treturn isValid;\n\t};\n\n\tconst handleConfirm = () => {\n\t\tif (!validate()) return;\n\t\tonConfirm(config.tagName, text.trim(), values);\n\t\tonClose();\n\t};\n\n\treturn (\n\t\t<Modal isOpen={isOpen} onClose={onClose} title={`Вставка <${config.tagName}>`} size=\"md\">\n\t\t\t<ModalContent>\n\t\t\t\t<GridContainer gap=\"md\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t{config.description}.<br />\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<strong>Пример:</strong> {config.example}\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<Input\n\t\t\t\t\t\tlabel={config.title}\n\t\t\t\t\t\tdescription={`Данный текст будет вставлен в редактор и обёрнуть в специальный семантический тег ${config.tagName}`}\n\t\t\t\t\t\tvalue={text}\n\t\t\t\t\t\tonChange={setText}\n\t\t\t\t\t\terror={errors[\"text\"] ?? undefined}\n\t\t\t\t\t\trequired\n\t\t\t\t\t/>\n\t\t\t\t\t{config.fields.map((field) => {\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\tkey={field.name}\n\t\t\t\t\t\t\t\tlabel={field.label}\n\t\t\t\t\t\t\t\tdescription={field.description}\n\t\t\t\t\t\t\t\tplaceholder={field.placeholder}\n\t\t\t\t\t\t\t\tvalue={values[field.name] ?? \"\"}\n\t\t\t\t\t\t\t\tonChange={(value) => handleChange(field.name, value)}\n\t\t\t\t\t\t\t\terror={errors[field.name] ?? undefined}\n\t\t\t\t\t\t\t\trequired={field.required}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</GridContainer>\n\t\t\t</ModalContent>\n\t\t\t<ModalFooter>\n\t\t\t\t<Button appearance=\"solid\" tone=\"error\" onClick={onClose}>\n\t\t\t\t\tОтмена\n\t\t\t\t</Button>\n\t\t\t\t<Button appearance=\"solid\" tone=\"success\" onClick={handleConfirm}>\n\t\t\t\t\tПодтвердить\n\t\t\t\t</Button>\n\t\t\t</ModalFooter>\n\t\t</Modal>\n\t);\n}\n","import { TagTypes } from \"./toolbar\";\n\nimport type { SemanticTagConfig } from \"./SemanticDialog\";\n\nexport const SemanticTagConfigs: Record<TagTypes, SemanticTagConfig> = {\n\t[TagTypes.abbr]: {\n\t\ttagName: \"abbr\",\n\t\ttitle: \"Аббревиатура\",\n\t\tdescription: \"Обозначает аббревиатуры и сокращения, при наведении покажет расшифровку\",\n\t\texample: (\n\t\t\t<>\n\t\t\t\t<abbr title=\"Национальное управление по аэронавтике и исследованию космического пространства\">НАСА</abbr>\n\t\t\t\t<div className=\"marginTopMd\">\n\t\t\t\t\t<code>{`<abbr title=\"Национальное управление по аэронавтике и исследованию космического пространства\">НАСА</abbr>`}</code>\n\t\t\t\t</div>\n\t\t\t</>\n\t\t),\n\t\tfields: [\n\t\t\t{\n\t\t\t\tname: \"title\",\n\t\t\t\tlabel: \"Расшифровка\",\n\t\t\t\tdescription: \"Появится как подсказка и будет прочитана скринридером\",\n\t\t\t\tplaceholder: \"например: HyperText Markup Language\",\n\t\t\t\trequired: true\n\t\t\t}\n\t\t]\n\t},\n\t[TagTypes.lang]: {\n\t\ttagName: \"span\",\n\t\ttitle: \"Текст на другом языке\",\n\t\tdescription:\n\t\t\t\"Указывает язык фрагмента текста, если он отличается от основного языка страницы, скринридер прочитает это слово с французским произношением\",\n\t\texample: (\n\t\t\t<>\n\t\t\t\t<span lang=\"fr\">Bonjour!</span> — сказал турист.\n\t\t\t\t<div className=\"marginTopMd\">\n\t\t\t\t\t<code>{`<span lang=\"fr\">Bonjour!</span> — сказал турист.`}</code>\n\t\t\t\t</div>\n\t\t\t</>\n\t\t),\n\t\tfields: [\n\t\t\t{\n\t\t\t\tname: \"lang\",\n\t\t\t\tlabel: \"Код языка\",\n\t\t\t\tplaceholder: \"en, fr, ru\",\n\t\t\t\trequired: true,\n\t\t\t\tvalidate: (val) => (!/^[a-z]{2,3}(-[A-Z]{2})?$/.test(val) ? \"Неверный код языка (например, en или en-US)\" : null)\n\t\t\t}\n\t\t]\n\t},\n\t[TagTypes.time]: {\n\t\ttagName: \"time\",\n\t\ttitle: \"Дата/время\",\n\t\tdescription: \"\",\n\t\texample: \"\",\n\t\tfields: [\n\t\t\t{\n\t\t\t\tname: \"datetime\",\n\t\t\t\tlabel: \"Дата/время (machine-readable)\",\n\t\t\t\tdescription: \"Формат ISO 8601: 2025-05-18, 14:30, 2025-05-18T14:30\",\n\t\t\t\tplaceholder: \"например: 2025-05-18T14:30\",\n\t\t\t\trequired: true\n\t\t\t}\n\t\t]\n\t},\n\t[TagTypes.cite]: {\n\t\ttagName: \"cite\",\n\t\ttitle: \"Цитата источника\",\n\t\tdescription: \"Обозначает название книги, статьи, фильма или другого произведения, на которое вы ссылаетесь\",\n\t\texample: (\n\t\t\t<>\n\t\t\t\tПо словам Эйнштейна: <cite>«Воображение важнее знания»</cite>.\n\t\t\t\t<div className=\"marginTopMd\">\n\t\t\t\t\t<code>{`По словам Эйнштейна: <cite>«Воображение важнее знания»</cite>.`}</code>\n\t\t\t\t</div>\n\t\t\t</>\n\t\t),\n\t\tfields: [\n\t\t\t{\n\t\t\t\tname: \"title\",\n\t\t\t\tlabel: \"Название источника\",\n\t\t\t\tdescription: \"Будет отображаться как подсказка\",\n\t\t\t\tplaceholder: \"например: Википедия\",\n\t\t\t\trequired: false\n\t\t\t}\n\t\t]\n\t},\n\t// [TagTypes.address]: {\n\t// \ttagName: \"address\",\n\t// \ttitle: \"Указывает контакты автора статьи/страницы (не для почтовых адресов компаний!)\",\n\t// \tdescription: \"\",\n\t// \texample: ``,\n\t// \tfields: [\n\t// \t\t{\n\t// \t\t\tname: \"aria-label\",\n\t// \t\t\tlabel: \"Описание (для доступности)\",\n\t// \t\t\tdescription: \"Содержимое будет прочитано скринридером, если адрес не очевиден\",\n\t// \t\t\tplaceholder: \"например: Контактный адрес компании\",\n\t// \t\t\trequired: false\n\t// \t\t}\n\t// \t]\n\t// },\n\t[TagTypes.del]: {\n\t\ttagName: \"del\",\n\t\ttitle: \"Изменения в тексте\",\n\t\tdescription: \"Удаленный фрагмент\",\n\t\texample: (\n\t\t\t<>\n\t\t\t\tПроект сдачи: <del>1 июня</del> <ins>15 июня</ins>\n\t\t\t\t<div className=\"marginTopMd\">\n\t\t\t\t\t<code>{`Проект сдачи: <del>1 июня</del> <ins>15 июня</ins>`}</code>\n\t\t\t\t</div>\n\t\t\t</>\n\t\t),\n\t\tfields: [\n\t\t\t{\n\t\t\t\tname: \"datetime\",\n\t\t\t\tlabel: \"Когда был удалён\",\n\t\t\t\tdescription: \"Формат ISO 8601: 2025-05-18T14:30\",\n\t\t\t\tplaceholder: \"например: 2025-05-18T14:30\",\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"cite\",\n\t\t\t\tlabel: \"Источник/обоснование\",\n\t\t\t\tdescription: \"Ссылка на объяснение причины\",\n\t\t\t\tplaceholder: \"например: https://example.com/edit-log\",\n\t\t\t\trequired: false\n\t\t\t}\n\t\t]\n\t},\n\t[TagTypes.ins]: {\n\t\ttagName: \"ins\",\n\t\ttitle: \"Изменения в тексте\",\n\t\tdescription: \"Новый добавленный текст\",\n\t\texample: (\n\t\t\t<>\n\t\t\t\tПроект сдачи: <del>1 июня</del> <ins>15 июня</ins>\n\t\t\t\t<div className=\"marginTopMd\">\n\t\t\t\t\t<code>{`Проект сдачи: <del>1 июня</del> <ins>15 июня</ins>`}</code>\n\t\t\t\t</div>\n\t\t\t</>\n\t\t),\n\t\tfields: [\n\t\t\t{\n\t\t\t\tname: \"datetime\",\n\t\t\t\tlabel: \"Когда был добавлен\",\n\t\t\t\tdescription: \"Формат ISO 8601: 2025-05-18T14:30\",\n\t\t\t\tplaceholder: \"например: 2025-05-18T14:30\",\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"cite\",\n\t\t\t\tlabel: \"Источник/обоснование\",\n\t\t\t\tdescription: \"Ссылка на объяснение причины\",\n\t\t\t\tplaceholder: \"например: https://example.com/edit-log\",\n\t\t\t\trequired: false\n\t\t\t}\n\t\t]\n\t}\n};\n","import { useEffect, useEffectEvent, useState } from \"react\";\n\nimport { Button } from \"../button\";\nimport { GridContainer } from \"../grid\";\nimport { Input } from \"../input\";\nimport { Modal, ModalContent, ModalFooter } from \"../modal\";\nimport { RadioGroup } from \"../radio-group\";\n\ntype TimeDialogInitialState = {\n\tmode?: TimeMode;\n\tfrom?: string;\n\tto?: string;\n};\n\ninterface TimeDialogProps {\n\tisOpen: boolean;\n\tonClose: () => void;\n\tonConfirm: (tagName: string, text: string, attributes: Record<string, string>) => void;\n\tinitialState?: TimeDialogInitialState;\n}\n\ntype TimeMode = \"date\" | \"datetime\" | \"time\" | \"range-time\" | \"range-date\" | \"range-datetime\";\n\n/**\n * Диалог настройки временного атрибута или значения в текстовом редакторе.\n */\nexport function TimeDialog({ isOpen, onClose, onConfirm, initialState }: TimeDialogProps) {\n\tconst [mode, setMode] = useState<TimeMode | undefined>(\"date\");\n\tconst [from, setFrom] = useState(\"\");\n\tconst [to, setTo] = useState(\"\");\n\tconst [errors, setErrors] = useState<{ from?: string; to?: string }>({});\n\n\tconst syncInitialState = useEffectEvent((initialState?: TimeDialogInitialState) => {\n\t\tsetMode(initialState?.mode ?? \"date\");\n\t\tsetFrom(initialState?.from ?? \"\");\n\t\tsetTo(initialState?.to ?? \"\");\n\t\tsetErrors({});\n\t});\n\n\tuseEffect(() => {\n\t\tif (isOpen) {\n\t\t\tsyncInitialState(initialState);\n\t\t}\n\t}, [isOpen, initialState]);\n\n\tconst validate = () => {\n\t\tconst newErrors: typeof errors = {};\n\t\t// const isValid = true;\n\n\t\tconst isDate = (v: string) => /^\\d{4}-\\d{2}-\\d{2}$/.test(v);\n\t\tconst isTime = (v: string) => /^\\d{2}:\\d{2}$/.test(v);\n\t\tconst isDateTime = (v: string) => /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}$/.test(v);\n\n\t\tconst check = (label: string, value: string, type: \"date\" | \"time\" | \"datetime\") => {\n\t\t\tif (!value) return `${label} обязательно`;\n\t\t\tif (type === \"date\" && !isDate(value)) return \"Неверный формат даты (ГГГГ-ММ-ДД)\";\n\t\t\tif (type === \"time\" && !isTime(value)) return \"Неверный формат времени (ЧЧ:ММ)\";\n\t\t\tif (type === \"datetime\" && !isDateTime(value)) return \"Неверный формат даты и времени (ГГГГ-ММ-ДДTЧЧ:ММ)\";\n\t\t\treturn undefined;\n\t\t};\n\n\t\tswitch (mode) {\n\t\t\tcase \"date\":\n\t\t\t\tnewErrors.from = check(\"Дата\", from, \"date\");\n\t\t\t\tbreak;\n\t\t\tcase \"time\":\n\t\t\t\tnewErrors.from = check(\"Время\", from, \"time\");\n\t\t\t\tbreak;\n\t\t\tcase \"datetime\":\n\t\t\t\tnewErrors.from = check(\"Дата и время\", from, \"datetime\");\n\t\t\t\tbreak;\n\t\t\tcase \"range-time\":\n\t\t\t\tnewErrors.from = check(\"Время начала\", from, \"time\");\n\t\t\t\tnewErrors.to = check(\"Время окончания\", to, \"time\");\n\t\t\t\tbreak;\n\t\t\tcase \"range-date\":\n\t\t\t\tnewErrors.from = check(\"Дата начала\", from, \"date\");\n\t\t\t\tnewErrors.to = check(\"Дата окончания\", to, \"date\");\n\t\t\t\tbreak;\n\t\t\tcase \"range-datetime\":\n\t\t\t\tnewErrors.from = check(\"Начало\", from, \"datetime\");\n\t\t\t\tnewErrors.to = check(\"Окончание\", to, \"datetime\");\n\t\t\t\tbreak;\n\t\t}\n\n\t\tsetErrors(newErrors);\n\t\treturn Object.values(newErrors).every((e) => !e);\n\t};\n\n\tconst handleConfirm = () => {\n\t\tif (!validate()) return;\n\n\t\tconst datetime = to ? `${from}/${to}` : from;\n\t\tonConfirm(\"time\", datetime, { datetime });\n\t\tonClose();\n\t};\n\n\tconst renderInputs = () => {\n\t\tswitch (mode) {\n\t\t\tcase \"date\":\n\t\t\tcase \"datetime\":\n\t\t\tcase \"time\":\n\t\t\t\treturn (\n\t\t\t\t\t<Input\n\t\t\t\t\t\tlabel=\"Значение\"\n\t\t\t\t\t\tplaceholder={mode === \"time\" ? \"09:00\" : mode === \"date\" ? \"2025-05-18\" : \"2025-05-18T09:00\"}\n\t\t\t\t\t\tvalue={from}\n\t\t\t\t\t\tonChange={setFrom}\n\t\t\t\t\t\terror={errors.from}\n\t\t\t\t\t/>\n\t\t\t\t);\n\t\t\tcase \"range-time\":\n\t\t\tcase \"range-date\":\n\t\t\tcase \"range-datetime\":\n\t\t\t\treturn (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\tlabel=\"С\"\n\t\t\t\t\t\t\tplaceholder={mode.includes(\"time\") ? \"09:00\" : mode.includes(\"date\") ? \"2025-05-18\" : \"2025-05-18T09:00\"}\n\t\t\t\t\t\t\tvalue={from}\n\t\t\t\t\t\t\tonChange={setFrom}\n\t\t\t\t\t\t\terror={errors.from}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\tlabel=\"По\"\n\t\t\t\t\t\t\tplaceholder={mode.includes(\"time\") ? \"17:00\" : mode.includes(\"date\") ? \"2025-05-22\" : \"2025-05-22T17:00\"}\n\t\t\t\t\t\t\tvalue={to}\n\t\t\t\t\t\t\tonChange={setFrom}\n\t\t\t\t\t\t\terror={errors.to}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</>\n\t\t\t\t);\n\t\t}\n\t};\n\n\treturn (\n\t\t<Modal isOpen={isOpen} onClose={onClose} title=\"Вставка <time>\" size=\"md\">\n\t\t\t<ModalContent>\n\t\t\t\t<GridContainer gap=\"md\">\n\t\t\t\t\t<RadioGroup label=\"Тип значения\" value={mode} onChange={setMode}>\n\t\t\t\t\t\t<RadioGroup.Option label=\"Дата\" value=\"date\" />\n\t\t\t\t\t\t<RadioGroup.Option label=\"Дата и время\" value=\"datetime\" />\n\t\t\t\t\t\t<RadioGroup.Option label=\"Время\" value=\"time\" />\n\t\t\t\t\t\t<RadioGroup.Option label=\"Диапазон дат\" value=\"range-date\" />\n\t\t\t\t\t\t<RadioGroup.Option label=\"Диапазон времени\" value=\"range-time\" />\n\t\t\t\t\t\t<RadioGroup.Option label=\"Диапазон даты и времени\" value=\"range-datetime\" />\n\t\t\t\t\t</RadioGroup>\n\n\t\t\t\t\t<GridContainer gap=\"md\">{renderInputs()}</GridContainer>\n\t\t\t\t</GridContainer>\n\t\t\t</ModalContent>\n\t\t\t<ModalFooter>\n\t\t\t\t<Button appearance=\"solid\" tone=\"error\" onClick={onClose}>\n\t\t\t\t\tОтмена\n\t\t\t\t</Button>\n\t\t\t\t<Button appearance=\"solid\" tone=\"success\" onClick={handleConfirm}>\n\t\t\t\t\tПодтвердить\n\t\t\t\t</Button>\n\t\t\t</ModalFooter>\n\t\t</Modal>\n\t);\n}\n","import type { ComponentType } from \"react\";\n\nimport { EmailDialog } from \"./EmailDialog\";\nimport { LinkDialog } from \"./LinkDialog\";\nimport { PhoneDialog } from \"./PhoneDialog\";\nimport { SemanticDialog } from \"./SemanticDialog\";\nimport { SemanticTagConfigs } from \"./semanticTagConfigs\";\nimport { TimeDialog } from \"./TimeDialog\";\nimport { LinkTypes, TagTypes } from \"./toolbar\";\n\nimport type { LocalLinkDialogAdapterProps } from \"./editorModel\";\nimport type { LinkType } from \"./model/textEditorTypes\";\n\ninterface TextEditorDialogsProps {\n\tlinkTypeDialog: LinkTypes | null;\n\ttagTypeDialog: TagTypes | null;\n\tlocalLinkDialogComponent?: ComponentType<LocalLinkDialogAdapterProps>;\n\tonCloseLinkDialog: () => void;\n\tonCloseTagDialog: () => void;\n\tonAddLink: (url: string, text: string, add: string, ariaLabel: string, showQrCode: boolean) => void;\n\tonAddLocalLink: (url: string, caption: string) => void;\n\tonInsertSemanticTag: (tagName: string, text: string, attributes: Record<string, string>) => void;\n\tgetCurrentSelectionText: () => string;\n\tgetSelectedLinkState: () => LinkType;\n}\n\n/**\n * Контейнер набора диалогов, которые используются редактором для вставки ссылок и семантических сущностей.\n */\nexport function TextEditorDialogs({\n\tlinkTypeDialog,\n\ttagTypeDialog,\n\tlocalLinkDialogComponent,\n\tonCloseLinkDialog,\n\tonCloseTagDialog,\n\tonAddLink,\n\tonAddLocalLink,\n\tonInsertSemanticTag,\n\tgetCurrentSelectionText,\n\tgetSelectedLinkState\n}: TextEditorDialogsProps) {\n\tconst LocalLinkDialogComponent = localLinkDialogComponent;\n\n\treturn (\n\t\t<>\n\t\t\t{linkTypeDialog && (\n\t\t\t\t<>\n\t\t\t\t\t{LocalLinkDialogComponent && (\n\t\t\t\t\t\t<LocalLinkDialogComponent\n\t\t\t\t\t\t\tisOpen={linkTypeDialog === LinkTypes.LOCAL_LINK}\n\t\t\t\t\t\t\tonClose={onCloseLinkDialog}\n\t\t\t\t\t\t\tonConfirm={onAddLocalLink}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<LinkDialog\n\t\t\t\t\t\tisOpen={linkTypeDialog === LinkTypes.LINK}\n\t\t\t\t\t\tinitialState={getSelectedLinkState()}\n\t\t\t\t\t\tonClose={onCloseLinkDialog}\n\t\t\t\t\t\tonConfirm={onAddLink}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<PhoneDialog\n\t\t\t\t\t\tisOpen={linkTypeDialog === LinkTypes.PHONE}\n\t\t\t\t\t\tinitialState={getSelectedLinkState()}\n\t\t\t\t\t\tonClose={onCloseLinkDialog}\n\t\t\t\t\t\tonConfirm={onAddLink}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<EmailDialog\n\t\t\t\t\t\tisOpen={linkTypeDialog === LinkTypes.EMAIL}\n\t\t\t\t\t\tinitialState={getSelectedLinkState()}\n\t\t\t\t\t\tonClose={onCloseLinkDialog}\n\t\t\t\t\t\tonConfirm={onAddLink}\n\t\t\t\t\t/>\n\t\t\t\t</>\n\t\t\t)}\n\n\t\t\t{tagTypeDialog &&\n\t\t\t\t(tagTypeDialog !== TagTypes.time ? (\n\t\t\t\t\t<SemanticDialog\n\t\t\t\t\t\tisOpen={true}\n\t\t\t\t\t\tonClose={onCloseTagDialog}\n\t\t\t\t\t\tonConfirm={onInsertSemanticTag}\n\t\t\t\t\t\tconfig={SemanticTagConfigs[tagTypeDialog]}\n\t\t\t\t\t\tinitialText={getCurrentSelectionText()}\n\t\t\t\t\t/>\n\t\t\t\t) : (\n\t\t\t\t\t<TimeDialog isOpen={true} onClose={onCloseTagDialog} onConfirm={onInsertSemanticTag} />\n\t\t\t\t))}\n\t\t</>\n\t);\n}\n","import { useCallback, useMemo, useState } from \"react\";\n\nimport { $generateHtmlFromNodes } from \"@lexical/html\";\nimport { ListItemNode, ListNode } from \"@lexical/list\";\nimport { LexicalComposer } from \"@lexical/react/LexicalComposer\";\nimport { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\nimport { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\nimport { HistoryPlugin } from \"@lexical/react/LexicalHistoryPlugin\";\nimport { ListPlugin } from \"@lexical/react/LexicalListPlugin\";\nimport { OnChangePlugin } from \"@lexical/react/LexicalOnChangePlugin\";\nimport { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\nimport { HeadingNode, QuoteNode } from \"@lexical/rich-text\";\nimport { type LexicalEditor, type EditorState as LexicalEditorState } from \"lexical\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { TextEditorCoreProps, isLexicalTextRaw } from \"./editorModel\";\nimport { InitialHtmlPlugin, SelectionStatePlugin } from \"./lexical/plugins\";\nimport { createLexicalRaw } from \"./lib/serialization/createLexicalRaw\";\nimport { useTextEditorLexicalActions } from \"./model/hooks/useTextEditorLexicalActions\";\nimport { DEFAULT_TOOLBAR_STATE, type LexicalToolbarState } from \"./model/textEditorTypes\";\nimport { AccessibleLinkNode } from \"./nodes/AccessibleLinkNode\";\nimport { SemanticTagNode } from \"./nodes/SemanticTagNode\";\nimport TextEditorStyle from \"./TextEditor.module.scss\";\nimport \"./TextEditor.scss\";\nimport { TextEditorDialogs } from \"./TextEditorDialogs\";\nimport { type LinkTypes, type TagTypes, TextEditorToolbarLexical } from \"./toolbar\";\n\ntype TextEditorProps = TextEditorCoreProps;\n\n/**\n * Редактор форматированного текста на базе Lexical. Поддерживает тулбар, бизнес-адаптеры и сериализацию контента в единый формат данных.\n */\nexport function TextEditorLexicalClient({ initialData, onChange, toolbarComponents, businessAdapters }: TextEditorProps) {\n\tconst LocalLinkDialogComponent = businessAdapters?.LocalLinkDialogComponent;\n\tconst [isFocused, setIsFocused] = useState(false);\n\tconst [toolbarState, setToolbarState] = useState<LexicalToolbarState>(DEFAULT_TOOLBAR_STATE);\n\tconst [editor, setEditor] = useState<LexicalEditor | null>(null);\n\tconst [linkTypeDialog, setLinkTypeDialog] = useState<LinkTypes | null>(null);\n\tconst [tagTypeDialog, setTagTypeDialog] = useState<TagTypes | null>(null);\n\n\tconst lexicalRaw = isLexicalTextRaw(initialData?.raw) ? initialData.raw : null;\n\tconst hasLexicalRaw = !!lexicalRaw;\n\n\tconst initialEditorState = useMemo(() => {\n\t\tif (!lexicalRaw) return undefined;\n\t\treturn JSON.stringify(lexicalRaw.editorState);\n\t}, [lexicalRaw]);\n\n\tconst handleError = useCallback((error: Error) => {\n\t\tconsole.error(\"Ошибка редактора Lexical\", error);\n\t}, []);\n\n\tconst handleChange = useCallback(\n\t\t(editorState: LexicalEditorState, lexicalEditor: LexicalEditor) => {\n\t\t\tlet html = \"\";\n\t\t\teditorState.read(() => {\n\t\t\t\thtml = $generateHtmlFromNodes(lexicalEditor, null);\n\t\t\t});\n\n\t\t\tconst raw = createLexicalRaw(editorState);\n\t\t\tonChange({ raw, html });\n\t\t},\n\t\t[onChange]\n\t);\n\n\tconst openLinkDialog = useCallback((type: LinkTypes) => {\n\t\tsetLinkTypeDialog(type);\n\t}, []);\n\n\tconst openTagDialog = useCallback((type: TagTypes) => {\n\t\tsetTagTypeDialog(type);\n\t}, []);\n\n\tconst actions = useTextEditorLexicalActions({\n\t\teditor,\n\t\ttoolbarState,\n\t\thasLocalLinkDialog: !!LocalLinkDialogComponent,\n\t\tonOpenLinkDialog: openLinkDialog,\n\t\tonOpenTagDialog: openTagDialog\n\t});\n\n\tconst initialConfig = useMemo(\n\t\t() => ({\n\t\t\tnamespace: \"KtkTextEditorLexical\",\n\t\t\tonError: handleError,\n\t\t\ttheme: {\n\t\t\t\tparagraph: \"paragraph\",\n\t\t\t\ttext: {\n\t\t\t\t\tcode: \"lexicalTextCode\",\n\t\t\t\t\thighlight: \"lexicalTextHighlight\",\n\t\t\t\t\tunderline: \"lexicalTextUnderline\",\n\t\t\t\t\tstrikethrough: \"lexicalTextStrikethrough\"\n\t\t\t\t}\n\t\t\t},\n\t\t\tnodes: [HeadingNode, QuoteNode, ListNode, ListItemNode, AccessibleLinkNode, SemanticTagNode],\n\t\t\teditorState: initialEditorState\n\t\t}),\n\t\t[handleError, initialEditorState]\n\t);\n\n\treturn (\n\t\t<div className={TextEditorStyle.textEditor}>\n\t\t\t<div\n\t\t\t\tclassName={cn(TextEditorStyle.textEditorContent, {\n\t\t\t\t\t[TextEditorStyle.focused]: isFocused\n\t\t\t\t})}>\n\t\t\t\t<LexicalComposer initialConfig={initialConfig}>\n\t\t\t\t\t<TextEditorToolbarLexical\n\t\t\t\t\t\ttoolbarComponents={toolbarComponents}\n\t\t\t\t\t\tstate={toolbarState}\n\t\t\t\t\t\tonBlockStyleToggle={actions.handleBlockStyleToggle}\n\t\t\t\t\t\tonInlineStyleToggle={actions.handleInlineStyleToggle}\n\t\t\t\t\t\tonAlignmentChange={actions.handleAlignmentChange}\n\t\t\t\t\t\tonLinkClick={actions.handleLinkClick}\n\t\t\t\t\t\tonTagClick={actions.handleTagClick}\n\t\t\t\t\t\tonUndo={actions.handleUndo}\n\t\t\t\t\t\tonRedo={actions.handleRedo}\n\t\t\t\t\t\tonCleanTag={actions.handleCleanSemanticTag}\n\t\t\t\t\t/>\n\t\t\t\t\t<RichTextPlugin\n\t\t\t\t\t\tcontentEditable={\n\t\t\t\t\t\t\t<ContentEditable\n\t\t\t\t\t\t\t\tclassName=\"lexicalEditorContentEditable\"\n\t\t\t\t\t\t\t\tonFocus={() => setIsFocused(true)}\n\t\t\t\t\t\t\t\tonBlur={() => setIsFocused(false)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t}\n\t\t\t\t\t\tplaceholder={<div className=\"lexicalEditorPlaceholder\">Введите текст...</div>}\n\t\t\t\t\t\tErrorBoundary={LexicalErrorBoundary}\n\t\t\t\t\t/>\n\t\t\t\t\t<HistoryPlugin />\n\t\t\t\t\t<ListPlugin />\n\t\t\t\t\t<SelectionStatePlugin onEditorReady={setEditor} onStateChange={setToolbarState} />\n\t\t\t\t\t<InitialHtmlPlugin initialHTML={initialData?.html} shouldSkip={hasLexicalRaw} />\n\t\t\t\t\t<OnChangePlugin onChange={handleChange} ignoreSelectionChange />\n\t\t\t\t</LexicalComposer>\n\t\t\t</div>\n\n\t\t\t<TextEditorDialogs\n\t\t\t\tlinkTypeDialog={linkTypeDialog}\n\t\t\t\ttagTypeDialog={tagTypeDialog}\n\t\t\t\tlocalLinkDialogComponent={LocalLinkDialogComponent}\n\t\t\t\tonCloseLinkDialog={() => setLinkTypeDialog(null)}\n\t\t\t\tonCloseTagDialog={() => setTagTypeDialog(null)}\n\t\t\t\tonAddLink={actions.handleAddLink}\n\t\t\t\tonAddLocalLink={actions.handleAddLocalLink}\n\t\t\t\tonInsertSemanticTag={actions.insertSemanticTagAtSelection}\n\t\t\t\tgetCurrentSelectionText={actions.getCurrentSelectionText}\n\t\t\t\tgetSelectedLinkState={actions.getSelectedLinkState}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TextEditorLexicalClient-Dt4eaPA3.js","names":[],"sources":["../../src/text-editor/lib/serialization/createLexicalRaw.ts","../../src/text-editor/lib/semantic/getSemanticTagDepth.ts","../../src/text-editor/nodes/AccessibleLinkNode.ts","../../src/text-editor/nodes/SemanticTagNode.ts","../../src/text-editor/model/hooks/useTextEditorLexicalActions.ts","../../src/text-editor/TextEditor.module.scss","../../src/text-editor/EmailDialog.tsx","../../src/text-editor/LinkDialog.tsx","../../src/text-editor/PhoneDialog.tsx","../../src/text-editor/SemanticDialog.tsx","../../src/text-editor/semanticTagConfigs.tsx","../../src/text-editor/TimeDialog.tsx","../../src/text-editor/TextEditorDialogs.tsx","../../src/text-editor/TextEditorLexicalClient.tsx"],"sourcesContent":["import { EditorState as LexicalEditorState } from \"lexical\";\n\nimport type { TextEditorLexicalRaw } from \"../../editorModel\";\n\nexport const createLexicalRaw = (editorState: LexicalEditorState): TextEditorLexicalRaw => {\n\treturn {\n\t\tformat: \"lexical\",\n\t\tversion: 1,\n\t\teditorState: editorState.toJSON() as unknown as Record<string, unknown>\n\t};\n};\n","import type { LexicalNode } from \"lexical\";\n\nexport const getSemanticTagDepth = (node: LexicalNode): number => {\n\tlet depth = 0;\n\tlet current: LexicalNode | null = node;\n\n\twhile (current) {\n\t\tdepth += 1;\n\t\tcurrent = current.getParent();\n\t}\n\n\treturn depth;\n};\n","import { LinkAttributes, LinkNode, SerializedLinkNode } from \"@lexical/link\";\nimport {\n\t$applyNodeReplacement,\n\tDOMConversionMap,\n\tDOMConversionOutput,\n\tEditorConfig,\n\tElementNode,\n\tLexicalNode,\n\tLexicalUpdateJSON,\n\tNodeKey,\n\tRangeSelection,\n\tSpread\n} from \"lexical\";\n\nexport type AccessibleLinkAttributes = LinkAttributes & {\n\tariaLabel?: null | string;\n\tqrCode?: boolean;\n\tadd?: null | string;\n\ttext?: null | string;\n};\n\nexport type SerializedAccessibleLinkNode = Spread<\n\t{\n\t\tariaLabel: null | string;\n\t\tqrCode: boolean;\n\t\tadd: null | string;\n\t\ttext: null | string;\n\t},\n\tSerializedLinkNode\n>;\n\nconst convertAccessibleLinkElement = (domNode: Node): DOMConversionOutput => {\n\tif (!(domNode instanceof HTMLAnchorElement)) {\n\t\treturn { node: null };\n\t}\n\n\tconst textContent = domNode.textContent;\n\tif ((textContent === null || textContent === \"\") && domNode.children.length === 0) {\n\t\treturn { node: null };\n\t}\n\n\treturn {\n\t\tnode: $createAccessibleLinkNode(domNode.getAttribute(\"href\") || \"\", {\n\t\t\trel: domNode.getAttribute(\"rel\"),\n\t\t\ttarget: domNode.getAttribute(\"target\"),\n\t\t\ttitle: domNode.getAttribute(\"title\"),\n\t\t\tariaLabel: domNode.getAttribute(\"aria-label\"),\n\t\t\tqrCode: domNode.getAttribute(\"data-qr-code\") === \"true\",\n\t\t\tadd: null,\n\t\t\ttext: textContent\n\t\t})\n\t};\n};\n\nexport class AccessibleLinkNode extends LinkNode {\n\t__ariaLabel: null | string;\n\t__qrCode: boolean;\n\t__add: null | string;\n\t__text: null | string;\n\n\tstatic getType(): string {\n\t\treturn \"accessible-link\";\n\t}\n\n\tstatic clone(node: AccessibleLinkNode): AccessibleLinkNode {\n\t\treturn new AccessibleLinkNode(\n\t\t\tnode.__url,\n\t\t\t{\n\t\t\t\trel: node.__rel,\n\t\t\t\ttarget: node.__target,\n\t\t\t\ttitle: node.__title,\n\t\t\t\tariaLabel: node.__ariaLabel,\n\t\t\t\tqrCode: node.__qrCode,\n\t\t\t\tadd: node.__add,\n\t\t\t\ttext: node.__text\n\t\t\t},\n\t\t\tnode.__key\n\t\t);\n\t}\n\n\tconstructor(url = \"\", attributes: AccessibleLinkAttributes = {}, key?: NodeKey) {\n\t\tsuper(url, attributes, key);\n\n\t\tconst { ariaLabel = null, qrCode = false, add = null, text = null } = attributes;\n\t\tthis.__ariaLabel = ariaLabel;\n\t\tthis.__qrCode = qrCode;\n\t\tthis.__add = add;\n\t\tthis.__text = text;\n\t}\n\n\tstatic importDOM(): DOMConversionMap | null {\n\t\treturn {\n\t\t\ta: () => ({\n\t\t\t\tconversion: convertAccessibleLinkElement,\n\t\t\t\tpriority: 2\n\t\t\t})\n\t\t};\n\t}\n\n\tstatic importJSON(serializedNode: SerializedAccessibleLinkNode): AccessibleLinkNode {\n\t\treturn $createAccessibleLinkNode().updateFromJSON(serializedNode);\n\t}\n\n\tupdateFromJSON(serializedNode: LexicalUpdateJSON<SerializedAccessibleLinkNode>): this {\n\t\treturn super\n\t\t\t.updateFromJSON(serializedNode)\n\t\t\t.setAriaLabel(serializedNode.ariaLabel || null)\n\t\t\t.setQrCode(!!serializedNode.qrCode)\n\t\t\t.setAdd(serializedNode.add || null)\n\t\t\t.setText(serializedNode.text || null);\n\t}\n\n\texportJSON(): SerializedAccessibleLinkNode {\n\t\treturn {\n\t\t\t...super.exportJSON(),\n\t\t\ttype: \"accessible-link\",\n\t\t\tversion: 1,\n\t\t\tariaLabel: this.getAriaLabel(),\n\t\t\tqrCode: this.getQrCode(),\n\t\t\tadd: this.getAdd(),\n\t\t\ttext: this.getText()\n\t\t} as SerializedAccessibleLinkNode;\n\t}\n\n\tcreateDOM(config: EditorConfig): HTMLElement {\n\t\tconst dom = super.createDOM(config) as HTMLElement;\n\t\tthis.applyAccessibleAttributes(null, dom);\n\t\treturn dom;\n\t}\n\n\tupdateDOM(prevNode: this, anchor: HTMLElement, config: EditorConfig): boolean {\n\t\tconst isUpdated = super.updateDOM(prevNode, anchor as never, config);\n\t\tthis.applyAccessibleAttributes(prevNode, anchor);\n\t\treturn isUpdated;\n\t}\n\n\tapplyAccessibleAttributes(prevNode: this | null, anchor: HTMLElement): void {\n\t\tif (!(anchor instanceof HTMLAnchorElement)) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!prevNode || prevNode.__ariaLabel !== this.__ariaLabel) {\n\t\t\tif (this.__ariaLabel) {\n\t\t\t\tanchor.setAttribute(\"aria-label\", this.__ariaLabel);\n\t\t\t} else {\n\t\t\t\tanchor.removeAttribute(\"aria-label\");\n\t\t\t}\n\t\t}\n\n\t\tif (!prevNode || prevNode.__qrCode !== this.__qrCode) {\n\t\t\tanchor.setAttribute(\"data-qr-code\", this.__qrCode ? \"true\" : \"false\");\n\t\t}\n\t}\n\n\tinsertNewAfter(_selection: RangeSelection, restoreSelection = true): null | ElementNode {\n\t\tconst linkNode = $createAccessibleLinkNode(this.__url, {\n\t\t\trel: this.__rel,\n\t\t\ttarget: this.__target,\n\t\t\ttitle: this.__title,\n\t\t\tariaLabel: this.__ariaLabel,\n\t\t\tqrCode: this.__qrCode,\n\t\t\tadd: this.__add,\n\t\t\ttext: this.__text\n\t\t});\n\t\tthis.insertAfter(linkNode, restoreSelection);\n\t\treturn linkNode;\n\t}\n\n\tgetAriaLabel(): null | string {\n\t\treturn this.getLatest().__ariaLabel;\n\t}\n\n\tsetAriaLabel(ariaLabel: null | string): this {\n\t\tconst writable = this.getWritable();\n\t\twritable.__ariaLabel = ariaLabel;\n\t\treturn this;\n\t}\n\n\tgetQrCode(): boolean {\n\t\treturn this.getLatest().__qrCode;\n\t}\n\n\tsetQrCode(qrCode: boolean): this {\n\t\tconst writable = this.getWritable();\n\t\twritable.__qrCode = qrCode;\n\t\treturn this;\n\t}\n\n\tgetAdd(): null | string {\n\t\treturn this.getLatest().__add;\n\t}\n\n\tsetAdd(add: null | string): this {\n\t\tconst writable = this.getWritable();\n\t\twritable.__add = add;\n\t\treturn this;\n\t}\n\n\tgetText(): null | string {\n\t\treturn this.getLatest().__text;\n\t}\n\n\tsetText(text: null | string): this {\n\t\tconst writable = this.getWritable();\n\t\twritable.__text = text;\n\t\treturn this;\n\t}\n}\n\nexport const $createAccessibleLinkNode = (url = \"\", attributes?: AccessibleLinkAttributes): AccessibleLinkNode => {\n\treturn $applyNodeReplacement(new AccessibleLinkNode(url, attributes));\n};\n\nexport const $isAccessibleLinkNode = (node: LexicalNode | null | undefined): node is AccessibleLinkNode => {\n\treturn node instanceof AccessibleLinkNode;\n};\n","import {\n\t$applyNodeReplacement,\n\tDOMConversionMap,\n\tDOMConversionOutput,\n\tEditorConfig,\n\tElementNode,\n\tLexicalNode,\n\tLexicalUpdateJSON,\n\tNodeKey,\n\tRangeSelection,\n\tSerializedElementNode,\n\tSpread\n} from \"lexical\";\n\nexport type SemanticTagAttributes = Record<string, string>;\n\nexport type SerializedSemanticTagNode = Spread<\n\t{\n\t\ttag: string;\n\t\tattributes: SemanticTagAttributes;\n\t\ttext: null | string;\n\t},\n\tSerializedElementNode\n>;\n\nconst getAttributesFromElement = (element: HTMLElement): SemanticTagAttributes => {\n\tconst attributes: SemanticTagAttributes = {};\n\tArray.from(element.attributes).forEach((attr) => {\n\t\tif (attr.name === \"class\") return;\n\t\tattributes[attr.name] = attr.value;\n\t});\n\treturn attributes;\n};\n\nconst convertSemanticTagElement = (domNode: Node): DOMConversionOutput => {\n\tif (!(domNode instanceof HTMLElement)) {\n\t\treturn { node: null };\n\t}\n\n\tconst tag = domNode.tagName.toLowerCase();\n\tif (![\"abbr\", \"span\", \"time\", \"cite\", \"del\", \"ins\"].includes(tag)) {\n\t\treturn { node: null };\n\t}\n\n\tconst text = domNode.textContent;\n\tif ((text === null || text === \"\") && domNode.children.length === 0) {\n\t\treturn { node: null };\n\t}\n\n\treturn {\n\t\tnode: $createSemanticTagNode(tag, getAttributesFromElement(domNode), text)\n\t};\n};\n\nexport class SemanticTagNode extends ElementNode {\n\t__tag: string;\n\t__attributes: SemanticTagAttributes;\n\t__text: null | string;\n\n\tstatic getType(): string {\n\t\treturn \"semantic-tag\";\n\t}\n\n\tstatic clone(node: SemanticTagNode): SemanticTagNode {\n\t\treturn new SemanticTagNode(node.__tag, node.__attributes, node.__text, node.__key);\n\t}\n\n\tconstructor(tag = \"span\", attributes: SemanticTagAttributes = {}, text: null | string = null, key?: NodeKey) {\n\t\tsuper(key);\n\t\tthis.__tag = tag;\n\t\tthis.__attributes = attributes;\n\t\tthis.__text = text;\n\t}\n\n\tstatic importDOM(): DOMConversionMap | null {\n\t\treturn {\n\t\t\tabbr: () => ({ conversion: convertSemanticTagElement, priority: 2 }),\n\t\t\tspan: () => ({ conversion: convertSemanticTagElement, priority: 2 }),\n\t\t\ttime: () => ({ conversion: convertSemanticTagElement, priority: 2 }),\n\t\t\tcite: () => ({ conversion: convertSemanticTagElement, priority: 2 }),\n\t\t\tdel: () => ({ conversion: convertSemanticTagElement, priority: 2 }),\n\t\t\tins: () => ({ conversion: convertSemanticTagElement, priority: 2 })\n\t\t};\n\t}\n\n\tstatic importJSON(serializedNode: SerializedSemanticTagNode): SemanticTagNode {\n\t\treturn $createSemanticTagNode(serializedNode.tag, serializedNode.attributes, serializedNode.text).updateFromJSON(serializedNode);\n\t}\n\n\tupdateFromJSON(serializedNode: LexicalUpdateJSON<SerializedSemanticTagNode>): this {\n\t\treturn super\n\t\t\t.updateFromJSON(serializedNode)\n\t\t\t.setTag(serializedNode.tag)\n\t\t\t.setAttributes(serializedNode.attributes || {})\n\t\t\t.setText(serializedNode.text || null);\n\t}\n\n\texportJSON(): SerializedSemanticTagNode {\n\t\treturn {\n\t\t\t...super.exportJSON(),\n\t\t\ttype: \"semantic-tag\",\n\t\t\tversion: 1,\n\t\t\ttag: this.getTag(),\n\t\t\tattributes: this.getAttributes(),\n\t\t\ttext: this.getText()\n\t\t};\n\t}\n\n\tcreateDOM(config: EditorConfig): HTMLElement {\n\t\tvoid config;\n\t\tconst element = document.createElement(this.__tag);\n\t\tthis.applyEditorAttributes(element);\n\t\treturn element;\n\t}\n\n\tupdateDOM(prevNode: this, dom: HTMLElement): boolean {\n\t\tif (prevNode.__tag !== this.__tag) {\n\t\t\treturn true;\n\t\t}\n\n\t\tthis.applyEditorAttributes(dom);\n\t\treturn false;\n\t}\n\n\texportDOM(): { element: HTMLElement } {\n\t\tconst element = document.createElement(this.__tag);\n\t\tObject.entries(this.__attributes).forEach(([key, value]) => {\n\t\t\telement.setAttribute(key, value);\n\t\t});\n\t\treturn { element };\n\t}\n\n\tapplyEditorAttributes(dom: HTMLElement): void {\n\t\tdom.classList.add(\"custom-tag-highlight\");\n\t\tArray.from(dom.attributes).forEach((attr) => {\n\t\t\tif (attr.name === \"class\") return;\n\t\t\tdom.removeAttribute(attr.name);\n\t\t});\n\t\tObject.entries(this.__attributes).forEach(([key, value]) => {\n\t\t\tdom.setAttribute(key, value);\n\t\t});\n\t}\n\n\tinsertNewAfter(_selection: RangeSelection, restoreSelection = true): null | ElementNode {\n\t\tconst node = $createSemanticTagNode(this.__tag, this.__attributes, this.__text);\n\t\tthis.insertAfter(node, restoreSelection);\n\t\treturn node;\n\t}\n\n\tcanInsertTextBefore(): boolean {\n\t\treturn false;\n\t}\n\n\tcanInsertTextAfter(): boolean {\n\t\treturn false;\n\t}\n\n\tcanBeEmpty(): boolean {\n\t\treturn false;\n\t}\n\n\tisInline(): boolean {\n\t\treturn true;\n\t}\n\n\tgetTag(): string {\n\t\treturn this.getLatest().__tag;\n\t}\n\n\tsetTag(tag: string): this {\n\t\tconst writable = this.getWritable();\n\t\twritable.__tag = tag;\n\t\treturn this;\n\t}\n\n\tgetAttributes(): SemanticTagAttributes {\n\t\treturn this.getLatest().__attributes;\n\t}\n\n\tsetAttributes(attributes: SemanticTagAttributes): this {\n\t\tconst writable = this.getWritable();\n\t\twritable.__attributes = attributes;\n\t\treturn this;\n\t}\n\n\tgetText(): null | string {\n\t\treturn this.getLatest().__text;\n\t}\n\n\tsetText(text: null | string): this {\n\t\tconst writable = this.getWritable();\n\t\twritable.__text = text;\n\t\treturn this;\n\t}\n}\n\nexport const $createSemanticTagNode = (\n\ttag: string,\n\tattributes: SemanticTagAttributes = {},\n\ttext: null | string = null\n): SemanticTagNode => {\n\treturn $applyNodeReplacement(new SemanticTagNode(tag, attributes, text));\n};\n\nexport const $isSemanticTagNode = (node: LexicalNode | null | undefined): node is SemanticTagNode => {\n\treturn node instanceof SemanticTagNode;\n};\n","import { useCallback } from \"react\";\n\nimport { $isLinkNode } from \"@lexical/link\";\nimport { INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND, REMOVE_LIST_COMMAND } from \"@lexical/list\";\nimport { $createHeadingNode, $createQuoteNode } from \"@lexical/rich-text\";\nimport { $setBlocksType } from \"@lexical/selection\";\nimport { $findMatchingParent } from \"@lexical/utils\";\nimport {\n\t$createParagraphNode,\n\t$createTextNode,\n\t$getSelection,\n\t$isRangeSelection,\n\tElementFormatType,\n\tFORMAT_ELEMENT_COMMAND,\n\tFORMAT_TEXT_COMMAND,\n\ttype LexicalEditor,\n\ttype LexicalNode,\n\tREDO_COMMAND,\n\tUNDO_COMMAND\n} from \"lexical\";\n\nimport { getSemanticTagDepth } from \"../../lib/semantic/getSemanticTagDepth\";\nimport { getHeadingTagByStyle, getLexicalInlineStyle } from \"../../lib/toolbar/styleMappers\";\nimport { $createAccessibleLinkNode, $isAccessibleLinkNode } from \"../../nodes/AccessibleLinkNode\";\nimport { $createSemanticTagNode, $isSemanticTagNode, type SemanticTagNode } from \"../../nodes/SemanticTagNode\";\nimport { LinkTypes, TagTypes } from \"../../toolbar\";\nimport { type LexicalToolbarState, type LinkType, type TextAlignment } from \"../textEditorTypes\";\n\ninterface InsertLinkPayload {\n\turl: string;\n\ttext: string;\n\tadd: string;\n\tariaLabel: string;\n\tqrCode: boolean;\n}\n\ninterface UseTextEditorLexicalActionsParams {\n\teditor: LexicalEditor | null;\n\ttoolbarState: LexicalToolbarState;\n\thasLocalLinkDialog: boolean;\n\tonOpenLinkDialog: (type: LinkTypes) => void;\n\tonOpenTagDialog: (type: TagTypes) => void;\n}\n\nexport function useTextEditorLexicalActions({\n\teditor,\n\ttoolbarState,\n\thasLocalLinkDialog,\n\tonOpenLinkDialog,\n\tonOpenTagDialog\n}: UseTextEditorLexicalActionsParams) {\n\tconst handleBlockStyleToggle = useCallback(\n\t\t(style: string) => {\n\t\t\tif (!editor) return;\n\n\t\t\tif (style === \"unordered-list-item\") {\n\t\t\t\tif (toolbarState.blockType === \"unordered-list-item\") {\n\t\t\t\t\teditor.dispatchCommand(REMOVE_LIST_COMMAND, undefined);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\teditor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, undefined);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (style === \"ordered-list-item\") {\n\t\t\t\tif (toolbarState.blockType === \"ordered-list-item\") {\n\t\t\t\t\teditor.dispatchCommand(REMOVE_LIST_COMMAND, undefined);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\teditor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, undefined);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\teditor.update(() => {\n\t\t\t\tconst selection = $getSelection();\n\t\t\t\tif (!$isRangeSelection(selection)) return;\n\n\t\t\t\tif (style === \"unstyled\" || style === \"paragraph\") {\n\t\t\t\t\t$setBlocksType(selection, () => $createParagraphNode());\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (style === \"blockquote\") {\n\t\t\t\t\t$setBlocksType(selection, () => $createQuoteNode());\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst headingTag = getHeadingTagByStyle(style);\n\t\t\t\tif (headingTag) {\n\t\t\t\t\t$setBlocksType(selection, () => $createHeadingNode(headingTag));\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t\t[editor, toolbarState.blockType]\n\t);\n\n\tconst handleInlineStyleToggle = useCallback(\n\t\t(style: string) => {\n\t\t\tif (!editor) return;\n\n\t\t\tconst lexicalStyle = getLexicalInlineStyle(style);\n\t\t\tif (!lexicalStyle) return;\n\n\t\t\teditor.dispatchCommand(FORMAT_TEXT_COMMAND, lexicalStyle as never);\n\t\t},\n\t\t[editor]\n\t);\n\n\tconst handleAlignmentChange = useCallback(\n\t\t(alignment: TextAlignment) => {\n\t\t\tif (!editor) return;\n\t\t\teditor.dispatchCommand(FORMAT_ELEMENT_COMMAND, alignment as ElementFormatType);\n\t\t},\n\t\t[editor]\n\t);\n\n\tconst handleUndo = useCallback(() => {\n\t\tif (!editor) return;\n\t\teditor.dispatchCommand(UNDO_COMMAND, undefined);\n\t}, [editor]);\n\n\tconst handleRedo = useCallback(() => {\n\t\tif (!editor) return;\n\t\teditor.dispatchCommand(REDO_COMMAND, undefined);\n\t}, [editor]);\n\n\tconst getCurrentSelectionText = useCallback((): string => {\n\t\tif (!editor) return \"\";\n\n\t\tlet text = \"\";\n\t\teditor.getEditorState().read(() => {\n\t\t\tconst selection = $getSelection();\n\t\t\tif (!$isRangeSelection(selection)) return;\n\t\t\ttext = selection.getTextContent();\n\t\t});\n\n\t\treturn text;\n\t}, [editor]);\n\n\tconst insertLinkAtSelection = useCallback(\n\t\t(payload: InsertLinkPayload) => {\n\t\t\tif (!editor) return;\n\n\t\t\teditor.update(() => {\n\t\t\t\tconst selection = $getSelection();\n\t\t\t\tif (!$isRangeSelection(selection)) return;\n\n\t\t\t\tconst selectionText = selection.getTextContent();\n\t\t\t\tconst finalText = payload.text.length > 0 ? payload.text : selectionText;\n\t\t\t\tif (!finalText.trim()) return;\n\n\t\t\t\tconst linkNode = $createAccessibleLinkNode(payload.url, {\n\t\t\t\t\ttarget: \"_blank\",\n\t\t\t\t\trel: \"noopener noreferrer\",\n\t\t\t\t\tariaLabel: payload.ariaLabel || selectionText || finalText,\n\t\t\t\t\tqrCode: payload.qrCode,\n\t\t\t\t\tadd: payload.add || null,\n\t\t\t\t\ttext: finalText\n\t\t\t\t});\n\n\t\t\t\tconst textNode = $createTextNode(finalText);\n\t\t\t\tlinkNode.append(textNode);\n\t\t\t\tselection.insertNodes([linkNode]);\n\t\t\t});\n\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\teditor.focus();\n\t\t\t});\n\t\t},\n\t\t[editor]\n\t);\n\n\tconst handleAddLink = useCallback(\n\t\t(url: string, text: string, add: string, ariaLabel: string, showQrCode: boolean) => {\n\t\t\tinsertLinkAtSelection({\n\t\t\t\turl,\n\t\t\t\ttext,\n\t\t\t\tadd,\n\t\t\t\tariaLabel,\n\t\t\t\tqrCode: showQrCode\n\t\t\t});\n\t\t},\n\t\t[insertLinkAtSelection]\n\t);\n\n\tconst handleAddLocalLink = useCallback(\n\t\t(url: string, caption: string) => {\n\t\t\tinsertLinkAtSelection({\n\t\t\t\turl,\n\t\t\t\ttext: caption,\n\t\t\t\tadd: \"\",\n\t\t\t\tariaLabel: \"Внутренняя ссылка на статью: \" + caption,\n\t\t\t\tqrCode: false\n\t\t\t});\n\t\t},\n\t\t[insertLinkAtSelection]\n\t);\n\n\tconst getSelectedLinkState = useCallback((): LinkType => {\n\t\tif (!editor) return \"\";\n\n\t\tlet state: LinkType = \"\";\n\t\teditor.getEditorState().read(() => {\n\t\t\tconst selection = $getSelection();\n\t\t\tif (!$isRangeSelection(selection)) {\n\t\t\t\tstate = \"\";\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst selectionText = selection.getTextContent();\n\t\t\tconst anchorNode = selection.anchor.getNode();\n\t\t\tconst linkNode = $findMatchingParent(anchorNode, (node) => $isAccessibleLinkNode(node) || $isLinkNode(node));\n\n\t\t\tif ($isAccessibleLinkNode(linkNode)) {\n\t\t\t\tstate = {\n\t\t\t\t\turl: linkNode.getURL(),\n\t\t\t\t\tariaLabel: linkNode.getAriaLabel() || \"\",\n\t\t\t\t\ttext: linkNode.getText() || selectionText,\n\t\t\t\t\tadd: linkNode.getAdd() || \"\",\n\t\t\t\t\tqrCode: linkNode.getQrCode()\n\t\t\t\t};\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ($isLinkNode(linkNode)) {\n\t\t\t\tstate = {\n\t\t\t\t\turl: linkNode.getURL(),\n\t\t\t\t\tariaLabel: \"\",\n\t\t\t\t\ttext: selectionText,\n\t\t\t\t\tadd: \"\",\n\t\t\t\t\tqrCode: false\n\t\t\t\t};\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tstate = selectionText;\n\t\t});\n\n\t\treturn state;\n\t}, [editor]);\n\n\tconst handleLinkClick = useCallback(\n\t\t(type: LinkTypes) => {\n\t\t\tif (type === LinkTypes.LOCAL_LINK && !hasLocalLinkDialog) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tonOpenLinkDialog(type);\n\t\t},\n\t\t[hasLocalLinkDialog, onOpenLinkDialog]\n\t);\n\n\tconst insertSemanticTagAtSelection = useCallback(\n\t\t(tag: string, text: string, attributes: Record<string, string>) => {\n\t\t\tif (!editor) return;\n\n\t\t\teditor.update(() => {\n\t\t\t\tconst selection = $getSelection();\n\t\t\t\tif (!$isRangeSelection(selection)) return;\n\n\t\t\t\tconst selectionText = selection.getTextContent().trim();\n\t\t\t\tconst finalText =\n\t\t\t\t\ttext || selectionText || attributes[\"title\"] || attributes[\"aria-label\"] || Object.values(attributes).join(\" \") || tag;\n\n\t\t\t\tif (!finalText.trim()) return;\n\n\t\t\t\tconst node = $createSemanticTagNode(tag, attributes, finalText);\n\t\t\t\tnode.append($createTextNode(finalText));\n\t\t\t\tselection.insertNodes([node]);\n\t\t\t});\n\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\teditor.focus();\n\t\t\t});\n\t\t},\n\t\t[editor]\n\t);\n\n\tconst handleCleanSemanticTag = useCallback(() => {\n\t\tif (!editor) return;\n\n\t\teditor.update(() => {\n\t\t\tconst selection = $getSelection();\n\t\t\tif (!$isRangeSelection(selection) || selection.isCollapsed()) return;\n\n\t\t\tconst selectedNodes = selection.getNodes();\n\t\t\tconst semanticNodes = new Set<SemanticTagNode>();\n\n\t\t\tselectedNodes.forEach((node) => {\n\t\t\t\tlet current: LexicalNode | null = node;\n\t\t\t\twhile (current) {\n\t\t\t\t\tif ($isSemanticTagNode(current)) {\n\t\t\t\t\t\tsemanticNodes.add(current);\n\t\t\t\t\t}\n\t\t\t\t\tcurrent = current.getParent();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tconst sortedNodes = Array.from(semanticNodes).sort((a, b) => getSemanticTagDepth(b) - getSemanticTagDepth(a));\n\t\t\tsortedNodes.forEach((node) => {\n\t\t\t\tif (!node.isAttached()) return;\n\t\t\t\tconst children = node.getChildren();\n\t\t\t\tchildren.forEach((child) => node.insertBefore(child));\n\t\t\t\tnode.remove();\n\t\t\t});\n\t\t});\n\t}, [editor]);\n\n\tconst handleTagClick = useCallback(\n\t\t(type: TagTypes) => {\n\t\t\tonOpenTagDialog(type);\n\t\t},\n\t\t[onOpenTagDialog]\n\t);\n\n\treturn {\n\t\thandleAddLink,\n\t\thandleAddLocalLink,\n\t\thandleAlignmentChange,\n\t\thandleBlockStyleToggle,\n\t\thandleCleanSemanticTag,\n\t\thandleInlineStyleToggle,\n\t\thandleLinkClick,\n\t\thandleRedo,\n\t\thandleTagClick,\n\t\thandleUndo,\n\t\tgetCurrentSelectionText,\n\t\tgetSelectedLinkState,\n\t\tinsertSemanticTagAtSelection\n\t};\n}\n","@use \"@/styles/mixins/mixin\" as *;\n\n.textEditor {\n\tfont-size: inherit;\n}\n\n.textEditorContent {\n\tposition: relative;\n\tpadding: var(--space-md);\n\tborder-radius: var(--radius-md);\n\tbackground-color: var(--surface-secondary);\n\tborder: var(--border);\n\n\t&.focused {\n\t\tborder-color: var(--brand-primary);\n\t}\n}\n\n.wrapper {\n\tfont-size: inherit;\n}\n","import { type MouseEvent, useEffect, useState } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { isSafe } from \"@ryuzaki13/react-foundation-lib/validators\";\n\nimport { Button } from \"../button\";\nimport { Input } from \"../input\";\nimport { Modal, ModalContent, ModalFooter } from \"../modal\";\n\nimport { LinkType } from \"./linkTypes\";\n\ninterface EmailDialogProps {\n\tisOpen: boolean;\n\tonClose: () => void;\n\tonConfirm: (url: string, text: string, add: string, ariaLabel: string, showQrCode: boolean) => void;\n\tinitialState?: LinkType;\n}\n\n/**\n * Диалог вставки или редактирования email-ссылки в текстовом редакторе.\n */\nexport function EmailDialog({ isOpen, onClose, onConfirm, initialState }: EmailDialogProps) {\n\tconst [email, setEmail] = useState(\"\");\n\tconst [ariaLabel, setAriaLabel] = useState(\"\");\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [state] = useState(() => {\n\t\tif (isSafe(initialState) && typeof initialState === \"string\") {\n\t\t\treturn { text: \"\", add: \"\", ariaLabel: \"\", url: initialState };\n\t\t}\n\n\t\treturn initialState;\n\t});\n\n\tuseEffect(() => {\n\t\tif (isOpen) {\n\t\t\tif (isSafe(state)) {\n\t\t\t\tsetEmail(state.url ?? \"\");\n\t\t\t\tsetAriaLabel(state.ariaLabel ?? \"\");\n\t\t\t}\n\t\t}\n\t}, [isOpen, state]);\n\n\tconst validateEmail = (email: string): boolean => {\n\t\tconst emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\t\tif (!emailRegex.test(email)) {\n\t\t\tsetError(\"Некорректный email адрес\");\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t};\n\n\tconst handleConfirm = (e: MouseEvent) => {\n\t\te.preventDefault();\n\n\t\tif (!validateEmail(email)) return;\n\t\tif (!ariaLabel) {\n\t\t\tsetError(\"Добавьте описание для email\");\n\t\t\treturn;\n\t\t}\n\n\t\tonConfirm(`mailto:${email}`, \"\", \"\", ariaLabel, false);\n\t\thandleClose();\n\t};\n\n\tconst handleClose = () => {\n\t\tsetEmail(\"\");\n\t\tsetAriaLabel(\"\");\n\t\tsetError(null);\n\t\tonClose();\n\t};\n\n\treturn (\n\t\t<Modal isOpen={isOpen} onClose={handleClose} title=\"Ссылка на email\" size=\"md\">\n\t\t\t<ModalContent>\n\t\t\t\t<div className={cn(\"flexColumn\", \"gapMd\")}>\n\t\t\t\t\t<Input label=\"Email адрес\" value={email} onChange={setEmail} placeholder=\"some_email@mail.ru\" />\n\n\t\t\t\t\t{error && (\n\t\t\t\t\t\t<div className=\"textColorDanger\">\n\t\t\t\t\t\t\t<strong>Ошибка ввода:</strong> <span className=\"fontItalic\">{error}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<Input\n\t\t\t\t\t\tlabel=\"Текст для экранных читалок\"\n\t\t\t\t\t\tvalue={ariaLabel}\n\t\t\t\t\t\tonChange={setAriaLabel}\n\t\t\t\t\t\tplaceholder=\"Электронная почта руководителя городской думмы\"\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t</ModalContent>\n\t\t\t<ModalFooter>\n\t\t\t\t<Button appearance=\"outline\" tone=\"error\" onClick={handleClose}>\n\t\t\t\t\tОтмена\n\t\t\t\t</Button>\n\t\t\t\t<Button appearance=\"outline\" tone=\"success\" onClick={handleConfirm} disabled={!email || !ariaLabel}>\n\t\t\t\t\tПодтвердить\n\t\t\t\t</Button>\n\t\t\t</ModalFooter>\n\t\t</Modal>\n\t);\n}\n","import { type MouseEvent, useEffect, useState } from \"react\";\n\nimport { isSafe, validateUrl } from \"@ryuzaki13/react-foundation-lib/validators\";\n\nimport { Button } from \"../button\";\nimport { CheckBox } from \"../check-box\";\nimport { GridContainer } from \"../grid\";\nimport { Input } from \"../input\";\nimport { Modal, ModalContent, ModalFooter } from \"../modal\";\n\nimport { LinkType } from \"./linkTypes\";\n\ninterface LinkDialogProps {\n\tisOpen: boolean;\n\tonClose: () => void;\n\tonConfirm: (url: string, text: string, add: string, ariaLabel: string, showQrCode: boolean) => void;\n\tinitialState?: LinkType;\n}\n\n/**\n * Диалог вставки или редактирования ссылки в текстовом редакторе.\n */\nexport function LinkDialog({ isOpen, onClose, onConfirm, initialState }: LinkDialogProps) {\n\tconst [url, setUrl] = useState(\"\");\n\tconst [ariaLabel, setAriaLabel] = useState(\"\");\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [showQrCode, setShowQrCode] = useState(false);\n\tconst [state] = useState(() => {\n\t\tif (isSafe(initialState)) {\n\t\t\tif (typeof initialState === \"string\") {\n\t\t\t\treturn { text: \"\", add: \"\", ariaLabel: \"\", url: initialState };\n\t\t\t}\n\t\t}\n\t\treturn initialState;\n\t});\n\n\tuseEffect(() => {\n\t\tif (isOpen) {\n\t\t\tif (isSafe(state)) {\n\t\t\t\tsetUrl(state.url ?? \"\");\n\t\t\t\tsetAriaLabel(state.ariaLabel ?? \"\");\n\t\t\t}\n\t\t}\n\t}, [isOpen, state]);\n\n\tconst handleUrlChange = (value: string) => {\n\t\tsetUrl(value);\n\n\t\t// Очищаем ошибку при изменении URL\n\t\tif (error) {\n\t\t\tsetError(null);\n\t\t}\n\t};\n\n\tconst handleConfirm = (e: MouseEvent) => {\n\t\te.preventDefault();\n\n\t\tconst validation = validateUrl(url);\n\t\tif (!validation.isValid) {\n\t\t\tsetError(validation.error);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!ariaLabel) {\n\t\t\tsetError(\"добавьте описание для ссылки\");\n\t\t\treturn;\n\t\t}\n\n\t\t// Добавляем протокол, если его нет\n\t\tconst finalUrl = url.startsWith(\"http\") ? url : `https://${url}`;\n\t\tonConfirm(finalUrl, \"\", \"\", ariaLabel, showQrCode);\n\t\thandleClose();\n\t};\n\n\tconst handleClose = () => {\n\t\tsetUrl(\"\");\n\t\tsetAriaLabel(\"\");\n\t\tsetError(null);\n\t\tonClose();\n\t};\n\n\treturn (\n\t\t<Modal isOpen={isOpen} onClose={handleClose} title=\"Ссылка на внешний url\" size=\"md\">\n\t\t\t<ModalContent>\n\t\t\t\t<GridContainer gap=\"md\">\n\t\t\t\t\t<Input label=\"Полный URL адрес\" value={url} onChange={handleUrlChange} placeholder=\"https://somesite.ru\" />\n\n\t\t\t\t\t{error && (\n\t\t\t\t\t\t<div className=\"textColorDanger\">\n\t\t\t\t\t\t\t<strong>Ошибка ввода:</strong> <span className=\"fontItalic\">{error}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<Input\n\t\t\t\t\t\tlabel=\"Текст для экранных читалок\"\n\t\t\t\t\t\tvalue={ariaLabel}\n\t\t\t\t\t\tonChange={setAriaLabel}\n\t\t\t\t\t\tplaceholder=\"Ссылка на официальный сайт городской думмы\"\n\t\t\t\t\t/>\n\n\t\t\t\t\t<CheckBox title=\"Показать кнопку для генерации QR кода ссылки\" value={showQrCode} onChange={setShowQrCode} />\n\t\t\t\t</GridContainer>\n\t\t\t</ModalContent>\n\t\t\t<ModalFooter>\n\t\t\t\t<Button appearance=\"outline\" tone=\"error\" onClick={handleClose}>\n\t\t\t\t\tОтмена\n\t\t\t\t</Button>\n\t\t\t\t<Button appearance=\"outline\" tone=\"success\" onClick={handleConfirm} disabled={!url || !ariaLabel}>\n\t\t\t\t\tПодтвердить\n\t\t\t\t</Button>\n\t\t\t</ModalFooter>\n\t\t</Modal>\n\t);\n}\n","import { type MouseEvent, useEffect, useState } from \"react\";\n\nimport { formatPhone } from \"@ryuzaki13/react-foundation-lib/formatters\";\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { isSafe } from \"@ryuzaki13/react-foundation-lib/validators\";\n\nimport { Button } from \"../button\";\nimport { GridContainer } from \"../grid\";\nimport { Input } from \"../input\";\nimport { Modal, ModalContent, ModalFooter } from \"../modal\";\n\nimport { LinkType } from \"./linkTypes\";\n\ninterface PhoneDialogProps {\n\tisOpen: boolean;\n\tonClose: () => void;\n\tonConfirm: (url: string, text: string, add: string, ariaLabel: string, showQrCode: boolean) => void;\n\tinitialState?: LinkType;\n}\n\n/**\n * Диалог вставки или редактирования телефонной ссылки в текстовом редакторе.\n */\nexport function PhoneDialog({ isOpen, onClose, onConfirm, initialState }: PhoneDialogProps) {\n\tconst [phone, setPhone] = useState(\"\");\n\tconst [phoneAdd, setPhoneAdd] = useState(\"\");\n\tconst [ariaLabel, setAriaLabel] = useState(\"\");\n\tconst [error, setError] = useState<string | null>(null);\n\tconst [state] = useState(() => {\n\t\tif (isSafe(initialState) && typeof initialState === \"string\") {\n\t\t\treturn { text: \"\", add: \"\", ariaLabel: \"\", url: initialState };\n\t\t}\n\n\t\treturn initialState;\n\t});\n\n\tuseEffect(() => {\n\t\tif (isOpen) {\n\t\t\tif (isSafe(state)) {\n\t\t\t\tsetPhone((state.url ?? \"\").replace(/\\D/g, \"\").slice(0, 11).replace(/^7/, \"\"));\n\n\t\t\t\tif (!state.add) {\n\t\t\t\t\tsetPhoneAdd((state.url ?? \"\").replace(/\\D/g, \"\").slice(11));\n\t\t\t\t} else {\n\t\t\t\t\tsetPhoneAdd((state.add ?? \"\").replace(/\\D/g, \"\"));\n\t\t\t\t}\n\n\t\t\t\tsetAriaLabel(state.ariaLabel ?? \"\");\n\t\t\t}\n\t\t}\n\t}, [isOpen, state]);\n\n\tconst handlePhoneChange = (value: string) => {\n\t\tvalue = value.replace(/\\D/g, \"\");\n\t\tif (value.length <= 10) {\n\t\t\tsetPhone(value);\n\t\t\tsetError(null);\n\t\t} else {\n\t\t\tsetError(\"нельзя ввести более 10 цифр\");\n\t\t}\n\t};\n\n\tconst validatePhone = (phone: string): boolean => {\n\t\tif (phone.length !== 10) {\n\t\t\tsetError(\"номер телефона должен содержать 10 цифр\");\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t};\n\n\tconst handleConfirm = (e: MouseEvent) => {\n\t\te.preventDefault();\n\n\t\tif (!validatePhone(phone)) return;\n\t\tif (!ariaLabel) {\n\t\t\tsetError(\"добавьте описание для телефона\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst formattedPhone = formatPhone(phone);\n\t\tconst fullPhone = `+7${phone}`;\n\t\tonConfirm(`tel:${fullPhone}`, phoneAdd ? `${formattedPhone} доб. ${phoneAdd}` : formattedPhone, phoneAdd, ariaLabel, false);\n\t\thandleClose();\n\t};\n\n\tconst handleClose = () => {\n\t\tsetPhone(\"\");\n\t\tsetAriaLabel(\"\");\n\t\tsetError(null);\n\t\tonClose();\n\t};\n\n\treturn (\n\t\t<Modal isOpen={isOpen} onClose={handleClose} title=\"Ссылка на телефон\" size=\"md\">\n\t\t\t<ModalContent>\n\t\t\t\t<GridContainer gap=\"md\">\n\t\t\t\t\t<div className={cn(\"flex\", \"alignItemsEnd\", \"gapSm\")}>\n\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\tlabel=\"Номер телефона без 7-ки\"\n\t\t\t\t\t\t\tdescription=\"Вводится только номер (10) цифр без каких-либо дополнительных символов. Ссылка будет привязана к текущему выделенному фрагменту текста. Поэтому текст самой ссылки можно оформить грамотно, например: +7 (3522) 12-34-56 доб. 100\"\n\t\t\t\t\t\t\tvalue={phone}\n\t\t\t\t\t\t\tonChange={handlePhoneChange}\n\t\t\t\t\t\t\tplaceholder=\"3522123456\"\n\t\t\t\t\t\t\tclassName=\"flex1\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<Input label=\"Добавочный номер\" value={phoneAdd} onChange={setPhoneAdd} placeholder=\"100\" />\n\t\t\t\t\t</div>\n\t\t\t\t\t{error && (\n\t\t\t\t\t\t<div className=\"textColorDanger\">\n\t\t\t\t\t\t\t<strong>Ошибка ввода:</strong> <span className=\"fontItalic\">{error}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<Input\n\t\t\t\t\t\tlabel=\"Текст для экранных читалок\"\n\t\t\t\t\t\tdescription=\"Обязательное поле для организации доступности ссылки для лиц с ОВЗ, использующих скринридеры\"\n\t\t\t\t\t\tvalue={ariaLabel}\n\t\t\t\t\t\tonChange={setAriaLabel}\n\t\t\t\t\t\tplaceholder=\"Контактный телефон директора\"\n\t\t\t\t\t/>\n\t\t\t\t</GridContainer>\n\t\t\t</ModalContent>\n\t\t\t<ModalFooter>\n\t\t\t\t<Button appearance=\"solid\" tone=\"error\" onClick={handleClose}>\n\t\t\t\t\tОтмена\n\t\t\t\t</Button>\n\t\t\t\t<Button appearance=\"solid\" tone=\"success\" onClick={handleConfirm} disabled={!phone || !ariaLabel}>\n\t\t\t\t\tПодтвердить\n\t\t\t\t</Button>\n\t\t\t</ModalFooter>\n\t\t</Modal>\n\t);\n}\n","import { type ReactNode, useEffect, useState } from \"react\";\n\nimport { Button } from \"../button\";\nimport { GridContainer } from \"../grid\";\nimport { Input } from \"../input\";\nimport { Modal, ModalContent, ModalFooter } from \"../modal\";\n\nexport interface AttributeField {\n\tname: string;\n\tlabel: string;\n\tdescription?: string;\n\tplaceholder?: string;\n\trequired?: boolean;\n\tvalidate?: (value: string) => string | null;\n}\n\nexport interface SemanticTagConfig {\n\ttagName: string;\n\ttitle: string;\n\tdescription: string;\n\texample: ReactNode;\n\tfields: AttributeField[];\n}\n\ninterface SemanticDialogProps {\n\tisOpen: boolean;\n\tonClose: () => void;\n\tonConfirm: (tagName: string, text: string, attributes: Record<string, string>) => void;\n\tconfig: SemanticTagConfig;\n\tinitialState?: Record<string, string>;\n\tinitialText?: string;\n}\n\n/**\n * Диалог настройки семантического тега и его атрибутов в текстовом редакторе.\n */\nexport function SemanticDialog({ isOpen, onClose, onConfirm, config, initialText = \"\", initialState = {} }: SemanticDialogProps) {\n\tconst [text, setText] = useState(initialText);\n\tconst [values, setValues] = useState<Record<string, string>>({});\n\tconst [errors, setErrors] = useState<Record<string, string | null>>({});\n\tconst [initialized, setInitialized] = useState(false);\n\n\tuseEffect(() => {\n\t\tif (isOpen && !initialized) {\n\t\t\tconst initial = config.fields.reduce(\n\t\t\t\t(acc, field) => {\n\t\t\t\t\tacc[field.name] = initialState[field.name] ?? \"\";\n\t\t\t\t\treturn acc;\n\t\t\t\t},\n\t\t\t\t{} as Record<string, string>\n\t\t\t);\n\t\t\tsetValues(initial);\n\t\t\tsetErrors({});\n\t\t\tsetInitialized(true);\n\t\t} else if (!isOpen && initialized) {\n\t\t\tsetInitialized(false); // сбрасываем при закрытии\n\t\t}\n\t}, [isOpen, config.fields, initialState, initialized]);\n\n\tconst handleChange = (name: string, value: string) => {\n\t\tsetValues((prev) => ({ ...prev, [name]: value }));\n\t\tsetErrors((prev) => ({ ...prev, [name]: null }));\n\t};\n\n\tconst validate = (): boolean => {\n\t\tconst newErrors: Record<string, string | null> = {};\n\t\tlet isValid = true;\n\n\t\tif (!text.trim()) {\n\t\t\tnewErrors[\"text\"] = \"Обязательное поле\";\n\t\t\tisValid = false;\n\t\t}\n\n\t\tfor (const field of config.fields) {\n\t\t\tconst value = values[field.name]?.trim();\n\t\t\tif (field.required && !value) {\n\t\t\t\tnewErrors[field.name] = \"Обязательное поле\";\n\t\t\t\tisValid = false;\n\t\t\t} else if (field.validate) {\n\t\t\t\tconst err = field.validate(value);\n\t\t\t\tif (err) {\n\t\t\t\t\tnewErrors[field.name] = err;\n\t\t\t\t\tisValid = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tsetErrors(newErrors);\n\t\treturn isValid;\n\t};\n\n\tconst handleConfirm = () => {\n\t\tif (!validate()) return;\n\t\tonConfirm(config.tagName, text.trim(), values);\n\t\tonClose();\n\t};\n\n\treturn (\n\t\t<Modal isOpen={isOpen} onClose={onClose} title={`Вставка <${config.tagName}>`} size=\"md\">\n\t\t\t<ModalContent>\n\t\t\t\t<GridContainer gap=\"md\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t{config.description}.<br />\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<strong>Пример:</strong> {config.example}\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<Input\n\t\t\t\t\t\tlabel={config.title}\n\t\t\t\t\t\tdescription={`Данный текст будет вставлен в редактор и обёрнуть в специальный семантический тег ${config.tagName}`}\n\t\t\t\t\t\tvalue={text}\n\t\t\t\t\t\tonChange={setText}\n\t\t\t\t\t\terror={errors[\"text\"] ?? undefined}\n\t\t\t\t\t\trequired\n\t\t\t\t\t/>\n\t\t\t\t\t{config.fields.map((field) => {\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\tkey={field.name}\n\t\t\t\t\t\t\t\tlabel={field.label}\n\t\t\t\t\t\t\t\tdescription={field.description}\n\t\t\t\t\t\t\t\tplaceholder={field.placeholder}\n\t\t\t\t\t\t\t\tvalue={values[field.name] ?? \"\"}\n\t\t\t\t\t\t\t\tonChange={(value) => handleChange(field.name, value)}\n\t\t\t\t\t\t\t\terror={errors[field.name] ?? undefined}\n\t\t\t\t\t\t\t\trequired={field.required}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</GridContainer>\n\t\t\t</ModalContent>\n\t\t\t<ModalFooter>\n\t\t\t\t<Button appearance=\"solid\" tone=\"error\" onClick={onClose}>\n\t\t\t\t\tОтмена\n\t\t\t\t</Button>\n\t\t\t\t<Button appearance=\"solid\" tone=\"success\" onClick={handleConfirm}>\n\t\t\t\t\tПодтвердить\n\t\t\t\t</Button>\n\t\t\t</ModalFooter>\n\t\t</Modal>\n\t);\n}\n","import { TagTypes } from \"./toolbar\";\n\nimport type { SemanticTagConfig } from \"./SemanticDialog\";\n\nexport const SemanticTagConfigs: Record<TagTypes, SemanticTagConfig> = {\n\t[TagTypes.abbr]: {\n\t\ttagName: \"abbr\",\n\t\ttitle: \"Аббревиатура\",\n\t\tdescription: \"Обозначает аббревиатуры и сокращения, при наведении покажет расшифровку\",\n\t\texample: (\n\t\t\t<>\n\t\t\t\t<abbr title=\"Национальное управление по аэронавтике и исследованию космического пространства\">НАСА</abbr>\n\t\t\t\t<div className=\"marginTopMd\">\n\t\t\t\t\t<code>{`<abbr title=\"Национальное управление по аэронавтике и исследованию космического пространства\">НАСА</abbr>`}</code>\n\t\t\t\t</div>\n\t\t\t</>\n\t\t),\n\t\tfields: [\n\t\t\t{\n\t\t\t\tname: \"title\",\n\t\t\t\tlabel: \"Расшифровка\",\n\t\t\t\tdescription: \"Появится как подсказка и будет прочитана скринридером\",\n\t\t\t\tplaceholder: \"например: HyperText Markup Language\",\n\t\t\t\trequired: true\n\t\t\t}\n\t\t]\n\t},\n\t[TagTypes.lang]: {\n\t\ttagName: \"span\",\n\t\ttitle: \"Текст на другом языке\",\n\t\tdescription:\n\t\t\t\"Указывает язык фрагмента текста, если он отличается от основного языка страницы, скринридер прочитает это слово с французским произношением\",\n\t\texample: (\n\t\t\t<>\n\t\t\t\t<span lang=\"fr\">Bonjour!</span> — сказал турист.\n\t\t\t\t<div className=\"marginTopMd\">\n\t\t\t\t\t<code>{`<span lang=\"fr\">Bonjour!</span> — сказал турист.`}</code>\n\t\t\t\t</div>\n\t\t\t</>\n\t\t),\n\t\tfields: [\n\t\t\t{\n\t\t\t\tname: \"lang\",\n\t\t\t\tlabel: \"Код языка\",\n\t\t\t\tplaceholder: \"en, fr, ru\",\n\t\t\t\trequired: true,\n\t\t\t\tvalidate: (val) => (!/^[a-z]{2,3}(-[A-Z]{2})?$/.test(val) ? \"Неверный код языка (например, en или en-US)\" : null)\n\t\t\t}\n\t\t]\n\t},\n\t[TagTypes.time]: {\n\t\ttagName: \"time\",\n\t\ttitle: \"Дата/время\",\n\t\tdescription: \"\",\n\t\texample: \"\",\n\t\tfields: [\n\t\t\t{\n\t\t\t\tname: \"datetime\",\n\t\t\t\tlabel: \"Дата/время (machine-readable)\",\n\t\t\t\tdescription: \"Формат ISO 8601: 2025-05-18, 14:30, 2025-05-18T14:30\",\n\t\t\t\tplaceholder: \"например: 2025-05-18T14:30\",\n\t\t\t\trequired: true\n\t\t\t}\n\t\t]\n\t},\n\t[TagTypes.cite]: {\n\t\ttagName: \"cite\",\n\t\ttitle: \"Цитата источника\",\n\t\tdescription: \"Обозначает название книги, статьи, фильма или другого произведения, на которое вы ссылаетесь\",\n\t\texample: (\n\t\t\t<>\n\t\t\t\tПо словам Эйнштейна: <cite>«Воображение важнее знания»</cite>.\n\t\t\t\t<div className=\"marginTopMd\">\n\t\t\t\t\t<code>{`По словам Эйнштейна: <cite>«Воображение важнее знания»</cite>.`}</code>\n\t\t\t\t</div>\n\t\t\t</>\n\t\t),\n\t\tfields: [\n\t\t\t{\n\t\t\t\tname: \"title\",\n\t\t\t\tlabel: \"Название источника\",\n\t\t\t\tdescription: \"Будет отображаться как подсказка\",\n\t\t\t\tplaceholder: \"например: Википедия\",\n\t\t\t\trequired: false\n\t\t\t}\n\t\t]\n\t},\n\t// [TagTypes.address]: {\n\t// \ttagName: \"address\",\n\t// \ttitle: \"Указывает контакты автора статьи/страницы (не для почтовых адресов компаний!)\",\n\t// \tdescription: \"\",\n\t// \texample: ``,\n\t// \tfields: [\n\t// \t\t{\n\t// \t\t\tname: \"aria-label\",\n\t// \t\t\tlabel: \"Описание (для доступности)\",\n\t// \t\t\tdescription: \"Содержимое будет прочитано скринридером, если адрес не очевиден\",\n\t// \t\t\tplaceholder: \"например: Контактный адрес компании\",\n\t// \t\t\trequired: false\n\t// \t\t}\n\t// \t]\n\t// },\n\t[TagTypes.del]: {\n\t\ttagName: \"del\",\n\t\ttitle: \"Изменения в тексте\",\n\t\tdescription: \"Удаленный фрагмент\",\n\t\texample: (\n\t\t\t<>\n\t\t\t\tПроект сдачи: <del>1 июня</del> <ins>15 июня</ins>\n\t\t\t\t<div className=\"marginTopMd\">\n\t\t\t\t\t<code>{`Проект сдачи: <del>1 июня</del> <ins>15 июня</ins>`}</code>\n\t\t\t\t</div>\n\t\t\t</>\n\t\t),\n\t\tfields: [\n\t\t\t{\n\t\t\t\tname: \"datetime\",\n\t\t\t\tlabel: \"Когда был удалён\",\n\t\t\t\tdescription: \"Формат ISO 8601: 2025-05-18T14:30\",\n\t\t\t\tplaceholder: \"например: 2025-05-18T14:30\",\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"cite\",\n\t\t\t\tlabel: \"Источник/обоснование\",\n\t\t\t\tdescription: \"Ссылка на объяснение причины\",\n\t\t\t\tplaceholder: \"например: https://example.com/edit-log\",\n\t\t\t\trequired: false\n\t\t\t}\n\t\t]\n\t},\n\t[TagTypes.ins]: {\n\t\ttagName: \"ins\",\n\t\ttitle: \"Изменения в тексте\",\n\t\tdescription: \"Новый добавленный текст\",\n\t\texample: (\n\t\t\t<>\n\t\t\t\tПроект сдачи: <del>1 июня</del> <ins>15 июня</ins>\n\t\t\t\t<div className=\"marginTopMd\">\n\t\t\t\t\t<code>{`Проект сдачи: <del>1 июня</del> <ins>15 июня</ins>`}</code>\n\t\t\t\t</div>\n\t\t\t</>\n\t\t),\n\t\tfields: [\n\t\t\t{\n\t\t\t\tname: \"datetime\",\n\t\t\t\tlabel: \"Когда был добавлен\",\n\t\t\t\tdescription: \"Формат ISO 8601: 2025-05-18T14:30\",\n\t\t\t\tplaceholder: \"например: 2025-05-18T14:30\",\n\t\t\t\trequired: false\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"cite\",\n\t\t\t\tlabel: \"Источник/обоснование\",\n\t\t\t\tdescription: \"Ссылка на объяснение причины\",\n\t\t\t\tplaceholder: \"например: https://example.com/edit-log\",\n\t\t\t\trequired: false\n\t\t\t}\n\t\t]\n\t}\n};\n","import { useEffect, useEffectEvent, useState } from \"react\";\n\nimport { Button } from \"../button\";\nimport { GridContainer } from \"../grid\";\nimport { Input } from \"../input\";\nimport { Modal, ModalContent, ModalFooter } from \"../modal\";\nimport { RadioGroup } from \"../radio-group\";\n\ntype TimeDialogInitialState = {\n\tmode?: TimeMode;\n\tfrom?: string;\n\tto?: string;\n};\n\ninterface TimeDialogProps {\n\tisOpen: boolean;\n\tonClose: () => void;\n\tonConfirm: (tagName: string, text: string, attributes: Record<string, string>) => void;\n\tinitialState?: TimeDialogInitialState;\n}\n\ntype TimeMode = \"date\" | \"datetime\" | \"time\" | \"range-time\" | \"range-date\" | \"range-datetime\";\n\n/**\n * Диалог настройки временного атрибута или значения в текстовом редакторе.\n */\nexport function TimeDialog({ isOpen, onClose, onConfirm, initialState }: TimeDialogProps) {\n\tconst [mode, setMode] = useState<TimeMode | undefined>(\"date\");\n\tconst [from, setFrom] = useState(\"\");\n\tconst [to, setTo] = useState(\"\");\n\tconst [errors, setErrors] = useState<{ from?: string; to?: string }>({});\n\n\tconst syncInitialState = useEffectEvent((initialState?: TimeDialogInitialState) => {\n\t\tsetMode(initialState?.mode ?? \"date\");\n\t\tsetFrom(initialState?.from ?? \"\");\n\t\tsetTo(initialState?.to ?? \"\");\n\t\tsetErrors({});\n\t});\n\n\tuseEffect(() => {\n\t\tif (isOpen) {\n\t\t\tsyncInitialState(initialState);\n\t\t}\n\t}, [isOpen, initialState]);\n\n\tconst validate = () => {\n\t\tconst newErrors: typeof errors = {};\n\t\t// const isValid = true;\n\n\t\tconst isDate = (v: string) => /^\\d{4}-\\d{2}-\\d{2}$/.test(v);\n\t\tconst isTime = (v: string) => /^\\d{2}:\\d{2}$/.test(v);\n\t\tconst isDateTime = (v: string) => /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}$/.test(v);\n\n\t\tconst check = (label: string, value: string, type: \"date\" | \"time\" | \"datetime\") => {\n\t\t\tif (!value) return `${label} обязательно`;\n\t\t\tif (type === \"date\" && !isDate(value)) return \"Неверный формат даты (ГГГГ-ММ-ДД)\";\n\t\t\tif (type === \"time\" && !isTime(value)) return \"Неверный формат времени (ЧЧ:ММ)\";\n\t\t\tif (type === \"datetime\" && !isDateTime(value)) return \"Неверный формат даты и времени (ГГГГ-ММ-ДДTЧЧ:ММ)\";\n\t\t\treturn undefined;\n\t\t};\n\n\t\tswitch (mode) {\n\t\t\tcase \"date\":\n\t\t\t\tnewErrors.from = check(\"Дата\", from, \"date\");\n\t\t\t\tbreak;\n\t\t\tcase \"time\":\n\t\t\t\tnewErrors.from = check(\"Время\", from, \"time\");\n\t\t\t\tbreak;\n\t\t\tcase \"datetime\":\n\t\t\t\tnewErrors.from = check(\"Дата и время\", from, \"datetime\");\n\t\t\t\tbreak;\n\t\t\tcase \"range-time\":\n\t\t\t\tnewErrors.from = check(\"Время начала\", from, \"time\");\n\t\t\t\tnewErrors.to = check(\"Время окончания\", to, \"time\");\n\t\t\t\tbreak;\n\t\t\tcase \"range-date\":\n\t\t\t\tnewErrors.from = check(\"Дата начала\", from, \"date\");\n\t\t\t\tnewErrors.to = check(\"Дата окончания\", to, \"date\");\n\t\t\t\tbreak;\n\t\t\tcase \"range-datetime\":\n\t\t\t\tnewErrors.from = check(\"Начало\", from, \"datetime\");\n\t\t\t\tnewErrors.to = check(\"Окончание\", to, \"datetime\");\n\t\t\t\tbreak;\n\t\t}\n\n\t\tsetErrors(newErrors);\n\t\treturn Object.values(newErrors).every((e) => !e);\n\t};\n\n\tconst handleConfirm = () => {\n\t\tif (!validate()) return;\n\n\t\tconst datetime = to ? `${from}/${to}` : from;\n\t\tonConfirm(\"time\", datetime, { datetime });\n\t\tonClose();\n\t};\n\n\tconst renderInputs = () => {\n\t\tswitch (mode) {\n\t\t\tcase \"date\":\n\t\t\tcase \"datetime\":\n\t\t\tcase \"time\":\n\t\t\t\treturn (\n\t\t\t\t\t<Input\n\t\t\t\t\t\tlabel=\"Значение\"\n\t\t\t\t\t\tplaceholder={mode === \"time\" ? \"09:00\" : mode === \"date\" ? \"2025-05-18\" : \"2025-05-18T09:00\"}\n\t\t\t\t\t\tvalue={from}\n\t\t\t\t\t\tonChange={setFrom}\n\t\t\t\t\t\terror={errors.from}\n\t\t\t\t\t/>\n\t\t\t\t);\n\t\t\tcase \"range-time\":\n\t\t\tcase \"range-date\":\n\t\t\tcase \"range-datetime\":\n\t\t\t\treturn (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\tlabel=\"С\"\n\t\t\t\t\t\t\tplaceholder={mode.includes(\"time\") ? \"09:00\" : mode.includes(\"date\") ? \"2025-05-18\" : \"2025-05-18T09:00\"}\n\t\t\t\t\t\t\tvalue={from}\n\t\t\t\t\t\t\tonChange={setFrom}\n\t\t\t\t\t\t\terror={errors.from}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\tlabel=\"По\"\n\t\t\t\t\t\t\tplaceholder={mode.includes(\"time\") ? \"17:00\" : mode.includes(\"date\") ? \"2025-05-22\" : \"2025-05-22T17:00\"}\n\t\t\t\t\t\t\tvalue={to}\n\t\t\t\t\t\t\tonChange={setFrom}\n\t\t\t\t\t\t\terror={errors.to}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</>\n\t\t\t\t);\n\t\t}\n\t};\n\n\treturn (\n\t\t<Modal isOpen={isOpen} onClose={onClose} title=\"Вставка <time>\" size=\"md\">\n\t\t\t<ModalContent>\n\t\t\t\t<GridContainer gap=\"md\">\n\t\t\t\t\t<RadioGroup label=\"Тип значения\" value={mode} onChange={setMode}>\n\t\t\t\t\t\t<RadioGroup.Option label=\"Дата\" value=\"date\" />\n\t\t\t\t\t\t<RadioGroup.Option label=\"Дата и время\" value=\"datetime\" />\n\t\t\t\t\t\t<RadioGroup.Option label=\"Время\" value=\"time\" />\n\t\t\t\t\t\t<RadioGroup.Option label=\"Диапазон дат\" value=\"range-date\" />\n\t\t\t\t\t\t<RadioGroup.Option label=\"Диапазон времени\" value=\"range-time\" />\n\t\t\t\t\t\t<RadioGroup.Option label=\"Диапазон даты и времени\" value=\"range-datetime\" />\n\t\t\t\t\t</RadioGroup>\n\n\t\t\t\t\t<GridContainer gap=\"md\">{renderInputs()}</GridContainer>\n\t\t\t\t</GridContainer>\n\t\t\t</ModalContent>\n\t\t\t<ModalFooter>\n\t\t\t\t<Button appearance=\"solid\" tone=\"error\" onClick={onClose}>\n\t\t\t\t\tОтмена\n\t\t\t\t</Button>\n\t\t\t\t<Button appearance=\"solid\" tone=\"success\" onClick={handleConfirm}>\n\t\t\t\t\tПодтвердить\n\t\t\t\t</Button>\n\t\t\t</ModalFooter>\n\t\t</Modal>\n\t);\n}\n","import type { ComponentType } from \"react\";\n\nimport { EmailDialog } from \"./EmailDialog\";\nimport { LinkDialog } from \"./LinkDialog\";\nimport { PhoneDialog } from \"./PhoneDialog\";\nimport { SemanticDialog } from \"./SemanticDialog\";\nimport { SemanticTagConfigs } from \"./semanticTagConfigs\";\nimport { TimeDialog } from \"./TimeDialog\";\nimport { LinkTypes, TagTypes } from \"./toolbar\";\n\nimport type { LocalLinkDialogAdapterProps } from \"./editorModel\";\nimport type { LinkType } from \"./model/textEditorTypes\";\n\ninterface TextEditorDialogsProps {\n\tlinkTypeDialog: LinkTypes | null;\n\ttagTypeDialog: TagTypes | null;\n\tlocalLinkDialogComponent?: ComponentType<LocalLinkDialogAdapterProps>;\n\tonCloseLinkDialog: () => void;\n\tonCloseTagDialog: () => void;\n\tonAddLink: (url: string, text: string, add: string, ariaLabel: string, showQrCode: boolean) => void;\n\tonAddLocalLink: (url: string, caption: string) => void;\n\tonInsertSemanticTag: (tagName: string, text: string, attributes: Record<string, string>) => void;\n\tgetCurrentSelectionText: () => string;\n\tgetSelectedLinkState: () => LinkType;\n}\n\n/**\n * Контейнер набора диалогов, которые используются редактором для вставки ссылок и семантических сущностей.\n */\nexport function TextEditorDialogs({\n\tlinkTypeDialog,\n\ttagTypeDialog,\n\tlocalLinkDialogComponent,\n\tonCloseLinkDialog,\n\tonCloseTagDialog,\n\tonAddLink,\n\tonAddLocalLink,\n\tonInsertSemanticTag,\n\tgetCurrentSelectionText,\n\tgetSelectedLinkState\n}: TextEditorDialogsProps) {\n\tconst LocalLinkDialogComponent = localLinkDialogComponent;\n\n\treturn (\n\t\t<>\n\t\t\t{linkTypeDialog && (\n\t\t\t\t<>\n\t\t\t\t\t{LocalLinkDialogComponent && (\n\t\t\t\t\t\t<LocalLinkDialogComponent\n\t\t\t\t\t\t\tisOpen={linkTypeDialog === LinkTypes.LOCAL_LINK}\n\t\t\t\t\t\t\tonClose={onCloseLinkDialog}\n\t\t\t\t\t\t\tonConfirm={onAddLocalLink}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<LinkDialog\n\t\t\t\t\t\tisOpen={linkTypeDialog === LinkTypes.LINK}\n\t\t\t\t\t\tinitialState={getSelectedLinkState()}\n\t\t\t\t\t\tonClose={onCloseLinkDialog}\n\t\t\t\t\t\tonConfirm={onAddLink}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<PhoneDialog\n\t\t\t\t\t\tisOpen={linkTypeDialog === LinkTypes.PHONE}\n\t\t\t\t\t\tinitialState={getSelectedLinkState()}\n\t\t\t\t\t\tonClose={onCloseLinkDialog}\n\t\t\t\t\t\tonConfirm={onAddLink}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<EmailDialog\n\t\t\t\t\t\tisOpen={linkTypeDialog === LinkTypes.EMAIL}\n\t\t\t\t\t\tinitialState={getSelectedLinkState()}\n\t\t\t\t\t\tonClose={onCloseLinkDialog}\n\t\t\t\t\t\tonConfirm={onAddLink}\n\t\t\t\t\t/>\n\t\t\t\t</>\n\t\t\t)}\n\n\t\t\t{tagTypeDialog &&\n\t\t\t\t(tagTypeDialog !== TagTypes.time ? (\n\t\t\t\t\t<SemanticDialog\n\t\t\t\t\t\tisOpen={true}\n\t\t\t\t\t\tonClose={onCloseTagDialog}\n\t\t\t\t\t\tonConfirm={onInsertSemanticTag}\n\t\t\t\t\t\tconfig={SemanticTagConfigs[tagTypeDialog]}\n\t\t\t\t\t\tinitialText={getCurrentSelectionText()}\n\t\t\t\t\t/>\n\t\t\t\t) : (\n\t\t\t\t\t<TimeDialog isOpen={true} onClose={onCloseTagDialog} onConfirm={onInsertSemanticTag} />\n\t\t\t\t))}\n\t\t</>\n\t);\n}\n","import { useCallback, useMemo, useState } from \"react\";\n\nimport { $generateHtmlFromNodes } from \"@lexical/html\";\nimport { ListItemNode, ListNode } from \"@lexical/list\";\nimport { LexicalComposer } from \"@lexical/react/LexicalComposer\";\nimport { ContentEditable } from \"@lexical/react/LexicalContentEditable\";\nimport { LexicalErrorBoundary } from \"@lexical/react/LexicalErrorBoundary\";\nimport { HistoryPlugin } from \"@lexical/react/LexicalHistoryPlugin\";\nimport { ListPlugin } from \"@lexical/react/LexicalListPlugin\";\nimport { OnChangePlugin } from \"@lexical/react/LexicalOnChangePlugin\";\nimport { RichTextPlugin } from \"@lexical/react/LexicalRichTextPlugin\";\nimport { HeadingNode, QuoteNode } from \"@lexical/rich-text\";\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { type LexicalEditor, type EditorState as LexicalEditorState } from \"lexical\";\n\nimport { TextEditorCoreProps, isLexicalTextRaw } from \"./editorModel\";\nimport { InitialHtmlPlugin, SelectionStatePlugin } from \"./lexical/plugins\";\nimport { createLexicalRaw } from \"./lib/serialization/createLexicalRaw\";\nimport { useTextEditorLexicalActions } from \"./model/hooks/useTextEditorLexicalActions\";\nimport { DEFAULT_TOOLBAR_STATE, type LexicalToolbarState } from \"./model/textEditorTypes\";\nimport { AccessibleLinkNode } from \"./nodes/AccessibleLinkNode\";\nimport { SemanticTagNode } from \"./nodes/SemanticTagNode\";\nimport TextEditorStyle from \"./TextEditor.module.scss\";\nimport \"./TextEditor.scss\";\nimport { TextEditorDialogs } from \"./TextEditorDialogs\";\nimport { type LinkTypes, type TagTypes, TextEditorToolbarLexical } from \"./toolbar\";\n\ntype TextEditorProps = TextEditorCoreProps;\n\n/**\n * Редактор форматированного текста на базе Lexical. Поддерживает тулбар, бизнес-адаптеры и сериализацию контента в единый формат данных.\n */\nexport function TextEditorLexicalClient({ initialData, onChange, toolbarComponents, businessAdapters }: TextEditorProps) {\n\tconst LocalLinkDialogComponent = businessAdapters?.LocalLinkDialogComponent;\n\tconst [isFocused, setIsFocused] = useState(false);\n\tconst [toolbarState, setToolbarState] = useState<LexicalToolbarState>(DEFAULT_TOOLBAR_STATE);\n\tconst [editor, setEditor] = useState<LexicalEditor | null>(null);\n\tconst [linkTypeDialog, setLinkTypeDialog] = useState<LinkTypes | null>(null);\n\tconst [tagTypeDialog, setTagTypeDialog] = useState<TagTypes | null>(null);\n\n\tconst lexicalRaw = isLexicalTextRaw(initialData?.raw) ? initialData.raw : null;\n\tconst hasLexicalRaw = !!lexicalRaw;\n\n\tconst initialEditorState = useMemo(() => {\n\t\tif (!lexicalRaw) return undefined;\n\t\treturn JSON.stringify(lexicalRaw.editorState);\n\t}, [lexicalRaw]);\n\n\tconst handleError = useCallback((error: Error) => {\n\t\tconsole.error(\"Ошибка редактора Lexical\", error);\n\t}, []);\n\n\tconst handleChange = useCallback(\n\t\t(editorState: LexicalEditorState, lexicalEditor: LexicalEditor) => {\n\t\t\tlet html = \"\";\n\t\t\teditorState.read(() => {\n\t\t\t\thtml = $generateHtmlFromNodes(lexicalEditor, null);\n\t\t\t});\n\n\t\t\tconst raw = createLexicalRaw(editorState);\n\t\t\tonChange({ raw, html });\n\t\t},\n\t\t[onChange]\n\t);\n\n\tconst openLinkDialog = useCallback((type: LinkTypes) => {\n\t\tsetLinkTypeDialog(type);\n\t}, []);\n\n\tconst openTagDialog = useCallback((type: TagTypes) => {\n\t\tsetTagTypeDialog(type);\n\t}, []);\n\n\tconst actions = useTextEditorLexicalActions({\n\t\teditor,\n\t\ttoolbarState,\n\t\thasLocalLinkDialog: !!LocalLinkDialogComponent,\n\t\tonOpenLinkDialog: openLinkDialog,\n\t\tonOpenTagDialog: openTagDialog\n\t});\n\n\tconst initialConfig = useMemo(\n\t\t() => ({\n\t\t\tnamespace: \"KtkTextEditorLexical\",\n\t\t\tonError: handleError,\n\t\t\ttheme: {\n\t\t\t\tparagraph: \"paragraph\",\n\t\t\t\ttext: {\n\t\t\t\t\tcode: \"lexicalTextCode\",\n\t\t\t\t\thighlight: \"lexicalTextHighlight\",\n\t\t\t\t\tunderline: \"lexicalTextUnderline\",\n\t\t\t\t\tstrikethrough: \"lexicalTextStrikethrough\"\n\t\t\t\t}\n\t\t\t},\n\t\t\tnodes: [HeadingNode, QuoteNode, ListNode, ListItemNode, AccessibleLinkNode, SemanticTagNode],\n\t\t\teditorState: initialEditorState\n\t\t}),\n\t\t[handleError, initialEditorState]\n\t);\n\n\treturn (\n\t\t<div className={TextEditorStyle.textEditor}>\n\t\t\t<div\n\t\t\t\tclassName={cn(TextEditorStyle.textEditorContent, {\n\t\t\t\t\t[TextEditorStyle.focused]: isFocused\n\t\t\t\t})}>\n\t\t\t\t<LexicalComposer initialConfig={initialConfig}>\n\t\t\t\t\t<TextEditorToolbarLexical\n\t\t\t\t\t\ttoolbarComponents={toolbarComponents}\n\t\t\t\t\t\tstate={toolbarState}\n\t\t\t\t\t\tonBlockStyleToggle={actions.handleBlockStyleToggle}\n\t\t\t\t\t\tonInlineStyleToggle={actions.handleInlineStyleToggle}\n\t\t\t\t\t\tonAlignmentChange={actions.handleAlignmentChange}\n\t\t\t\t\t\tonLinkClick={actions.handleLinkClick}\n\t\t\t\t\t\tonTagClick={actions.handleTagClick}\n\t\t\t\t\t\tonUndo={actions.handleUndo}\n\t\t\t\t\t\tonRedo={actions.handleRedo}\n\t\t\t\t\t\tonCleanTag={actions.handleCleanSemanticTag}\n\t\t\t\t\t/>\n\t\t\t\t\t<RichTextPlugin\n\t\t\t\t\t\tcontentEditable={\n\t\t\t\t\t\t\t<ContentEditable\n\t\t\t\t\t\t\t\tclassName=\"lexicalEditorContentEditable\"\n\t\t\t\t\t\t\t\tonFocus={() => setIsFocused(true)}\n\t\t\t\t\t\t\t\tonBlur={() => setIsFocused(false)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t}\n\t\t\t\t\t\tplaceholder={<div className=\"lexicalEditorPlaceholder\">Введите текст...</div>}\n\t\t\t\t\t\tErrorBoundary={LexicalErrorBoundary}\n\t\t\t\t\t/>\n\t\t\t\t\t<HistoryPlugin />\n\t\t\t\t\t<ListPlugin />\n\t\t\t\t\t<SelectionStatePlugin onEditorReady={setEditor} onStateChange={setToolbarState} />\n\t\t\t\t\t<InitialHtmlPlugin initialHTML={initialData?.html} shouldSkip={hasLexicalRaw} />\n\t\t\t\t\t<OnChangePlugin onChange={handleChange} ignoreSelectionChange />\n\t\t\t\t</LexicalComposer>\n\t\t\t</div>\n\n\t\t\t<TextEditorDialogs\n\t\t\t\tlinkTypeDialog={linkTypeDialog}\n\t\t\t\ttagTypeDialog={tagTypeDialog}\n\t\t\t\tlocalLinkDialogComponent={LocalLinkDialogComponent}\n\t\t\t\tonCloseLinkDialog={() => setLinkTypeDialog(null)}\n\t\t\t\tonCloseTagDialog={() => setTagTypeDialog(null)}\n\t\t\t\tonAddLink={actions.handleAddLink}\n\t\t\t\tonAddLocalLink={actions.handleAddLocalLink}\n\t\t\t\tonInsertSemanticTag={actions.insertSemanticTagAtSelection}\n\t\t\t\tgetCurrentSelectionText={actions.getCurrentSelectionText}\n\t\t\t\tgetSelectedLinkState={actions.getSelectedLinkState}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as e } from "./ui.module-BisoTevy.js";
|
|
2
|
-
import { c as t, o as n } from "./Input-
|
|
2
|
+
import { c as t, o as n } from "./Input-Wrew1puH.js";
|
|
3
3
|
import { cn as r } from "@ryuzaki13/react-foundation-lib/utils";
|
|
4
4
|
import { jsx as i } from "react/jsx-runtime";
|
|
5
5
|
var a = { textarea: "TjY2iu" };
|
|
@@ -41,4 +41,4 @@ function o({ label: o, description: s, className: c, disabled: l, size: u, value
|
|
|
41
41
|
//#endregion
|
|
42
42
|
export { o as t };
|
|
43
43
|
|
|
44
|
-
//# sourceMappingURL=Textarea-
|
|
44
|
+
//# sourceMappingURL=Textarea-DOVrPH4I.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Textarea-
|
|
1
|
+
{"version":3,"file":"Textarea-DOVrPH4I.js","names":[],"sources":["../../src/textarea/Textarea.module.scss","../../src/textarea/Textarea.tsx"],"sourcesContent":[".textarea {\n\twidth: 100%;\n\tmin-height: 6em;\n\tresize: vertical;\n\tpadding: var(--space-sm);\n\tdisplay: block;\n}\n","import { TextareaHTMLAttributes } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { InputUI, useInputFieldIds } from \"../input\";\nimport { UiBaseProps } from \"../types\";\nimport uiStyles from \"../ui.module.scss\";\n\nimport styles from \"./Textarea.module.scss\";\n\nexport interface TextareaProps\n\textends Omit<TextareaHTMLAttributes<HTMLTextAreaElement>, \"children\" | \"onChange\" | \"size\" | \"value\">, UiBaseProps<string> {\n\terror?: string;\n\tonClearError?: () => void;\n}\n\n/**\n * Многострочное текстовое поле для ввода свободного текста. Поддерживает подпись, описание, ошибки и единый визуальный стиль формы.\n */\nexport function Textarea({\n\tlabel,\n\tdescription,\n\tclassName,\n\tdisabled,\n\tsize,\n\tvalue,\n\tonChange,\n\terror,\n\tonClearError,\n\tid: externalId,\n\t...props\n}: TextareaProps) {\n\tconst { controlId, labelId, descriptionId, errorId, describedBy } = useInputFieldIds({\n\t\tid: externalId,\n\t\thasLabel: label !== undefined && label !== null,\n\t\thasDescription: !!description,\n\t\thasError: !!error\n\t});\n\n\treturn (\n\t\t<InputUI\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\tdisabled={disabled}\n\t\t\tsize={size}\n\t\t\terror={error}\n\t\t\tcontrolId={controlId}\n\t\t\tlabelId={labelId}\n\t\t\tdescriptionId={descriptionId}\n\t\t\terrorId={errorId}>\n\t\t\t<textarea\n\t\t\t\t{...props}\n\t\t\t\tid={controlId}\n\t\t\t\tdisabled={disabled}\n\t\t\t\tvalue={value}\n\t\t\t\taria-invalid={!!error || undefined}\n\t\t\t\taria-labelledby={labelId}\n\t\t\t\taria-describedby={describedBy}\n\t\t\t\tdata-invalid={error ? \"\" : undefined}\n\t\t\t\tclassName={cn(uiStyles.uiControl, styles.textarea, \"scrollable\", className)}\n\t\t\t\tonChange={(event) => {\n\t\t\t\t\tonChange?.(event.target.value);\n\t\t\t\t\tif (error && onClearError) {\n\t\t\t\t\t\tonClearError();\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t/>\n\t\t</InputUI>\n\t);\n}\n"],"mappings":";;;;;;;ACmBA,SAAgB,EAAS,EACxB,UACA,gBACA,cACA,aACA,SACA,UACA,aACA,UACA,iBACA,IAAI,GACJ,GAAG,KACc;CACjB,IAAM,EAAE,cAAW,YAAS,kBAAe,YAAS,mBAAgB,EAAiB;EACpF,IAAI;EACJ,UAAU,KAAiC;EAC3C,gBAAgB,CAAC,CAAC;EAClB,UAAU,CAAC,CAAC;CACb,CAAC;CAED,OACC,kBAAC,GAAD;EACQ;EACM;EACH;EACJ;EACC;EACI;EACF;EACM;EACN;YACT,kBAAC,YAAD;GACC,GAAI;GACJ,IAAI;GACM;GACH;GACP,gBAAc,CAAC,CAAC,KAAS,KAAA;GACzB,mBAAiB;GACjB,oBAAkB;GAClB,gBAAc,IAAQ,KAAK,KAAA;GAC3B,WAAW,EAAG,EAAS,WAAW,EAAO,UAAU,cAAc,CAAS;GAC1E,WAAW,MAAU;IAEpB,AADA,IAAW,EAAM,OAAO,KAAK,GACzB,KAAS,KACZ,EAAa;GAEf;EACA,CAAA;CACO,CAAA;AAEX"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimePanel-_kF2RtHk.js","names":[],"sources":["../../src/date-time-input/lib/dateTimeValue.ts","../../src/date-time-input/lib/timePanelState.ts","../../src/date-time-input/ui/TimePanel.module.scss","../../src/date-time-input/ui/TimePanel.tsx"],"sourcesContent":["import { dateToIndexedSegmentValues, indexedSegmentsToDate, parseDateSegmentMask } from \"@ryuzaki13/react-foundation-lib/date-segments\";\nimport { createCalendarDate, type DateFormatPreset, formatDate, parseDate, parseDateByPattern } from \"@ryuzaki13/react-foundation-lib/formatters\";\n\nexport type DateTimeInputMode = \"date-time\" | \"time\";\n\n/**\n * Фиксированный формат нового поля даты-времени.\n */\nexport const DATE_TIME_INPUT_FORMAT = \"dd.MM.yyyy HH:mm\";\nexport const TIME_INPUT_FORMAT = \"HH:mm\";\n\nconst DATE_TIME_INPUT_PRESET_NAME = \"__date_time_input__\";\nconst TIME_INPUT_PRESET_NAME = \"__time_input__\";\nconst TIME_ONLY_BASE_YEAR = 1970;\nconst TIME_ONLY_BASE_MONTH = 0;\nconst TIME_ONLY_BASE_DAY = 1;\nconst TIME_SEGMENTS = parseDateSegmentMask(TIME_INPUT_FORMAT);\n\n/**\n * Создаёт техническую базовую дату для режима выбора только времени.\n */\nexport function createTimeOnlyBaseDate(hours = 0, minutes = 0): Date {\n\treturn createCalendarDate(TIME_ONLY_BASE_YEAR, TIME_ONLY_BASE_MONTH, TIME_ONLY_BASE_DAY, hours, minutes, 0, 0);\n}\n\n/**\n * Возвращает формат пользовательского ввода для выбранного режима.\n */\nexport function getDateTimeInputFormat(mode: DateTimeInputMode = \"date-time\"): string {\n\treturn mode === \"time\" ? TIME_INPUT_FORMAT : DATE_TIME_INPUT_FORMAT;\n}\n\n/**\n * Создаёт временную предустановку форматирования для нового поля даты-времени.\n */\nexport function createDateTimeInputPreset(mode: DateTimeInputMode = \"date-time\"): DateFormatPreset {\n\treturn {\n\t\tname: mode === \"time\" ? TIME_INPUT_PRESET_NAME : DATE_TIME_INPUT_PRESET_NAME,\n\t\tpattern: getDateTimeInputFormat(mode),\n\t\tlocale: \"ru-RU\",\n\t\tinvalidFallback: \"\"\n\t};\n}\n\n/**\n * Нормализует внешнее значение к валидному Date без timezone-сдвига.\n */\nexport function normalizeDateTimeValue(value: Date | null | undefined, mode: DateTimeInputMode = \"date-time\"): Date | null {\n\tif (value == null) return null;\n\n\tconst parsedValue = parseDate(value);\n\tif (!parsedValue) return null;\n\n\tif (mode === \"time\") {\n\t\treturn createTimeOnlyBaseDate(parsedValue.getHours(), parsedValue.getMinutes());\n\t}\n\n\treturn parsedValue;\n}\n\n/**\n * Форматирует значение поля даты-времени в фиксированный пользовательский формат.\n */\nexport function formatDateTimeInputValue(value: Date | null | undefined, mode: DateTimeInputMode = \"date-time\"): string {\n\tif (!value) return \"\";\n\treturn formatDate(normalizeDateTimeValue(value, mode), createDateTimeInputPreset(mode));\n}\n\n/**\n * Строго парсит строку пользовательского ввода в Date.\n */\nexport function parseDateTimeInputValue(value: string, mode: DateTimeInputMode = \"date-time\"): Date | null {\n\tif (mode === \"time\") {\n\t\tconst match = /^\\d{2}:\\d{2}$/.exec(value.trim());\n\t\tif (!match) return null;\n\n\t\tconst values = dateToIndexedSegmentValues(createTimeOnlyBaseDate(), TIME_SEGMENTS);\n\t\tvalues.set(0, value.slice(0, 2));\n\t\tvalues.set(2, value.slice(3, 5));\n\n\t\treturn indexedSegmentsToDate(TIME_SEGMENTS, values, {\n\t\t\tdefaultDate: createTimeOnlyBaseDate()\n\t\t});\n\t}\n\n\tconst parsed = parseDateByPattern(value, DATE_TIME_INPUT_FORMAT);\n\tif (!parsed || parsed.kind !== \"date-time\") return null;\n\n\treturn parsed.date;\n}\n\n/**\n * Проверяет, попадает ли дата-время в допустимый диапазон.\n */\nexport function isDateTimeWithinRange(value: Date, minDate?: Date, maxDate?: Date, mode: DateTimeInputMode = \"date-time\"): boolean {\n\tconst normalizedValue = normalizeDateTimeValue(value, mode);\n\tif (!normalizedValue) return false;\n\n\tif (mode === \"time\") {\n\t\tconst valueMinutes = normalizedValue.getHours() * 60 + normalizedValue.getMinutes();\n\t\tconst normalizedMinDate = minDate ? normalizeDateTimeValue(minDate, \"time\") : null;\n\t\tconst normalizedMaxDate = maxDate ? normalizeDateTimeValue(maxDate, \"time\") : null;\n\n\t\tif (normalizedMinDate) {\n\t\t\tconst minMinutes = normalizedMinDate.getHours() * 60 + normalizedMinDate.getMinutes();\n\t\t\tif (valueMinutes < minMinutes) return false;\n\t\t}\n\n\t\tif (normalizedMaxDate) {\n\t\t\tconst maxMinutes = normalizedMaxDate.getHours() * 60 + normalizedMaxDate.getMinutes();\n\t\t\tif (valueMinutes > maxMinutes) return false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tif (minDate && normalizedValue < minDate) return false;\n\tif (maxDate && normalizedValue > maxDate) return false;\n\n\treturn true;\n}\n\n/**\n * Переносит дату выбранного дня, сохраняя часы и минуты базового значения.\n */\nexport function mergeDateWithTime(datePart: Date, timeSource?: Date | null): Date {\n\tconst source = normalizeDateTimeValue(timeSource);\n\tconst hours = source?.getHours() ?? 0;\n\tconst minutes = source?.getMinutes() ?? 0;\n\n\treturn createCalendarDate(datePart.getFullYear(), datePart.getMonth(), datePart.getDate(), hours, minutes, 0, 0);\n}\n\n/**\n * Переносит часы и минуты в базовую календарную дату.\n */\nexport function mergeTimeIntoDate(baseDate: Date, hours: number, minutes: number, mode: DateTimeInputMode = \"date-time\"): Date {\n\tif (mode === \"time\") {\n\t\treturn createTimeOnlyBaseDate(hours, minutes);\n\t}\n\n\treturn createCalendarDate(baseDate.getFullYear(), baseDate.getMonth(), baseDate.getDate(), hours, minutes, 0, 0);\n}\n\n/**\n * Создаёт рабочую дату для picker-сценариев без выбранного значения.\n */\nexport function resolvePickerBaseDate(value: Date | null | undefined, fallbackDate: Date, mode: DateTimeInputMode = \"date-time\"): Date {\n\tif (mode === \"time\") {\n\t\treturn normalizeDateTimeValue(value, \"time\") ?? createTimeOnlyBaseDate();\n\t}\n\n\treturn normalizeDateTimeValue(value, mode) ?? fallbackDate;\n}\n\n/**\n * Возвращает границы часов и минут для выбранного календарного дня.\n */\nexport function getTimeRangeForDay(\n\tday: Date,\n\tminDate?: Date,\n\tmaxDate?: Date,\n\tmode: DateTimeInputMode = \"date-time\"\n): {\n\tdisabled: boolean;\n\tminHour: number;\n\tmaxHour: number;\n\tminMinuteByHour: (hour: number) => number;\n\tmaxMinuteByHour: (hour: number) => number;\n} {\n\tconst normalizedDay = normalizeDateTimeValue(day, mode) ?? day;\n\tconst normalizedMinDate = minDate ? normalizeDateTimeValue(minDate, mode) : null;\n\tconst normalizedMaxDate = maxDate ? normalizeDateTimeValue(maxDate, mode) : null;\n\tconst isSameMinDay =\n\t\t!!normalizedMinDate &&\n\t\tnormalizedDay.getFullYear() === normalizedMinDate.getFullYear() &&\n\t\tnormalizedDay.getMonth() === normalizedMinDate.getMonth() &&\n\t\tnormalizedDay.getDate() === normalizedMinDate.getDate();\n\tconst isSameMaxDay =\n\t\t!!normalizedMaxDate &&\n\t\tnormalizedDay.getFullYear() === normalizedMaxDate.getFullYear() &&\n\t\tnormalizedDay.getMonth() === normalizedMaxDate.getMonth() &&\n\t\tnormalizedDay.getDate() === normalizedMaxDate.getDate();\n\n\tconst minHour = isSameMinDay ? normalizedMinDate!.getHours() : 0;\n\tconst maxHour = isSameMaxDay ? normalizedMaxDate!.getHours() : 23;\n\tconst minMinuteAtBoundary = isSameMinDay && minHour === maxHour ? normalizedMinDate!.getMinutes() : 0;\n\tconst maxMinuteAtBoundary = isSameMaxDay && minHour === maxHour ? normalizedMaxDate!.getMinutes() : 59;\n\tconst disabled = minHour > maxHour || (minHour === maxHour && minMinuteAtBoundary > maxMinuteAtBoundary);\n\n\treturn {\n\t\tdisabled,\n\t\tminHour,\n\t\tmaxHour,\n\t\tminMinuteByHour: (hour) => {\n\t\t\tif (disabled) return 0;\n\t\t\treturn isSameMinDay && hour === minHour ? normalizedMinDate!.getMinutes() : 0;\n\t\t},\n\t\tmaxMinuteByHour: (hour) => {\n\t\t\tif (disabled) return 59;\n\t\t\treturn isSameMaxDay && hour === maxHour ? normalizedMaxDate!.getMinutes() : 59;\n\t\t}\n\t};\n}\n\n/**\n * Ограничивает часы и минуты допустимым диапазоном текущего дня.\n */\nexport function clampTimeForDay(\n\tday: Date,\n\thours: number,\n\tminutes: number,\n\tminDate?: Date,\n\tmaxDate?: Date,\n\tmode: DateTimeInputMode = \"date-time\"\n): { hours: number; minutes: number } {\n\tconst range = getTimeRangeForDay(day, minDate, maxDate, mode);\n\tif (range.disabled) {\n\t\treturn { hours: 0, minutes: 0 };\n\t}\n\n\tconst clampedHour = Math.min(Math.max(hours, range.minHour), range.maxHour);\n\tconst minMinute = range.minMinuteByHour(clampedHour);\n\tconst maxMinute = range.maxMinuteByHour(clampedHour);\n\tconst clampedMinute = Math.min(Math.max(minutes, minMinute), maxMinute);\n\n\treturn {\n\t\thours: clampedHour,\n\t\tminutes: clampedMinute\n\t};\n}\n","import { getTimeRangeForDay } from \"./dateTimeValue\";\n\nimport type { DateTimeInputMode } from \"./dateTimeValue\";\n\n/**\n * Состояние и доступные значения для панели выбора времени.\n */\nexport interface TimePanelState {\n\tdisabled: boolean;\n\tselectedHour: number;\n\tselectedMinute: number;\n\thours: number[];\n\tminutes: number[];\n}\n\n/**\n * Собирает состояние часов и минут для панели выбора времени.\n */\nexport function buildTimePanelState(value: Date, minDate?: Date, maxDate?: Date, mode: DateTimeInputMode = \"date-time\"): TimePanelState {\n\tconst timeRange = getTimeRangeForDay(value, minDate, maxDate, mode);\n\tconst selectedHour = value.getHours();\n\tconst selectedMinute = value.getMinutes();\n\tconst minuteMin = timeRange.minMinuteByHour(selectedHour);\n\tconst minuteMax = timeRange.maxMinuteByHour(selectedHour);\n\n\tif (timeRange.disabled) {\n\t\treturn {\n\t\t\tdisabled: true,\n\t\t\tselectedHour,\n\t\t\tselectedMinute,\n\t\t\thours: [],\n\t\t\tminutes: []\n\t\t};\n\t}\n\n\treturn {\n\t\tdisabled: false,\n\t\tselectedHour,\n\t\tselectedMinute,\n\t\thours: Array.from({ length: timeRange.maxHour - timeRange.minHour + 1 }, (_, index) => timeRange.minHour + index),\n\t\tminutes: Array.from({ length: minuteMax - minuteMin + 1 }, (_, index) => minuteMin + index)\n\t};\n}\n",".timePanel {\n\theight: 100%;\n}\n\n.hint {\n\tfont-size: var(--font-size-xs);\n\tcolor: var(--content-1);\n}\n\n.fields {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(2, minmax(0, 1fr));\n\tgap: var(--space-sm);\n\tmin-height: 10em;\n\theight: 100%;\n}\n\n.field {\n\tdisplay: grid;\n\tgrid-template-rows: auto 1fr;\n\tgap: var(--space-xs);\n\tmin-height: 0;\n}\n\n.label {\n\t// font-size: var(--font-size-sm);\n\tcolor: var(--content-1);\n}\n\n.wheel {\n\tmin-height: 10em;\n}\n","import { WheelPicker } from \"../../wheel-picker\";\nimport { buildTimePanelState } from \"../lib/timePanelState\";\n\nimport styles from \"./TimePanel.module.scss\";\n\nimport type { DateTimeInputMode } from \"../lib\";\n\n/**\n * Пропсы панели выбора времени.\n */\nexport interface TimePanelProps {\n\tvalue: Date;\n\tdisabled?: boolean;\n\tminDate?: Date;\n\tmaxDate?: Date;\n\tmode?: DateTimeInputMode;\n\tonChange: (hours: number, minutes: number) => void;\n}\n\n/**\n * Переиспользуемая панель выбора времени поверх internal wheel-picker.\n */\nexport function TimePanel({ value, disabled, minDate, maxDate, mode = \"date-time\", onChange }: TimePanelProps) {\n\tconst state = buildTimePanelState(value, minDate, maxDate, mode);\n\n\t/**\n\t * Форматирует двузначное значение времени.\n\t */\n\tconst formatValue = (timePart: number) => String(timePart).padStart(2, \"0\");\n\n\tif (state.disabled) {\n\t\treturn (\n\t\t\t<div className={styles.timePanel}>\n\t\t\t\t<p className={styles.hint}>Для выбранного дня нет доступного времени в заданном диапазоне.</p>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div className={styles.timePanel}>\n\t\t\t<div className={styles.fields}>\n\t\t\t\t<label className={styles.field}>\n\t\t\t\t\t<span className={styles.label}>Часы</span>\n\t\t\t\t\t<WheelPicker\n\t\t\t\t\t\tclassName={styles.wheel}\n\t\t\t\t\t\titems={state.hours}\n\t\t\t\t\t\tvalue={state.selectedHour}\n\t\t\t\t\t\tonChange={(hours) => onChange(hours, state.selectedMinute)}\n\t\t\t\t\t\tariaLabel=\"Выбор часов\"\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tformatItem={formatValue}\n\t\t\t\t\t/>\n\t\t\t\t</label>\n\n\t\t\t\t<label className={styles.field}>\n\t\t\t\t\t<span className={styles.label}>Минуты</span>\n\t\t\t\t\t<WheelPicker\n\t\t\t\t\t\tclassName={styles.wheel}\n\t\t\t\t\t\titems={state.minutes}\n\t\t\t\t\t\tvalue={state.selectedMinute}\n\t\t\t\t\t\tonChange={(minutes) => onChange(state.selectedHour, minutes)}\n\t\t\t\t\t\tariaLabel=\"Выбор минут\"\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tformatItem={formatValue}\n\t\t\t\t\t/>\n\t\t\t\t</label>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TimePanel-_kF2RtHk.js","names":[],"sources":["../../src/date-time-input/lib/dateTimeValue.ts","../../src/date-time-input/lib/timePanelState.ts","../../src/date-time-input/ui/TimePanel.module.scss","../../src/date-time-input/ui/TimePanel.tsx"],"sourcesContent":["import { dateToIndexedSegmentValues, indexedSegmentsToDate, parseDateSegmentMask } from \"@ryuzaki13/react-foundation-lib/date-segments\";\nimport {\n\tcreateCalendarDate,\n\ttype DateFormatPreset,\n\tformatDate,\n\tparseDate,\n\tparseDateByPattern\n} from \"@ryuzaki13/react-foundation-lib/formatters\";\n\nexport type DateTimeInputMode = \"date-time\" | \"time\";\n\n/**\n * Фиксированный формат нового поля даты-времени.\n */\nexport const DATE_TIME_INPUT_FORMAT = \"dd.MM.yyyy HH:mm\";\nexport const TIME_INPUT_FORMAT = \"HH:mm\";\n\nconst DATE_TIME_INPUT_PRESET_NAME = \"__date_time_input__\";\nconst TIME_INPUT_PRESET_NAME = \"__time_input__\";\nconst TIME_ONLY_BASE_YEAR = 1970;\nconst TIME_ONLY_BASE_MONTH = 0;\nconst TIME_ONLY_BASE_DAY = 1;\nconst TIME_SEGMENTS = parseDateSegmentMask(TIME_INPUT_FORMAT);\n\n/**\n * Создаёт техническую базовую дату для режима выбора только времени.\n */\nexport function createTimeOnlyBaseDate(hours = 0, minutes = 0): Date {\n\treturn createCalendarDate(TIME_ONLY_BASE_YEAR, TIME_ONLY_BASE_MONTH, TIME_ONLY_BASE_DAY, hours, minutes, 0, 0);\n}\n\n/**\n * Возвращает формат пользовательского ввода для выбранного режима.\n */\nexport function getDateTimeInputFormat(mode: DateTimeInputMode = \"date-time\"): string {\n\treturn mode === \"time\" ? TIME_INPUT_FORMAT : DATE_TIME_INPUT_FORMAT;\n}\n\n/**\n * Создаёт временную предустановку форматирования для нового поля даты-времени.\n */\nexport function createDateTimeInputPreset(mode: DateTimeInputMode = \"date-time\"): DateFormatPreset {\n\treturn {\n\t\tname: mode === \"time\" ? TIME_INPUT_PRESET_NAME : DATE_TIME_INPUT_PRESET_NAME,\n\t\tpattern: getDateTimeInputFormat(mode),\n\t\tlocale: \"ru-RU\",\n\t\tinvalidFallback: \"\"\n\t};\n}\n\n/**\n * Нормализует внешнее значение к валидному Date без timezone-сдвига.\n */\nexport function normalizeDateTimeValue(value: Date | null | undefined, mode: DateTimeInputMode = \"date-time\"): Date | null {\n\tif (value == null) return null;\n\n\tconst parsedValue = parseDate(value);\n\tif (!parsedValue) return null;\n\n\tif (mode === \"time\") {\n\t\treturn createTimeOnlyBaseDate(parsedValue.getHours(), parsedValue.getMinutes());\n\t}\n\n\treturn parsedValue;\n}\n\n/**\n * Форматирует значение поля даты-времени в фиксированный пользовательский формат.\n */\nexport function formatDateTimeInputValue(value: Date | null | undefined, mode: DateTimeInputMode = \"date-time\"): string {\n\tif (!value) return \"\";\n\treturn formatDate(normalizeDateTimeValue(value, mode), createDateTimeInputPreset(mode));\n}\n\n/**\n * Строго парсит строку пользовательского ввода в Date.\n */\nexport function parseDateTimeInputValue(value: string, mode: DateTimeInputMode = \"date-time\"): Date | null {\n\tif (mode === \"time\") {\n\t\tconst match = /^\\d{2}:\\d{2}$/.exec(value.trim());\n\t\tif (!match) return null;\n\n\t\tconst values = dateToIndexedSegmentValues(createTimeOnlyBaseDate(), TIME_SEGMENTS);\n\t\tvalues.set(0, value.slice(0, 2));\n\t\tvalues.set(2, value.slice(3, 5));\n\n\t\treturn indexedSegmentsToDate(TIME_SEGMENTS, values, {\n\t\t\tdefaultDate: createTimeOnlyBaseDate()\n\t\t});\n\t}\n\n\tconst parsed = parseDateByPattern(value, DATE_TIME_INPUT_FORMAT);\n\tif (!parsed || parsed.kind !== \"date-time\") return null;\n\n\treturn parsed.date;\n}\n\n/**\n * Проверяет, попадает ли дата-время в допустимый диапазон.\n */\nexport function isDateTimeWithinRange(value: Date, minDate?: Date, maxDate?: Date, mode: DateTimeInputMode = \"date-time\"): boolean {\n\tconst normalizedValue = normalizeDateTimeValue(value, mode);\n\tif (!normalizedValue) return false;\n\n\tif (mode === \"time\") {\n\t\tconst valueMinutes = normalizedValue.getHours() * 60 + normalizedValue.getMinutes();\n\t\tconst normalizedMinDate = minDate ? normalizeDateTimeValue(minDate, \"time\") : null;\n\t\tconst normalizedMaxDate = maxDate ? normalizeDateTimeValue(maxDate, \"time\") : null;\n\n\t\tif (normalizedMinDate) {\n\t\t\tconst minMinutes = normalizedMinDate.getHours() * 60 + normalizedMinDate.getMinutes();\n\t\t\tif (valueMinutes < minMinutes) return false;\n\t\t}\n\n\t\tif (normalizedMaxDate) {\n\t\t\tconst maxMinutes = normalizedMaxDate.getHours() * 60 + normalizedMaxDate.getMinutes();\n\t\t\tif (valueMinutes > maxMinutes) return false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tif (minDate && normalizedValue < minDate) return false;\n\tif (maxDate && normalizedValue > maxDate) return false;\n\n\treturn true;\n}\n\n/**\n * Переносит дату выбранного дня, сохраняя часы и минуты базового значения.\n */\nexport function mergeDateWithTime(datePart: Date, timeSource?: Date | null): Date {\n\tconst source = normalizeDateTimeValue(timeSource);\n\tconst hours = source?.getHours() ?? 0;\n\tconst minutes = source?.getMinutes() ?? 0;\n\n\treturn createCalendarDate(datePart.getFullYear(), datePart.getMonth(), datePart.getDate(), hours, minutes, 0, 0);\n}\n\n/**\n * Переносит часы и минуты в базовую календарную дату.\n */\nexport function mergeTimeIntoDate(baseDate: Date, hours: number, minutes: number, mode: DateTimeInputMode = \"date-time\"): Date {\n\tif (mode === \"time\") {\n\t\treturn createTimeOnlyBaseDate(hours, minutes);\n\t}\n\n\treturn createCalendarDate(baseDate.getFullYear(), baseDate.getMonth(), baseDate.getDate(), hours, minutes, 0, 0);\n}\n\n/**\n * Создаёт рабочую дату для picker-сценариев без выбранного значения.\n */\nexport function resolvePickerBaseDate(value: Date | null | undefined, fallbackDate: Date, mode: DateTimeInputMode = \"date-time\"): Date {\n\tif (mode === \"time\") {\n\t\treturn normalizeDateTimeValue(value, \"time\") ?? createTimeOnlyBaseDate();\n\t}\n\n\treturn normalizeDateTimeValue(value, mode) ?? fallbackDate;\n}\n\n/**\n * Возвращает границы часов и минут для выбранного календарного дня.\n */\nexport function getTimeRangeForDay(\n\tday: Date,\n\tminDate?: Date,\n\tmaxDate?: Date,\n\tmode: DateTimeInputMode = \"date-time\"\n): {\n\tdisabled: boolean;\n\tminHour: number;\n\tmaxHour: number;\n\tminMinuteByHour: (hour: number) => number;\n\tmaxMinuteByHour: (hour: number) => number;\n} {\n\tconst normalizedDay = normalizeDateTimeValue(day, mode) ?? day;\n\tconst normalizedMinDate = minDate ? normalizeDateTimeValue(minDate, mode) : null;\n\tconst normalizedMaxDate = maxDate ? normalizeDateTimeValue(maxDate, mode) : null;\n\tconst isSameMinDay =\n\t\t!!normalizedMinDate &&\n\t\tnormalizedDay.getFullYear() === normalizedMinDate.getFullYear() &&\n\t\tnormalizedDay.getMonth() === normalizedMinDate.getMonth() &&\n\t\tnormalizedDay.getDate() === normalizedMinDate.getDate();\n\tconst isSameMaxDay =\n\t\t!!normalizedMaxDate &&\n\t\tnormalizedDay.getFullYear() === normalizedMaxDate.getFullYear() &&\n\t\tnormalizedDay.getMonth() === normalizedMaxDate.getMonth() &&\n\t\tnormalizedDay.getDate() === normalizedMaxDate.getDate();\n\n\tconst minHour = isSameMinDay ? normalizedMinDate!.getHours() : 0;\n\tconst maxHour = isSameMaxDay ? normalizedMaxDate!.getHours() : 23;\n\tconst minMinuteAtBoundary = isSameMinDay && minHour === maxHour ? normalizedMinDate!.getMinutes() : 0;\n\tconst maxMinuteAtBoundary = isSameMaxDay && minHour === maxHour ? normalizedMaxDate!.getMinutes() : 59;\n\tconst disabled = minHour > maxHour || (minHour === maxHour && minMinuteAtBoundary > maxMinuteAtBoundary);\n\n\treturn {\n\t\tdisabled,\n\t\tminHour,\n\t\tmaxHour,\n\t\tminMinuteByHour: (hour) => {\n\t\t\tif (disabled) return 0;\n\t\t\treturn isSameMinDay && hour === minHour ? normalizedMinDate!.getMinutes() : 0;\n\t\t},\n\t\tmaxMinuteByHour: (hour) => {\n\t\t\tif (disabled) return 59;\n\t\t\treturn isSameMaxDay && hour === maxHour ? normalizedMaxDate!.getMinutes() : 59;\n\t\t}\n\t};\n}\n\n/**\n * Ограничивает часы и минуты допустимым диапазоном текущего дня.\n */\nexport function clampTimeForDay(\n\tday: Date,\n\thours: number,\n\tminutes: number,\n\tminDate?: Date,\n\tmaxDate?: Date,\n\tmode: DateTimeInputMode = \"date-time\"\n): { hours: number; minutes: number } {\n\tconst range = getTimeRangeForDay(day, minDate, maxDate, mode);\n\tif (range.disabled) {\n\t\treturn { hours: 0, minutes: 0 };\n\t}\n\n\tconst clampedHour = Math.min(Math.max(hours, range.minHour), range.maxHour);\n\tconst minMinute = range.minMinuteByHour(clampedHour);\n\tconst maxMinute = range.maxMinuteByHour(clampedHour);\n\tconst clampedMinute = Math.min(Math.max(minutes, minMinute), maxMinute);\n\n\treturn {\n\t\thours: clampedHour,\n\t\tminutes: clampedMinute\n\t};\n}\n","import { getTimeRangeForDay } from \"./dateTimeValue\";\n\nimport type { DateTimeInputMode } from \"./dateTimeValue\";\n\n/**\n * Состояние и доступные значения для панели выбора времени.\n */\nexport interface TimePanelState {\n\tdisabled: boolean;\n\tselectedHour: number;\n\tselectedMinute: number;\n\thours: number[];\n\tminutes: number[];\n}\n\n/**\n * Собирает состояние часов и минут для панели выбора времени.\n */\nexport function buildTimePanelState(value: Date, minDate?: Date, maxDate?: Date, mode: DateTimeInputMode = \"date-time\"): TimePanelState {\n\tconst timeRange = getTimeRangeForDay(value, minDate, maxDate, mode);\n\tconst selectedHour = value.getHours();\n\tconst selectedMinute = value.getMinutes();\n\tconst minuteMin = timeRange.minMinuteByHour(selectedHour);\n\tconst minuteMax = timeRange.maxMinuteByHour(selectedHour);\n\n\tif (timeRange.disabled) {\n\t\treturn {\n\t\t\tdisabled: true,\n\t\t\tselectedHour,\n\t\t\tselectedMinute,\n\t\t\thours: [],\n\t\t\tminutes: []\n\t\t};\n\t}\n\n\treturn {\n\t\tdisabled: false,\n\t\tselectedHour,\n\t\tselectedMinute,\n\t\thours: Array.from({ length: timeRange.maxHour - timeRange.minHour + 1 }, (_, index) => timeRange.minHour + index),\n\t\tminutes: Array.from({ length: minuteMax - minuteMin + 1 }, (_, index) => minuteMin + index)\n\t};\n}\n",".timePanel {\n\theight: 100%;\n}\n\n.hint {\n\tfont-size: var(--font-size-xs);\n\tcolor: var(--content-1);\n}\n\n.fields {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(2, minmax(0, 1fr));\n\tgap: var(--space-sm);\n\tmin-height: 10em;\n\theight: 100%;\n}\n\n.field {\n\tdisplay: grid;\n\tgrid-template-rows: auto 1fr;\n\tgap: var(--space-xs);\n\tmin-height: 0;\n}\n\n.label {\n\t// font-size: var(--font-size-sm);\n\tcolor: var(--content-1);\n}\n\n.wheel {\n\tmin-height: 10em;\n}\n","import { WheelPicker } from \"../../wheel-picker\";\nimport { buildTimePanelState } from \"../lib/timePanelState\";\n\nimport styles from \"./TimePanel.module.scss\";\n\nimport type { DateTimeInputMode } from \"../lib\";\n\n/**\n * Пропсы панели выбора времени.\n */\nexport interface TimePanelProps {\n\tvalue: Date;\n\tdisabled?: boolean;\n\tminDate?: Date;\n\tmaxDate?: Date;\n\tmode?: DateTimeInputMode;\n\tonChange: (hours: number, minutes: number) => void;\n}\n\n/**\n * Переиспользуемая панель выбора времени поверх internal wheel-picker.\n */\nexport function TimePanel({ value, disabled, minDate, maxDate, mode = \"date-time\", onChange }: TimePanelProps) {\n\tconst state = buildTimePanelState(value, minDate, maxDate, mode);\n\n\t/**\n\t * Форматирует двузначное значение времени.\n\t */\n\tconst formatValue = (timePart: number) => String(timePart).padStart(2, \"0\");\n\n\tif (state.disabled) {\n\t\treturn (\n\t\t\t<div className={styles.timePanel}>\n\t\t\t\t<p className={styles.hint}>Для выбранного дня нет доступного времени в заданном диапазоне.</p>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div className={styles.timePanel}>\n\t\t\t<div className={styles.fields}>\n\t\t\t\t<label className={styles.field}>\n\t\t\t\t\t<span className={styles.label}>Часы</span>\n\t\t\t\t\t<WheelPicker\n\t\t\t\t\t\tclassName={styles.wheel}\n\t\t\t\t\t\titems={state.hours}\n\t\t\t\t\t\tvalue={state.selectedHour}\n\t\t\t\t\t\tonChange={(hours) => onChange(hours, state.selectedMinute)}\n\t\t\t\t\t\tariaLabel=\"Выбор часов\"\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tformatItem={formatValue}\n\t\t\t\t\t/>\n\t\t\t\t</label>\n\n\t\t\t\t<label className={styles.field}>\n\t\t\t\t\t<span className={styles.label}>Минуты</span>\n\t\t\t\t\t<WheelPicker\n\t\t\t\t\t\tclassName={styles.wheel}\n\t\t\t\t\t\titems={state.minutes}\n\t\t\t\t\t\tvalue={state.selectedMinute}\n\t\t\t\t\t\tonChange={(minutes) => onChange(state.selectedHour, minutes)}\n\t\t\t\t\t\tariaLabel=\"Выбор минут\"\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tformatItem={formatValue}\n\t\t\t\t\t/>\n\t\t\t\t</label>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as e, i as t, n, r, t as i } from "./TreePickerBase-
|
|
1
|
+
import { a as e, i as t, n, r, t as i } from "./TreePickerBase-qNHIWbYL.js";
|
|
2
2
|
import { jsx as a } from "react/jsx-runtime";
|
|
3
3
|
import { useMemo as o } from "react";
|
|
4
4
|
//#region src/tree-select/TreeMultiSelect.tsx
|
|
@@ -37,4 +37,4 @@ function c({ label: c, description: l, disabled: u, placeholder: d = "Выбер
|
|
|
37
37
|
//#endregion
|
|
38
38
|
export { c as t };
|
|
39
39
|
|
|
40
|
-
//# sourceMappingURL=TreeMultiSelect-
|
|
40
|
+
//# sourceMappingURL=TreeMultiSelect-C76RYavo.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TreeMultiSelect-
|
|
1
|
+
{"version":3,"file":"TreeMultiSelect-C76RYavo.js","names":[],"sources":["../../src/tree-select/TreeMultiSelect.tsx"],"sourcesContent":["import { useMemo } from \"react\";\n\nimport { UiBaseProps } from \"../types\";\n\nimport { createTreeNodeIndex, getTreeNodeSelectionState, toggleTreeMultiSelection, treeMultiValueToSelectedIds } from \"./model/treeUtils\";\nimport { TreePickerBase } from \"./TreePickerBase\";\nimport { TreeMultiSelectValue, TreeSelectNode } from \"./types\";\n\nexport interface TreeMultiSelectProps extends Omit<UiBaseProps<TreeMultiSelectValue>, \"placeholder\"> {\n\tnodes: readonly TreeSelectNode[];\n\tplaceholder?: string;\n\tquery?: string;\n\tdefaultQuery?: string;\n\tonQuery?: (value: string) => void;\n\tisLoading?: boolean;\n\terror?: string;\n}\n\nfunction formatTreeMultiSummary(selectedIds: Set<string>, treeIndex: ReturnType<typeof createTreeNodeIndex>) {\n\tif (selectedIds.size === 0) {\n\t\treturn undefined;\n\t}\n\n\tif (selectedIds.size === 1) {\n\t\tconst selectedNode = treeIndex.nodeById.get([...selectedIds][0]);\n\n\t\tif (!selectedNode) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (selectedNode.code && selectedNode.code !== selectedNode.label) {\n\t\t\treturn `${selectedNode.label} · ${selectedNode.code}`;\n\t\t}\n\n\t\treturn selectedNode.label;\n\t}\n\n\treturn `Выбрано ${selectedIds.size} узл.`;\n}\n\nexport function TreeMultiSelect({\n\tlabel,\n\tdescription,\n\tdisabled,\n\tplaceholder = \"Выберите значения\",\n\tsize,\n\tnodes,\n\tvalue,\n\tonChange,\n\tquery,\n\tdefaultQuery,\n\tonQuery,\n\tisLoading,\n\terror\n}: TreeMultiSelectProps) {\n\tconst treeIndex = useMemo(() => createTreeNodeIndex(nodes), [nodes]);\n\tconst selectedIds = useMemo(() => treeMultiValueToSelectedIds(value, treeIndex), [treeIndex, value]);\n\tconst selectionState = useMemo(() => getTreeNodeSelectionState(selectedIds, treeIndex), [selectedIds, treeIndex]);\n\tconst selectedSummary = useMemo(() => formatTreeMultiSummary(selectedIds, treeIndex), [selectedIds, treeIndex]);\n\n\treturn (\n\t\t<TreePickerBase\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\tdisabled={disabled}\n\t\t\tplaceholder={placeholder}\n\t\t\tsize={size}\n\t\t\tnodes={nodes}\n\t\t\tselectedIds={selectionState.selectedIds}\n\t\t\tpartialIds={selectionState.partialIds}\n\t\t\tselectionMode=\"multi\"\n\t\t\ttriggerMode=\"search\"\n\t\t\tselectedSummary={selectedSummary}\n\t\t\tquery={query}\n\t\t\tdefaultQuery={defaultQuery}\n\t\t\tonQuery={onQuery}\n\t\t\tonNodeActivate={(node) => onChange(toggleTreeMultiSelection(value, node.id, treeIndex))}\n\t\t\tonClearSelection={() => onChange({})}\n\t\t\tisLoading={isLoading}\n\t\t\terror={error}\n\t\t/>\n\t);\n}\n"],"mappings":";;;;AAkBA,SAAS,EAAuB,GAA0B,GAAmD;CACxG,MAAY,SAAS,GAIzB;MAAI,EAAY,SAAS,GAAG;GAC3B,IAAM,IAAe,EAAU,SAAS,IAAI,CAAC,GAAG,CAAW,CAAC,CAAC,EAAE;GAU/D,OARK,IAID,EAAa,QAAQ,EAAa,SAAS,EAAa,QACpD,GAAG,EAAa,MAAM,KAAK,EAAa,SAGzC,EAAa,QAPnB;EAQF;EAEA,OAAO,WAAW,EAAY,KAAK;CAFnC;AAGD;AAEA,SAAgB,EAAgB,EAC/B,UACA,gBACA,aACA,iBAAc,qBACd,SACA,UACA,UACA,aACA,UACA,iBACA,YACA,cACA,YACwB;CACxB,IAAM,IAAY,QAAc,EAAoB,CAAK,GAAG,CAAC,CAAK,CAAC,GAC7D,IAAc,QAAc,EAA4B,GAAO,CAAS,GAAG,CAAC,GAAW,CAAK,CAAC,GAC7F,IAAiB,QAAc,EAA0B,GAAa,CAAS,GAAG,CAAC,GAAa,CAAS,CAAC,GAC1G,IAAkB,QAAc,EAAuB,GAAa,CAAS,GAAG,CAAC,GAAa,CAAS,CAAC;CAE9G,OACC,kBAAC,GAAD;EACQ;EACM;EACH;EACG;EACP;EACC;EACP,aAAa,EAAe;EAC5B,YAAY,EAAe;EAC3B,eAAc;EACd,aAAY;EACK;EACV;EACO;EACL;EACT,iBAAiB,MAAS,EAAS,EAAyB,GAAO,EAAK,IAAI,CAAS,CAAC;EACtF,wBAAwB,EAAS,CAAC,CAAC;EACxB;EACJ;CACP,CAAA;AAEH"}
|