@ryuzaki13/react-foundation-ui 2.1.0 → 3.0.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/COLOR_TOKENS_MIGRATION.md +224 -0
- package/README.md +14 -18
- package/dist/advanced-search/index.js +8 -8
- package/dist/badge/index.js +1 -1
- package/dist/barcode-scanner/index.js +2 -2
- package/dist/base-table/index.js +1 -1
- package/dist/button/index.js +1 -1
- package/dist/check-box/index.js +1 -1
- package/dist/chunks/{CalendarView-Bhaov_XE.js → CalendarView-Dm55k0bN.js} +2 -2
- package/dist/chunks/CalendarView-Dm55k0bN.js.map +1 -0
- package/dist/chunks/ImageViewerRuntime-HGBWp9NM.js.map +1 -1
- package/dist/chunks/{TextEditorLexicalClient-CSXZQOYo.js → TextEditorLexicalClient-D46Zed55.js} +6 -6
- package/dist/chunks/TextEditorLexicalClient-D46Zed55.js.map +1 -0
- package/dist/chunks/{badge-DUI2ET6q.js → badge-6mXO9BWP.js} +2 -2
- package/dist/chunks/badge-6mXO9BWP.js.map +1 -0
- package/dist/chunks/{base-table-BqW1n7tv.js → base-table-BWvKfI2W.js} +2 -2
- package/dist/chunks/{base-table-BqW1n7tv.js.map → base-table-BWvKfI2W.js.map} +1 -1
- package/dist/chunks/{button-BaUlN-nt.js → button-DF21yxVp.js} +3 -3
- package/dist/chunks/{button-BaUlN-nt.js.map → button-DF21yxVp.js.map} +1 -1
- package/dist/chunks/{check-box-CC8CDnSR.js → check-box-CZyhzmR0.js} +3 -3
- package/dist/chunks/{check-box-CC8CDnSR.js.map → check-box-CZyhzmR0.js.map} +1 -1
- package/dist/chunks/{context-menu-Dj6MXgv6.js → context-menu-DgvXGCuI.js} +3 -3
- package/dist/chunks/context-menu-DgvXGCuI.js.map +1 -0
- package/dist/chunks/{date-input-DkLfO3Ng.js → date-input-BwLOiGXp.js} +5 -5
- package/dist/chunks/{date-input-DkLfO3Ng.js.map → date-input-BwLOiGXp.js.map} +1 -1
- package/dist/chunks/dialog-Dqq8ZN99.js +50 -0
- package/dist/chunks/dialog-Dqq8ZN99.js.map +1 -0
- package/dist/chunks/{input-D1jOxm0t.js → input-DSPKgiCK.js} +2 -2
- package/dist/chunks/input-DSPKgiCK.js.map +1 -0
- package/dist/chunks/{input-files-CDGpJaUm.js → input-files-tIS17-zX.js} +3 -3
- package/dist/chunks/input-files-tIS17-zX.js.map +1 -0
- package/dist/chunks/{input-search-Ci1ubGox.js → input-search-Cat4c7SM.js} +2 -2
- package/dist/chunks/{input-search-Ci1ubGox.js.map → input-search-Cat4c7SM.js.map} +1 -1
- package/dist/chunks/misc-DeGboAt-.js.map +1 -1
- package/dist/chunks/{modal-CbAwLHlM.js → modal-dplfAaER.js} +2 -2
- package/dist/chunks/{modal-CbAwLHlM.js.map → modal-dplfAaER.js.map} +1 -1
- package/dist/chunks/{multi-select-V7SLAduU.js → multi-select-BZ9N6Dal.js} +4 -4
- package/dist/chunks/{multi-select-V7SLAduU.js.map → multi-select-BZ9N6Dal.js.map} +1 -1
- package/dist/chunks/{picker-DZ4-1BvK.js → picker-lvm82d0A.js} +3 -3
- package/dist/chunks/picker-lvm82d0A.js.map +1 -0
- package/dist/chunks/popover-Bne-Ljbs.js.map +1 -1
- package/dist/chunks/{radio-group-DhpP7JSJ.js → radio-group-CRk_1ODZ.js} +2 -2
- package/dist/chunks/radio-group-CRk_1ODZ.js.map +1 -0
- package/dist/chunks/{select-B7cWlJxL.js → select-aTGupQan.js} +4 -4
- package/dist/chunks/{select-B7cWlJxL.js.map → select-aTGupQan.js.map} +1 -1
- package/dist/chunks/{table-DMLFUBlb.js → table-DxoSOvQK.js} +2 -2
- package/dist/chunks/table-DxoSOvQK.js.map +1 -0
- package/dist/chunks/{ui.module-BsDio9A3.js → ui.module-oRwY3Zli.js} +2 -1
- package/dist/chunks/ui.module-oRwY3Zli.js.map +1 -0
- package/dist/chunks/{uiClasses-BVwFzzsr.js → uiClasses-CQj47jkF.js} +11 -2
- package/dist/chunks/uiClasses-CQj47jkF.js.map +1 -0
- package/dist/chunks/wheel-picker-FS58cRsQ.js.map +1 -1
- package/dist/context-menu/index.js +1 -1
- package/dist/date-input/index.js +2 -2
- package/dist/date-time-input/index.js +3 -3
- package/dist/dialog/index.js +2 -50
- package/dist/disclosure/index.js +2 -2
- package/dist/disclosure/index.js.map +1 -1
- package/dist/drop-zone/index.js +1 -1
- package/dist/drop-zone/index.js.map +1 -1
- package/dist/errors/index.js +4 -4
- package/dist/errors/index.js.map +1 -1
- package/dist/expandable-action-panel/index.js +1 -1
- package/dist/image/index.js +5 -5
- package/dist/image/index.js.map +1 -1
- package/dist/input/index.js +1 -1
- package/dist/input-date-time/index.js +2 -2
- package/dist/input-file/index.js +2 -2
- package/dist/input-files/index.js +1 -1
- package/dist/input-image/index.js +2 -2
- package/dist/input-search/index.js +1 -1
- package/dist/layout-picker/index.js +1 -1
- package/dist/layout-picker/index.js.map +1 -1
- package/dist/listbox/index.js +1 -1
- package/dist/modal/index.js +1 -1
- package/dist/multi-select/index.js +1 -1
- package/dist/notifications/index.js +1 -1
- package/dist/notifications/index.js.map +1 -1
- package/dist/option/index.js +1 -1
- package/dist/picker/index.js +1 -1
- package/dist/preset-range-date-input/index.js +1 -1
- package/dist/preset-select/index.js +1 -1
- package/dist/radio-button/index.js +2 -2
- package/dist/radio-group/index.js +1 -1
- package/dist/select/index.js +1 -1
- package/dist/simple-table/index.js +1 -1
- package/dist/slider/index.js +3 -3
- package/dist/slider/index.js.map +1 -1
- package/dist/state-select/index.js +1 -1
- package/dist/status-indicator/StatusIndicator.d.ts.map +1 -1
- package/dist/status-indicator/index.js +2 -0
- package/dist/status-indicator/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/switch/index.js +1 -1
- package/dist/table/index.js +1 -1
- package/dist/table-editor/index.d.ts +3 -0
- package/dist/table-editor/index.d.ts.map +1 -0
- package/dist/table-editor/index.js +462 -0
- package/dist/table-editor/index.js.map +1 -0
- package/dist/table-editor/model/useTableEditor.d.ts +25 -0
- package/dist/table-editor/model/useTableEditor.d.ts.map +1 -0
- package/dist/table-editor/model/useTableEditorTable.d.ts +10 -0
- package/dist/table-editor/model/useTableEditorTable.d.ts.map +1 -0
- package/dist/table-editor/ui/TableEditor.d.ts +21 -0
- package/dist/table-editor/ui/TableEditor.d.ts.map +1 -0
- package/dist/table-editor/ui/TableEditorGrid.d.ts +14 -0
- package/dist/table-editor/ui/TableEditorGrid.d.ts.map +1 -0
- package/dist/table-editor/ui/TableEditorStructure.d.ts +10 -0
- package/dist/table-editor/ui/TableEditorStructure.d.ts.map +1 -0
- package/dist/table-editor/ui/TableEditorToolbar.d.ts +11 -0
- package/dist/table-editor/ui/TableEditorToolbar.d.ts.map +1 -0
- package/dist/table-sorting/index.js +1 -1
- package/dist/tabs/index.js +2 -2
- package/dist/tabs/index.js.map +1 -1
- package/dist/tag-input/index.js +2 -2
- package/dist/tag-input/index.js.map +1 -1
- package/dist/text-editor/index.js +1 -1
- package/dist/textarea/index.js +2 -2
- package/dist/toggle/index.js +1 -1
- package/dist/toggle/index.js.map +1 -1
- package/dist/tree-select/index.js +3 -3
- package/dist/tree-select/index.js.map +1 -1
- package/dist/tree-table/index.js +1 -1
- package/dist/tree-table/index.js.map +1 -1
- package/dist/types.d.ts +3 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/uiClasses.d.ts.map +1 -1
- package/package.json +8 -3
- package/src/styles/_border.scss +2 -2
- package/src/styles/_color.scss +8 -8
- package/src/styles/_components.scss +2 -2
- package/src/styles/_normalize.scss +4 -4
- package/src/styles/config/_index.scss +95 -182
- package/src/styles/mixins/_controls.scss +43 -26
- package/src/styles/mixins/_mixin.scss +0 -187
- package/src/styles/mixins/controls.test.ts +28 -6
- package/src/styles/themes/_interactive-surface.scss +12 -12
- package/src/styles/themes/_theme.scss +21 -157
- package/src/styles/themes/theme.test.ts +66 -48
- package/storybook-static/assets/{Badge-BXbiidny.js → Badge-DLpkFLAr.js} +8 -2
- package/storybook-static/assets/{Badge.stories-DCOkVsyk.js → Badge.stories-DwwZ0O7j.js} +7 -1
- package/storybook-static/assets/{BadgeList-DgUScGRc.js → BadgeList-C0bhovUR.js} +2 -2
- package/storybook-static/assets/{BadgeList-CD5894x5.css → BadgeList-DbjeNuw0.css} +1 -1
- package/storybook-static/assets/{BarcodeScannerDialog.stories-7Bv_TejN.js → BarcodeScannerDialog.stories-DYXaW4Vw.js} +1 -1
- package/storybook-static/assets/{Button-0UDcBhBt.js → Button-B1nvnaMI.js} +12 -2
- package/storybook-static/assets/{Button-BpQRrzrS.js → Button-PAj4mH8o.js} +4 -2
- package/storybook-static/assets/Button.stories-CNvWyh5M.js +106 -0
- package/storybook-static/assets/{CalendarView-B93LI4f_.js → CalendarView-WUXapLvN.js} +1 -1
- package/storybook-static/assets/CalendarView-dgpVDRJR.css +1 -0
- package/storybook-static/assets/{CheckBox-BaAouU5d.js → CheckBox-B9f_n0Nh.js} +2 -2
- package/storybook-static/assets/{CheckBox-CFusvDS8.js → CheckBox-C3r_FdXc.js} +1 -1
- package/storybook-static/assets/{CheckBox.stories-Bdr_GC0M.js → CheckBox.stories-B5CFQBFx.js} +1 -1
- package/storybook-static/assets/{Color-6AOWCN3U-B8A6Hc7V.js → Color-6AOWCN3U-tYUAsbHo.js} +1 -1
- package/storybook-static/assets/{ContextMenu-CvHpWBGV.js → ContextMenu-C-T3O2d9.js} +1 -1
- package/storybook-static/assets/{ContextMenu-BcNU89-b.js → ContextMenu-PIvPPvq1.js} +1 -1
- package/storybook-static/assets/ContextMenu-yhWq2uJ3.css +1 -0
- package/storybook-static/assets/{ContextMenu.stories-DQDlVNxB.js → ContextMenu.stories-Bmy_0Oug.js} +1 -1
- package/storybook-static/assets/{CustomOptionButton-DkGlBvWP.js → CustomOptionButton-D_qTIop3.js} +1 -1
- package/storybook-static/assets/{DateInput-NkrPSWMl.js → DateInput-B7GZSkR3.js} +1 -1
- package/storybook-static/assets/{DateInput-CWsb-NhT.js → DateInput-C-goSdP-.js} +1 -1
- package/storybook-static/assets/{DateInput.stories-Bvz465d-.js → DateInput.stories-CeAMz_x1.js} +1 -1
- package/storybook-static/assets/{DateRangePresetSelect-DC6_r8SQ.js → DateRangePresetSelect-BZ9U_l_x.js} +1 -1
- package/storybook-static/assets/{DateRangePresetSelect-DQlphKzc.js → DateRangePresetSelect-BmjgWIxM.js} +1 -1
- package/storybook-static/assets/{DateRangePresetSelect.stories-DVfqPYN5.js → DateRangePresetSelect.stories-5UGP9HcH.js} +1 -1
- package/storybook-static/assets/{Detail-CXQYyd94.js → Detail-C6duvCft.js} +1 -1
- package/storybook-static/assets/{Detail.stories-BEXByYXt.js → Detail.stories-DQZciNeZ.js} +1 -1
- package/storybook-static/assets/{Dialog-CyYTYgbp.js → Dialog-87D5Shqd.js} +1 -1
- package/storybook-static/assets/{Dialog-B2UTbDCv.js → Dialog-Bx4-acbv.js} +1 -1
- package/storybook-static/assets/{Dialog.stories-BWluB4Ya.js → Dialog.stories-BgOQABzP.js} +1 -1
- package/storybook-static/assets/{Disclosure-Dv5XOsna.js → Disclosure-ZctFZjdw.js} +1 -1
- package/storybook-static/assets/{Disclosure.stories-BxK_fmJE.js → Disclosure.stories-BioI8Dpv.js} +1 -1
- package/storybook-static/assets/{DisclosureGroup-B2O8D8CG.js → DisclosureGroup-Cn2EEocA.js} +1 -1
- package/storybook-static/assets/DisclosureGroup-D_ldcGgp.css +1 -0
- package/storybook-static/assets/{DocsRenderer-JROSPFPF-7N0jH0Oi.js → DocsRenderer-JROSPFPF-CoppGUHs.js} +1 -1
- package/storybook-static/assets/{DropZone-DL34ooyF.js → DropZone-68BioqBN.js} +1 -1
- package/storybook-static/assets/{DropZone-ZlPjdEuO.js → DropZone-BpInQyuE.js} +1 -1
- package/storybook-static/assets/{DropZone-C7HIN5ml.css → DropZone-C4gPTIz0.css} +1 -1
- package/storybook-static/assets/{DropZone.stories-BT9JvF9d.js → DropZone.stories-DhVyaedf.js} +1 -1
- package/storybook-static/assets/{DropdownMenu-BhC5f2Qc.js → DropdownMenu-Dw-i5abQ.js} +1 -1
- package/storybook-static/assets/{ExpandableActionPanel-C77qVHBP.js → ExpandableActionPanel-Bb7Eo_iW.js} +1 -1
- package/storybook-static/assets/{ExpandableActionPanel.stories-D1MJEw6F.js → ExpandableActionPanel.stories-B0XABlVT.js} +1 -1
- package/storybook-static/assets/{Flex-BHt3-yoh.js → Flex-CG5yKEBH.js} +1 -1
- package/storybook-static/assets/{Flex.stories-M8QVGuVA.js → Flex.stories-Cfx4TAqp.js} +1 -1
- package/storybook-static/assets/{FloatingPopover-Dch6_6e0.js → FloatingPopover-B8zZ8eYf.js} +1 -1
- package/storybook-static/assets/FloatingPopover-Di16BZj-.css +1 -0
- package/storybook-static/assets/FormattedTableCell-BzBZlmxd.js +15 -0
- package/storybook-static/assets/FormattedTableCell-CTIL_ueu.css +1 -0
- package/storybook-static/assets/{Grid-CcyaioK_.js → Grid-3MdRiyY4.js} +1 -1
- package/storybook-static/assets/{Grid.stories-CTHcYkKa.js → Grid.stories-DUfosHcu.js} +1 -1
- package/storybook-static/assets/{ImageCropper.stories-B84lQIPy.js → ImageCropper.stories-DBLj9S4C.js} +1 -1
- package/storybook-static/assets/{ImageRenderer-kTsPC-b5.js → ImageRenderer-bZHWE6lq.js} +1 -1
- package/storybook-static/assets/{ImageRenderer.stories-pozsCEPL.js → ImageRenderer.stories-BU2tt9QR.js} +1 -1
- package/storybook-static/assets/{ImageView.stories-CNttofCE.js → ImageView.stories-t_ree_kB.js} +1 -1
- package/storybook-static/assets/{ImageViewer.stories-D_7oQpyX.js → ImageViewer.stories-kodL93QT.js} +2 -2
- package/storybook-static/assets/{ImageViewerRuntime-Dnc70fBS.js → ImageViewerRuntime-Dkw7fwZ1.js} +1 -1
- package/storybook-static/assets/ImageViewerRuntime-MxAd4mC-.css +1 -0
- package/storybook-static/assets/{Input-DvRmrrtj.js → Input-C-Q_V0Uc.js} +1 -1
- package/storybook-static/assets/{Input-CYgnggvb.css → Input-CIA3PkB4.css} +1 -1
- package/storybook-static/assets/{Input-BO9q-b1i.js → Input-Ckb0G4jj.js} +1 -1
- package/storybook-static/assets/{Input.stories-DeKdGxIC.js → Input.stories-BZITY0Np.js} +1 -1
- package/storybook-static/assets/{InputDateTime-hqRtizlN.js → InputDateTime-DF-R-IPb.js} +1 -1
- package/storybook-static/assets/{InputDateTime.stories-BpGhWbRp.js → InputDateTime.stories-2ELFc29n.js} +1 -1
- package/storybook-static/assets/{InputFile-CExDbGYJ.js → InputFile-3Sn8IwRI.js} +1 -1
- package/storybook-static/assets/{InputFile-CTDHdo2g.js → InputFile-Xo-rxvud.js} +1 -1
- package/storybook-static/assets/{InputFile.stories-BIinoG-U.js → InputFile.stories-B4EHuTtj.js} +1 -1
- package/storybook-static/assets/{InputFiles-Cvdn_5IV.js → InputFiles-CRFuoEBd.js} +1 -1
- package/storybook-static/assets/{InputFiles-BWeRuTCh.js → InputFiles-DzdnkOiD.js} +1 -1
- package/storybook-static/assets/{InputFiles.stories-J2bb48sN.js → InputFiles.stories-BRCSXgg-.js} +1 -1
- package/storybook-static/assets/{InputFilesList-ByK52qUe.css → InputFilesList-BbwB0oHE.css} +1 -1
- package/storybook-static/assets/{InputFilesList-DO6IJW98.js → InputFilesList-CvL4pjsZ.js} +1 -1
- package/storybook-static/assets/{InputImage-C7zaIkCa.js → InputImage-B1v_PWfN.js} +1 -1
- package/storybook-static/assets/{InputImage-BtsIbqEc.js → InputImage-qAzSyHzj.js} +1 -1
- package/storybook-static/assets/{InputImage.stories--ewdBKin.js → InputImage.stories-4NLpODaa.js} +1 -1
- package/storybook-static/assets/{InteractiveComponents-Cy9Y2J_q.js → InteractiveComponents-Bdy-KTOF.js} +1 -1
- package/storybook-static/assets/{InteractiveComponents.stories-CgC4nhd3.js → InteractiveComponents.stories-C_ZAVn0R.js} +1 -1
- package/storybook-static/assets/{LayoutPicker-CfgWKTDC.js → LayoutPicker-8wwVLPom.js} +1 -1
- package/storybook-static/assets/{LayoutPicker-DhJgMxdf.js → LayoutPicker-B4eblsaF.js} +1 -1
- package/storybook-static/assets/{LayoutPicker-BY4-fUQa.css → LayoutPicker-DaPDA0_s.css} +1 -1
- package/storybook-static/assets/{LayoutPicker.stories-Bli7rQRh.js → LayoutPicker.stories-BkA-VmHP.js} +1 -1
- package/storybook-static/assets/{Listbox-bq5sSQnZ.js → Listbox-ChaW3JrO.js} +1 -1
- package/storybook-static/assets/{Listbox-_MNXWNW7.js → Listbox-CyH7MftX.js} +1 -1
- package/storybook-static/assets/{Listbox.stories-BP9mqHoo.js → Listbox.stories-_31FVhoW.js} +1 -1
- package/storybook-static/assets/{Modal-CNt7-iWI.js → Modal-CaGOliEb.js} +1 -1
- package/storybook-static/assets/{Modal-Dwqp7agw.js → Modal-DGR9lZ4E.js} +1 -1
- package/storybook-static/assets/{Modal.stories-D2Hj75pl.js → Modal.stories-C1yvEVNj.js} +1 -1
- package/storybook-static/assets/{ModalManagerProvider-BoCpnUex.js → ModalManagerProvider-BrPY3nRM.js} +1 -1
- package/storybook-static/assets/{MultiSelect-B1BckUGX.js → MultiSelect-D-O71OBm.js} +1 -1
- package/storybook-static/assets/{MultiSelect-CTfbXQVD.js → MultiSelect-D4S4B3va.js} +1 -1
- package/storybook-static/assets/{MultiSelect.stories-BdMJk22c.js → MultiSelect.stories-B0QY0_Ru.js} +1 -1
- package/storybook-static/assets/{NoData-CNK8-UBc.js → NoData-B6xgAMXh.js} +1 -1
- package/storybook-static/assets/NotificationsHost-BIyd1XQ0.css +1 -0
- package/storybook-static/assets/{NotificationsHost-Cczj_pFY.js → NotificationsHost-DJ3Y-Bov.js} +1 -1
- package/storybook-static/assets/{NotificationsHost.stories-BPB6hfSI.js → NotificationsHost.stories-B2ULIi8d.js} +1 -1
- package/storybook-static/assets/{ODataMultiSelect-CahWMsCQ.js → ODataMultiSelect-0SfdyLn9.js} +1 -1
- package/storybook-static/assets/{ODataMultiSelect.stories-Dnyu2-gz.js → ODataMultiSelect.stories-BLq2Lzuq.js} +1 -1
- package/storybook-static/assets/{ODataSelect-DxbjbdNx.js → ODataSelect-CkdBSdJ6.js} +1 -1
- package/storybook-static/assets/{ODataSelect.stories-DfK9yHK7.js → ODataSelect.stories-OLMZHd_q.js} +1 -1
- package/storybook-static/assets/{ODataTreeMultiSelect-DOgHyKon.js → ODataTreeMultiSelect-DMLCMhQn.js} +1 -1
- package/storybook-static/assets/{ODataTreeMultiSelect.stories-Dv0-ackb.js → ODataTreeMultiSelect.stories-aY5Q0IHe.js} +1 -1
- package/storybook-static/assets/{ODataTreeSelect-DIoygv27.js → ODataTreeSelect-ME1K7NL2.js} +1 -1
- package/storybook-static/assets/{ODataTreeSelect.stories-D4mZcW9Z.js → ODataTreeSelect.stories-C7UPHKEr.js} +1 -1
- package/storybook-static/assets/{OneStepScroller-DNTilSDM.js → OneStepScroller-RRsghqzx.js} +1 -1
- package/storybook-static/assets/{Option-qcKM13Ly.js → Option-CcZ3aKLZ.js} +1 -1
- package/storybook-static/assets/Option-DD2t6DLq.css +1 -0
- package/storybook-static/assets/{OptionButton-DrNo-DMV.js → OptionButton-B-RTb3Ua.js} +1 -1
- package/storybook-static/assets/{PeriodSelect-Dk-_iKeR.js → PeriodSelect-B-89h-o8.js} +1 -1
- package/storybook-static/assets/{PeriodSelect-DjzmUohy.js → PeriodSelect-CUUixF0M.js} +1 -1
- package/storybook-static/assets/{PeriodSelect.stories-d58Lz3DJ.js → PeriodSelect.stories-CU1V-pP4.js} +1 -1
- package/storybook-static/assets/{PickerField-Dv1S8Wit.js → PickerField-DykK8Xgu.js} +1 -1
- package/storybook-static/assets/{PickerTriggerActions-dbXPGPRy.js → PickerTriggerActions-C2qYXlH1.js} +1 -1
- package/storybook-static/assets/{Popover-tPH8grZD.js → Popover-Bg-XuklM.js} +1 -1
- package/storybook-static/assets/{Popover-DMrefrsO.js → Popover-D_MNKdnD.js} +1 -1
- package/storybook-static/assets/{Popover.stories-BGgMddUi.js → Popover.stories-D2Asjc6d.js} +1 -1
- package/storybook-static/assets/{PresetRangeDateInput-Bi01AT1-.js → PresetRangeDateInput-B1KqD3aB.js} +1 -1
- package/storybook-static/assets/{PresetRangeDateInput-Bi5D7AvA.js → PresetRangeDateInput-CYXkpgts.js} +1 -1
- package/storybook-static/assets/{PresetRangeDateInput.stories-BK9PG5Us.js → PresetRangeDateInput.stories-CTML1dIg.js} +1 -1
- package/storybook-static/assets/{PresetSelect-Bo_urWXj.js → PresetSelect-4PvR0s4U.js} +1 -1
- package/storybook-static/assets/{README-CsYvQc-H.js → README--I7LDhOP.js} +1 -1
- package/storybook-static/assets/{README-DQzhOQJs.js → README-1Ks0ldtQ.js} +1 -1
- package/storybook-static/assets/{README-BCXhBI3h.js → README-44qHXI_X.js} +1 -1
- package/storybook-static/assets/{README-oTjX8jJr.js → README-B3Q9ZlQz.js} +1 -1
- package/storybook-static/assets/{README-C1EYYUCN.js → README-B5MLKvrO.js} +1 -1
- package/storybook-static/assets/{README-CvomZuv4.js → README-B5vVbHbw.js} +1 -1
- package/storybook-static/assets/{README-CiRdh2G1.js → README-BJsszjH8.js} +1 -1
- package/storybook-static/assets/{README-CAYUX5Nb.js → README-BK-2_7T4.js} +1 -1
- package/storybook-static/assets/{README-qyGL-RQj.js → README-BKGcgtnD.js} +1 -1
- package/storybook-static/assets/{README-DJeVd42x.js → README-BNUdkNxv.js} +1 -1
- package/storybook-static/assets/{README-CUw7AGFv.js → README-BSSrY3Ri.js} +1 -1
- package/storybook-static/assets/{README-Bccm-jZn.js → README-BVOzG1wf.js} +1 -1
- package/storybook-static/assets/{README-BatM3k6o.js → README-BZbDJrol.js} +1 -1
- package/storybook-static/assets/{README-BrnWLQ7I.js → README-BcReoeGQ.js} +1 -1
- package/storybook-static/assets/{README-C9LAWG5A.js → README-BdgUDdVT.js} +1 -1
- package/storybook-static/assets/{README-DnE0W6xN.js → README-BpSdRy6R.js} +1 -1
- package/storybook-static/assets/{README-CHOXjCGT.js → README-BrduLUi1.js} +1 -1
- package/storybook-static/assets/{README-WDknu02X.js → README-Bt44WdOn.js} +1 -1
- package/storybook-static/assets/{README-DXV0j4Y9.js → README-Bta2DZoW.js} +1 -1
- package/storybook-static/assets/{README-BbwNWG_A.js → README-Bwa8ai1X.js} +1 -1
- package/storybook-static/assets/{README-DRTv3qN5.js → README-C1TqCBPf.js} +1 -1
- package/storybook-static/assets/{README-B2NTIwVC.js → README-C5Cq8Lo7.js} +1 -1
- package/storybook-static/assets/{README-BOY9oCZ5.js → README-CE0sa_3S.js} +1 -1
- package/storybook-static/assets/{README-DENkRq75.js → README-COnopkzM.js} +1 -1
- package/storybook-static/assets/{README-BRxnSb_H.js → README-CUEwtG21.js} +1 -1
- package/storybook-static/assets/{README-DOqinQqt.js → README-CVEiXGCU.js} +1 -1
- package/storybook-static/assets/{README-CSkB_qWo.js → README-CWxf5v2C.js} +1 -1
- package/storybook-static/assets/{README-DNkooR8C.js → README-CjbqfpYX.js} +1 -1
- package/storybook-static/assets/{README-XlmyqVIs.js → README-CnE5ZG98.js} +1 -1
- package/storybook-static/assets/{README-CLfxQA5V.js → README-Co-LXT0Y.js} +1 -1
- package/storybook-static/assets/{README-BPDYLPfh.js → README-CoJlt7mW.js} +1 -1
- package/storybook-static/assets/{README-G5BEMzLO.js → README-DFiFAUAq.js} +1 -1
- package/storybook-static/assets/{README-cmKi-NfO.js → README-DMCaXjMn.js} +1 -1
- package/storybook-static/assets/{README-ChyNimpn.js → README-DecmlELk.js} +3 -3
- package/storybook-static/assets/{README-Bsm0nJfv.js → README-Diow36TX.js} +1 -1
- package/storybook-static/assets/{README-BO0pPMhH.js → README-DlE5gepf.js} +1 -1
- package/storybook-static/assets/{README-DLL_V1qq.js → README-Dl_id19k.js} +1 -1
- package/storybook-static/assets/{README-D7IkoGLE.js → README-DpxWpc-I.js} +1 -1
- package/storybook-static/assets/{README-DI6PuVn_.js → README-Dqpnap9b.js} +1 -1
- package/storybook-static/assets/{README-DSx__uJY.js → README-DrSuJ2Ll.js} +1 -1
- package/storybook-static/assets/{README-CIy0Pj6l.js → README-Dtb7kJXX.js} +1 -1
- package/storybook-static/assets/{README-CgvojwYv.js → README-Ib9AxEso.js} +1 -1
- package/storybook-static/assets/{README-5MsrC0tc.js → README-NCp7adRE.js} +1 -1
- package/storybook-static/assets/{README-CDXBNJlU.js → README-SHZwgJhZ.js} +1 -1
- package/storybook-static/assets/{README-Bzz8tDjY.js → README-VY7CL7vi.js} +1 -1
- package/storybook-static/assets/{README-BIYrg5Jw.js → README-Ve2RJTbZ.js} +1 -1
- package/storybook-static/assets/{README-BTCDTs4l.js → README-bU5ZgdrN.js} +1 -1
- package/storybook-static/assets/{README-DqTSHU_3.js → README-kpAlQZLM.js} +1 -1
- package/storybook-static/assets/{README-iy7SbqPS.js → README-l0W43XHl.js} +1 -1
- package/storybook-static/assets/{README-BxY8B5jC.js → README-tetbJraG.js} +1 -1
- package/storybook-static/assets/{README-DnjCb77l.js → README-vUJFU3Tw.js} +1 -1
- package/storybook-static/assets/{README-lyLRoc9A.js → README-vjP8Z9fC.js} +1 -1
- package/storybook-static/assets/{README-DCitesDJ.js → README-ypHLhhny.js} +1 -1
- package/storybook-static/assets/{RadioButton-C5lYvVIl.js → RadioButton-ByRN6fXm.js} +1 -1
- package/storybook-static/assets/{RadioButton-_-grgF60.js → RadioButton-DRIJvobR.js} +1 -1
- package/storybook-static/assets/{RadioButton.stories-BNifE29D.js → RadioButton.stories-C6lOZsje.js} +1 -1
- package/storybook-static/assets/{RadioGroup-DWfHyBaQ.js → RadioGroup-5P3FMqFW.js} +1 -1
- package/storybook-static/assets/{RadioGroup-BU95Hbl0.css → RadioGroup-DHnDIEgi.css} +1 -1
- package/storybook-static/assets/{RadioGroup-CmDrRqLi.js → RadioGroup-Dskh-JZM.js} +1 -1
- package/storybook-static/assets/{RadioGroup.stories-1PW9Krj9.js → RadioGroup.stories-BDbOjwVa.js} +1 -1
- package/storybook-static/assets/{Scrollable-CWkMU4wH.js → Scrollable-Cat0ixOK.js} +1 -1
- package/storybook-static/assets/{Select-BCGnO525.js → Select-BiIixkSk.js} +1 -1
- package/storybook-static/assets/{Select-DYtEG5uI.js → Select-ImY9WR7I.js} +1 -1
- package/storybook-static/assets/{Select.stories-CgldXYRU.js → Select.stories-DR8qQrXW.js} +1 -1
- package/storybook-static/assets/{SerializableSelect-MmvKHZiv.js → SerializableSelect-C2swvXju.js} +1 -1
- package/storybook-static/assets/{SerializableSelect.stories-Di0iM37P.js → SerializableSelect.stories-CvoyFECC.js} +1 -1
- package/storybook-static/assets/{SingleDateTimeInput-Ds5YsLHg.js → SingleDateTimeInput-CjixqW_K.js} +1 -1
- package/storybook-static/assets/{SingleDateTimeInput-Cz2Y7KEq.js → SingleDateTimeInput-hV5Om2LV.js} +1 -1
- package/storybook-static/assets/{SingleDateTimeInput.stories-BnuERNSZ.js → SingleDateTimeInput.stories-CPDP-M6P.js} +1 -1
- package/storybook-static/assets/Slider-DxdPx1Pb.css +1 -0
- package/storybook-static/assets/{Slider-Csaz4BeY.js → Slider-FbV_mr1Y.js} +1 -1
- package/storybook-static/assets/{Slider-CiZ7R_NX.js → Slider-PcbxPCWE.js} +1 -1
- package/storybook-static/assets/{Slider.stories-7Heg0Pgz.js → Slider.stories-CH9grPep.js} +1 -1
- package/storybook-static/assets/{SliderInput-bTh2JTHG.js → SliderInput-DPYcLCwD.js} +1 -1
- package/storybook-static/assets/{SliderInput-qWpLFzxj.js → SliderInput-iqnLqNiU.js} +1 -1
- package/storybook-static/assets/{SliderInput.stories-DR_zyE-u.js → SliderInput.stories-qVDa0KhJ.js} +1 -1
- package/storybook-static/assets/{Sortable-P86Ancoa.js → Sortable-DzJSN0MG.js} +1 -1
- package/storybook-static/assets/{Sortable.stories-iiOkIM-G.js → Sortable.stories-BaQ2T15L.js} +1 -1
- package/storybook-static/assets/{Splitter-mG3bB-U4.js → Splitter-Ka7c1ZDV.js} +1 -1
- package/storybook-static/assets/{Splitter.stories-WhQOQVRq.js → Splitter.stories-BbjjUT39.js} +1 -1
- package/storybook-static/assets/{StateSelect-De2PQDzp.js → StateSelect-CfyyDUiq.js} +1 -1
- package/storybook-static/assets/{StateSelect-u1kaZwdD.js → StateSelect-DSzDU5Jy.js} +1 -1
- package/storybook-static/assets/{StateSelect.stories-BO-C9UTF.js → StateSelect.stories-0c32Rlr2.js} +1 -1
- package/storybook-static/assets/{StatusIndicator-BiTbPB5o.js → StatusIndicator-CcCdDffH.js} +1 -1
- package/storybook-static/assets/StatusIndicator-CpCGmnO7.css +1 -0
- package/storybook-static/assets/StatusIndicator.stories-Bazi6rxF.js +31 -0
- package/storybook-static/assets/{StringToggle.stories-CBt8bXzz.js → StringToggle.stories-Bl6HAr4o.js} +1 -1
- package/storybook-static/assets/{Switch-BRKFbtp4.js → Switch-BqAkQzIJ.js} +1 -1
- package/storybook-static/assets/{Switch-BC2KYLX2.js → Switch-Vl7s55bO.js} +1 -1
- package/storybook-static/assets/{Switch.stories-BAmX4W8J.js → Switch.stories-Cq2n8Vr4.js} +1 -1
- package/storybook-static/assets/{Table-D1OJnVmO.js → Table-BgxoZKJs.js} +1 -1
- package/storybook-static/assets/Table-j_3ID7Xq.css +1 -0
- package/storybook-static/assets/{Table.stories-C_JSdhJl.js → Table.stories-DxnnXMZX.js} +3 -3
- package/storybook-static/assets/TableEditor-CaZCZgKf.css +1 -0
- package/storybook-static/assets/TableEditor.stories-D5Ke41-O.js +61 -0
- package/storybook-static/assets/{Tabs-DiUKiz-h.js → Tabs-BPJG7wBI.js} +1 -1
- package/storybook-static/assets/{Tabs.stories-DGys1vSD.js → Tabs.stories-cQ4RTo0w.js} +1 -1
- package/storybook-static/assets/{TabsBox-D-bkJX9j.css → TabsBox-B3REnb6D.css} +1 -1
- package/storybook-static/assets/{TabsBox-D4yfPiDY.js → TabsBox-CGgEovb9.js} +1 -1
- package/storybook-static/assets/{TagInput-ZyC-89b3.js → TagInput-CGHC-7Rv.js} +1 -1
- package/storybook-static/assets/{TagInput-ChmW4s9O.css → TagInput-RJbbcfoR.css} +1 -1
- package/storybook-static/assets/{TagInput.stories-hVoLW5qr.js → TagInput.stories-BSy_dJ5n.js} +1 -1
- package/storybook-static/assets/{Text-CMJA_7QZ.js → Text-D5fn4NbN.js} +1 -1
- package/storybook-static/assets/{Textarea-Du012ObX.js → Textarea-CbWAz4J8.js} +1 -1
- package/storybook-static/assets/{Textarea-DjKw5r4e.js → Textarea-pXxz-925.js} +1 -1
- package/storybook-static/assets/{Textarea.stories-ShFda4o7.js → Textarea.stories-BkPejDdf.js} +1 -1
- package/storybook-static/assets/{TimePanel-Bfkpbjrx.js → TimePanel-BJulRHL2.js} +1 -1
- package/storybook-static/assets/{TimePanel-Bh98qsCo.css → TimePanel-D9_hb7w4.css} +1 -1
- package/storybook-static/assets/{TimePanel.stories-4pV3fQVB.js → TimePanel.stories-CJmuKdfu.js} +1 -1
- package/storybook-static/assets/{Toggle-CPohFihI.js → Toggle-B2S8eW_z.js} +1 -1
- package/storybook-static/assets/Toggle-ClE8Zovo.css +1 -0
- package/storybook-static/assets/{Toggle-ChC8G1Et.js → Toggle-DjqQBHtJ.js} +1 -1
- package/storybook-static/assets/{Toggle.stories-B3H1M8Ra.js → Toggle.stories-7KRSUGU9.js} +1 -1
- package/storybook-static/assets/{TreeMultiSelect-CbNz09Jk.js → TreeMultiSelect-B7Dd0sH5.js} +1 -1
- package/storybook-static/assets/{TreeMultiSelect-BpuHCHgJ.js → TreeMultiSelect-DfvInPvn.js} +1 -1
- package/storybook-static/assets/{TreeMultiSelect.stories-Cmt05HgT.js → TreeMultiSelect.stories-DrokeiS6.js} +1 -1
- package/storybook-static/assets/{TreePickerBase-DGvBAQiy.js → TreePickerBase-CN9UeNWV.js} +1 -1
- package/storybook-static/assets/{TreePickerBase-B6DED6Hz.css → TreePickerBase-CmFF9pWE.css} +1 -1
- package/storybook-static/assets/{TreeSelect-DvAlRur3.js → TreeSelect-D3s-_McF.js} +1 -1
- package/storybook-static/assets/{TreeSelect-C_GCYsA3.js → TreeSelect-DPX2Q1Sv.js} +1 -1
- package/storybook-static/assets/{TreeSelect.stories-Cch2A2z5.js → TreeSelect.stories-DvUGVU34.js} +1 -1
- package/storybook-static/assets/TreeTable-BvB3kj4h.css +1 -0
- package/storybook-static/assets/{TreeTable-CmVxMvld.js → TreeTable-By3223dp.js} +1 -1
- package/storybook-static/assets/{TreeTable.stories-B46N8o8E.js → TreeTable.stories-DKAKV_e2.js} +2 -2
- package/storybook-static/assets/{array-D-_yMMUK-DYqn1Ozn.js → array-D-_yMMUK-DnJ_b27D.js} +1 -1
- package/storybook-static/assets/{blocks-Bu5I-6jJ.js → blocks-C4R1QC9R.js} +3 -3
- package/storybook-static/assets/{check-BdRTIK6S.js → check-DkXl--jW.js} +1 -1
- package/storybook-static/assets/{chevron-down-EtmpBUf8.js → chevron-down-DnX0I3Pg.js} +1 -1
- package/storybook-static/assets/{chevron-left-CTLa8HIb.js → chevron-left-18ya0d2d.js} +1 -1
- package/storybook-static/assets/{chevron-right-D_c_Cvi0.js → chevron-right-DilGYzJ6.js} +1 -1
- package/storybook-static/assets/{chunk-W22LQPXL-B7ERYz6B.js → chunk-W22LQPXL-WTP7vHyr.js} +1 -1
- package/storybook-static/assets/{circle-alert-Dj1kZNNX.js → circle-alert-DVNv_dVS.js} +1 -1
- package/storybook-static/assets/{circle-check-B1w7Ls8y.js → circle-check-vIdCi5Zq.js} +1 -1
- package/storybook-static/assets/{components-DqRn1i2k.js → components-BtEbmBZQ.js} +3 -3
- package/storybook-static/assets/{contextMenu-ylNgC9hS.js → contextMenu-1dx6rzYN.js} +1 -1
- package/storybook-static/assets/{defaultRenderers-CyUQG_f-.js → defaultRenderers-UxEpV_2H.js} +1 -1
- package/storybook-static/assets/{download-dw_WzNlC.js → download-37V1rEcU.js} +1 -1
- package/storybook-static/assets/{floating-ui.react-C9sdi3nv.js → floating-ui.react-DT-xu5am.js} +1 -1
- package/storybook-static/assets/{formatters-DVE1YVNQ-CMsbb5-m.js → formatters-DVE1YVNQ-YIdRxgw-.js} +1 -1
- package/storybook-static/assets/{foundationApi-BJETphYp.js → foundationApi-FaYaPMaR.js} +1 -1
- package/storybook-static/assets/{foundationLib-DfRlYoD7.js → foundationLib-DLCLUXOF.js} +1 -1
- package/storybook-static/assets/{hooks-B-ZW7F36.js → hooks-BuU9-pEZ.js} +1 -1
- package/storybook-static/assets/{iframe-D0R9pFj7.js → iframe-0M2vpakb.js} +4 -4
- package/storybook-static/assets/iframe-BMXB4CtM.js +1 -0
- package/storybook-static/assets/iframe-BT_jngkf.css +1 -0
- package/storybook-static/assets/{info-B0qzF0Mr.js → info-2PUHH67D.js} +1 -1
- package/storybook-static/assets/odata-DIkxH78d.js +1 -0
- package/storybook-static/assets/odataStoryFixtures-BDQiSxyk.js +25 -0
- package/storybook-static/assets/{react-ClkCNz5L.js → react-CfjIdTfH.js} +1 -1
- package/storybook-static/assets/{refresh-cw-K68D1zRy.js → refresh-cw-CHFG8NIc.js} +1 -1
- package/storybook-static/assets/{settings-2-D0jFfhpt.js → settings-2-CYde2-4U.js} +1 -1
- package/storybook-static/assets/{sortable-fWu4d9fl.js → sortable-Cy9ZqA3f.js} +1 -1
- package/storybook-static/assets/{syntaxhighlighter-QEQV7K2Y-Cs3Bxe3I.js → syntaxhighlighter-QEQV7K2Y-C2U-3XXV.js} +1 -1
- package/storybook-static/assets/tableFeatures-Dx3U-F9E.js +1 -0
- package/storybook-static/assets/{trash-2-Bj60L0sq.js → trash-2-7-oMZEr8.js} +1 -1
- package/storybook-static/assets/{triangle-alert-CmzQ-r9i.js → triangle-alert-BSmuthen.js} +1 -1
- package/storybook-static/assets/ui-DSS1yTEO.css +1 -0
- package/storybook-static/assets/ui.module-SH8ehXul.js +1 -0
- package/storybook-static/assets/uiClasses-e9OQfdw2.js +1 -0
- package/storybook-static/assets/{useODataSelectBase-CC4MnYeK.js → useODataSelectBase-C3B3Xw87.js} +1 -1
- package/storybook-static/assets/{useODataTreeData-DsQmGQij.js → useODataTreeData-deUW5mSv.js} +1 -1
- package/storybook-static/assets/{usePickerDefaultFilter-BMBLqfz8.js → usePickerDefaultFilter-ien2ZY7g.js} +1 -1
- package/storybook-static/assets/{usePickerQuery-Qg7qGfmP.js → usePickerQuery-DdE3I7AV.js} +1 -1
- package/storybook-static/assets/{usePickerTriggerController-D-mhhmpS.js → usePickerTriggerController-ZRvj4FHy.js} +1 -1
- package/storybook-static/assets/useTable-CK68Q4S4.js +1 -0
- package/storybook-static/assets/{x-DU3Tpzms.js → x-NXcyLtyX.js} +1 -1
- package/storybook-static/iframe.html +3 -3
- package/storybook-static/index.json +1 -1
- package/storybook-static/project.json +1 -1
- package/dist/chunks/CalendarView-Bhaov_XE.js.map +0 -1
- package/dist/chunks/TextEditorLexicalClient-CSXZQOYo.js.map +0 -1
- package/dist/chunks/badge-DUI2ET6q.js.map +0 -1
- package/dist/chunks/context-menu-Dj6MXgv6.js.map +0 -1
- package/dist/chunks/input-D1jOxm0t.js.map +0 -1
- package/dist/chunks/input-files-CDGpJaUm.js.map +0 -1
- package/dist/chunks/picker-DZ4-1BvK.js.map +0 -1
- package/dist/chunks/radio-group-DhpP7JSJ.js.map +0 -1
- package/dist/chunks/table-DMLFUBlb.js.map +0 -1
- package/dist/chunks/ui.module-BsDio9A3.js.map +0 -1
- package/dist/chunks/uiClasses-BVwFzzsr.js.map +0 -1
- package/dist/dialog/index.js.map +0 -1
- package/storybook-static/assets/Button.stories-CLMnxj3w.js +0 -93
- package/storybook-static/assets/CalendarView-DKvrkS40.css +0 -1
- package/storybook-static/assets/ContextMenu-CFPrlO2u.css +0 -1
- package/storybook-static/assets/DisclosureGroup-CVFMwx22.css +0 -1
- package/storybook-static/assets/FloatingPopover-jwILx9b0.css +0 -1
- package/storybook-static/assets/FormattedTableCell-AZc2IHfK.css +0 -1
- package/storybook-static/assets/FormattedTableCell-CXyG4Yj2.js +0 -15
- package/storybook-static/assets/ImageViewerRuntime-CRmlrtpL.css +0 -1
- package/storybook-static/assets/NotificationsHost-D5Pvn4eu.css +0 -1
- package/storybook-static/assets/Option-DXh7BISz.css +0 -1
- package/storybook-static/assets/Slider-CK-W2ZTO.css +0 -1
- package/storybook-static/assets/StatusIndicator-CU9ICMrC.css +0 -1
- package/storybook-static/assets/StatusIndicator.stories-COaZnrFa.js +0 -31
- package/storybook-static/assets/Table-BGvRn9y0.css +0 -1
- package/storybook-static/assets/Toggle-fKG2dFY0.css +0 -1
- package/storybook-static/assets/TreeTable--ZoksUiw.css +0 -1
- package/storybook-static/assets/iframe-COgZ5GwG.js +0 -1
- package/storybook-static/assets/iframe-IhWQT6NX.css +0 -1
- package/storybook-static/assets/odata-tqjAk19x.js +0 -1
- package/storybook-static/assets/odataStoryFixtures-D2yHs_jK.js +0 -25
- package/storybook-static/assets/ui-C3BskXT9.css +0 -1
- package/storybook-static/assets/ui.module-31LPbZGK.js +0 -1
- package/storybook-static/assets/uiClasses-Bz6cvlDQ.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select-B7cWlJxL.js","names":[],"sources":["../../src/select/lib/getOptionSearchText.ts","../../src/select/model/useODataSelect.ts","../../src/select/lib/createSelectOptionSections.ts","../../src/select/Select.tsx","../../src/select/SelectOptionContent.tsx","../../src/select/ODataSelect.tsx","../../src/select/ODataDependentSegmentSelect.tsx","../../src/select/SerializableSelect.tsx"],"sourcesContent":["import { ReactNode } from \"react\";\n\nimport { InputType } from \"@ryuzaki13/react-foundation-lib/types\";\n\nimport { extractPickerTextContent } from \"../../picker\";\nimport { type SelectOptionGroup } from \"../SelectOptionGroup\";\n\nexport function getOptionSearchText<T extends InputType>({\n\toption,\n\tgetOptionLabel,\n\tgetOptionCode,\n\tgetOptionGroup\n}: {\n\toption: T;\n\tgetOptionLabel: (option: T) => ReactNode;\n\tgetOptionCode?: (option: T) => ReactNode;\n\tgetOptionGroup?: (option: T) => SelectOptionGroup | undefined;\n}) {\n\treturn [\n\t\textractPickerTextContent(getOptionLabel(option)),\n\t\textractPickerTextContent(getOptionCode?.(option)),\n\t\textractPickerTextContent(getOptionGroup?.(option)?.label)\n\t]\n\t\t.filter((part): part is string => Boolean(part))\n\t\t.join(\" \")\n\t\t.toLowerCase();\n}\n\n/** Находит selected option по value и возвращает fallback, если значение еще не нормализовано. */\nexport function resolveSelectedOption<TOption extends { value: string }>(\n\toptions: readonly TOption[],\n\tvalue: string,\n\tfallback: TOption\n): TOption {\n\treturn options.find((option) => option.value === value) ?? fallback;\n}\n","import { useMemo } from \"react\";\n\nimport { ODataCollectionModel, ODataSingleSelectProps } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { CollectionItem } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\nimport { useODataSelectBase } from \"./useODataSelectBase\";\n\ninterface UseODataSelectOptions extends Omit<ODataSingleSelectProps, \"model\"> {\n\tmodel: Required<ODataCollectionModel>;\n\tonChange: (value: string | undefined) => void;\n}\n\nexport function useODataSelect({ odata, segment, model, value, dependencies, onChange }: UseODataSelectOptions) {\n\tconst odataModel = useODataSelectBase({\n\t\todata,\n\t\tsegment,\n\t\tmodel,\n\t\tvalue: value ? [value] : [],\n\t\tdependencies\n\t});\n\n\tconst selectedItem = odataModel.selectedItems[0];\n\tconst options = useMemo(() => {\n\t\tif (!selectedItem) {\n\t\t\treturn odataModel.filteredItems;\n\t\t}\n\n\t\treturn [selectedItem, ...odataModel.filteredItems];\n\t}, [odataModel.filteredItems, selectedItem]);\n\n\tconst handleChange = (item: CollectionItem | undefined) => {\n\t\tonChange(item?.[odataModel.selectionKey]);\n\t};\n\n\treturn {\n\t\t...odataModel,\n\t\tselectedItem,\n\t\toptions,\n\t\thandleChange\n\t};\n}\n","import { type SelectOptionGroup } from \"../SelectOptionGroup\";\n\nexport type SelectOptionSectionItem<TOption> = {\n\treadonly option: TOption;\n\treadonly index: number;\n};\n\nexport type SelectOptionSection<TOption> = {\n\treadonly group: SelectOptionGroup | undefined;\n\treadonly items: readonly SelectOptionSectionItem<TOption>[];\n};\n\n/**\n * Собирает соседние опции с одинаковым group key в секции, сохраняя исходные индексы для клавиатурной навигации listbox.\n */\nexport function createSelectOptionSections<TOption>(\n\toptions: readonly TOption[],\n\tgetOptionGroup: (option: TOption) => SelectOptionGroup | undefined\n): readonly SelectOptionSection<TOption>[] {\n\tconst sections: Array<{ group: SelectOptionGroup | undefined; items: SelectOptionSectionItem<TOption>[] }> = [];\n\n\toptions.forEach((option, index) => {\n\t\tconst group = getOptionGroup(option);\n\t\tconst currentSection = sections.at(-1);\n\t\tconst belongsToCurrentSection = currentSection?.group?.key === group?.key;\n\n\t\tif (currentSection && belongsToCurrentSection) {\n\t\t\tcurrentSection.items.push({ option, index });\n\t\t\treturn;\n\t\t}\n\n\t\tsections.push({\n\t\t\tgroup,\n\t\t\titems: [{ option, index }]\n\t\t});\n\t});\n\n\treturn sections;\n}\n","import { type CSSProperties, Fragment, ReactNode, useCallback, useMemo, useRef, useState } from \"react\";\n\nimport { Placement } from \"@floating-ui/react\";\nimport { InputType } from \"@ryuzaki13/react-foundation-lib/types\";\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { CheckIcon } from \"lucide-react\";\n\nimport { CustomOptionButton, Option, OptionButton } from \"../option\";\nimport {\n\textractPickerTextContent,\n\tPickerField,\n\tPickerPopup,\n\tPickerStatus,\n\tPickerTrigger,\n\tusePickerDefaultFilter,\n\tusePickerFloatingListbox,\n\tusePickerQuery,\n\tusePickerTriggerController\n} from \"../picker\";\nimport { ChangeHandler, UiBaseProps } from \"../types\";\nimport uiStyles from \"../ui.module.scss\";\n\nimport { getOptionSearchText } from \"./lib\";\nimport { createSelectOptionSections } from \"./lib/createSelectOptionSections\";\nimport { type SelectOptionGroup, type SelectOptionKey } from \"./SelectOptionGroup\";\n\nexport { type SelectOptionGroup, type SelectOptionKey } from \"./SelectOptionGroup\";\n\nexport type SelectOptionState = {\n\tactive: boolean;\n\tselected: boolean;\n\tdisabled: boolean;\n};\n\ntype SelectSharedProps<TOption extends InputType> = Omit<UiBaseProps<TOption, TOption | undefined>, \"onChange\"> & {\n\toptions: readonly TOption[];\n\tgetOptionKey: (option: TOption) => SelectOptionKey;\n\tgetOptionLabel: (option: TOption) => string;\n\tgetOptionCode?: (option: TOption) => string;\n\t/** Явный поисковый текст для опции с произвольным ReactNode-render. */\n\tgetOptionSearchText?: (option: TOption) => string | readonly string[];\n\tgetOptionDisabled?: (option: TOption) => boolean;\n\tgetOptionAriaLabel?: (option: TOption) => string;\n\tgetOptionGroup?: (option: TOption) => SelectOptionGroup | undefined;\n\tgetOptionClassName?: (option: TOption, state: SelectOptionState) => string | undefined;\n\trenderOption?: (option: TOption, state: SelectOptionState) => ReactNode;\n\trenderValue?: (option: TOption) => ReactNode;\n\tclassName?: string;\n\tbuttonClassName?: string;\n\toptionsClassName?: string;\n\toptionsMaxWidth?: CSSProperties[\"maxWidth\"];\n\toptionsContentClassName?: string;\n\tsearchable?: boolean;\n\tquery?: string;\n\tdefaultQuery?: string;\n\tonQuery?: (value: string) => void;\n\tdefaultFilter?: boolean;\n\tisLoading?: boolean;\n\trenderPopupHeader?: ReactNode;\n\temptyState?: ReactNode;\n\terrorState?: ReactNode;\n\tplacement?: Placement;\n};\n\ntype SelectChangeValue<TOption extends InputType, TClearable extends boolean | undefined> = true extends TClearable\n\t? TOption | undefined\n\t: TOption;\n\nexport type SelectProps<TOption extends InputType, TClearable extends boolean | undefined = false> = SelectSharedProps<TOption> & {\n\tclearable?: TClearable;\n\tonChange: ChangeHandler<SelectChangeValue<TOption, TClearable>>;\n};\n\n/**\n * Выпадающий список выбора значения из набора опций. Подходит для форм, фильтров и простых справочников.\n */\nexport function Select<TOption extends InputType, TClearable extends boolean | undefined = false>(props: SelectProps<TOption, TClearable>) {\n\tconst {\n\t\tlabel,\n\t\tdescription,\n\t\tdisabled,\n\t\tplaceholder,\n\t\tsize,\n\t\toptions,\n\t\tvalue,\n\t\tonChange,\n\t\tgetOptionKey,\n\t\tgetOptionLabel,\n\t\tgetOptionCode,\n\t\tgetOptionSearchText: getExplicitOptionSearchText,\n\t\tgetOptionDisabled,\n\t\tgetOptionAriaLabel,\n\t\tgetOptionGroup,\n\t\tgetOptionClassName,\n\t\trenderOption,\n\t\trenderValue,\n\t\tclassName,\n\t\tbuttonClassName,\n\t\toptionsClassName,\n\t\toptionsMaxWidth,\n\t\toptionsContentClassName,\n\t\tsearchable = false,\n\t\tdefaultFilter = true,\n\t\tquery,\n\t\tdefaultQuery,\n\t\tonQuery,\n\t\trenderPopupHeader,\n\t\temptyState,\n\t\tisLoading,\n\t\terrorState,\n\t\tplacement = \"bottom-start\",\n\t\tclearable = false\n\t} = props;\n\tconst emitChange = onChange as ChangeHandler<TOption | undefined>;\n\n\tconst inputRef = useRef<HTMLInputElement | null>(null);\n\tconst [open, setOpen] = useState(false);\n\tconst triggerMode = searchable ? \"search-single\" : \"display\";\n\tconst selectedKey = value === undefined ? undefined : getOptionKey(value);\n\tconst selectedOption =\n\t\tselectedKey === undefined ? undefined : (options.find((option) => getOptionKey(option) === selectedKey) ?? value);\n\tconst {\n\t\tquery: currentQuery,\n\t\tsetQuery,\n\t\tresetQueryOnClose\n\t} = usePickerQuery({\n\t\tquery,\n\t\tdefaultQuery,\n\t\tonQuery,\n\t\ttriggerMode\n\t});\n\tconst handleOpenChange = (nextOpen: boolean) => {\n\t\tif (open && !nextOpen && resetQueryOnClose) {\n\t\t\tsetQuery(\"\");\n\t\t}\n\n\t\tsetOpen(nextOpen);\n\t};\n\tconst getSearchText = useCallback(\n\t\t(option: TOption) =>\n\t\t\tgetExplicitOptionSearchText?.(option) ??\n\t\t\tgetOptionSearchText({\n\t\t\t\toption,\n\t\t\t\tgetOptionLabel,\n\t\t\t\tgetOptionCode,\n\t\t\t\tgetOptionGroup\n\t\t\t}),\n\t\t[getExplicitOptionSearchText, getOptionCode, getOptionGroup, getOptionLabel]\n\t);\n\tconst visibleOptions = usePickerDefaultFilter({\n\t\toptions,\n\t\tquery: currentQuery,\n\t\tenabled: searchable && defaultFilter,\n\t\tgetSearchText\n\t});\n\tconst optionSections = useMemo(\n\t\t() => (getOptionGroup ? createSelectOptionSections(visibleOptions, getOptionGroup) : undefined),\n\t\t[getOptionGroup, visibleOptions]\n\t);\n\tconst selectedIndex = selectedKey === undefined ? -1 : visibleOptions.findIndex((option) => getOptionKey(option) === selectedKey);\n\tconst {\n\t\tactiveIndex,\n\t\tcontext,\n\t\tfloatingStyles,\n\t\tgetFloatingProps,\n\t\tsetReference,\n\t\tsetFloating,\n\t\tsetOptionRef,\n\t\tclose,\n\t\topenList,\n\t\ttoggleOpen,\n\t\tselectOption,\n\t\tselectActiveOption,\n\t\thandleReferenceKeyDown,\n\t\thandleFloatingKeyDown,\n\t\tgetOptionId,\n\t\tgetActiveOptionId\n\t} = usePickerFloatingListbox({\n\t\toptions: visibleOptions,\n\t\tselectedIndex,\n\t\topen,\n\t\tonOpenChange: handleOpenChange,\n\t\tgetOptionDisabled,\n\t\tonSelect: emitChange,\n\t\tdisabled,\n\t\tplacement,\n\t\ttriggerMode\n\t});\n\n\tconst hasOptions = visibleOptions.length > 0;\n\tconst labelContent = selectedOption !== undefined ? getOptionLabel(selectedOption) : undefined;\n\tconst displayContent = selectedOption !== undefined ? (renderValue ? renderValue(selectedOption) : labelContent) : undefined;\n\tconst labelText = extractPickerTextContent(labelContent);\n\tconst codeText = selectedOption !== undefined ? extractPickerTextContent(getOptionCode?.(selectedOption)) : undefined;\n\tconst displayText =\n\t\textractPickerTextContent(displayContent) ?? labelText ?? codeText ?? (selectedKey !== undefined ? String(selectedKey) : \"\");\n\tconst showSearchValue = searchable && (open || currentQuery.length > 0);\n\tconst inputValue = showSearchValue ? currentQuery : selectedOption !== undefined ? displayText : \"\";\n\tconst triggerController = usePickerTriggerController({\n\t\tmode: triggerMode,\n\t\topen,\n\t\tcurrentQuery,\n\t\thasDisplayValue: selectedOption !== undefined,\n\t\tinputRef,\n\t\tsetQuery,\n\t\topenList,\n\t\tclose,\n\t\ttoggleOpen\n\t});\n\tconst setInputNode = (node: HTMLInputElement | null) => {\n\t\tinputRef.current = node;\n\t};\n\tconst handleClear = () => {\n\t\tif (clearable) {\n\t\t\temitChange(undefined);\n\t\t}\n\n\t\tsetQuery(\"\");\n\t\tclose();\n\t};\n\tconst renderOptionNode = (listId: string, option: TOption, index: number) => {\n\t\tconst optionKey = getOptionKey(option);\n\t\tconst selected = selectedKey !== undefined && optionKey === selectedKey;\n\t\tconst active = index === activeIndex;\n\t\tconst optionDisabled = getOptionDisabled?.(option) ?? false;\n\t\tconst optionState = { active, selected, disabled: optionDisabled };\n\n\t\treturn (\n\t\t\t<Option\n\t\t\t\tkey={optionKey}\n\t\t\t\tid={getOptionId(listId, index)}\n\t\t\t\tref={(node) => setOptionRef(index, node)}\n\t\t\t\trole=\"option\"\n\t\t\t\taria-selected={selected}\n\t\t\t\taria-disabled={optionDisabled || undefined}\n\t\t\t\taria-label={getOptionAriaLabel?.(option)}\n\t\t\t\tactive={active}\n\t\t\t\tselected={selected}\n\t\t\t\tdisabled={optionDisabled}\n\t\t\t\tclassName={getOptionClassName?.(option, optionState)}>\n\t\t\t\t{renderOption ? (\n\t\t\t\t\t<CustomOptionButton\n\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\tdisabled={optionDisabled}\n\t\t\t\t\t\tonMouseDown={(event) => event.preventDefault()}\n\t\t\t\t\t\tonClick={() => selectOption(option)}>\n\t\t\t\t\t\t{renderOption(option, optionState)}\n\t\t\t\t\t</CustomOptionButton>\n\t\t\t\t) : (\n\t\t\t\t\t<OptionButton\n\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\tdisabled={optionDisabled}\n\t\t\t\t\t\ticon={selected ? <CheckIcon /> : <span />}\n\t\t\t\t\t\ttext={getOptionLabel(option)}\n\t\t\t\t\t\tcode={getOptionCode?.(option)}\n\t\t\t\t\t\tonMouseDown={(event) => event.preventDefault()}\n\t\t\t\t\t\tonClick={() => selectOption(option)}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</Option>\n\t\t);\n\t};\n\n\treturn (\n\t\t<PickerField label={label} description={description} disabled={disabled} size={size} className={className}>\n\t\t\t{({ controlId, labelId, describedBy }) => {\n\t\t\t\tconst listId = `${controlId}-listbox`;\n\n\t\t\t\treturn (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<PickerTrigger\n\t\t\t\t\t\t\tref={setInputNode}\n\t\t\t\t\t\t\trootRef={setReference}\n\t\t\t\t\t\t\tid={controlId}\n\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\treadOnly={!searchable}\n\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\trole=\"combobox\"\n\t\t\t\t\t\t\tisLoading={isLoading}\n\t\t\t\t\t\t\topen={open}\n\t\t\t\t\t\t\toptionCount={options.length}\n\t\t\t\t\t\t\tlabel={label}\n\t\t\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\t\t\tvalue={inputValue}\n\t\t\t\t\t\t\tselectedValue={displayContent ?? displayText}\n\t\t\t\t\t\t\thasSelection={selectedOption !== undefined}\n\t\t\t\t\t\t\tshowSelectedValue={false /*selectedOption !== undefined && !showSearchValue*/}\n\t\t\t\t\t\t\tclearable={Boolean(clearable)}\n\t\t\t\t\t\t\tonClear={handleClear}\n\t\t\t\t\t\t\tonToggleMouseDown={triggerController.handleToggleMouseDown}\n\t\t\t\t\t\t\tonToggleClick={triggerController.handleToggleClick}\n\t\t\t\t\t\t\taria-labelledby={labelId}\n\t\t\t\t\t\t\taria-describedby={describedBy}\n\t\t\t\t\t\t\taria-haspopup=\"listbox\"\n\t\t\t\t\t\t\taria-expanded={open}\n\t\t\t\t\t\t\taria-controls={open ? listId : undefined}\n\t\t\t\t\t\t\taria-autocomplete={searchable ? \"list\" : \"none\"}\n\t\t\t\t\t\t\taria-activedescendant={open ? getActiveOptionId(listId) : undefined}\n\t\t\t\t\t\t\tinputClassName={cn(buttonClassName, \"textOverflow\")}\n\t\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\t\tif (!searchable) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\ttriggerController.handleTriggerInputChange(event.target.value);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tonClick={triggerController.handleTriggerClick}\n\t\t\t\t\t\t\tonFocus={(event) => {\n\t\t\t\t\t\t\t\ttriggerController.handleTriggerFocus(event.currentTarget);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\t\t\t\thandleReferenceKeyDown(event);\n\n\t\t\t\t\t\t\t\tif (event.defaultPrevented) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\ttriggerController.handleTriggerKeyDown({\n\t\t\t\t\t\t\t\t\tevent,\n\t\t\t\t\t\t\t\t\tonActivateWhenOpen: selectActiveOption,\n\t\t\t\t\t\t\t\t\tenableSpaceActivation: !searchable\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t<PickerPopup\n\t\t\t\t\t\t\topen={open}\n\t\t\t\t\t\t\tcontext={context}\n\t\t\t\t\t\t\tfloatingStyles={floatingStyles}\n\t\t\t\t\t\t\tlistId={listId}\n\t\t\t\t\t\t\tlabelId={labelId}\n\t\t\t\t\t\t\tdescriptionId={describedBy}\n\t\t\t\t\t\t\tactiveOptionId={hasOptions ? getActiveOptionId(listId) : undefined}\n\t\t\t\t\t\t\tsetFloating={setFloating}\n\t\t\t\t\t\t\tgetFloatingProps={getFloatingProps}\n\t\t\t\t\t\t\tonKeyDown={handleFloatingKeyDown}\n\t\t\t\t\t\t\tclassName={optionsClassName}\n\t\t\t\t\t\t\tmaxWidth={optionsMaxWidth}\n\t\t\t\t\t\t\ttoolbar={renderPopupHeader}>\n\t\t\t\t\t\t\t<div className={cn(optionsContentClassName, \"h100 scrollable overscroll\")}>\n\t\t\t\t\t\t\t\t{hasOptions ? (\n\t\t\t\t\t\t\t\t\toptionSections ? (\n\t\t\t\t\t\t\t\t\t\toptionSections.map((section, sectionIndex) => {\n\t\t\t\t\t\t\t\t\t\t\tconst groupLabelId = section.group ? `${listId}-group-${sectionIndex}` : undefined;\n\t\t\t\t\t\t\t\t\t\t\tconst optionNodes = section.items.map(({ option, index }) =>\n\t\t\t\t\t\t\t\t\t\t\t\trenderOptionNode(listId, option, index)\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t\treturn section.group ? (\n\t\t\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\t\t\tkey={`group-${String(section.group.key)}-${sectionIndex}`}\n\t\t\t\t\t\t\t\t\t\t\t\t\trole=\"group\"\n\t\t\t\t\t\t\t\t\t\t\t\t\taria-labelledby={groupLabelId}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div id={groupLabelId} className={uiStyles.uiPopupGroupLabel}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{section.group.label}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{optionNodes}\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t\t<Fragment key={`options-${sectionIndex}`}>{optionNodes}</Fragment>\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\tvisibleOptions.map((option, index) => renderOptionNode(listId, option, index))\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\t\t<PickerStatus emptyState={emptyState} errorState={errorState} />\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</PickerPopup>\n\t\t\t\t\t</>\n\t\t\t\t);\n\t\t\t}}\n\t\t</PickerField>\n\t);\n}\n","import { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { OptionCode, OptionText } from \"../option\";\nimport { HighlightText } from \"../text\";\n\ninterface OptionContentProps {\n\tlabel: string;\n\tcode?: string;\n\thighlight?: string;\n\t/** Приватный визуальный modifier label для специализированного владельца option. */\n\tlabelClassName?: string;\n\t/** Отдельный modifier code, потому что code задаёт собственный variable-font weight. */\n\tcodeClassName?: string;\n}\n\n/**\n * Универсальный рендерер опции. Используется и в single-select, и в multi-select.\n */\nexport function SelectOptionContent({ label, code, highlight, labelClassName, codeClassName }: OptionContentProps) {\n\treturn (\n\t\t<>\n\t\t\t<OptionText className={cn(\"flexEllipsis\", labelClassName)}>\n\t\t\t\t<HighlightText text={label} highlight={highlight} />\n\t\t\t</OptionText>\n\t\t\t{code && (\n\t\t\t\t<OptionCode className={codeClassName}>\n\t\t\t\t\t<HighlightText text={code} highlight={highlight} />\n\t\t\t\t</OptionCode>\n\t\t\t)}\n\t\t</>\n\t);\n}\n","import React from \"react\";\n\nimport { ODataSingleSelectProps, useODataCollectionModel } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { CollectionItem } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\nimport { InputUILoading } from \"../input\";\nimport { UiBaseProps } from \"../types\";\n\nimport { useODataSelect } from \"./model/useODataSelect\";\nimport { Select } from \"./Select\";\nimport { SelectOptionContent } from \"./SelectOptionContent\";\n\ntype ODataSelectProps = Omit<ODataSingleSelectProps, \"value\"> & UiBaseProps<string | undefined> & { clearable?: boolean };\n\nfunction getODataOptionTextKey(item: CollectionItem | undefined, textKey: string, codeKey: string) {\n\tif (!item) {\n\t\treturn textKey || codeKey;\n\t}\n\n\treturn textKey || Object.keys(item).find((key) => key !== codeKey) || codeKey;\n}\n\nexport const ODataSelect: React.FC<ODataSelectProps> = ({\n\todata,\n\tsegment,\n\tmodel: initialModel,\n\tsize,\n\tlabel,\n\tdescription,\n\tdisabled,\n\tvalue,\n\tdependencies,\n\tonChange,\n\tclearable\n}) => {\n\tconst model = useODataCollectionModel(initialModel);\n\tconst odataModel = useODataSelect({\n\t\todata,\n\t\tsegment,\n\t\tmodel,\n\t\tvalue,\n\t\tdependencies,\n\t\tonChange\n\t});\n\n\tif (odataModel.isLoading) {\n\t\treturn <InputUILoading size={size} label={label} description={description} />;\n\t}\n\n\tconst hideCode = segment.hideCode ?? odata.hideCode;\n\tconst resolvedTextKey = getODataOptionTextKey(odataModel.selectedItem ?? odataModel.options[0], odataModel.textKey, odataModel.codeKey);\n\n\treturn (\n\t\t<Select\n\t\t\tsize={size}\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\toptions={odataModel.options}\n\t\t\tvalue={odataModel.selectedItem}\n\t\t\tonChange={odataModel.handleChange}\n\t\t\tgetOptionKey={(item) => item[odataModel.codeKey]}\n\t\t\tgetOptionLabel={(item) => item[resolvedTextKey]}\n\t\t\tgetOptionCode={hideCode ? undefined : (item) => item[odataModel.codeKey]}\n\t\t\tgetOptionAriaLabel={(item) =>\n\t\t\t\thideCode || item[resolvedTextKey] === item[odataModel.codeKey]\n\t\t\t\t\t? String(item[resolvedTextKey])\n\t\t\t\t\t: `${item[resolvedTextKey]} ${item[odataModel.codeKey]}`\n\t\t\t}\n\t\t\trenderValue={(item) => (\n\t\t\t\t<SelectOptionContent label={item[resolvedTextKey]} code={hideCode ? undefined : item[odataModel.codeKey]} />\n\t\t\t)}\n\t\t\trenderOption={(item) => (\n\t\t\t\t<SelectOptionContent\n\t\t\t\t\tlabel={item[resolvedTextKey]}\n\t\t\t\t\tcode={hideCode ? undefined : item[odataModel.codeKey]}\n\t\t\t\t\thighlight={odataModel.debouncedQuery}\n\t\t\t\t/>\n\t\t\t)}\n\t\t\tsearchable\n\t\t\tquery={odataModel.query}\n\t\t\tonQuery={odataModel.setQuery}\n\t\t\tdefaultFilter={false}\n\t\t\tdisabled={disabled || odataModel.isLoading}\n\t\t\tplaceholder={odataModel.placeholder}\n\t\t\tisLoading={odataModel.isLoading}\n\t\t\terrorState={odataModel.isError ? \"Ошибка загрузки\" : undefined}\n\t\t\temptyState={!odataModel.isLoading && !odataModel.isError ? \"Нет данных\" : undefined}\n\t\t\tclearable={clearable}\n\t\t/>\n\t);\n};\n","import { useCallback } from \"react\";\n\nimport { useODataDependentSelection } from \"../odata-dependent\";\n\nimport { ODataSelect } from \"./ODataSelect\";\n\nimport type { ODataDependentSegmentControlProps } from \"../odata-dependent\";\n\nexport type ODataDependentSegmentSelectProps = ODataDependentSegmentControlProps & {\n\t/** Показывает действие очистки выбранного значения. */\n\tclearable?: boolean;\n};\n\n/**\n * Адаптирует один развёрнутый зависимый OData-сегмент к single-select UI.\n * Общий снимок остаётся массивным, поэтому совместим с `dependencies` и\n * может совместно использоваться с segment-level MultiSelect-контролами.\n */\nexport function ODataDependentSegmentSelect(props: ODataDependentSegmentSelectProps) {\n\tconst { item, disabled, label, description, size, width = 15, clearable } = props;\n\tconst selection = useODataDependentSelection(props);\n\tconst { updateSegment } = selection;\n\tconst widthStyle = `calc(${width}em + var(--width-add))`;\n\n\tconst handleSelectionChange = useCallback(\n\t\t(value: string | undefined) => {\n\t\t\tupdateSegment(item.id, value === undefined ? [] : [value]);\n\t\t},\n\t\t[item.id, updateSegment]\n\t);\n\n\treturn (\n\t\t<div style={{ maxWidth: widthStyle, minWidth: widthStyle }}>\n\t\t\t<ODataSelect\n\t\t\t\todata={item.odata}\n\t\t\t\tsegment={item.segment}\n\t\t\t\tmodel={item.model}\n\t\t\t\tdependencies={selection.values}\n\t\t\t\tvalue={selection.values[item.id]?.[0]}\n\t\t\t\tonChange={handleSelectionChange}\n\t\t\t\tdisabled={disabled || selection.isSegmentDisabled(item.id)}\n\t\t\t\tlabel={label}\n\t\t\t\tdescription={description}\n\t\t\t\tsize={size}\n\t\t\t\tclearable={clearable}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n","import { Select } from \"./Select\";\n\nimport type { UiBaseProps } from \"../types\";\nimport type { SelectOptionKey } from \"./Select\";\n\ntype SerializableOptionRecord = Record<string, unknown>;\n\ntype SerializableOptionKeyField<TOption extends SerializableOptionRecord> = {\n\t[K in keyof TOption]: Extract<TOption[K], SelectOptionKey> extends never ? never : K;\n}[keyof TOption];\n\ntype SerializableOptionValue<TOption extends SerializableOptionRecord, TOptionKey extends SerializableOptionKeyField<TOption>> = Extract<\n\tTOption[TOptionKey],\n\tSelectOptionKey\n>;\n\nexport interface SerializableSelectProps<\n\tTOption extends SerializableOptionRecord,\n\tTOptionKey extends SerializableOptionKeyField<TOption>,\n\tTOptionLabel extends keyof TOption\n> extends Omit<UiBaseProps<SerializableOptionValue<TOption, TOptionKey> | undefined>, \"onChange\"> {\n\toptions: readonly TOption[];\n\tonChange: (value: SerializableOptionValue<TOption, TOptionKey> | undefined) => void;\n\toptionKey: TOptionKey;\n\toptionLabel: TOptionLabel;\n\trenderCode?: true;\n\tclassName?: string;\n\tclearable?: boolean;\n}\n\nfunction getSerializableOptionKey<TOption extends SerializableOptionRecord, TOptionKey extends SerializableOptionKeyField<TOption>>(\n\toption: TOption,\n\toptionKey: TOptionKey\n): Extract<TOption[TOptionKey], SelectOptionKey> {\n\treturn String(option[optionKey]) as Extract<TOption[TOptionKey], SelectOptionKey>;\n}\n\nfunction getSerializableOptionLabel<\n\tTOption extends SerializableOptionRecord,\n\tTOptionKey extends SerializableOptionKeyField<TOption>,\n\tTOptionLabel extends keyof TOption\n>(option: TOption, optionLabel: TOptionLabel, optionKey: TOptionKey): string {\n\tconst label = option[optionLabel];\n\n\tif (typeof label === \"string\" || typeof label === \"number\") {\n\t\treturn String(label);\n\t}\n\n\tconst key = getSerializableOptionKey(option, optionKey);\n\treturn String(key);\n}\n\nexport function SerializableSelect<\n\tTOption extends SerializableOptionRecord,\n\tTOptionKey extends SerializableOptionKeyField<TOption>,\n\tTOptionLabel extends keyof TOption\n>({\n\tlabel,\n\tdescription,\n\tdisabled,\n\tplaceholder,\n\tsize,\n\toptions,\n\tvalue,\n\tonChange,\n\toptionKey,\n\toptionLabel,\n\trenderCode,\n\tclassName,\n\tclearable\n}: SerializableSelectProps<TOption, TOptionKey, TOptionLabel>) {\n\tconst selectedOption =\n\t\tvalue === undefined ? undefined : options.find((option) => getSerializableOptionKey(option, optionKey) === value);\n\n\treturn (\n\t\t<Select\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\tdisabled={disabled}\n\t\t\tplaceholder={placeholder}\n\t\t\tsize={size}\n\t\t\toptions={options}\n\t\t\tvalue={selectedOption}\n\t\t\tonChange={(option: TOption | undefined) => onChange(option ? getSerializableOptionKey(option, optionKey) : undefined)}\n\t\t\tgetOptionKey={(option: TOption) => getSerializableOptionKey(option, optionKey)}\n\t\t\tgetOptionLabel={(option: TOption) => getSerializableOptionLabel(option, optionLabel, optionKey)}\n\t\t\tgetOptionCode={renderCode ? (option: TOption) => getSerializableOptionKey(option, optionKey) : undefined}\n\t\t\tclassName={className}\n\t\t\tclearable={clearable}\n\t\t/>\n\t);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"select-aTGupQan.js","names":[],"sources":["../../src/select/lib/getOptionSearchText.ts","../../src/select/model/useODataSelect.ts","../../src/select/lib/createSelectOptionSections.ts","../../src/select/Select.tsx","../../src/select/SelectOptionContent.tsx","../../src/select/ODataSelect.tsx","../../src/select/ODataDependentSegmentSelect.tsx","../../src/select/SerializableSelect.tsx"],"sourcesContent":["import { ReactNode } from \"react\";\n\nimport { InputType } from \"@ryuzaki13/react-foundation-lib/types\";\n\nimport { extractPickerTextContent } from \"../../picker\";\nimport { type SelectOptionGroup } from \"../SelectOptionGroup\";\n\nexport function getOptionSearchText<T extends InputType>({\n\toption,\n\tgetOptionLabel,\n\tgetOptionCode,\n\tgetOptionGroup\n}: {\n\toption: T;\n\tgetOptionLabel: (option: T) => ReactNode;\n\tgetOptionCode?: (option: T) => ReactNode;\n\tgetOptionGroup?: (option: T) => SelectOptionGroup | undefined;\n}) {\n\treturn [\n\t\textractPickerTextContent(getOptionLabel(option)),\n\t\textractPickerTextContent(getOptionCode?.(option)),\n\t\textractPickerTextContent(getOptionGroup?.(option)?.label)\n\t]\n\t\t.filter((part): part is string => Boolean(part))\n\t\t.join(\" \")\n\t\t.toLowerCase();\n}\n\n/** Находит selected option по value и возвращает fallback, если значение еще не нормализовано. */\nexport function resolveSelectedOption<TOption extends { value: string }>(\n\toptions: readonly TOption[],\n\tvalue: string,\n\tfallback: TOption\n): TOption {\n\treturn options.find((option) => option.value === value) ?? fallback;\n}\n","import { useMemo } from \"react\";\n\nimport { ODataCollectionModel, ODataSingleSelectProps } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { CollectionItem } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\nimport { useODataSelectBase } from \"./useODataSelectBase\";\n\ninterface UseODataSelectOptions extends Omit<ODataSingleSelectProps, \"model\"> {\n\tmodel: Required<ODataCollectionModel>;\n\tonChange: (value: string | undefined) => void;\n}\n\nexport function useODataSelect({ odata, segment, model, value, dependencies, onChange }: UseODataSelectOptions) {\n\tconst odataModel = useODataSelectBase({\n\t\todata,\n\t\tsegment,\n\t\tmodel,\n\t\tvalue: value ? [value] : [],\n\t\tdependencies\n\t});\n\n\tconst selectedItem = odataModel.selectedItems[0];\n\tconst options = useMemo(() => {\n\t\tif (!selectedItem) {\n\t\t\treturn odataModel.filteredItems;\n\t\t}\n\n\t\treturn [selectedItem, ...odataModel.filteredItems];\n\t}, [odataModel.filteredItems, selectedItem]);\n\n\tconst handleChange = (item: CollectionItem | undefined) => {\n\t\tonChange(item?.[odataModel.selectionKey]);\n\t};\n\n\treturn {\n\t\t...odataModel,\n\t\tselectedItem,\n\t\toptions,\n\t\thandleChange\n\t};\n}\n","import { type SelectOptionGroup } from \"../SelectOptionGroup\";\n\nexport type SelectOptionSectionItem<TOption> = {\n\treadonly option: TOption;\n\treadonly index: number;\n};\n\nexport type SelectOptionSection<TOption> = {\n\treadonly group: SelectOptionGroup | undefined;\n\treadonly items: readonly SelectOptionSectionItem<TOption>[];\n};\n\n/**\n * Собирает соседние опции с одинаковым group key в секции, сохраняя исходные индексы для клавиатурной навигации listbox.\n */\nexport function createSelectOptionSections<TOption>(\n\toptions: readonly TOption[],\n\tgetOptionGroup: (option: TOption) => SelectOptionGroup | undefined\n): readonly SelectOptionSection<TOption>[] {\n\tconst sections: Array<{ group: SelectOptionGroup | undefined; items: SelectOptionSectionItem<TOption>[] }> = [];\n\n\toptions.forEach((option, index) => {\n\t\tconst group = getOptionGroup(option);\n\t\tconst currentSection = sections.at(-1);\n\t\tconst belongsToCurrentSection = currentSection?.group?.key === group?.key;\n\n\t\tif (currentSection && belongsToCurrentSection) {\n\t\t\tcurrentSection.items.push({ option, index });\n\t\t\treturn;\n\t\t}\n\n\t\tsections.push({\n\t\t\tgroup,\n\t\t\titems: [{ option, index }]\n\t\t});\n\t});\n\n\treturn sections;\n}\n","import { type CSSProperties, Fragment, ReactNode, useCallback, useMemo, useRef, useState } from \"react\";\n\nimport { Placement } from \"@floating-ui/react\";\nimport { InputType } from \"@ryuzaki13/react-foundation-lib/types\";\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { CheckIcon } from \"lucide-react\";\n\nimport { CustomOptionButton, Option, OptionButton } from \"../option\";\nimport {\n\textractPickerTextContent,\n\tPickerField,\n\tPickerPopup,\n\tPickerStatus,\n\tPickerTrigger,\n\tusePickerDefaultFilter,\n\tusePickerFloatingListbox,\n\tusePickerQuery,\n\tusePickerTriggerController\n} from \"../picker\";\nimport { ChangeHandler, UiBaseProps } from \"../types\";\nimport uiStyles from \"../ui.module.scss\";\n\nimport { getOptionSearchText } from \"./lib\";\nimport { createSelectOptionSections } from \"./lib/createSelectOptionSections\";\nimport { type SelectOptionGroup, type SelectOptionKey } from \"./SelectOptionGroup\";\n\nexport { type SelectOptionGroup, type SelectOptionKey } from \"./SelectOptionGroup\";\n\nexport type SelectOptionState = {\n\tactive: boolean;\n\tselected: boolean;\n\tdisabled: boolean;\n};\n\ntype SelectSharedProps<TOption extends InputType> = Omit<UiBaseProps<TOption, TOption | undefined>, \"onChange\"> & {\n\toptions: readonly TOption[];\n\tgetOptionKey: (option: TOption) => SelectOptionKey;\n\tgetOptionLabel: (option: TOption) => string;\n\tgetOptionCode?: (option: TOption) => string;\n\t/** Явный поисковый текст для опции с произвольным ReactNode-render. */\n\tgetOptionSearchText?: (option: TOption) => string | readonly string[];\n\tgetOptionDisabled?: (option: TOption) => boolean;\n\tgetOptionAriaLabel?: (option: TOption) => string;\n\tgetOptionGroup?: (option: TOption) => SelectOptionGroup | undefined;\n\tgetOptionClassName?: (option: TOption, state: SelectOptionState) => string | undefined;\n\trenderOption?: (option: TOption, state: SelectOptionState) => ReactNode;\n\trenderValue?: (option: TOption) => ReactNode;\n\tclassName?: string;\n\tbuttonClassName?: string;\n\toptionsClassName?: string;\n\toptionsMaxWidth?: CSSProperties[\"maxWidth\"];\n\toptionsContentClassName?: string;\n\tsearchable?: boolean;\n\tquery?: string;\n\tdefaultQuery?: string;\n\tonQuery?: (value: string) => void;\n\tdefaultFilter?: boolean;\n\tisLoading?: boolean;\n\trenderPopupHeader?: ReactNode;\n\temptyState?: ReactNode;\n\terrorState?: ReactNode;\n\tplacement?: Placement;\n};\n\ntype SelectChangeValue<TOption extends InputType, TClearable extends boolean | undefined> = true extends TClearable\n\t? TOption | undefined\n\t: TOption;\n\nexport type SelectProps<TOption extends InputType, TClearable extends boolean | undefined = false> = SelectSharedProps<TOption> & {\n\tclearable?: TClearable;\n\tonChange: ChangeHandler<SelectChangeValue<TOption, TClearable>>;\n};\n\n/**\n * Выпадающий список выбора значения из набора опций. Подходит для форм, фильтров и простых справочников.\n */\nexport function Select<TOption extends InputType, TClearable extends boolean | undefined = false>(props: SelectProps<TOption, TClearable>) {\n\tconst {\n\t\tlabel,\n\t\tdescription,\n\t\tdisabled,\n\t\tplaceholder,\n\t\tsize,\n\t\toptions,\n\t\tvalue,\n\t\tonChange,\n\t\tgetOptionKey,\n\t\tgetOptionLabel,\n\t\tgetOptionCode,\n\t\tgetOptionSearchText: getExplicitOptionSearchText,\n\t\tgetOptionDisabled,\n\t\tgetOptionAriaLabel,\n\t\tgetOptionGroup,\n\t\tgetOptionClassName,\n\t\trenderOption,\n\t\trenderValue,\n\t\tclassName,\n\t\tbuttonClassName,\n\t\toptionsClassName,\n\t\toptionsMaxWidth,\n\t\toptionsContentClassName,\n\t\tsearchable = false,\n\t\tdefaultFilter = true,\n\t\tquery,\n\t\tdefaultQuery,\n\t\tonQuery,\n\t\trenderPopupHeader,\n\t\temptyState,\n\t\tisLoading,\n\t\terrorState,\n\t\tplacement = \"bottom-start\",\n\t\tclearable = false\n\t} = props;\n\tconst emitChange = onChange as ChangeHandler<TOption | undefined>;\n\n\tconst inputRef = useRef<HTMLInputElement | null>(null);\n\tconst [open, setOpen] = useState(false);\n\tconst triggerMode = searchable ? \"search-single\" : \"display\";\n\tconst selectedKey = value === undefined ? undefined : getOptionKey(value);\n\tconst selectedOption =\n\t\tselectedKey === undefined ? undefined : (options.find((option) => getOptionKey(option) === selectedKey) ?? value);\n\tconst {\n\t\tquery: currentQuery,\n\t\tsetQuery,\n\t\tresetQueryOnClose\n\t} = usePickerQuery({\n\t\tquery,\n\t\tdefaultQuery,\n\t\tonQuery,\n\t\ttriggerMode\n\t});\n\tconst handleOpenChange = (nextOpen: boolean) => {\n\t\tif (open && !nextOpen && resetQueryOnClose) {\n\t\t\tsetQuery(\"\");\n\t\t}\n\n\t\tsetOpen(nextOpen);\n\t};\n\tconst getSearchText = useCallback(\n\t\t(option: TOption) =>\n\t\t\tgetExplicitOptionSearchText?.(option) ??\n\t\t\tgetOptionSearchText({\n\t\t\t\toption,\n\t\t\t\tgetOptionLabel,\n\t\t\t\tgetOptionCode,\n\t\t\t\tgetOptionGroup\n\t\t\t}),\n\t\t[getExplicitOptionSearchText, getOptionCode, getOptionGroup, getOptionLabel]\n\t);\n\tconst visibleOptions = usePickerDefaultFilter({\n\t\toptions,\n\t\tquery: currentQuery,\n\t\tenabled: searchable && defaultFilter,\n\t\tgetSearchText\n\t});\n\tconst optionSections = useMemo(\n\t\t() => (getOptionGroup ? createSelectOptionSections(visibleOptions, getOptionGroup) : undefined),\n\t\t[getOptionGroup, visibleOptions]\n\t);\n\tconst selectedIndex = selectedKey === undefined ? -1 : visibleOptions.findIndex((option) => getOptionKey(option) === selectedKey);\n\tconst {\n\t\tactiveIndex,\n\t\tcontext,\n\t\tfloatingStyles,\n\t\tgetFloatingProps,\n\t\tsetReference,\n\t\tsetFloating,\n\t\tsetOptionRef,\n\t\tclose,\n\t\topenList,\n\t\ttoggleOpen,\n\t\tselectOption,\n\t\tselectActiveOption,\n\t\thandleReferenceKeyDown,\n\t\thandleFloatingKeyDown,\n\t\tgetOptionId,\n\t\tgetActiveOptionId\n\t} = usePickerFloatingListbox({\n\t\toptions: visibleOptions,\n\t\tselectedIndex,\n\t\topen,\n\t\tonOpenChange: handleOpenChange,\n\t\tgetOptionDisabled,\n\t\tonSelect: emitChange,\n\t\tdisabled,\n\t\tplacement,\n\t\ttriggerMode\n\t});\n\n\tconst hasOptions = visibleOptions.length > 0;\n\tconst labelContent = selectedOption !== undefined ? getOptionLabel(selectedOption) : undefined;\n\tconst displayContent = selectedOption !== undefined ? (renderValue ? renderValue(selectedOption) : labelContent) : undefined;\n\tconst labelText = extractPickerTextContent(labelContent);\n\tconst codeText = selectedOption !== undefined ? extractPickerTextContent(getOptionCode?.(selectedOption)) : undefined;\n\tconst displayText =\n\t\textractPickerTextContent(displayContent) ?? labelText ?? codeText ?? (selectedKey !== undefined ? String(selectedKey) : \"\");\n\tconst showSearchValue = searchable && (open || currentQuery.length > 0);\n\tconst inputValue = showSearchValue ? currentQuery : selectedOption !== undefined ? displayText : \"\";\n\tconst triggerController = usePickerTriggerController({\n\t\tmode: triggerMode,\n\t\topen,\n\t\tcurrentQuery,\n\t\thasDisplayValue: selectedOption !== undefined,\n\t\tinputRef,\n\t\tsetQuery,\n\t\topenList,\n\t\tclose,\n\t\ttoggleOpen\n\t});\n\tconst setInputNode = (node: HTMLInputElement | null) => {\n\t\tinputRef.current = node;\n\t};\n\tconst handleClear = () => {\n\t\tif (clearable) {\n\t\t\temitChange(undefined);\n\t\t}\n\n\t\tsetQuery(\"\");\n\t\tclose();\n\t};\n\tconst renderOptionNode = (listId: string, option: TOption, index: number) => {\n\t\tconst optionKey = getOptionKey(option);\n\t\tconst selected = selectedKey !== undefined && optionKey === selectedKey;\n\t\tconst active = index === activeIndex;\n\t\tconst optionDisabled = getOptionDisabled?.(option) ?? false;\n\t\tconst optionState = { active, selected, disabled: optionDisabled };\n\n\t\treturn (\n\t\t\t<Option\n\t\t\t\tkey={optionKey}\n\t\t\t\tid={getOptionId(listId, index)}\n\t\t\t\tref={(node) => setOptionRef(index, node)}\n\t\t\t\trole=\"option\"\n\t\t\t\taria-selected={selected}\n\t\t\t\taria-disabled={optionDisabled || undefined}\n\t\t\t\taria-label={getOptionAriaLabel?.(option)}\n\t\t\t\tactive={active}\n\t\t\t\tselected={selected}\n\t\t\t\tdisabled={optionDisabled}\n\t\t\t\tclassName={getOptionClassName?.(option, optionState)}>\n\t\t\t\t{renderOption ? (\n\t\t\t\t\t<CustomOptionButton\n\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\tdisabled={optionDisabled}\n\t\t\t\t\t\tonMouseDown={(event) => event.preventDefault()}\n\t\t\t\t\t\tonClick={() => selectOption(option)}>\n\t\t\t\t\t\t{renderOption(option, optionState)}\n\t\t\t\t\t</CustomOptionButton>\n\t\t\t\t) : (\n\t\t\t\t\t<OptionButton\n\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\tdisabled={optionDisabled}\n\t\t\t\t\t\ticon={selected ? <CheckIcon /> : <span />}\n\t\t\t\t\t\ttext={getOptionLabel(option)}\n\t\t\t\t\t\tcode={getOptionCode?.(option)}\n\t\t\t\t\t\tonMouseDown={(event) => event.preventDefault()}\n\t\t\t\t\t\tonClick={() => selectOption(option)}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</Option>\n\t\t);\n\t};\n\n\treturn (\n\t\t<PickerField label={label} description={description} disabled={disabled} size={size} className={className}>\n\t\t\t{({ controlId, labelId, describedBy }) => {\n\t\t\t\tconst listId = `${controlId}-listbox`;\n\n\t\t\t\treturn (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<PickerTrigger\n\t\t\t\t\t\t\tref={setInputNode}\n\t\t\t\t\t\t\trootRef={setReference}\n\t\t\t\t\t\t\tid={controlId}\n\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\treadOnly={!searchable}\n\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\trole=\"combobox\"\n\t\t\t\t\t\t\tisLoading={isLoading}\n\t\t\t\t\t\t\topen={open}\n\t\t\t\t\t\t\toptionCount={options.length}\n\t\t\t\t\t\t\tlabel={label}\n\t\t\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\t\t\tvalue={inputValue}\n\t\t\t\t\t\t\tselectedValue={displayContent ?? displayText}\n\t\t\t\t\t\t\thasSelection={selectedOption !== undefined}\n\t\t\t\t\t\t\tshowSelectedValue={false /*selectedOption !== undefined && !showSearchValue*/}\n\t\t\t\t\t\t\tclearable={Boolean(clearable)}\n\t\t\t\t\t\t\tonClear={handleClear}\n\t\t\t\t\t\t\tonToggleMouseDown={triggerController.handleToggleMouseDown}\n\t\t\t\t\t\t\tonToggleClick={triggerController.handleToggleClick}\n\t\t\t\t\t\t\taria-labelledby={labelId}\n\t\t\t\t\t\t\taria-describedby={describedBy}\n\t\t\t\t\t\t\taria-haspopup=\"listbox\"\n\t\t\t\t\t\t\taria-expanded={open}\n\t\t\t\t\t\t\taria-controls={open ? listId : undefined}\n\t\t\t\t\t\t\taria-autocomplete={searchable ? \"list\" : \"none\"}\n\t\t\t\t\t\t\taria-activedescendant={open ? getActiveOptionId(listId) : undefined}\n\t\t\t\t\t\t\tinputClassName={cn(buttonClassName, \"textOverflow\")}\n\t\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\t\tif (!searchable) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\ttriggerController.handleTriggerInputChange(event.target.value);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tonClick={triggerController.handleTriggerClick}\n\t\t\t\t\t\t\tonFocus={(event) => {\n\t\t\t\t\t\t\t\ttriggerController.handleTriggerFocus(event.currentTarget);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\t\t\t\thandleReferenceKeyDown(event);\n\n\t\t\t\t\t\t\t\tif (event.defaultPrevented) {\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\ttriggerController.handleTriggerKeyDown({\n\t\t\t\t\t\t\t\t\tevent,\n\t\t\t\t\t\t\t\t\tonActivateWhenOpen: selectActiveOption,\n\t\t\t\t\t\t\t\t\tenableSpaceActivation: !searchable\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t<PickerPopup\n\t\t\t\t\t\t\topen={open}\n\t\t\t\t\t\t\tcontext={context}\n\t\t\t\t\t\t\tfloatingStyles={floatingStyles}\n\t\t\t\t\t\t\tlistId={listId}\n\t\t\t\t\t\t\tlabelId={labelId}\n\t\t\t\t\t\t\tdescriptionId={describedBy}\n\t\t\t\t\t\t\tactiveOptionId={hasOptions ? getActiveOptionId(listId) : undefined}\n\t\t\t\t\t\t\tsetFloating={setFloating}\n\t\t\t\t\t\t\tgetFloatingProps={getFloatingProps}\n\t\t\t\t\t\t\tonKeyDown={handleFloatingKeyDown}\n\t\t\t\t\t\t\tclassName={optionsClassName}\n\t\t\t\t\t\t\tmaxWidth={optionsMaxWidth}\n\t\t\t\t\t\t\ttoolbar={renderPopupHeader}>\n\t\t\t\t\t\t\t<div className={cn(optionsContentClassName, \"h100 scrollable overscroll\")}>\n\t\t\t\t\t\t\t\t{hasOptions ? (\n\t\t\t\t\t\t\t\t\toptionSections ? (\n\t\t\t\t\t\t\t\t\t\toptionSections.map((section, sectionIndex) => {\n\t\t\t\t\t\t\t\t\t\t\tconst groupLabelId = section.group ? `${listId}-group-${sectionIndex}` : undefined;\n\t\t\t\t\t\t\t\t\t\t\tconst optionNodes = section.items.map(({ option, index }) =>\n\t\t\t\t\t\t\t\t\t\t\t\trenderOptionNode(listId, option, index)\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t\treturn section.group ? (\n\t\t\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\t\t\tkey={`group-${String(section.group.key)}-${sectionIndex}`}\n\t\t\t\t\t\t\t\t\t\t\t\t\trole=\"group\"\n\t\t\t\t\t\t\t\t\t\t\t\t\taria-labelledby={groupLabelId}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div id={groupLabelId} className={uiStyles.uiPopupGroupLabel}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{section.group.label}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{optionNodes}\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t\t<Fragment key={`options-${sectionIndex}`}>{optionNodes}</Fragment>\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\tvisibleOptions.map((option, index) => renderOptionNode(listId, option, index))\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\t\t<PickerStatus emptyState={emptyState} errorState={errorState} />\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</PickerPopup>\n\t\t\t\t\t</>\n\t\t\t\t);\n\t\t\t}}\n\t\t</PickerField>\n\t);\n}\n","import { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { OptionCode, OptionText } from \"../option\";\nimport { HighlightText } from \"../text\";\n\ninterface OptionContentProps {\n\tlabel: string;\n\tcode?: string;\n\thighlight?: string;\n\t/** Приватный визуальный modifier label для специализированного владельца option. */\n\tlabelClassName?: string;\n\t/** Отдельный modifier code, потому что code задаёт собственный variable-font weight. */\n\tcodeClassName?: string;\n}\n\n/**\n * Универсальный рендерер опции. Используется и в single-select, и в multi-select.\n */\nexport function SelectOptionContent({ label, code, highlight, labelClassName, codeClassName }: OptionContentProps) {\n\treturn (\n\t\t<>\n\t\t\t<OptionText className={cn(\"flexEllipsis\", labelClassName)}>\n\t\t\t\t<HighlightText text={label} highlight={highlight} />\n\t\t\t</OptionText>\n\t\t\t{code && (\n\t\t\t\t<OptionCode className={codeClassName}>\n\t\t\t\t\t<HighlightText text={code} highlight={highlight} />\n\t\t\t\t</OptionCode>\n\t\t\t)}\n\t\t</>\n\t);\n}\n","import React from \"react\";\n\nimport { ODataSingleSelectProps, useODataCollectionModel } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { CollectionItem } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\nimport { InputUILoading } from \"../input\";\nimport { UiBaseProps } from \"../types\";\n\nimport { useODataSelect } from \"./model/useODataSelect\";\nimport { Select } from \"./Select\";\nimport { SelectOptionContent } from \"./SelectOptionContent\";\n\ntype ODataSelectProps = Omit<ODataSingleSelectProps, \"value\"> & UiBaseProps<string | undefined> & { clearable?: boolean };\n\nfunction getODataOptionTextKey(item: CollectionItem | undefined, textKey: string, codeKey: string) {\n\tif (!item) {\n\t\treturn textKey || codeKey;\n\t}\n\n\treturn textKey || Object.keys(item).find((key) => key !== codeKey) || codeKey;\n}\n\nexport const ODataSelect: React.FC<ODataSelectProps> = ({\n\todata,\n\tsegment,\n\tmodel: initialModel,\n\tsize,\n\tlabel,\n\tdescription,\n\tdisabled,\n\tvalue,\n\tdependencies,\n\tonChange,\n\tclearable\n}) => {\n\tconst model = useODataCollectionModel(initialModel);\n\tconst odataModel = useODataSelect({\n\t\todata,\n\t\tsegment,\n\t\tmodel,\n\t\tvalue,\n\t\tdependencies,\n\t\tonChange\n\t});\n\n\tif (odataModel.isLoading) {\n\t\treturn <InputUILoading size={size} label={label} description={description} />;\n\t}\n\n\tconst hideCode = segment.hideCode ?? odata.hideCode;\n\tconst resolvedTextKey = getODataOptionTextKey(odataModel.selectedItem ?? odataModel.options[0], odataModel.textKey, odataModel.codeKey);\n\n\treturn (\n\t\t<Select\n\t\t\tsize={size}\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\toptions={odataModel.options}\n\t\t\tvalue={odataModel.selectedItem}\n\t\t\tonChange={odataModel.handleChange}\n\t\t\tgetOptionKey={(item) => item[odataModel.codeKey]}\n\t\t\tgetOptionLabel={(item) => item[resolvedTextKey]}\n\t\t\tgetOptionCode={hideCode ? undefined : (item) => item[odataModel.codeKey]}\n\t\t\tgetOptionAriaLabel={(item) =>\n\t\t\t\thideCode || item[resolvedTextKey] === item[odataModel.codeKey]\n\t\t\t\t\t? String(item[resolvedTextKey])\n\t\t\t\t\t: `${item[resolvedTextKey]} ${item[odataModel.codeKey]}`\n\t\t\t}\n\t\t\trenderValue={(item) => (\n\t\t\t\t<SelectOptionContent label={item[resolvedTextKey]} code={hideCode ? undefined : item[odataModel.codeKey]} />\n\t\t\t)}\n\t\t\trenderOption={(item) => (\n\t\t\t\t<SelectOptionContent\n\t\t\t\t\tlabel={item[resolvedTextKey]}\n\t\t\t\t\tcode={hideCode ? undefined : item[odataModel.codeKey]}\n\t\t\t\t\thighlight={odataModel.debouncedQuery}\n\t\t\t\t/>\n\t\t\t)}\n\t\t\tsearchable\n\t\t\tquery={odataModel.query}\n\t\t\tonQuery={odataModel.setQuery}\n\t\t\tdefaultFilter={false}\n\t\t\tdisabled={disabled || odataModel.isLoading}\n\t\t\tplaceholder={odataModel.placeholder}\n\t\t\tisLoading={odataModel.isLoading}\n\t\t\terrorState={odataModel.isError ? \"Ошибка загрузки\" : undefined}\n\t\t\temptyState={!odataModel.isLoading && !odataModel.isError ? \"Нет данных\" : undefined}\n\t\t\tclearable={clearable}\n\t\t/>\n\t);\n};\n","import { useCallback } from \"react\";\n\nimport { useODataDependentSelection } from \"../odata-dependent\";\n\nimport { ODataSelect } from \"./ODataSelect\";\n\nimport type { ODataDependentSegmentControlProps } from \"../odata-dependent\";\n\nexport type ODataDependentSegmentSelectProps = ODataDependentSegmentControlProps & {\n\t/** Показывает действие очистки выбранного значения. */\n\tclearable?: boolean;\n};\n\n/**\n * Адаптирует один развёрнутый зависимый OData-сегмент к single-select UI.\n * Общий снимок остаётся массивным, поэтому совместим с `dependencies` и\n * может совместно использоваться с segment-level MultiSelect-контролами.\n */\nexport function ODataDependentSegmentSelect(props: ODataDependentSegmentSelectProps) {\n\tconst { item, disabled, label, description, size, width = 15, clearable } = props;\n\tconst selection = useODataDependentSelection(props);\n\tconst { updateSegment } = selection;\n\tconst widthStyle = `calc(${width}em + var(--width-add))`;\n\n\tconst handleSelectionChange = useCallback(\n\t\t(value: string | undefined) => {\n\t\t\tupdateSegment(item.id, value === undefined ? [] : [value]);\n\t\t},\n\t\t[item.id, updateSegment]\n\t);\n\n\treturn (\n\t\t<div style={{ maxWidth: widthStyle, minWidth: widthStyle }}>\n\t\t\t<ODataSelect\n\t\t\t\todata={item.odata}\n\t\t\t\tsegment={item.segment}\n\t\t\t\tmodel={item.model}\n\t\t\t\tdependencies={selection.values}\n\t\t\t\tvalue={selection.values[item.id]?.[0]}\n\t\t\t\tonChange={handleSelectionChange}\n\t\t\t\tdisabled={disabled || selection.isSegmentDisabled(item.id)}\n\t\t\t\tlabel={label}\n\t\t\t\tdescription={description}\n\t\t\t\tsize={size}\n\t\t\t\tclearable={clearable}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n","import { Select } from \"./Select\";\n\nimport type { UiBaseProps } from \"../types\";\nimport type { SelectOptionKey } from \"./Select\";\n\ntype SerializableOptionRecord = Record<string, unknown>;\n\ntype SerializableOptionKeyField<TOption extends SerializableOptionRecord> = {\n\t[K in keyof TOption]: Extract<TOption[K], SelectOptionKey> extends never ? never : K;\n}[keyof TOption];\n\ntype SerializableOptionValue<TOption extends SerializableOptionRecord, TOptionKey extends SerializableOptionKeyField<TOption>> = Extract<\n\tTOption[TOptionKey],\n\tSelectOptionKey\n>;\n\nexport interface SerializableSelectProps<\n\tTOption extends SerializableOptionRecord,\n\tTOptionKey extends SerializableOptionKeyField<TOption>,\n\tTOptionLabel extends keyof TOption\n> extends Omit<UiBaseProps<SerializableOptionValue<TOption, TOptionKey> | undefined>, \"onChange\"> {\n\toptions: readonly TOption[];\n\tonChange: (value: SerializableOptionValue<TOption, TOptionKey> | undefined) => void;\n\toptionKey: TOptionKey;\n\toptionLabel: TOptionLabel;\n\trenderCode?: true;\n\tclassName?: string;\n\tclearable?: boolean;\n}\n\nfunction getSerializableOptionKey<TOption extends SerializableOptionRecord, TOptionKey extends SerializableOptionKeyField<TOption>>(\n\toption: TOption,\n\toptionKey: TOptionKey\n): Extract<TOption[TOptionKey], SelectOptionKey> {\n\treturn String(option[optionKey]) as Extract<TOption[TOptionKey], SelectOptionKey>;\n}\n\nfunction getSerializableOptionLabel<\n\tTOption extends SerializableOptionRecord,\n\tTOptionKey extends SerializableOptionKeyField<TOption>,\n\tTOptionLabel extends keyof TOption\n>(option: TOption, optionLabel: TOptionLabel, optionKey: TOptionKey): string {\n\tconst label = option[optionLabel];\n\n\tif (typeof label === \"string\" || typeof label === \"number\") {\n\t\treturn String(label);\n\t}\n\n\tconst key = getSerializableOptionKey(option, optionKey);\n\treturn String(key);\n}\n\nexport function SerializableSelect<\n\tTOption extends SerializableOptionRecord,\n\tTOptionKey extends SerializableOptionKeyField<TOption>,\n\tTOptionLabel extends keyof TOption\n>({\n\tlabel,\n\tdescription,\n\tdisabled,\n\tplaceholder,\n\tsize,\n\toptions,\n\tvalue,\n\tonChange,\n\toptionKey,\n\toptionLabel,\n\trenderCode,\n\tclassName,\n\tclearable\n}: SerializableSelectProps<TOption, TOptionKey, TOptionLabel>) {\n\tconst selectedOption =\n\t\tvalue === undefined ? undefined : options.find((option) => getSerializableOptionKey(option, optionKey) === value);\n\n\treturn (\n\t\t<Select\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\tdisabled={disabled}\n\t\t\tplaceholder={placeholder}\n\t\t\tsize={size}\n\t\t\toptions={options}\n\t\t\tvalue={selectedOption}\n\t\t\tonChange={(option: TOption | undefined) => onChange(option ? getSerializableOptionKey(option, optionKey) : undefined)}\n\t\t\tgetOptionKey={(option: TOption) => getSerializableOptionKey(option, optionKey)}\n\t\t\tgetOptionLabel={(option: TOption) => getSerializableOptionLabel(option, optionLabel, optionKey)}\n\t\t\tgetOptionCode={renderCode ? (option: TOption) => getSerializableOptionKey(option, optionKey) : undefined}\n\t\t\tclassName={className}\n\t\t\tclearable={clearable}\n\t\t/>\n\t);\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as e, c as t, d as n, i as r, n as i, o as a, p as ee, r as te, s as ne, t as re } from "./base-table-
|
|
1
|
+
import { a as e, c as t, d as n, i as r, n as i, o as a, p as ee, r as te, s as ne, t as re } from "./base-table-BWvKfI2W.js";
|
|
2
2
|
import { useEffect as ie, useEffectEvent as ae, useMemo as o, useRef as s } from "react";
|
|
3
3
|
import { jsx as c } from "react/jsx-runtime";
|
|
4
4
|
import { formatPipelineDisplayValue as l } from "@ryuzaki13/react-foundation-lib/formatters";
|
|
@@ -138,4 +138,4 @@ function m({ title: m, isLoading: h, isFetching: se, data: g, columns: _, select
|
|
|
138
138
|
//#endregion
|
|
139
139
|
export { m as t };
|
|
140
140
|
|
|
141
|
-
//# sourceMappingURL=table-
|
|
141
|
+
//# sourceMappingURL=table-DxoSOvQK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table-DxoSOvQK.js","names":[],"sources":["../../src/table/Table.module.scss","../../src/table/Table.tsx"],"sourcesContent":[".selectedIndicatorCell {\n\tbox-shadow: inset 0.1875rem 0 0 var(--accent-text);\n}\n\n.sentinel {\n\theight: 1px;\n}\n","import { useEffect, useEffectEvent, useMemo, useRef } from \"react\";\n\nimport { formatPipelineDisplayValue } from \"@ryuzaki13/react-foundation-lib/formatters\";\nimport { TableFormulaRowData } from \"@ryuzaki13/react-foundation-lib/formulas\";\nimport {\n\ttype FoundationTableRow,\n\tfoundationTableFeatures,\n\ttype TableColumnDef,\n\ttype TableColumnOrderState,\n\ttype TableColumnSizingState,\n\ttype TableColumnVisibilityState,\n\ttype TableSelectionMode,\n\tuseTableRowSelection\n} from \"@ryuzaki13/react-foundation-lib/table\";\nimport { useTable } from \"@tanstack/react-table\";\n\nimport {\n\tBaseTable,\n\tbuildBaseTableMergedCellsLayout,\n\tbuildTableFormattingSnapshot,\n\tFormattedTableCell,\n\tgetOrderedVisibleLeafColumns,\n\tshouldUseTableFormatting,\n\tuseTableColumnOrder,\n\tuseTableColumnPinning,\n\tuseTableColumnSizing,\n\tuseTableColumnVisibility,\n\ttype BaseTableColumnState,\n\ttype BaseTableProps,\n\ttype TableColumnPinningState\n} from \"../base-table\";\n\nimport styles from \"./Table.module.scss\";\n\n/**\n * Возвращает индекс как строковый id, если внешний id не передан.\n */\nfunction defaultGetRowId<TData>(_row: TData, index: number): string {\n\treturn String(index);\n}\n\n/**\n * Пропсы компонента Table.\n *\n * Компонент предназначен для плоских данных и по API осознанно сближен с TreeTable.\n */\nexport interface TableProps<TData extends object> {\n\t/**\n\t * Необязательный заголовок над таблицей.\n\t */\n\ttitle?: string;\n\t/**\n\t * Признак первичной загрузки.\n\t */\n\tisLoading?: boolean;\n\t/**\n\t * Признак фоновой догрузки или обновления данных.\n\t */\n\tisFetching?: boolean;\n\t/**\n\t * Плоский источник строк.\n\t */\n\tdata: readonly TData[] | undefined | null;\n\t/**\n\t * Описание колонок таблицы.\n\t */\n\tcolumns: readonly TableColumnDef<TData>[];\n\t/**\n\t * Режим выбора строк.\n\t */\n\tselectionMode?: TableSelectionMode;\n\t/**\n\t * Внешний список выбранных строк.\n\t *\n\t * Если передан, таблица синхронизирует визуальное выделение с этим набором id.\n\t */\n\tselectedRowIds?: readonly string[];\n\t/**\n\t * Стабильный идентификатор строки.\n\t *\n\t * Если не задан, используется индекс строки.\n\t */\n\tgetRowId?: (row: TData, index: number) => string;\n\t/**\n\t * Дополнительный CSS-класс корневого контейнера.\n\t */\n\tclassName?: string;\n\tminHeight?: `${number}em` | `${number}%`;\n\t/**\n\t * Дополнительный CSS-класс тега `table`.\n\t */\n\ttableClassName?: string;\n\t/**\n\t * Внешнее controlled-состояние видимости колонок.\n\t */\n\tcolumnVisibility?: TableColumnVisibilityState;\n\t/**\n\t * Стартовое uncontrolled-состояние видимости колонок.\n\t */\n\tdefaultColumnVisibility?: TableColumnVisibilityState;\n\t/**\n\t * Внешнее controlled-состояние порядка колонок.\n\t */\n\tcolumnOrder?: readonly string[];\n\t/**\n\t * Стартовое uncontrolled-состояние порядка колонок.\n\t */\n\tdefaultColumnOrder?: readonly string[];\n\t/**\n\t * Внешнее controlled-состояние ширин колонок в px.\n\t */\n\tcolumnSizing?: TableColumnSizingState;\n\t/**\n\t * Стартовое uncontrolled-состояние ширин колонок в px.\n\t */\n\tdefaultColumnSizing?: TableColumnSizingState;\n\t/**\n\t * Внешнее controlled-состояние start-pinning для колонок.\n\t */\n\tcolumnPinning?: TableColumnPinningState;\n\t/**\n\t * Стартовое uncontrolled-состояние start-pinning для колонок.\n\t */\n\tdefaultColumnPinning?: TableColumnPinningState;\n\t/**\n\t * Включает изменение ширины колонок через header-handle.\n\t */\n\tenableColumnResizing?: boolean;\n\t/**\n\t * Включает изменение порядка колонок через drag&drop заголовков.\n\t */\n\tenableColumnReordering?: boolean;\n\t/**\n\t * Минимальная ширина колонки при resize в px.\n\t */\n\tcolumnResizeMinWidth?: number;\n\t/**\n\t * Вызывается после изменения видимости колонок.\n\t */\n\tonColumnVisibilityChange?: (state: TableColumnVisibilityState) => void;\n\t/**\n\t * Вызывается после изменения порядка колонок.\n\t */\n\tonColumnOrderChange?: (state: TableColumnOrderState) => void;\n\t/**\n\t * Вызывается после изменения ширины колонок.\n\t */\n\tonColumnSizingChange?: (state: TableColumnSizingState) => void;\n\t/**\n\t * Вызывается после изменения start-pinning state.\n\t */\n\tonColumnPinningChange?: (state: TableColumnPinningState) => void;\n\t/**\n\t * Вызывается при активации строки кликом или клавиатурой.\n\t */\n\tonRowClick?: (row: TData) => void;\n\t/**\n\t * Вызывается после изменения выбранных строк.\n\t */\n\tonRowSelectionChange?: (rows: TData[]) => void;\n\t/**\n\t * Вызывается при достижении конца таблицы внутри scroll-контейнера.\n\t */\n\tonReachEnd?: () => void;\n\t/**\n\t * Позволяет запретить выбор отдельных строк.\n\t */\n\tgetRowCanSelect?: (row: TData) => boolean;\n\t/**\n\t * Позволяет добавить CSS-класс для конкретной строки.\n\t */\n\tgetRowClassName?: (row: TData) => string | undefined;\n\t/**\n\t * Контекстное меню заголовка колонки. Используется для общих runtime-действий\n\t * вроде server sorting без встраивания доменной логики в shared-таблицу.\n\t */\n\trenderHeaderContextMenu?: BaseTableProps<TData>[\"renderHeaderContextMenu\"];\n\t/**\n\t * Тонкая точка расширения содержимого ячейки поверх стандартного форматирования.\n\t *\n\t * В отличие от `column.cell`, этот слот не отключает общий formatting-runtime:\n\t * `defaultContent` уже содержит отформатированное значение, если оно применимо.\n\t */\n\trenderCellContent?: BaseTableProps<TData>[\"renderCellContent\"];\n}\n\n/**\n * Плоская таблица на базе TanStack Table как React-альтернатива `sap.m.Table`.\n */\nexport function Table<TData extends object>({\n\ttitle,\n\tisLoading,\n\tisFetching,\n\tdata,\n\tcolumns,\n\tselectionMode = \"none\",\n\tselectedRowIds,\n\tgetRowId,\n\tclassName,\n\tminHeight,\n\ttableClassName,\n\tcolumnVisibility,\n\tdefaultColumnVisibility,\n\tcolumnOrder,\n\tdefaultColumnOrder,\n\tcolumnSizing,\n\tdefaultColumnSizing,\n\tcolumnPinning,\n\tdefaultColumnPinning,\n\tenableColumnResizing = false,\n\tenableColumnReordering = false,\n\tcolumnResizeMinWidth,\n\tonColumnVisibilityChange,\n\tonColumnOrderChange,\n\tonColumnSizingChange,\n\tonColumnPinningChange,\n\tonRowClick,\n\tonRowSelectionChange,\n\tonReachEnd,\n\tgetRowCanSelect,\n\tgetRowClassName,\n\trenderHeaderContextMenu,\n\trenderCellContent\n}: TableProps<TData>) {\n\tconst tableData = useMemo(() => data ?? [], [data]);\n\tconst formattingSnapshot = useMemo(() => buildTableFormattingSnapshot(columns), [columns]);\n\tconst resolveRowId = getRowId ?? defaultGetRowId<TData>;\n\tconst rowById = useMemo(() => new Map(tableData.map((row, index) => [resolveRowId(row, index), row])), [resolveRowId, tableData]);\n\tconst availableRowIds = useMemo(() => Array.from(rowById.keys()), [rowById]);\n\tconst scrollableRef = useRef<HTMLDivElement | null>(null);\n\tconst sentinelRef = useRef<HTMLDivElement | null>(null);\n\n\tconst { rowSelection, activateRowSelection } = useTableRowSelection({\n\t\tavailableRowIds,\n\t\trowById,\n\t\tselectionMode,\n\t\tselectedRowIds,\n\t\tonRowSelectionChange\n\t});\n\tconst { columnVisibility: resolvedColumnVisibility, onColumnVisibilityChange: handleColumnVisibilityChange } = useTableColumnVisibility(\n\t\t{\n\t\t\tcolumnVisibility,\n\t\t\tdefaultColumnVisibility,\n\t\t\tonColumnVisibilityChange\n\t\t}\n\t);\n\tconst { columnOrder: resolvedColumnOrder, onColumnOrderChange: handleColumnOrderChange } = useTableColumnOrder({\n\t\tcolumnOrder,\n\t\tdefaultColumnOrder,\n\t\tonColumnOrderChange\n\t});\n\tconst { columnSizing: resolvedColumnSizing, onColumnSizingChange: handleColumnSizingChange } = useTableColumnSizing({\n\t\tcolumnSizing,\n\t\tdefaultColumnSizing,\n\t\tcolumnResizeMinWidth,\n\t\tonColumnSizingChange\n\t});\n\tconst { columnPinning: resolvedColumnPinning, onColumnPinningChange: handleColumnPinningChange } = useTableColumnPinning({\n\t\tcolumnPinning,\n\t\tdefaultColumnPinning,\n\t\tonColumnPinningChange\n\t});\n\tconst baseTableColumnState = useMemo<BaseTableColumnState>(\n\t\t() => ({\n\t\t\tcolumnOrder: resolvedColumnOrder,\n\t\t\tcolumnPinning: resolvedColumnPinning,\n\t\t\tcolumnSizing: resolvedColumnSizing,\n\t\t\tcolumnVisibility: resolvedColumnVisibility\n\t\t}),\n\t\t[resolvedColumnOrder, resolvedColumnPinning, resolvedColumnSizing, resolvedColumnVisibility]\n\t);\n\n\tconst emitReachEnd = useEffectEvent(() => {\n\t\tonReachEnd?.();\n\t});\n\n\tuseEffect(() => {\n\t\tif (!onReachEnd || !scrollableRef.current || !sentinelRef.current || isLoading) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst observer = new IntersectionObserver(\n\t\t\t(entries) => {\n\t\t\t\tconst entry = entries[0];\n\n\t\t\t\tif (entry?.isIntersecting) {\n\t\t\t\t\temitReachEnd();\n\t\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\t\troot: scrollableRef.current,\n\t\t\t\tthreshold: 0.1\n\t\t\t}\n\t\t);\n\n\t\tobserver.observe(sentinelRef.current);\n\n\t\treturn () => observer.disconnect();\n\t}, [isLoading, onReachEnd, tableData.length]);\n\n\tconst table = useTable({\n\t\tfeatures: foundationTableFeatures,\n\t\tdata: tableData as TData[],\n\t\tcolumns: columns as TableColumnDef<TData>[],\n\t\tstate: {\n\t\t\tcolumnOrder: resolvedColumnOrder,\n\t\t\tcolumnPinning: resolvedColumnPinning,\n\t\t\tcolumnSizing: resolvedColumnSizing,\n\t\t\tcolumnVisibility: resolvedColumnVisibility,\n\t\t\trowSelection\n\t\t},\n\t\tonColumnOrderChange: handleColumnOrderChange,\n\t\tonColumnPinningChange: handleColumnPinningChange,\n\t\tonColumnSizingChange: handleColumnSizingChange,\n\t\tonColumnVisibilityChange: handleColumnVisibilityChange,\n\t\tgetRowId: (row, index) => resolveRowId(row, index),\n\t\tenableMultiRowSelection: selectionMode === \"multi\",\n\t\tenableRowSelection: (row) => {\n\t\t\tif (selectionMode === \"none\") {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn getRowCanSelect ? getRowCanSelect(row.original) : true;\n\t\t}\n\t});\n\n\tconst visibleLeafColumns = getOrderedVisibleLeafColumns(table, baseTableColumnState);\n\tconst rowModelRows = table.getRowModel().rows;\n\tconst mergedCellLayout = useMemo(\n\t\t() =>\n\t\t\tbuildBaseTableMergedCellsLayout({\n\t\t\t\trows: rowModelRows,\n\t\t\t\tcolumns: visibleLeafColumns\n\t\t\t}),\n\t\t[rowModelRows, visibleLeafColumns]\n\t);\n\tconst leadingColumnId = visibleLeafColumns[0]?.id;\n\n\t/**\n\t * Активирует строку: обновляет выбор в соответствии с режимом и вызывает внешний callback.\n\t */\n\tconst activateRow = (row: FoundationTableRow<TData>) => {\n\t\tactivateRowSelection(row.id, row.getCanSelect());\n\t\tonRowClick?.(row.original);\n\t};\n\n\treturn (\n\t\t<BaseTable\n\t\t\ttable={table}\n\t\t\tcolumnState={baseTableColumnState}\n\t\t\ttitle={title}\n\t\t\tisLoading={isLoading}\n\t\t\tisFetching={isFetching}\n\t\t\tclassName={className}\n\t\t\tminHeight={minHeight}\n\t\t\ttableClassName={tableClassName}\n\t\t\tselectionMode={selectionMode}\n\t\t\tscrollableRef={scrollableRef}\n\t\t\tonActivateRow={selectionMode !== \"none\" || onRowClick ? activateRow : undefined}\n\t\t\tisRowInteractive={(row) => Boolean(onRowClick || (selectionMode !== \"none\" && row.getCanSelect()))}\n\t\t\tgetRowClassName={(row) => getRowClassName?.(row.original)}\n\t\t\tgetCellClassName={({ row, cell }) =>\n\t\t\t\tcell.column.id === leadingColumnId && row.getIsSelected() ? styles.selectedIndicatorCell : undefined\n\t\t\t}\n\t\t\tgetCellLayout={({ cell }) => mergedCellLayout.get(cell.id)}\n\t\t\trenderHeaderContextMenu={renderHeaderContextMenu}\n\t\t\tenableColumnResizing={enableColumnResizing}\n\t\t\tenableColumnReordering={enableColumnReordering}\n\t\t\tcolumnResizeMinWidth={columnResizeMinWidth}\n\t\t\trenderCellContent={(args) => {\n\t\t\t\tconst displayValue = formatPipelineDisplayValue({\n\t\t\t\t\tfield: formattingSnapshot.runtimeByColumnId[args.cell.column.id],\n\t\t\t\t\trawValue: args.cell.getValue(),\n\t\t\t\t\trowData: args.row.original as TableFormulaRowData,\n\t\t\t\t\trowKind: \"plain\"\n\t\t\t\t});\n\t\t\t\tconst defaultContent = !shouldUseTableFormatting({\n\t\t\t\t\tcolumnId: args.cell.column.id,\n\t\t\t\t\truntimeByColumnId: formattingSnapshot.runtimeByColumnId,\n\t\t\t\t\tcustomCellColumnIds: formattingSnapshot.customCellColumnIds\n\t\t\t\t}) ? (\n\t\t\t\t\targs.defaultContent\n\t\t\t\t) : (\n\t\t\t\t\t<FormattedTableCell displayValue={displayValue} align={args.columnMeta?.align} />\n\t\t\t\t);\n\n\t\t\t\tif (renderCellContent) {\n\t\t\t\t\treturn renderCellContent({\n\t\t\t\t\t\t...args,\n\t\t\t\t\t\tdefaultContent,\n\t\t\t\t\t\tdisplayValue\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn defaultContent;\n\t\t\t}}\n\t\t\tafterTableContent={onReachEnd ? <div ref={sentinelRef} className={styles.sentinel} aria-hidden=\"true\" /> : null}\n\t\t/>\n\t);\n}\n"],"mappings":"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"}
|
|
@@ -19,6 +19,7 @@ var e = {
|
|
|
19
19
|
required: "_7GxEke",
|
|
20
20
|
invalid: "kkpwQI",
|
|
21
21
|
uiToneNeutral: "DPvwku",
|
|
22
|
+
uiToneAccent: "O9zizU",
|
|
22
23
|
uiToneBrand: "BTLgLF",
|
|
23
24
|
uiToneError: "SRqz74",
|
|
24
25
|
uiToneWarning: "e-6pS0",
|
|
@@ -63,4 +64,4 @@ var e = {
|
|
|
63
64
|
//#endregion
|
|
64
65
|
export { e as t };
|
|
65
66
|
|
|
66
|
-
//# sourceMappingURL=ui.module-
|
|
67
|
+
//# sourceMappingURL=ui.module-oRwY3Zli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui.module-oRwY3Zli.js","names":[],"sources":["../../src/ui.module.scss"],"sourcesContent":["@use \"@/styles/mixins\" as *;\n\n.uiSizable {\n\t--base-width: 100%;\n\n\twidth: var(--base-width);\n\n\t&.xs {\n\t\t--base-width: calc(var(--drp-ui-width-xs, var(--ui-width-xs)) - var(--width-add));\n\t}\n\n\t&.sm {\n\t\t--base-width: calc(var(--drp-ui-width-sm, var(--ui-width-sm)) - var(--width-add));\n\t}\n\n\t&.md {\n\t\t--base-width: calc(var(--drp-ui-width-md, var(--ui-width-md)) - var(--width-add));\n\t}\n\n\t&.lg {\n\t\t--base-width: calc(var(--drp-ui-width-lg, var(--ui-width-lg)) - var(--width-add));\n\t}\n\n\t&.xl {\n\t\t--base-width: calc(var(--drp-ui-width-xl, var(--ui-width-xl)) - var(--width-add));\n\t}\n}\n\n// TODO: Тестовый класс\n.uiErrorElement {\n\t--grid-size: var(--space-sm);\n\t--grid-line-size: var(--border-width);\n\t--grid-line-color: color-mix(in srgb, var(--error-fill) 12%, var(--surface-0));\n\n\theight: var(--control-height);\n\twidth: 100%; // calc(10em - var(--width-add));\n\tflex-shrink: 0;\n\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\n\tborder: var(--focus-width) solid var(--error-border);\n\tborder-radius: var(--radius-sm);\n\toutline: none;\n\n\tfont-weight: 700;\n\tfont-variation-settings: \"wght\" 700;\n\n\tcolor: var(--error-text);\n\tbackground-color: var(--surface-0);\n\tbackground-image:\n\t\trepeating-linear-gradient(\n\t\t\t45deg,\n\t\t\tvar(--grid-line-color) 0 var(--grid-line-size),\n\t\t\ttransparent var(--grid-line-size) var(--grid-size)\n\t\t),\n\t\trepeating-linear-gradient(\n\t\t\t-45deg,\n\t\t\tvar(--grid-line-color) 0 var(--grid-line-size),\n\t\t\ttransparent var(--grid-line-size) var(--grid-size)\n\t\t);\n}\n\n.uiContainer {\n\tposition: relative;\n\twidth: 100%;\n}\n\n.uiInputContainer {\n\t@extend .uiContainer;\n\n\t--padding-right: var(--control-height);\n}\n\n.uiLabelBase {\n\tdisplay: inline-block;\n\tfont-weight: 400;\n\tfont-variation-settings: \"wght\" 400;\n}\n\n.uiLabel {\n\t@extend .uiLabelBase;\n\n\tmargin-block: var(--space-xs);\n}\n\n.uiDescription {\n\t--paragraph-margin: 0;\n\n\tpadding-bottom: var(--space-xs);\n\tcolor: var(--content-1);\n\tfont-weight: 300;\n\tfont-variation-settings: \"wght\" 300;\n}\n\n.uiLabel,\n.uiDescription {\n\tmargin-inline: var(--space-xs);\n}\n\n.uiPlaceholder {\n\tcolor: var(--content-2);\n\tfont-weight: 100;\n\tfont-variation-settings: \"wght\" 100;\n\t// font-size: var(--font-size-sm);\n\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n\n.required {\n\t.uiLabelBase::after {\n\t\tcontent: \" *\";\n\t\tcolor: var(--error-text);\n\t}\n}\n\n.uiControl {\n\t@include ui-tone(\"neutral\");\n\t@include ui-appearance-outline;\n\t@include ui-control-base;\n\n\t--ui-radius: var(--radius-sm);\n\n\t&.invalid,\n\t&:invalid {\n\t\t@include ui-tone(\"error\");\n\t\t@include ui-appearance-outline;\n\t}\n\n\t&::placeholder {\n\t\t@extend .uiPlaceholder;\n\t}\n}\n\n.uiToneNeutral {\n\t@include ui-tone(\"neutral\");\n}\n\n.uiToneAccent {\n\t@include ui-tone(\"accent\");\n}\n\n.uiToneBrand {\n\t@include ui-tone(\"brand\");\n}\n\n.uiToneError {\n\t@include ui-tone(\"error\");\n}\n\n.uiToneWarning {\n\t@include ui-tone(\"warning\");\n}\n\n.uiToneSuccess {\n\t@include ui-tone(\"success\");\n}\n\n.uiToneInfo {\n\t@include ui-tone(\"info\");\n}\n\n.uiAppearanceSolid {\n\t@include ui-appearance-solid;\n}\n\n.uiAppearanceOutline {\n\t@include ui-appearance-outline;\n}\n\n.uiAppearanceGhost {\n\t@include ui-appearance-ghost;\n}\n\n.uiAppearanceTransparent {\n\t@include ui-appearance-transparent;\n}\n\n.uiInputControl {\n\t@extend .uiControl;\n\n\theight: var(--control-height);\n}\n\n.uiInputWithToggle {\n\t@extend .uiInputControl;\n\n\tcolor: var(--content-0);\n\n\tpadding: 0 var(--padding-right) 0 var(--space-sm);\n\twidth: 100%;\n\ttext-align: left;\n\n\t// &[type=\"button\"] {\n\t// \twhite-space: nowrap;\n\t// }\n}\n\n.uiSelectionControl {\n\t@include ui-control-base;\n\n\t--ui-color: var(--content-0);\n\t--ui-color-hover: var(--content-0);\n\t--ui-color-active: var(--content-0);\n\t--ui-background: var(--surface-0);\n\t--ui-background-hover: var(--ui-tone-soft);\n\t--ui-background-active: var(--ui-tone-soft);\n\t--ui-border-color: var(--ui-tone-border);\n\t--ui-border-hover: var(--ui-tone-border-hover);\n\t--ui-border-active: var(--ui-tone-border-active);\n\t--ui-border-focus: var(--ui-tone-border-focus);\n\n\tappearance: none;\n\tmargin: 0;\n\tcursor: pointer;\n\n\t&:checked {\n\t\tborder-color: var(--ui-tone-border-active);\n\n\t\t& + .uiSelectionIcon {\n\t\t\tcolor: var(--ui-tone-fill);\n\t\t}\n\t}\n\n\t&:disabled {\n\t\tcursor: default;\n\n\t\tborder-color: var(--border-0);\n\n\t\t&:checked {\n\t\t\t& + .uiSelectionIcon {\n\t\t\t\tcolor: var(--border-0);\n\t\t\t}\n\t\t}\n\t}\n}\n\n.uiSelectionIcon {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tposition: absolute;\n\ttop: 50%;\n\tleft: 50%;\n\ttransform: translate(-50%, -50%);\n\tpointer-events: none;\n\tcolor: transparent;\n\ttransition:\n\t\tcolor var(--transition-fast) ease,\n\t\topacity var(--transition-fast) ease;\n}\n\n.uiElement,\n.uiPopupOption {\n\t&.disabled,\n\t&:disabled {\n\t\tuser-select: none;\n\n\t\t.uiLabel,\n\t\t.uiDescription {\n\t\t\tcolor: var(--content-2);\n\t\t}\n\n\t\t.uiPlaceholder,\n\t\t.uiOptionText,\n\t\t.uiOptionCode {\n\t\t\topacity: 0.25;\n\t\t}\n\t}\n\n\t// Класс disabled используется у составных ненативных элементов: им нужно явно запретить события.\n\t&.disabled {\n\t\tcursor: default;\n\t\tpointer-events: none;\n\t}\n\n\t// Нативный disabled уже блокирует активацию, а pointer-events остаются для курсора и tooltip.\n\t&:disabled {\n\t\tcursor: not-allowed;\n\t}\n}\n\n.uiPanelTonePrimary {\n\t--ui-panel-background: var(--surface-0);\n}\n\n.uiPanelToneSecondary {\n\t--ui-panel-background: var(--surface-1);\n}\n\n.uiPanelToneTertiary {\n\t--ui-panel-background: var(--surface-2);\n}\n\n.uiFilledPanel {\n\tbackground-color: var(--ui-panel-background, var(--surface-0));\n}\n\n.uiFramedPanel {\n\tborder: var(--border);\n\tborder-radius: var(--radius-sm);\n\tpadding: var(--space-sm);\n}\n\n.uiPanel {\n\t@extend .uiFramedPanel;\n\t@extend .uiFilledPanel;\n}\n\n.uiStateFocus {\n\t@include focusVisible;\n\n\tbackground-color: var(--surface-1);\n\tborder-color: var(--border-1);\n\tcursor: pointer;\n}\n\n.uiOptionBase {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: flex-start;\n\tgap: var(--space-sm);\n\theight: 100%;\n\twidth: 100%;\n\ttext-align: left;\n}\n\n.uiPopupOption {\n\t@extend .uiOptionBase;\n\n\theight: auto;\n\tmin-height: var(--control-height);\n}\n\n.uiPopupOption {\n\tborder-radius: var(--radius-sm);\n\tborder: none;\n\tbackground-color: transparent;\n\tcolor: var(--content-0);\n\n\ttransition:\n\t\tbackground-color var(--transition-fast) ease,\n\t\tcolor var(--transition-fast) ease;\n\n\t.uiMenuOptionIcon,\n\t.uiPopupOptionIcon {\n\t\tflex-shrink: 0;\n\t\tfont-size: var(--font-size-sm);\n\t\twidth: var(--icon-size);\n\t\theight: var(--icon-size);\n\t}\n\n\t.uiMenuOptionIcon,\n\t.keyboard {\n\t\tcolor: var(--content-2);\n\t}\n\n\t&.selected {\n\t\tcolor: var(--accent-on-fill);\n\t\tbackground-color: var(--accent-fill);\n\t\tcursor: default;\n\t}\n\n\t&.uiPopupOptionActive,\n\t&:active {\n\t\tcolor: var(--accent-on-fill);\n\t\tbackground-color: var(--accent-fill);\n\t}\n\n\t@include hover(true) {\n\t\tcolor: var(--accent-on-fill);\n\t\tbackground-color: var(--accent-fill);\n\t\tcursor: pointer;\n\t}\n\n\t&.disabled {\n\t\t// background-color: var(--surface-2);\n\t\tcolor: var(--content-2);\n\t}\n\n\t&:focus-within {\n\t\t// @extend .uiStateFocus;\n\t\t@include focusVisible;\n\t}\n}\n\n.uiOptionButton,\n.uiOptionLink {\n\t@extend .uiOptionBase;\n\n\tflex: 1 1 0;\n\tmin-width: 0;\n\theight: 100%;\n\tpadding: var(--space-xs) var(--space-sm);\n\tborder: none;\n\tborder-radius: inherit;\n\toutline: none;\n\tbackground: transparent;\n\tcolor: inherit;\n\tcursor: inherit;\n\ttext-decoration: none;\n}\n\n.uiPopupOptionSeparator {\n\tborder-top: var(--border);\n\tmargin-block: var(--space-xs);\n}\n\n.uiPopupGroupLabel {\n\tpadding: var(--space-xs) var(--space-sm);\n\tcolor: var(--content-2);\n\tfont-weight: 300;\n\ttext-transform: uppercase;\n\tfont-size: var(--font-size-sm);\n}\n\n.uiMenuOptionIcon {\n\tdisplay: flex;\n\talign-items: center;\n}\n\n.uiOptionText {\n\t// font-size: var(--font-size-sm);\n\tflex: 1;\n\tmin-width: 0;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n\n.uiOptionCode {\n\tfont-family: var(--font-family-mono);\n\t// font-size: var(--font-size-sm);\n\tcolor: var(--content-1);\n\tfont-weight: 300;\n\tfont-variation-settings: \"wght\" 300;\n}\n\n.uiOptionContentEmphasize {\n\tfont-weight: 600;\n\tfont-variation-settings: \"wght\" 600;\n}\n\n.uiToggleButtonContainer {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: flex-end;\n\theight: 100%;\n\twidth: 100%;\n\n\ttransition-property: width;\n\ttransition-duration: var(--transition-fast);\n\ttransition-timing-function: cubic-bezier(1, 0, 0.5, 0.5);\n\n\t> button {\n\t\tbackground: transparent;\n\t\tborder: none;\n\t\tcursor: pointer;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\theight: var(--control-height);\n\t\twidth: var(--control-height);\n\t\tborder-radius: var(--radius-sm);\n\t\tflex: 0 0 var(--control-height);\n\t}\n\n\t// &[data-disabled] {\n\t// \tcursor: default;\n\t// \tpointer-events: none;\n\t// \topacity: var(--disabled-opacity);\n\t// }\n}\n\n.uiToggleButton {\n\tcolor: var(--content-0);\n\n\t&:hover {\n\t\tcolor: var(--accent-text);\n\t}\n}\n\n.uiToggleIcon {\n\ttransition: transform var(--transition-fast) ease-in-out;\n\n\t&.uiToggleIconOpen {\n\t\ttransform: rotate(180deg);\n\t}\n}\n\n// TODO: пока в свалку стили для дата-подобных компонентов\n\n// Для компонентов, который не являются input, но выставляют себя за него\n.uiInputControlFake {\n\t@extend .uiInputControl;\n\n\twidth: 100%;\n\tpadding: 0 var(--space-sm);\n\tfont-size: var(--font-size-md);\n\n\tdisplay: flex;\n\talign-items: center;\n\n\tcursor: text;\n}\n\n.uiClearButton {\n\tcolor: var(--error-text);\n\n\t&:disabled {\n\t\topacity: 0;\n\t\tpointer-events: none;\n\t\twidth: 0;\n\t\theight: 0;\n\t\tpadding: 0;\n\t\tmargin: 0;\n\t\toverflow: hidden;\n\t}\n}\n\n.uiButtonSeparator {\n\tborder-left: var(--border);\n\theight: calc(100% - var(--space-sm));\n}\n"],"mappings":""}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as e } from "./ui.module-
|
|
1
|
+
import { t as e } from "./ui.module-oRwY3Zli.js";
|
|
2
2
|
//#region src/uiClasses.ts
|
|
3
3
|
var t = {
|
|
4
4
|
neutral: {
|
|
@@ -13,6 +13,10 @@ var t = {
|
|
|
13
13
|
tone: "neutral",
|
|
14
14
|
appearance: "ghost"
|
|
15
15
|
},
|
|
16
|
+
accent: {
|
|
17
|
+
tone: "accent",
|
|
18
|
+
appearance: "solid"
|
|
19
|
+
},
|
|
16
20
|
brand: {
|
|
17
21
|
tone: "brand",
|
|
18
22
|
appearance: "solid"
|
|
@@ -33,6 +37,10 @@ var t = {
|
|
|
33
37
|
tone: "info",
|
|
34
38
|
appearance: "solid"
|
|
35
39
|
},
|
|
40
|
+
accentOutline: {
|
|
41
|
+
tone: "accent",
|
|
42
|
+
appearance: "outline"
|
|
43
|
+
},
|
|
36
44
|
brandOutline: {
|
|
37
45
|
tone: "brand",
|
|
38
46
|
appearance: "outline"
|
|
@@ -58,6 +66,7 @@ var t = {
|
|
|
58
66
|
appearance: "transparent"
|
|
59
67
|
}
|
|
60
68
|
}, n = {
|
|
69
|
+
accent: e.uiToneAccent,
|
|
61
70
|
neutral: e.uiToneNeutral,
|
|
62
71
|
brand: e.uiToneBrand,
|
|
63
72
|
error: e.uiToneError,
|
|
@@ -95,4 +104,4 @@ function c({ variant: e, tone: n, appearance: r, fallbackTone: i = "neutral", fa
|
|
|
95
104
|
//#endregion
|
|
96
105
|
export { c as i, s as n, a as r, o as t };
|
|
97
106
|
|
|
98
|
-
//# sourceMappingURL=uiClasses-
|
|
107
|
+
//# sourceMappingURL=uiClasses-CQj47jkF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uiClasses-CQj47jkF.js","names":[],"sources":["../../src/uiClasses.ts"],"sourcesContent":["import uiStyles from \"./ui.module.scss\";\n\nimport type { UiAppearance, UiPanelTone, UiTone, UiVariant } from \"./types\";\n\nexport type UiScheme = {\n\ttone: UiTone;\n\tappearance: UiAppearance;\n};\n\nexport type UiSelectionAppearance = Extract<UiAppearance, \"outline\" | \"solid\">;\n\nconst variantSchemeMap: Record<UiVariant, UiScheme> = {\n\tneutral: { tone: \"neutral\", appearance: \"solid\" },\n\tneutralOutline: { tone: \"neutral\", appearance: \"outline\" },\n\tghost: { tone: \"neutral\", appearance: \"ghost\" },\n\taccent: { tone: \"accent\", appearance: \"solid\" },\n\tbrand: { tone: \"brand\", appearance: \"solid\" },\n\terror: { tone: \"error\", appearance: \"solid\" },\n\twarning: { tone: \"warning\", appearance: \"solid\" },\n\tsuccess: { tone: \"success\", appearance: \"solid\" },\n\tinfo: { tone: \"info\", appearance: \"solid\" },\n\taccentOutline: { tone: \"accent\", appearance: \"outline\" },\n\tbrandOutline: { tone: \"brand\", appearance: \"outline\" },\n\terrorOutline: { tone: \"error\", appearance: \"outline\" },\n\twarningOutline: { tone: \"warning\", appearance: \"outline\" },\n\tsuccessOutline: { tone: \"success\", appearance: \"outline\" },\n\tinfoOutline: { tone: \"info\", appearance: \"outline\" },\n\ttransparent: { tone: \"neutral\", appearance: \"transparent\" }\n};\n\nconst toneClassNameMap: Record<UiTone, string> = {\n\taccent: uiStyles.uiToneAccent,\n\tneutral: uiStyles.uiToneNeutral,\n\tbrand: uiStyles.uiToneBrand,\n\terror: uiStyles.uiToneError,\n\twarning: uiStyles.uiToneWarning,\n\tsuccess: uiStyles.uiToneSuccess,\n\tinfo: uiStyles.uiToneInfo\n};\n\nconst appearanceClassNameMap: Record<UiAppearance, string> = {\n\tsolid: uiStyles.uiAppearanceSolid,\n\toutline: uiStyles.uiAppearanceOutline,\n\tghost: uiStyles.uiAppearanceGhost,\n\ttransparent: uiStyles.uiAppearanceTransparent\n};\n\nconst panelToneClassNameMap: Record<UiPanelTone, string> = {\n\tprimary: uiStyles.uiPanelTonePrimary,\n\tsecondary: uiStyles.uiPanelToneSecondary,\n\ttertiary: uiStyles.uiPanelToneTertiary\n};\n\nexport function getUiToneClassName(tone: UiTone): string {\n\treturn toneClassNameMap[tone];\n}\n\nexport function getUiAppearanceClassName(appearance: UiAppearance): string {\n\treturn appearanceClassNameMap[appearance];\n}\n\nexport function getUiPanelToneClassName(tone: UiPanelTone): string {\n\treturn panelToneClassNameMap[tone];\n}\n\nexport function resolveUiScheme({\n\tvariant,\n\ttone,\n\tappearance,\n\tfallbackTone = \"neutral\",\n\tfallbackAppearance = \"outline\"\n}: {\n\tvariant?: UiVariant;\n\ttone?: UiTone;\n\tappearance?: UiAppearance;\n\tfallbackTone?: UiTone;\n\tfallbackAppearance?: UiAppearance;\n}): UiScheme {\n\tif (tone || appearance) {\n\t\treturn {\n\t\t\ttone: tone ?? fallbackTone,\n\t\t\tappearance: appearance ?? fallbackAppearance\n\t\t};\n\t}\n\n\tif (variant) {\n\t\treturn variantSchemeMap[variant];\n\t}\n\n\treturn {\n\t\ttone: fallbackTone,\n\t\tappearance: fallbackAppearance\n\t};\n}\n"],"mappings":";;AAWA,IAAM,IAAgD;CACrD,SAAS;EAAE,MAAM;EAAW,YAAY;CAAQ;CAChD,gBAAgB;EAAE,MAAM;EAAW,YAAY;CAAU;CACzD,OAAO;EAAE,MAAM;EAAW,YAAY;CAAQ;CAC9C,QAAQ;EAAE,MAAM;EAAU,YAAY;CAAQ;CAC9C,OAAO;EAAE,MAAM;EAAS,YAAY;CAAQ;CAC5C,OAAO;EAAE,MAAM;EAAS,YAAY;CAAQ;CAC5C,SAAS;EAAE,MAAM;EAAW,YAAY;CAAQ;CAChD,SAAS;EAAE,MAAM;EAAW,YAAY;CAAQ;CAChD,MAAM;EAAE,MAAM;EAAQ,YAAY;CAAQ;CAC1C,eAAe;EAAE,MAAM;EAAU,YAAY;CAAU;CACvD,cAAc;EAAE,MAAM;EAAS,YAAY;CAAU;CACrD,cAAc;EAAE,MAAM;EAAS,YAAY;CAAU;CACrD,gBAAgB;EAAE,MAAM;EAAW,YAAY;CAAU;CACzD,gBAAgB;EAAE,MAAM;EAAW,YAAY;CAAU;CACzD,aAAa;EAAE,MAAM;EAAQ,YAAY;CAAU;CACnD,aAAa;EAAE,MAAM;EAAW,YAAY;CAAc;AAC3D,GAEM,IAA2C;CAChD,QAAQ,EAAS;CACjB,SAAS,EAAS;CAClB,OAAO,EAAS;CAChB,OAAO,EAAS;CAChB,SAAS,EAAS;CAClB,SAAS,EAAS;CAClB,MAAM,EAAS;AAChB,GAEM,IAAuD;CAC5D,OAAO,EAAS;CAChB,SAAS,EAAS;CAClB,OAAO,EAAS;CAChB,aAAa,EAAS;AACvB,GAEM,IAAqD;CAC1D,SAAS,EAAS;CAClB,WAAW,EAAS;CACpB,UAAU,EAAS;AACpB;AAEA,SAAgB,EAAmB,GAAsB;CACxD,OAAO,EAAiB;AACzB;AAEA,SAAgB,EAAyB,GAAkC;CAC1E,OAAO,EAAuB;AAC/B;AAEA,SAAgB,EAAwB,GAA2B;CAClE,OAAO,EAAsB;AAC9B;AAEA,SAAgB,EAAgB,EAC/B,YACA,SACA,eACA,kBAAe,WACf,wBAAqB,aAOT;CAYZ,OAXI,KAAQ,IACJ;EACN,MAAM,KAAQ;EACd,YAAY,KAAc;CAC3B,IAGG,IACI,EAAiB,KAGlB;EACN,MAAM;EACN,YAAY;CACb;AACD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wheel-picker-FS58cRsQ.js","names":[],"sources":["../../src/wheel-picker/lib/wheelPickerMath.ts","../../src/wheel-picker/WheelPicker.module.scss","../../src/wheel-picker/WheelPicker.tsx"],"sourcesContent":["/**\n * Возвращает безопасный индекс внутри диапазона элементов wheel-picker.\n */\nexport function clampWheelIndex(index: number, itemsCount: number): number {\n\tif (itemsCount <= 0) return 0;\n\tif (index < 0) return 0;\n\tif (index > itemsCount - 1) return itemsCount - 1;\n\n\treturn index;\n}\n\n/**\n * Возвращает высоту viewport wheel-picker с учётом минимального значения.\n */\nexport function resolveWheelViewportHeight(measuredHeight: number, minHeight: number): number {\n\tif (!Number.isFinite(measuredHeight) || measuredHeight <= 0) return minHeight;\n\treturn Math.max(measuredHeight, minHeight);\n}\n\n/**\n * Возвращает высоту одной строки picker-а.\n */\nexport function resolveWheelItemHeight(viewportHeight: number, visibleRows: number): number {\n\tconst safeVisibleRows = Math.max(1, visibleRows);\n\treturn Math.max(1, Math.round(viewportHeight / safeVisibleRows));\n}\n\n/**\n * Возвращает отступы сверху и снизу, чтобы выбранное значение всегда было по центру.\n */\nexport function resolveWheelEdgePadding(viewportHeight: number, itemHeight: number): number {\n\treturn Math.max(0, Math.round(viewportHeight / 2 - itemHeight / 2));\n}\n\n/**\n * Возвращает scrollTop, при котором значение с данным индексом окажется в центре viewport.\n */\nexport function resolveWheelScrollTop(index: number, itemHeight: number): number {\n\treturn Math.max(0, Math.round(index * itemHeight));\n}\n\n/**\n * Возвращает ближайший индекс по текущему положению scrollTop.\n */\nexport function resolveClosestWheelIndex(scrollTop: number, itemHeight: number, itemsCount: number): number {\n\tif (itemsCount <= 0 || itemHeight <= 0) return 0;\n\treturn clampWheelIndex(Math.round(scrollTop / itemHeight), itemsCount);\n}\n","@use \"@/styles/mixins\" as *;\n\n.wheelPicker {\n\t--wheel-picker-min-height: 10em;\n\t--wheel-picker-viewport-height: var(--wheel-picker-min-height);\n\t--wheel-picker-item-height: calc(var(--wheel-picker-viewport-height) / 7);\n\t--wheel-picker-edge-padding: calc((var(--wheel-picker-viewport-height) / 2) - (var(--wheel-picker-item-height) / 2));\n\n\tposition: relative;\n\tmin-height: var(--wheel-picker-min-height);\n\theight: 100%;\n\tborder: var(--border);\n\tborder-radius: var(--radius-sm);\n\tbackground: linear-gradient(to bottom, var(--surface-0), transparent 18%, transparent 82%, var(--surface-0)), var(--surface-1);\n\toverflow: hidden;\n}\n\n.viewport {\n\tposition: relative;\n\theight: var(--wheel-picker-viewport-height);\n}\n\n.scroller {\n\theight: 100%;\n\toverflow-y: auto;\n\toverscroll-behavior: contain;\n\tscroll-snap-type: y mandatory;\n\tscrollbar-width: none;\n\tpadding-block: var(--wheel-picker-edge-padding);\n\toutline: none;\n\n\t&::-webkit-scrollbar {\n\t\tdisplay: none;\n\t}\n\n\t&:focus-visible {\n\t\t@include focusVisible;\n\t}\n}\n\n.items {\n\tdisplay: grid;\n}\n\n.item {\n\theight: var(--wheel-picker-item-height);\n\tpadding: 0 var(--space-sm);\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tscroll-snap-align: center;\n\tbackground: transparent;\n\tcolor: var(--content-2);\n\tfont-family: var(--font-family-mono);\n\tfont-variant-numeric: tabular-nums;\n\ttransition:\n\t\tcolor var(--transition-fast) ease,\n\t\tbackground-color var(--transition-fast) ease,\n\t\tfont-variation-settings var(--transition-fast) ease;\n\n\t&[data-selected] {\n\t\tcolor: var(--content-0);\n\t\tfont-weight: 600;\n\t\tfont-variation-settings: \"wght\" 600;\n\t}\n\n\t&:hover:not(:disabled) {\n\t\tbackground: color-mix(in srgb, var(--surface-accent) 40%, transparent);\n\t}\n\n\t&:disabled {\n\t\tcursor: default;\n\t}\n}\n\n.selectionFrame {\n\tposition: absolute;\n\ttop: 50%;\n\tleft: 0;\n\tright: 0;\n\theight: var(--wheel-picker-item-height);\n\ttransform: translateY(-50%);\n\tborder-top: var(--border);\n\tborder-bottom: var(--border);\n\t// border-radius: var(--radius-xs);\n\tbackground: color-mix(in srgb, var(--surface-accent) 28%, transparent);\n\tpointer-events: none;\n}\n","import type { CSSProperties, Key, KeyboardEvent, ReactNode } from \"react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport {\n\tclampWheelIndex,\n\tresolveClosestWheelIndex,\n\tresolveWheelEdgePadding,\n\tresolveWheelItemHeight,\n\tresolveWheelScrollTop,\n\tresolveWheelViewportHeight\n} from \"./lib/wheelPickerMath\";\nimport styles from \"./WheelPicker.module.scss\";\n\n/**\n * Пропсы внутреннего wheel-picker.\n */\nexport interface WheelPickerProps<T> {\n\titems: readonly T[];\n\tvalue: T;\n\tonChange: (value: T) => void;\n\tariaLabel: string;\n\tdisabled?: boolean;\n\tclassName?: string;\n\tminHeight?: number;\n\tvisibleRows?: number;\n\tformatItem?: (item: T) => ReactNode;\n\tgetItemKey?: (item: T, index: number) => Key;\n}\n\nconst DEFAULT_MIN_HEIGHT = 192;\nconst DEFAULT_VISIBLE_ROWS = 7;\nconst SNAP_TIMEOUT_MS = 96;\n\n/**\n * Внутренний wheel-picker со snap-кареткой по центру и блокировкой page scroll.\n */\nexport function WheelPicker<T>({\n\titems,\n\tvalue,\n\tonChange,\n\tariaLabel,\n\tdisabled,\n\tclassName,\n\tminHeight = DEFAULT_MIN_HEIGHT,\n\tvisibleRows = DEFAULT_VISIBLE_ROWS,\n\tformatItem,\n\tgetItemKey\n}: WheelPickerProps<T>) {\n\tconst rootRef = useRef<HTMLDivElement | null>(null);\n\tconst scrollerRef = useRef<HTMLDivElement | null>(null);\n\tconst snapTimeoutRef = useRef<number | null>(null);\n\tconst valueIndex = useMemo(\n\t\t() =>\n\t\t\tMath.max(\n\t\t\t\t0,\n\t\t\t\titems.findIndex((item) => Object.is(item, value))\n\t\t\t),\n\t\t[items, value]\n\t);\n\tconst [measuredHeight, setMeasuredHeight] = useState(0);\n\tconst viewportHeight = resolveWheelViewportHeight(measuredHeight, minHeight);\n\tconst itemHeight = resolveWheelItemHeight(viewportHeight, visibleRows);\n\tconst edgePadding = resolveWheelEdgePadding(viewportHeight, itemHeight);\n\tconst lastAppliedIndexRef = useRef(valueIndex);\n\n\t/**\n\t * Возвращает высоту контентной области wheel без рамок, чтобы избежать накопления высоты.\n\t */\n\tconst readContentHeight = useCallback((element: HTMLDivElement) => Math.round(element.clientHeight), []);\n\n\t/**\n\t * Доводит scroll до ближайшего центра и синхронизирует выбранное значение.\n\t */\n\tconst snapToClosestValue = useCallback(() => {\n\t\tconst scroller = scrollerRef.current;\n\t\tif (!scroller || items.length === 0) return;\n\n\t\tconst nextIndex = resolveClosestWheelIndex(scroller.scrollTop, itemHeight, items.length);\n\t\tscroller.scrollTo({\n\t\t\ttop: resolveWheelScrollTop(nextIndex, itemHeight),\n\t\t\tbehavior: \"smooth\"\n\t\t});\n\n\t\tif (nextIndex !== lastAppliedIndexRef.current) {\n\t\t\tlastAppliedIndexRef.current = nextIndex;\n\t\t\tonChange(items[nextIndex]);\n\t\t}\n\t}, [itemHeight, items, onChange]);\n\n\t/**\n\t * Планирует мягкую доводку wheel после завершения scroll/wheel.\n\t */\n\tconst scheduleSnap = useCallback(() => {\n\t\tif (snapTimeoutRef.current !== null) {\n\t\t\twindow.clearTimeout(snapTimeoutRef.current);\n\t\t}\n\n\t\tsnapTimeoutRef.current = window.setTimeout(() => {\n\t\t\tsnapTimeoutRef.current = null;\n\t\t\tsnapToClosestValue();\n\t\t}, SNAP_TIMEOUT_MS);\n\t}, [snapToClosestValue]);\n\n\tuseEffect(() => {\n\t\tconst root = rootRef.current;\n\t\tif (!root || typeof ResizeObserver === \"undefined\") return;\n\n\t\tconst syncMeasuredHeight = (nextHeight: number) => {\n\t\t\tsetMeasuredHeight((prevHeight) => (prevHeight === nextHeight ? prevHeight : nextHeight));\n\t\t};\n\n\t\tconst observer = new ResizeObserver((entries) => {\n\t\t\tconst entry = entries[0];\n\t\t\tconst nextHeight = Math.round(entry?.contentRect.height ?? readContentHeight(root));\n\n\t\t\tsyncMeasuredHeight(nextHeight);\n\t\t});\n\n\t\tobserver.observe(root);\n\t\tsyncMeasuredHeight(readContentHeight(root));\n\n\t\treturn () => observer.disconnect();\n\t}, [readContentHeight]);\n\n\tuseEffect(() => {\n\t\tconst scroller = scrollerRef.current;\n\t\tif (!scroller || items.length === 0) return;\n\n\t\tconst targetIndex = clampWheelIndex(valueIndex, items.length);\n\t\tlastAppliedIndexRef.current = targetIndex;\n\t\tscroller.scrollTo({\n\t\t\ttop: resolveWheelScrollTop(targetIndex, itemHeight),\n\t\t\tbehavior: \"auto\"\n\t\t});\n\t}, [itemHeight, items.length, valueIndex]);\n\n\tuseEffect(() => {\n\t\tconst scroller = scrollerRef.current;\n\t\tif (!scroller) return;\n\n\t\tconst handleScroll = () => {\n\t\t\tif (disabled) return;\n\t\t\tscheduleSnap();\n\t\t};\n\n\t\tconst handleWheel = (event: WheelEvent) => {\n\t\t\tif (disabled) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tscroller.scrollTop += event.deltaY;\n\t\t\tscheduleSnap();\n\t\t};\n\n\t\tscroller.addEventListener(\"scroll\", handleScroll, { passive: true });\n\t\tscroller.addEventListener(\"wheel\", handleWheel, { passive: false });\n\n\t\treturn () => {\n\t\t\tscroller.removeEventListener(\"scroll\", handleScroll);\n\t\t\tscroller.removeEventListener(\"wheel\", handleWheel);\n\t\t};\n\t}, [disabled, items, onChange, scheduleSnap]);\n\n\tuseEffect(() => {\n\t\treturn () => {\n\t\t\tif (snapTimeoutRef.current !== null) {\n\t\t\t\twindow.clearTimeout(snapTimeoutRef.current);\n\t\t\t}\n\t\t};\n\t}, []);\n\n\t/**\n\t * Меняет значение по стрелкам вверх и вниз.\n\t */\n\tconst handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n\t\tif (disabled || items.length === 0) return;\n\n\t\tif (event.key !== \"ArrowUp\" && event.key !== \"ArrowDown\") return;\n\t\tevent.preventDefault();\n\n\t\tconst delta = event.key === \"ArrowUp\" ? -1 : 1;\n\t\tconst nextIndex = clampWheelIndex(valueIndex + delta, items.length);\n\t\tif (nextIndex === valueIndex) return;\n\n\t\tlastAppliedIndexRef.current = nextIndex;\n\t\tonChange(items[nextIndex]);\n\t};\n\n\tconst cssVars = {\n\t\t\"--wheel-picker-min-height\": `${minHeight}px`,\n\t\t\"--wheel-picker-viewport-height\": `${viewportHeight}px`,\n\t\t\"--wheel-picker-item-height\": `${itemHeight}px`,\n\t\t\"--wheel-picker-edge-padding\": `${edgePadding}px`\n\t} as CSSProperties;\n\n\treturn (\n\t\t<div ref={rootRef} className={cn(styles.wheelPicker, className)} style={cssVars}>\n\t\t\t<div className={styles.viewport}>\n\t\t\t\t<div\n\t\t\t\t\tref={scrollerRef}\n\t\t\t\t\tclassName={styles.scroller}\n\t\t\t\t\trole=\"listbox\"\n\t\t\t\t\ttabIndex={disabled ? -1 : 0}\n\t\t\t\t\taria-label={ariaLabel}\n\t\t\t\t\taria-disabled={disabled || undefined}\n\t\t\t\t\tonKeyDown={handleKeyDown}>\n\t\t\t\t\t<div className={styles.items}>\n\t\t\t\t\t\t{items.map((item, index) => {\n\t\t\t\t\t\t\tconst selected = index === valueIndex;\n\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tkey={getItemKey?.(item, index) ?? index}\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\trole=\"option\"\n\t\t\t\t\t\t\t\t\taria-selected={selected}\n\t\t\t\t\t\t\t\t\tclassName={styles.item}\n\t\t\t\t\t\t\t\t\tdata-selected={selected ? \"\" : undefined}\n\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\tlastAppliedIndexRef.current = index;\n\t\t\t\t\t\t\t\t\t\tonChange(item);\n\t\t\t\t\t\t\t\t\t}}>\n\t\t\t\t\t\t\t\t\t{formatItem?.(item) ?? String(item)}\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div className={styles.selectionFrame} aria-hidden=\"true\" />\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"wheel-picker-FS58cRsQ.js","names":[],"sources":["../../src/wheel-picker/lib/wheelPickerMath.ts","../../src/wheel-picker/WheelPicker.module.scss","../../src/wheel-picker/WheelPicker.tsx"],"sourcesContent":["/**\n * Возвращает безопасный индекс внутри диапазона элементов wheel-picker.\n */\nexport function clampWheelIndex(index: number, itemsCount: number): number {\n\tif (itemsCount <= 0) return 0;\n\tif (index < 0) return 0;\n\tif (index > itemsCount - 1) return itemsCount - 1;\n\n\treturn index;\n}\n\n/**\n * Возвращает высоту viewport wheel-picker с учётом минимального значения.\n */\nexport function resolveWheelViewportHeight(measuredHeight: number, minHeight: number): number {\n\tif (!Number.isFinite(measuredHeight) || measuredHeight <= 0) return minHeight;\n\treturn Math.max(measuredHeight, minHeight);\n}\n\n/**\n * Возвращает высоту одной строки picker-а.\n */\nexport function resolveWheelItemHeight(viewportHeight: number, visibleRows: number): number {\n\tconst safeVisibleRows = Math.max(1, visibleRows);\n\treturn Math.max(1, Math.round(viewportHeight / safeVisibleRows));\n}\n\n/**\n * Возвращает отступы сверху и снизу, чтобы выбранное значение всегда было по центру.\n */\nexport function resolveWheelEdgePadding(viewportHeight: number, itemHeight: number): number {\n\treturn Math.max(0, Math.round(viewportHeight / 2 - itemHeight / 2));\n}\n\n/**\n * Возвращает scrollTop, при котором значение с данным индексом окажется в центре viewport.\n */\nexport function resolveWheelScrollTop(index: number, itemHeight: number): number {\n\treturn Math.max(0, Math.round(index * itemHeight));\n}\n\n/**\n * Возвращает ближайший индекс по текущему положению scrollTop.\n */\nexport function resolveClosestWheelIndex(scrollTop: number, itemHeight: number, itemsCount: number): number {\n\tif (itemsCount <= 0 || itemHeight <= 0) return 0;\n\treturn clampWheelIndex(Math.round(scrollTop / itemHeight), itemsCount);\n}\n","@use \"@/styles/mixins\" as *;\n\n.wheelPicker {\n\t--wheel-picker-min-height: 10em;\n\t--wheel-picker-viewport-height: var(--wheel-picker-min-height);\n\t--wheel-picker-item-height: calc(var(--wheel-picker-viewport-height) / 7);\n\t--wheel-picker-edge-padding: calc((var(--wheel-picker-viewport-height) / 2) - (var(--wheel-picker-item-height) / 2));\n\n\tposition: relative;\n\tmin-height: var(--wheel-picker-min-height);\n\theight: 100%;\n\tborder: var(--border);\n\tborder-radius: var(--radius-sm);\n\tbackground: linear-gradient(to bottom, var(--surface-0), transparent 18%, transparent 82%, var(--surface-0)), var(--surface-1);\n\toverflow: hidden;\n}\n\n.viewport {\n\tposition: relative;\n\theight: var(--wheel-picker-viewport-height);\n}\n\n.scroller {\n\theight: 100%;\n\toverflow-y: auto;\n\toverscroll-behavior: contain;\n\tscroll-snap-type: y mandatory;\n\tscrollbar-width: none;\n\tpadding-block: var(--wheel-picker-edge-padding);\n\toutline: none;\n\n\t&::-webkit-scrollbar {\n\t\tdisplay: none;\n\t}\n\n\t&:focus-visible {\n\t\t@include focusVisible;\n\t}\n}\n\n.items {\n\tdisplay: grid;\n}\n\n.item {\n\theight: var(--wheel-picker-item-height);\n\tpadding: 0 var(--space-sm);\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tscroll-snap-align: center;\n\tbackground: transparent;\n\tcolor: var(--content-2);\n\tfont-family: var(--font-family-mono);\n\tfont-variant-numeric: tabular-nums;\n\ttransition:\n\t\tcolor var(--transition-fast) ease,\n\t\tbackground-color var(--transition-fast) ease,\n\t\tfont-variation-settings var(--transition-fast) ease;\n\n\t&[data-selected] {\n\t\tcolor: var(--content-0);\n\t\tfont-weight: 600;\n\t\tfont-variation-settings: \"wght\" 600;\n\t}\n\n\t&:hover:not(:disabled) {\n\t\tbackground: color-mix(in srgb, var(--accent-fill) 40%, transparent);\n\t}\n\n\t&:disabled {\n\t\tcursor: default;\n\t}\n}\n\n.selectionFrame {\n\tposition: absolute;\n\ttop: 50%;\n\tleft: 0;\n\tright: 0;\n\theight: var(--wheel-picker-item-height);\n\ttransform: translateY(-50%);\n\tborder-top: var(--border);\n\tborder-bottom: var(--border);\n\t// border-radius: var(--radius-xs);\n\tbackground: color-mix(in srgb, var(--accent-fill) 28%, transparent);\n\tpointer-events: none;\n}\n","import type { CSSProperties, Key, KeyboardEvent, ReactNode } from \"react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport {\n\tclampWheelIndex,\n\tresolveClosestWheelIndex,\n\tresolveWheelEdgePadding,\n\tresolveWheelItemHeight,\n\tresolveWheelScrollTop,\n\tresolveWheelViewportHeight\n} from \"./lib/wheelPickerMath\";\nimport styles from \"./WheelPicker.module.scss\";\n\n/**\n * Пропсы внутреннего wheel-picker.\n */\nexport interface WheelPickerProps<T> {\n\titems: readonly T[];\n\tvalue: T;\n\tonChange: (value: T) => void;\n\tariaLabel: string;\n\tdisabled?: boolean;\n\tclassName?: string;\n\tminHeight?: number;\n\tvisibleRows?: number;\n\tformatItem?: (item: T) => ReactNode;\n\tgetItemKey?: (item: T, index: number) => Key;\n}\n\nconst DEFAULT_MIN_HEIGHT = 192;\nconst DEFAULT_VISIBLE_ROWS = 7;\nconst SNAP_TIMEOUT_MS = 96;\n\n/**\n * Внутренний wheel-picker со snap-кареткой по центру и блокировкой page scroll.\n */\nexport function WheelPicker<T>({\n\titems,\n\tvalue,\n\tonChange,\n\tariaLabel,\n\tdisabled,\n\tclassName,\n\tminHeight = DEFAULT_MIN_HEIGHT,\n\tvisibleRows = DEFAULT_VISIBLE_ROWS,\n\tformatItem,\n\tgetItemKey\n}: WheelPickerProps<T>) {\n\tconst rootRef = useRef<HTMLDivElement | null>(null);\n\tconst scrollerRef = useRef<HTMLDivElement | null>(null);\n\tconst snapTimeoutRef = useRef<number | null>(null);\n\tconst valueIndex = useMemo(\n\t\t() =>\n\t\t\tMath.max(\n\t\t\t\t0,\n\t\t\t\titems.findIndex((item) => Object.is(item, value))\n\t\t\t),\n\t\t[items, value]\n\t);\n\tconst [measuredHeight, setMeasuredHeight] = useState(0);\n\tconst viewportHeight = resolveWheelViewportHeight(measuredHeight, minHeight);\n\tconst itemHeight = resolveWheelItemHeight(viewportHeight, visibleRows);\n\tconst edgePadding = resolveWheelEdgePadding(viewportHeight, itemHeight);\n\tconst lastAppliedIndexRef = useRef(valueIndex);\n\n\t/**\n\t * Возвращает высоту контентной области wheel без рамок, чтобы избежать накопления высоты.\n\t */\n\tconst readContentHeight = useCallback((element: HTMLDivElement) => Math.round(element.clientHeight), []);\n\n\t/**\n\t * Доводит scroll до ближайшего центра и синхронизирует выбранное значение.\n\t */\n\tconst snapToClosestValue = useCallback(() => {\n\t\tconst scroller = scrollerRef.current;\n\t\tif (!scroller || items.length === 0) return;\n\n\t\tconst nextIndex = resolveClosestWheelIndex(scroller.scrollTop, itemHeight, items.length);\n\t\tscroller.scrollTo({\n\t\t\ttop: resolveWheelScrollTop(nextIndex, itemHeight),\n\t\t\tbehavior: \"smooth\"\n\t\t});\n\n\t\tif (nextIndex !== lastAppliedIndexRef.current) {\n\t\t\tlastAppliedIndexRef.current = nextIndex;\n\t\t\tonChange(items[nextIndex]);\n\t\t}\n\t}, [itemHeight, items, onChange]);\n\n\t/**\n\t * Планирует мягкую доводку wheel после завершения scroll/wheel.\n\t */\n\tconst scheduleSnap = useCallback(() => {\n\t\tif (snapTimeoutRef.current !== null) {\n\t\t\twindow.clearTimeout(snapTimeoutRef.current);\n\t\t}\n\n\t\tsnapTimeoutRef.current = window.setTimeout(() => {\n\t\t\tsnapTimeoutRef.current = null;\n\t\t\tsnapToClosestValue();\n\t\t}, SNAP_TIMEOUT_MS);\n\t}, [snapToClosestValue]);\n\n\tuseEffect(() => {\n\t\tconst root = rootRef.current;\n\t\tif (!root || typeof ResizeObserver === \"undefined\") return;\n\n\t\tconst syncMeasuredHeight = (nextHeight: number) => {\n\t\t\tsetMeasuredHeight((prevHeight) => (prevHeight === nextHeight ? prevHeight : nextHeight));\n\t\t};\n\n\t\tconst observer = new ResizeObserver((entries) => {\n\t\t\tconst entry = entries[0];\n\t\t\tconst nextHeight = Math.round(entry?.contentRect.height ?? readContentHeight(root));\n\n\t\t\tsyncMeasuredHeight(nextHeight);\n\t\t});\n\n\t\tobserver.observe(root);\n\t\tsyncMeasuredHeight(readContentHeight(root));\n\n\t\treturn () => observer.disconnect();\n\t}, [readContentHeight]);\n\n\tuseEffect(() => {\n\t\tconst scroller = scrollerRef.current;\n\t\tif (!scroller || items.length === 0) return;\n\n\t\tconst targetIndex = clampWheelIndex(valueIndex, items.length);\n\t\tlastAppliedIndexRef.current = targetIndex;\n\t\tscroller.scrollTo({\n\t\t\ttop: resolveWheelScrollTop(targetIndex, itemHeight),\n\t\t\tbehavior: \"auto\"\n\t\t});\n\t}, [itemHeight, items.length, valueIndex]);\n\n\tuseEffect(() => {\n\t\tconst scroller = scrollerRef.current;\n\t\tif (!scroller) return;\n\n\t\tconst handleScroll = () => {\n\t\t\tif (disabled) return;\n\t\t\tscheduleSnap();\n\t\t};\n\n\t\tconst handleWheel = (event: WheelEvent) => {\n\t\t\tif (disabled) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tscroller.scrollTop += event.deltaY;\n\t\t\tscheduleSnap();\n\t\t};\n\n\t\tscroller.addEventListener(\"scroll\", handleScroll, { passive: true });\n\t\tscroller.addEventListener(\"wheel\", handleWheel, { passive: false });\n\n\t\treturn () => {\n\t\t\tscroller.removeEventListener(\"scroll\", handleScroll);\n\t\t\tscroller.removeEventListener(\"wheel\", handleWheel);\n\t\t};\n\t}, [disabled, items, onChange, scheduleSnap]);\n\n\tuseEffect(() => {\n\t\treturn () => {\n\t\t\tif (snapTimeoutRef.current !== null) {\n\t\t\t\twindow.clearTimeout(snapTimeoutRef.current);\n\t\t\t}\n\t\t};\n\t}, []);\n\n\t/**\n\t * Меняет значение по стрелкам вверх и вниз.\n\t */\n\tconst handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n\t\tif (disabled || items.length === 0) return;\n\n\t\tif (event.key !== \"ArrowUp\" && event.key !== \"ArrowDown\") return;\n\t\tevent.preventDefault();\n\n\t\tconst delta = event.key === \"ArrowUp\" ? -1 : 1;\n\t\tconst nextIndex = clampWheelIndex(valueIndex + delta, items.length);\n\t\tif (nextIndex === valueIndex) return;\n\n\t\tlastAppliedIndexRef.current = nextIndex;\n\t\tonChange(items[nextIndex]);\n\t};\n\n\tconst cssVars = {\n\t\t\"--wheel-picker-min-height\": `${minHeight}px`,\n\t\t\"--wheel-picker-viewport-height\": `${viewportHeight}px`,\n\t\t\"--wheel-picker-item-height\": `${itemHeight}px`,\n\t\t\"--wheel-picker-edge-padding\": `${edgePadding}px`\n\t} as CSSProperties;\n\n\treturn (\n\t\t<div ref={rootRef} className={cn(styles.wheelPicker, className)} style={cssVars}>\n\t\t\t<div className={styles.viewport}>\n\t\t\t\t<div\n\t\t\t\t\tref={scrollerRef}\n\t\t\t\t\tclassName={styles.scroller}\n\t\t\t\t\trole=\"listbox\"\n\t\t\t\t\ttabIndex={disabled ? -1 : 0}\n\t\t\t\t\taria-label={ariaLabel}\n\t\t\t\t\taria-disabled={disabled || undefined}\n\t\t\t\t\tonKeyDown={handleKeyDown}>\n\t\t\t\t\t<div className={styles.items}>\n\t\t\t\t\t\t{items.map((item, index) => {\n\t\t\t\t\t\t\tconst selected = index === valueIndex;\n\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tkey={getItemKey?.(item, index) ?? index}\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\trole=\"option\"\n\t\t\t\t\t\t\t\t\taria-selected={selected}\n\t\t\t\t\t\t\t\t\tclassName={styles.item}\n\t\t\t\t\t\t\t\t\tdata-selected={selected ? \"\" : undefined}\n\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\tlastAppliedIndexRef.current = index;\n\t\t\t\t\t\t\t\t\t\tonChange(item);\n\t\t\t\t\t\t\t\t\t}}>\n\t\t\t\t\t\t\t\t\t{formatItem?.(item) ?? String(item)}\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div className={styles.selectionFrame} aria-hidden=\"true\" />\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as e, t } from "../chunks/context-menu-
|
|
1
|
+
import { n as e, t } from "../chunks/context-menu-DgvXGCuI.js";
|
|
2
2
|
export { e as ContextMenu, t as DropdownMenu };
|
package/dist/date-input/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as e, i as t, n, o as r, r as i, s as a, t as o } from "../chunks/CalendarView-
|
|
2
|
-
import { _ as s, a as c, b as l, c as u, d, f, g as p, h as m, i as h, l as g, m as _, n as v, o as y, p as b, r as x, s as S, t as C, u as w, v as T, y as E } from "../chunks/date-input-
|
|
1
|
+
import { a as e, i as t, n, o as r, r as i, s as a, t as o } from "../chunks/CalendarView-Dm55k0bN.js";
|
|
2
|
+
import { _ as s, a as c, b as l, c as u, d, f, g as p, h as m, i as h, l as g, m as _, n as v, o as y, p as b, r as x, s as S, t as C, u as w, v as T, y as E } from "../chunks/date-input-BwLOiGXp.js";
|
|
3
3
|
export { o as CalendarView, p as DATE_INPUT_SELECTION_MODES, s as DATE_INPUT_SELECTION_MODE_OPTIONS, n as DATE_INPUT_WEEK_END_DAYS, i as DATE_PICKER_LEVELS, x as DEFAULT_DATE_INPUT_FORMAT, h as DEFAULT_DATE_INPUT_PRESET, C as RangeDateInput, v as SingleDateInput, c as areRangeDateValuesEqual, y as areSingleDateValuesEqual, S as formatDateInputValue, u as formatRangeDateValue, g as formatSingleDateValue, t as getDatePickerLevelForSelectionMode, T as isDateInputSelectionMode, e as isDatePickerLevelAvailable, E as normalizeDateInputSelectionModes, w as normalizeRangeDateValue, d as normalizeRangeEndDateValue, f as normalizeSingleDateValue, b as parseRangeDateValue, _ as parseRangeEndDateValue, m as parseSingleDateValue, r as resolveAvailableDatePickerLevel, a as resolveDateInputPeriodRangeState, l as resolveDateInputSelectionModeOptionsByModes };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { r as e } from "../chunks/popover-Bne-Ljbs.js";
|
|
2
|
-
import { t } from "../chunks/ui.module-
|
|
3
|
-
import { c as n, d as r, i } from "../chunks/input-
|
|
4
|
-
import { t as a } from "../chunks/CalendarView-
|
|
2
|
+
import { t } from "../chunks/ui.module-oRwY3Zli.js";
|
|
3
|
+
import { c as n, d as r, i } from "../chunks/input-DSPKgiCK.js";
|
|
4
|
+
import { t as a } from "../chunks/CalendarView-Dm55k0bN.js";
|
|
5
5
|
import { t as o } from "../chunks/wheel-picker-FS58cRsQ.js";
|
|
6
6
|
import { useCallback as s, useMemo as c, useRef as l, useState as u } from "react";
|
|
7
7
|
import { cn as d } from "@ryuzaki13/react-foundation-lib/utils";
|
package/dist/dialog/index.js
CHANGED
|
@@ -1,50 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
4
|
-
import { createPortal as o } from "react-dom";
|
|
5
|
-
//#region src/dialog/Dialog.tsx
|
|
6
|
-
function s({ title: s, description: c, open: l, onClose: u, minWidth: d, children: f }) {
|
|
7
|
-
let p = e(), m = e(), h = r({
|
|
8
|
-
active: l,
|
|
9
|
-
trapFocus: !0,
|
|
10
|
-
restoreFocus: !0,
|
|
11
|
-
initialFocus: "auto"
|
|
12
|
-
});
|
|
13
|
-
if (n({
|
|
14
|
-
active: l,
|
|
15
|
-
onDismiss: u,
|
|
16
|
-
containerRef: h
|
|
17
|
-
}), !l || typeof document > "u") return null;
|
|
18
|
-
let g = t("dialog-root");
|
|
19
|
-
return g ? o(/* @__PURE__ */ i("div", {
|
|
20
|
-
className: "fixed inset0 flexCenter surfaceBackdrop",
|
|
21
|
-
style: { zIndex: "var(--z-dialog)" },
|
|
22
|
-
onMouseDown: (e) => e.target === e.currentTarget && u(),
|
|
23
|
-
children: /* @__PURE__ */ a("div", {
|
|
24
|
-
ref: h,
|
|
25
|
-
role: "dialog",
|
|
26
|
-
"aria-modal": "true",
|
|
27
|
-
"aria-labelledby": s ? p : void 0,
|
|
28
|
-
"aria-describedby": c ? m : void 0,
|
|
29
|
-
tabIndex: -1,
|
|
30
|
-
className: "surface0 shadowMd paddingLg radiusSm",
|
|
31
|
-
style: { minWidth: d },
|
|
32
|
-
children: [
|
|
33
|
-
s && /* @__PURE__ */ i("h2", {
|
|
34
|
-
id: p,
|
|
35
|
-
className: "margin0",
|
|
36
|
-
children: s
|
|
37
|
-
}),
|
|
38
|
-
c && /* @__PURE__ */ i("p", {
|
|
39
|
-
id: m,
|
|
40
|
-
children: c
|
|
41
|
-
}),
|
|
42
|
-
f
|
|
43
|
-
]
|
|
44
|
-
})
|
|
45
|
-
}), g) : null;
|
|
46
|
-
}
|
|
47
|
-
//#endregion
|
|
48
|
-
export { s as Dialog };
|
|
49
|
-
|
|
50
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
import { t as e } from "../chunks/dialog-Dqq8ZN99.js";
|
|
2
|
+
export { e as Dialog };
|
package/dist/disclosure/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as e } from "../chunks/ui.module-
|
|
2
|
-
import { n as t } from "../chunks/uiClasses-
|
|
1
|
+
import { t as e } from "../chunks/ui.module-oRwY3Zli.js";
|
|
2
|
+
import { n as t } from "../chunks/uiClasses-CQj47jkF.js";
|
|
3
3
|
import { t as n } from "../chunks/flex-C7njxZ74.js";
|
|
4
4
|
import { useId as r, useState as i } from "react";
|
|
5
5
|
import { cn as a } from "@ryuzaki13/react-foundation-lib/utils";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/disclosure/Disclosure.module.scss","../../src/disclosure/Disclosure.tsx","../../src/disclosure/DisclosureGroup.tsx"],"sourcesContent":[".disclosureHeader {\n\tdisplay: flex;\n\talign-items: center;\n}\n\n.disclosureButton {\n\t// flex: 1 1 auto;\n\tmin-width: 0;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: flex-start;\n\n\t&:hover {\n\t\tcolor: var(--
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/disclosure/Disclosure.module.scss","../../src/disclosure/Disclosure.tsx","../../src/disclosure/DisclosureGroup.tsx"],"sourcesContent":[".disclosureHeader {\n\tdisplay: flex;\n\talign-items: center;\n}\n\n.disclosureButton {\n\t// flex: 1 1 auto;\n\tmin-width: 0;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: flex-start;\n\n\t&:hover {\n\t\tcolor: var(--accent-text);\n\t}\n}\n\n.disclosureActions {\n\t// flex: 0 0 auto;\n\tdisplay: flex;\n\talign-items: center;\n\tpadding-inline-end: var(--space-sm);\n}\n\n.disclosureGroup {\n\t> .disclosure {\n\t\tborder-radius: 0;\n\n\t\t&:not(:first-child) {\n\t\t\tborder-top: none;\n\t\t}\n\n\t\t&:first-child {\n\t\t\tborder-top-left-radius: var(--radius-sm);\n\t\t\tborder-top-right-radius: var(--radius-sm);\n\t\t}\n\n\t\t&:last-child {\n\t\t\tborder-bottom-left-radius: var(--radius-sm);\n\t\t\tborder-bottom-right-radius: var(--radius-sm);\n\t\t}\n\t}\n}\n","import { type PropsWithChildren, type ReactNode, useId, useState } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { ChevronDownIcon, ChevronUpIcon } from \"lucide-react\";\n\nimport { FlexSpacer } from \"../flex\";\nimport { UiPanelTone } from \"../types\";\nimport uiStyles from \"../ui.module.scss\";\nimport { getUiPanelToneClassName } from \"../uiClasses\";\n\nimport styles from \"./Disclosure.module.scss\";\n\nexport interface DisclosureProps extends PropsWithChildren {\n\tlabel: ReactNode;\n\tdefaultOpen?: boolean;\n\ttone?: UiPanelTone;\n\t/** Независимые действия в правой части заголовка, расположенные вне кнопки раскрытия. */\n\theaderActions?: ReactNode;\n}\n\n/**\n * Раскрывающийся блок с заголовком и скрываемым содержимым. Используется для FAQ, настроек и компактного размещения второстепенной информации.\n */\nexport function Disclosure({ label, defaultOpen, headerActions, tone = \"primary\", children }: DisclosureProps) {\n\tconst [open, setOpen] = useState(defaultOpen === true);\n\tconst panelId = useId();\n\tconst buttonId = useId();\n\tconst panelTone = getUiPanelToneClassName(tone);\n\n\treturn (\n\t\t<div className={cn(uiStyles.uiElement, uiStyles.uiPanel, panelTone, styles.disclosure)}>\n\t\t\t<div className={styles.disclosureHeader}>\n\t\t\t\t<button\n\t\t\t\t\tid={buttonId}\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\taria-expanded={open}\n\t\t\t\t\taria-controls={panelId}\n\t\t\t\t\tclassName={cn(styles.disclosureButton, \"fontBold radiusSm paddingSm gapSm\")}\n\t\t\t\t\tdata-ui=\"disclosure-toggle\"\n\t\t\t\t\tdata-action={open ? \"collapse-disclosure\" : \"expand-disclosure\"}\n\t\t\t\t\tonClick={() => setOpen((prevOpen) => !prevOpen)}>\n\t\t\t\t\t{open ? <ChevronUpIcon /> : <ChevronDownIcon />}\n\t\t\t\t\t{label}\n\t\t\t\t</button>\n\t\t\t\t{headerActions ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<FlexSpacer />\n\t\t\t\t\t\t{headerActions}\n\t\t\t\t\t</>\n\t\t\t\t) : null}\n\t\t\t</div>\n\n\t\t\t{open && (\n\t\t\t\t<div id={panelId} role=\"region\" aria-labelledby={buttonId}>\n\t\t\t\t\t<div className=\"paddingMd\">{children}</div>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","import React from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { Disclosure, DisclosureProps } from \"./Disclosure\";\nimport styles from \"./Disclosure.module.scss\";\n\ninterface DisclosureGroupProps {\n\tchildren?:\n\t\t| (React.ReactElement<DisclosureProps, typeof Disclosure> | null | undefined | false)\n\t\t| (React.ReactElement<DisclosureProps, typeof Disclosure> | null | undefined | false)[];\n\tclassName?: string;\n}\n\n/**\n * Групповой контейнер для нескольких `Disclosure`. Помогает выстраивать последовательный список раскрывающихся секций.\n */\nexport function DisclosureGroup({ className, children }: DisclosureGroupProps) {\n\treturn <div className={cn(styles.disclosureGroup, className)}>{children}</div>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;ACuBA,SAAgB,EAAW,EAAE,UAAO,gBAAa,kBAAe,UAAO,WAAW,eAA6B;CAC9G,IAAM,CAAC,GAAM,KAAW,EAAS,MAAgB,EAAI,GAC/C,IAAU,EAAM,GAChB,IAAW,EAAM,GACjB,IAAY,EAAwB,CAAI;CAE9C,OACC,kBAAC,OAAD;EAAK,WAAW,EAAG,EAAS,WAAW,EAAS,SAAS,GAAW,EAAO,UAAU;EAArF,UAAA,CACC,kBAAC,OAAD;GAAK,WAAW,EAAO;GAAvB,UAAA,CACC,kBAAC,UAAD;IACC,IAAI;IACJ,MAAK;IACL,iBAAe;IACf,iBAAe;IACf,WAAW,EAAG,EAAO,kBAAkB,mCAAmC;IAC1E,WAAQ;IACR,eAAa,IAAO,wBAAwB;IAC5C,eAAe,GAAS,MAAa,CAAC,CAAQ;IAR/C,UAAA,CASS,EAAP,IAAQ,IAAoB,GAArB,CAAgB,CAAsB,GAC7C,CACM;GACP,CAAA,GAAA,IACA,kBAAA,GAAA,EAAA,UAAA,CACC,kBAAC,GAAD,CAAa,CAAA,GACZ,CACA,EAAA,CAAA,IACC,IACA;EAEJ,CAAA,GAAA,KACA,kBAAC,OAAD;GAAK,IAAI;GAAS,MAAK;GAAS,mBAAiB;GAChD,UAAA,kBAAC,OAAD;IAAK,WAAU;IAAa;GAAc,CAAA;EACtC,CAAA,CAEF;;AAEP;;;AC1CA,SAAgB,EAAgB,EAAE,cAAW,eAAkC;CAC9E,OAAO,kBAAC,OAAD;EAAK,WAAW,EAAG,EAAO,iBAAiB,CAAS;EAAI;CAAc,CAAA;AAC9E"}
|
package/dist/drop-zone/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as e } from "../chunks/input-files-
|
|
1
|
+
import { n as e } from "../chunks/input-files-tIS17-zX.js";
|
|
2
2
|
import { useCallback as t, useMemo as n, useRef as r, useState as i } from "react";
|
|
3
3
|
import { cn as a, handleKeyboardActivation as o } from "@ryuzaki13/react-foundation-lib/utils";
|
|
4
4
|
import { Fragment as s, jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/drop-zone/DropZone.module.scss","../../src/drop-zone/DropZone.tsx"],"sourcesContent":[".zone {\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: center;\n\tgap: var(--space-sm);\n\n\tmin-height: 8em;\n\tpadding: var(--space-lg);\n\n\tborder: var(--border-width) dashed var(--border-0);\n\tborder-radius: var(--radius-sm);\n\tbackground-color: var(--surface-0);\n\n\tcolor: var(--content-2);\n\tcursor: pointer;\n\n\ttransition-property: border-color, background-color;\n\ttransition-duration: var(--transition-fast);\n\n\t&.dragOver {\n\t\tborder-color: var(--content-accent);\n\t\tbackground-color: var(--surface-1);\n\t}\n\n\t&.disabled {\n\t\tcursor: default;\n\t\tpointer-events: none;\n\t\tbackground-color: var(--surface-2);\n\t\tborder-color: var(--overlay-backdrop);\n\n\t\t.icon,\n\t\t.hint {\n\t\t\topacity: 0.25;\n\t\t}\n\t}\n}\n\n.icon {\n\twidth: 2em;\n\theight: 2em;\n\tcolor: var(--content-2);\n}\n\n.hint {\n\ttext-align: center;\n}\n","import { ChangeEvent, ReactNode, useCallback, useMemo, useRef, useState } from \"react\";\n\nimport {\n\tassertValidAccept,\n\tassertValidAllowedMime,\n\treadFile,\n\tReadFileError,\n\tReadFileResult,\n\tReadMode\n} from \"@ryuzaki13/react-foundation-lib/file\";\nimport { cn, handleKeyboardActivation } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { UploadIcon } from \"lucide-react\";\n\nimport { InputFilesList } from \"../input-files\";\n\nimport styles from \"./DropZone.module.scss\";\n\n/**\n * Пропсы компонента DropZone.\n *\n * Компонент представляет собой визуальную зону для выбора файлов.\n * Поддерживает перетаскивание и выбор по клику, а результаты передаются в onDrop.\n */\nexport interface DropZoneProps {\n\tvalue: ReadFileResult[];\n\t/** Вызывается с массивом результатов readFile после сброса файлов */\n\tonChange: (results: ReadFileResult[]) => void;\n\t/** Callback ошибки чтения одного из файлов */\n\tonChangeError?: (error: ReadFileError) => void;\n\n\t/** HTML-атрибут accept для нативного input[type=\"file\"] (например `[\".pdf\", \".docx\"]`) */\n\taccept?: readonly string[];\n\t/** Список допустимых MIME-типов — передаётся в readFile (например `[\"application/pdf\", \"image/png\"]`) */\n\tallowedMime?: readonly string[];\n\t/** Максимальный размер одного файла в байтах */\n\tmaxBytes?: number;\n\t/** Режим чтения: \"data-url\" (по умолчанию) или \"array-buffer\" */\n\treadMode?: ReadMode;\n\t/** Разрешить сброс нескольких файлов (по умолчанию true) */\n\tmultiple?: boolean;\n\n\t/** Блокировка компонента */\n\tdisabled?: boolean;\n\t/** CSS-класс обёртки */\n\tclassName?: string;\n\t/**\n\t * Кастомный контент внутри зоны.\n\t * По умолчанию отображается иконка загрузки и текст \"Перетащите файлы сюда\".\n\t */\n\tchildren?: ReactNode;\n}\n\n/**\n * DropZone — зона для перетаскивания файлов и выбора по клику.\n *\n * При наведении файла зона подсвечивается (пунктирная рамка меняет цвет).\n * При сбросе файлов каждый читается через readFile, успешные результаты\n * передаются в onDrop, ошибки — в onDropError.\n *\n * Поддерживает кастомный контент через children.\n * Если children не указан — отображается иконка загрузки и подсказка.\n */\nexport function DropZone({\n\tvalue,\n\tonChange,\n\tonChangeError,\n\taccept,\n\tallowedMime,\n\tmaxBytes,\n\treadMode,\n\tmultiple = true,\n\tdisabled,\n\tclassName,\n\tchildren\n}: DropZoneProps) {\n\tassertValidAllowedMime(allowedMime);\n\tassertValidAccept(accept);\n\n\t/** Счётчик вложенности drag-событий для корректной обработки dragLeave */\n\tconst dragCounter = useRef(0);\n\t/** Скрытый input для выбора файлов по клику */\n\tconst inputRef = useRef<HTMLInputElement>(null);\n\t/** Состояние: файл перетаскивается над зоной */\n\tconst [isDragOver, setIsDragOver] = useState(false);\n\n\t/**\n\t * Формируем HTML-атрибут accept из accept или allowedMime.\n\t */\n\tconst acceptAttr = useMemo(() => {\n\t\tif (accept && accept.length > 0) {\n\t\t\treturn accept.join(\",\");\n\t\t}\n\t\tif (allowedMime && allowedMime.length > 0) {\n\t\t\treturn allowedMime.join(\",\");\n\t\t}\n\t\treturn \"*\";\n\t}, [allowedMime, accept]);\n\n\tconst readDroppedFile = useCallback(\n\t\t(file: File) => {\n\t\t\tif (readMode === \"array-buffer\") {\n\t\t\t\treturn readFile(file, { allowedMime, maxBytes, mode: \"array-buffer\" });\n\t\t\t}\n\n\t\t\treturn readFile(file, { allowedMime, maxBytes });\n\t\t},\n\t\t[allowedMime, maxBytes, readMode]\n\t);\n\n\tconst processFiles = useCallback(\n\t\tasync (files: File[]) => {\n\t\t\tif (disabled || files.length === 0) return;\n\n\t\t\tconst filesToProcess = multiple ? files : files.slice(0, 1);\n\t\t\tconst results: ReadFileResult[] = [];\n\n\t\t\tfor (const file of filesToProcess) {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await readDroppedFile(file);\n\t\t\t\t\tresults.push(result);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (err instanceof ReadFileError && onChangeError) {\n\t\t\t\t\t\tonChangeError(err);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (results.length > 0) {\n\t\t\t\tonChange(results);\n\t\t\t}\n\t\t},\n\t\t[disabled, multiple, onChange, onChangeError, readDroppedFile]\n\t);\n\n\tconst openFileDialog = useCallback(() => {\n\t\tif (disabled) return;\n\n\t\tinputRef.current?.click();\n\t}, [disabled]);\n\n\t/**\n\t * Обработка dragEnter — увеличиваем счётчик и включаем подсветку.\n\t * Счётчик нужен потому что dragEnter/dragLeave срабатывают\n\t * на каждом дочернем элементе внутри зоны.\n\t */\n\tconst handleDragEnter = useCallback(\n\t\t(e: React.DragEvent) => {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\tif (disabled) return;\n\n\t\t\tdragCounter.current += 1;\n\t\t\tif (dragCounter.current === 1) {\n\t\t\t\tsetIsDragOver(true);\n\t\t\t}\n\t\t},\n\t\t[disabled]\n\t);\n\n\t/**\n\t * Обработка dragOver — предотвращаем дефолтное поведение браузера\n\t * (иначе drop-событие не сработает).\n\t */\n\tconst handleDragOver = useCallback(\n\t\t(e: React.DragEvent) => {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\tif (disabled) return;\n\n\t\t\te.dataTransfer.dropEffect = \"copy\";\n\t\t},\n\t\t[disabled]\n\t);\n\n\t/**\n\t * Обработка dragLeave — уменьшаем счётчик, выключаем подсветку при 0.\n\t */\n\tconst handleDragLeave = useCallback(\n\t\t(e: React.DragEvent) => {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\tif (disabled) return;\n\n\t\t\tdragCounter.current -= 1;\n\t\t\tif (dragCounter.current === 0) {\n\t\t\t\tsetIsDragOver(false);\n\t\t\t}\n\t\t},\n\t\t[disabled]\n\t);\n\n\t/**\n\t * Обработка drop — читаем сброшенные файлы через общую логику.\n\t */\n\tconst handleDrop = useCallback(\n\t\tasync (e: React.DragEvent) => {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\n\t\t\t// Сбрасываем состояние drag\n\t\t\tdragCounter.current = 0;\n\t\t\tsetIsDragOver(false);\n\n\t\t\tif (disabled) return;\n\n\t\t\tconst droppedFiles = Array.from(e.dataTransfer.files);\n\t\t\tawait processFiles(droppedFiles);\n\t\t},\n\t\t[disabled, processFiles]\n\t);\n\n\tconst handleInputChange = useCallback(\n\t\tasync (e: ChangeEvent<HTMLInputElement>) => {\n\t\t\tconst selectedFiles = Array.from(e.target.files ?? []);\n\t\t\tawait processFiles(selectedFiles);\n\n\t\t\t// Сбрасываем значение, чтобы повторный выбор того же файла тоже вызывал change.\n\t\t\te.target.value = \"\";\n\t\t},\n\t\t[processFiles]\n\t);\n\n\tconst handleKeyDown = useCallback(\n\t\t(e: React.KeyboardEvent<HTMLDivElement>) => {\n\t\t\thandleKeyboardActivation(e, openFileDialog, { disabled });\n\t\t},\n\t\t[disabled, openFileDialog]\n\t);\n\n\treturn (\n\t\t<div>\n\t\t\t<input\n\t\t\t\tref={inputRef}\n\t\t\t\ttype=\"file\"\n\t\t\t\thidden\n\t\t\t\tdisabled={disabled}\n\t\t\t\tmultiple={multiple}\n\t\t\t\taccept={acceptAttr}\n\t\t\t\tonChange={handleInputChange}\n\t\t\t/>\n\t\t\t<div\n\t\t\t\tclassName={cn(styles.zone, isDragOver && styles.dragOver, disabled && styles.disabled, className)}\n\t\t\t\tonClick={openFileDialog}\n\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\tonDragEnter={handleDragEnter}\n\t\t\t\tonDragOver={handleDragOver}\n\t\t\t\tonDragLeave={handleDragLeave}\n\t\t\t\tonDrop={handleDrop}\n\t\t\t\trole=\"button\"\n\t\t\t\ttabIndex={disabled ? -1 : 0}\n\t\t\t\taria-disabled={disabled}>\n\t\t\t\t{children ?? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t{/* Иконка загрузки по умолчанию */}\n\t\t\t\t\t\t<UploadIcon className={styles.icon} />\n\t\t\t\t\t\t{/* Текст подсказки */}\n\t\t\t\t\t\t<span className={styles.hint}>\n\t\t\t\t\t\t\t{multiple ? \"Перетащите файлы сюда или нажмите для выбора\" : \"Перетащите файл сюда или нажмите для выбора\"}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</div>\n\n\t\t\t{/* Список выбранных файлов */}\n\t\t\t<InputFilesList files={value} onChange={onChange} />\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/drop-zone/DropZone.module.scss","../../src/drop-zone/DropZone.tsx"],"sourcesContent":[".zone {\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: center;\n\tgap: var(--space-sm);\n\n\tmin-height: 8em;\n\tpadding: var(--space-lg);\n\n\tborder: var(--border-width) dashed var(--border-0);\n\tborder-radius: var(--radius-sm);\n\tbackground-color: var(--surface-0);\n\n\tcolor: var(--content-2);\n\tcursor: pointer;\n\n\ttransition-property: border-color, background-color;\n\ttransition-duration: var(--transition-fast);\n\n\t&.dragOver {\n\t\tborder-color: var(--accent-text);\n\t\tbackground-color: var(--surface-1);\n\t}\n\n\t&.disabled {\n\t\tcursor: default;\n\t\tpointer-events: none;\n\t\tbackground-color: var(--surface-2);\n\t\tborder-color: var(--overlay-backdrop);\n\n\t\t.icon,\n\t\t.hint {\n\t\t\topacity: 0.25;\n\t\t}\n\t}\n}\n\n.icon {\n\twidth: 2em;\n\theight: 2em;\n\tcolor: var(--content-2);\n}\n\n.hint {\n\ttext-align: center;\n}\n","import { ChangeEvent, ReactNode, useCallback, useMemo, useRef, useState } from \"react\";\n\nimport {\n\tassertValidAccept,\n\tassertValidAllowedMime,\n\treadFile,\n\tReadFileError,\n\tReadFileResult,\n\tReadMode\n} from \"@ryuzaki13/react-foundation-lib/file\";\nimport { cn, handleKeyboardActivation } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { UploadIcon } from \"lucide-react\";\n\nimport { InputFilesList } from \"../input-files\";\n\nimport styles from \"./DropZone.module.scss\";\n\n/**\n * Пропсы компонента DropZone.\n *\n * Компонент представляет собой визуальную зону для выбора файлов.\n * Поддерживает перетаскивание и выбор по клику, а результаты передаются в onDrop.\n */\nexport interface DropZoneProps {\n\tvalue: ReadFileResult[];\n\t/** Вызывается с массивом результатов readFile после сброса файлов */\n\tonChange: (results: ReadFileResult[]) => void;\n\t/** Callback ошибки чтения одного из файлов */\n\tonChangeError?: (error: ReadFileError) => void;\n\n\t/** HTML-атрибут accept для нативного input[type=\"file\"] (например `[\".pdf\", \".docx\"]`) */\n\taccept?: readonly string[];\n\t/** Список допустимых MIME-типов — передаётся в readFile (например `[\"application/pdf\", \"image/png\"]`) */\n\tallowedMime?: readonly string[];\n\t/** Максимальный размер одного файла в байтах */\n\tmaxBytes?: number;\n\t/** Режим чтения: \"data-url\" (по умолчанию) или \"array-buffer\" */\n\treadMode?: ReadMode;\n\t/** Разрешить сброс нескольких файлов (по умолчанию true) */\n\tmultiple?: boolean;\n\n\t/** Блокировка компонента */\n\tdisabled?: boolean;\n\t/** CSS-класс обёртки */\n\tclassName?: string;\n\t/**\n\t * Кастомный контент внутри зоны.\n\t * По умолчанию отображается иконка загрузки и текст \"Перетащите файлы сюда\".\n\t */\n\tchildren?: ReactNode;\n}\n\n/**\n * DropZone — зона для перетаскивания файлов и выбора по клику.\n *\n * При наведении файла зона подсвечивается (пунктирная рамка меняет цвет).\n * При сбросе файлов каждый читается через readFile, успешные результаты\n * передаются в onDrop, ошибки — в onDropError.\n *\n * Поддерживает кастомный контент через children.\n * Если children не указан — отображается иконка загрузки и подсказка.\n */\nexport function DropZone({\n\tvalue,\n\tonChange,\n\tonChangeError,\n\taccept,\n\tallowedMime,\n\tmaxBytes,\n\treadMode,\n\tmultiple = true,\n\tdisabled,\n\tclassName,\n\tchildren\n}: DropZoneProps) {\n\tassertValidAllowedMime(allowedMime);\n\tassertValidAccept(accept);\n\n\t/** Счётчик вложенности drag-событий для корректной обработки dragLeave */\n\tconst dragCounter = useRef(0);\n\t/** Скрытый input для выбора файлов по клику */\n\tconst inputRef = useRef<HTMLInputElement>(null);\n\t/** Состояние: файл перетаскивается над зоной */\n\tconst [isDragOver, setIsDragOver] = useState(false);\n\n\t/**\n\t * Формируем HTML-атрибут accept из accept или allowedMime.\n\t */\n\tconst acceptAttr = useMemo(() => {\n\t\tif (accept && accept.length > 0) {\n\t\t\treturn accept.join(\",\");\n\t\t}\n\t\tif (allowedMime && allowedMime.length > 0) {\n\t\t\treturn allowedMime.join(\",\");\n\t\t}\n\t\treturn \"*\";\n\t}, [allowedMime, accept]);\n\n\tconst readDroppedFile = useCallback(\n\t\t(file: File) => {\n\t\t\tif (readMode === \"array-buffer\") {\n\t\t\t\treturn readFile(file, { allowedMime, maxBytes, mode: \"array-buffer\" });\n\t\t\t}\n\n\t\t\treturn readFile(file, { allowedMime, maxBytes });\n\t\t},\n\t\t[allowedMime, maxBytes, readMode]\n\t);\n\n\tconst processFiles = useCallback(\n\t\tasync (files: File[]) => {\n\t\t\tif (disabled || files.length === 0) return;\n\n\t\t\tconst filesToProcess = multiple ? files : files.slice(0, 1);\n\t\t\tconst results: ReadFileResult[] = [];\n\n\t\t\tfor (const file of filesToProcess) {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await readDroppedFile(file);\n\t\t\t\t\tresults.push(result);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (err instanceof ReadFileError && onChangeError) {\n\t\t\t\t\t\tonChangeError(err);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (results.length > 0) {\n\t\t\t\tonChange(results);\n\t\t\t}\n\t\t},\n\t\t[disabled, multiple, onChange, onChangeError, readDroppedFile]\n\t);\n\n\tconst openFileDialog = useCallback(() => {\n\t\tif (disabled) return;\n\n\t\tinputRef.current?.click();\n\t}, [disabled]);\n\n\t/**\n\t * Обработка dragEnter — увеличиваем счётчик и включаем подсветку.\n\t * Счётчик нужен потому что dragEnter/dragLeave срабатывают\n\t * на каждом дочернем элементе внутри зоны.\n\t */\n\tconst handleDragEnter = useCallback(\n\t\t(e: React.DragEvent) => {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\tif (disabled) return;\n\n\t\t\tdragCounter.current += 1;\n\t\t\tif (dragCounter.current === 1) {\n\t\t\t\tsetIsDragOver(true);\n\t\t\t}\n\t\t},\n\t\t[disabled]\n\t);\n\n\t/**\n\t * Обработка dragOver — предотвращаем дефолтное поведение браузера\n\t * (иначе drop-событие не сработает).\n\t */\n\tconst handleDragOver = useCallback(\n\t\t(e: React.DragEvent) => {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\tif (disabled) return;\n\n\t\t\te.dataTransfer.dropEffect = \"copy\";\n\t\t},\n\t\t[disabled]\n\t);\n\n\t/**\n\t * Обработка dragLeave — уменьшаем счётчик, выключаем подсветку при 0.\n\t */\n\tconst handleDragLeave = useCallback(\n\t\t(e: React.DragEvent) => {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\t\t\tif (disabled) return;\n\n\t\t\tdragCounter.current -= 1;\n\t\t\tif (dragCounter.current === 0) {\n\t\t\t\tsetIsDragOver(false);\n\t\t\t}\n\t\t},\n\t\t[disabled]\n\t);\n\n\t/**\n\t * Обработка drop — читаем сброшенные файлы через общую логику.\n\t */\n\tconst handleDrop = useCallback(\n\t\tasync (e: React.DragEvent) => {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\n\t\t\t// Сбрасываем состояние drag\n\t\t\tdragCounter.current = 0;\n\t\t\tsetIsDragOver(false);\n\n\t\t\tif (disabled) return;\n\n\t\t\tconst droppedFiles = Array.from(e.dataTransfer.files);\n\t\t\tawait processFiles(droppedFiles);\n\t\t},\n\t\t[disabled, processFiles]\n\t);\n\n\tconst handleInputChange = useCallback(\n\t\tasync (e: ChangeEvent<HTMLInputElement>) => {\n\t\t\tconst selectedFiles = Array.from(e.target.files ?? []);\n\t\t\tawait processFiles(selectedFiles);\n\n\t\t\t// Сбрасываем значение, чтобы повторный выбор того же файла тоже вызывал change.\n\t\t\te.target.value = \"\";\n\t\t},\n\t\t[processFiles]\n\t);\n\n\tconst handleKeyDown = useCallback(\n\t\t(e: React.KeyboardEvent<HTMLDivElement>) => {\n\t\t\thandleKeyboardActivation(e, openFileDialog, { disabled });\n\t\t},\n\t\t[disabled, openFileDialog]\n\t);\n\n\treturn (\n\t\t<div>\n\t\t\t<input\n\t\t\t\tref={inputRef}\n\t\t\t\ttype=\"file\"\n\t\t\t\thidden\n\t\t\t\tdisabled={disabled}\n\t\t\t\tmultiple={multiple}\n\t\t\t\taccept={acceptAttr}\n\t\t\t\tonChange={handleInputChange}\n\t\t\t/>\n\t\t\t<div\n\t\t\t\tclassName={cn(styles.zone, isDragOver && styles.dragOver, disabled && styles.disabled, className)}\n\t\t\t\tonClick={openFileDialog}\n\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\tonDragEnter={handleDragEnter}\n\t\t\t\tonDragOver={handleDragOver}\n\t\t\t\tonDragLeave={handleDragLeave}\n\t\t\t\tonDrop={handleDrop}\n\t\t\t\trole=\"button\"\n\t\t\t\ttabIndex={disabled ? -1 : 0}\n\t\t\t\taria-disabled={disabled}>\n\t\t\t\t{children ?? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t{/* Иконка загрузки по умолчанию */}\n\t\t\t\t\t\t<UploadIcon className={styles.icon} />\n\t\t\t\t\t\t{/* Текст подсказки */}\n\t\t\t\t\t\t<span className={styles.hint}>\n\t\t\t\t\t\t\t{multiple ? \"Перетащите файлы сюда или нажмите для выбора\" : \"Перетащите файл сюда или нажмите для выбора\"}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</div>\n\n\t\t\t{/* Список выбранных файлов */}\n\t\t\t<InputFilesList files={value} onChange={onChange} />\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
|