@ryuzaki13/react-foundation-ui 1.6.8 → 1.6.9
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/advanced-search/index.js +5 -5
- package/dist/chunks/{TextEditorLexicalClient-iTf_y4Bu.js → TextEditorLexicalClient-Dcd6OD8n.js} +2 -2
- package/dist/chunks/{TextEditorLexicalClient-iTf_y4Bu.js.map → TextEditorLexicalClient-Dcd6OD8n.js.map} +1 -1
- package/dist/chunks/{date-input-BbsvnayB.js → date-input-DEHI8-wq.js} +2 -2
- package/dist/chunks/{date-input-BbsvnayB.js.map → date-input-DEHI8-wq.js.map} +1 -1
- package/dist/chunks/{input-D3u9BYWD.js → input-CCdBtl-C.js} +38 -32
- package/dist/chunks/input-CCdBtl-C.js.map +1 -0
- package/dist/chunks/{input-files-D7iu_1n5.js → input-files-TXdXrSAs.js} +4 -4
- package/dist/chunks/{input-files-D7iu_1n5.js.map → input-files-TXdXrSAs.js.map} +1 -1
- package/dist/chunks/{input-search-4841icgL.js → input-search-Ca8iqeK2.js} +2 -2
- package/dist/chunks/{input-search-4841icgL.js.map → input-search-Ca8iqeK2.js.map} +1 -1
- package/dist/chunks/{multi-select-BDvaRbUc.js → multi-select-Bs1GU5MD.js} +2 -2
- package/dist/chunks/{multi-select-BDvaRbUc.js.map → multi-select-Bs1GU5MD.js.map} +1 -1
- package/dist/chunks/{picker-lpH_xp14.js → picker-CrRdwdA5.js} +8 -8
- package/dist/chunks/{picker-lpH_xp14.js.map → picker-CrRdwdA5.js.map} +1 -1
- package/dist/chunks/{select-3KLv_evq.js → select-DeeGYtVc.js} +3 -3
- package/dist/chunks/{select-3KLv_evq.js.map → select-DeeGYtVc.js.map} +1 -1
- package/dist/date-input/index.js +1 -1
- package/dist/date-time-input/index.js +3 -3
- package/dist/drop-zone/index.js +1 -1
- package/dist/image/index.js +2 -2
- package/dist/input/Input.d.ts +4 -1
- package/dist/input/Input.d.ts.map +1 -1
- package/dist/input/index.js +2 -2
- package/dist/input-date-time/index.js +4 -4
- package/dist/input-file/index.js +4 -4
- package/dist/input-files/index.js +1 -1
- package/dist/input-image/index.js +4 -4
- package/dist/input-search/index.js +1 -1
- package/dist/layout-picker/index.js +1 -1
- package/dist/multi-select/index.js +1 -1
- package/dist/picker/index.js +1 -1
- package/dist/preset-range-date-input/index.js +1 -1
- package/dist/preset-select/index.js +1 -1
- package/dist/select/index.js +1 -1
- package/dist/slider/index.js +18 -18
- package/dist/state-select/index.js +1 -1
- package/dist/tag-input/index.js +1 -1
- package/dist/text-editor/index.js +1 -1
- package/dist/textarea/index.js +1 -1
- package/dist/tree-select/index.js +3 -3
- package/package.json +1 -1
- package/storybook-static/assets/{Badge-BH9cJCAY.js → Badge-BjBJb0mU.js} +1 -1
- package/storybook-static/assets/{Badge.stories-BYF_eQ_s.js → Badge.stories-bIfUH-yy.js} +1 -1
- package/storybook-static/assets/{BadgeList-BteW6yba.js → BadgeList-CSME5ioE.js} +1 -1
- package/storybook-static/assets/{Button-BBBwst3q.js → Button-BPMeIixh.js} +1 -1
- package/storybook-static/assets/{Button-CZHQwnrH.js → Button-Co85wvGY.js} +1 -1
- package/storybook-static/assets/{Button.stories-COfvjrY-.js → Button.stories-B9rrXaof.js} +1 -1
- package/storybook-static/assets/{CalendarView-CpatuJ76.js → CalendarView-BMz3z7jD.js} +1 -1
- package/storybook-static/assets/{CheckBox-BsCRJAKJ.js → CheckBox-B72Cmtaf.js} +1 -1
- package/storybook-static/assets/{CheckBox-DzJOAC6E.js → CheckBox-BResPjSq.js} +1 -1
- package/storybook-static/assets/{CheckBox.stories-R5UoXY2p.js → CheckBox.stories-Cqtm9UBg.js} +1 -1
- package/storybook-static/assets/{Color-6AOWCN3U-BXndQGo6.js → Color-6AOWCN3U-6zQ0aDDt.js} +1 -1
- package/storybook-static/assets/{ContextMenu-PyHghx7l.js → ContextMenu-BV-OLyX_.js} +1 -1
- package/storybook-static/assets/{ContextMenu-D3-LIbYd.js → ContextMenu-C9WykyIU.js} +1 -1
- package/storybook-static/assets/{ContextMenu.stories-BE6qp6B7.js → ContextMenu.stories-U1W_lMGh.js} +1 -1
- package/storybook-static/assets/{DateInput-gEh23Tlv.js → DateInput-C5w1-hy7.js} +1 -1
- package/storybook-static/assets/{DateInput-B59FLYqZ.js → DateInput-DaTeTS3s.js} +1 -1
- package/storybook-static/assets/{DateInput.stories-CIosjM5S.js → DateInput.stories-Dyyz7UMz.js} +1 -1
- package/storybook-static/assets/{DateRangePresetSelect-BGpfgxTw.js → DateRangePresetSelect-Df0irmdA.js} +1 -1
- package/storybook-static/assets/{DateRangePresetSelect-eOh2VTiQ.js → DateRangePresetSelect-DhMe-m4i.js} +1 -1
- package/storybook-static/assets/{DateRangePresetSelect.stories-atP3PX4M.js → DateRangePresetSelect.stories-CvwoJ7lD.js} +1 -1
- package/storybook-static/assets/{Detail-BWMcwojf.js → Detail-Cdh9fyyH.js} +1 -1
- package/storybook-static/assets/{Detail.stories-CdwSt-w7.js → Detail.stories-B6G_j_6A.js} +1 -1
- package/storybook-static/assets/{Dialog-B1pH_FwI.js → Dialog-9xARsvHJ.js} +1 -1
- package/storybook-static/assets/{Dialog-zSUu48WZ.js → Dialog-CKNXp8KO.js} +1 -1
- package/storybook-static/assets/{Dialog.stories-DGXSyA5S.js → Dialog.stories-Dre5cUMx.js} +1 -1
- package/storybook-static/assets/{Disclosure-CSRJd54k.js → Disclosure-vbRaiYkK.js} +1 -1
- package/storybook-static/assets/{Disclosure.stories-DYWa6mIL.js → Disclosure.stories-C4VRChtc.js} +1 -1
- package/storybook-static/assets/{DisclosureGroup-8OGJhi6k.js → DisclosureGroup-ZZhbeIRB.js} +1 -1
- package/storybook-static/assets/{DocsRenderer-JROSPFPF-DIPCXW75.js → DocsRenderer-JROSPFPF-BHLHzELP.js} +1 -1
- package/storybook-static/assets/{DropZone-CNHIeT8y.js → DropZone-CdzJFmF_.js} +1 -1
- package/storybook-static/assets/{DropZone-Hol7tyoC.js → DropZone-DYD8m-WY.js} +1 -1
- package/storybook-static/assets/{DropZone.stories-CB-82WXu.js → DropZone.stories-DRzuE2vU.js} +1 -1
- package/storybook-static/assets/{DropdownMenu-BkvphuPG.js → DropdownMenu-BdTz_Ptj.js} +1 -1
- package/storybook-static/assets/{ExpandableActionPanel-D1GU08pC.js → ExpandableActionPanel-DEPmrsnk.js} +1 -1
- package/storybook-static/assets/{ExpandableActionPanel.stories-CPg9t51H.js → ExpandableActionPanel.stories-BE7mdinl.js} +1 -1
- package/storybook-static/assets/{Flex-DQKATg5D.js → Flex-XJLvKVvt.js} +1 -1
- package/storybook-static/assets/{Flex.stories-DUtfrPQE.js → Flex.stories-BSuqTMzF.js} +1 -1
- package/storybook-static/assets/{FloatingPopover-DcvsLzUp.js → FloatingPopover-knMoS2qC.js} +1 -1
- package/storybook-static/assets/{FormattedTableCell-BsiXduX6.js → FormattedTableCell-BfFlODcQ.js} +1 -1
- package/storybook-static/assets/{Grid-DZ77Nt29.js → Grid-BQhpngv4.js} +1 -1
- package/storybook-static/assets/{Grid.stories-DSFAaQXP.js → Grid.stories-D_y1SBc8.js} +1 -1
- package/storybook-static/assets/{ImageCropper.stories-BznTRYpf.js → ImageCropper.stories-FZOA4MDm.js} +1 -1
- package/storybook-static/assets/{ImageRenderer-Bk2hHaOz.js → ImageRenderer-YCNRUsf3.js} +1 -1
- package/storybook-static/assets/{ImageRenderer.stories-vL6-fvWD.js → ImageRenderer.stories-w_O5AorR.js} +1 -1
- package/storybook-static/assets/{ImageView.stories-Bdtc8uSn.js → ImageView.stories-DHpZpY6i.js} +1 -1
- package/storybook-static/assets/{ImageViewer.stories-BNBKxTS7.js → ImageViewer.stories-DVur88oi.js} +2 -2
- package/storybook-static/assets/{ImageViewerRuntime-CEx0a6NV.js → ImageViewerRuntime-DHsDOTkI.js} +1 -1
- package/storybook-static/assets/Input-DmyHUqFK.js +3 -0
- package/storybook-static/assets/{Input-QHO-MarM.js → Input-cLIPWJ3S.js} +1 -1
- package/storybook-static/assets/{Input.stories-OgJxL5gh.js → Input.stories-DKi7fLm4.js} +1 -1
- package/storybook-static/assets/{InputDateTime-DKkrE7wv.js → InputDateTime-0x_60nGl.js} +1 -1
- package/storybook-static/assets/{InputDateTime.stories-BXQe74zA.js → InputDateTime.stories--EVU3NN2.js} +1 -1
- package/storybook-static/assets/{InputFile-BGZXYtb0.js → InputFile-BsJB40TL.js} +1 -1
- package/storybook-static/assets/{InputFile-BSv8B_ke.js → InputFile-iHlVGdes.js} +1 -1
- package/storybook-static/assets/{InputFile.stories-CPG9pfLt.js → InputFile.stories-CCHijHkw.js} +1 -1
- package/storybook-static/assets/{InputFiles-B5pqrH9_.js → InputFiles-B8KyPoQv.js} +1 -1
- package/storybook-static/assets/{InputFiles-DtyE7WHL.js → InputFiles-CUWYjhS9.js} +1 -1
- package/storybook-static/assets/{InputFiles.stories-CJ4Ltoho.js → InputFiles.stories-DKvTOpt2.js} +1 -1
- package/storybook-static/assets/{InputFilesList-DSDKGyGW.js → InputFilesList-D234NNsd.js} +1 -1
- package/storybook-static/assets/{InputImage-Bku82LkV.js → InputImage-BLuKH0cM.js} +1 -1
- package/storybook-static/assets/{InputImage-LmGlUcN7.js → InputImage-BZBVXOzi.js} +1 -1
- package/storybook-static/assets/{InputImage.stories-Bmac6ARR.js → InputImage.stories-CGyRVsxr.js} +1 -1
- package/storybook-static/assets/{InteractiveComponents-NpX5JJGz.js → InteractiveComponents-CZAi65Yc.js} +1 -1
- package/storybook-static/assets/{InteractiveComponents.stories-BM68v2N1.js → InteractiveComponents.stories-Dr_qTuv_.js} +1 -1
- package/storybook-static/assets/{LayoutPicker-Biuv2wk3.js → LayoutPicker-BJC6CkZA.js} +1 -1
- package/storybook-static/assets/{LayoutPicker-D5J4yobv.js → LayoutPicker-oODyGDhs.js} +1 -1
- package/storybook-static/assets/{LayoutPicker.stories-D9RoLDFh.js → LayoutPicker.stories-B7SBNaJ5.js} +1 -1
- package/storybook-static/assets/{Listbox-DcX4TpeL.js → Listbox-4deIYtd5.js} +1 -1
- package/storybook-static/assets/{Listbox-hz1us358.js → Listbox-B0oP0kP_.js} +1 -1
- package/storybook-static/assets/{Listbox.stories-C1zTx4lV.js → Listbox.stories-DBsGzxTf.js} +1 -1
- package/storybook-static/assets/{Modal-BWpK-3RC.js → Modal-DmvMGAbn.js} +1 -1
- package/storybook-static/assets/{Modal.stories-C0Vu70NL.js → Modal.stories-B5m-QmoV.js} +1 -1
- package/storybook-static/assets/{ModalManagerProvider-D4RBeFQU.js → ModalManagerProvider-BrXUxhsr.js} +1 -1
- package/storybook-static/assets/{MultiSelect-DDlktjVy.js → MultiSelect-GauKopyh.js} +1 -1
- package/storybook-static/assets/{MultiSelect-C9mFgvGF.js → MultiSelect-z7BbE2br.js} +1 -1
- package/storybook-static/assets/{MultiSelect.stories-CGNeMuHd.js → MultiSelect.stories-Bkv3L4gA.js} +1 -1
- package/storybook-static/assets/{NoData-CfHEnqBb.js → NoData-DzRjocEa.js} +1 -1
- package/storybook-static/assets/{NotificationsHost-QQgvBqnj.js → NotificationsHost-DnaDUaBo.js} +1 -1
- package/storybook-static/assets/{NotificationsHost.stories-BD7EObP3.js → NotificationsHost.stories-kMde5O1r.js} +1 -1
- package/storybook-static/assets/{ODataMultiSelect-D019frRl.js → ODataMultiSelect-Bxwuucyq.js} +1 -1
- package/storybook-static/assets/{ODataMultiSelect.stories-C9dslw6q.js → ODataMultiSelect.stories-BZ9GpyO6.js} +1 -1
- package/storybook-static/assets/{ODataSelect-DGvwVOS-.js → ODataSelect-B3YW1vMn.js} +1 -1
- package/storybook-static/assets/{ODataSelect.stories-BI98Mc9i.js → ODataSelect.stories-DdZPvlZQ.js} +1 -1
- package/storybook-static/assets/{ODataTreeMultiSelect-n6IQR0cO.js → ODataTreeMultiSelect-ABvp9Jw2.js} +1 -1
- package/storybook-static/assets/{ODataTreeMultiSelect.stories-B9OrbwCj.js → ODataTreeMultiSelect.stories-BpA3BGs6.js} +1 -1
- package/storybook-static/assets/{ODataTreeSelect-oiKVq7ek.js → ODataTreeSelect-Dd4cEOJ2.js} +1 -1
- package/storybook-static/assets/{ODataTreeSelect.stories-C7iZ0F7H.js → ODataTreeSelect.stories-D0jNx9Fx.js} +1 -1
- package/storybook-static/assets/{OneStepScroller-8wagbdbs.js → OneStepScroller-LWKPQ4zF.js} +1 -1
- package/storybook-static/assets/{PeriodSelect-DxToZXqe.js → PeriodSelect-CUZPOFyO.js} +1 -1
- package/storybook-static/assets/{PeriodSelect-DFAi17Ej.js → PeriodSelect-DQuQU6G9.js} +1 -1
- package/storybook-static/assets/{PeriodSelect.stories-DrRz3yNz.js → PeriodSelect.stories-D1wcws2m.js} +1 -1
- package/storybook-static/assets/{PickerSelectionToolbar-D1ge85bL.js → PickerSelectionToolbar-BrcD45PX.js} +1 -1
- package/storybook-static/assets/{PickerTriggerActions-9pKMXQqi.js → PickerTriggerActions-DXHW51rc.js} +1 -1
- package/storybook-static/assets/{Popover-Dz-nNtC1.js → Popover-Dqz0kSoL.js} +1 -1
- package/storybook-static/assets/{Popover-CQUaiPAD.js → Popover-W94COpwE.js} +1 -1
- package/storybook-static/assets/{Popover.stories-Dsh3vlGC.js → Popover.stories-VVPYIdc2.js} +1 -1
- package/storybook-static/assets/{PresetRangeDateInput-BGeIel4o.js → PresetRangeDateInput-BueHzRgF.js} +1 -1
- package/storybook-static/assets/{PresetRangeDateInput-j0zAzhiB.js → PresetRangeDateInput-CzXyY5S_.js} +1 -1
- package/storybook-static/assets/{PresetRangeDateInput.stories-TrWSvY-M.js → PresetRangeDateInput.stories-CtZCYqqV.js} +1 -1
- package/storybook-static/assets/{PresetSelect-38KUTO3N.js → PresetSelect-C1qu4z5K.js} +1 -1
- package/storybook-static/assets/{RadioButton-CtRtwS3I.js → RadioButton-BK7izxPZ.js} +1 -1
- package/storybook-static/assets/{RadioButton-D8yBtqK1.js → RadioButton-C1ifDEJ8.js} +1 -1
- package/storybook-static/assets/{RadioButton.stories-Dcc3TQYI.js → RadioButton.stories-D0WqG_6J.js} +1 -1
- package/storybook-static/assets/{RadioGroup-BcNUOoen.js → RadioGroup-C9PyWYee.js} +1 -1
- package/storybook-static/assets/{RadioGroup-DhF8x85S.js → RadioGroup-omXMMa0q.js} +1 -1
- package/storybook-static/assets/{RadioGroup.stories-DYVsF9V3.js → RadioGroup.stories-cekjemmK.js} +1 -1
- package/storybook-static/assets/{Scrollable-Bh2rpfAn.js → Scrollable-DcHx886P.js} +1 -1
- package/storybook-static/assets/{Select-CBnZeg5H.js → Select-BoTu6Otb.js} +1 -1
- package/storybook-static/assets/{Select-YMkbnwwo.js → Select-CBMrYzkw.js} +1 -1
- package/storybook-static/assets/{Select.stories-CSmhKRHH.js → Select.stories-3hgLOUNU.js} +1 -1
- package/storybook-static/assets/{SelectOptionContent-BGI95rYW.js → SelectOptionContent-DqKMbr5G.js} +1 -1
- package/storybook-static/assets/{SerializableSelect-Bqq5YI3U.js → SerializableSelect-CYcxpdIe.js} +1 -1
- package/storybook-static/assets/{SerializableSelect.stories-BnnEcfua.js → SerializableSelect.stories-CnZnjtjD.js} +1 -1
- package/storybook-static/assets/{SingleDateTimeInput-CW9o-1cz.js → SingleDateTimeInput-DMfEsPu5.js} +1 -1
- package/storybook-static/assets/{SingleDateTimeInput-Zxm6Vedj.js → SingleDateTimeInput-rbNU_KO-.js} +1 -1
- package/storybook-static/assets/{SingleDateTimeInput.stories-B4ENGl3e.js → SingleDateTimeInput.stories-TgTOUo-Y.js} +1 -1
- package/storybook-static/assets/{Slider-DsYPbCCE.js → Slider-DCIIkWz_.js} +1 -1
- package/storybook-static/assets/{Slider-BdY3pUkK.js → Slider-Dxecri8F.js} +1 -1
- package/storybook-static/assets/{Slider.stories-Coz2_WUn.js → Slider.stories-BRipjSIm.js} +1 -1
- package/storybook-static/assets/{SliderInput-BIRwDyzx.js → SliderInput-PQ5uxXHE.js} +1 -1
- package/storybook-static/assets/{SliderInput-B7F-qYmb.js → SliderInput-TPGWb2cl.js} +1 -1
- package/storybook-static/assets/{SliderInput.stories-BmFNVxns.js → SliderInput.stories-CmANlT0P.js} +1 -1
- package/storybook-static/assets/{Sortable-DewjXJHH.js → Sortable-DAjL5x6G.js} +1 -1
- package/storybook-static/assets/{Sortable.stories-DjDEHfbr.js → Sortable.stories-Dl2wApfw.js} +1 -1
- package/storybook-static/assets/{Splitter-BEl27MLi.js → Splitter-BHBHUJKu.js} +1 -1
- package/storybook-static/assets/{Splitter.stories-DbVszgSe.js → Splitter.stories-Nj66s6aD.js} +1 -1
- package/storybook-static/assets/{StateSelect-CgWHXo-b.js → StateSelect-BfQIK04A.js} +1 -1
- package/storybook-static/assets/{StateSelect-BalgGekN.js → StateSelect-CHXGACeH.js} +1 -1
- package/storybook-static/assets/{StateSelect.stories-C9B7mFLn.js → StateSelect.stories-DXiKDU0l.js} +1 -1
- package/storybook-static/assets/{StringToggle.stories-Bp_X25qM.js → StringToggle.stories-DaCHu-59.js} +1 -1
- package/storybook-static/assets/{Switch-j-ZXbmAp.js → Switch-BY9fB1md.js} +1 -1
- package/storybook-static/assets/{Switch-CMhSVav5.js → Switch-Ct_ConVp.js} +1 -1
- package/storybook-static/assets/{Switch.stories-D_fgEJKx.js → Switch.stories-JemVigGs.js} +1 -1
- package/storybook-static/assets/{Table-DQ94rvHY.js → Table-C-7NAuof.js} +1 -1
- package/storybook-static/assets/{Table.stories-lgQzeacf.js → Table.stories-Ch8DZ1Er.js} +1 -1
- package/storybook-static/assets/{Tabs-7SvGdRJy.js → Tabs-5dAPoFdD.js} +1 -1
- package/storybook-static/assets/{Tabs.stories-C-_Dnrt2.js → Tabs.stories-8N-qDmwD.js} +1 -1
- package/storybook-static/assets/{TabsBox-CcqmMAUz.js → TabsBox-ah2I0RzK.js} +1 -1
- package/storybook-static/assets/{TagInput-jRsa9QsJ.js → TagInput-BSBy6FGI.js} +1 -1
- package/storybook-static/assets/{TagInput.stories-BURLH1G5.js → TagInput.stories-Cp4NH6uS.js} +1 -1
- package/storybook-static/assets/{Text-CNxXY5Sc.js → Text-Zfl1pnOB.js} +1 -1
- package/storybook-static/assets/{Textarea-BZQt0v7T.js → Textarea-CQ5OWkWr.js} +1 -1
- package/storybook-static/assets/{Textarea-De2JE4Ro.js → Textarea-Ci63XMCS.js} +1 -1
- package/storybook-static/assets/{Textarea.stories-B4bz59CP.js → Textarea.stories-x8s51N7A.js} +1 -1
- package/storybook-static/assets/{TimePanel-CrsDz5Fk.js → TimePanel-VuyMHXDo.js} +1 -1
- package/storybook-static/assets/{TimePanel.stories-BfQL7f4T.js → TimePanel.stories-BcH1OpQi.js} +1 -1
- package/storybook-static/assets/{Toggle-o_AGl3LG.js → Toggle-6WG03vXI.js} +1 -1
- package/storybook-static/assets/{Toggle-iot4QLkN.js → Toggle-aHeH-OSg.js} +1 -1
- package/storybook-static/assets/{Toggle.stories-BsVnCzsC.js → Toggle.stories-DXCkI5KF.js} +1 -1
- package/storybook-static/assets/{TreeMultiSelect-DSg3hrvD.js → TreeMultiSelect-CXLNh_oz.js} +1 -1
- package/storybook-static/assets/{TreeMultiSelect-Z3XWSrul.js → TreeMultiSelect-Y9IFldJK.js} +1 -1
- package/storybook-static/assets/{TreeMultiSelect.stories-IKP2y4Gr.js → TreeMultiSelect.stories-B0kD_upG.js} +1 -1
- package/storybook-static/assets/{TreePickerBase-Cb_E6TeZ.js → TreePickerBase-CahwOsJC.js} +1 -1
- package/storybook-static/assets/{TreeSelect-C0UHhpjh.js → TreeSelect-BP7Vf-2A.js} +1 -1
- package/storybook-static/assets/{TreeSelect-e5FHYBKv.js → TreeSelect-DvH-ZFOI.js} +1 -1
- package/storybook-static/assets/{TreeSelect.stories-pDvcI-gD.js → TreeSelect.stories-CgWNFu8e.js} +1 -1
- package/storybook-static/assets/{TreeTable-xH5byped.js → TreeTable-CIC71Y88.js} +1 -1
- package/storybook-static/assets/{TreeTable.stories-prCzbc-c.js → TreeTable.stories-_Dq5sw-X.js} +1 -1
- package/storybook-static/assets/{async-BbOn6VVh.js → async-DJAT8q-R.js} +1 -1
- package/storybook-static/assets/{blocks-CoG4hpAV.js → blocks-D9lz1ATD.js} +3 -3
- package/storybook-static/assets/{browserAndReact-0zweowYb.js → browserAndReact-C6DrL5k_.js} +1 -1
- package/storybook-static/assets/{check-C0DpMGSp.js → check-D-pRbifd.js} +1 -1
- package/storybook-static/assets/{chevron-down-m1qyuFhY.js → chevron-down-BAJeUu08.js} +1 -1
- package/storybook-static/assets/{chevron-left-BlL0VUfl.js → chevron-left-HD9WWs57.js} +1 -1
- package/storybook-static/assets/{chevron-right-64NskoUH.js → chevron-right-CZrNP4jX.js} +1 -1
- package/storybook-static/assets/{chunk-W22LQPXL-BaRb3YbO.js → chunk-W22LQPXL-Dx-maav9.js} +1 -1
- package/storybook-static/assets/{circle-alert-Bq1Q7W5J.js → circle-alert-BFyuxfnG.js} +1 -1
- package/storybook-static/assets/{circle-check-tLjxj8sd.js → circle-check-Dq-oIKf6.js} +1 -1
- package/storybook-static/assets/{components-kriHInuM.js → components-CUSaaeSo.js} +3 -3
- package/storybook-static/assets/{contextMenu-BT7QpZ6n.js → contextMenu-D5WMcaLg.js} +1 -1
- package/storybook-static/assets/{defaultRenderers-EOc_OhCd.js → defaultRenderers-CAnjhfBP.js} +1 -1
- package/storybook-static/assets/{download-D3E3I3aq.js → download-C_38uliq.js} +1 -1
- package/storybook-static/assets/{filesAndExcel-Co7Q2iNd.js → filesAndExcel-Bekt15pL.js} +1 -1
- package/storybook-static/assets/{floating-ui.react-D5Ukah9Z.js → floating-ui.react-DoVJpX2x.js} +1 -1
- package/storybook-static/assets/{formatters-DbL0R1Z_.js → formatters-BRSUcXAN.js} +1 -1
- package/storybook-static/assets/{formatters-runtime-C_nsRl37.js → formatters-runtime-CF_Luo6h.js} +1 -1
- package/storybook-static/assets/{foundationLib-D9IOmAle.js → foundationLib-BDGsEERi.js} +1 -1
- package/storybook-static/assets/{hooks-D4UOjCRZ.js → hooks-BCpfqVmW.js} +1 -1
- package/storybook-static/assets/{iframe-CMe_3E2f.js → iframe-B47EHFYA.js} +3 -3
- package/storybook-static/assets/iframe-vD_yRY8M.js +1 -0
- package/storybook-static/assets/{info-CEAi6tyH.js → info-CO0GTW6b.js} +1 -1
- package/storybook-static/assets/{odata-CUv2THMH.js → odata-BsYWUKHK.js} +1 -1
- package/storybook-static/assets/{odataAndTables-BWxOcxAj.js → odataAndTables-BeDyprZ5.js} +1 -1
- package/storybook-static/assets/{odataFetchFn-DU0d9C9s.js → odataFetchFn-CQDzz9jw.js} +1 -1
- package/storybook-static/assets/{odataStoryFixtures-DEm-HTej.js → odataStoryFixtures-Lbk9-G1n.js} +1 -1
- package/storybook-static/assets/{persisted-Cb1uI9qA.js → persisted-n9lLAGen.js} +1 -1
- package/storybook-static/assets/{pureUtilities-BehkqFcW.js → pureUtilities-Cjep-9ME.js} +1 -1
- package/storybook-static/assets/{react-CnXXoRg7.js → react-Dum50wFM.js} +1 -1
- package/storybook-static/assets/{refresh-cw-C6d4NNEE.js → refresh-cw-Z-vaBKRi.js} +1 -1
- package/storybook-static/assets/{runtimeAndState-B3NePX9Z.js → runtimeAndState-Bpzlfw-r.js} +1 -1
- package/storybook-static/assets/{settings-2-BjPL8jHC.js → settings-2-jRmpHiGC.js} +1 -1
- package/storybook-static/assets/{sortable-Co660xp7.js → sortable-0-RVrtIo.js} +1 -1
- package/storybook-static/assets/{syntaxhighlighter-T5IQBZDB-y-N6WUWQ.js → syntaxhighlighter-T5IQBZDB-DpT8XIiL.js} +1 -1
- package/storybook-static/assets/{trash-2-Be_6cLkJ.js → trash-2-Bzm5QETq.js} +1 -1
- package/storybook-static/assets/{triangle-alert-Dm4eQLfe.js → triangle-alert-CSo2X-iA.js} +1 -1
- package/storybook-static/assets/{useODataSelectBase-BqhhSyKo.js → useODataSelectBase-CET7yfip.js} +1 -1
- package/storybook-static/assets/{useODataTreeData-Cm08lSsT.js → useODataTreeData-BZz-oUoz.js} +1 -1
- package/storybook-static/assets/{usePickerQuery-C7d0_yoI.js → usePickerQuery-He2zO5LX.js} +1 -1
- package/storybook-static/assets/{usePickerTriggerController-BuU8fG89.js → usePickerTriggerController-CZp4AJvd.js} +1 -1
- package/storybook-static/assets/{x-F26VOr3_.js → x-WX7BqMFr.js} +1 -1
- package/storybook-static/iframe.html +2 -2
- package/storybook-static/project.json +1 -1
- package/dist/chunks/input-D3u9BYWD.js.map +0 -1
- package/storybook-static/assets/Input-DhRD6lSq.js +0 -3
- package/storybook-static/assets/iframe-DVPKkM_M.js +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { r as e } from "./popover-IztNF45J.js";
|
|
2
2
|
import { t } from "./ui.module-DHVTOqZ0.js";
|
|
3
|
-
import { s as n } from "./input-
|
|
3
|
+
import { s as n } from "./input-CCdBtl-C.js";
|
|
4
4
|
import { n as r, o as i, s as a, t as o } from "./CalendarView-DGElHRTJ.js";
|
|
5
5
|
import { n as s } from "./radio-group-BRR1ZQDA.js";
|
|
6
6
|
import { useCallback as c, useEffect as l, useMemo as u, useRef as d, useState as f } from "react";
|
|
@@ -338,4 +338,4 @@ function X(e) {
|
|
|
338
338
|
//#endregion
|
|
339
339
|
export { I as a, R as c, N as d, j as f, B as h, C as i, L as l, H as m, Y as n, F as o, V as p, w as r, z as s, X as t, M as u };
|
|
340
340
|
|
|
341
|
-
//# sourceMappingURL=date-input-
|
|
341
|
+
//# sourceMappingURL=date-input-DEHI8-wq.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-input-BbsvnayB.js","names":[],"sources":["../../src/date-input/lib/dateInputValue.ts","../../src/date-input/model/useDateInput.ts","../../src/date-input/ui/DateInput.module.scss","../../src/date-input/ui/DateInput.tsx"],"sourcesContent":["import {\n\tDEFAULT_DATE_PRESET_NAMES,\n\tformatDate,\n\tformatDateRange,\n\tgetCalendarPeriod,\n\tgetDatePreset,\n\tisDateRangeTuple,\n\tparseDateByFormat,\n\tresolveDateFormatName,\n\ttype CalendarPeriodOptions,\n\ttype DateFormatPrecision,\n\ttype DateRangeInput,\n\ttype NullableDateRange\n} from \"@ryuzaki13/react-foundation-lib/formatters\";\n\n/**\n * Пресет даты по умолчанию для текстового поля.\n */\nexport const DEFAULT_DATE_INPUT_PRESET = DEFAULT_DATE_PRESET_NAMES.date;\n\n/**\n * @deprecated Используйте `DEFAULT_DATE_INPUT_PRESET`.\n */\nexport const DEFAULT_DATE_INPUT_FORMAT = \"dd.MM.yyyy\";\n\nconst RANGE_SEPARATOR = \" - \";\n\nexport type DateInputValueOptions = {\n\t/**\n\t * Имя пресета форматирования даты.\n\t */\n\tdatePreset?: string;\n\t/**\n\t * Точность календарного значения.\n\t */\n\tdatePickerLevel?: DateFormatPrecision;\n\t/**\n\t * Размер периода, который выбирается и нормализуется полем.\n\t */\n\tselectionMode?: CalendarPeriodOptions[\"selectionMode\"];\n\t/**\n\t * Последний включённый день недели для режима выбора недели.\n\t */\n\tweekEndDay?: CalendarPeriodOptions[\"weekEndDay\"];\n\t/**\n\t * Опорная дата для пресетов без года, например `month-long`.\n\t */\n\treferenceDate?: Date;\n};\n\nexport type DateInputValueOptionsInput = string | DateInputValueOptions | undefined;\n\n/**\n * Возвращает точность форматирования поля даты.\n */\nfunction resolveDateInputPrecision(options: DateInputValueOptions): DateFormatPrecision {\n\tif (options.selectionMode === \"day\" || options.selectionMode === \"week\") {\n\t\treturn \"day\";\n\t}\n\n\tif (options.selectionMode === \"month\" || options.selectionMode === \"year\") {\n\t\treturn options.selectionMode;\n\t}\n\n\treturn options.datePickerLevel ?? \"day\";\n}\n\nfunction resolveCalendarPeriodOptions(options?: DateInputValueOptions): CalendarPeriodOptions {\n\treturn {\n\t\tselectionMode: options?.selectionMode,\n\t\tweekEndDay: options?.weekEndDay\n\t};\n}\n\n/**\n * Нормализует объектные опции и позиционный вызов с именем пресета.\n */\nfunction normalizeDateInputValueOptions(\n\toptionsOrPreset?: DateInputValueOptionsInput,\n\tdatePickerLevel?: DateFormatPrecision\n): DateInputValueOptions {\n\tif (typeof optionsOrPreset === \"string\" || optionsOrPreset === undefined) {\n\t\treturn {\n\t\t\tdatePreset: optionsOrPreset,\n\t\t\tdatePickerLevel\n\t\t};\n\t}\n\n\tif (datePickerLevel && optionsOrPreset.datePickerLevel === undefined) {\n\t\treturn {\n\t\t\t...optionsOrPreset,\n\t\t\tdatePickerLevel\n\t\t};\n\t}\n\n\treturn optionsOrPreset;\n}\n\n/**\n * Проверяет новый `datePreset` и возвращает только зарегистрированное имя пресета.\n */\nfunction resolveDateInputPresetName(datePreset?: string): string {\n\tconst resolvedPresetName = resolveDateFormatName(datePreset, DEFAULT_DATE_INPUT_PRESET);\n\treturn getDatePreset(resolvedPresetName) ? resolvedPresetName : DEFAULT_DATE_INPUT_PRESET;\n}\n\n/**\n * Приводит результат универсального парсинга к календарной дате.\n */\nfunction parseDateTimeValue(value: string, options: DateInputValueOptions): Date | null {\n\treturn (\n\t\tparseDateByFormat(value, resolveDateInputPresetName(options.datePreset), {\n\t\t\tdefaultFormat: DEFAULT_DATE_INPUT_PRESET,\n\t\t\tprecision: resolveDateInputPrecision(options),\n\t\t\treferenceDate: options.referenceDate\n\t\t})?.date ?? null\n\t);\n}\n\n/**\n * Приводит одиночную дату к началу выбранного календарного периода.\n */\nexport function normalizeSingleDateValue(date: Date | null, options?: DateInputValueOptions): Date | null {\n\treturn getCalendarPeriod(date, resolveCalendarPeriodOptions(options))?.start ?? null;\n}\n\n/**\n * Приводит диапазон дат к границам выбранных календарных периодов.\n */\nexport function normalizeRangeDateValue(range: NullableDateRange | null, options?: DateInputValueOptions): NullableDateRange | null {\n\tif (!isDateRangeTuple(range)) return null;\n\n\tconst [startDate, endDate] = range;\n\treturn [normalizeSingleDateValue(startDate, options), normalizeRangeEndDateValue(endDate, options)];\n}\n\n/**\n * Приводит конечную дату диапазона к концу выбранного календарного периода.\n */\nexport function normalizeRangeEndDateValue(date: Date | null, options?: DateInputValueOptions): Date | null {\n\treturn getCalendarPeriod(date, resolveCalendarPeriodOptions(options))?.end ?? null;\n}\n\nfunction getDateTime(date: Date | null): number | null {\n\treturn date?.getTime() ?? null;\n}\n\n/**\n * Сравнивает одиночные даты после нормализации к точности поля ввода.\n */\nexport function areSingleDateValuesEqual(left: Date | null, right: Date | null, options?: DateInputValueOptions): boolean {\n\treturn getDateTime(normalizeSingleDateValue(left, options)) === getDateTime(normalizeSingleDateValue(right, options));\n}\n\n/**\n * Сравнивает диапазоны дат после нормализации к границам выбранных периодов.\n */\nexport function areRangeDateValuesEqual(\n\tleft: NullableDateRange | null,\n\tright: NullableDateRange | null,\n\toptions?: DateInputValueOptions\n): boolean {\n\tconst normalizedLeft = normalizeRangeDateValue(left, options);\n\tconst normalizedRight = normalizeRangeDateValue(right, options);\n\n\treturn (\n\t\tgetDateTime(normalizedLeft?.[0] ?? null) === getDateTime(normalizedRight?.[0] ?? null) &&\n\t\tgetDateTime(normalizedLeft?.[1] ?? null) === getDateTime(normalizedRight?.[1] ?? null)\n\t);\n}\n\n/**\n * Форматирует одиночную дату для текстового поля.\n */\nexport function formatSingleDateValue(\n\tdate: Date | null,\n\toptionsOrPreset?: DateInputValueOptionsInput,\n\tdatePickerLevel?: DateFormatPrecision\n): string {\n\tif (!date) return \"\";\n\n\tconst options = normalizeDateInputValueOptions(optionsOrPreset, datePickerLevel);\n\tconst period = getCalendarPeriod(date, resolveCalendarPeriodOptions(options));\n\n\t// Single-поле хранит начало недели, но показывает обе включительные границы выбранного периода.\n\tif (options.selectionMode === \"week\" && period) {\n\t\treturn formatDateRange(period.start, period.end, resolveDateInputPresetName(options.datePreset), {\n\t\t\tprecision: resolveDateInputPrecision(options)\n\t\t});\n\t}\n\n\treturn formatDate(date, resolveDateInputPresetName(options.datePreset), {\n\t\tprecision: resolveDateInputPrecision(options)\n\t});\n}\n\n/**\n * Форматирует диапазон дат для текстового поля.\n */\nexport function formatRangeDateValue(\n\trange: NullableDateRange | null,\n\toptionsOrPreset?: DateInputValueOptionsInput,\n\tdatePickerLevel?: DateFormatPrecision\n): string {\n\tif (!isDateRangeTuple(range)) return \"\";\n\n\tconst options = normalizeDateInputValueOptions(optionsOrPreset, datePickerLevel);\n\tconst [startDate, endDate] = range;\n\tif (startDate && endDate) {\n\t\treturn formatDateRange(startDate, endDate, resolveDateInputPresetName(options.datePreset), {\n\t\t\tprecision: resolveDateInputPrecision(options)\n\t\t});\n\t}\n\n\tif (startDate) {\n\t\treturn `${formatDate(startDate, resolveDateInputPresetName(options.datePreset), {\n\t\t\tprecision: resolveDateInputPrecision(options)\n\t\t})}${RANGE_SEPARATOR}`;\n\t}\n\n\treturn \"\";\n}\n\n/**\n * Унифицирует форматирование значения поля даты.\n */\nexport function formatDateInputValue(\n\tvalue: DateRangeInput,\n\toptionsOrPreset?: DateInputValueOptionsInput,\n\tdatePickerLevel?: DateFormatPrecision\n): string {\n\tif (isDateRangeTuple(value)) {\n\t\treturn formatRangeDateValue(value, optionsOrPreset, datePickerLevel);\n\t}\n\n\treturn formatSingleDateValue(value, optionsOrPreset, datePickerLevel);\n}\n\n/**\n * Парсит строку одиночной даты по заданному пресету.\n */\nexport function parseSingleDateValue(\n\tvalue: string,\n\toptionsOrPreset?: DateInputValueOptionsInput,\n\tdatePickerLevel?: DateFormatPrecision\n): Date | null {\n\tconst options = normalizeDateInputValueOptions(optionsOrPreset, datePickerLevel);\n\t// Для отображаемого диапазона single-week источником значения остаётся его первая граница.\n\tconst singleValue = options.selectionMode === \"week\" ? (value.split(RANGE_SEPARATOR)[0] ?? \"\") : value;\n\n\treturn normalizeSingleDateValue(parseDateTimeValue(singleValue, options), options);\n}\n\n/**\n * Парсит строку диапазона дат по заданному пресету.\n */\nexport function parseRangeDateValue(\n\tvalue: string,\n\toptionsOrPreset?: DateInputValueOptionsInput,\n\tdatePickerLevel?: DateFormatPrecision\n): NullableDateRange {\n\tconst options = normalizeDateInputValueOptions(optionsOrPreset, datePickerLevel);\n\tconst [startPart = \"\", endPart = \"\"] = value.split(RANGE_SEPARATOR);\n\n\treturn [parseSingleDateValue(startPart, options), parseRangeEndDateValue(endPart, options)];\n}\n\n/**\n * Парсит конечную дату диапазона и нормализует её к концу суток.\n */\nexport function parseRangeEndDateValue(\n\tvalue: string,\n\toptionsOrPreset?: DateInputValueOptionsInput,\n\tdatePickerLevel?: DateFormatPrecision\n): Date | null {\n\tconst options = normalizeDateInputValueOptions(optionsOrPreset, datePickerLevel);\n\treturn normalizeRangeEndDateValue(parseDateTimeValue(value, options), options);\n}\n","import { useMemo, useState } from \"react\";\n\nimport { isDateRangeTuple, type NullableDateRange } from \"@ryuzaki13/react-foundation-lib/formatters\";\n\nimport {\n\tDateInputValueOptions,\n\tformatDateInputValue,\n\tnormalizeRangeDateValue,\n\tnormalizeRangeEndDateValue,\n\tnormalizeSingleDateValue,\n\tparseRangeDateValue,\n\tparseSingleDateValue,\n\ttype DateInputOptions\n} from \"../lib\";\n\nfunction resolveReferenceDate(value: Date | NullableDateRange | null): Date | undefined {\n\tif (isDateRangeTuple(value)) {\n\t\treturn value[0] ?? value[1] ?? undefined;\n\t}\n\n\treturn value ?? undefined;\n}\n\n/**\n * Хук управляет текстовым представлением и выбранным значением поля даты.\n */\nexport const useDateInput = (options: DateInputOptions) => {\n\tconst externalSelectedDate = useMemo(() => {\n\t\tconst selectionOptions: DateInputValueOptions = {\n\t\t\tselectionMode: options.selectionMode,\n\t\t\tweekEndDay: options.weekEndDay\n\t\t};\n\n\t\tif (options.selectsRange) {\n\t\t\treturn normalizeRangeDateValue(options.value as NullableDateRange | null, selectionOptions);\n\t\t}\n\n\t\treturn normalizeSingleDateValue(options.value as Date | null, selectionOptions);\n\t}, [options.selectsRange, options.selectionMode, options.value, options.weekEndDay]);\n\tconst formatOptions = useMemo<DateInputValueOptions>(\n\t\t() => ({\n\t\t\tdatePreset: options.datePreset,\n\t\t\tdatePickerLevel: options.datePickerLevel,\n\t\t\tselectionMode: options.selectionMode,\n\t\t\tweekEndDay: options.weekEndDay\n\t\t}),\n\t\t[options.datePickerLevel, options.datePreset, options.selectionMode, options.weekEndDay]\n\t);\n\tconst externalInputValue = formatDateInputValue(externalSelectedDate, formatOptions);\n\tconst externalStateSignature = JSON.stringify([\n\t\toptions.selectsRange,\n\t\toptions.datePreset ?? null,\n\t\toptions.datePickerLevel ?? null,\n\t\toptions.selectionMode ?? null,\n\t\toptions.weekEndDay ?? null,\n\t\tisDateRangeTuple(externalSelectedDate)\n\t\t\t? [externalSelectedDate[0]?.getTime() ?? null, externalSelectedDate[1]?.getTime() ?? null]\n\t\t\t: (externalSelectedDate?.getTime() ?? null)\n\t]);\n\tconst [draftState, setDraftState] = useState(() => ({\n\t\tsourceSignature: externalStateSignature,\n\t\tselectedDate: externalSelectedDate,\n\t\tinputValue: externalInputValue\n\t}));\n\tconst hasCurrentDraft = draftState.sourceSignature === externalStateSignature;\n\tconst selectedDate = hasCurrentDraft ? draftState.selectedDate : externalSelectedDate;\n\tconst inputValue = hasCurrentDraft ? draftState.inputValue : externalInputValue;\n\n\t/**\n\t * Сохраняет пользовательский текст только относительно текущего controlled-снимка.\n\t * При внешней смене value или формата отображение сразу выводится из новых props.\n\t */\n\tconst setInputValue = (nextInputValue: string) => {\n\t\tsetDraftState((currentState) => {\n\t\t\tconst currentSelectedDate =\n\t\t\t\tcurrentState.sourceSignature === externalStateSignature ? currentState.selectedDate : externalSelectedDate;\n\n\t\t\treturn {\n\t\t\t\tsourceSignature: externalStateSignature,\n\t\t\t\tselectedDate: currentSelectedDate,\n\t\t\t\tinputValue: nextInputValue\n\t\t\t};\n\t\t});\n\t};\n\n\t/**\n\t * Обновляет локальный незавершённый выбор, не зеркаля controlled value через effect.\n\t */\n\tconst setSelectedDate = (nextSelectedDate: Date | NullableDateRange | null) => {\n\t\tsetDraftState((currentState) => {\n\t\t\tconst currentInputValue =\n\t\t\t\tcurrentState.sourceSignature === externalStateSignature ? currentState.inputValue : externalInputValue;\n\n\t\t\treturn {\n\t\t\t\tsourceSignature: externalStateSignature,\n\t\t\t\tselectedDate: nextSelectedDate,\n\t\t\t\tinputValue: currentInputValue\n\t\t\t};\n\t\t});\n\t};\n\n\t/**\n\t * Форматирует значение поля даты согласно текущему пресету.\n\t */\n\tconst formatValue = (value: Date | NullableDateRange | null): string => formatDateInputValue(value, formatOptions);\n\n\t/**\n\t * Парсит строковое значение поля в дату или диапазон дат.\n\t */\n\tconst parseDate = (dateString: string): Date | NullableDateRange | null => {\n\t\tconst parseOptions: DateInputValueOptions = {\n\t\t\t...formatOptions,\n\t\t\treferenceDate: resolveReferenceDate(selectedDate)\n\t\t};\n\n\t\tif (options.selectsRange) {\n\t\t\treturn parseRangeDateValue(dateString, parseOptions);\n\t\t}\n\n\t\treturn parseSingleDateValue(dateString, parseOptions);\n\t};\n\n\t/**\n\t * Обрабатывает выбор даты из календаря.\n\t */\n\tconst handleSelect = (date: Date | NullableDateRange) => {\n\t\tconst [selectedStartDate, selectedEndDate] = (Array.isArray(date) ? date : [date, null]) as NullableDateRange;\n\n\t\tif (options.selectsRange) {\n\t\t\tconst normalizedStartDate = normalizeSingleDateValue(selectedStartDate, formatOptions);\n\t\t\tconst normalizedEndDate = normalizeRangeEndDateValue(selectedEndDate, formatOptions);\n\n\t\t\tif (normalizedStartDate && normalizedEndDate) {\n\t\t\t\tif (normalizedEndDate < normalizedStartDate) {\n\t\t\t\t\tconst swappedRange: NullableDateRange = [\n\t\t\t\t\t\tnormalizeSingleDateValue(selectedEndDate, formatOptions),\n\t\t\t\t\t\tnormalizeRangeEndDateValue(selectedStartDate, formatOptions)\n\t\t\t\t\t];\n\t\t\t\t\tsetDraftState({\n\t\t\t\t\t\tsourceSignature: externalStateSignature,\n\t\t\t\t\t\tselectedDate: swappedRange,\n\t\t\t\t\t\tinputValue: formatValue(swappedRange)\n\t\t\t\t\t});\n\t\t\t\t\toptions.onChange(swappedRange);\n\t\t\t\t} else {\n\t\t\t\t\tconst nextRange: NullableDateRange = [normalizedStartDate, normalizedEndDate];\n\t\t\t\t\tsetDraftState({\n\t\t\t\t\t\tsourceSignature: externalStateSignature,\n\t\t\t\t\t\tselectedDate: nextRange,\n\t\t\t\t\t\tinputValue: formatValue(nextRange)\n\t\t\t\t\t});\n\t\t\t\t\toptions.onChange(nextRange);\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tconst nextRange: NullableDateRange = [normalizedStartDate, null];\n\t\t\tsetDraftState({\n\t\t\t\tsourceSignature: externalStateSignature,\n\t\t\t\tselectedDate: nextRange,\n\t\t\t\tinputValue: formatValue(nextRange)\n\t\t\t});\n\t\t\treturn false;\n\t\t}\n\n\t\tconst normalizedDate = normalizeSingleDateValue(selectedStartDate, formatOptions);\n\t\tsetDraftState({\n\t\t\tsourceSignature: externalStateSignature,\n\t\t\tselectedDate: normalizedDate,\n\t\t\tinputValue: formatValue(normalizedDate)\n\t\t});\n\t\toptions.onChange(normalizedDate);\n\n\t\treturn true;\n\t};\n\n\treturn {\n\t\tinputValue,\n\t\tsetInputValue,\n\t\tselectedDate,\n\t\tsetSelectedDate,\n\t\thandleSelect,\n\t\tformatDate: formatValue,\n\t\tparseDate\n\t};\n};\n",".selectionModeControl {\n\tmargin-top: var(--space-sm);\n\tpadding-top: var(--space-sm);\n\tborder-top: var(--border);\n}\n","import { JSX, useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { isDateRangeTuple, type NullableDateRange } from \"@ryuzaki13/react-foundation-lib/formatters\";\nimport { CalendarDaysIcon } from \"lucide-react\";\n\nimport { InputText } from \"../../input\";\nimport { Popover } from \"../../popover\";\nimport { RadioGroup } from \"../../radio-group\";\nimport { UiBaseProps } from \"../../types\";\nimport uiStyles from \"../../ui.module.scss\";\nimport {\n\tareRangeDateValuesEqual,\n\tareSingleDateValuesEqual,\n\tDATE_INPUT_SELECTION_MODES,\n\tisDatePickerLevelAvailable,\n\tresolveAvailableDatePickerLevel,\n\ttype DateInputSelectionMode,\n\ttype DateInputWeekEndDay,\n\ttype DatePickerLevel\n} from \"../lib\";\nimport { useDateInput } from \"../model\";\n\nimport { CalendarView } from \"./CalendarView\";\nimport styles from \"./DateInput.module.scss\";\n\ninterface BaseDateInputProps {\n\terror?: string;\n\tonClearError?: () => void;\n\n\tminDate?: Date;\n\tmaxDate?: Date;\n\n\tdatePreset?: string;\n\n\t/**\n\t * Минимальный уровень календарной навигации. Размер выбранного периода задаёт `selectionMode`.\n\t */\n\tdatePickerLevel?: DatePickerLevel;\n\t/**\n\t * Размер периода, который выбирает поле: день, неделя, месяц или год.\n\t */\n\tselectionMode?: DateInputSelectionMode;\n\t/**\n\t * Последний включённый день недели для `selectionMode=\"week\"`.\n\t */\n\tweekEndDay?: DateInputWeekEndDay;\n\t/**\n\t * Показывает переключатель `selectionMode` под календарём.\n\t */\n\tallowSelectionModeChange?: boolean;\n\t/**\n\t * Ограничивает набор режимов в runtime-переключателе.\n\t */\n\tselectionModeOptions?: readonly DateInputSelectionMode[];\n\t/**\n\t * Сообщает наружу о runtime-смене режима выбора.\n\t */\n\tonSelectionModeChange?: (selectionMode: DateInputSelectionMode) => void;\n}\n\nexport interface DateSingleInputProps extends BaseDateInputProps, UiBaseProps<Date | null> {\n\tselectsRange?: false;\n}\nexport interface DateRangeInputProps extends BaseDateInputProps, UiBaseProps<NullableDateRange | null> {\n\tselectsRange: true;\n}\n\ntype DateInputProps = DateSingleInputProps | DateRangeInputProps;\n\ninterface CalendarTypeState {\n\treadonly view: DatePickerLevel;\n\treadonly selectionMode: DateInputSelectionMode;\n\treadonly minDatePickerLevel: DatePickerLevel;\n}\n\nconst selectionModeLabels: Record<DateInputSelectionMode, string> = {\n\tday: \"День\",\n\tweek: \"Неделя\",\n\tmonth: \"Месяц\",\n\tyear: \"Год\"\n};\n\nfunction resolveSelectionModeOptions(\n\tselectionModeOptions: readonly DateInputSelectionMode[] | undefined,\n\tselectionMode: DateInputSelectionMode\n): readonly DateInputSelectionMode[] {\n\tconst enabledModes = new Set(selectionModeOptions?.length ? selectionModeOptions : DATE_INPUT_SELECTION_MODES);\n\tenabledModes.add(selectionMode);\n\n\treturn DATE_INPUT_SELECTION_MODES.filter((mode) => enabledModes.has(mode));\n}\n\nfunction DateInput(props: DateSingleInputProps): JSX.Element;\nfunction DateInput(props: DateRangeInputProps): JSX.Element;\nfunction DateInput({\n\tplaceholder,\n\tdisabled,\n\terror,\n\tonClearError,\n\tminDate,\n\tmaxDate,\n\tdatePickerLevel,\n\tselectionMode: controlledSelectionMode,\n\tweekEndDay = \"sunday\",\n\tallowSelectionModeChange,\n\tselectionModeOptions,\n\tonSelectionModeChange,\n\t...props\n}: DateInputProps) {\n\tconst [open, setOpen] = useState(false);\n\tconst [uncontrolledSelectionMode, setUncontrolledSelectionMode] = useState<DateInputSelectionMode>(controlledSelectionMode ?? \"day\");\n\tconst selectionMode = controlledSelectionMode ?? uncontrolledSelectionMode;\n\tconst minDatePickerLevel = datePickerLevel ?? \"day\";\n\tconst preferredCalendarType = resolveAvailableDatePickerLevel(selectionMode, minDatePickerLevel);\n\tconst [calendarTypeState, setCalendarTypeState] = useState<CalendarTypeState>(() => ({\n\t\tview: preferredCalendarType,\n\t\tselectionMode,\n\t\tminDatePickerLevel\n\t}));\n\tconst calendarType =\n\t\tcalendarTypeState.selectionMode === selectionMode &&\n\t\tcalendarTypeState.minDatePickerLevel === minDatePickerLevel &&\n\t\tisDatePickerLevelAvailable(calendarTypeState.view, minDatePickerLevel)\n\t\t\t? calendarTypeState.view\n\t\t\t: preferredCalendarType;\n\n\tconst initialDateRef = useRef(props.value);\n\tconst dateInputValueOptions = {\n\t\tselectionMode,\n\t\tweekEndDay\n\t};\n\n\tconst { inputValue, setInputValue, selectedDate, setSelectedDate, handleSelect, formatDate, parseDate } = useDateInput({\n\t\t...props,\n\t\tdatePickerLevel: minDatePickerLevel,\n\t\tselectionMode,\n\t\tweekEndDay\n\t});\n\tconst rangeOnChange = props.selectsRange ? props.onChange : undefined;\n\n\tconst updateCalendarType = useCallback(\n\t\t(calendarType: DatePickerLevel) => {\n\t\t\tif (isDatePickerLevelAvailable(calendarType, minDatePickerLevel)) {\n\t\t\t\tsetCalendarTypeState({\n\t\t\t\t\tview: calendarType,\n\t\t\t\t\tselectionMode,\n\t\t\t\t\tminDatePickerLevel\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t[minDatePickerLevel, selectionMode]\n\t);\n\n\tuseEffect(() => {\n\t\tinitialDateRef.current = props.value;\n\t}, [props.value]);\n\n\tconst handleInputBlur = () => {\n\t\tif (inputValue) {\n\t\t\tconst parsedDate = parseDate(inputValue);\n\t\t\tif (parsedDate) {\n\t\t\t\tsetInputValue(formatDate(parsedDate));\n\n\t\t\t\tif (props.selectsRange && isDateRangeTuple(parsedDate)) {\n\t\t\t\t\tconst selectedRange = isDateRangeTuple(selectedDate) ? selectedDate : null;\n\n\t\t\t\t\tif (areRangeDateValuesEqual(parsedDate, selectedRange, dateInputValueOptions)) return;\n\n\t\t\t\t\tsetSelectedDate(parsedDate);\n\t\t\t\t\tprops.onChange(parsedDate);\n\t\t\t\t} else if (!props.selectsRange && parsedDate instanceof Date) {\n\t\t\t\t\tconst selectedSingleDate = selectedDate instanceof Date ? selectedDate : null;\n\n\t\t\t\t\tif (areSingleDateValuesEqual(parsedDate, selectedSingleDate, dateInputValueOptions)) return;\n\n\t\t\t\t\tsetSelectedDate(parsedDate);\n\t\t\t\t\tprops.onChange(parsedDate);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tconst handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n\t\tif (event.key === \"Enter\") {\n\t\t\tevent.preventDefault();\n\t\t\thandleInputBlur();\n\t\t}\n\t};\n\n\tconst handleCalendarDateSelect = useCallback(\n\t\t(value: Date | NullableDateRange) => {\n\t\t\tif (handleSelect(value)) {\n\t\t\t\tsetOpen(false);\n\t\t\t}\n\t\t},\n\t\t[handleSelect]\n\t);\n\n\tconst handleSelectionModeChange = useCallback(\n\t\t(nextSelectionMode: DateInputSelectionMode) => {\n\t\t\tif (controlledSelectionMode === undefined) {\n\t\t\t\tsetUncontrolledSelectionMode(nextSelectionMode);\n\t\t\t}\n\n\t\t\tonSelectionModeChange?.(nextSelectionMode);\n\t\t\tsetCalendarTypeState({\n\t\t\t\tview: resolveAvailableDatePickerLevel(nextSelectionMode, minDatePickerLevel),\n\t\t\t\tselectionMode: nextSelectionMode,\n\t\t\t\tminDatePickerLevel\n\t\t\t});\n\t\t},\n\t\t[controlledSelectionMode, minDatePickerLevel, onSelectionModeChange]\n\t);\n\n\tconst handleCancel = useCallback(() => {\n\t\t// Восстановить исходное состояние при отмене\n\t\tif (rangeOnChange) {\n\t\t\tconst [, selectedEndDate] = isDateRangeTuple(selectedDate) ? selectedDate : [null, null];\n\n\t\t\tif (!selectedEndDate) {\n\t\t\t\t// Восстановить исходное состояние диапазона\n\t\t\t\tconst initialValue = initialDateRef.current;\n\t\t\t\tconst initialRange = Array.isArray(initialValue) ? initialValue : null;\n\t\t\t\tconst initialStart = initialRange?.[0] ?? null;\n\t\t\t\tconst initialEnd = initialRange?.[1] ?? null;\n\n\t\t\t\tif (initialStart && initialEnd) {\n\t\t\t\t\tconst initialSelectedDate: NullableDateRange = [initialStart, initialEnd];\n\t\t\t\t\tsetSelectedDate(initialSelectedDate);\n\t\t\t\t\tsetInputValue(formatDate(initialSelectedDate));\n\n\t\t\t\t\trangeOnChange(initialSelectedDate);\n\t\t\t\t} else {\n\t\t\t\t\t// Если начального диапазона нет, очистить всё\n\t\t\t\t\tsetSelectedDate([null, null]);\n\t\t\t\t\tsetInputValue(\"\");\n\n\t\t\t\t\trangeOnChange([null, null]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}, [rangeOnChange, selectedDate, setSelectedDate, setInputValue, formatDate]);\n\n\tconst availableSelectionModes = resolveSelectionModeOptions(selectionModeOptions, selectionMode);\n\tconst showSelectionModeControl = allowSelectionModeChange && availableSelectionModes.length > 1;\n\n\treturn (\n\t\t<Popover\n\t\t\topen={open}\n\t\t\tonOpenChange={(value) => {\n\t\t\t\tsetOpen(value);\n\t\t\t\tif (!value) {\n\t\t\t\t\thandleCancel();\n\t\t\t\t}\n\t\t\t}}>\n\t\t\t<InputText\n\t\t\t\tlabel={props.label}\n\t\t\t\tdescription={props.description}\n\t\t\t\tsize={props.size}\n\t\t\t\tvalue={inputValue}\n\t\t\t\tonChange={setInputValue}\n\t\t\t\tonBlur={handleInputBlur}\n\t\t\t\tonKeyUp={handleKeyDown}\n\t\t\t\tplaceholder={placeholder}\n\t\t\t\tdisabled={disabled}\n\t\t\t\terror={error}\n\t\t\t\tonClearError={onClearError}\n\t\t\t\tendAdornmentWidth=\"var(--control-height)\"\n\t\t\t\tendAdornment={\n\t\t\t\t\t<Popover.Trigger>\n\t\t\t\t\t\t<div className={uiStyles.uiToggleButtonContainer}>\n\t\t\t\t\t\t\t<button type=\"button\" disabled={disabled} aria-label=\"Открыть календарь\" className={uiStyles.uiToggleButton}>\n\t\t\t\t\t\t\t\t<CalendarDaysIcon />\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</Popover.Trigger>\n\t\t\t\t}\n\t\t\t/>\n\n\t\t\t<Popover.Content background=\"primary\">\n\t\t\t\t<CalendarView\n\t\t\t\t\tview={calendarType}\n\t\t\t\t\tdatePickerLevel={minDatePickerLevel}\n\t\t\t\t\tselectionMode={selectionMode}\n\t\t\t\t\tweekEndDay={weekEndDay}\n\t\t\t\t\tonViewChange={updateCalendarType}\n\t\t\t\t\tvalue={selectedDate ?? null}\n\t\t\t\t\tonChange={handleCalendarDateSelect}\n\t\t\t\t\tminDate={minDate}\n\t\t\t\t\tmaxDate={maxDate}\n\t\t\t\t\tselectsRange={!!props.selectsRange}\n\t\t\t\t/>\n\t\t\t\t{showSelectionModeControl && (\n\t\t\t\t\t<div className={styles.selectionModeControl}>\n\t\t\t\t\t\t<RadioGroup<DateInputSelectionMode>\n\t\t\t\t\t\t\tvalue={selectionMode}\n\t\t\t\t\t\t\tonChange={handleSelectionModeChange}\n\t\t\t\t\t\t\tnoWrap\n\t\t\t\t\t\t\taria-label=\"Режим выбора даты\">\n\t\t\t\t\t\t\t{availableSelectionModes.map((mode) => (\n\t\t\t\t\t\t\t\t<RadioGroup.Option key={mode} value={mode} label={selectionModeLabels[mode]} />\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</RadioGroup>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</Popover.Content>\n\t\t</Popover>\n\t);\n}\n\nexport function SingleDateInput(props: Omit<DateSingleInputProps, \"selectsRange\">) {\n\treturn <DateInput {...props} />;\n}\n\nexport function RangeDateInput(props: Omit<DateRangeInputProps, \"selectsRange\">) {\n\treturn <DateInput {...props} selectsRange={true} />;\n}\n"],"mappings":";;;;;;;;;;AAkBA,IAAa,IAA4B,EAA0B,MAKtD,IAA4B,cAEnC,IAAkB;AA8BxB,SAAS,EAA0B,GAAqD;CASvF,OARI,EAAQ,kBAAkB,SAAS,EAAQ,kBAAkB,SACzD,QAGJ,EAAQ,kBAAkB,WAAW,EAAQ,kBAAkB,SAC3D,EAAQ,gBAGT,EAAQ,mBAAmB;AACnC;AAEA,SAAS,EAA6B,GAAwD;CAC7F,OAAO;EACN,eAAe,GAAS;EACxB,YAAY,GAAS;CACtB;AACD;AAKA,SAAS,EACR,GACA,GACwB;CAexB,OAdI,OAAO,KAAoB,YAAY,MAAoB,KAAA,IACvD;EACN,YAAY;EACZ;CACD,IAGG,KAAmB,EAAgB,oBAAoB,KAAA,IACnD;EACN,GAAG;EACH;CACD,IAGM;AACR;AAKA,SAAS,EAA2B,GAA6B;CAChE,IAAM,IAAqB,EAAsB,GAAY,CAAyB;CACtF,OAAO,EAAc,CAAkB,IAAI,IAAqB;AACjE;AAKA,SAAS,EAAmB,GAAe,GAA6C;CACvF,OACC,EAAkB,GAAO,EAA2B,EAAQ,UAAU,GAAG;EACxE,eAAe;EACf,WAAW,EAA0B,CAAO;EAC5C,eAAe,EAAQ;CACxB,CAAC,CAAC,EAAE,QAAQ;AAEd;AAKA,SAAgB,EAAyB,GAAmB,GAA8C;CACzG,OAAO,EAAkB,GAAM,EAA6B,CAAO,CAAC,CAAC,EAAE,SAAS;AACjF;AAKA,SAAgB,EAAwB,GAAiC,GAA2D;CACnI,IAAI,CAAC,EAAiB,CAAK,GAAG,OAAO;CAErC,IAAM,CAAC,GAAW,KAAW;CAC7B,OAAO,CAAC,EAAyB,GAAW,CAAO,GAAG,EAA2B,GAAS,CAAO,CAAC;AACnG;AAKA,SAAgB,EAA2B,GAAmB,GAA8C;CAC3G,OAAO,EAAkB,GAAM,EAA6B,CAAO,CAAC,CAAC,EAAE,OAAO;AAC/E;AAEA,SAAS,EAAY,GAAkC;CACtD,OAAO,GAAM,QAAQ,KAAK;AAC3B;AAKA,SAAgB,EAAyB,GAAmB,GAAoB,GAA0C;CACzH,OAAO,EAAY,EAAyB,GAAM,CAAO,CAAC,MAAM,EAAY,EAAyB,GAAO,CAAO,CAAC;AACrH;AAKA,SAAgB,EACf,GACA,GACA,GACU;CACV,IAAM,IAAiB,EAAwB,GAAM,CAAO,GACtD,IAAkB,EAAwB,GAAO,CAAO;CAE9D,OACC,EAAY,IAAiB,MAAM,IAAI,MAAM,EAAY,IAAkB,MAAM,IAAI,KACrF,EAAY,IAAiB,MAAM,IAAI,MAAM,EAAY,IAAkB,MAAM,IAAI;AAEvF;AAKA,SAAgB,EACf,GACA,GACA,GACS;CACT,IAAI,CAAC,GAAM,OAAO;CAElB,IAAM,IAAU,EAA+B,GAAiB,CAAe,GACzE,IAAS,EAAkB,GAAM,EAA6B,CAAO,CAAC;CAS5E,OANI,EAAQ,kBAAkB,UAAU,IAChC,EAAgB,EAAO,OAAO,EAAO,KAAK,EAA2B,EAAQ,UAAU,GAAG,EAChG,WAAW,EAA0B,CAAO,EAC7C,CAAC,IAGK,EAAW,GAAM,EAA2B,EAAQ,UAAU,GAAG,EACvE,WAAW,EAA0B,CAAO,EAC7C,CAAC;AACF;AAKA,SAAgB,EACf,GACA,GACA,GACS;CACT,IAAI,CAAC,EAAiB,CAAK,GAAG,OAAO;CAErC,IAAM,IAAU,EAA+B,GAAiB,CAAe,GACzE,CAAC,GAAW,KAAW;CAa7B,OAZI,KAAa,IACT,EAAgB,GAAW,GAAS,EAA2B,EAAQ,UAAU,GAAG,EAC1F,WAAW,EAA0B,CAAO,EAC7C,CAAC,IAGE,IACI,GAAG,EAAW,GAAW,EAA2B,EAAQ,UAAU,GAAG,EAC/E,WAAW,EAA0B,CAAO,EAC7C,CAAC,IAAI,MAGC;AACR;AAKA,SAAgB,EACf,GACA,GACA,GACS;CAKT,OAJI,EAAiB,CAAK,IAClB,EAAqB,GAAO,GAAiB,CAAe,IAG7D,EAAsB,GAAO,GAAiB,CAAe;AACrE;AAKA,SAAgB,EACf,GACA,GACA,GACc;CACd,IAAM,IAAU,EAA+B,GAAiB,CAAe;CAI/E,OAAO,EAAyB,EAFZ,EAAQ,kBAAkB,SAAU,EAAM,MAAM,CAAe,CAAC,CAAC,MAAM,KAAM,GAEjC,CAAO,GAAG,CAAO;AAClF;AAKA,SAAgB,EACf,GACA,GACA,GACoB;CACpB,IAAM,IAAU,EAA+B,GAAiB,CAAe,GACzE,CAAC,IAAY,IAAI,IAAU,MAAM,EAAM,MAAM,CAAe;CAElE,OAAO,CAAC,EAAqB,GAAW,CAAO,GAAG,EAAuB,GAAS,CAAO,CAAC;AAC3F;AAKA,SAAgB,EACf,GACA,GACA,GACc;CACd,IAAM,IAAU,EAA+B,GAAiB,CAAe;CAC/E,OAAO,EAA2B,EAAmB,GAAO,CAAO,GAAG,CAAO;AAC9E;;;ACtQA,SAAS,EAAqB,GAA0D;CAKvF,OAJI,EAAiB,CAAK,IAClB,EAAM,MAAM,EAAM,MAAM,KAAA,IAGzB,KAAS,KAAA;AACjB;AAKA,IAAa,KAAgB,MAA8B;CAC1D,IAAM,IAAuB,QAAc;EAC1C,IAAM,IAA0C;GAC/C,eAAe,EAAQ;GACvB,YAAY,EAAQ;EACrB;EAMA,OAJI,EAAQ,eACJ,EAAwB,EAAQ,OAAmC,CAAgB,IAGpF,EAAyB,EAAQ,OAAsB,CAAgB;CAC/E,GAAG;EAAC,EAAQ;EAAc,EAAQ;EAAe,EAAQ;EAAO,EAAQ;CAAU,CAAC,GAC7E,IAAgB,SACd;EACN,YAAY,EAAQ;EACpB,iBAAiB,EAAQ;EACzB,eAAe,EAAQ;EACvB,YAAY,EAAQ;CACrB,IACA;EAAC,EAAQ;EAAiB,EAAQ;EAAY,EAAQ;EAAe,EAAQ;CAAU,CACxF,GACM,IAAqB,EAAqB,GAAsB,CAAa,GAC7E,IAAyB,KAAK,UAAU;EAC7C,EAAQ;EACR,EAAQ,cAAc;EACtB,EAAQ,mBAAmB;EAC3B,EAAQ,iBAAiB;EACzB,EAAQ,cAAc;EACtB,EAAiB,CAAoB,IAClC,CAAC,EAAqB,EAAE,EAAE,QAAQ,KAAK,MAAM,EAAqB,EAAE,EAAE,QAAQ,KAAK,IAAI,IACtF,GAAsB,QAAQ,KAAK;CACxC,CAAC,GACK,CAAC,GAAY,KAAiB,SAAgB;EACnD,iBAAiB;EACjB,cAAc;EACd,YAAY;CACb,EAAE,GACI,IAAkB,EAAW,oBAAoB,GACjD,IAAe,IAAkB,EAAW,eAAe,GAC3D,IAAa,IAAkB,EAAW,aAAa,GAMvD,KAAiB,MAA2B;EACjD,GAAe,MAAiB;GAC/B,IAAM,IACL,EAAa,oBAAoB,IAAyB,EAAa,eAAe;GAEvF,OAAO;IACN,iBAAiB;IACjB,cAAc;IACd,YAAY;GACb;EACD,CAAC;CACF,GAKM,KAAmB,MAAsD;EAC9E,GAAe,MAAiB;GAC/B,IAAM,IACL,EAAa,oBAAoB,IAAyB,EAAa,aAAa;GAErF,OAAO;IACN,iBAAiB;IACjB,cAAc;IACd,YAAY;GACb;EACD,CAAC;CACF,GAKM,KAAe,MAAmD,EAAqB,GAAO,CAAa;CAyEjH,OAAO;EACN;EACA;EACA;EACA;EACA,eAzDqB,MAAmC;GACxD,IAAM,CAAC,GAAmB,KAAoB,MAAM,QAAQ,CAAI,IAAI,IAAO,CAAC,GAAM,IAAI;GAEtF,IAAI,EAAQ,cAAc;IACzB,IAAM,IAAsB,EAAyB,GAAmB,CAAa,GAC/E,IAAoB,EAA2B,GAAiB,CAAa;IAEnF,IAAI,KAAuB,GAAmB;KAC7C,IAAI,IAAoB,GAAqB;MAC5C,IAAM,IAAkC,CACvC,EAAyB,GAAiB,CAAa,GACvD,EAA2B,GAAmB,CAAa,CAC5D;MAMA,AALA,EAAc;OACb,iBAAiB;OACjB,cAAc;OACd,YAAY,EAAY,CAAY;MACrC,CAAC,GACD,EAAQ,SAAS,CAAY;KAC9B,OAAO;MACN,IAAM,IAA+B,CAAC,GAAqB,CAAiB;MAM5E,AALA,EAAc;OACb,iBAAiB;OACjB,cAAc;OACd,YAAY,EAAY,CAAS;MAClC,CAAC,GACD,EAAQ,SAAS,CAAS;KAC3B;KAEA,OAAO;IACR;IAEA,IAAM,IAA+B,CAAC,GAAqB,IAAI;IAM/D,OALA,EAAc;KACb,iBAAiB;KACjB,cAAc;KACd,YAAY,EAAY,CAAS;IAClC,CAAC,GACM;GACR;GAEA,IAAM,IAAiB,EAAyB,GAAmB,CAAa;GAQhF,OAPA,EAAc;IACb,iBAAiB;IACjB,cAAc;IACd,YAAY,EAAY,CAAc;GACvC,CAAC,GACD,EAAQ,SAAS,CAAc,GAExB;EACR;EAQC,YAAY;EACZ,YA3EkB,MAAwD;GAC1E,IAAM,IAAsC;IAC3C,GAAG;IACH,eAAe,EAAqB,CAAY;GACjD;GAMA,OAJI,EAAQ,eACJ,EAAoB,GAAY,CAAY,IAG7C,EAAqB,GAAY,CAAY;EACrD;CAiEA;AACD,2CE/GM,IAA8D;CACnE,KAAK;CACL,MAAM;CACN,OAAO;CACP,MAAM;AACP;AAEA,SAAS,EACR,GACA,GACoC;CACpC,IAAM,IAAe,IAAI,IAAI,GAAsB,SAAS,IAAuB,CAA0B;CAG7G,OAFA,EAAa,IAAI,CAAa,GAEvB,EAA2B,QAAQ,MAAS,EAAa,IAAI,CAAI,CAAC;AAC1E;AAIA,SAAS,EAAU,EAClB,gBACA,aACA,UACA,iBACA,YACA,YACA,oBACA,eAAe,GACf,gBAAa,UACb,6BACA,yBACA,0BACA,GAAG,KACe;CAClB,IAAM,CAAC,GAAM,KAAW,EAAS,EAAK,GAChC,CAAC,GAA2B,KAAgC,EAAiC,KAA2B,KAAK,GAC7H,IAAgB,KAA2B,GAC3C,IAAqB,KAAmB,OACxC,IAAwB,EAAgC,GAAe,CAAkB,GACzF,CAAC,GAAmB,KAAwB,SAAmC;EACpF,MAAM;EACN;EACA;CACD,EAAE,GACI,IACL,EAAkB,kBAAkB,KACpC,EAAkB,uBAAuB,KACzC,EAA2B,EAAkB,MAAM,CAAkB,IAClE,EAAkB,OAClB,GAEE,IAAiB,EAAO,EAAM,KAAK,GACnC,IAAwB;EAC7B;EACA;CACD,GAEM,EAAE,eAAY,kBAAe,iBAAc,oBAAiB,iBAAc,eAAY,kBAAc,EAAa;EACtH,GAAG;EACH,iBAAiB;EACjB;EACA;CACD,CAAC,GACK,IAAgB,EAAM,eAAe,EAAM,WAAW,KAAA,GAEtD,KAAqB,GACzB,MAAkC;EAClC,AAAI,EAA2B,GAAc,CAAkB,KAC9D,EAAqB;GACpB,MAAM;GACN;GACA;EACD,CAAC;CAEH,GACA,CAAC,GAAoB,CAAa,CACnC;CAEA,QAAgB;EACf,EAAe,UAAU,EAAM;CAChC,GAAG,CAAC,EAAM,KAAK,CAAC;CAEhB,IAAM,UAAwB;EAC7B,IAAI,GAAY;GACf,IAAM,IAAa,GAAU,CAAU;GACvC,IAAI,GAGH;QAFA,EAAc,EAAW,CAAU,CAAC,GAEhC,EAAM,gBAAgB,EAAiB,CAAU,GAAG;KAGvD,IAAI,EAAwB,GAFN,EAAiB,CAAY,IAAI,IAAe,MAEf,CAAqB,GAAG;KAG/E,AADA,EAAgB,CAAU,GAC1B,EAAM,SAAS,CAAU;IAC1B,OAAO,IAAI,CAAC,EAAM,gBAAgB,aAAsB,MAAM;KAG7D,IAAI,EAAyB,GAFF,aAAwB,OAAO,IAAe,MAEZ,CAAqB,GAAG;KAGrF,AADA,EAAgB,CAAU,GAC1B,EAAM,SAAS,CAAU;IAC1B;;EAEF;CACD,GAEM,MAAiB,MAAiD;EACvE,AAAI,EAAM,QAAQ,YACjB,EAAM,eAAe,GACrB,EAAgB;CAElB,GAEM,KAA2B,GAC/B,MAAoC;EACpC,AAAI,EAAa,CAAK,KACrB,EAAQ,EAAK;CAEf,GACA,CAAC,CAAY,CACd,GAEM,KAA4B,GAChC,MAA8C;EAM9C,AALI,MAA4B,KAAA,KAC/B,EAA6B,CAAiB,GAG/C,IAAwB,CAAiB,GACzC,EAAqB;GACpB,MAAM,EAAgC,GAAmB,CAAkB;GAC3E,eAAe;GACf;EACD,CAAC;CACF,GACA;EAAC;EAAyB;EAAoB;CAAqB,CACpE,GAEM,KAAe,QAAkB;EAEtC,IAAI,GAAe;GAClB,IAAM,GAAG,KAAmB,EAAiB,CAAY,IAAI,IAAe,CAAC,MAAM,IAAI;GAEvF,IAAI,CAAC,GAAiB;IAErB,IAAM,IAAe,EAAe,SAC9B,IAAe,MAAM,QAAQ,CAAY,IAAI,IAAe,MAC5D,IAAe,IAAe,MAAM,MACpC,IAAa,IAAe,MAAM;IAExC,IAAI,KAAgB,GAAY;KAC/B,IAAM,IAAyC,CAAC,GAAc,CAAU;KAIxE,AAHA,EAAgB,CAAmB,GACnC,EAAc,EAAW,CAAmB,CAAC,GAE7C,EAAc,CAAmB;IAClC,OAKC,AAHA,EAAgB,CAAC,MAAM,IAAI,CAAC,GAC5B,EAAc,EAAE,GAEhB,EAAc,CAAC,MAAM,IAAI,CAAC;GAE5B;EACD;CACD,GAAG;EAAC;EAAe;EAAc;EAAiB;EAAe;CAAU,CAAC,GAEtE,IAA0B,EAA4B,GAAsB,CAAa,GACzF,KAA2B,KAA4B,EAAwB,SAAS;CAE9F,OACC,kBAAC,GAAD;EACO;EACN,eAAe,MAAU;GAExB,AADA,EAAQ,CAAK,GACR,KACJ,GAAa;EAEf;EAPD,UAAA,CAQC,kBAAC,GAAD;GACC,OAAO,EAAM;GACb,aAAa,EAAM;GACnB,MAAM,EAAM;GACZ,OAAO;GACP,UAAU;GACV,QAAQ;GACR,SAAS;GACI;GACH;GACH;GACO;GACd,mBAAkB;GAClB,cACC,kBAAC,EAAQ,SAAT,EAAA,UACC,kBAAC,OAAD;IAAK,WAAW,EAAS;IACxB,UAAA,kBAAC,UAAD;KAAQ,MAAK;KAAmB;KAAU,cAAW;KAAoB,WAAW,EAAS;KAC5F,UAAA,kBAAC,IAAD,CAAmB,CAAA;IACZ,CAAA;GACJ,CAAA,EACW,CAAA;EAElB,CAAA,GAED,kBAAC,EAAQ,SAAT;GAAiB,YAAW;GAA5B,UAAA,CACC,kBAAC,GAAD;IACC,MAAM;IACN,iBAAiB;IACF;IACH;IACZ,cAAc;IACd,OAAO,KAAgB;IACvB,UAAU;IACD;IACA;IACT,cAAc,CAAC,CAAC,EAAM;GACtB,CAAA,GACA,MACA,kBAAC,OAAD;IAAK,WAAW,EAAO;IACtB,UAAA,kBAAC,GAAD;KACC,OAAO;KACP,UAAU;KACV,QAAA;KACA,cAAW;KACV,UAAA,EAAwB,KAAK,MAC7B,kBAAC,EAAW,QAAZ;MAA8B,OAAO;MAAM,OAAO,EAAoB;KAAQ,GAAtD,CAAsD,CAC9E;IACU,CAAA;GACR,CAAA,CAEU;EACT,CAAA,CAAA;;AAEX;AAEA,SAAgB,EAAgB,GAAmD;CAClF,OAAO,kBAAC,GAAD,EAAW,GAAI,EAAQ,CAAA;AAC/B;AAEA,SAAgB,EAAe,GAAkD;CAChF,OAAO,kBAAC,GAAD;EAAW,GAAI;EAAO,cAAc;CAAO,CAAA;AACnD"}
|
|
1
|
+
{"version":3,"file":"date-input-DEHI8-wq.js","names":[],"sources":["../../src/date-input/lib/dateInputValue.ts","../../src/date-input/model/useDateInput.ts","../../src/date-input/ui/DateInput.module.scss","../../src/date-input/ui/DateInput.tsx"],"sourcesContent":["import {\n\tDEFAULT_DATE_PRESET_NAMES,\n\tformatDate,\n\tformatDateRange,\n\tgetCalendarPeriod,\n\tgetDatePreset,\n\tisDateRangeTuple,\n\tparseDateByFormat,\n\tresolveDateFormatName,\n\ttype CalendarPeriodOptions,\n\ttype DateFormatPrecision,\n\ttype DateRangeInput,\n\ttype NullableDateRange\n} from \"@ryuzaki13/react-foundation-lib/formatters\";\n\n/**\n * Пресет даты по умолчанию для текстового поля.\n */\nexport const DEFAULT_DATE_INPUT_PRESET = DEFAULT_DATE_PRESET_NAMES.date;\n\n/**\n * @deprecated Используйте `DEFAULT_DATE_INPUT_PRESET`.\n */\nexport const DEFAULT_DATE_INPUT_FORMAT = \"dd.MM.yyyy\";\n\nconst RANGE_SEPARATOR = \" - \";\n\nexport type DateInputValueOptions = {\n\t/**\n\t * Имя пресета форматирования даты.\n\t */\n\tdatePreset?: string;\n\t/**\n\t * Точность календарного значения.\n\t */\n\tdatePickerLevel?: DateFormatPrecision;\n\t/**\n\t * Размер периода, который выбирается и нормализуется полем.\n\t */\n\tselectionMode?: CalendarPeriodOptions[\"selectionMode\"];\n\t/**\n\t * Последний включённый день недели для режима выбора недели.\n\t */\n\tweekEndDay?: CalendarPeriodOptions[\"weekEndDay\"];\n\t/**\n\t * Опорная дата для пресетов без года, например `month-long`.\n\t */\n\treferenceDate?: Date;\n};\n\nexport type DateInputValueOptionsInput = string | DateInputValueOptions | undefined;\n\n/**\n * Возвращает точность форматирования поля даты.\n */\nfunction resolveDateInputPrecision(options: DateInputValueOptions): DateFormatPrecision {\n\tif (options.selectionMode === \"day\" || options.selectionMode === \"week\") {\n\t\treturn \"day\";\n\t}\n\n\tif (options.selectionMode === \"month\" || options.selectionMode === \"year\") {\n\t\treturn options.selectionMode;\n\t}\n\n\treturn options.datePickerLevel ?? \"day\";\n}\n\nfunction resolveCalendarPeriodOptions(options?: DateInputValueOptions): CalendarPeriodOptions {\n\treturn {\n\t\tselectionMode: options?.selectionMode,\n\t\tweekEndDay: options?.weekEndDay\n\t};\n}\n\n/**\n * Нормализует объектные опции и позиционный вызов с именем пресета.\n */\nfunction normalizeDateInputValueOptions(\n\toptionsOrPreset?: DateInputValueOptionsInput,\n\tdatePickerLevel?: DateFormatPrecision\n): DateInputValueOptions {\n\tif (typeof optionsOrPreset === \"string\" || optionsOrPreset === undefined) {\n\t\treturn {\n\t\t\tdatePreset: optionsOrPreset,\n\t\t\tdatePickerLevel\n\t\t};\n\t}\n\n\tif (datePickerLevel && optionsOrPreset.datePickerLevel === undefined) {\n\t\treturn {\n\t\t\t...optionsOrPreset,\n\t\t\tdatePickerLevel\n\t\t};\n\t}\n\n\treturn optionsOrPreset;\n}\n\n/**\n * Проверяет новый `datePreset` и возвращает только зарегистрированное имя пресета.\n */\nfunction resolveDateInputPresetName(datePreset?: string): string {\n\tconst resolvedPresetName = resolveDateFormatName(datePreset, DEFAULT_DATE_INPUT_PRESET);\n\treturn getDatePreset(resolvedPresetName) ? resolvedPresetName : DEFAULT_DATE_INPUT_PRESET;\n}\n\n/**\n * Приводит результат универсального парсинга к календарной дате.\n */\nfunction parseDateTimeValue(value: string, options: DateInputValueOptions): Date | null {\n\treturn (\n\t\tparseDateByFormat(value, resolveDateInputPresetName(options.datePreset), {\n\t\t\tdefaultFormat: DEFAULT_DATE_INPUT_PRESET,\n\t\t\tprecision: resolveDateInputPrecision(options),\n\t\t\treferenceDate: options.referenceDate\n\t\t})?.date ?? null\n\t);\n}\n\n/**\n * Приводит одиночную дату к началу выбранного календарного периода.\n */\nexport function normalizeSingleDateValue(date: Date | null, options?: DateInputValueOptions): Date | null {\n\treturn getCalendarPeriod(date, resolveCalendarPeriodOptions(options))?.start ?? null;\n}\n\n/**\n * Приводит диапазон дат к границам выбранных календарных периодов.\n */\nexport function normalizeRangeDateValue(range: NullableDateRange | null, options?: DateInputValueOptions): NullableDateRange | null {\n\tif (!isDateRangeTuple(range)) return null;\n\n\tconst [startDate, endDate] = range;\n\treturn [normalizeSingleDateValue(startDate, options), normalizeRangeEndDateValue(endDate, options)];\n}\n\n/**\n * Приводит конечную дату диапазона к концу выбранного календарного периода.\n */\nexport function normalizeRangeEndDateValue(date: Date | null, options?: DateInputValueOptions): Date | null {\n\treturn getCalendarPeriod(date, resolveCalendarPeriodOptions(options))?.end ?? null;\n}\n\nfunction getDateTime(date: Date | null): number | null {\n\treturn date?.getTime() ?? null;\n}\n\n/**\n * Сравнивает одиночные даты после нормализации к точности поля ввода.\n */\nexport function areSingleDateValuesEqual(left: Date | null, right: Date | null, options?: DateInputValueOptions): boolean {\n\treturn getDateTime(normalizeSingleDateValue(left, options)) === getDateTime(normalizeSingleDateValue(right, options));\n}\n\n/**\n * Сравнивает диапазоны дат после нормализации к границам выбранных периодов.\n */\nexport function areRangeDateValuesEqual(\n\tleft: NullableDateRange | null,\n\tright: NullableDateRange | null,\n\toptions?: DateInputValueOptions\n): boolean {\n\tconst normalizedLeft = normalizeRangeDateValue(left, options);\n\tconst normalizedRight = normalizeRangeDateValue(right, options);\n\n\treturn (\n\t\tgetDateTime(normalizedLeft?.[0] ?? null) === getDateTime(normalizedRight?.[0] ?? null) &&\n\t\tgetDateTime(normalizedLeft?.[1] ?? null) === getDateTime(normalizedRight?.[1] ?? null)\n\t);\n}\n\n/**\n * Форматирует одиночную дату для текстового поля.\n */\nexport function formatSingleDateValue(\n\tdate: Date | null,\n\toptionsOrPreset?: DateInputValueOptionsInput,\n\tdatePickerLevel?: DateFormatPrecision\n): string {\n\tif (!date) return \"\";\n\n\tconst options = normalizeDateInputValueOptions(optionsOrPreset, datePickerLevel);\n\tconst period = getCalendarPeriod(date, resolveCalendarPeriodOptions(options));\n\n\t// Single-поле хранит начало недели, но показывает обе включительные границы выбранного периода.\n\tif (options.selectionMode === \"week\" && period) {\n\t\treturn formatDateRange(period.start, period.end, resolveDateInputPresetName(options.datePreset), {\n\t\t\tprecision: resolveDateInputPrecision(options)\n\t\t});\n\t}\n\n\treturn formatDate(date, resolveDateInputPresetName(options.datePreset), {\n\t\tprecision: resolveDateInputPrecision(options)\n\t});\n}\n\n/**\n * Форматирует диапазон дат для текстового поля.\n */\nexport function formatRangeDateValue(\n\trange: NullableDateRange | null,\n\toptionsOrPreset?: DateInputValueOptionsInput,\n\tdatePickerLevel?: DateFormatPrecision\n): string {\n\tif (!isDateRangeTuple(range)) return \"\";\n\n\tconst options = normalizeDateInputValueOptions(optionsOrPreset, datePickerLevel);\n\tconst [startDate, endDate] = range;\n\tif (startDate && endDate) {\n\t\treturn formatDateRange(startDate, endDate, resolveDateInputPresetName(options.datePreset), {\n\t\t\tprecision: resolveDateInputPrecision(options)\n\t\t});\n\t}\n\n\tif (startDate) {\n\t\treturn `${formatDate(startDate, resolveDateInputPresetName(options.datePreset), {\n\t\t\tprecision: resolveDateInputPrecision(options)\n\t\t})}${RANGE_SEPARATOR}`;\n\t}\n\n\treturn \"\";\n}\n\n/**\n * Унифицирует форматирование значения поля даты.\n */\nexport function formatDateInputValue(\n\tvalue: DateRangeInput,\n\toptionsOrPreset?: DateInputValueOptionsInput,\n\tdatePickerLevel?: DateFormatPrecision\n): string {\n\tif (isDateRangeTuple(value)) {\n\t\treturn formatRangeDateValue(value, optionsOrPreset, datePickerLevel);\n\t}\n\n\treturn formatSingleDateValue(value, optionsOrPreset, datePickerLevel);\n}\n\n/**\n * Парсит строку одиночной даты по заданному пресету.\n */\nexport function parseSingleDateValue(\n\tvalue: string,\n\toptionsOrPreset?: DateInputValueOptionsInput,\n\tdatePickerLevel?: DateFormatPrecision\n): Date | null {\n\tconst options = normalizeDateInputValueOptions(optionsOrPreset, datePickerLevel);\n\t// Для отображаемого диапазона single-week источником значения остаётся его первая граница.\n\tconst singleValue = options.selectionMode === \"week\" ? (value.split(RANGE_SEPARATOR)[0] ?? \"\") : value;\n\n\treturn normalizeSingleDateValue(parseDateTimeValue(singleValue, options), options);\n}\n\n/**\n * Парсит строку диапазона дат по заданному пресету.\n */\nexport function parseRangeDateValue(\n\tvalue: string,\n\toptionsOrPreset?: DateInputValueOptionsInput,\n\tdatePickerLevel?: DateFormatPrecision\n): NullableDateRange {\n\tconst options = normalizeDateInputValueOptions(optionsOrPreset, datePickerLevel);\n\tconst [startPart = \"\", endPart = \"\"] = value.split(RANGE_SEPARATOR);\n\n\treturn [parseSingleDateValue(startPart, options), parseRangeEndDateValue(endPart, options)];\n}\n\n/**\n * Парсит конечную дату диапазона и нормализует её к концу суток.\n */\nexport function parseRangeEndDateValue(\n\tvalue: string,\n\toptionsOrPreset?: DateInputValueOptionsInput,\n\tdatePickerLevel?: DateFormatPrecision\n): Date | null {\n\tconst options = normalizeDateInputValueOptions(optionsOrPreset, datePickerLevel);\n\treturn normalizeRangeEndDateValue(parseDateTimeValue(value, options), options);\n}\n","import { useMemo, useState } from \"react\";\n\nimport { isDateRangeTuple, type NullableDateRange } from \"@ryuzaki13/react-foundation-lib/formatters\";\n\nimport {\n\tDateInputValueOptions,\n\tformatDateInputValue,\n\tnormalizeRangeDateValue,\n\tnormalizeRangeEndDateValue,\n\tnormalizeSingleDateValue,\n\tparseRangeDateValue,\n\tparseSingleDateValue,\n\ttype DateInputOptions\n} from \"../lib\";\n\nfunction resolveReferenceDate(value: Date | NullableDateRange | null): Date | undefined {\n\tif (isDateRangeTuple(value)) {\n\t\treturn value[0] ?? value[1] ?? undefined;\n\t}\n\n\treturn value ?? undefined;\n}\n\n/**\n * Хук управляет текстовым представлением и выбранным значением поля даты.\n */\nexport const useDateInput = (options: DateInputOptions) => {\n\tconst externalSelectedDate = useMemo(() => {\n\t\tconst selectionOptions: DateInputValueOptions = {\n\t\t\tselectionMode: options.selectionMode,\n\t\t\tweekEndDay: options.weekEndDay\n\t\t};\n\n\t\tif (options.selectsRange) {\n\t\t\treturn normalizeRangeDateValue(options.value as NullableDateRange | null, selectionOptions);\n\t\t}\n\n\t\treturn normalizeSingleDateValue(options.value as Date | null, selectionOptions);\n\t}, [options.selectsRange, options.selectionMode, options.value, options.weekEndDay]);\n\tconst formatOptions = useMemo<DateInputValueOptions>(\n\t\t() => ({\n\t\t\tdatePreset: options.datePreset,\n\t\t\tdatePickerLevel: options.datePickerLevel,\n\t\t\tselectionMode: options.selectionMode,\n\t\t\tweekEndDay: options.weekEndDay\n\t\t}),\n\t\t[options.datePickerLevel, options.datePreset, options.selectionMode, options.weekEndDay]\n\t);\n\tconst externalInputValue = formatDateInputValue(externalSelectedDate, formatOptions);\n\tconst externalStateSignature = JSON.stringify([\n\t\toptions.selectsRange,\n\t\toptions.datePreset ?? null,\n\t\toptions.datePickerLevel ?? null,\n\t\toptions.selectionMode ?? null,\n\t\toptions.weekEndDay ?? null,\n\t\tisDateRangeTuple(externalSelectedDate)\n\t\t\t? [externalSelectedDate[0]?.getTime() ?? null, externalSelectedDate[1]?.getTime() ?? null]\n\t\t\t: (externalSelectedDate?.getTime() ?? null)\n\t]);\n\tconst [draftState, setDraftState] = useState(() => ({\n\t\tsourceSignature: externalStateSignature,\n\t\tselectedDate: externalSelectedDate,\n\t\tinputValue: externalInputValue\n\t}));\n\tconst hasCurrentDraft = draftState.sourceSignature === externalStateSignature;\n\tconst selectedDate = hasCurrentDraft ? draftState.selectedDate : externalSelectedDate;\n\tconst inputValue = hasCurrentDraft ? draftState.inputValue : externalInputValue;\n\n\t/**\n\t * Сохраняет пользовательский текст только относительно текущего controlled-снимка.\n\t * При внешней смене value или формата отображение сразу выводится из новых props.\n\t */\n\tconst setInputValue = (nextInputValue: string) => {\n\t\tsetDraftState((currentState) => {\n\t\t\tconst currentSelectedDate =\n\t\t\t\tcurrentState.sourceSignature === externalStateSignature ? currentState.selectedDate : externalSelectedDate;\n\n\t\t\treturn {\n\t\t\t\tsourceSignature: externalStateSignature,\n\t\t\t\tselectedDate: currentSelectedDate,\n\t\t\t\tinputValue: nextInputValue\n\t\t\t};\n\t\t});\n\t};\n\n\t/**\n\t * Обновляет локальный незавершённый выбор, не зеркаля controlled value через effect.\n\t */\n\tconst setSelectedDate = (nextSelectedDate: Date | NullableDateRange | null) => {\n\t\tsetDraftState((currentState) => {\n\t\t\tconst currentInputValue =\n\t\t\t\tcurrentState.sourceSignature === externalStateSignature ? currentState.inputValue : externalInputValue;\n\n\t\t\treturn {\n\t\t\t\tsourceSignature: externalStateSignature,\n\t\t\t\tselectedDate: nextSelectedDate,\n\t\t\t\tinputValue: currentInputValue\n\t\t\t};\n\t\t});\n\t};\n\n\t/**\n\t * Форматирует значение поля даты согласно текущему пресету.\n\t */\n\tconst formatValue = (value: Date | NullableDateRange | null): string => formatDateInputValue(value, formatOptions);\n\n\t/**\n\t * Парсит строковое значение поля в дату или диапазон дат.\n\t */\n\tconst parseDate = (dateString: string): Date | NullableDateRange | null => {\n\t\tconst parseOptions: DateInputValueOptions = {\n\t\t\t...formatOptions,\n\t\t\treferenceDate: resolveReferenceDate(selectedDate)\n\t\t};\n\n\t\tif (options.selectsRange) {\n\t\t\treturn parseRangeDateValue(dateString, parseOptions);\n\t\t}\n\n\t\treturn parseSingleDateValue(dateString, parseOptions);\n\t};\n\n\t/**\n\t * Обрабатывает выбор даты из календаря.\n\t */\n\tconst handleSelect = (date: Date | NullableDateRange) => {\n\t\tconst [selectedStartDate, selectedEndDate] = (Array.isArray(date) ? date : [date, null]) as NullableDateRange;\n\n\t\tif (options.selectsRange) {\n\t\t\tconst normalizedStartDate = normalizeSingleDateValue(selectedStartDate, formatOptions);\n\t\t\tconst normalizedEndDate = normalizeRangeEndDateValue(selectedEndDate, formatOptions);\n\n\t\t\tif (normalizedStartDate && normalizedEndDate) {\n\t\t\t\tif (normalizedEndDate < normalizedStartDate) {\n\t\t\t\t\tconst swappedRange: NullableDateRange = [\n\t\t\t\t\t\tnormalizeSingleDateValue(selectedEndDate, formatOptions),\n\t\t\t\t\t\tnormalizeRangeEndDateValue(selectedStartDate, formatOptions)\n\t\t\t\t\t];\n\t\t\t\t\tsetDraftState({\n\t\t\t\t\t\tsourceSignature: externalStateSignature,\n\t\t\t\t\t\tselectedDate: swappedRange,\n\t\t\t\t\t\tinputValue: formatValue(swappedRange)\n\t\t\t\t\t});\n\t\t\t\t\toptions.onChange(swappedRange);\n\t\t\t\t} else {\n\t\t\t\t\tconst nextRange: NullableDateRange = [normalizedStartDate, normalizedEndDate];\n\t\t\t\t\tsetDraftState({\n\t\t\t\t\t\tsourceSignature: externalStateSignature,\n\t\t\t\t\t\tselectedDate: nextRange,\n\t\t\t\t\t\tinputValue: formatValue(nextRange)\n\t\t\t\t\t});\n\t\t\t\t\toptions.onChange(nextRange);\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tconst nextRange: NullableDateRange = [normalizedStartDate, null];\n\t\t\tsetDraftState({\n\t\t\t\tsourceSignature: externalStateSignature,\n\t\t\t\tselectedDate: nextRange,\n\t\t\t\tinputValue: formatValue(nextRange)\n\t\t\t});\n\t\t\treturn false;\n\t\t}\n\n\t\tconst normalizedDate = normalizeSingleDateValue(selectedStartDate, formatOptions);\n\t\tsetDraftState({\n\t\t\tsourceSignature: externalStateSignature,\n\t\t\tselectedDate: normalizedDate,\n\t\t\tinputValue: formatValue(normalizedDate)\n\t\t});\n\t\toptions.onChange(normalizedDate);\n\n\t\treturn true;\n\t};\n\n\treturn {\n\t\tinputValue,\n\t\tsetInputValue,\n\t\tselectedDate,\n\t\tsetSelectedDate,\n\t\thandleSelect,\n\t\tformatDate: formatValue,\n\t\tparseDate\n\t};\n};\n",".selectionModeControl {\n\tmargin-top: var(--space-sm);\n\tpadding-top: var(--space-sm);\n\tborder-top: var(--border);\n}\n","import { JSX, useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { isDateRangeTuple, type NullableDateRange } from \"@ryuzaki13/react-foundation-lib/formatters\";\nimport { CalendarDaysIcon } from \"lucide-react\";\n\nimport { InputText } from \"../../input\";\nimport { Popover } from \"../../popover\";\nimport { RadioGroup } from \"../../radio-group\";\nimport { UiBaseProps } from \"../../types\";\nimport uiStyles from \"../../ui.module.scss\";\nimport {\n\tareRangeDateValuesEqual,\n\tareSingleDateValuesEqual,\n\tDATE_INPUT_SELECTION_MODES,\n\tisDatePickerLevelAvailable,\n\tresolveAvailableDatePickerLevel,\n\ttype DateInputSelectionMode,\n\ttype DateInputWeekEndDay,\n\ttype DatePickerLevel\n} from \"../lib\";\nimport { useDateInput } from \"../model\";\n\nimport { CalendarView } from \"./CalendarView\";\nimport styles from \"./DateInput.module.scss\";\n\ninterface BaseDateInputProps {\n\terror?: string;\n\tonClearError?: () => void;\n\n\tminDate?: Date;\n\tmaxDate?: Date;\n\n\tdatePreset?: string;\n\n\t/**\n\t * Минимальный уровень календарной навигации. Размер выбранного периода задаёт `selectionMode`.\n\t */\n\tdatePickerLevel?: DatePickerLevel;\n\t/**\n\t * Размер периода, который выбирает поле: день, неделя, месяц или год.\n\t */\n\tselectionMode?: DateInputSelectionMode;\n\t/**\n\t * Последний включённый день недели для `selectionMode=\"week\"`.\n\t */\n\tweekEndDay?: DateInputWeekEndDay;\n\t/**\n\t * Показывает переключатель `selectionMode` под календарём.\n\t */\n\tallowSelectionModeChange?: boolean;\n\t/**\n\t * Ограничивает набор режимов в runtime-переключателе.\n\t */\n\tselectionModeOptions?: readonly DateInputSelectionMode[];\n\t/**\n\t * Сообщает наружу о runtime-смене режима выбора.\n\t */\n\tonSelectionModeChange?: (selectionMode: DateInputSelectionMode) => void;\n}\n\nexport interface DateSingleInputProps extends BaseDateInputProps, UiBaseProps<Date | null> {\n\tselectsRange?: false;\n}\nexport interface DateRangeInputProps extends BaseDateInputProps, UiBaseProps<NullableDateRange | null> {\n\tselectsRange: true;\n}\n\ntype DateInputProps = DateSingleInputProps | DateRangeInputProps;\n\ninterface CalendarTypeState {\n\treadonly view: DatePickerLevel;\n\treadonly selectionMode: DateInputSelectionMode;\n\treadonly minDatePickerLevel: DatePickerLevel;\n}\n\nconst selectionModeLabels: Record<DateInputSelectionMode, string> = {\n\tday: \"День\",\n\tweek: \"Неделя\",\n\tmonth: \"Месяц\",\n\tyear: \"Год\"\n};\n\nfunction resolveSelectionModeOptions(\n\tselectionModeOptions: readonly DateInputSelectionMode[] | undefined,\n\tselectionMode: DateInputSelectionMode\n): readonly DateInputSelectionMode[] {\n\tconst enabledModes = new Set(selectionModeOptions?.length ? selectionModeOptions : DATE_INPUT_SELECTION_MODES);\n\tenabledModes.add(selectionMode);\n\n\treturn DATE_INPUT_SELECTION_MODES.filter((mode) => enabledModes.has(mode));\n}\n\nfunction DateInput(props: DateSingleInputProps): JSX.Element;\nfunction DateInput(props: DateRangeInputProps): JSX.Element;\nfunction DateInput({\n\tplaceholder,\n\tdisabled,\n\terror,\n\tonClearError,\n\tminDate,\n\tmaxDate,\n\tdatePickerLevel,\n\tselectionMode: controlledSelectionMode,\n\tweekEndDay = \"sunday\",\n\tallowSelectionModeChange,\n\tselectionModeOptions,\n\tonSelectionModeChange,\n\t...props\n}: DateInputProps) {\n\tconst [open, setOpen] = useState(false);\n\tconst [uncontrolledSelectionMode, setUncontrolledSelectionMode] = useState<DateInputSelectionMode>(controlledSelectionMode ?? \"day\");\n\tconst selectionMode = controlledSelectionMode ?? uncontrolledSelectionMode;\n\tconst minDatePickerLevel = datePickerLevel ?? \"day\";\n\tconst preferredCalendarType = resolveAvailableDatePickerLevel(selectionMode, minDatePickerLevel);\n\tconst [calendarTypeState, setCalendarTypeState] = useState<CalendarTypeState>(() => ({\n\t\tview: preferredCalendarType,\n\t\tselectionMode,\n\t\tminDatePickerLevel\n\t}));\n\tconst calendarType =\n\t\tcalendarTypeState.selectionMode === selectionMode &&\n\t\tcalendarTypeState.minDatePickerLevel === minDatePickerLevel &&\n\t\tisDatePickerLevelAvailable(calendarTypeState.view, minDatePickerLevel)\n\t\t\t? calendarTypeState.view\n\t\t\t: preferredCalendarType;\n\n\tconst initialDateRef = useRef(props.value);\n\tconst dateInputValueOptions = {\n\t\tselectionMode,\n\t\tweekEndDay\n\t};\n\n\tconst { inputValue, setInputValue, selectedDate, setSelectedDate, handleSelect, formatDate, parseDate } = useDateInput({\n\t\t...props,\n\t\tdatePickerLevel: minDatePickerLevel,\n\t\tselectionMode,\n\t\tweekEndDay\n\t});\n\tconst rangeOnChange = props.selectsRange ? props.onChange : undefined;\n\n\tconst updateCalendarType = useCallback(\n\t\t(calendarType: DatePickerLevel) => {\n\t\t\tif (isDatePickerLevelAvailable(calendarType, minDatePickerLevel)) {\n\t\t\t\tsetCalendarTypeState({\n\t\t\t\t\tview: calendarType,\n\t\t\t\t\tselectionMode,\n\t\t\t\t\tminDatePickerLevel\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t[minDatePickerLevel, selectionMode]\n\t);\n\n\tuseEffect(() => {\n\t\tinitialDateRef.current = props.value;\n\t}, [props.value]);\n\n\tconst handleInputBlur = () => {\n\t\tif (inputValue) {\n\t\t\tconst parsedDate = parseDate(inputValue);\n\t\t\tif (parsedDate) {\n\t\t\t\tsetInputValue(formatDate(parsedDate));\n\n\t\t\t\tif (props.selectsRange && isDateRangeTuple(parsedDate)) {\n\t\t\t\t\tconst selectedRange = isDateRangeTuple(selectedDate) ? selectedDate : null;\n\n\t\t\t\t\tif (areRangeDateValuesEqual(parsedDate, selectedRange, dateInputValueOptions)) return;\n\n\t\t\t\t\tsetSelectedDate(parsedDate);\n\t\t\t\t\tprops.onChange(parsedDate);\n\t\t\t\t} else if (!props.selectsRange && parsedDate instanceof Date) {\n\t\t\t\t\tconst selectedSingleDate = selectedDate instanceof Date ? selectedDate : null;\n\n\t\t\t\t\tif (areSingleDateValuesEqual(parsedDate, selectedSingleDate, dateInputValueOptions)) return;\n\n\t\t\t\t\tsetSelectedDate(parsedDate);\n\t\t\t\t\tprops.onChange(parsedDate);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tconst handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n\t\tif (event.key === \"Enter\") {\n\t\t\tevent.preventDefault();\n\t\t\thandleInputBlur();\n\t\t}\n\t};\n\n\tconst handleCalendarDateSelect = useCallback(\n\t\t(value: Date | NullableDateRange) => {\n\t\t\tif (handleSelect(value)) {\n\t\t\t\tsetOpen(false);\n\t\t\t}\n\t\t},\n\t\t[handleSelect]\n\t);\n\n\tconst handleSelectionModeChange = useCallback(\n\t\t(nextSelectionMode: DateInputSelectionMode) => {\n\t\t\tif (controlledSelectionMode === undefined) {\n\t\t\t\tsetUncontrolledSelectionMode(nextSelectionMode);\n\t\t\t}\n\n\t\t\tonSelectionModeChange?.(nextSelectionMode);\n\t\t\tsetCalendarTypeState({\n\t\t\t\tview: resolveAvailableDatePickerLevel(nextSelectionMode, minDatePickerLevel),\n\t\t\t\tselectionMode: nextSelectionMode,\n\t\t\t\tminDatePickerLevel\n\t\t\t});\n\t\t},\n\t\t[controlledSelectionMode, minDatePickerLevel, onSelectionModeChange]\n\t);\n\n\tconst handleCancel = useCallback(() => {\n\t\t// Восстановить исходное состояние при отмене\n\t\tif (rangeOnChange) {\n\t\t\tconst [, selectedEndDate] = isDateRangeTuple(selectedDate) ? selectedDate : [null, null];\n\n\t\t\tif (!selectedEndDate) {\n\t\t\t\t// Восстановить исходное состояние диапазона\n\t\t\t\tconst initialValue = initialDateRef.current;\n\t\t\t\tconst initialRange = Array.isArray(initialValue) ? initialValue : null;\n\t\t\t\tconst initialStart = initialRange?.[0] ?? null;\n\t\t\t\tconst initialEnd = initialRange?.[1] ?? null;\n\n\t\t\t\tif (initialStart && initialEnd) {\n\t\t\t\t\tconst initialSelectedDate: NullableDateRange = [initialStart, initialEnd];\n\t\t\t\t\tsetSelectedDate(initialSelectedDate);\n\t\t\t\t\tsetInputValue(formatDate(initialSelectedDate));\n\n\t\t\t\t\trangeOnChange(initialSelectedDate);\n\t\t\t\t} else {\n\t\t\t\t\t// Если начального диапазона нет, очистить всё\n\t\t\t\t\tsetSelectedDate([null, null]);\n\t\t\t\t\tsetInputValue(\"\");\n\n\t\t\t\t\trangeOnChange([null, null]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}, [rangeOnChange, selectedDate, setSelectedDate, setInputValue, formatDate]);\n\n\tconst availableSelectionModes = resolveSelectionModeOptions(selectionModeOptions, selectionMode);\n\tconst showSelectionModeControl = allowSelectionModeChange && availableSelectionModes.length > 1;\n\n\treturn (\n\t\t<Popover\n\t\t\topen={open}\n\t\t\tonOpenChange={(value) => {\n\t\t\t\tsetOpen(value);\n\t\t\t\tif (!value) {\n\t\t\t\t\thandleCancel();\n\t\t\t\t}\n\t\t\t}}>\n\t\t\t<InputText\n\t\t\t\tlabel={props.label}\n\t\t\t\tdescription={props.description}\n\t\t\t\tsize={props.size}\n\t\t\t\tvalue={inputValue}\n\t\t\t\tonChange={setInputValue}\n\t\t\t\tonBlur={handleInputBlur}\n\t\t\t\tonKeyUp={handleKeyDown}\n\t\t\t\tplaceholder={placeholder}\n\t\t\t\tdisabled={disabled}\n\t\t\t\terror={error}\n\t\t\t\tonClearError={onClearError}\n\t\t\t\tendAdornmentWidth=\"var(--control-height)\"\n\t\t\t\tendAdornment={\n\t\t\t\t\t<Popover.Trigger>\n\t\t\t\t\t\t<div className={uiStyles.uiToggleButtonContainer}>\n\t\t\t\t\t\t\t<button type=\"button\" disabled={disabled} aria-label=\"Открыть календарь\" className={uiStyles.uiToggleButton}>\n\t\t\t\t\t\t\t\t<CalendarDaysIcon />\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</Popover.Trigger>\n\t\t\t\t}\n\t\t\t/>\n\n\t\t\t<Popover.Content background=\"primary\">\n\t\t\t\t<CalendarView\n\t\t\t\t\tview={calendarType}\n\t\t\t\t\tdatePickerLevel={minDatePickerLevel}\n\t\t\t\t\tselectionMode={selectionMode}\n\t\t\t\t\tweekEndDay={weekEndDay}\n\t\t\t\t\tonViewChange={updateCalendarType}\n\t\t\t\t\tvalue={selectedDate ?? null}\n\t\t\t\t\tonChange={handleCalendarDateSelect}\n\t\t\t\t\tminDate={minDate}\n\t\t\t\t\tmaxDate={maxDate}\n\t\t\t\t\tselectsRange={!!props.selectsRange}\n\t\t\t\t/>\n\t\t\t\t{showSelectionModeControl && (\n\t\t\t\t\t<div className={styles.selectionModeControl}>\n\t\t\t\t\t\t<RadioGroup<DateInputSelectionMode>\n\t\t\t\t\t\t\tvalue={selectionMode}\n\t\t\t\t\t\t\tonChange={handleSelectionModeChange}\n\t\t\t\t\t\t\tnoWrap\n\t\t\t\t\t\t\taria-label=\"Режим выбора даты\">\n\t\t\t\t\t\t\t{availableSelectionModes.map((mode) => (\n\t\t\t\t\t\t\t\t<RadioGroup.Option key={mode} value={mode} label={selectionModeLabels[mode]} />\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</RadioGroup>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</Popover.Content>\n\t\t</Popover>\n\t);\n}\n\nexport function SingleDateInput(props: Omit<DateSingleInputProps, \"selectsRange\">) {\n\treturn <DateInput {...props} />;\n}\n\nexport function RangeDateInput(props: Omit<DateRangeInputProps, \"selectsRange\">) {\n\treturn <DateInput {...props} selectsRange={true} />;\n}\n"],"mappings":";;;;;;;;;;AAkBA,IAAa,IAA4B,EAA0B,MAKtD,IAA4B,cAEnC,IAAkB;AA8BxB,SAAS,EAA0B,GAAqD;CASvF,OARI,EAAQ,kBAAkB,SAAS,EAAQ,kBAAkB,SACzD,QAGJ,EAAQ,kBAAkB,WAAW,EAAQ,kBAAkB,SAC3D,EAAQ,gBAGT,EAAQ,mBAAmB;AACnC;AAEA,SAAS,EAA6B,GAAwD;CAC7F,OAAO;EACN,eAAe,GAAS;EACxB,YAAY,GAAS;CACtB;AACD;AAKA,SAAS,EACR,GACA,GACwB;CAexB,OAdI,OAAO,KAAoB,YAAY,MAAoB,KAAA,IACvD;EACN,YAAY;EACZ;CACD,IAGG,KAAmB,EAAgB,oBAAoB,KAAA,IACnD;EACN,GAAG;EACH;CACD,IAGM;AACR;AAKA,SAAS,EAA2B,GAA6B;CAChE,IAAM,IAAqB,EAAsB,GAAY,CAAyB;CACtF,OAAO,EAAc,CAAkB,IAAI,IAAqB;AACjE;AAKA,SAAS,EAAmB,GAAe,GAA6C;CACvF,OACC,EAAkB,GAAO,EAA2B,EAAQ,UAAU,GAAG;EACxE,eAAe;EACf,WAAW,EAA0B,CAAO;EAC5C,eAAe,EAAQ;CACxB,CAAC,CAAC,EAAE,QAAQ;AAEd;AAKA,SAAgB,EAAyB,GAAmB,GAA8C;CACzG,OAAO,EAAkB,GAAM,EAA6B,CAAO,CAAC,CAAC,EAAE,SAAS;AACjF;AAKA,SAAgB,EAAwB,GAAiC,GAA2D;CACnI,IAAI,CAAC,EAAiB,CAAK,GAAG,OAAO;CAErC,IAAM,CAAC,GAAW,KAAW;CAC7B,OAAO,CAAC,EAAyB,GAAW,CAAO,GAAG,EAA2B,GAAS,CAAO,CAAC;AACnG;AAKA,SAAgB,EAA2B,GAAmB,GAA8C;CAC3G,OAAO,EAAkB,GAAM,EAA6B,CAAO,CAAC,CAAC,EAAE,OAAO;AAC/E;AAEA,SAAS,EAAY,GAAkC;CACtD,OAAO,GAAM,QAAQ,KAAK;AAC3B;AAKA,SAAgB,EAAyB,GAAmB,GAAoB,GAA0C;CACzH,OAAO,EAAY,EAAyB,GAAM,CAAO,CAAC,MAAM,EAAY,EAAyB,GAAO,CAAO,CAAC;AACrH;AAKA,SAAgB,EACf,GACA,GACA,GACU;CACV,IAAM,IAAiB,EAAwB,GAAM,CAAO,GACtD,IAAkB,EAAwB,GAAO,CAAO;CAE9D,OACC,EAAY,IAAiB,MAAM,IAAI,MAAM,EAAY,IAAkB,MAAM,IAAI,KACrF,EAAY,IAAiB,MAAM,IAAI,MAAM,EAAY,IAAkB,MAAM,IAAI;AAEvF;AAKA,SAAgB,EACf,GACA,GACA,GACS;CACT,IAAI,CAAC,GAAM,OAAO;CAElB,IAAM,IAAU,EAA+B,GAAiB,CAAe,GACzE,IAAS,EAAkB,GAAM,EAA6B,CAAO,CAAC;CAS5E,OANI,EAAQ,kBAAkB,UAAU,IAChC,EAAgB,EAAO,OAAO,EAAO,KAAK,EAA2B,EAAQ,UAAU,GAAG,EAChG,WAAW,EAA0B,CAAO,EAC7C,CAAC,IAGK,EAAW,GAAM,EAA2B,EAAQ,UAAU,GAAG,EACvE,WAAW,EAA0B,CAAO,EAC7C,CAAC;AACF;AAKA,SAAgB,EACf,GACA,GACA,GACS;CACT,IAAI,CAAC,EAAiB,CAAK,GAAG,OAAO;CAErC,IAAM,IAAU,EAA+B,GAAiB,CAAe,GACzE,CAAC,GAAW,KAAW;CAa7B,OAZI,KAAa,IACT,EAAgB,GAAW,GAAS,EAA2B,EAAQ,UAAU,GAAG,EAC1F,WAAW,EAA0B,CAAO,EAC7C,CAAC,IAGE,IACI,GAAG,EAAW,GAAW,EAA2B,EAAQ,UAAU,GAAG,EAC/E,WAAW,EAA0B,CAAO,EAC7C,CAAC,IAAI,MAGC;AACR;AAKA,SAAgB,EACf,GACA,GACA,GACS;CAKT,OAJI,EAAiB,CAAK,IAClB,EAAqB,GAAO,GAAiB,CAAe,IAG7D,EAAsB,GAAO,GAAiB,CAAe;AACrE;AAKA,SAAgB,EACf,GACA,GACA,GACc;CACd,IAAM,IAAU,EAA+B,GAAiB,CAAe;CAI/E,OAAO,EAAyB,EAFZ,EAAQ,kBAAkB,SAAU,EAAM,MAAM,CAAe,CAAC,CAAC,MAAM,KAAM,GAEjC,CAAO,GAAG,CAAO;AAClF;AAKA,SAAgB,EACf,GACA,GACA,GACoB;CACpB,IAAM,IAAU,EAA+B,GAAiB,CAAe,GACzE,CAAC,IAAY,IAAI,IAAU,MAAM,EAAM,MAAM,CAAe;CAElE,OAAO,CAAC,EAAqB,GAAW,CAAO,GAAG,EAAuB,GAAS,CAAO,CAAC;AAC3F;AAKA,SAAgB,EACf,GACA,GACA,GACc;CACd,IAAM,IAAU,EAA+B,GAAiB,CAAe;CAC/E,OAAO,EAA2B,EAAmB,GAAO,CAAO,GAAG,CAAO;AAC9E;;;ACtQA,SAAS,EAAqB,GAA0D;CAKvF,OAJI,EAAiB,CAAK,IAClB,EAAM,MAAM,EAAM,MAAM,KAAA,IAGzB,KAAS,KAAA;AACjB;AAKA,IAAa,KAAgB,MAA8B;CAC1D,IAAM,IAAuB,QAAc;EAC1C,IAAM,IAA0C;GAC/C,eAAe,EAAQ;GACvB,YAAY,EAAQ;EACrB;EAMA,OAJI,EAAQ,eACJ,EAAwB,EAAQ,OAAmC,CAAgB,IAGpF,EAAyB,EAAQ,OAAsB,CAAgB;CAC/E,GAAG;EAAC,EAAQ;EAAc,EAAQ;EAAe,EAAQ;EAAO,EAAQ;CAAU,CAAC,GAC7E,IAAgB,SACd;EACN,YAAY,EAAQ;EACpB,iBAAiB,EAAQ;EACzB,eAAe,EAAQ;EACvB,YAAY,EAAQ;CACrB,IACA;EAAC,EAAQ;EAAiB,EAAQ;EAAY,EAAQ;EAAe,EAAQ;CAAU,CACxF,GACM,IAAqB,EAAqB,GAAsB,CAAa,GAC7E,IAAyB,KAAK,UAAU;EAC7C,EAAQ;EACR,EAAQ,cAAc;EACtB,EAAQ,mBAAmB;EAC3B,EAAQ,iBAAiB;EACzB,EAAQ,cAAc;EACtB,EAAiB,CAAoB,IAClC,CAAC,EAAqB,EAAE,EAAE,QAAQ,KAAK,MAAM,EAAqB,EAAE,EAAE,QAAQ,KAAK,IAAI,IACtF,GAAsB,QAAQ,KAAK;CACxC,CAAC,GACK,CAAC,GAAY,KAAiB,SAAgB;EACnD,iBAAiB;EACjB,cAAc;EACd,YAAY;CACb,EAAE,GACI,IAAkB,EAAW,oBAAoB,GACjD,IAAe,IAAkB,EAAW,eAAe,GAC3D,IAAa,IAAkB,EAAW,aAAa,GAMvD,KAAiB,MAA2B;EACjD,GAAe,MAAiB;GAC/B,IAAM,IACL,EAAa,oBAAoB,IAAyB,EAAa,eAAe;GAEvF,OAAO;IACN,iBAAiB;IACjB,cAAc;IACd,YAAY;GACb;EACD,CAAC;CACF,GAKM,KAAmB,MAAsD;EAC9E,GAAe,MAAiB;GAC/B,IAAM,IACL,EAAa,oBAAoB,IAAyB,EAAa,aAAa;GAErF,OAAO;IACN,iBAAiB;IACjB,cAAc;IACd,YAAY;GACb;EACD,CAAC;CACF,GAKM,KAAe,MAAmD,EAAqB,GAAO,CAAa;CAyEjH,OAAO;EACN;EACA;EACA;EACA;EACA,eAzDqB,MAAmC;GACxD,IAAM,CAAC,GAAmB,KAAoB,MAAM,QAAQ,CAAI,IAAI,IAAO,CAAC,GAAM,IAAI;GAEtF,IAAI,EAAQ,cAAc;IACzB,IAAM,IAAsB,EAAyB,GAAmB,CAAa,GAC/E,IAAoB,EAA2B,GAAiB,CAAa;IAEnF,IAAI,KAAuB,GAAmB;KAC7C,IAAI,IAAoB,GAAqB;MAC5C,IAAM,IAAkC,CACvC,EAAyB,GAAiB,CAAa,GACvD,EAA2B,GAAmB,CAAa,CAC5D;MAMA,AALA,EAAc;OACb,iBAAiB;OACjB,cAAc;OACd,YAAY,EAAY,CAAY;MACrC,CAAC,GACD,EAAQ,SAAS,CAAY;KAC9B,OAAO;MACN,IAAM,IAA+B,CAAC,GAAqB,CAAiB;MAM5E,AALA,EAAc;OACb,iBAAiB;OACjB,cAAc;OACd,YAAY,EAAY,CAAS;MAClC,CAAC,GACD,EAAQ,SAAS,CAAS;KAC3B;KAEA,OAAO;IACR;IAEA,IAAM,IAA+B,CAAC,GAAqB,IAAI;IAM/D,OALA,EAAc;KACb,iBAAiB;KACjB,cAAc;KACd,YAAY,EAAY,CAAS;IAClC,CAAC,GACM;GACR;GAEA,IAAM,IAAiB,EAAyB,GAAmB,CAAa;GAQhF,OAPA,EAAc;IACb,iBAAiB;IACjB,cAAc;IACd,YAAY,EAAY,CAAc;GACvC,CAAC,GACD,EAAQ,SAAS,CAAc,GAExB;EACR;EAQC,YAAY;EACZ,YA3EkB,MAAwD;GAC1E,IAAM,IAAsC;IAC3C,GAAG;IACH,eAAe,EAAqB,CAAY;GACjD;GAMA,OAJI,EAAQ,eACJ,EAAoB,GAAY,CAAY,IAG7C,EAAqB,GAAY,CAAY;EACrD;CAiEA;AACD,2CE/GM,IAA8D;CACnE,KAAK;CACL,MAAM;CACN,OAAO;CACP,MAAM;AACP;AAEA,SAAS,EACR,GACA,GACoC;CACpC,IAAM,IAAe,IAAI,IAAI,GAAsB,SAAS,IAAuB,CAA0B;CAG7G,OAFA,EAAa,IAAI,CAAa,GAEvB,EAA2B,QAAQ,MAAS,EAAa,IAAI,CAAI,CAAC;AAC1E;AAIA,SAAS,EAAU,EAClB,gBACA,aACA,UACA,iBACA,YACA,YACA,oBACA,eAAe,GACf,gBAAa,UACb,6BACA,yBACA,0BACA,GAAG,KACe;CAClB,IAAM,CAAC,GAAM,KAAW,EAAS,EAAK,GAChC,CAAC,GAA2B,KAAgC,EAAiC,KAA2B,KAAK,GAC7H,IAAgB,KAA2B,GAC3C,IAAqB,KAAmB,OACxC,IAAwB,EAAgC,GAAe,CAAkB,GACzF,CAAC,GAAmB,KAAwB,SAAmC;EACpF,MAAM;EACN;EACA;CACD,EAAE,GACI,IACL,EAAkB,kBAAkB,KACpC,EAAkB,uBAAuB,KACzC,EAA2B,EAAkB,MAAM,CAAkB,IAClE,EAAkB,OAClB,GAEE,IAAiB,EAAO,EAAM,KAAK,GACnC,IAAwB;EAC7B;EACA;CACD,GAEM,EAAE,eAAY,kBAAe,iBAAc,oBAAiB,iBAAc,eAAY,kBAAc,EAAa;EACtH,GAAG;EACH,iBAAiB;EACjB;EACA;CACD,CAAC,GACK,IAAgB,EAAM,eAAe,EAAM,WAAW,KAAA,GAEtD,KAAqB,GACzB,MAAkC;EAClC,AAAI,EAA2B,GAAc,CAAkB,KAC9D,EAAqB;GACpB,MAAM;GACN;GACA;EACD,CAAC;CAEH,GACA,CAAC,GAAoB,CAAa,CACnC;CAEA,QAAgB;EACf,EAAe,UAAU,EAAM;CAChC,GAAG,CAAC,EAAM,KAAK,CAAC;CAEhB,IAAM,UAAwB;EAC7B,IAAI,GAAY;GACf,IAAM,IAAa,GAAU,CAAU;GACvC,IAAI,GAGH;QAFA,EAAc,EAAW,CAAU,CAAC,GAEhC,EAAM,gBAAgB,EAAiB,CAAU,GAAG;KAGvD,IAAI,EAAwB,GAFN,EAAiB,CAAY,IAAI,IAAe,MAEf,CAAqB,GAAG;KAG/E,AADA,EAAgB,CAAU,GAC1B,EAAM,SAAS,CAAU;IAC1B,OAAO,IAAI,CAAC,EAAM,gBAAgB,aAAsB,MAAM;KAG7D,IAAI,EAAyB,GAFF,aAAwB,OAAO,IAAe,MAEZ,CAAqB,GAAG;KAGrF,AADA,EAAgB,CAAU,GAC1B,EAAM,SAAS,CAAU;IAC1B;;EAEF;CACD,GAEM,MAAiB,MAAiD;EACvE,AAAI,EAAM,QAAQ,YACjB,EAAM,eAAe,GACrB,EAAgB;CAElB,GAEM,KAA2B,GAC/B,MAAoC;EACpC,AAAI,EAAa,CAAK,KACrB,EAAQ,EAAK;CAEf,GACA,CAAC,CAAY,CACd,GAEM,KAA4B,GAChC,MAA8C;EAM9C,AALI,MAA4B,KAAA,KAC/B,EAA6B,CAAiB,GAG/C,IAAwB,CAAiB,GACzC,EAAqB;GACpB,MAAM,EAAgC,GAAmB,CAAkB;GAC3E,eAAe;GACf;EACD,CAAC;CACF,GACA;EAAC;EAAyB;EAAoB;CAAqB,CACpE,GAEM,KAAe,QAAkB;EAEtC,IAAI,GAAe;GAClB,IAAM,GAAG,KAAmB,EAAiB,CAAY,IAAI,IAAe,CAAC,MAAM,IAAI;GAEvF,IAAI,CAAC,GAAiB;IAErB,IAAM,IAAe,EAAe,SAC9B,IAAe,MAAM,QAAQ,CAAY,IAAI,IAAe,MAC5D,IAAe,IAAe,MAAM,MACpC,IAAa,IAAe,MAAM;IAExC,IAAI,KAAgB,GAAY;KAC/B,IAAM,IAAyC,CAAC,GAAc,CAAU;KAIxE,AAHA,EAAgB,CAAmB,GACnC,EAAc,EAAW,CAAmB,CAAC,GAE7C,EAAc,CAAmB;IAClC,OAKC,AAHA,EAAgB,CAAC,MAAM,IAAI,CAAC,GAC5B,EAAc,EAAE,GAEhB,EAAc,CAAC,MAAM,IAAI,CAAC;GAE5B;EACD;CACD,GAAG;EAAC;EAAe;EAAc;EAAiB;EAAe;CAAU,CAAC,GAEtE,IAA0B,EAA4B,GAAsB,CAAa,GACzF,KAA2B,KAA4B,EAAwB,SAAS;CAE9F,OACC,kBAAC,GAAD;EACO;EACN,eAAe,MAAU;GAExB,AADA,EAAQ,CAAK,GACR,KACJ,GAAa;EAEf;EAPD,UAAA,CAQC,kBAAC,GAAD;GACC,OAAO,EAAM;GACb,aAAa,EAAM;GACnB,MAAM,EAAM;GACZ,OAAO;GACP,UAAU;GACV,QAAQ;GACR,SAAS;GACI;GACH;GACH;GACO;GACd,mBAAkB;GAClB,cACC,kBAAC,EAAQ,SAAT,EAAA,UACC,kBAAC,OAAD;IAAK,WAAW,EAAS;IACxB,UAAA,kBAAC,UAAD;KAAQ,MAAK;KAAmB;KAAU,cAAW;KAAoB,WAAW,EAAS;KAC5F,UAAA,kBAAC,IAAD,CAAmB,CAAA;IACZ,CAAA;GACJ,CAAA,EACW,CAAA;EAElB,CAAA,GAED,kBAAC,EAAQ,SAAT;GAAiB,YAAW;GAA5B,UAAA,CACC,kBAAC,GAAD;IACC,MAAM;IACN,iBAAiB;IACF;IACH;IACZ,cAAc;IACd,OAAO,KAAgB;IACvB,UAAU;IACD;IACA;IACT,cAAc,CAAC,CAAC,EAAM;GACtB,CAAA,GACA,MACA,kBAAC,OAAD;IAAK,WAAW,EAAO;IACtB,UAAA,kBAAC,GAAD;KACC,OAAO;KACP,UAAU;KACV,QAAA;KACA,cAAW;KACV,UAAA,EAAwB,KAAK,MAC7B,kBAAC,EAAW,QAAZ;MAA8B,OAAO;MAAM,OAAO,EAAoB;KAAQ,GAAtD,CAAsD,CAC9E;IACU,CAAA;GACR,CAAA,CAEU;EACT,CAAA,CAAA;;AAEX;AAEA,SAAgB,EAAgB,GAAmD;CAClF,OAAO,kBAAC,GAAD,EAAW,GAAI,EAAQ,CAAA;AAC/B;AAEA,SAAgB,EAAe,GAAkD;CAChF,OAAO,kBAAC,GAAD;EAAW,GAAI;EAAO,cAAc;CAAO,CAAA;AACnD"}
|
|
@@ -39,30 +39,36 @@ function f({ label: t, controlId: n, labelId: r }) {
|
|
|
39
39
|
function p() {
|
|
40
40
|
return /* @__PURE__ */ o("div", { className: a(e.uiInputControlFake, "skeletonLine") });
|
|
41
41
|
}
|
|
42
|
-
function m({ label: t, description: n, size: r, disabled: i,
|
|
43
|
-
let { controlId:
|
|
42
|
+
function m({ label: t, description: n, size: r, disabled: i, isLoading: c, className: l }) {
|
|
43
|
+
let { controlId: u, labelId: p, descriptionId: m } = d({
|
|
44
44
|
hasLabel: t != null,
|
|
45
45
|
hasDescription: !!n
|
|
46
46
|
});
|
|
47
47
|
return /* @__PURE__ */ s("div", {
|
|
48
|
-
className: a(e.uiElement, e.uiSizable, r && e[r], e.disabled,
|
|
48
|
+
className: a(e.uiElement, e.uiSizable, r && e[r], e.disabled, l),
|
|
49
49
|
"aria-disabled": i || void 0,
|
|
50
50
|
children: [
|
|
51
51
|
t && /* @__PURE__ */ o(f, {
|
|
52
52
|
label: t,
|
|
53
|
-
controlId:
|
|
54
|
-
labelId:
|
|
53
|
+
controlId: u,
|
|
54
|
+
labelId: p
|
|
55
55
|
}),
|
|
56
56
|
n && /* @__PURE__ */ o("p", {
|
|
57
57
|
id: m,
|
|
58
58
|
className: e.uiDescription,
|
|
59
59
|
children: n
|
|
60
60
|
}),
|
|
61
|
-
/* @__PURE__ */ o(
|
|
61
|
+
/* @__PURE__ */ o("div", { className: a(e.uiInputControlFake, c && "skeletonLine") })
|
|
62
62
|
]
|
|
63
63
|
});
|
|
64
64
|
}
|
|
65
|
-
function h(
|
|
65
|
+
function h(e) {
|
|
66
|
+
return /* @__PURE__ */ o(m, {
|
|
67
|
+
...e,
|
|
68
|
+
isLoading: !0
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
function g({ label: t, description: n, disabled: r, className: i, error: c, size: l, controlId: d, labelId: p, descriptionId: m, errorId: h, required: g, children: _ }) {
|
|
66
72
|
return /* @__PURE__ */ s("div", {
|
|
67
73
|
className: a(e.uiElement, e.uiSizable, l && e[l], r && e.disabled, g && e.required, i),
|
|
68
74
|
"aria-disabled": r || void 0,
|
|
@@ -89,7 +95,7 @@ function h({ label: t, description: n, disabled: r, className: i, error: c, size
|
|
|
89
95
|
]
|
|
90
96
|
});
|
|
91
97
|
}
|
|
92
|
-
function
|
|
98
|
+
function _({ className: e, endAdornment: t, endAdornmentClassName: n, endAdornmentWidth: r, children: i }) {
|
|
93
99
|
let c = t != null, l = c && r ? { "--input-end-adornment-width": r } : void 0;
|
|
94
100
|
return /* @__PURE__ */ s("div", {
|
|
95
101
|
className: a(u.controlLayout, e),
|
|
@@ -100,7 +106,7 @@ function g({ className: e, endAdornment: t, endAdornmentClassName: n, endAdornme
|
|
|
100
106
|
})]
|
|
101
107
|
});
|
|
102
108
|
}
|
|
103
|
-
function
|
|
109
|
+
function v({ onClick: e, disabled: t, className: n, ariaLabel: r = "Очистить значение" }) {
|
|
104
110
|
return /* @__PURE__ */ o("button", {
|
|
105
111
|
type: "button",
|
|
106
112
|
disabled: t || !e,
|
|
@@ -110,47 +116,47 @@ function _({ onClick: e, disabled: t, className: n, ariaLabel: r = "Очисти
|
|
|
110
116
|
children: /* @__PURE__ */ o(c, {})
|
|
111
117
|
});
|
|
112
118
|
}
|
|
113
|
-
function
|
|
119
|
+
function y(e, t, n) {
|
|
114
120
|
if (n) return n;
|
|
115
121
|
if (e && t) return "calc((var(--control-height) * 2) + var(--space-xs))";
|
|
116
122
|
if (e || t) return "var(--control-height)";
|
|
117
123
|
}
|
|
118
|
-
function
|
|
124
|
+
function b({ endAdornment: e, onClear: t, disabled: n }) {
|
|
119
125
|
if (!(e == null && !t)) return /* @__PURE__ */ s("div", {
|
|
120
126
|
className: u.endAdornmentGroup,
|
|
121
|
-
children: [e, t && /* @__PURE__ */ o(
|
|
127
|
+
children: [e, t && /* @__PURE__ */ o(v, {
|
|
122
128
|
onClick: t,
|
|
123
129
|
disabled: n
|
|
124
130
|
})]
|
|
125
131
|
});
|
|
126
132
|
}
|
|
127
|
-
function
|
|
133
|
+
function x({ label: t, description: n, disabled: r, className: s, onClear: c, error: l, onClearError: f, onChange: p, value: m, size: h, allowedPattern: v, endAdornment: x, endAdornmentClassName: S, endAdornmentWidth: C, type: w = "text", ...T }) {
|
|
128
134
|
let [E, D] = i(!1), O = (e) => {
|
|
129
135
|
let t = e.target.value;
|
|
130
|
-
|
|
136
|
+
v !== void 0 && D(t !== "" && !v.test(t)), p(t), l && f && f();
|
|
131
137
|
}, k = !!(m && m.length > 0), A = k ? l : void 0, { controlId: j, labelId: M, descriptionId: N, errorId: P, describedBy: F } = d({
|
|
132
138
|
id: T.id,
|
|
133
139
|
hasLabel: t != null,
|
|
134
140
|
hasDescription: !!n,
|
|
135
141
|
hasError: !!A
|
|
136
|
-
}), I = k && (!!l || E), L =
|
|
142
|
+
}), I = k && (!!l || E), L = b({
|
|
137
143
|
endAdornment: x,
|
|
138
144
|
onClear: c,
|
|
139
145
|
disabled: r || !k
|
|
140
|
-
}), R =
|
|
141
|
-
return /* @__PURE__ */ o(
|
|
146
|
+
}), R = y(x != null, !!c, C);
|
|
147
|
+
return /* @__PURE__ */ o(g, {
|
|
142
148
|
label: t,
|
|
143
149
|
description: n,
|
|
144
150
|
disabled: r,
|
|
145
151
|
required: T.required,
|
|
146
152
|
className: s,
|
|
147
|
-
size:
|
|
153
|
+
size: h,
|
|
148
154
|
error: A,
|
|
149
155
|
controlId: j,
|
|
150
156
|
labelId: M,
|
|
151
157
|
descriptionId: N,
|
|
152
158
|
errorId: P,
|
|
153
|
-
children: /* @__PURE__ */ o(
|
|
159
|
+
children: /* @__PURE__ */ o(_, {
|
|
154
160
|
endAdornment: L,
|
|
155
161
|
endAdornmentClassName: S,
|
|
156
162
|
endAdornmentWidth: R,
|
|
@@ -170,21 +176,21 @@ function b({ label: t, description: n, disabled: r, className: s, onClear: c, er
|
|
|
170
176
|
})
|
|
171
177
|
});
|
|
172
178
|
}
|
|
173
|
-
function
|
|
179
|
+
function S({ label: t, description: i, disabled: s, className: c, onClear: f, error: p, onClearError: m, onChange: h, value: v, size: x, endAdornment: S, endAdornmentClassName: C, endAdornmentWidth: w, ...T }) {
|
|
174
180
|
let E = T, { controlId: D, labelId: O, descriptionId: k, errorId: A, describedBy: j } = d({
|
|
175
181
|
id: T.id,
|
|
176
182
|
hasLabel: t != null,
|
|
177
183
|
hasDescription: !!i,
|
|
178
184
|
hasError: !!p
|
|
179
|
-
}), M = r(null), N = r(null), P =
|
|
185
|
+
}), M = r(null), N = r(null), P = v !== void 0 && typeof v == "number" && !isNaN(v) ? String(v) : "";
|
|
180
186
|
n(() => {
|
|
181
187
|
let e = N.current;
|
|
182
|
-
if (e && Object.is(e.value,
|
|
188
|
+
if (e && Object.is(e.value, v)) {
|
|
183
189
|
M.current && M.current.value !== e.raw && (M.current.value = e.raw);
|
|
184
190
|
return;
|
|
185
191
|
}
|
|
186
192
|
N.current = null, M.current && M.current.value !== P && (M.current.value = P);
|
|
187
|
-
}, [P,
|
|
193
|
+
}, [P, v]);
|
|
188
194
|
let F = f ? () => {
|
|
189
195
|
f();
|
|
190
196
|
} : void 0, I = (e) => {
|
|
@@ -192,13 +198,13 @@ function x({ label: t, description: i, disabled: s, className: c, onClear: f, er
|
|
|
192
198
|
N.current = {
|
|
193
199
|
value: n,
|
|
194
200
|
raw: t
|
|
195
|
-
},
|
|
196
|
-
}, L =
|
|
201
|
+
}, h(n), p && m && m();
|
|
202
|
+
}, L = b({
|
|
197
203
|
endAdornment: S,
|
|
198
204
|
onClear: F,
|
|
199
205
|
disabled: s
|
|
200
|
-
}), R =
|
|
201
|
-
return /* @__PURE__ */ o(
|
|
206
|
+
}), R = y(S != null, !!F, w);
|
|
207
|
+
return /* @__PURE__ */ o(g, {
|
|
202
208
|
label: t,
|
|
203
209
|
description: i,
|
|
204
210
|
disabled: s,
|
|
@@ -210,7 +216,7 @@ function x({ label: t, description: i, disabled: s, className: c, onClear: f, er
|
|
|
210
216
|
labelId: O,
|
|
211
217
|
descriptionId: k,
|
|
212
218
|
errorId: A,
|
|
213
|
-
children: /* @__PURE__ */ o(
|
|
219
|
+
children: /* @__PURE__ */ o(_, {
|
|
214
220
|
endAdornment: L,
|
|
215
221
|
endAdornmentClassName: C,
|
|
216
222
|
endAdornmentWidth: R,
|
|
@@ -230,16 +236,16 @@ function x({ label: t, description: i, disabled: s, className: c, onClear: f, er
|
|
|
230
236
|
})
|
|
231
237
|
});
|
|
232
238
|
}
|
|
233
|
-
var
|
|
239
|
+
var C = x;
|
|
234
240
|
//#endregion
|
|
235
241
|
//#region src/input/InputErrorComponent.tsx
|
|
236
|
-
function
|
|
242
|
+
function w({ text: t }) {
|
|
237
243
|
return /* @__PURE__ */ o("div", {
|
|
238
244
|
className: e.uiErrorElement,
|
|
239
245
|
children: t
|
|
240
246
|
});
|
|
241
247
|
}
|
|
242
248
|
//#endregion
|
|
243
|
-
export { p as a,
|
|
249
|
+
export { p as a, g as c, d, u as f, _ as i, m as l, C as n, S as o, v as r, x as s, w as t, h as u };
|
|
244
250
|
|
|
245
|
-
//# sourceMappingURL=input-
|
|
251
|
+
//# sourceMappingURL=input-CCdBtl-C.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input-CCdBtl-C.js","names":[],"sources":["../../src/input/Input.module.scss","../../src/input/lib/useInputFieldIds.ts","../../src/input/Input.tsx","../../src/input/InputErrorComponent.tsx"],"sourcesContent":["@use \"@/styles/mixins\" as *;\n\n.controlLayout {\n\tposition: relative;\n\twidth: 100%;\n}\n\n.input {\n\theight: var(--control-height);\n\twidth: 100%;\n\tpadding: var(--space-xs) var(--space-sm);\n\tfont-size: var(--font-size-md);\n\n\t--ui-color: var(--content-0);\n\t--ui-color-hover: var(--content-0);\n\t--ui-color-active: var(--content-0);\n\n\t--button-size: cacl(var(--control-height) - var(--border-width) * 2);\n}\n\n.inputNumber {\n\tappearance: textfield;\n\t-moz-appearance: textfield;\n\n\t&::-webkit-inner-spin-button,\n\t&::-webkit-outer-spin-button {\n\t\t-webkit-appearance: none;\n\t\tmargin: 0;\n\t}\n}\n\n.controlWithEndAdornment {\n\tpadding-right: calc(var(--input-end-adornment-width, var(--control-height)) + var(--space-sm));\n}\n\n.controlEndAdornment {\n\tposition: absolute;\n\theight: 100%;\n\ttop: 0;\n\tright: calc(var(--border-width) * 2);\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: flex-end;\n\tmax-width: calc(100% - var(--space-md));\n}\n\n.endAdornmentGroup {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: var(--space-xs);\n}\n\n.clearButton {\n\twidth: var(--button-size);\n\theight: var(--button-size);\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tborder: none;\n\tborder-radius: var(--radius-sm);\n\n\tbackground: transparent;\n\tcolor: var(--content-2);\n\n\ttransition:\n\t\tcolor var(--transition-fast) ease,\n\t\tbackground-color var(--transition-fast) ease;\n\n\t&:hover {\n\t\tcolor: var(--content-accent);\n\t}\n\n\t&:focus-visible {\n\t\t@include focusVisible;\n\t}\n\n\t&:disabled {\n\t\tpointer-events: none;\n\t\topacity: var(--disabled-opacity);\n\t}\n}\n\n.error {\n\tposition: absolute;\n\tz-index: 11;\n\tbottom: calc(var(--space-xs) * -1);\n\tleft: 0;\n\tright: 0;\n\ttransform: translateY(100%);\n\t// font-size: var(--font-size-sm);\n\tcolor: var(--status-error-on-fill);\n\tbackground: var(--status-error-fill);\n\tborder-radius: var(--radius-sm);\n\tpadding: var(--space-xs) var(--space-sm);\n\tbox-shadow: var(--shadow-sm);\n\topacity: 0.9;\n}\n","import { useId } from \"react\";\n\nexport interface UseInputFieldIdsOptions {\n\tid?: string;\n\thasLabel?: boolean;\n\thasDescription?: boolean;\n\thasError?: boolean;\n}\n\nexport interface InputFieldIds {\n\tcontrolId: string;\n\tlabelId?: string;\n\tdescriptionId?: string;\n\terrorId?: string;\n\tdescribedBy?: string;\n}\n\nexport function useInputFieldIds({ id: externalId, hasLabel, hasDescription, hasError }: UseInputFieldIdsOptions): InputFieldIds {\n\tconst autoId = useId();\n\tconst controlId = externalId ?? autoId;\n\tconst labelId = hasLabel ? `${controlId}-label` : undefined;\n\tconst descriptionId = hasDescription ? `${controlId}-description` : undefined;\n\tconst errorId = hasError ? `${controlId}-error` : undefined;\n\tconst describedBy = [descriptionId, errorId].filter(Boolean).join(\" \") || undefined;\n\n\treturn {\n\t\tcontrolId,\n\t\tlabelId,\n\t\tdescriptionId,\n\t\terrorId,\n\t\tdescribedBy\n\t};\n}\n","import React, { CSSProperties, InputHTMLAttributes, ReactNode, useLayoutEffect, useRef, useState } from \"react\";\n\nimport { toFiniteNumber } from \"@ryuzaki13/react-foundation-lib/formatters\";\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { XIcon } from \"lucide-react\";\n\nimport { UiBaseProps, UiSize } from \"../types\";\nimport uiStyles from \"../ui.module.scss\";\n\nimport styles from \"./Input.module.scss\";\nimport { useInputFieldIds } from \"./lib/useInputFieldIds\";\n\nexport interface InputUIProps extends Omit<UiBaseProps<never>, \"value\" | \"onChange\"> {\n\tclassName?: string;\n\terror?: string;\n\tcontrolId?: string;\n\tlabelId?: string;\n\tdescriptionId?: string;\n\terrorId?: string;\n\trequired?: boolean;\n\tchildren: React.ReactNode;\n}\n\nexport interface InputControlRenderProps {\n\tcontrolClassName?: string;\n}\n\nexport interface InputControlProps {\n\tclassName?: string;\n\tendAdornment?: ReactNode;\n\tendAdornmentClassName?: string;\n\tendAdornmentWidth?: string;\n\tchildren: (props: InputControlRenderProps) => ReactNode;\n}\n\nexport interface InputClearButtonProps {\n\tonClick?: () => void;\n\tdisabled?: boolean;\n\tclassName?: string;\n\tariaLabel?: string;\n}\n\nfunction InputLabel({ label, controlId, labelId }: { label: React.ReactNode; controlId?: string; labelId?: string }) {\n\treturn (\n\t\t<label id={labelId} htmlFor={controlId} className={uiStyles.uiLabel}>\n\t\t\t{label}\n\t\t</label>\n\t);\n}\n\nexport function InputLoadingFrame() {\n\treturn <div className={cn(uiStyles.uiInputControlFake, \"skeletonLine\")} />;\n}\n\nexport function InputUIFrame({\n\tlabel,\n\tdescription,\n\tsize,\n\tdisabled,\n\tisLoading,\n\tclassName\n}: Pick<InputUIProps, \"label\" | \"description\" | \"size\" | \"disabled\" | \"className\"> & { isLoading?: boolean }) {\n\tconst { controlId, labelId, descriptionId } = useInputFieldIds({\n\t\thasLabel: label !== undefined && label !== null,\n\t\thasDescription: !!description\n\t});\n\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(uiStyles.uiElement, uiStyles.uiSizable, size && uiStyles[size as UiSize], uiStyles.disabled, className)}\n\t\t\taria-disabled={disabled || undefined}>\n\t\t\t{label && <InputLabel label={label} controlId={controlId} labelId={labelId} />}\n\t\t\t{description && (\n\t\t\t\t<p id={descriptionId} className={uiStyles.uiDescription}>\n\t\t\t\t\t{description}\n\t\t\t\t</p>\n\t\t\t)}\n\t\t\t<div className={cn(uiStyles.uiInputControlFake, isLoading && \"skeletonLine\")} />\n\t\t</div>\n\t);\n}\n\nexport function InputUILoading(props: Pick<InputUIProps, \"label\" | \"description\" | \"size\" | \"disabled\" | \"className\">) {\n\treturn <InputUIFrame {...props} isLoading />;\n}\n\n/**\n * Низкоуровневая оболочка поля ввода с общими элементами оформления.\n */\nexport function InputUI({\n\tlabel,\n\tdescription,\n\tdisabled,\n\tclassName,\n\terror,\n\tsize,\n\tcontrolId,\n\tlabelId,\n\tdescriptionId,\n\terrorId,\n\trequired,\n\tchildren\n}: InputUIProps) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\tuiStyles.uiElement,\n\t\t\t\tuiStyles.uiSizable,\n\t\t\t\tsize && uiStyles[size as UiSize],\n\t\t\t\tdisabled && uiStyles.disabled,\n\t\t\t\trequired && uiStyles.required,\n\t\t\t\tclassName\n\t\t\t)}\n\t\t\taria-disabled={disabled || undefined}>\n\t\t\t{label && <InputLabel label={label} controlId={controlId} labelId={labelId} />}\n\t\t\t{description && (\n\t\t\t\t<p id={descriptionId} className={uiStyles.uiDescription}>\n\t\t\t\t\t{description}\n\t\t\t\t</p>\n\t\t\t)}\n\t\t\t<div className={styles.controlLayout}>\n\t\t\t\t{children}\n\n\t\t\t\t{error && (\n\t\t\t\t\t<p id={errorId} className={styles.error} role=\"alert\">\n\t\t\t\t\t\t{error}\n\t\t\t\t\t</p>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nexport function InputControl({ className, endAdornment, endAdornmentClassName, endAdornmentWidth, children }: InputControlProps) {\n\tconst hasEndAdornment = endAdornment !== undefined && endAdornment !== null;\n\tconst style =\n\t\thasEndAdornment && endAdornmentWidth ? ({ \"--input-end-adornment-width\": endAdornmentWidth } as CSSProperties) : undefined;\n\n\treturn (\n\t\t<div className={cn(styles.controlLayout, className)} style={style}>\n\t\t\t{children({ controlClassName: hasEndAdornment ? styles.controlWithEndAdornment : undefined })}\n\t\t\t{hasEndAdornment && <div className={cn(styles.controlEndAdornment, endAdornmentClassName)}>{endAdornment}</div>}\n\t\t</div>\n\t);\n}\n\nexport function InputClearButton({ onClick, disabled, className, ariaLabel = \"Очистить значение\" }: InputClearButtonProps) {\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdisabled={disabled || !onClick}\n\t\t\tclassName={cn(styles.clearButton, className)}\n\t\t\tonClick={onClick}\n\t\t\taria-label={ariaLabel}>\n\t\t\t<XIcon />\n\t\t</button>\n\t);\n}\n\nfunction resolveEndAdornmentWidth(hasAdornment: boolean, hasClearAction: boolean, explicitWidth?: string) {\n\tif (explicitWidth) {\n\t\treturn explicitWidth;\n\t}\n\n\tif (hasAdornment && hasClearAction) {\n\t\treturn \"calc((var(--control-height) * 2) + var(--space-xs))\";\n\t}\n\n\tif (hasAdornment || hasClearAction) {\n\t\treturn \"var(--control-height)\";\n\t}\n\n\treturn undefined;\n}\n\nfunction createEndAdornment({ endAdornment, onClear, disabled }: { endAdornment?: ReactNode; onClear?: () => void; disabled?: boolean }) {\n\tif ((endAdornment === undefined || endAdornment === null) && !onClear) {\n\t\treturn undefined;\n\t}\n\n\treturn (\n\t\t<div className={styles.endAdornmentGroup}>\n\t\t\t{endAdornment}\n\t\t\t{onClear && <InputClearButton onClick={onClear} disabled={disabled} />}\n\t\t</div>\n\t);\n}\n\nexport interface BaseInputProps<T extends number | string | undefined, V = T>\n\textends Omit<InputHTMLAttributes<HTMLInputElement>, \"size\" | \"value\" | \"type\" | \"defaultValue\" | \"onChange\">, UiBaseProps<T, V> {\n\tonClear?: () => void;\n\terror?: string;\n\tonClearError?: () => void;\n\tdefaultValue?: T;\n\tendAdornment?: ReactNode;\n\tendAdornmentClassName?: string;\n\tendAdornmentWidth?: string;\n}\n\nexport interface InputTextProps extends BaseInputProps<string> {\n\ttype?: \"email\" | \"password\" | \"search\" | \"tel\" | \"text\" | \"url\";\n\n\t/**\n\t * Регулярное выражение для валидации всего введённого значения.\n\t * При несоответствии поле подсвечивается как невалидное, но текст не удаляется.\n\t * Пример: `/^\\d*$/`\n\t */\n\tallowedPattern?: RegExp;\n}\n\n/**\n * Базовое текстовое поле ввода для строковых значений.\n */\nexport function InputText({\n\tlabel,\n\tdescription,\n\tdisabled,\n\tclassName,\n\tonClear,\n\terror,\n\tonClearError,\n\tonChange,\n\tvalue,\n\tsize,\n\tallowedPattern,\n\tendAdornment,\n\tendAdornmentClassName,\n\tendAdornmentWidth,\n\ttype = \"text\",\n\t...props\n}: InputTextProps) {\n\tconst [internalInvalid, setInternalInvalid] = useState(false);\n\n\tconst handleInput = (e: React.ChangeEvent<HTMLInputElement>) => {\n\t\tconst newValue = e.target.value;\n\n\t\tif (allowedPattern !== undefined) {\n\t\t\tsetInternalInvalid(newValue !== \"\" && !allowedPattern.test(newValue));\n\t\t}\n\n\t\tonChange(newValue);\n\t\tif (error && onClearError) onClearError();\n\t};\n\n\tconst hasValue = Boolean(value && value.length > 0);\n\tconst visibleError = hasValue ? error : undefined;\n\tconst { controlId, labelId, descriptionId, errorId, describedBy } = useInputFieldIds({\n\t\tid: props.id,\n\t\thasLabel: label !== undefined && label !== null,\n\t\thasDescription: !!description,\n\t\thasError: !!visibleError\n\t});\n\tconst isInvalid = hasValue && (!!error || internalInvalid);\n\tconst resolvedEndAdornment = createEndAdornment({ endAdornment, onClear, disabled: disabled || !hasValue });\n\tconst hasCustomAdornment = endAdornment !== undefined && endAdornment !== null;\n\tconst resolvedEndAdornmentWidth = resolveEndAdornmentWidth(hasCustomAdornment, !!onClear, endAdornmentWidth);\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\trequired={props.required}\n\t\t\tclassName={className}\n\t\t\tsize={size}\n\t\t\terror={visibleError}\n\t\t\tcontrolId={controlId}\n\t\t\tlabelId={labelId}\n\t\t\tdescriptionId={descriptionId}\n\t\t\terrorId={errorId}>\n\t\t\t<InputControl\n\t\t\t\tendAdornment={resolvedEndAdornment}\n\t\t\t\tendAdornmentClassName={endAdornmentClassName}\n\t\t\t\tendAdornmentWidth={resolvedEndAdornmentWidth}>\n\t\t\t\t{({ controlClassName }) => (\n\t\t\t\t\t<input\n\t\t\t\t\t\t{...props}\n\t\t\t\t\t\tid={controlId}\n\t\t\t\t\t\ttype={type}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tvalue={value}\n\t\t\t\t\t\taria-invalid={isInvalid || undefined}\n\t\t\t\t\t\taria-labelledby={labelId}\n\t\t\t\t\t\taria-describedby={describedBy}\n\t\t\t\t\t\tdata-invalid={isInvalid ? \"\" : undefined}\n\t\t\t\t\t\tclassName={cn(uiStyles.uiInputControl, styles.input, controlClassName)}\n\t\t\t\t\t\tonChange={handleInput}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</InputControl>\n\t\t</InputUI>\n\t);\n}\n\n/**\n * Числовое поле ввода с нормализацией значения и защитой от промежуточного невалидного ввода.\n */\nexport function InputNumber({\n\tlabel,\n\tdescription,\n\tdisabled,\n\tclassName,\n\tonClear,\n\terror,\n\tonClearError,\n\tonChange,\n\tvalue,\n\tsize,\n\tendAdornment,\n\tendAdornmentClassName,\n\tendAdornmentWidth,\n\t...props\n}: BaseInputProps<number | undefined>) {\n\tconst inputProps = props as InputHTMLAttributes<HTMLInputElement>;\n\tconst { controlId, labelId, descriptionId, errorId, describedBy } = useInputFieldIds({\n\t\tid: props.id,\n\t\thasLabel: label !== undefined && label !== null,\n\t\thasDescription: !!description,\n\t\thasError: !!error\n\t});\n\n\tconst inputRef = useRef<HTMLInputElement | null>(null);\n\tconst numberDraftRef = useRef<{ readonly value: number | undefined; readonly raw: string } | null>(null);\n\tconst externalRawValue = value !== undefined && typeof value === \"number\" && !isNaN(value) ? String(value) : \"\";\n\n\t/**\n\t * Числовой input хранит промежуточную строку в DOM, а controlled number остаётся\n\t * источником истины. Layout-effect синхронизирует именно внешнюю DOM-систему,\n\t * поэтому не создаёт каскадного React render и не ломает ввод неполных чисел.\n\t */\n\tuseLayoutEffect(() => {\n\t\tconst numberDraft = numberDraftRef.current;\n\t\tif (numberDraft && Object.is(numberDraft.value, value)) {\n\t\t\tif (inputRef.current && inputRef.current.value !== numberDraft.raw) {\n\t\t\t\tinputRef.current.value = numberDraft.raw;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tnumberDraftRef.current = null;\n\t\tif (inputRef.current && inputRef.current.value !== externalRawValue) {\n\t\t\tinputRef.current.value = externalRawValue;\n\t\t}\n\t}, [externalRawValue, value]);\n\n\tconst handleClear = onClear\n\t\t? () => {\n\t\t\t\tonClear();\n\t\t\t}\n\t\t: undefined;\n\n\tconst handleInput = (e: React.ChangeEvent<HTMLInputElement>) => {\n\t\tconst raw = e.target.value;\n\n\t\tconst parsed = toFiniteNumber(raw); // ?? value ?? 0;\n\t\tnumberDraftRef.current = { value: parsed, raw };\n\n\t\tonChange(parsed);\n\t\tif (error && onClearError) onClearError();\n\t};\n\n\tconst resolvedEndAdornment = createEndAdornment({ endAdornment, onClear: handleClear, disabled });\n\tconst hasCustomAdornment = endAdornment !== undefined && endAdornment !== null;\n\tconst resolvedEndAdornmentWidth = resolveEndAdornmentWidth(hasCustomAdornment, !!handleClear, endAdornmentWidth);\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\trequired={props.required}\n\t\t\tclassName={className}\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<InputControl\n\t\t\t\tendAdornment={resolvedEndAdornment}\n\t\t\t\tendAdornmentClassName={endAdornmentClassName}\n\t\t\t\tendAdornmentWidth={resolvedEndAdornmentWidth}>\n\t\t\t\t{({ controlClassName }) => (\n\t\t\t\t\t<input\n\t\t\t\t\t\t{...inputProps}\n\t\t\t\t\t\tref={inputRef}\n\t\t\t\t\t\tid={controlId}\n\t\t\t\t\t\ttype=\"number\"\n\t\t\t\t\t\tinputMode=\"decimal\"\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\tdefaultValue={externalRawValue}\n\t\t\t\t\t\taria-labelledby={labelId}\n\t\t\t\t\t\taria-describedby={describedBy}\n\t\t\t\t\t\tclassName={cn(uiStyles.uiInputControl, styles.input, styles.inputNumber, controlClassName)}\n\t\t\t\t\t\tonChange={handleInput}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</InputControl>\n\t\t</InputUI>\n\t);\n}\n\n/**\n * Совместимый алиас для `InputText`.\n */\nexport const Input = InputText;\n","import styles from \"../ui.module.scss\";\n\ninterface InputErrorComponentProps {\n\ttext: string;\n}\n\nexport function InputErrorComponent({ text }: InputErrorComponentProps) {\n\treturn <div className={styles.uiErrorElement}>{text}</div>;\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as e } from "./ui.module-DHVTOqZ0.js";
|
|
2
|
-
import { c as t,
|
|
2
|
+
import { c as t, d as n, i as r } from "./input-CCdBtl-C.js";
|
|
3
3
|
import { useCallback as i, useRef as a } from "react";
|
|
4
4
|
import { cn as o, handleKeyboardActivation as s } from "@ryuzaki13/react-foundation-lib/utils";
|
|
5
5
|
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
@@ -41,7 +41,7 @@ function g({ files: e, onChange: t }) {
|
|
|
41
41
|
function _(u) {
|
|
42
42
|
let { value: _, onReadError: v, accept: y, allowedMime: b, maxBytes: x, maxFiles: S, label: C, description: w, placeholder: T = "Выберите файлы", disabled: E, size: D, error: O, onClearError: k, className: A } = u;
|
|
43
43
|
p(b), f(y);
|
|
44
|
-
let j = a(null), { controlId: M, labelId: N, descriptionId: P, errorId: F, describedBy: I } =
|
|
44
|
+
let j = a(null), { controlId: M, labelId: N, descriptionId: P, errorId: F, describedBy: I } = n({
|
|
45
45
|
hasLabel: C != null,
|
|
46
46
|
hasDescription: !!w,
|
|
47
47
|
hasError: !!O
|
|
@@ -115,7 +115,7 @@ function _(u) {
|
|
|
115
115
|
onChange: R,
|
|
116
116
|
tabIndex: -1
|
|
117
117
|
}),
|
|
118
|
-
/* @__PURE__ */ c(
|
|
118
|
+
/* @__PURE__ */ c(r, { children: () => /* @__PURE__ */ c("div", {
|
|
119
119
|
role: "button",
|
|
120
120
|
tabIndex: E || L ? -1 : 0,
|
|
121
121
|
onClick: z,
|
|
@@ -138,4 +138,4 @@ function _(u) {
|
|
|
138
138
|
//#endregion
|
|
139
139
|
export { g as n, _ as t };
|
|
140
140
|
|
|
141
|
-
//# sourceMappingURL=input-files-
|
|
141
|
+
//# sourceMappingURL=input-files-TXdXrSAs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-files-D7iu_1n5.js","names":[],"sources":["../../src/input-files/InputFiles.module.scss","../../src/input-files/InputFilesList.tsx","../../src/input-files/InputFiles.tsx"],"sourcesContent":["/* Контрол, имитирующий внешний вид InputText */\n.control {\n\theight: var(--control-height);\n\twidth: 100%;\n\tpadding: 0 var(--space-sm);\n\tfont-size: var(--font-size-md);\n\tcursor: pointer;\n\n\tdisplay: flex;\n\talign-items: center;\n}\n\n/* Скрытый нативный input[type=\"file\"] */\n.hiddenInput {\n\tposition: absolute;\n\twidth: 0;\n\theight: 0;\n\topacity: 0;\n\toverflow: hidden;\n\tpointer-events: none;\n}\n\n/* Список выбранных файлов */\n.fileList {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: var(--space-xs);\n\tmargin-top: var(--space-xs);\n}\n\n/* Элемент списка — строка с именем файла и кнопкой удаления */\n.fileItem {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: var(--space-xs);\n\tpadding: var(--space-xs) var(--space-sm);\n\tbackground-color: var(--surface-2);\n\tborder-radius: var(--radius-sm);\n\t// font-size: var(--font-size-sm);\n}\n\n/* Имя файла — обрезка с троеточием */\n.fileItemName {\n\tflex: 1;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n\n/* Кнопка удаления файла из списка */\n.removeButton {\n\tflex-shrink: 0;\n\twidth: 1.25em;\n\theight: 1.25em;\n\tcolor: var(--content-2);\n\n\t&:hover {\n\t\tcolor: var(--content-accent);\n\t}\n}\n","import { useCallback } from \"react\";\n\nimport { ReadFileResult } from \"@ryuzaki13/react-foundation-lib/file\";\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { XIcon } from \"lucide-react\";\n\nimport styles from \"./InputFiles.module.scss\";\n\ninterface InputFilesListProps<TFile extends ReadFileResult> {\n\tfiles: TFile[];\n\tonChange: (files: TFile[]) => void;\n}\n\nexport function InputFilesList<TFile extends ReadFileResult>({ files, onChange }: InputFilesListProps<TFile>) {\n\tconst handleRemove = useCallback(\n\t\t(index: number) => {\n\t\t\tonChange(files.filter((_, i) => i !== index));\n\t\t},\n\t\t[files, onChange]\n\t);\n\n\tif (!files || !files.length) return null;\n\n\treturn (\n\t\t<ul className={styles.fileList}>\n\t\t\t{files.map((item, index) => (\n\t\t\t\t<li key={`${item.meta.name}-${item.meta.lastModified}`} className={styles.fileItem}>\n\t\t\t\t\t<span className={styles.fileItemName}>{item.meta.name}</span>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName={cn(styles.removeButton, \"flexCenter\")}\n\t\t\t\t\t\tonClick={() => handleRemove(index)}\n\t\t\t\t\t\taria-label={`Удалить ${item.meta.name}`}>\n\t\t\t\t\t\t<XIcon />\n\t\t\t\t\t</button>\n\t\t\t\t</li>\n\t\t\t))}\n\t\t</ul>\n\t);\n}\n","import { useCallback, useRef } from \"react\";\n\nimport { assertValidAccept, assertValidAllowedMime, readFile, ReadFileError, ReadFileResult } from \"@ryuzaki13/react-foundation-lib/file\";\nimport { cn, handleKeyboardActivation } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { InputControl, InputUI, useInputFieldIds } from \"../input\";\nimport { UiBaseProps } from \"../types\";\nimport uiStyles from \"../ui.module.scss\";\n\nimport styles from \"./InputFiles.module.scss\";\nimport { InputFilesList } from \"./InputFilesList\";\n\ninterface InputFilesCommonProps extends Omit<UiBaseProps<undefined>, \"value\" | \"onChange\"> {\n\t/** Callback ошибки чтения файла */\n\tonReadError?: (error: ReadFileError) => void;\n\n\t/** HTML-атрибут accept для нативного input[type=\"file\"] (например `[\".pdf\", \".docx\"]`) */\n\taccept?: readonly string[];\n\t/** Список допустимых MIME-типов — передаётся в readFile */\n\tallowedMime?: readonly string[];\n\t/** Максимальный размер одного файла в байтах */\n\tmaxBytes?: number;\n\t/** Максимальное количество файлов. При достижении лимита input блокируется */\n\tmaxFiles?: number;\n\n\t/** Текст ошибки под полем */\n\terror?: string;\n\t/** Callback сброса ошибки */\n\tonClearError?: () => void;\n\t/** CSS-класс обёртки */\n\tclassName?: string;\n}\n\ntype InputFilesDataUrlResult = Extract<ReadFileResult, { mode: \"data-url\" }>;\ntype InputFilesArrayBufferResult = Extract<ReadFileResult, { mode: \"array-buffer\" }>;\n\n/**\n * Пропсы компонента InputFiles.\n *\n * Компонент предназначен для выбора нескольких файлов.\n * Выбранные файлы отображаются списком под полем ввода,\n * каждый с кнопкой удаления (крестик).\n *\n * В onChange передаётся обновлённый массив результатов readFile.\n */\nexport type InputFilesProps =\n\t| (InputFilesCommonProps & {\n\t\t\tvalue: InputFilesDataUrlResult[];\n\t\t\tonChange: (value: InputFilesDataUrlResult[]) => void;\n\t\t\t/** Режим чтения: \"data-url\" по умолчанию */\n\t\t\treadMode?: \"data-url\";\n\t })\n\t| (InputFilesCommonProps & {\n\t\t\tvalue: InputFilesArrayBufferResult[];\n\t\t\tonChange: (value: InputFilesArrayBufferResult[]) => void;\n\t\t\t/** Режим чтения файла как ArrayBuffer */\n\t\t\treadMode: \"array-buffer\";\n\t });\n\n/**\n * InputFiles — компонент выбора нескольких файлов.\n *\n * Поле стилизовано как InputText. При клике открывается нативный\n * диалог с multiple. Каждый выбранный файл читается через readFile\n * и добавляется в массив value.\n *\n * Список выбранных файлов отображается под полем.\n * Каждый файл можно удалить кнопкой «крестик».\n *\n * InputFiles типизирует массив по `readMode`.\n * Если `readMode` не задан или равен `\"data-url\"`, в `value` и `onChange`\n * используется массив объектов с `dataUrl`. Если `readMode` равен\n * `\"array-buffer\"`, используется массив объектов с `buffer`.\n */\nexport function InputFiles(props: InputFilesProps) {\n\tconst {\n\t\tvalue,\n\t\tonReadError,\n\t\taccept,\n\t\tallowedMime,\n\t\tmaxBytes,\n\t\tmaxFiles,\n\t\tlabel,\n\t\tdescription,\n\t\tplaceholder = \"Выберите файлы\",\n\t\tdisabled,\n\t\tsize,\n\t\terror,\n\t\tonClearError,\n\t\tclassName\n\t} = props;\n\n\tassertValidAllowedMime(allowedMime);\n\tassertValidAccept(accept);\n\n\t/** Реф на скрытый нативный input[type=\"file\"] */\n\tconst inputRef = useRef<HTMLInputElement>(null);\n\tconst { controlId, labelId, descriptionId, errorId, describedBy } = useInputFieldIds({\n\t\thasLabel: label !== undefined && label !== null,\n\t\thasDescription: !!description,\n\t\thasError: !!error\n\t});\n\n\t/** Достигнут ли лимит файлов */\n\tconst isLimitReached = typeof maxFiles === \"number\" && value.length >= maxFiles;\n\n\t/**\n\t * Обработчик выбора файлов из нативного диалога.\n\t * Каждый файл читается через readFile.\n\t * Успешно прочитанные файлы добавляются к текущему массиву value.\n\t */\n\tconst handleChange = useCallback(\n\t\tasync (e: React.ChangeEvent<HTMLInputElement>) => {\n\t\t\tconst files = e.target.files;\n\t\t\tif (!files || files.length === 0) return;\n\n\t\t\tconst selectedFiles = Array.from(files);\n\n\t\t\t// Сбрасываем значение input чтобы можно было выбрать те же файлы повторно\n\t\t\te.target.value = \"\";\n\n\t\t\t// Сбрасываем ошибку при выборе новых файлов\n\t\t\tif (error && onClearError) onClearError();\n\n\t\t\t// Определяем сколько файлов можно ещё добавить\n\t\t\tconst remaining = typeof maxFiles === \"number\" ? maxFiles - value.length : selectedFiles.length;\n\t\t\tconst filesToProcess = selectedFiles.slice(0, remaining);\n\n\t\t\tif (props.readMode === \"array-buffer\") {\n\t\t\t\t// Читаем файлы как ArrayBuffer и сохраняем точный тип массива для потребителя.\n\t\t\t\tconst results: InputFilesArrayBufferResult[] = [];\n\n\t\t\t\tfor (const file of filesToProcess) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await readFile(file, { allowedMime, maxBytes, mode: \"array-buffer\" });\n\t\t\t\t\t\tresults.push(result);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tif (err instanceof ReadFileError && onReadError) {\n\t\t\t\t\t\t\tonReadError(err);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (results.length > 0) {\n\t\t\t\t\tprops.onChange([...props.value, ...results]);\n\t\t\t\t}\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Читаем файлы как Data URL и сохраняем точный тип массива для потребителя.\n\t\t\tconst results: InputFilesDataUrlResult[] = [];\n\t\t\tfor (const file of filesToProcess) {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await readFile(file, { allowedMime, maxBytes });\n\t\t\t\t\tresults.push(result);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (err instanceof ReadFileError && onReadError) {\n\t\t\t\t\t\tonReadError(err);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (results.length > 0) {\n\t\t\t\tprops.onChange([...props.value, ...results]);\n\t\t\t}\n\t\t},\n\t\t[props, maxFiles, value.length, allowedMime, maxBytes, onReadError, error, onClearError]\n\t);\n\n\t/** Клик по видимому контролу открывает нативный диалог */\n\tconst handleClick = useCallback(() => {\n\t\tinputRef.current?.click();\n\t}, []);\n\n\tconst filesList =\n\t\tprops.readMode === \"array-buffer\" ? (\n\t\t\t<InputFilesList files={props.value} onChange={props.onChange} />\n\t\t) : (\n\t\t\t<InputFilesList files={props.value} onChange={props.onChange} />\n\t\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\tclassName={className}\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<input\n\t\t\t\tref={inputRef}\n\t\t\t\tid={controlId}\n\t\t\t\ttype=\"file\"\n\t\t\t\taccept={(accept ?? allowedMime)?.join(\",\")}\n\t\t\t\tmultiple\n\t\t\t\tdisabled={disabled || isLimitReached}\n\t\t\t\tclassName={styles.hiddenInput}\n\t\t\t\tonChange={handleChange}\n\t\t\t\ttabIndex={-1}\n\t\t\t/>\n\n\t\t\t<InputControl>\n\t\t\t\t{() => (\n\t\t\t\t\t<div\n\t\t\t\t\t\trole=\"button\"\n\t\t\t\t\t\ttabIndex={disabled || isLimitReached ? -1 : 0}\n\t\t\t\t\t\tonClick={handleClick}\n\t\t\t\t\t\tonKeyDown={(event) => handleKeyboardActivation(event, handleClick, { disabled: disabled || isLimitReached })}\n\t\t\t\t\t\tclassName={cn(uiStyles.uiInputControl, styles.control, !!error && \"invalid\")}\n\t\t\t\t\t\tdata-disabled={disabled || undefined}\n\t\t\t\t\t\taria-invalid={!!error || undefined}\n\t\t\t\t\t\taria-disabled={disabled || isLimitReached}\n\t\t\t\t\t\taria-labelledby={labelId}\n\t\t\t\t\t\taria-describedby={describedBy}>\n\t\t\t\t\t\t<span className={uiStyles.uiPlaceholder}>{isLimitReached ? `Максимум ${maxFiles} файлов` : placeholder}</span>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</InputControl>\n\n\t\t\t{/* Список выбранных файлов */}\n\t\t\t{filesList}\n\t\t</InputUI>\n\t);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"input-files-TXdXrSAs.js","names":[],"sources":["../../src/input-files/InputFiles.module.scss","../../src/input-files/InputFilesList.tsx","../../src/input-files/InputFiles.tsx"],"sourcesContent":["/* Контрол, имитирующий внешний вид InputText */\n.control {\n\theight: var(--control-height);\n\twidth: 100%;\n\tpadding: 0 var(--space-sm);\n\tfont-size: var(--font-size-md);\n\tcursor: pointer;\n\n\tdisplay: flex;\n\talign-items: center;\n}\n\n/* Скрытый нативный input[type=\"file\"] */\n.hiddenInput {\n\tposition: absolute;\n\twidth: 0;\n\theight: 0;\n\topacity: 0;\n\toverflow: hidden;\n\tpointer-events: none;\n}\n\n/* Список выбранных файлов */\n.fileList {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: var(--space-xs);\n\tmargin-top: var(--space-xs);\n}\n\n/* Элемент списка — строка с именем файла и кнопкой удаления */\n.fileItem {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: var(--space-xs);\n\tpadding: var(--space-xs) var(--space-sm);\n\tbackground-color: var(--surface-2);\n\tborder-radius: var(--radius-sm);\n\t// font-size: var(--font-size-sm);\n}\n\n/* Имя файла — обрезка с троеточием */\n.fileItemName {\n\tflex: 1;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n\n/* Кнопка удаления файла из списка */\n.removeButton {\n\tflex-shrink: 0;\n\twidth: 1.25em;\n\theight: 1.25em;\n\tcolor: var(--content-2);\n\n\t&:hover {\n\t\tcolor: var(--content-accent);\n\t}\n}\n","import { useCallback } from \"react\";\n\nimport { ReadFileResult } from \"@ryuzaki13/react-foundation-lib/file\";\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { XIcon } from \"lucide-react\";\n\nimport styles from \"./InputFiles.module.scss\";\n\ninterface InputFilesListProps<TFile extends ReadFileResult> {\n\tfiles: TFile[];\n\tonChange: (files: TFile[]) => void;\n}\n\nexport function InputFilesList<TFile extends ReadFileResult>({ files, onChange }: InputFilesListProps<TFile>) {\n\tconst handleRemove = useCallback(\n\t\t(index: number) => {\n\t\t\tonChange(files.filter((_, i) => i !== index));\n\t\t},\n\t\t[files, onChange]\n\t);\n\n\tif (!files || !files.length) return null;\n\n\treturn (\n\t\t<ul className={styles.fileList}>\n\t\t\t{files.map((item, index) => (\n\t\t\t\t<li key={`${item.meta.name}-${item.meta.lastModified}`} className={styles.fileItem}>\n\t\t\t\t\t<span className={styles.fileItemName}>{item.meta.name}</span>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName={cn(styles.removeButton, \"flexCenter\")}\n\t\t\t\t\t\tonClick={() => handleRemove(index)}\n\t\t\t\t\t\taria-label={`Удалить ${item.meta.name}`}>\n\t\t\t\t\t\t<XIcon />\n\t\t\t\t\t</button>\n\t\t\t\t</li>\n\t\t\t))}\n\t\t</ul>\n\t);\n}\n","import { useCallback, useRef } from \"react\";\n\nimport { assertValidAccept, assertValidAllowedMime, readFile, ReadFileError, ReadFileResult } from \"@ryuzaki13/react-foundation-lib/file\";\nimport { cn, handleKeyboardActivation } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { InputControl, InputUI, useInputFieldIds } from \"../input\";\nimport { UiBaseProps } from \"../types\";\nimport uiStyles from \"../ui.module.scss\";\n\nimport styles from \"./InputFiles.module.scss\";\nimport { InputFilesList } from \"./InputFilesList\";\n\ninterface InputFilesCommonProps extends Omit<UiBaseProps<undefined>, \"value\" | \"onChange\"> {\n\t/** Callback ошибки чтения файла */\n\tonReadError?: (error: ReadFileError) => void;\n\n\t/** HTML-атрибут accept для нативного input[type=\"file\"] (например `[\".pdf\", \".docx\"]`) */\n\taccept?: readonly string[];\n\t/** Список допустимых MIME-типов — передаётся в readFile */\n\tallowedMime?: readonly string[];\n\t/** Максимальный размер одного файла в байтах */\n\tmaxBytes?: number;\n\t/** Максимальное количество файлов. При достижении лимита input блокируется */\n\tmaxFiles?: number;\n\n\t/** Текст ошибки под полем */\n\terror?: string;\n\t/** Callback сброса ошибки */\n\tonClearError?: () => void;\n\t/** CSS-класс обёртки */\n\tclassName?: string;\n}\n\ntype InputFilesDataUrlResult = Extract<ReadFileResult, { mode: \"data-url\" }>;\ntype InputFilesArrayBufferResult = Extract<ReadFileResult, { mode: \"array-buffer\" }>;\n\n/**\n * Пропсы компонента InputFiles.\n *\n * Компонент предназначен для выбора нескольких файлов.\n * Выбранные файлы отображаются списком под полем ввода,\n * каждый с кнопкой удаления (крестик).\n *\n * В onChange передаётся обновлённый массив результатов readFile.\n */\nexport type InputFilesProps =\n\t| (InputFilesCommonProps & {\n\t\t\tvalue: InputFilesDataUrlResult[];\n\t\t\tonChange: (value: InputFilesDataUrlResult[]) => void;\n\t\t\t/** Режим чтения: \"data-url\" по умолчанию */\n\t\t\treadMode?: \"data-url\";\n\t })\n\t| (InputFilesCommonProps & {\n\t\t\tvalue: InputFilesArrayBufferResult[];\n\t\t\tonChange: (value: InputFilesArrayBufferResult[]) => void;\n\t\t\t/** Режим чтения файла как ArrayBuffer */\n\t\t\treadMode: \"array-buffer\";\n\t });\n\n/**\n * InputFiles — компонент выбора нескольких файлов.\n *\n * Поле стилизовано как InputText. При клике открывается нативный\n * диалог с multiple. Каждый выбранный файл читается через readFile\n * и добавляется в массив value.\n *\n * Список выбранных файлов отображается под полем.\n * Каждый файл можно удалить кнопкой «крестик».\n *\n * InputFiles типизирует массив по `readMode`.\n * Если `readMode` не задан или равен `\"data-url\"`, в `value` и `onChange`\n * используется массив объектов с `dataUrl`. Если `readMode` равен\n * `\"array-buffer\"`, используется массив объектов с `buffer`.\n */\nexport function InputFiles(props: InputFilesProps) {\n\tconst {\n\t\tvalue,\n\t\tonReadError,\n\t\taccept,\n\t\tallowedMime,\n\t\tmaxBytes,\n\t\tmaxFiles,\n\t\tlabel,\n\t\tdescription,\n\t\tplaceholder = \"Выберите файлы\",\n\t\tdisabled,\n\t\tsize,\n\t\terror,\n\t\tonClearError,\n\t\tclassName\n\t} = props;\n\n\tassertValidAllowedMime(allowedMime);\n\tassertValidAccept(accept);\n\n\t/** Реф на скрытый нативный input[type=\"file\"] */\n\tconst inputRef = useRef<HTMLInputElement>(null);\n\tconst { controlId, labelId, descriptionId, errorId, describedBy } = useInputFieldIds({\n\t\thasLabel: label !== undefined && label !== null,\n\t\thasDescription: !!description,\n\t\thasError: !!error\n\t});\n\n\t/** Достигнут ли лимит файлов */\n\tconst isLimitReached = typeof maxFiles === \"number\" && value.length >= maxFiles;\n\n\t/**\n\t * Обработчик выбора файлов из нативного диалога.\n\t * Каждый файл читается через readFile.\n\t * Успешно прочитанные файлы добавляются к текущему массиву value.\n\t */\n\tconst handleChange = useCallback(\n\t\tasync (e: React.ChangeEvent<HTMLInputElement>) => {\n\t\t\tconst files = e.target.files;\n\t\t\tif (!files || files.length === 0) return;\n\n\t\t\tconst selectedFiles = Array.from(files);\n\n\t\t\t// Сбрасываем значение input чтобы можно было выбрать те же файлы повторно\n\t\t\te.target.value = \"\";\n\n\t\t\t// Сбрасываем ошибку при выборе новых файлов\n\t\t\tif (error && onClearError) onClearError();\n\n\t\t\t// Определяем сколько файлов можно ещё добавить\n\t\t\tconst remaining = typeof maxFiles === \"number\" ? maxFiles - value.length : selectedFiles.length;\n\t\t\tconst filesToProcess = selectedFiles.slice(0, remaining);\n\n\t\t\tif (props.readMode === \"array-buffer\") {\n\t\t\t\t// Читаем файлы как ArrayBuffer и сохраняем точный тип массива для потребителя.\n\t\t\t\tconst results: InputFilesArrayBufferResult[] = [];\n\n\t\t\t\tfor (const file of filesToProcess) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await readFile(file, { allowedMime, maxBytes, mode: \"array-buffer\" });\n\t\t\t\t\t\tresults.push(result);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tif (err instanceof ReadFileError && onReadError) {\n\t\t\t\t\t\t\tonReadError(err);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (results.length > 0) {\n\t\t\t\t\tprops.onChange([...props.value, ...results]);\n\t\t\t\t}\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Читаем файлы как Data URL и сохраняем точный тип массива для потребителя.\n\t\t\tconst results: InputFilesDataUrlResult[] = [];\n\t\t\tfor (const file of filesToProcess) {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await readFile(file, { allowedMime, maxBytes });\n\t\t\t\t\tresults.push(result);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (err instanceof ReadFileError && onReadError) {\n\t\t\t\t\t\tonReadError(err);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (results.length > 0) {\n\t\t\t\tprops.onChange([...props.value, ...results]);\n\t\t\t}\n\t\t},\n\t\t[props, maxFiles, value.length, allowedMime, maxBytes, onReadError, error, onClearError]\n\t);\n\n\t/** Клик по видимому контролу открывает нативный диалог */\n\tconst handleClick = useCallback(() => {\n\t\tinputRef.current?.click();\n\t}, []);\n\n\tconst filesList =\n\t\tprops.readMode === \"array-buffer\" ? (\n\t\t\t<InputFilesList files={props.value} onChange={props.onChange} />\n\t\t) : (\n\t\t\t<InputFilesList files={props.value} onChange={props.onChange} />\n\t\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\tclassName={className}\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<input\n\t\t\t\tref={inputRef}\n\t\t\t\tid={controlId}\n\t\t\t\ttype=\"file\"\n\t\t\t\taccept={(accept ?? allowedMime)?.join(\",\")}\n\t\t\t\tmultiple\n\t\t\t\tdisabled={disabled || isLimitReached}\n\t\t\t\tclassName={styles.hiddenInput}\n\t\t\t\tonChange={handleChange}\n\t\t\t\ttabIndex={-1}\n\t\t\t/>\n\n\t\t\t<InputControl>\n\t\t\t\t{() => (\n\t\t\t\t\t<div\n\t\t\t\t\t\trole=\"button\"\n\t\t\t\t\t\ttabIndex={disabled || isLimitReached ? -1 : 0}\n\t\t\t\t\t\tonClick={handleClick}\n\t\t\t\t\t\tonKeyDown={(event) => handleKeyboardActivation(event, handleClick, { disabled: disabled || isLimitReached })}\n\t\t\t\t\t\tclassName={cn(uiStyles.uiInputControl, styles.control, !!error && \"invalid\")}\n\t\t\t\t\t\tdata-disabled={disabled || undefined}\n\t\t\t\t\t\taria-invalid={!!error || undefined}\n\t\t\t\t\t\taria-disabled={disabled || isLimitReached}\n\t\t\t\t\t\taria-labelledby={labelId}\n\t\t\t\t\t\taria-describedby={describedBy}>\n\t\t\t\t\t\t<span className={uiStyles.uiPlaceholder}>{isLimitReached ? `Максимум ${maxFiles} файлов` : placeholder}</span>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</InputControl>\n\n\t\t\t{/* Список выбранных файлов */}\n\t\t\t{filesList}\n\t\t</InputUI>\n\t);\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as e } from "./input-
|
|
1
|
+
import { n as e } from "./input-CCdBtl-C.js";
|
|
2
2
|
import { useState as t } from "react";
|
|
3
3
|
import { jsx as n } from "react/jsx-runtime";
|
|
4
4
|
//#region src/input-search/InputSearch.tsx
|
|
@@ -27,4 +27,4 @@ function r({ onChange: r, ...i }) {
|
|
|
27
27
|
//#endregion
|
|
28
28
|
export { r as t };
|
|
29
29
|
|
|
30
|
-
//# sourceMappingURL=input-search-
|
|
30
|
+
//# sourceMappingURL=input-search-Ca8iqeK2.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-search-
|
|
1
|
+
{"version":3,"file":"input-search-Ca8iqeK2.js","names":[],"sources":["../../src/input-search/InputSearch.tsx"],"sourcesContent":["import React, { useState } from \"react\";\n\nimport { BaseInputProps, Input } from \"../input\";\n\ninterface SearchInputProps extends BaseInputProps<string> {\n\tonChange: (value: string) => void;\n}\n\nexport function InputSearch({ onChange, ...props }: SearchInputProps) {\n\tconst [searchTerm, setSearchTerm] = useState(() => props.defaultValue ?? props.value ?? \"\");\n\tconst [previousSearch, setPreviousSearch] = useState(() => props.defaultValue ?? props.value ?? \"\");\n\n\tconst handleSearch = (term: string) => {\n\t\tconst changedTerm = term.trim();\n\n\t\t// Проверяем, изменилось ли значение с предыдущего поиска\n\t\tif (changedTerm === previousSearch) return;\n\n\t\tsetPreviousSearch(changedTerm);\n\t\tonChange(changedTerm);\n\t};\n\n\tconst handleClear = () => {\n\t\tsetSearchTerm(\"\");\n\t\tsetPreviousSearch(\"\");\n\t\tonChange(\"\");\n\t};\n\n\tconst handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n\t\tif (event.key === \"Enter\") {\n\t\t\tevent.preventDefault();\n\t\t\thandleSearch(searchTerm);\n\t\t}\n\t};\n\n\tconst handleBlur = () => {\n\t\thandleSearch(searchTerm);\n\t};\n\n\tconst handleChange = (value: string) => {\n\t\tsetSearchTerm(value);\n\t\t// Не вызываем onSearch здесь - только по Enter/blur\n\t};\n\n\treturn (\n\t\t<Input {...props} value={searchTerm} onChange={handleChange} onKeyDown={handleKeyDown} onBlur={handleBlur} onClear={handleClear} />\n\t);\n}\n"],"mappings":";;;;AAQA,SAAgB,EAAY,EAAE,aAAU,GAAG,KAA2B;CACrE,IAAM,CAAC,GAAY,KAAiB,QAAe,EAAM,gBAAgB,EAAM,SAAS,EAAE,GACpF,CAAC,GAAgB,KAAqB,QAAe,EAAM,gBAAgB,EAAM,SAAS,EAAE,GAE5F,KAAgB,MAAiB;EACtC,IAAM,IAAc,EAAK,KAAK;EAG1B,MAAgB,MAEpB,EAAkB,CAAW,GAC7B,EAAS,CAAW;CACrB,GAEM,UAAoB;EAGzB,AAFA,EAAc,EAAE,GAChB,EAAkB,EAAE,GACpB,EAAS,EAAE;CACZ,GAEM,KAAiB,MAAiD;EACvE,AAAI,EAAM,QAAQ,YACjB,EAAM,eAAe,GACrB,EAAa,CAAU;CAEzB,GAEM,UAAmB;EACxB,EAAa,CAAU;CACxB,GAEM,KAAgB,MAAkB;EACvC,EAAc,CAAK;CAEpB;CAEA,OACC,kBAAC,GAAD;EAAO,GAAI;EAAO,OAAO;EAAY,UAAU;EAAc,WAAW;EAAe,QAAQ;EAAY,SAAS;CAAc,CAAA;AAEpI"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as e } from "./ui.module-DHVTOqZ0.js";
|
|
2
2
|
import { Text as t } from "../text/index.js";
|
|
3
3
|
import { t as n } from "./check-box-sfGjYczQ.js";
|
|
4
|
-
import { a as r, c as i, d as a, f as o, i as s, l as c, n as l, p as u, r as d, t as f, u as p } from "./picker-
|
|
4
|
+
import { a as r, c as i, d as a, f as o, i as s, l as c, n as l, p as u, r as d, t as f, u as p } from "./picker-CrRdwdA5.js";
|
|
5
5
|
import { t as ee } from "./separator-B72Aq-6a.js";
|
|
6
6
|
import { n as m, r as h, t as g } from "./useODataSelectBase-Bq36Wp1U.js";
|
|
7
7
|
import { forwardRef as _, useCallback as te, useMemo as v, useRef as ne, useState as y } from "react";
|
|
@@ -524,4 +524,4 @@ function I({ label: e, description: t, disabled: n, placeholder: r, size: i, opt
|
|
|
524
524
|
//#endregion
|
|
525
525
|
export { k as a, j as i, N as n, T as o, M as r, C as s, I as t };
|
|
526
526
|
|
|
527
|
-
//# sourceMappingURL=multi-select-
|
|
527
|
+
//# sourceMappingURL=multi-select-Bs1GU5MD.js.map
|