@ryuzaki13/react-foundation-ui 3.8.3 → 3.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/base-table/index.js +1 -1
- package/dist/chunks/{TextEditorLexicalClient-U-sTxmCU.js → TextEditorLexicalClient-BQH41FFT.js} +2 -2
- package/dist/chunks/{TextEditorLexicalClient-U-sTxmCU.js.map → TextEditorLexicalClient-BQH41FFT.js.map} +1 -1
- package/dist/chunks/{base-table-BMesCx6H.js → base-table-9H5YuVvB.js} +2 -2
- package/dist/chunks/{base-table-BMesCx6H.js.map → base-table-9H5YuVvB.js.map} +1 -1
- package/dist/chunks/{context-menu-CrSXJxQL.js → context-menu-BV8636Ou.js} +2 -2
- package/dist/chunks/{context-menu-CrSXJxQL.js.map → context-menu-BV8636Ou.js.map} +1 -1
- package/dist/chunks/{date-input-CzCDou4s.js → date-input-B7iG9cA7.js} +2 -2
- package/dist/chunks/{date-input-CzCDou4s.js.map → date-input-B7iG9cA7.js.map} +1 -1
- package/dist/chunks/{input-CuRK9Vbz.js → input-KXI7o06g.js} +7 -7
- package/dist/chunks/input-KXI7o06g.js.map +1 -0
- package/dist/chunks/{input-files-B8j6Pb_M.js → input-files-CnBNlJo0.js} +2 -2
- package/dist/chunks/{input-files-B8j6Pb_M.js.map → input-files-CnBNlJo0.js.map} +1 -1
- package/dist/chunks/{picker-SJXnHwsj.js → picker-DagDe9OH.js} +17 -16
- package/dist/chunks/picker-DagDe9OH.js.map +1 -0
- package/dist/chunks/select-C-1U-ujV.js +368 -0
- package/dist/chunks/select-C-1U-ujV.js.map +1 -0
- package/dist/chunks/{table-OvvWkKfy.js → table-BRC1OTyE.js} +2 -2
- package/dist/chunks/{table-OvvWkKfy.js.map → table-BRC1OTyE.js.map} +1 -1
- package/dist/context-menu/index.js +1 -1
- package/dist/date-input/index.js +1 -1
- package/dist/date-time-input/index.js +1 -1
- package/dist/drop-zone/index.js +1 -1
- package/dist/image/index.js +2 -2
- package/dist/input/Input.d.ts +2 -2
- package/dist/input/Input.d.ts.map +1 -1
- package/dist/input/index.js +1 -1
- package/dist/input-date-time/index.js +1 -1
- package/dist/input-file/index.js +1 -1
- package/dist/input-files/index.js +1 -1
- package/dist/input-image/index.js +1 -1
- package/dist/input-search/index.js +1 -1
- package/dist/layout-picker/index.js +1 -1
- package/dist/listbox/index.js +1 -1
- package/dist/multi-select/index.js +171 -161
- package/dist/multi-select/index.js.map +1 -1
- package/dist/multi-select/ui/DeprecatedMultiSelect.d.ts +2 -0
- package/dist/multi-select/ui/DeprecatedMultiSelect.d.ts.map +1 -1
- package/dist/multi-select/ui/MultiSelect.d.ts +3 -0
- package/dist/multi-select/ui/MultiSelect.d.ts.map +1 -1
- package/dist/multi-select/ui/MultiSelectCore.d.ts +1 -1
- package/dist/multi-select/ui/MultiSelectCore.d.ts.map +1 -1
- package/dist/multi-select/ui/ODataDependentSegmentMultiSelect.d.ts.map +1 -1
- package/dist/multi-select/ui/ODataMultiSelect.d.ts +5 -2
- package/dist/multi-select/ui/ODataMultiSelect.d.ts.map +1 -1
- package/dist/multi-select/ui/SerializableMultiSelect.d.ts +3 -1
- package/dist/multi-select/ui/SerializableMultiSelect.d.ts.map +1 -1
- package/dist/odata-dependent/ODataDependentSegmentControlProps.d.ts +4 -0
- package/dist/odata-dependent/ODataDependentSegmentControlProps.d.ts.map +1 -1
- package/dist/period-select/PeriodSelect.d.ts +2 -0
- package/dist/period-select/PeriodSelect.d.ts.map +1 -1
- package/dist/period-select/index.js.map +1 -1
- package/dist/picker/PickerField.d.ts +1 -1
- package/dist/picker/PickerField.d.ts.map +1 -1
- package/dist/picker/PickerTriggerInput.d.ts.map +1 -1
- package/dist/picker/index.js +1 -1
- package/dist/picker/types.d.ts +2 -0
- package/dist/picker/types.d.ts.map +1 -1
- package/dist/preset-range-date-input/index.js +1 -1
- package/dist/preset-select/PresetSelect.d.ts +2 -0
- package/dist/preset-select/PresetSelect.d.ts.map +1 -1
- package/dist/preset-select/index.js +1 -1
- package/dist/preset-select/index.js.map +1 -1
- package/dist/select/ODataDependentSegmentSelect.d.ts.map +1 -1
- package/dist/select/ODataSelect.d.ts +3 -1
- package/dist/select/ODataSelect.d.ts.map +1 -1
- package/dist/select/Select.d.ts +3 -0
- package/dist/select/Select.d.ts.map +1 -1
- package/dist/select/SerializableSelect.d.ts +3 -1
- package/dist/select/SerializableSelect.d.ts.map +1 -1
- package/dist/select/index.js +1 -1
- package/dist/simple-table/index.js +1 -1
- package/dist/slider/index.js +2 -2
- package/dist/state-select/StateSelect.d.ts +3 -1
- package/dist/state-select/StateSelect.d.ts.map +1 -1
- package/dist/state-select/index.js +10 -8
- package/dist/state-select/index.js.map +1 -1
- package/dist/table/index.js +1 -1
- package/dist/table-editor/index.js +1 -1
- package/dist/table-sorting/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/ODataTreeMultiSelect.d.ts +3 -1
- package/dist/tree-select/ODataTreeMultiSelect.d.ts.map +1 -1
- package/dist/tree-select/ODataTreeSelect.d.ts +3 -1
- package/dist/tree-select/ODataTreeSelect.d.ts.map +1 -1
- package/dist/tree-select/TreeMultiSelect.d.ts +4 -1
- package/dist/tree-select/TreeMultiSelect.d.ts.map +1 -1
- package/dist/tree-select/TreePickerBase.d.ts +3 -1
- package/dist/tree-select/TreePickerBase.d.ts.map +1 -1
- package/dist/tree-select/TreeSelect.d.ts +4 -1
- package/dist/tree-select/TreeSelect.d.ts.map +1 -1
- package/dist/tree-select/index.js +271 -259
- package/dist/tree-select/index.js.map +1 -1
- package/dist/tree-table/index.js +1 -1
- package/package.json +1 -1
- package/storybook-static/assets/{Badge-Exgo2liR.js → Badge-CL58JilM.js} +1 -1
- package/storybook-static/assets/{Badge.stories-BSZPB2hP.js → Badge.stories-CXFTvV3D.js} +1 -1
- package/storybook-static/assets/{BadgeList-vXAflISJ.js → BadgeList-DLssobfd.js} +1 -1
- package/storybook-static/assets/{BarcodeScannerDialog.stories-B5JJTqxe.js → BarcodeScannerDialog.stories-CpMywpKq.js} +1 -1
- package/storybook-static/assets/{Button-W5ftYk1w.js → Button-CSbLv1K7.js} +1 -1
- package/storybook-static/assets/{Button-BzRtAjtM.js → Button-DMAPWgMI.js} +1 -1
- package/storybook-static/assets/{Button.stories-DcuEJMqp.js → Button.stories-CU1kYMvA.js} +1 -1
- package/storybook-static/assets/{CalendarView-C8taheM_.js → CalendarView-DuCLo_x5.js} +1 -1
- package/storybook-static/assets/{CheckBox-C-EWY4_-.js → CheckBox-BBPasWSk.js} +1 -1
- package/storybook-static/assets/{CheckBox-Cahw6EU8.js → CheckBox-Bfcdvr2o.js} +1 -1
- package/storybook-static/assets/{CheckBox.stories-DL49eu_s.js → CheckBox.stories-sGH6EuU4.js} +1 -1
- package/storybook-static/assets/{Color-6AOWCN3U-B0iuSBAP.js → Color-6AOWCN3U-5NJhf8m9.js} +1 -1
- package/storybook-static/assets/{ContextMenu-DqLKk-wW.js → ContextMenu-CxuYkXjJ.js} +1 -1
- package/storybook-static/assets/{ContextMenu-k1Mubm6h.js → ContextMenu-z6NKmD0I.js} +1 -1
- package/storybook-static/assets/{ContextMenu.stories-CNnrfTxO.js → ContextMenu.stories-CI5IW_KX.js} +1 -1
- package/storybook-static/assets/{DateInput-CgBBiqYK.js → DateInput-A8NURpCX.js} +1 -1
- package/storybook-static/assets/{DateInput-NSuuc0Vu.js → DateInput-BkCbK0M5.js} +1 -1
- package/storybook-static/assets/{DateInput.stories-eWY9Pqwp.js → DateInput.stories-DnzeyBpg.js} +1 -1
- package/storybook-static/assets/{DateRangePresetSelect-Ch6rsktY.js → DateRangePresetSelect-Bh7qMFTr.js} +1 -1
- package/storybook-static/assets/{DateRangePresetSelect-DibXoV_U.js → DateRangePresetSelect-CGZkf8Ty.js} +1 -1
- package/storybook-static/assets/{DateRangePresetSelect.stories-B8yndfPd.js → DateRangePresetSelect.stories-Drm2FCnJ.js} +1 -1
- package/storybook-static/assets/{DeprecatedMultiSelect-D8BCr3qw.js → DeprecatedMultiSelect-8TWWhsLi.js} +1 -1
- package/storybook-static/assets/{DeprecatedMultiSelect-1K4GSVRr.js → DeprecatedMultiSelect-BebYsPmQ.js} +1 -1
- package/storybook-static/assets/{DeprecatedMultiSelect.stories-DH7fIprL.js → DeprecatedMultiSelect.stories-7iL6YOgh.js} +1 -1
- package/storybook-static/assets/{Detail-CzQ7DLhL.js → Detail-BOZkPwOI.js} +1 -1
- package/storybook-static/assets/{Detail.stories-DzmSAGkt.js → Detail.stories-RZALoKmD.js} +1 -1
- package/storybook-static/assets/{Dialog-DEDDnDtQ.js → Dialog-BsslYClj.js} +1 -1
- package/storybook-static/assets/{Dialog-Cm7gLcJI.js → Dialog-CeukIYpx.js} +1 -1
- package/storybook-static/assets/{Dialog.stories-BzvBjaiX.js → Dialog.stories-y7MpdGQr.js} +1 -1
- package/storybook-static/assets/{Disclosure-Bpji7KuP.js → Disclosure-CiTnWx5y.js} +1 -1
- package/storybook-static/assets/{Disclosure.stories-Bwuzf5fl.js → Disclosure.stories-UWW9oheF.js} +1 -1
- package/storybook-static/assets/{DisclosureGroup-bCpsF5YE.js → DisclosureGroup-CT3BdQXr.js} +1 -1
- package/storybook-static/assets/{DocsRenderer-JROSPFPF-DQRIOLjc.js → DocsRenderer-JROSPFPF-x50rjjKP.js} +1 -1
- package/storybook-static/assets/{DropZone-Diu_Hlgs.js → DropZone-DUn9vW2w.js} +1 -1
- package/storybook-static/assets/{DropZone-qvCLdJmm.js → DropZone-gWSeoAx6.js} +1 -1
- package/storybook-static/assets/{DropZone.stories-DHgexefI.js → DropZone.stories-CmaVl9to.js} +1 -1
- package/storybook-static/assets/{DropdownMenu-Bl2IPF3Q.js → DropdownMenu-DkeS8gOF.js} +1 -1
- package/storybook-static/assets/{ExpandableActionPanel-B3iQGrX8.js → ExpandableActionPanel-DdqWZDe2.js} +1 -1
- package/storybook-static/assets/{ExpandableActionPanel.stories-DRnMPxSP.js → ExpandableActionPanel.stories-CA-dpb07.js} +1 -1
- package/storybook-static/assets/{Flex-CrWmRoxc.js → Flex-DpQpF63N.js} +1 -1
- package/storybook-static/assets/{Flex.stories-Db20If9k.js → Flex.stories-DtlKiJno.js} +1 -1
- package/storybook-static/assets/{FlexContainer-YYPiKtpT.js → FlexContainer-C1d63I55.js} +1 -1
- package/storybook-static/assets/{FlexItem-CXY6tvoB.js → FlexItem-DsoW-br3.js} +1 -1
- package/storybook-static/assets/{FloatingPopover-DSRofmW2.js → FloatingPopover-7MpESGU4.js} +1 -1
- package/storybook-static/assets/{FormattedTableCell-B-t0D2oX.js → FormattedTableCell-B4RRbSFK.js} +1 -1
- package/storybook-static/assets/{Grid-Ad2q9giD.js → Grid-DsCUaz46.js} +1 -1
- package/storybook-static/assets/{Grid-CUmJniwF.js → Grid-eqZxtRIA.js} +1 -1
- package/storybook-static/assets/{Grid.stories-CsohhjMJ.js → Grid.stories-DAGg0GWi.js} +1 -1
- package/storybook-static/assets/{GridContainer-DfZnU_h-.js → GridContainer-B9JaLUGE.js} +1 -1
- package/storybook-static/assets/{ImageCropper.stories-Bdg7E1B6.js → ImageCropper.stories-W76XOOMv.js} +1 -1
- package/storybook-static/assets/{ImageRenderer-DEsg7Nf5.js → ImageRenderer-DYg7BkPO.js} +1 -1
- package/storybook-static/assets/{ImageRenderer.stories-C2uPYFbK.js → ImageRenderer.stories-rgJV0OBp.js} +1 -1
- package/storybook-static/assets/{ImageView.stories-qFIo_3jG.js → ImageView.stories-D9h6sg3j.js} +1 -1
- package/storybook-static/assets/{ImageViewer.stories-D6RoxWRG.js → ImageViewer.stories-Bd0WJOp1.js} +2 -2
- package/storybook-static/assets/{ImageViewerRuntime-DEVRfnpp.js → ImageViewerRuntime-DOjvjbv0.js} +1 -1
- package/storybook-static/assets/Input-7N70tL0u.js +3 -0
- package/storybook-static/assets/{Input-CXSVW4qb.js → Input-BxrxwNyD.js} +1 -1
- package/storybook-static/assets/{Input.stories-CKUo8mda.js → Input.stories-Df1j802b.js} +1 -1
- package/storybook-static/assets/{InputDateTime-CBgevl2k.js → InputDateTime-UdemHZXV.js} +1 -1
- package/storybook-static/assets/{InputDateTime.stories-Dc_yRirT.js → InputDateTime.stories-yRwAe5_5.js} +1 -1
- package/storybook-static/assets/{InputFile-VkGuvstd.js → InputFile-5LpFR1Fq.js} +1 -1
- package/storybook-static/assets/{InputFile-BX9qIipq.js → InputFile-DDhf7A_J.js} +1 -1
- package/storybook-static/assets/{InputFile.stories-VernHNAn.js → InputFile.stories-BVDT-BAx.js} +1 -1
- package/storybook-static/assets/{InputFiles-BpSb2G11.js → InputFiles-CgM2BwNO.js} +1 -1
- package/storybook-static/assets/{InputFiles-CRFuNd-6.js → InputFiles-D3CPIXiK.js} +1 -1
- package/storybook-static/assets/{InputFiles.stories-CfrGV2lA.js → InputFiles.stories-XMHBA9Fn.js} +1 -1
- package/storybook-static/assets/{InputFilesList-BoL4jQmC.js → InputFilesList-DSivq9iT.js} +1 -1
- package/storybook-static/assets/{InputImage-BKfXCZHx.js → InputImage-BG_QyAh3.js} +1 -1
- package/storybook-static/assets/{InputImage-BcUm7aKp.js → InputImage-CY0A9Xz-.js} +1 -1
- package/storybook-static/assets/{InputImage.stories-l1xnaTXn.js → InputImage.stories-DiGXytZU.js} +1 -1
- package/storybook-static/assets/{InteractiveComponents-DKix-b3k.js → InteractiveComponents-Bf9KitNR.js} +5 -5
- package/storybook-static/assets/{InteractiveComponents.stories-CK118Tbj.js → InteractiveComponents.stories-TwALUGGN.js} +1 -1
- package/storybook-static/assets/{LayoutPicker-Ca57uusp.js → LayoutPicker-BLrNe8g_.js} +1 -1
- package/storybook-static/assets/{LayoutPicker-BqI2-D2r.js → LayoutPicker-MhA9N4WI.js} +1 -1
- package/storybook-static/assets/{LayoutPicker.stories-BDRBBnj-.js → LayoutPicker.stories-BCME5Ogr.js} +1 -1
- package/storybook-static/assets/{Listbox-lrvI9Fx9.js → Listbox-B8F2xWvs.js} +1 -1
- package/storybook-static/assets/{Listbox-D_Qgzkw1.js → Listbox-y_3VijHU.js} +1 -1
- package/storybook-static/assets/{Listbox.stories-Djb1uju9.js → Listbox.stories-mp0p0NpO.js} +1 -1
- package/storybook-static/assets/{Modal-BpqYaQXu.js → Modal-DgEV0vBs.js} +1 -1
- package/storybook-static/assets/{Modal-CLZFIZH2.js → Modal-qIsW7BkG.js} +1 -1
- package/storybook-static/assets/{Modal.stories-DNpMq9oL.js → Modal.stories-CQ-Hn4GK.js} +1 -1
- package/storybook-static/assets/{ModalManagerProvider-DMlNCo5h.js → ModalManagerProvider-DEoq4q_O.js} +1 -1
- package/storybook-static/assets/MultiSelect-D-6XHQUG.js +79 -0
- package/storybook-static/assets/{MultiSelect-C593f3VV.js → MultiSelect-PGooEkAK.js} +1 -1
- package/storybook-static/assets/MultiSelect.stories-B0JzMViN.js +81 -0
- package/storybook-static/assets/MultiSelectCore-B0VbnEBc.js +3 -0
- package/storybook-static/assets/{NoData-Bvl_1jH4.js → NoData-DCuuvSoD.js} +1 -1
- package/storybook-static/assets/{NotificationsHost-CdPm_hcB.js → NotificationsHost-CWqG91Yh.js} +1 -1
- package/storybook-static/assets/{NotificationsHost.stories-Bo_dwZZe.js → NotificationsHost.stories-CEp-AppV.js} +1 -1
- package/storybook-static/assets/{ODataMultiSelect-BVlJ8U90.js → ODataMultiSelect-CwVneYzi.js} +1 -1
- package/storybook-static/assets/{ODataMultiSelect.stories-CqHpctYU.js → ODataMultiSelect.stories-BRnVOZsK.js} +1 -1
- package/storybook-static/assets/{ODataSelect-BCl-z6Sg.js → ODataSelect-DyKTFqk7.js} +1 -1
- package/storybook-static/assets/ODataSelect.stories-B-3GaeU4.js +148 -0
- package/storybook-static/assets/{ODataTreeMultiSelect-1CrmEPOx.js → ODataTreeMultiSelect-16xNi9qI.js} +1 -1
- package/storybook-static/assets/{ODataTreeMultiSelect.stories-B2YMNMyr.js → ODataTreeMultiSelect.stories-DI9tH2qD.js} +1 -1
- package/storybook-static/assets/{ODataTreeSelect-BqP9H4QH.js → ODataTreeSelect-Dk262plK.js} +1 -1
- package/storybook-static/assets/{ODataTreeSelect.stories-x_GCdGW8.js → ODataTreeSelect.stories-DfaL0dci.js} +1 -1
- package/storybook-static/assets/{OneStepScroller-B1H-Yg0P.js → OneStepScroller-DI8qlm5c.js} +1 -1
- package/storybook-static/assets/{Option-ChGr-plg.js → Option-CG3bU2cY.js} +1 -1
- package/storybook-static/assets/{OptionButton-D6mT04a1.js → OptionButton-DF0E8aU5.js} +1 -1
- package/storybook-static/assets/{OptionContent-CXc6K3fK.js → OptionContent-BZ3FiJQ4.js} +1 -1
- package/storybook-static/assets/{OptionContentContainer-D0p7mbft.js → OptionContentContainer-CyI5IfqU.js} +1 -1
- package/storybook-static/assets/{PeriodSelect-CpnYgcOA.js → PeriodSelect-_gAbt3E6.js} +1 -1
- package/storybook-static/assets/{PeriodSelect-Bm9WdjpG.js → PeriodSelect-uR-Xk4vQ.js} +1 -1
- package/storybook-static/assets/{PeriodSelect.stories-4Im6GLjq.js → PeriodSelect.stories-D-Lp7QtA.js} +1 -1
- package/storybook-static/assets/PickerField-CByAoAAO.js +1 -0
- package/storybook-static/assets/{PickerTriggerActions-BCupttoF.js → PickerTriggerActions-CYM-UvRz.js} +1 -1
- package/storybook-static/assets/{Popover-CbgP8DJy.js → Popover-CRcVoLur.js} +1 -1
- package/storybook-static/assets/{Popover-CCHTXorF.js → Popover-CdnsB1ss.js} +1 -1
- package/storybook-static/assets/{Popover.stories-zZ2fYcQb.js → Popover.stories-Dxdt7Jc5.js} +1 -1
- package/storybook-static/assets/{PresetRangeDateInput-D-Xf5CL3.js → PresetRangeDateInput-BQkK3Nmd.js} +1 -1
- package/storybook-static/assets/{PresetRangeDateInput-cmWbFoHz.js → PresetRangeDateInput-BmAGj8ye.js} +1 -1
- package/storybook-static/assets/{PresetRangeDateInput.stories-C3VxU77P.js → PresetRangeDateInput.stories-CUIwCB6T.js} +1 -1
- package/storybook-static/assets/{PresetSelect-BmTJNeUt.js → PresetSelect-C7HG9CjN.js} +2 -2
- package/storybook-static/assets/{README-Bl2m1JMK.js → README-9DTI05kd.js} +1 -1
- package/storybook-static/assets/{README-DEOe-D4O.js → README-B-ihyEBx.js} +1 -1
- package/storybook-static/assets/{README-B_TP46xP.js → README-B0iHgO_3.js} +1 -1
- package/storybook-static/assets/{README-DcMAIy3x.js → README-B1GSwjas.js} +1 -1
- package/storybook-static/assets/{README-lHhj1ioe.js → README-BAjs7T_d.js} +1 -1
- package/storybook-static/assets/{README-BcSaq4c4.js → README-BEYMpavt.js} +1 -1
- package/storybook-static/assets/{README-DVPc9Io_.js → README-BL0-uTlP.js} +1 -1
- package/storybook-static/assets/{README-EmDsFxzc.js → README-BR8bdUjV.js} +1 -1
- package/storybook-static/assets/{README-jg6CIybs.js → README-BUnl1FiN.js} +1 -1
- package/storybook-static/assets/{README-BC4nu9of.js → README-BbUo3mGT.js} +1 -1
- package/storybook-static/assets/{README-BiyBf-O3.js → README-Bdir2bPK.js} +1 -1
- package/storybook-static/assets/{README-BMXu-jQk.js → README-BmwSZfOQ.js} +1 -1
- package/storybook-static/assets/{README-IkL3xuvr.js → README-BquP2lux.js} +1 -1
- package/storybook-static/assets/{README-Cu9QJjVK.js → README-BurB0dhj.js} +1 -1
- package/storybook-static/assets/{README-DLtEU6xV.js → README-ByIhL9zr.js} +1 -1
- package/storybook-static/assets/{README-DFF21yas.js → README-ByT9u_7g.js} +1 -1
- package/storybook-static/assets/{README-BkJ_PjJk.js → README-C41zKsq6.js} +1 -1
- package/storybook-static/assets/{README-HRwASuVm.js → README-C5-oc7fP.js} +1 -1
- package/storybook-static/assets/{README-CnX5IOsQ.js → README-C7NhXX-n.js} +1 -1
- package/storybook-static/assets/{README-T35eDlrl.js → README-C8jcwgeL.js} +1 -1
- package/storybook-static/assets/{README-DkgiAGPo.js → README-CNnGqdkH.js} +1 -1
- package/storybook-static/assets/{README-B7kN5fdq.js → README-CQlujiXR.js} +1 -1
- package/storybook-static/assets/{README-BZW-Ku8G.js → README-CTBkJ27k.js} +1 -1
- package/storybook-static/assets/{README-BsvaCxyJ.js → README-CTGZXXVP.js} +1 -1
- package/storybook-static/assets/{README-B3bdpv3F.js → README-CUghXL33.js} +1 -1
- package/storybook-static/assets/{README-xMu2rAZ4.js → README-CiJ5wkhQ.js} +1 -1
- package/storybook-static/assets/{README-CaZGDS4o.js → README-CoENtXo_.js} +1 -1
- package/storybook-static/assets/{README-UcG-T3oc.js → README-CoQeAVdv.js} +1 -1
- package/storybook-static/assets/{README-k2-wWcjY.js → README-CpJmZHQJ.js} +1 -1
- package/storybook-static/assets/{README-zF7TglyH.js → README-CtZBJdo2.js} +1 -1
- package/storybook-static/assets/{README-BfbEWAVW.js → README-CvP9yRMR.js} +1 -1
- package/storybook-static/assets/{README-CLTYPp6T.js → README-D-urpNSn.js} +1 -1
- package/storybook-static/assets/{README-3VGZSgWz.js → README-DAH3lVWd.js} +1 -1
- package/storybook-static/assets/{README-CXLnU8PY.js → README-DCWk-Vga.js} +1 -1
- package/storybook-static/assets/{README-5uy1ulgc.js → README-DMZYAdN0.js} +1 -1
- package/storybook-static/assets/{README-C_zVigpw.js → README-DNrPuueH.js} +1 -1
- package/storybook-static/assets/{README-D7IHIZJQ.js → README-DQ1aeQ_i.js} +1 -1
- package/storybook-static/assets/{README-vCy3YlCq.js → README-DTMZk60G.js} +1 -1
- package/storybook-static/assets/{README-CwqRXSIJ.js → README-DY7lgi4q.js} +1 -1
- package/storybook-static/assets/{README-Bc63jJ_g.js → README-DaaS2c7L.js} +1 -1
- package/storybook-static/assets/{README-Dv4LnFqu.js → README-De3j71sQ.js} +1 -1
- package/storybook-static/assets/{README-DnkVTJ7s.js → README-DevTRU4A.js} +1 -1
- package/storybook-static/assets/{README-CZciBX1A.js → README-DfRan6KR.js} +1 -1
- package/storybook-static/assets/{README-C4vu077M.js → README-Dhptn6UE.js} +1 -1
- package/storybook-static/assets/{README-BRE26E-6.js → README-DxTRj-9a.js} +1 -1
- package/storybook-static/assets/{README-Bfp-2y9L.js → README-DyKegKG_.js} +1 -1
- package/storybook-static/assets/{README-BW8ukk_3.js → README-KCmlmH_Z.js} +1 -1
- package/storybook-static/assets/{README-Iwf47F8s.js → README-VNB_Dj5F.js} +1 -1
- package/storybook-static/assets/{README-DXajBW2j.js → README-_8pxMMC7.js} +1 -1
- package/storybook-static/assets/{README-BeMdGWkW.js → README-j-Czw7ww.js} +1 -1
- package/storybook-static/assets/{README-DEtA9vXg.js → README-n4utUGcX.js} +1 -1
- package/storybook-static/assets/{README-Bf9aqOSG.js → README-xrMkjHIm.js} +1 -1
- package/storybook-static/assets/{README-CjwMWiHf.js → README-zlaX5PMG.js} +1 -1
- package/storybook-static/assets/{RadioButton-Cy_jQtud.js → RadioButton-CDIyYuS9.js} +1 -1
- package/storybook-static/assets/{RadioButton-BBfQWcy3.js → RadioButton-DV8K96H6.js} +1 -1
- package/storybook-static/assets/{RadioButton.stories-9V4bon68.js → RadioButton.stories-CRNqKsyz.js} +1 -1
- package/storybook-static/assets/{RadioGroup-TwFpisuE.js → RadioGroup-BnYFRvmn.js} +1 -1
- package/storybook-static/assets/{RadioGroup-BndgLwX8.js → RadioGroup-CIIw962S.js} +1 -1
- package/storybook-static/assets/{RadioGroup.stories-DJLxesgz.js → RadioGroup.stories-K4AidbLa.js} +1 -1
- package/storybook-static/assets/{Scrollable-DtB02dAG.js → Scrollable-BI1k9ogH.js} +1 -1
- package/storybook-static/assets/{Scrollable-pBI6H_we.js → Scrollable-DAghtYuE.js} +1 -1
- package/storybook-static/assets/{Scrollable.stories-CahJ5rFA.js → Scrollable.stories-B6Doakiv.js} +1 -1
- package/storybook-static/assets/Select-BNHTGJqG.js +66 -0
- package/storybook-static/assets/Select-BlnKV8rc.js +12 -0
- package/storybook-static/assets/Select.stories-DZPAoL4J.js +86 -0
- package/storybook-static/assets/{Separator-BQlVHMcy.js → Separator-BCUzEQRV.js} +1 -1
- package/storybook-static/assets/{Separator-BdOz35ux.js → Separator-CiETy9yM.js} +1 -1
- package/storybook-static/assets/{Separator.stories-DRmR0Kda.js → Separator.stories-DTzurpM_.js} +1 -1
- package/storybook-static/assets/{SerializableSelect-ClSz_VvD.js → SerializableSelect-CnQurr7F.js} +1 -1
- package/storybook-static/assets/SerializableSelect.stories-qJaV_fjJ.js +73 -0
- package/storybook-static/assets/{ShimmerText-CuhrU7uk.js → ShimmerText-I292TqXa.js} +1 -1
- package/storybook-static/assets/{ShimmerText.stories-Djb6DvbN.js → ShimmerText.stories-AKqXqp1k.js} +1 -1
- package/storybook-static/assets/{SingleDateTimeInput-hC1Ft3qs.js → SingleDateTimeInput-BrNi93tH.js} +1 -1
- package/storybook-static/assets/{SingleDateTimeInput-C4jzvJ05.js → SingleDateTimeInput-DSn0vaW-.js} +1 -1
- package/storybook-static/assets/{SingleDateTimeInput.stories-D-HmSpnz.js → SingleDateTimeInput.stories-C910kkYc.js} +1 -1
- package/storybook-static/assets/{Slider-u0qKNrgI.js → Slider-CXA5Zwku.js} +1 -1
- package/storybook-static/assets/{Slider-WLUfmHyw.js → Slider-DO460-pY.js} +1 -1
- package/storybook-static/assets/{Slider.stories-CX8fS5Ax.js → Slider.stories-B874XxeK.js} +1 -1
- package/storybook-static/assets/{SliderInput-BEirf0Ys.js → SliderInput-DTidinPI.js} +1 -1
- package/storybook-static/assets/{SliderInput-ibTyal5l.js → SliderInput-DsV8o7Yy.js} +1 -1
- package/storybook-static/assets/{SliderInput.stories-xuycnRN_.js → SliderInput.stories-CDWNO90y.js} +1 -1
- package/storybook-static/assets/{Sortable-p0kUHa8E.js → Sortable-CML34YIF.js} +1 -1
- package/storybook-static/assets/{Sortable.stories-BdCtmfnr.js → Sortable.stories-C-_fvnHM.js} +1 -1
- package/storybook-static/assets/{Splitter-BzAg1cZ0.js → Splitter-BcuA2qce.js} +1 -1
- package/storybook-static/assets/{Splitter.stories-C5zZ4lHf.js → Splitter.stories-CA0-L_Ja.js} +1 -1
- package/storybook-static/assets/StateSelect--FDEb4-v.js +4 -0
- package/storybook-static/assets/{StateSelect-CyjHfKNv.js → StateSelect-B23bb_PO.js} +1 -1
- package/storybook-static/assets/{StateSelect.stories-D94g21N9.js → StateSelect.stories-CEVPThtC.js} +1 -1
- package/storybook-static/assets/{StatusIndicator-ylfiroPh.js → StatusIndicator-BbTCS7Ku.js} +1 -1
- package/storybook-static/assets/{StatusIndicator.stories-BB7y4KGW.js → StatusIndicator.stories-BIps_Ecm.js} +1 -1
- package/storybook-static/assets/{StringToggle.stories-BwuTZAGa.js → StringToggle.stories-vhOfzslq.js} +1 -1
- package/storybook-static/assets/{Switch-BXWiUOXs.js → Switch-DibS4nSc.js} +1 -1
- package/storybook-static/assets/{Switch-DRLWRp0P.js → Switch-jJgwtWFK.js} +1 -1
- package/storybook-static/assets/{Switch.stories-taC_bi5a.js → Switch.stories-Cvky3KQz.js} +1 -1
- package/storybook-static/assets/{Table-BYiIQfjA.js → Table-DcNGLEI6.js} +1 -1
- package/storybook-static/assets/{Table.stories-B9u81cAN.js → Table.stories-DbEzudxD.js} +1 -1
- package/storybook-static/assets/{TableEditor.stories-CG0ULNok.js → TableEditor.stories-Be9nCkds.js} +1 -1
- package/storybook-static/assets/{Tabs-BYp06IN2.js → Tabs-CTL4MnkZ.js} +1 -1
- package/storybook-static/assets/{Tabs.stories-BCkUYsqs.js → Tabs.stories-CIVbz7kW.js} +1 -1
- package/storybook-static/assets/{TabsBox-DBm2a1iA.js → TabsBox-C9g1p4du.js} +1 -1
- package/storybook-static/assets/{TagInput-D9gedxBU.js → TagInput-DuJLeiyT.js} +1 -1
- package/storybook-static/assets/{TagInput.stories-6eOGQ16t.js → TagInput.stories-BLVFWr-T.js} +1 -1
- package/storybook-static/assets/{Text-CcgH9LXI.js → Text-Cr_TUUgL.js} +1 -1
- package/storybook-static/assets/{Textarea-DXOTj2Y7.js → Textarea-BImI6Q6v.js} +1 -1
- package/storybook-static/assets/{Textarea-aGrLpQXu.js → Textarea-DGaanGLG.js} +1 -1
- package/storybook-static/assets/{Textarea.stories-BwqxG2lk.js → Textarea.stories-DvQ2dDNh.js} +1 -1
- package/storybook-static/assets/{TimePanel-DroAbbvD.js → TimePanel-Cg2G5Hab.js} +1 -1
- package/storybook-static/assets/{TimePanel.stories-DgU6ia4A.js → TimePanel.stories-qy5mb3YN.js} +1 -1
- package/storybook-static/assets/{Toggle-BUSzQ1ww.js → Toggle-CroC7YOK.js} +1 -1
- package/storybook-static/assets/{Toggle-B7MbU9HB.js → Toggle-Dj8Ic_Ak.js} +1 -1
- package/storybook-static/assets/{Toggle.stories-BYU9hS62.js → Toggle.stories-CmyyubM8.js} +1 -1
- package/storybook-static/assets/TreeMultiSelect-BHNmPW50.js +1 -0
- package/storybook-static/assets/TreeMultiSelect-DBQYLjnA.js +22 -0
- package/storybook-static/assets/TreeMultiSelect.stories-BNsE1zgF.js +68 -0
- package/storybook-static/assets/TreePickerBase-ZEBy3EVT.js +76 -0
- package/storybook-static/assets/TreeSelect-T7G2pkyK.js +1 -0
- package/storybook-static/assets/TreeSelect-aiPeW2uJ.js +19 -0
- package/storybook-static/assets/TreeSelect.stories-E6ObkYJe.js +40 -0
- package/storybook-static/assets/{TreeTable-AIcYVdfl.js → TreeTable-C0ORe5Pe.js} +1 -1
- package/storybook-static/assets/{TreeTable.stories-BKbbLMK7.js → TreeTable.stories-PtGT_1X5.js} +1 -1
- package/storybook-static/assets/{blocks-Bdsl8TP-.js → blocks-DR4JL0hD.js} +3 -3
- package/storybook-static/assets/{check-DGqyuB4O.js → check-PtABqMc1.js} +1 -1
- package/storybook-static/assets/{chevron-down-BykqjXRq.js → chevron-down-BaujB0G_.js} +1 -1
- package/storybook-static/assets/{chevron-left-Z5uCO076.js → chevron-left-C1SZ4PrE.js} +1 -1
- package/storybook-static/assets/{chevron-right-C8yfwmkk.js → chevron-right-CfCjHN8b.js} +1 -1
- package/storybook-static/assets/{chunk-W22LQPXL-hfBk2z5K.js → chunk-W22LQPXL-Cis7lFT9.js} +1 -1
- package/storybook-static/assets/{circle-alert-C9sxb8DT.js → circle-alert-Mymt-6wl.js} +1 -1
- package/storybook-static/assets/{circle-check-BLrYJ_8h.js → circle-check-DzqMvzJX.js} +1 -1
- package/storybook-static/assets/{components-xYnqEbBt.js → components-Do91qDh3.js} +3 -3
- package/storybook-static/assets/{contextMenu-C-b4jBpY.js → contextMenu-8NKKgKoy.js} +1 -1
- package/storybook-static/assets/{download-g1fk8W6J.js → download-Cn6H3Bnv.js} +1 -1
- package/storybook-static/assets/{floating-ui.react-cCWtY5RA.js → floating-ui.react-BFqa49jG.js} +1 -1
- package/storybook-static/assets/{foundationApi-Ci5vPKh_.js → foundationApi-CChPwNx-.js} +1 -1
- package/storybook-static/assets/{foundationLib-DNlIsEyf.js → foundationLib-ClEyfTpa.js} +1 -1
- package/storybook-static/assets/{hooks-XqeLihmr.js → hooks-DUKyfcb_.js} +1 -1
- package/storybook-static/assets/{iframe-ltYEol2F.js → iframe-1Nw_zWMi.js} +3 -3
- package/storybook-static/assets/iframe-BgBwFMGW.js +1 -0
- package/storybook-static/assets/{info-CBSXRv7d.js → info-DMI56qGy.js} +1 -1
- package/storybook-static/assets/{odata-Dd_3_5NS.js → odata-D9M3xPIL.js} +1 -1
- package/storybook-static/assets/{odataStoryFixtures-3lOfs9T6.js → odataStoryFixtures-eHJgW7OK.js} +1 -1
- package/storybook-static/assets/{react-BxWB81Qy.js → react-DidV4ORc.js} +1 -1
- package/storybook-static/assets/{refresh-cw-FKHfW9eG.js → refresh-cw-B1ChlhvT.js} +1 -1
- package/storybook-static/assets/{settings-2-Cz1PtqGa.js → settings-2-BxwqnB9r.js} +1 -1
- package/storybook-static/assets/{sortable-BelHSus7.js → sortable-DMBM69Jm.js} +1 -1
- package/storybook-static/assets/{syntaxhighlighter-QEQV7K2Y-gGot_qSq.js → syntaxhighlighter-QEQV7K2Y-BJZNAUo-.js} +1 -1
- package/storybook-static/assets/{trash-2-BT2kW3r-.js → trash-2-B768_PZU.js} +1 -1
- package/storybook-static/assets/{triangle-alert-CPiJJHYc.js → triangle-alert-B8H-k2Bq.js} +1 -1
- package/storybook-static/assets/{useODataSelectBase-bPN0T_Xm.js → useODataSelectBase-BKAZcf4R.js} +1 -1
- package/storybook-static/assets/{useODataTreeData-CIpE4LZu.js → useODataTreeData-Bxlcmpg8.js} +1 -1
- package/storybook-static/assets/{usePickerQuery-OTz4Oze6.js → usePickerQuery-DJj2HmX9.js} +1 -1
- package/storybook-static/assets/{usePickerTriggerController-vNC5e_t0.js → usePickerTriggerController-CiD33ccS.js} +2 -2
- package/storybook-static/assets/{x-BdAuXjBq.js → x-Dt9SO3SL.js} +1 -1
- package/storybook-static/iframe.html +2 -2
- package/storybook-static/index.json +1 -1
- package/storybook-static/project.json +1 -1
- package/dist/chunks/input-CuRK9Vbz.js.map +0 -1
- package/dist/chunks/picker-SJXnHwsj.js.map +0 -1
- package/dist/chunks/select--oIrv7SC.js +0 -357
- package/dist/chunks/select--oIrv7SC.js.map +0 -1
- package/storybook-static/assets/Input-b2F0zrLw.js +0 -3
- package/storybook-static/assets/MultiSelect-DmC3DaMc.js +0 -76
- package/storybook-static/assets/MultiSelect.stories-R6JTKnFI.js +0 -64
- package/storybook-static/assets/MultiSelectCore-BaRmQrD-.js +0 -3
- package/storybook-static/assets/ODataSelect.stories-Cm-Xkq40.js +0 -148
- package/storybook-static/assets/PickerField-w1JCZyzA.js +0 -1
- package/storybook-static/assets/Select-BOnv-Uuv.js +0 -63
- package/storybook-static/assets/Select-CClfxa48.js +0 -12
- package/storybook-static/assets/Select.stories-C0X5pvUk.js +0 -69
- package/storybook-static/assets/SerializableSelect.stories-DozN_Quy.js +0 -73
- package/storybook-static/assets/StateSelect-bHA1Vf6z.js +0 -4
- package/storybook-static/assets/TreeMultiSelect-BhFYUbr0.js +0 -1
- package/storybook-static/assets/TreeMultiSelect-CZIyMaIZ.js +0 -20
- package/storybook-static/assets/TreeMultiSelect.stories-DG_mdSkQ.js +0 -60
- package/storybook-static/assets/TreePickerBase-CbULuQpp.js +0 -76
- package/storybook-static/assets/TreeSelect-CMSolQHr.js +0 -17
- package/storybook-static/assets/TreeSelect-Cu1BsepL.js +0 -1
- package/storybook-static/assets/TreeSelect.stories-B2J0N4ke.js +0 -32
- package/storybook-static/assets/iframe-TsWsvoxA.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input-files-B8j6Pb_M.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(--accent-text);\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-CnBNlJo0.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(--accent-text);\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,6 +1,6 @@
|
|
|
1
1
|
import { t as e } from "./ui.module-oRwY3Zli.js";
|
|
2
2
|
import { t } from "./grid-CFuzBigM.js";
|
|
3
|
-
import { a as n, c as r, d as i, i as a } from "./input-
|
|
3
|
+
import { a as n, c as r, d as i, i as a } from "./input-KXI7o06g.js";
|
|
4
4
|
import { t as o } from "./separator-CHpBud1e.js";
|
|
5
5
|
import { cn as s } from "@ryuzaki13/react-foundation-lib/utils";
|
|
6
6
|
import { ChevronDownIcon as c, XIcon as l } from "lucide-react";
|
|
@@ -11,8 +11,8 @@ import { FloatingFocusManager as y, FloatingPortal as b } from "@floating-ui/rea
|
|
|
11
11
|
import { AnimatePresence as x, motion as S } from "motion/react";
|
|
12
12
|
import { useFloatingListbox as C } from "@ryuzaki13/react-foundation-lib/hooks";
|
|
13
13
|
//#region src/picker/PickerField.tsx
|
|
14
|
-
function w({ id: e, label: t, description: n, disabled: a, size: o, className: s, error: c,
|
|
15
|
-
let { controlId:
|
|
14
|
+
function w({ id: e, label: t, description: n, disabled: a, size: o, className: s, error: c, required: l, children: u }) {
|
|
15
|
+
let { controlId: f, labelId: p, descriptionId: m, errorId: h, describedBy: g } = i({
|
|
16
16
|
id: e,
|
|
17
17
|
hasLabel: t != null,
|
|
18
18
|
hasDescription: !!n,
|
|
@@ -25,16 +25,17 @@ function w({ id: e, label: t, description: n, disabled: a, size: o, className: s
|
|
|
25
25
|
size: o,
|
|
26
26
|
className: s,
|
|
27
27
|
error: c,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
28
|
+
required: l,
|
|
29
|
+
controlId: f,
|
|
30
|
+
labelId: p,
|
|
31
|
+
descriptionId: m,
|
|
32
|
+
errorId: h,
|
|
33
|
+
children: u({
|
|
34
|
+
controlId: f,
|
|
35
|
+
labelId: p,
|
|
36
|
+
descriptionId: m,
|
|
37
|
+
errorId: h,
|
|
38
|
+
describedBy: g
|
|
38
39
|
})
|
|
39
40
|
});
|
|
40
41
|
}
|
|
@@ -254,7 +255,7 @@ function F({ open: t, disabled: n, children: r, onToggleMouseDown: i, onToggleCl
|
|
|
254
255
|
//#endregion
|
|
255
256
|
//#region src/picker/PickerTriggerInput.tsx
|
|
256
257
|
function I({ ref: t, rootRef: r, endAdornment: i, overlay: o, rootClassName: c, inputClassName: l, isLoading: p, ...m }) {
|
|
257
|
-
let h = o != null;
|
|
258
|
+
let h = o != null, g = m["aria-invalid"] === !0 || m["aria-invalid"] === "true";
|
|
258
259
|
return /* @__PURE__ */ d("div", {
|
|
259
260
|
ref: r,
|
|
260
261
|
className: s(e.uiInputContainer, E.triggerContainer, c),
|
|
@@ -264,7 +265,7 @@ function I({ ref: t, rootRef: r, endAdornment: i, overlay: o, rootClassName: c,
|
|
|
264
265
|
children: ({ controlClassName: n }) => /* @__PURE__ */ d("input", {
|
|
265
266
|
...m,
|
|
266
267
|
ref: t,
|
|
267
|
-
className: s(e.uiInputWithToggle, n, l)
|
|
268
|
+
className: s(e.uiInputWithToggle, g && e.invalid, n, l)
|
|
268
269
|
})
|
|
269
270
|
}), h ? o : null] })
|
|
270
271
|
});
|
|
@@ -459,4 +460,4 @@ function G({ mode: e, open: t, currentQuery: n, hasDisplayValue: r, inputRef: i,
|
|
|
459
460
|
//#endregion
|
|
460
461
|
export { T as _, B as a, I as c, N as d, M as f, D as g, O as h, V as i, F as l, k as m, U as n, R as o, A as p, H as r, L as s, G as t, P as u, w as v };
|
|
461
462
|
|
|
462
|
-
//# sourceMappingURL=picker-
|
|
463
|
+
//# sourceMappingURL=picker-DagDe9OH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"picker-DagDe9OH.js","names":[],"sources":["../../src/picker/PickerField.tsx","../../src/picker/PickerClearButton.tsx","../../src/picker/Picker.module.scss","../../src/picker/PickerSelectionToolbar.tsx","../../src/picker/PickerOptions.tsx","../../src/picker/model/extractPickerTextContent.ts","../../src/picker/PickerPlaceholder.ts","../../src/picker/PickerPopup.tsx","../../src/picker/PickerSelectedToken.tsx","../../src/picker/PickerStatus.tsx","../../src/picker/PickerTriggerActions.tsx","../../src/picker/PickerTriggerInput.tsx","../../src/picker/PickerTrigger.tsx","../../src/picker/model/createPickerTriggerPolicy.ts","../../src/picker/model/usePickerDefaultFilter.ts","../../src/picker/model/usePickerFloatingListbox.ts","../../src/picker/model/usePickerQuery.ts","../../src/picker/model/usePickerSelectionLifecycle.ts","../../src/picker/model/usePickerTriggerController.ts"],"sourcesContent":["import { InputType } from \"@ryuzaki13/react-foundation-lib/types\";\n\nimport { InputUI } from \"../input\";\nimport { useInputFieldIds } from \"../input/lib/useInputFieldIds\";\n\nimport { PickerFieldProps } from \"./types\";\n\nexport function PickerField<TValue extends InputType>({\n\tid,\n\tlabel,\n\tdescription,\n\tdisabled,\n\tsize,\n\tclassName,\n\terror,\n\trequired,\n\tchildren\n}: PickerFieldProps<TValue>) {\n\tconst { controlId, labelId, descriptionId, errorId, describedBy } = useInputFieldIds({\n\t\tid,\n\t\thasLabel: label !== undefined && label !== null,\n\t\thasDescription: !!description,\n\t\thasError: !!error\n\t});\n\n\treturn (\n\t\t<InputUI\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\tdisabled={disabled}\n\t\t\tsize={size}\n\t\t\tclassName={className}\n\t\t\terror={error}\n\t\t\trequired={required}\n\t\t\tcontrolId={controlId}\n\t\t\tlabelId={labelId}\n\t\t\tdescriptionId={descriptionId}\n\t\t\terrorId={errorId}>\n\t\t\t{children({ controlId, labelId, descriptionId, errorId, describedBy })}\n\t\t</InputUI>\n\t);\n}\n","import { type MouseEvent } from \"react\";\n\nimport { XIcon } from \"lucide-react\";\n\nimport uiStyles from \"../ui.module.scss\";\n\ntype PickerClearButtonProps = {\n\tdisabled?: boolean;\n\tariaLabel?: string;\n\tonClear: () => void;\n};\n\n/** Единое действие очистки выбранного значения во всех clearable picker-компонентах. */\nexport function PickerClearButton({ disabled, ariaLabel = \"Очистить выбор\", onClear }: PickerClearButtonProps) {\n\tconst stopTriggerInteraction = (event: MouseEvent<HTMLButtonElement>) => {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t};\n\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdisabled={disabled}\n\t\t\tclassName={uiStyles.uiClearButton}\n\t\t\tdata-ui=\"picker-clear-button\"\n\t\t\tdata-action=\"clear-picker\"\n\t\t\tonMouseDown={stopTriggerInteraction}\n\t\t\tonClick={(event) => {\n\t\t\t\tstopTriggerInteraction(event);\n\t\t\t\tonClear();\n\t\t\t}}\n\t\t\taria-label={ariaLabel}>\n\t\t\t<XIcon />\n\t\t</button>\n\t);\n}\n","@use \"@/styles/mixins\" as *;\n\n.popupPositioner,\n.options {\n\toverflow: hidden;\n\tdisplay: grid;\n\tgrid-template-rows: minmax(0, 1fr);\n\tborder-radius: var(--radius-sm);\n}\n\n.popupPositioner {\n\t--anchor-gap: var(--space-xs);\n\t--anchor-padding: var(--space-xs);\n\t--anchor-offset: 0;\n\t// Минимальная ширина нужна только floating-панели. Встроенный Listbox получает ширину от UiBaseProps.size.\n\t--input-width: min(100vw, var(--base-width, 15em));\n\n\tmin-width: 0;\n\tz-index: var(--z-dropdown);\n\tbox-shadow: var(--shadow-md);\n\n\t.options {\n\t\tmin-width: var(--input-width);\n\t}\n}\n\n.options {\n\twidth: 100%;\n\tmin-height: 0;\n\tmax-height: 75vh;\n\n\tpadding: var(--space-sm);\n\tbackground-color: var(--surface-0);\n\tborder: var(--border);\n\n\t&:empty {\n\t\tvisibility: hidden;\n\t}\n\n\t&[data-has-toolbar=\"true\"] {\n\t\tgrid-template-rows: auto minmax(0, 1fr);\n\t}\n}\n\n.optionsToolbar {\n\tdisplay: grid;\n\tgap: var(--space-xs);\n\tpadding: var(--space-xs);\n}\n\n.optionsBody {\n\tmin-height: 0;\n}\n\n.status {\n\tpadding: var(--space-xs) var(--space-sm);\n\tcolor: var(--content-2);\n}\n\n.statusError {\n\tcolor: var(--error-text);\n}\n\n.triggerContainer {\n\tposition: relative;\n\n\t&[data-has-overlay=\"true\"] input {\n\t\t--ui-color: transparent;\n\t\t--ui-color-hover: transparent;\n\t\t--ui-color-active: transparent;\n\n\t\tcolor: transparent;\n\t\tcaret-color: transparent;\n\t\t-webkit-text-fill-color: transparent;\n\t}\n}\n\n.triggerHasClear {\n\t--trigger-count: 2;\n\t// Резервирует в input место для кнопок очистки и открытия списка.\n\t--input-end-adornment-width: calc(var(--control-height) * 2);\n}\n\n.selectedToken {\n\tposition: absolute;\n\tinset: 0 calc(var(--control-height) * var(--trigger-count, 1) + var(--space-sm)) 0 var(--space-sm);\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: flex-end;\n\tmin-width: 0;\n\tpointer-events: none;\n}\n\n.selectedTokenText {\n\toverflow: hidden;\n\twhite-space: nowrap;\n\ttext-overflow: ellipsis;\n}\n\n@include mobile {\n\t.popupPositioner {\n\t\t--input-width: calc(100dvw - var(--space-xl));\n\t}\n}\n\n.selectionActionButton {\n\tpadding-block: var(--space-xs);\n\tborder-radius: var(--radius-sm);\n\n\t&:hover {\n\t\tbackground-color: var(--surface-2);\n\t}\n}\n","import { type Ref } from \"react\";\n\nimport { Grid } from \"../grid\";\n\nimport styles from \"./Picker.module.scss\";\n\ntype PickerSelectionToolbarProps = {\n\tonSelectAll: () => void;\n\tonDeselectAll: () => void;\n\tselectAllButtonRef?: Ref<HTMLButtonElement>;\n};\n\n/**\n * Общая панель массовых действий для picker-компонентов с множественным выбором.\n * Компонент не знает формат значения и делегирует изменение владельцу selection-модели.\n */\nexport function PickerSelectionToolbar({ onSelectAll, onDeselectAll, selectAllButtonRef }: PickerSelectionToolbarProps) {\n\treturn (\n\t\t<Grid.Container gap=\"xs\" templateColumns=\"1fr 1fr\">\n\t\t\t<button\n\t\t\t\tref={selectAllButtonRef}\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName={styles.selectionActionButton}\n\t\t\t\tonClick={onSelectAll}\n\t\t\t\tdata-ui=\"picker-select-all\"\n\t\t\t\tdata-action=\"select-all\">\n\t\t\t\tВыбрать все\n\t\t\t</button>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName={styles.selectionActionButton}\n\t\t\t\tonClick={onDeselectAll}\n\t\t\t\tdata-ui=\"picker-deselect-all\"\n\t\t\t\tdata-action=\"deselect-all\">\n\t\t\t\tСнять выбор\n\t\t\t</button>\n\t\t</Grid.Container>\n\t);\n}\n","import { type HTMLAttributes, type ReactNode, type Ref } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { Separator } from \"../separator\";\n\nimport styles from \"./Picker.module.scss\";\nimport { PickerSelectionToolbar } from \"./PickerSelectionToolbar\";\n\nexport type PickerSelectionActions = {\n\tonSelectAll: () => void;\n\tonDeselectAll: () => void;\n\tselectAllButtonRef?: Ref<HTMLButtonElement>;\n};\n\nexport interface PickerOptionsProps extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n\trootRef?: Ref<HTMLDivElement>;\n\tbodyRef?: Ref<HTMLDivElement>;\n\tbodyProps?: Omit<HTMLAttributes<HTMLDivElement>, \"children\" | \"className\">;\n\tchildren: ReactNode;\n\ttoolbar?: ReactNode | false;\n\tselectionActions?: PickerSelectionActions;\n\tlayoutClassName?: string;\n\tbodyClassName?: string;\n\tscrollable?: boolean;\n}\n\n/**\n * Единая оболочка списка опций для picker, listbox и menu. Если переданы\n * selectionActions, но не передан toolbar, компонент показывает стандартные\n * действия выбора и снятия выбора.\n */\nexport function PickerOptions({\n\trootRef,\n\tbodyRef,\n\tbodyProps,\n\tchildren,\n\ttoolbar,\n\tselectionActions,\n\tlayoutClassName,\n\tbodyClassName,\n\tscrollable = true,\n\tclassName,\n\t...props\n}: PickerOptionsProps) {\n\tconst resolvedToolbar = toolbar === undefined && selectionActions ? <PickerSelectionToolbar {...selectionActions} /> : toolbar || null;\n\n\treturn (\n\t\t<div\n\t\t\t{...props}\n\t\t\tref={rootRef}\n\t\t\tclassName={cn(styles.options, layoutClassName, className)}\n\t\t\tdata-ui=\"picker-options\"\n\t\t\tdata-has-toolbar={resolvedToolbar ? \"true\" : undefined}>\n\t\t\t{resolvedToolbar ? (\n\t\t\t\t<div className={styles.optionsToolbar}>\n\t\t\t\t\t{resolvedToolbar}\n\t\t\t\t\t<Separator />\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t<div\n\t\t\t\t{...bodyProps}\n\t\t\t\tref={bodyRef}\n\t\t\t\tclassName={cn(styles.optionsBody, scrollable ? \"scrollable overscroll\" : \"overflowHidden\", bodyClassName)}>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n","import { isValidElement, type ReactNode } from \"react\";\n\nexport function extractPickerTextContent(node: ReactNode): string | undefined {\n\tif (typeof node === \"string\" || typeof node === \"number\") {\n\t\treturn String(node);\n\t}\n\n\tif (Array.isArray(node)) {\n\t\tconst values = node\n\t\t\t.map(extractPickerTextContent)\n\t\t\t.filter((value): value is string => Boolean(value))\n\t\t\t.map((value) => value.trim())\n\t\t\t.filter(Boolean);\n\t\treturn values.length ? values.join(\" \") : undefined;\n\t}\n\n\tif (isValidElement<{ children?: ReactNode; searchText?: unknown }>(node)) {\n\t\tif (typeof node.props.searchText === \"string\") {\n\t\t\treturn node.props.searchText;\n\t\t}\n\n\t\treturn extractPickerTextContent(node.props.children);\n\t}\n\n\treturn undefined;\n}\n","import { type ReactNode } from \"react\";\n\nimport { extractPickerTextContent } from \"./model/extractPickerTextContent\";\n\ntype PickerPlaceholderParams = {\n\tplaceholder?: string;\n\tlabel?: ReactNode;\n\toptionCount: number;\n\tfallback?: string;\n};\n\n/**\n * Формирует единый текст placeholder для picker-компонентов и всегда показывает\n * актуальное количество доступных вариантов.\n */\nexport function getPickerPlaceholder({ placeholder, label, optionCount, fallback = \"Выберите значение\" }: PickerPlaceholderParams) {\n\tconst labelText = extractPickerTextContent(label);\n\tconst text = placeholder ?? labelText ?? fallback;\n\n\treturn `${text} <${optionCount}>`;\n}\n","import { type CSSProperties, type FocusEvent, type KeyboardEvent, type MouseEvent, type ReactNode, useRef } from \"react\";\n\nimport { FloatingContext, FloatingFocusManager, FloatingPortal } from \"@floating-ui/react\";\nimport { AnimatePresence, motion } from \"motion/react\";\n\nimport styles from \"./Picker.module.scss\";\nimport { PickerOptions, type PickerSelectionActions } from \"./PickerOptions\";\n\ninterface PickerPopupProps {\n\topen: boolean;\n\tcontext: FloatingContext;\n\tfloatingStyles: CSSProperties;\n\tlistId: string;\n\tlabelId?: string;\n\tpopupAriaLabel?: string;\n\tdescriptionId?: string;\n\tactiveOptionId?: string;\n\tariaMultiselectable?: boolean;\n\tpopupRole?: \"listbox\" | \"tree\" | \"treegrid\" | \"grid\" | \"dialog\";\n\tsetFloating: (node: HTMLElement | null) => void;\n\tgetFloatingProps: (userProps?: Record<string, unknown>) => Record<string, unknown>;\n\tonKeyDown: (event: KeyboardEvent<HTMLElement>) => void;\n\tinitialFocus?: number;\n\treturnFocus?: boolean;\n\ttabIndex?: number;\n\tclassName?: string;\n\tmaxWidth?: CSSProperties[\"maxWidth\"];\n\tlayoutClassName?: string;\n\tbodyClassName?: string;\n\ttoolbar?: ReactNode | false;\n\tselectionActions?: PickerSelectionActions;\n\tchildren: ReactNode;\n}\n\nfunction stopNestedFloatingMouseDown(event: MouseEvent<HTMLElement>): void {\n\tevent.stopPropagation();\n}\n\nexport function PickerPopup({\n\topen,\n\tcontext,\n\tfloatingStyles,\n\tlistId,\n\tlabelId,\n\tpopupAriaLabel,\n\tdescriptionId,\n\tactiveOptionId,\n\tariaMultiselectable,\n\tpopupRole = \"listbox\",\n\tsetFloating,\n\tgetFloatingProps,\n\tonKeyDown,\n\tinitialFocus = -1,\n\treturnFocus = false,\n\ttabIndex = 0,\n\tclassName,\n\tmaxWidth,\n\tlayoutClassName,\n\tbodyClassName,\n\ttoolbar,\n\tselectionActions,\n\tchildren\n}: PickerPopupProps) {\n\tconst compositeRef = useRef<HTMLDivElement | null>(null);\n\tconst isDialog = popupRole === \"dialog\";\n\tconst compositeProps = isDialog\n\t\t? undefined\n\t\t: getFloatingProps({\n\t\t\t\tid: listId,\n\t\t\t\trole: popupRole,\n\t\t\t\ttabIndex,\n\t\t\t\t\"aria-labelledby\": labelId,\n\t\t\t\t\"aria-label\": labelId ? undefined : popupAriaLabel,\n\t\t\t\t\"aria-describedby\": descriptionId,\n\t\t\t\t\"aria-activedescendant\": activeOptionId,\n\t\t\t\t\"aria-multiselectable\": ariaMultiselectable || undefined,\n\t\t\t\tonKeyDown\n\t\t\t});\n\tconst handlePositionerFocus = (event: FocusEvent<HTMLDivElement>) => {\n\t\tif (!isDialog && event.target === event.currentTarget) {\n\t\t\tcompositeRef.current?.focus();\n\t\t}\n\t};\n\n\treturn (\n\t\t<AnimatePresence>\n\t\t\t{open && (\n\t\t\t\t<FloatingPortal preserveTabOrder={false}>\n\t\t\t\t\t<FloatingFocusManager\n\t\t\t\t\t\tcontext={context}\n\t\t\t\t\t\tmodal={false}\n\t\t\t\t\t\tguards={false}\n\t\t\t\t\t\tinitialFocus={initialFocus}\n\t\t\t\t\t\treturnFocus={returnFocus}>\n\t\t\t\t\t\t<motion.div\n\t\t\t\t\t\t\tref={setFloating}\n\t\t\t\t\t\t\tstyle={{ ...floatingStyles, maxWidth }}\n\t\t\t\t\t\t\tclassName={styles.popupPositioner}\n\t\t\t\t\t\t\tinitial={{ opacity: 0, scale: 0.95 }}\n\t\t\t\t\t\t\tanimate={{ opacity: 1, scale: 1 }}\n\t\t\t\t\t\t\texit={{ opacity: 0, scale: 0.95 }}\n\t\t\t\t\t\t\ttabIndex={isDialog ? undefined : -1}\n\t\t\t\t\t\t\tonMouseDown={stopNestedFloatingMouseDown}\n\t\t\t\t\t\t\tonFocus={isDialog ? undefined : handlePositionerFocus}\n\t\t\t\t\t\t\t{...(isDialog\n\t\t\t\t\t\t\t\t? getFloatingProps({\n\t\t\t\t\t\t\t\t\t\tid: listId,\n\t\t\t\t\t\t\t\t\t\trole: \"dialog\",\n\t\t\t\t\t\t\t\t\t\ttabIndex,\n\t\t\t\t\t\t\t\t\t\t\"aria-labelledby\": labelId,\n\t\t\t\t\t\t\t\t\t\t\"aria-label\": labelId ? undefined : popupAriaLabel,\n\t\t\t\t\t\t\t\t\t\t\"aria-describedby\": descriptionId,\n\t\t\t\t\t\t\t\t\t\tonMouseDown: stopNestedFloatingMouseDown,\n\t\t\t\t\t\t\t\t\t\tonKeyDown\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t: {})}>\n\t\t\t\t\t\t\t<PickerOptions\n\t\t\t\t\t\t\t\tclassName={className}\n\t\t\t\t\t\t\t\tlayoutClassName={layoutClassName}\n\t\t\t\t\t\t\t\tbodyClassName={bodyClassName}\n\t\t\t\t\t\t\t\ttoolbar={toolbar}\n\t\t\t\t\t\t\t\tselectionActions={selectionActions}\n\t\t\t\t\t\t\t\tbodyRef={isDialog ? undefined : compositeRef}\n\t\t\t\t\t\t\t\tbodyProps={isDialog ? undefined : compositeProps}\n\t\t\t\t\t\t\t\tscrollable={false}>\n\t\t\t\t\t\t\t\t{children}\n\t\t\t\t\t\t\t</PickerOptions>\n\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t</FloatingFocusManager>\n\t\t\t\t</FloatingPortal>\n\t\t\t)}\n\t\t</AnimatePresence>\n\t);\n}\n","import { type HTMLAttributes, type ReactNode } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport styles from \"./Picker.module.scss\";\n\nexport interface PickerSelectedTokenProps extends Omit<HTMLAttributes<HTMLSpanElement>, \"children\"> {\n\tchildren: ReactNode;\n}\n\n/** Единое визуальное представление выбранного значения внутри picker-trigger. */\nexport function PickerSelectedToken({ children, className, ...props }: PickerSelectedTokenProps) {\n\treturn (\n\t\t<span {...props} className={cn(styles.selectedToken, className)} data-ui=\"picker-selected-token\">\n\t\t\t<span className={styles.selectedTokenText}>{children}</span>\n\t\t</span>\n\t);\n}\n","import { ReactNode } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport uiStyles from \"../ui.module.scss\";\n\nimport styles from \"./Picker.module.scss\";\n\ninterface PickerStatusProps {\n\temptyState?: ReactNode;\n\t// loadingState?: ReactNode;\n\terrorState?: ReactNode;\n}\n\nexport function PickerStatus({ emptyState, errorState }: PickerStatusProps) {\n\tconst content = errorState ?? emptyState;\n\n\tif (content === undefined || content === null) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<div className={cn(uiStyles.uiPopupOption, styles.status, errorState !== undefined && styles.statusError)} aria-disabled={true}>\n\t\t\t{content}\n\t\t</div>\n\t);\n}\n","import { type AriaAttributes, type MouseEvent, type ReactNode } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { ChevronDownIcon } from \"lucide-react\";\n\nimport uiStyles from \"../ui.module.scss\";\n\ninterface PickerTriggerActionsProps {\n\topen: boolean;\n\tdisabled?: boolean;\n\tchildren?: ReactNode;\n\tonToggleMouseDown?: (event: MouseEvent<HTMLButtonElement>) => void;\n\tonToggleClick: () => void;\n\topenAriaLabel?: string;\n\tcloseAriaLabel?: string;\n\t/**\n\t * Передаёт ARIA-связи непосредственно кнопке раскрытия, не меняя геометрию\n\t * контейнера с adornment-действиями.\n\t */\n\ttoggleAria?: Pick<AriaAttributes, \"aria-controls\" | \"aria-expanded\" | \"aria-haspopup\">;\n}\n\nexport function PickerTriggerActions({\n\topen,\n\tdisabled,\n\tchildren,\n\tonToggleMouseDown,\n\tonToggleClick,\n\topenAriaLabel = \"Открыть список\",\n\tcloseAriaLabel = \"Закрыть список\",\n\ttoggleAria\n}: PickerTriggerActionsProps) {\n\treturn (\n\t\t<div className={uiStyles.uiToggleButtonContainer} data-disabled={disabled || undefined}>\n\t\t\t{children}\n\n\t\t\t<div className={uiStyles.uiButtonSeparator} />\n\n\t\t\t<button\n\t\t\t\t{...toggleAria}\n\t\t\t\ttype=\"button\"\n\t\t\t\tdisabled={disabled}\n\t\t\t\taria-label={open ? closeAriaLabel : openAriaLabel}\n\t\t\t\tclassName={uiStyles.uiToggleButton}\n\t\t\t\tonMouseDown={onToggleMouseDown}\n\t\t\t\tonClick={onToggleClick}>\n\t\t\t\t<ChevronDownIcon className={cn(uiStyles.uiToggleIcon, open && uiStyles.uiToggleIconOpen)} />\n\t\t\t</button>\n\t\t</div>\n\t);\n}\n","import { type ComponentPropsWithoutRef, type ReactNode, type Ref } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { InputControl, InputLoadingFrame } from \"../input\";\nimport uiStyles from \"../ui.module.scss\";\n\nimport styles from \"./Picker.module.scss\";\n\nexport interface PickerTriggerInputProps extends Omit<ComponentPropsWithoutRef<\"input\">, \"size\"> {\n\trootRef?: (node: HTMLDivElement | null) => void;\n\tendAdornment?: ReactNode;\n\toverlay?: ReactNode;\n\trootClassName?: string;\n\tinputClassName?: string;\n\tisLoading?: boolean;\n}\n\nexport function PickerTriggerInput({\n\tref,\n\trootRef,\n\tendAdornment,\n\toverlay,\n\trootClassName,\n\tinputClassName,\n\tisLoading,\n\t...props\n}: PickerTriggerInputProps & { ref?: Ref<HTMLInputElement> }) {\n\tconst hasOverlay = overlay !== undefined && overlay !== null;\n\t// Picker проверяет выбранное значение, поэтому визуальная ошибка следует aria-invalid, а не native :invalid поискового input.\n\tconst isInvalid = props[\"aria-invalid\"] === true || props[\"aria-invalid\"] === \"true\";\n\n\treturn (\n\t\t<div\n\t\t\tref={rootRef}\n\t\t\tclassName={cn(uiStyles.uiInputContainer, styles.triggerContainer, rootClassName)}\n\t\t\tdata-has-overlay={hasOverlay || undefined}>\n\t\t\t{isLoading ? (\n\t\t\t\t<InputLoadingFrame />\n\t\t\t) : (\n\t\t\t\t<>\n\t\t\t\t\t<InputControl endAdornment={endAdornment}>\n\t\t\t\t\t\t{({ controlClassName }) => (\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\t{...props}\n\t\t\t\t\t\t\t\tref={ref}\n\t\t\t\t\t\t\t\tclassName={cn(uiStyles.uiInputWithToggle, isInvalid && uiStyles.invalid, controlClassName, inputClassName)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</InputControl>\n\t\t\t\t\t{hasOverlay ? overlay : null}\n\t\t\t\t</>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\nPickerTriggerInput.displayName = \"PickerTriggerInput\";\n","import { type ReactNode, type Ref } from \"react\";\n\nimport styles from \"./Picker.module.scss\";\nimport { PickerClearButton } from \"./PickerClearButton\";\nimport { getPickerPlaceholder } from \"./PickerPlaceholder\";\nimport { PickerSelectedToken } from \"./PickerSelectedToken\";\nimport { PickerTriggerActions } from \"./PickerTriggerActions\";\nimport { PickerTriggerInput, type PickerTriggerInputProps } from \"./PickerTriggerInput\";\n\nexport interface PickerTriggerProps extends Omit<PickerTriggerInputProps, \"placeholder\" | \"overlay\" | \"endAdornment\"> {\n\tref?: Ref<HTMLInputElement>;\n\topen: boolean;\n\toptionCount: number;\n\tplaceholder?: string;\n\tlabel?: ReactNode;\n\tplaceholderFallback?: string;\n\tselectedValue?: ReactNode;\n\thasSelection?: boolean;\n\tshowSelectedValue?: boolean;\n\tclearable?: boolean;\n\tonClear?: () => void;\n\tclearAriaLabel?: string;\n\tonToggleMouseDown?: PickerTriggerActionsProps[\"onToggleMouseDown\"];\n\tonToggleClick: PickerTriggerActionsProps[\"onToggleClick\"];\n\topenAriaLabel?: string;\n\tcloseAriaLabel?: string;\n}\n\ntype PickerTriggerActionsProps = Parameters<typeof PickerTriggerActions>[0];\n\n/**\n * Общая композиция picker-trigger: input, выбранное значение, очистка и кнопка\n * открытия. Владельцы picker-моделей передают только состояние и обработчики.\n */\nexport function PickerTrigger({\n\tref,\n\topen,\n\toptionCount,\n\tplaceholder,\n\tlabel,\n\tplaceholderFallback,\n\tselectedValue,\n\thasSelection,\n\tshowSelectedValue = selectedValue !== undefined && selectedValue !== null,\n\tclearable = false,\n\tonClear,\n\tclearAriaLabel,\n\tonToggleMouseDown,\n\tonToggleClick,\n\topenAriaLabel,\n\tcloseAriaLabel,\n\tdisabled,\n\tinputClassName,\n\t...inputProps\n}: PickerTriggerProps) {\n\tconst hasSelectedValue = hasSelection ?? (selectedValue !== undefined && selectedValue !== null);\n\tconst canClear = clearable && hasSelectedValue && onClear !== undefined && !disabled;\n\n\treturn (\n\t\t<PickerTriggerInput\n\t\t\t{...inputProps}\n\t\t\tref={ref}\n\t\t\tdisabled={disabled}\n\t\t\tplaceholder={\n\t\t\t\tshowSelectedValue ? undefined : getPickerPlaceholder({ placeholder, label, optionCount, fallback: placeholderFallback })\n\t\t\t}\n\t\t\tinputClassName={inputClassName}\n\t\t\trootClassName={clearable ? styles.triggerHasClear : undefined}\n\t\t\toverlay={showSelectedValue ? <PickerSelectedToken>{selectedValue}</PickerSelectedToken> : undefined}\n\t\t\tendAdornment={\n\t\t\t\t<PickerTriggerActions\n\t\t\t\t\topen={open}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tonToggleMouseDown={onToggleMouseDown}\n\t\t\t\t\tonToggleClick={onToggleClick}\n\t\t\t\t\topenAriaLabel={openAriaLabel}\n\t\t\t\t\tcloseAriaLabel={closeAriaLabel}>\n\t\t\t\t\t{canClear ? <PickerClearButton ariaLabel={clearAriaLabel} onClear={onClear} /> : null}\n\t\t\t\t</PickerTriggerActions>\n\t\t\t}\n\t\t/>\n\t);\n}\n","export type PickerTriggerMode = \"display\" | \"search-single\" | \"search-multi\";\n\ninterface PickerTriggerTextFocusParams {\n\topen: boolean;\n\tcurrentQuery: string;\n\thasDisplayValue: boolean;\n}\n\nexport interface PickerTriggerPolicy {\n\tfocusFloatingOnOpen: boolean;\n\trestoreFocusOnClose: boolean;\n\tresetQueryOnClose: boolean;\n\tshouldOpenOnTriggerClick: (open: boolean) => boolean;\n\tshouldOpenOnInputChange: (open: boolean) => boolean;\n\tshouldFocusReferenceOnToggle: (open: boolean) => boolean;\n\tshouldSelectTriggerTextOnFocus: (params: PickerTriggerTextFocusParams) => boolean;\n}\n\n/**\n * Единая политика поведения trigger-input для picker-компонентов.\n * Нормализует различия между display-режимом, single-search и multi-search.\n */\nexport function createPickerTriggerPolicy(mode: PickerTriggerMode): PickerTriggerPolicy {\n\tswitch (mode) {\n\t\tcase \"search-single\":\n\t\t\treturn {\n\t\t\t\tfocusFloatingOnOpen: false,\n\t\t\t\trestoreFocusOnClose: false,\n\t\t\t\tresetQueryOnClose: true,\n\t\t\t\tshouldOpenOnTriggerClick: () => false,\n\t\t\t\tshouldOpenOnInputChange: (open) => !open,\n\t\t\t\tshouldFocusReferenceOnToggle: (open) => !open,\n\t\t\t\tshouldSelectTriggerTextOnFocus: ({ open, currentQuery, hasDisplayValue }) =>\n\t\t\t\t\t!open && currentQuery.length === 0 && hasDisplayValue\n\t\t\t};\n\t\tcase \"search-multi\":\n\t\t\treturn {\n\t\t\t\tfocusFloatingOnOpen: false,\n\t\t\t\trestoreFocusOnClose: false,\n\t\t\t\tresetQueryOnClose: true,\n\t\t\t\tshouldOpenOnTriggerClick: () => false,\n\t\t\t\tshouldOpenOnInputChange: (open) => !open,\n\t\t\t\tshouldFocusReferenceOnToggle: (open) => !open,\n\t\t\t\tshouldSelectTriggerTextOnFocus: () => false\n\t\t\t};\n\t\tcase \"display\":\n\t\tdefault:\n\t\t\treturn {\n\t\t\t\tfocusFloatingOnOpen: true,\n\t\t\t\trestoreFocusOnClose: true,\n\t\t\t\tresetQueryOnClose: false,\n\t\t\t\tshouldOpenOnTriggerClick: (open) => !open,\n\t\t\t\tshouldOpenOnInputChange: () => false,\n\t\t\t\tshouldFocusReferenceOnToggle: () => false,\n\t\t\t\tshouldSelectTriggerTextOnFocus: () => false\n\t\t\t};\n\t}\n}\n","import { useMemo } from \"react\";\n\nimport { normalizeTextToLower } from \"@ryuzaki13/react-foundation-lib/formatters\";\n\ninterface UsePickerDefaultFilterOptions<T> {\n\toptions: readonly T[];\n\tquery: string;\n\tenabled?: boolean;\n\tgetSearchText: (option: T) => unknown;\n}\n\nfunction normalizeSearchText(value: unknown) {\n\tconst parts = Array.isArray(value) ? value : [value];\n\n\treturn normalizeTextToLower(parts.filter(Boolean).join(\" \"));\n}\n\nexport function usePickerDefaultFilter<T>({ options, query, enabled = true, getSearchText }: UsePickerDefaultFilterOptions<T>) {\n\tconst normalizedQuery = normalizeTextToLower(query);\n\n\treturn useMemo(() => {\n\t\tif (!enabled || !normalizedQuery) {\n\t\t\treturn [...options];\n\t\t}\n\n\t\treturn options.filter((option) => normalizeSearchText(getSearchText(option)).includes(normalizedQuery));\n\t}, [enabled, getSearchText, normalizedQuery, options]);\n}\n","import { Placement } from \"@floating-ui/react\";\nimport {\n\ttype FloatingListboxPlacementStrategy,\n\ttype FloatingListboxSizeResolver,\n\tuseFloatingListbox\n} from \"@ryuzaki13/react-foundation-lib/hooks\";\n\nimport { PickerTriggerMode, createPickerTriggerPolicy } from \"./createPickerTriggerPolicy\";\n\ninterface UsePickerFloatingListboxParams<T> {\n\toptions: readonly T[];\n\tselectedIndex: number;\n\topen?: boolean;\n\tonOpenChange?: (open: boolean) => void;\n\tgetOptionDisabled?: (option: T) => boolean;\n\tonSelect?: (option: T) => void;\n\tdisabled?: boolean;\n\tplacement?: Placement;\n\tplacementStrategy?: FloatingListboxPlacementStrategy;\n\tcloseOnSelect?: boolean;\n\tfocusFloatingOnOpen?: boolean;\n\tallowOpenWithoutOptions?: boolean;\n\trestoreFocusOnClose?: boolean;\n\ttriggerMode?: PickerTriggerMode;\n\tresolveFloatingSize?: FloatingListboxSizeResolver;\n}\n\n/**\n * Единая точка входа для popup/listbox поведения во всех picker-компонентах.\n */\nexport function usePickerFloatingListbox<T>(params: UsePickerFloatingListboxParams<T>) {\n\tconst triggerPolicy = params.triggerMode ? createPickerTriggerPolicy(params.triggerMode) : undefined;\n\n\treturn useFloatingListbox({\n\t\t...params,\n\t\tfocusFloatingOnOpen: params.focusFloatingOnOpen ?? triggerPolicy?.focusFloatingOnOpen,\n\t\trestoreFocusOnClose: params.restoreFocusOnClose ?? triggerPolicy?.restoreFocusOnClose\n\t});\n}\n","import { useState } from \"react\";\n\nimport { PickerTriggerMode, createPickerTriggerPolicy } from \"./createPickerTriggerPolicy\";\n\ninterface UsePickerQueryOptions {\n\tquery?: string;\n\tdefaultQuery?: string;\n\tonQuery?: (value: string) => void;\n\tresetOnClose?: boolean;\n\ttriggerMode?: PickerTriggerMode;\n}\n\n/**\n * Управляет controlled/uncontrolled query и возвращает policy закрытия владельцу open-state.\n * Сброс выполняется самим владельцем в событии close, поэтому hook не зеркалит lifecycle через effect.\n */\nexport function usePickerQuery({ query, defaultQuery, onQuery, resetOnClose, triggerMode }: UsePickerQueryOptions) {\n\tconst isControlled = query !== undefined;\n\tconst [internalQuery, setInternalQuery] = useState(defaultQuery ?? \"\");\n\tconst currentQuery = isControlled ? (query ?? \"\") : internalQuery;\n\tconst resolvedResetOnClose = resetOnClose ?? (triggerMode ? createPickerTriggerPolicy(triggerMode).resetQueryOnClose : true);\n\n\tconst setQuery = (nextValue: string) => {\n\t\tif (!isControlled) {\n\t\t\tsetInternalQuery(nextValue);\n\t\t}\n\n\t\tonQuery?.(nextValue);\n\t};\n\n\treturn {\n\t\tquery: currentQuery,\n\t\tsetQuery,\n\t\tclearQuery: () => setQuery(\"\"),\n\t\tresetQueryOnClose: resolvedResetOnClose\n\t};\n}\n","import { useEffect, useRef, useState } from \"react\";\n\ninterface UsePickerSelectionLifecycleOptions<TValue> {\n\tvalue: TValue;\n\topen: boolean;\n\tonCommit: (value: TValue) => void;\n\tonOpen?: () => void;\n\tonClose?: (value: TValue) => void;\n\tisEqual: (left: TValue, right: TValue) => boolean;\n}\n\n/**\n * Общий жизненный цикл чернового выбора для picker-компонентов,\n * где изменения подтверждаются при закрытии popup.\n */\nexport function usePickerSelectionLifecycle<TValue>({\n\tvalue,\n\topen,\n\tonCommit,\n\tonOpen,\n\tonClose,\n\tisEqual\n}: UsePickerSelectionLifecycleOptions<TValue>) {\n\tconst previousOpenRef = useRef(false);\n\tconst [draftValue, setDraftValue] = useState(value);\n\n\tuseEffect(() => {\n\t\tif (previousOpenRef.current && !open) {\n\t\t\tif (!isEqual(draftValue, value)) {\n\t\t\t\tonCommit(draftValue);\n\t\t\t}\n\n\t\t\tonClose?.(draftValue);\n\t\t}\n\n\t\tpreviousOpenRef.current = open;\n\t}, [draftValue, isEqual, onClose, onCommit, open, value]);\n\n\tconst prepareOpen = () => {\n\t\tsetDraftValue(value);\n\t\tonOpen?.();\n\t};\n\n\treturn {\n\t\tdraftValue,\n\t\tsetDraftValue,\n\t\tprepareOpen\n\t};\n}\n","import { MouseEvent, RefObject } from \"react\";\n\nimport { PickerTriggerMode, createPickerTriggerPolicy } from \"./createPickerTriggerPolicy\";\n\ninterface UsePickerTriggerControllerOptions {\n\tmode: PickerTriggerMode;\n\topen: boolean;\n\tcurrentQuery: string;\n\thasDisplayValue: boolean;\n\tinputRef: RefObject<HTMLInputElement | null>;\n\tsetQuery?: (value: string) => void;\n\topenList?: () => void;\n\tclose?: () => void;\n\ttoggleOpen?: () => void;\n\tonBeforeOpen?: () => void;\n}\n\ninterface HandleTriggerKeyDownOptions {\n\tevent: React.KeyboardEvent<HTMLElement>;\n\tonActivateWhenOpen?: () => void;\n\tenableSpaceActivation?: boolean;\n\tenableClosedArrowDownOpen?: boolean;\n\tsuppressClosedArrowUp?: boolean;\n}\n\nfunction focusInput(inputRef: RefObject<HTMLInputElement | null>) {\n\trequestAnimationFrame(() => {\n\t\tinputRef.current?.focus();\n\t});\n}\n\n/**\n * Единый контроллер пользовательских действий на trigger-input.\n * Держит поведение display/search-single/search-multi в одном месте.\n */\nexport function usePickerTriggerController({\n\tmode,\n\topen,\n\tcurrentQuery,\n\thasDisplayValue,\n\tinputRef,\n\tsetQuery,\n\topenList,\n\tclose,\n\ttoggleOpen,\n\tonBeforeOpen\n}: UsePickerTriggerControllerOptions) {\n\tconst policy = createPickerTriggerPolicy(mode);\n\n\tconst openTrigger = () => {\n\t\tonBeforeOpen?.();\n\n\t\tif (openList) {\n\t\t\topenList();\n\t\t\treturn;\n\t\t}\n\n\t\ttoggleOpen?.();\n\t};\n\n\tconst closeTrigger = () => {\n\t\tif (close) {\n\t\t\tclose();\n\t\t\treturn;\n\t\t}\n\n\t\ttoggleOpen?.();\n\t};\n\n\tconst toggleTrigger = () => {\n\t\tif (open) {\n\t\t\tcloseTrigger();\n\t\t} else {\n\t\t\topenTrigger();\n\t\t}\n\n\t\tif (policy.shouldFocusReferenceOnToggle(open)) {\n\t\t\tfocusInput(inputRef);\n\t\t}\n\t};\n\n\treturn {\n\t\tpolicy,\n\t\thandleTriggerInputChange: (nextValue: string) => {\n\t\t\tsetQuery?.(nextValue);\n\n\t\t\tif (policy.shouldOpenOnInputChange(open)) {\n\t\t\t\topenTrigger();\n\t\t\t}\n\t\t},\n\t\thandleTriggerClick: () => {\n\t\t\tif (policy.shouldOpenOnTriggerClick(open)) {\n\t\t\t\topenTrigger();\n\t\t\t}\n\t\t},\n\t\thandleTriggerFocus: (input: HTMLInputElement) => {\n\t\t\tif (\n\t\t\t\tpolicy.shouldSelectTriggerTextOnFocus({\n\t\t\t\t\topen,\n\t\t\t\t\tcurrentQuery,\n\t\t\t\t\thasDisplayValue\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\tinput.select();\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\thandleToggleMouseDown: (event: MouseEvent<HTMLButtonElement>) => {\n\t\t\tevent.preventDefault();\n\t\t},\n\t\thandleToggleClick: () => {\n\t\t\ttoggleTrigger();\n\t\t},\n\t\thandleTriggerKeyDown: ({\n\t\t\tevent,\n\t\t\tonActivateWhenOpen,\n\t\t\tenableSpaceActivation = false,\n\t\t\tenableClosedArrowDownOpen = false,\n\t\t\tsuppressClosedArrowUp = false\n\t\t}: HandleTriggerKeyDownOptions) => {\n\t\t\tif (!open && suppressClosedArrowUp && event.key === \"ArrowUp\") {\n\t\t\t\tevent.preventDefault();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!open && enableClosedArrowDownOpen && event.key === \"ArrowDown\") {\n\t\t\t\tevent.preventDefault();\n\t\t\t\ttoggleTrigger();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (event.key === \"Enter\") {\n\t\t\t\tevent.preventDefault();\n\n\t\t\t\tif (open) {\n\t\t\t\t\tonActivateWhenOpen?.();\n\t\t\t\t} else {\n\t\t\t\t\ttoggleTrigger();\n\t\t\t\t}\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (enableSpaceActivation && event.key === \" \") {\n\t\t\t\tevent.preventDefault();\n\n\t\t\t\tif (open) {\n\t\t\t\t\tonActivateWhenOpen?.();\n\t\t\t\t} else {\n\t\t\t\t\ttoggleTrigger();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\ttoggleTrigger\n\t};\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
import { HighlightText as e } from "../text/index.js";
|
|
2
|
+
import { t } from "./ui.module-oRwY3Zli.js";
|
|
3
|
+
import { u as n } from "./input-KXI7o06g.js";
|
|
4
|
+
import { a as r, f as i, i as a, m as o, r as s, s as c, t as l, u, v as d } from "./picker-DagDe9OH.js";
|
|
5
|
+
import { Option as f, OptionCode as p, OptionContent as m, OptionText as h } from "../option/index.js";
|
|
6
|
+
import { t as g } from "./odata-dependent-C_DCbKY2.js";
|
|
7
|
+
import { n as _ } from "./useODataSelectBase-DwR4Lfv-.js";
|
|
8
|
+
import { t as v } from "./OptionContentContainer-CWHlfm5Z.js";
|
|
9
|
+
import { cn as y } from "@ryuzaki13/react-foundation-lib/utils";
|
|
10
|
+
import { CheckIcon as ee } from "lucide-react";
|
|
11
|
+
import { Fragment as b, jsx as x, jsxs as S } from "react/jsx-runtime";
|
|
12
|
+
import { Fragment as te, useCallback as ne, useMemo as re, useRef as ie, useState as ae } from "react";
|
|
13
|
+
import { useODataCollectionModel as C } from "@ryuzaki13/react-foundation-api/odata";
|
|
14
|
+
//#region src/select/lib/getOptionSearchText.ts
|
|
15
|
+
function oe({ option: e, getOptionLabel: t, getOptionCode: n, getOptionGroup: r }) {
|
|
16
|
+
return [
|
|
17
|
+
o(t(e)),
|
|
18
|
+
o(n?.(e)),
|
|
19
|
+
o(r?.(e)?.label)
|
|
20
|
+
].filter((e) => !!e).join(" ").toLowerCase();
|
|
21
|
+
}
|
|
22
|
+
function w(e, t, n) {
|
|
23
|
+
return e.find((e) => e.value === t) ?? n;
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/select/model/useODataSelect.ts
|
|
27
|
+
function T({ odata: e, segment: t, model: n, value: r, dependencies: i, onChange: a }) {
|
|
28
|
+
let o = _({
|
|
29
|
+
odata: e,
|
|
30
|
+
segment: t,
|
|
31
|
+
model: n,
|
|
32
|
+
value: r ? [r] : [],
|
|
33
|
+
dependencies: i
|
|
34
|
+
}), s = o.selectedItems[0], c = re(() => s ? [s, ...o.filteredItems] : o.filteredItems, [o.filteredItems, s]), l = (e) => {
|
|
35
|
+
a(e?.[o.selectionKey]);
|
|
36
|
+
};
|
|
37
|
+
return {
|
|
38
|
+
...o,
|
|
39
|
+
selectedItem: s,
|
|
40
|
+
options: c,
|
|
41
|
+
handleChange: l
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/select/lib/createSelectOptionSections.ts
|
|
46
|
+
function se(e, t) {
|
|
47
|
+
let n = [];
|
|
48
|
+
return e.forEach((e, r) => {
|
|
49
|
+
let i = t(e), a = n.at(-1), o = a?.group?.key === i?.key;
|
|
50
|
+
if (a && o) {
|
|
51
|
+
a.items.push({
|
|
52
|
+
option: e,
|
|
53
|
+
index: r
|
|
54
|
+
});
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
n.push({
|
|
58
|
+
group: i,
|
|
59
|
+
items: [{
|
|
60
|
+
option: e,
|
|
61
|
+
index: r
|
|
62
|
+
}]
|
|
63
|
+
});
|
|
64
|
+
}), n;
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region src/select/Select.tsx
|
|
68
|
+
function E(e) {
|
|
69
|
+
let { label: n, description: p, disabled: h, placeholder: g, size: _, options: C, value: w, onChange: T, getOptionKey: E, getOptionLabel: D, getOptionCode: O, getOptionSearchText: k, getOptionDisabled: A, getOptionAriaLabel: j, getOptionGroup: M, getOptionClassName: N, renderOption: P, renderValue: F, className: ce, error: I, required: L, buttonClassName: le, optionsClassName: ue, optionsMaxWidth: de, optionsContentClassName: fe, searchable: R = !1, defaultFilter: pe = !0, query: me, defaultQuery: he, onQuery: ge, renderPopupHeader: _e, emptyState: ve, isLoading: ye, errorState: be, placement: xe = "bottom-start", clearable: z = !1 } = e, B = T, V = ie(null), [H, Se] = ae(!1), U = R ? "search-single" : "display", W = w === void 0 ? void 0 : E(w), G = W === void 0 ? void 0 : C.find((e) => E(e) === W) ?? w, { query: K, setQuery: q, resetQueryOnClose: Ce } = s({
|
|
70
|
+
query: me,
|
|
71
|
+
defaultQuery: he,
|
|
72
|
+
onQuery: ge,
|
|
73
|
+
triggerMode: U
|
|
74
|
+
}), we = (e) => {
|
|
75
|
+
H && !e && Ce && q(""), Se(e);
|
|
76
|
+
}, Te = ne((e) => k?.(e) ?? oe({
|
|
77
|
+
option: e,
|
|
78
|
+
getOptionLabel: D,
|
|
79
|
+
getOptionCode: O,
|
|
80
|
+
getOptionGroup: M
|
|
81
|
+
}), [
|
|
82
|
+
k,
|
|
83
|
+
O,
|
|
84
|
+
M,
|
|
85
|
+
D
|
|
86
|
+
]), J = r({
|
|
87
|
+
options: C,
|
|
88
|
+
query: K,
|
|
89
|
+
enabled: R && pe,
|
|
90
|
+
getSearchText: Te
|
|
91
|
+
}), Y = re(() => M ? se(J, M) : void 0, [M, J]), Ee = W === void 0 ? -1 : J.findIndex((e) => E(e) === W), { activeIndex: De, context: Oe, floatingStyles: ke, getFloatingProps: Ae, setReference: je, setFloating: Me, setOptionRef: Ne, close: X, openList: Pe, toggleOpen: Fe, selectOption: Ie, selectActiveOption: Le, handleReferenceKeyDown: Re, handleFloatingKeyDown: ze, getOptionId: Be, getActiveOptionId: Ve } = a({
|
|
92
|
+
options: J,
|
|
93
|
+
selectedIndex: Ee,
|
|
94
|
+
open: H,
|
|
95
|
+
onOpenChange: we,
|
|
96
|
+
getOptionDisabled: A,
|
|
97
|
+
onSelect: B,
|
|
98
|
+
disabled: h,
|
|
99
|
+
placement: xe,
|
|
100
|
+
triggerMode: U
|
|
101
|
+
}), He = J.length > 0, Ue = G === void 0 ? void 0 : D(G), Z = G === void 0 ? void 0 : F ? F(G) : Ue, We = o(Ue), Ge = G === void 0 ? void 0 : o(O?.(G)), Ke = o(Z) ?? We ?? Ge ?? (W === void 0 ? "" : String(W)), qe = R && (H || K.length > 0) ? K : G === void 0 ? "" : Ke, Q = l({
|
|
102
|
+
mode: U,
|
|
103
|
+
open: H,
|
|
104
|
+
currentQuery: K,
|
|
105
|
+
hasDisplayValue: G !== void 0,
|
|
106
|
+
inputRef: V,
|
|
107
|
+
setQuery: q,
|
|
108
|
+
openList: Pe,
|
|
109
|
+
close: X,
|
|
110
|
+
toggleOpen: Fe
|
|
111
|
+
}), Je = (e) => {
|
|
112
|
+
V.current = e;
|
|
113
|
+
}, Ye = () => {
|
|
114
|
+
z && B(void 0), q(""), X();
|
|
115
|
+
}, $ = (e, t, n) => {
|
|
116
|
+
let r = E(t), i = W !== void 0 && r === W, a = n === De, o = A?.(t) ?? !1, s = {
|
|
117
|
+
active: a,
|
|
118
|
+
selected: i,
|
|
119
|
+
disabled: o
|
|
120
|
+
};
|
|
121
|
+
return /* @__PURE__ */ x(f, {
|
|
122
|
+
id: Be(e, n),
|
|
123
|
+
ref: (e) => Ne(n, e),
|
|
124
|
+
role: "option",
|
|
125
|
+
"aria-selected": i,
|
|
126
|
+
"aria-disabled": o || void 0,
|
|
127
|
+
"aria-label": j?.(t),
|
|
128
|
+
active: a,
|
|
129
|
+
selected: i,
|
|
130
|
+
disabled: o,
|
|
131
|
+
className: N?.(t, s),
|
|
132
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
133
|
+
onClick: () => Ie(t),
|
|
134
|
+
children: P ? /* @__PURE__ */ x(v, { children: P(t, s) }) : /* @__PURE__ */ x(v, { children: /* @__PURE__ */ x(m, {
|
|
135
|
+
icon: x(i ? ee : "span", {}),
|
|
136
|
+
text: D(t),
|
|
137
|
+
code: O?.(t)
|
|
138
|
+
}) })
|
|
139
|
+
}, r);
|
|
140
|
+
};
|
|
141
|
+
return /* @__PURE__ */ x(d, {
|
|
142
|
+
label: n,
|
|
143
|
+
description: p,
|
|
144
|
+
disabled: h,
|
|
145
|
+
size: _,
|
|
146
|
+
className: ce,
|
|
147
|
+
error: I,
|
|
148
|
+
required: L,
|
|
149
|
+
children: ({ controlId: e, labelId: r, describedBy: a }) => {
|
|
150
|
+
let o = `${e}-listbox`;
|
|
151
|
+
return /* @__PURE__ */ S(b, { children: [/* @__PURE__ */ x(c, {
|
|
152
|
+
ref: Je,
|
|
153
|
+
rootRef: je,
|
|
154
|
+
id: e,
|
|
155
|
+
type: "text",
|
|
156
|
+
disabled: h,
|
|
157
|
+
readOnly: !R,
|
|
158
|
+
autoComplete: "off",
|
|
159
|
+
role: "combobox",
|
|
160
|
+
isLoading: ye,
|
|
161
|
+
open: H,
|
|
162
|
+
optionCount: C.length,
|
|
163
|
+
label: n,
|
|
164
|
+
placeholder: g,
|
|
165
|
+
value: qe,
|
|
166
|
+
selectedValue: Z ?? Ke,
|
|
167
|
+
hasSelection: G !== void 0,
|
|
168
|
+
showSelectedValue: !1,
|
|
169
|
+
clearable: !!z,
|
|
170
|
+
onClear: Ye,
|
|
171
|
+
onToggleMouseDown: Q.handleToggleMouseDown,
|
|
172
|
+
onToggleClick: Q.handleToggleClick,
|
|
173
|
+
"aria-labelledby": r,
|
|
174
|
+
"aria-describedby": a,
|
|
175
|
+
"aria-required": L || void 0,
|
|
176
|
+
"aria-invalid": !!I || void 0,
|
|
177
|
+
"aria-haspopup": "listbox",
|
|
178
|
+
"aria-expanded": H,
|
|
179
|
+
"aria-controls": H ? o : void 0,
|
|
180
|
+
"aria-autocomplete": R ? "list" : "none",
|
|
181
|
+
"aria-activedescendant": H ? Ve(o) : void 0,
|
|
182
|
+
inputClassName: y(le, "textOverflow"),
|
|
183
|
+
onChange: (e) => {
|
|
184
|
+
R && Q.handleTriggerInputChange(e.target.value);
|
|
185
|
+
},
|
|
186
|
+
onClick: Q.handleTriggerClick,
|
|
187
|
+
onFocus: (e) => {
|
|
188
|
+
Q.handleTriggerFocus(e.currentTarget);
|
|
189
|
+
},
|
|
190
|
+
onKeyDown: (e) => {
|
|
191
|
+
Re(e), !e.defaultPrevented && Q.handleTriggerKeyDown({
|
|
192
|
+
event: e,
|
|
193
|
+
onActivateWhenOpen: Le,
|
|
194
|
+
enableSpaceActivation: !R
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}), /* @__PURE__ */ x(i, {
|
|
198
|
+
open: H,
|
|
199
|
+
context: Oe,
|
|
200
|
+
floatingStyles: ke,
|
|
201
|
+
listId: o,
|
|
202
|
+
labelId: r,
|
|
203
|
+
descriptionId: a,
|
|
204
|
+
activeOptionId: He ? Ve(o) : void 0,
|
|
205
|
+
setFloating: Me,
|
|
206
|
+
getFloatingProps: Ae,
|
|
207
|
+
onKeyDown: ze,
|
|
208
|
+
className: ue,
|
|
209
|
+
maxWidth: de,
|
|
210
|
+
toolbar: _e,
|
|
211
|
+
children: /* @__PURE__ */ x("div", {
|
|
212
|
+
role: "presentation",
|
|
213
|
+
className: y(fe, "h100 scrollable overscroll"),
|
|
214
|
+
children: He ? Y ? Y.map((e, n) => {
|
|
215
|
+
let r = e.group ? `${o}-group-${n}` : void 0, i = e.items.map(({ option: e, index: t }) => $(o, e, t));
|
|
216
|
+
return e.group ? /* @__PURE__ */ S("div", {
|
|
217
|
+
role: "group",
|
|
218
|
+
"aria-labelledby": r,
|
|
219
|
+
children: [/* @__PURE__ */ x("div", {
|
|
220
|
+
id: r,
|
|
221
|
+
className: t.uiPopupGroupLabel,
|
|
222
|
+
children: e.group.label
|
|
223
|
+
}), i]
|
|
224
|
+
}, `group-${String(e.group.key)}-${n}`) : /* @__PURE__ */ x(te, { children: i }, `options-${n}`);
|
|
225
|
+
}) : J.map((e, t) => $(o, e, t)) : /* @__PURE__ */ x(u, {
|
|
226
|
+
emptyState: ve,
|
|
227
|
+
errorState: be
|
|
228
|
+
})
|
|
229
|
+
})
|
|
230
|
+
})] });
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
//#endregion
|
|
235
|
+
//#region src/select/SelectOptionContent.tsx
|
|
236
|
+
function D({ label: t, code: n, highlight: r, labelClassName: i, codeClassName: a }) {
|
|
237
|
+
return /* @__PURE__ */ S(b, { children: [/* @__PURE__ */ x(h, {
|
|
238
|
+
className: y("flexEllipsis", i),
|
|
239
|
+
children: /* @__PURE__ */ x(e, {
|
|
240
|
+
text: t,
|
|
241
|
+
highlight: r
|
|
242
|
+
})
|
|
243
|
+
}), n && /* @__PURE__ */ x(p, {
|
|
244
|
+
className: a,
|
|
245
|
+
children: /* @__PURE__ */ x(e, {
|
|
246
|
+
text: n,
|
|
247
|
+
highlight: r
|
|
248
|
+
})
|
|
249
|
+
})] });
|
|
250
|
+
}
|
|
251
|
+
//#endregion
|
|
252
|
+
//#region src/select/ODataSelect.tsx
|
|
253
|
+
function O(e, t, n) {
|
|
254
|
+
return e ? t || Object.keys(e).find((e) => e !== n) || n : t || n;
|
|
255
|
+
}
|
|
256
|
+
function k({ odata: e, segment: t, model: r, size: i, label: a, description: o, disabled: s, required: c, error: l, value: u, dependencies: d, onChange: f, clearable: p }) {
|
|
257
|
+
let m = T({
|
|
258
|
+
odata: e,
|
|
259
|
+
segment: t,
|
|
260
|
+
model: C(r),
|
|
261
|
+
value: u,
|
|
262
|
+
dependencies: d,
|
|
263
|
+
onChange: f
|
|
264
|
+
});
|
|
265
|
+
if (m.isLoading) return /* @__PURE__ */ x(n, {
|
|
266
|
+
size: i,
|
|
267
|
+
label: a,
|
|
268
|
+
description: o,
|
|
269
|
+
required: c
|
|
270
|
+
});
|
|
271
|
+
let h = t.hideCode ?? e.hideCode, g = O(m.selectedItem ?? m.options[0], m.textKey, m.codeKey);
|
|
272
|
+
return /* @__PURE__ */ x(E, {
|
|
273
|
+
size: i,
|
|
274
|
+
label: a,
|
|
275
|
+
description: o,
|
|
276
|
+
required: c,
|
|
277
|
+
error: l,
|
|
278
|
+
options: m.options,
|
|
279
|
+
value: m.selectedItem,
|
|
280
|
+
onChange: m.handleChange,
|
|
281
|
+
getOptionKey: (e) => e[m.codeKey],
|
|
282
|
+
getOptionLabel: (e) => e[g],
|
|
283
|
+
getOptionCode: h ? void 0 : (e) => e[m.codeKey],
|
|
284
|
+
getOptionAriaLabel: (e) => h || e[g] === e[m.codeKey] ? String(e[g]) : `${e[g]} ${e[m.codeKey]}`,
|
|
285
|
+
renderValue: (e) => /* @__PURE__ */ x(D, {
|
|
286
|
+
label: e[g],
|
|
287
|
+
code: h ? void 0 : e[m.codeKey]
|
|
288
|
+
}),
|
|
289
|
+
renderOption: (e) => /* @__PURE__ */ x(D, {
|
|
290
|
+
label: e[g],
|
|
291
|
+
code: h ? void 0 : e[m.codeKey],
|
|
292
|
+
highlight: m.debouncedQuery
|
|
293
|
+
}),
|
|
294
|
+
searchable: !0,
|
|
295
|
+
query: m.query,
|
|
296
|
+
onQuery: m.setQuery,
|
|
297
|
+
defaultFilter: !1,
|
|
298
|
+
disabled: s || m.isLoading,
|
|
299
|
+
placeholder: m.placeholder,
|
|
300
|
+
isLoading: m.isLoading,
|
|
301
|
+
errorState: m.isError ? "Ошибка загрузки" : void 0,
|
|
302
|
+
emptyState: !m.isLoading && !m.isError ? "Нет данных" : void 0,
|
|
303
|
+
clearable: p
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
//#endregion
|
|
307
|
+
//#region src/select/ODataDependentSegmentSelect.tsx
|
|
308
|
+
function A(e) {
|
|
309
|
+
let { item: t, disabled: n, label: r, description: i, required: a, fieldError: o, size: s, width: c = 15, clearable: l } = e, u = g(e), { updateSegment: d } = u, f = `calc(${c}em + var(--width-add))`, p = ne((e) => {
|
|
310
|
+
d(t.id, e === void 0 ? [] : [e]);
|
|
311
|
+
}, [t.id, d]);
|
|
312
|
+
return /* @__PURE__ */ x("div", {
|
|
313
|
+
style: {
|
|
314
|
+
maxWidth: f,
|
|
315
|
+
minWidth: f
|
|
316
|
+
},
|
|
317
|
+
children: /* @__PURE__ */ x(k, {
|
|
318
|
+
odata: t.odata,
|
|
319
|
+
segment: t.segment,
|
|
320
|
+
model: t.model,
|
|
321
|
+
dependencies: u.values,
|
|
322
|
+
value: u.values[t.id]?.[0],
|
|
323
|
+
onChange: p,
|
|
324
|
+
disabled: n || u.isSegmentDisabled(t.id),
|
|
325
|
+
label: r,
|
|
326
|
+
description: i,
|
|
327
|
+
required: a,
|
|
328
|
+
error: o,
|
|
329
|
+
size: s,
|
|
330
|
+
clearable: l
|
|
331
|
+
})
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
//#endregion
|
|
335
|
+
//#region src/select/SerializableSelect.tsx
|
|
336
|
+
function j(e, t) {
|
|
337
|
+
return String(e[t]);
|
|
338
|
+
}
|
|
339
|
+
function M(e, t, n) {
|
|
340
|
+
let r = e[t];
|
|
341
|
+
if (typeof r == "string" || typeof r == "number") return String(r);
|
|
342
|
+
let i = j(e, n);
|
|
343
|
+
return String(i);
|
|
344
|
+
}
|
|
345
|
+
function N({ label: e, description: t, disabled: n, placeholder: r, size: i, options: a, value: o, onChange: s, optionKey: c, optionLabel: l, renderCode: u, className: d, clearable: f, required: p, error: m }) {
|
|
346
|
+
let h = o === void 0 ? void 0 : a.find((e) => j(e, c) === o);
|
|
347
|
+
return /* @__PURE__ */ x(E, {
|
|
348
|
+
label: e,
|
|
349
|
+
description: t,
|
|
350
|
+
disabled: n,
|
|
351
|
+
placeholder: r,
|
|
352
|
+
size: i,
|
|
353
|
+
options: a,
|
|
354
|
+
value: h,
|
|
355
|
+
onChange: (e) => s(e ? j(e, c) : void 0),
|
|
356
|
+
getOptionKey: (e) => j(e, c),
|
|
357
|
+
getOptionLabel: (e) => M(e, l, c),
|
|
358
|
+
getOptionCode: u ? (e) => j(e, c) : void 0,
|
|
359
|
+
className: d,
|
|
360
|
+
clearable: f,
|
|
361
|
+
required: p,
|
|
362
|
+
error: m
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
//#endregion
|
|
366
|
+
export { w as a, E as i, A as n, k as r, N as t };
|
|
367
|
+
|
|
368
|
+
//# sourceMappingURL=select-C-1U-ujV.js.map
|