@ryuzaki13/react-foundation-ui 1.8.11 → 1.8.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/defaultRenderers-u_Vep6Pj.js.map +1 -1
- package/dist/chunks/multi-select-DtmRtX6v.js.map +1 -1
- package/dist/chunks/select-MN6zDPKM.js.map +1 -1
- package/dist/chunks/useODataSelectBase-DR4PrY1j.js.map +1 -1
- package/dist/multi-select/model/useODataMultiSelect.d.ts +1 -1
- package/dist/multi-select/model/useODataMultiSelect.d.ts.map +1 -1
- package/dist/multi-select/ui/MultiSelect.d.ts +1 -1
- package/dist/multi-select/ui/MultiSelect.d.ts.map +1 -1
- package/dist/multi-select/ui/SerializableMultiSelect.d.ts.map +1 -1
- package/dist/multi-select/ui/defaultRenderers.d.ts +1 -1
- package/dist/multi-select/ui/defaultRenderers.d.ts.map +1 -1
- package/dist/select/model/useODataSelect.d.ts +1 -1
- package/dist/select/model/useODataSelect.d.ts.map +1 -1
- package/dist/select/model/useODataSelectBase.d.ts +1 -1
- package/dist/select/model/useODataSelectBase.d.ts.map +1 -1
- package/dist/tree-select/index.js.map +1 -1
- package/dist/tree-select/model/buildODataTreeNodes.d.ts +1 -1
- package/dist/tree-select/model/buildODataTreeNodes.d.ts.map +1 -1
- package/package.json +3 -3
- package/storybook-static/assets/{Badge-BojMuOws.js → Badge-CveIo2LZ.js} +1 -1
- package/storybook-static/assets/{Badge.stories-C9gJRuIO.js → Badge.stories-Bd8M64xJ.js} +1 -1
- package/storybook-static/assets/{BadgeList-dNEWI7-O.js → BadgeList-xT41a0VL.js} +1 -1
- package/storybook-static/assets/{Button-Bbt3JzIY.js → Button-C5bBSb3k.js} +1 -1
- package/storybook-static/assets/{Button-CrTHXWYk.js → Button-DkDgfpHL.js} +1 -1
- package/storybook-static/assets/{Button.stories-BaYXOBeF.js → Button.stories-CeKPeGK5.js} +1 -1
- package/storybook-static/assets/{CalendarView-Dp0zus1o.js → CalendarView-CEqcrblx.js} +1 -1
- package/storybook-static/assets/{CheckBox-BiK9yWNt.js → CheckBox-DKeFkdOt.js} +1 -1
- package/storybook-static/assets/{CheckBox-UzYHaD6S.js → CheckBox-OVvAarW-.js} +1 -1
- package/storybook-static/assets/{CheckBox.stories-C2BOiWZj.js → CheckBox.stories-CfZ0p1yo.js} +1 -1
- package/storybook-static/assets/{Color-6AOWCN3U-C5S4wUlD.js → Color-6AOWCN3U-BWW7zrfs.js} +1 -1
- package/storybook-static/assets/{ContextMenu-BWQln_tb.js → ContextMenu-kia7is1N.js} +1 -1
- package/storybook-static/assets/{ContextMenu-D9EZxb7d.js → ContextMenu-xn2GtiLR.js} +1 -1
- package/storybook-static/assets/{ContextMenu.stories-U38zPh9_.js → ContextMenu.stories-CYuy9uXF.js} +1 -1
- package/storybook-static/assets/{CustomOptionButton-COIOrxQn.js → CustomOptionButton-C4w-APws.js} +1 -1
- package/storybook-static/assets/DateInput-BiUFIihm.js +1 -0
- package/storybook-static/assets/{DateInput-C-entb-r.js → DateInput-DAzE5mCE.js} +1 -1
- package/storybook-static/assets/{DateInput.stories-NmUXQLDU.js → DateInput.stories-BcowGCRD.js} +1 -1
- package/storybook-static/assets/{DateRangePresetSelect-BM1L1KOo.js → DateRangePresetSelect-CQm4dNLR.js} +1 -1
- package/storybook-static/assets/{DateRangePresetSelect-CAJzxaq0.js → DateRangePresetSelect-RIyqNBk9.js} +1 -1
- package/storybook-static/assets/{DateRangePresetSelect.stories-CC47XLnD.js → DateRangePresetSelect.stories-ypGyuGfy.js} +1 -1
- package/storybook-static/assets/{Detail-CDluXtts.js → Detail-CEypL2Nh.js} +1 -1
- package/storybook-static/assets/{Detail.stories-DjniLC4n.js → Detail.stories-DNkT7B-u.js} +1 -1
- package/storybook-static/assets/{Dialog-bzRSgGU7.js → Dialog-BVFFQJDH.js} +1 -1
- package/storybook-static/assets/{Dialog-bw6cHUsz.js → Dialog-DD0grLG3.js} +1 -1
- package/storybook-static/assets/{Dialog.stories-C6Rs6s_p.js → Dialog.stories-DSCypHqR.js} +1 -1
- package/storybook-static/assets/{Disclosure-DelA6FsQ.js → Disclosure-DauUgrev.js} +1 -1
- package/storybook-static/assets/{Disclosure.stories-D7yUinyb.js → Disclosure.stories-B1qB8vQZ.js} +1 -1
- package/storybook-static/assets/{DisclosureGroup-DbK7mU_Q.js → DisclosureGroup-D9oCCeHf.js} +1 -1
- package/storybook-static/assets/{DocsRenderer-JROSPFPF-v3z0zVN1.js → DocsRenderer-JROSPFPF-CmSf6tXp.js} +1 -1
- package/storybook-static/assets/{DropZone-Cyy-ttEO.js → DropZone-D42ueN1w.js} +1 -1
- package/storybook-static/assets/{DropZone-CI3NW4AC.js → DropZone-D8hbPCAv.js} +1 -1
- package/storybook-static/assets/{DropZone.stories-S0HSpGTB.js → DropZone.stories-DO-T_Bh4.js} +1 -1
- package/storybook-static/assets/{DropdownMenu-Ct1bSZsE.js → DropdownMenu-CknJDoji.js} +1 -1
- package/storybook-static/assets/{ExpandableActionPanel-Oj3xlasj.js → ExpandableActionPanel-Dqi_bo3c.js} +1 -1
- package/storybook-static/assets/{ExpandableActionPanel.stories-Ch7CLkpR.js → ExpandableActionPanel.stories-BD9QZGZN.js} +1 -1
- package/storybook-static/assets/{Flex-UiFm8Tkc.js → Flex-CaVn1IOP.js} +1 -1
- package/storybook-static/assets/{Flex.stories-CaDiVlBD.js → Flex.stories-Bp9Y6q6b.js} +1 -1
- package/storybook-static/assets/{FloatingPopover-CTYV9W7T.js → FloatingPopover-U7tx-Jlw.js} +1 -1
- package/storybook-static/assets/{FormattedTableCell-D-ysSR3p.js → FormattedTableCell-pmmhsAbN.js} +1 -1
- package/storybook-static/assets/{Grid-CigBXPe2.js → Grid-CEpMNurH.js} +1 -1
- package/storybook-static/assets/{Grid.stories-ay3z9DQZ.js → Grid.stories-BM-gO5DN.js} +1 -1
- package/storybook-static/assets/{ImageCropper.stories-Dkce_ugb.js → ImageCropper.stories-BWz5XU6U.js} +1 -1
- package/storybook-static/assets/{ImageRenderer-C9_EmGBW.js → ImageRenderer-BTYZEX5t.js} +1 -1
- package/storybook-static/assets/{ImageRenderer.stories-C7bXaNBI.js → ImageRenderer.stories-Dz2STM95.js} +1 -1
- package/storybook-static/assets/{ImageView.stories-D-ZzGlk8.js → ImageView.stories-DBVe0an3.js} +1 -1
- package/storybook-static/assets/{ImageViewer.stories-ItcRfxyy.js → ImageViewer.stories-C4Px97lD.js} +2 -2
- package/storybook-static/assets/{ImageViewerRuntime-eaupID36.js → ImageViewerRuntime-TJtlJVfa.js} +1 -1
- package/storybook-static/assets/{Input-op4j7Beh.js → Input-CIPgijvW.js} +1 -1
- package/storybook-static/assets/{Input-BUDNR96c.js → Input-D8io9jVS.js} +1 -1
- package/storybook-static/assets/{Input.stories-DwulvJIg.js → Input.stories-SUk3aYaC.js} +1 -1
- package/storybook-static/assets/{InputDateTime-B_cxOp6k.js → InputDateTime-DA5pIDuE.js} +1 -1
- package/storybook-static/assets/{InputDateTime.stories-BueLF4HC.js → InputDateTime.stories-DeudzDSU.js} +1 -1
- package/storybook-static/assets/{InputFile-C8z6TPc1.js → InputFile-C5mp5Y5I.js} +1 -1
- package/storybook-static/assets/{InputFile-DSg7sugm.js → InputFile-CGAC7ruP.js} +1 -1
- package/storybook-static/assets/{InputFile.stories-C6XSbIua.js → InputFile.stories-Cx1xQ6PE.js} +1 -1
- package/storybook-static/assets/{InputFiles-DoatLq3q.js → InputFiles-B7OBcPJN.js} +1 -1
- package/storybook-static/assets/{InputFiles-DeZ84Uu_.js → InputFiles-Hzl89Ghf.js} +1 -1
- package/storybook-static/assets/{InputFiles.stories-BMbE8SJU.js → InputFiles.stories-CG6QjDZH.js} +1 -1
- package/storybook-static/assets/{InputFilesList-CsfDDqaJ.js → InputFilesList-B6htWHF1.js} +1 -1
- package/storybook-static/assets/{InputImage-yJSq98EH.js → InputImage-BTa4S4Wp.js} +1 -1
- package/storybook-static/assets/{InputImage-D_YnB2Tw.js → InputImage-CQnoblAE.js} +1 -1
- package/storybook-static/assets/{InputImage.stories-nivUG307.js → InputImage.stories-CEI44Eyz.js} +1 -1
- package/storybook-static/assets/{InteractiveComponents-IPkC_Rkg.js → InteractiveComponents-B0ypWz1x.js} +1 -1
- package/storybook-static/assets/{InteractiveComponents.stories-D4VzVKZJ.js → InteractiveComponents.stories-BadApta9.js} +1 -1
- package/storybook-static/assets/{LayoutPicker-aMzPN5Do.js → LayoutPicker-COB9GlV_.js} +1 -1
- package/storybook-static/assets/{LayoutPicker-ZHkMi-LM.js → LayoutPicker-C_Uz7Tnj.js} +1 -1
- package/storybook-static/assets/{LayoutPicker.stories-DAzpzxn5.js → LayoutPicker.stories-Btp0IcaL.js} +1 -1
- package/storybook-static/assets/{Listbox-CR5nXC9J.js → Listbox-AAaZGSAl.js} +1 -1
- package/storybook-static/assets/{Listbox-BmfQOnrb.js → Listbox-CyfuZw7w.js} +1 -1
- package/storybook-static/assets/{Listbox.stories-CeOpsKxB.js → Listbox.stories-NDKQmjyQ.js} +1 -1
- package/storybook-static/assets/{Modal-BStp52Zo.js → Modal-BJDnJ4zv.js} +1 -1
- package/storybook-static/assets/{Modal.stories-CwGm5GYE.js → Modal.stories-D_X5lTLO.js} +1 -1
- package/storybook-static/assets/{ModalManagerProvider-B5uUXWF9.js → ModalManagerProvider-ShDjozpW.js} +1 -1
- package/storybook-static/assets/{MultiSelect-BDs02MZh.js → MultiSelect-B5CElQ3-.js} +1 -1
- package/storybook-static/assets/{MultiSelect-308npb27.js → MultiSelect-DqXfrjcH.js} +1 -1
- package/storybook-static/assets/{MultiSelect.stories-DRi_iTp4.js → MultiSelect.stories-fB3mcFmx.js} +1 -1
- package/storybook-static/assets/{NoData-ovaQEE9W.js → NoData-DDb0G7T8.js} +1 -1
- package/storybook-static/assets/{NotificationsHost-BpeMWhLY.js → NotificationsHost-CIGL-pKX.js} +1 -1
- package/storybook-static/assets/NotificationsHost.stories-B_MRb3fs.js +29 -0
- package/storybook-static/assets/{ODataMultiSelect-qlft9L9L.js → ODataMultiSelect-DQAitH4N.js} +1 -1
- package/storybook-static/assets/{ODataMultiSelect.stories-CMPIoPiy.js → ODataMultiSelect.stories-DwW221S9.js} +2 -2
- package/storybook-static/assets/{ODataSelect-DKBQArAK.js → ODataSelect-tiZhOIhE.js} +1 -1
- package/storybook-static/assets/{ODataSelect.stories-DxYIhtwe.js → ODataSelect.stories-BhaatPjK.js} +2 -2
- package/storybook-static/assets/{ODataTreeMultiSelect-DAt6THP3.js → ODataTreeMultiSelect-B9WqJ-Un.js} +1 -1
- package/storybook-static/assets/{ODataTreeMultiSelect.stories-CBNJP0mP.js → ODataTreeMultiSelect.stories-CAfKuhfU.js} +1 -1
- package/storybook-static/assets/{ODataTreeSelect-Bzzt4CQC.js → ODataTreeSelect-Cel1phxZ.js} +1 -1
- package/storybook-static/assets/{ODataTreeSelect.stories-CWVvuqOt.js → ODataTreeSelect.stories-BpBCpBA9.js} +1 -1
- package/storybook-static/assets/{OneStepScroller-BY5lz8qi.js → OneStepScroller-BSeGbz02.js} +1 -1
- package/storybook-static/assets/{Option-Rw8xwrPg.js → Option-BBtQ3GdK.js} +1 -1
- package/storybook-static/assets/{OptionButton-Br48w_Zg.js → OptionButton-B9nZuqqW.js} +1 -1
- package/storybook-static/assets/{PeriodSelect-DxSRwKw-.js → PeriodSelect-BGvhR3to.js} +1 -1
- package/storybook-static/assets/{PeriodSelect-8-wpXz6w.js → PeriodSelect-DA_zjcdA.js} +1 -1
- package/storybook-static/assets/{PeriodSelect.stories-B-qgUzlS.js → PeriodSelect.stories-DDP1eXyM.js} +1 -1
- package/storybook-static/assets/{PickerTriggerActions-C5xmysFh.js → PickerTriggerActions-BgvzqRBd.js} +1 -1
- package/storybook-static/assets/{Popover-Ds8PUigp.js → Popover-BQql18MF.js} +1 -1
- package/storybook-static/assets/{Popover-NJwt_vZZ.js → Popover-C0NebUMz.js} +1 -1
- package/storybook-static/assets/{Popover.stories-CUOFA_Xf.js → Popover.stories-CIyDUtlz.js} +1 -1
- package/storybook-static/assets/{PresetRangeDateInput-DyOpbkON.js → PresetRangeDateInput-BsgzPwCV.js} +1 -1
- package/storybook-static/assets/{PresetRangeDateInput-Xk0bOy3S.js → PresetRangeDateInput-htbxc3ni.js} +1 -1
- package/storybook-static/assets/{PresetRangeDateInput.stories-CwjUlXj0.js → PresetRangeDateInput.stories-ClHM5Kah.js} +1 -1
- package/storybook-static/assets/{PresetSelect-Ddmr0niY.js → PresetSelect-Dcx0BOTx.js} +1 -1
- package/storybook-static/assets/README--LCKbep-.js +110 -0
- package/storybook-static/assets/{README-DRnlD7y8.js → README-5M8ajrJp.js} +1 -1
- package/storybook-static/assets/README-5NhzH8VL.js +95 -0
- package/storybook-static/assets/README-Am6Fa6-b.js +69 -0
- package/storybook-static/assets/README-B3bFglqG.js +82 -0
- package/storybook-static/assets/README-B45Cwj2a.js +95 -0
- package/storybook-static/assets/README-B6Nq7NCU.js +416 -0
- package/storybook-static/assets/{README-B4zYJg6u.js → README-B6ltJiw3.js} +1 -1
- package/storybook-static/assets/{README-BdPlV5nA.js → README-BB_JPejH.js} +1 -1
- package/storybook-static/assets/README-BIq-FXcN.js +2124 -0
- package/storybook-static/assets/README-BSh5XUR9.js +110 -0
- package/storybook-static/assets/README-BXJneZAJ.js +147 -0
- package/storybook-static/assets/README-BYSgTTZt.js +296 -0
- package/storybook-static/assets/{README-BzVni2ve.js → README-BmhhWWEk.js} +1 -1
- package/storybook-static/assets/README-Bqnqu1bC.js +118 -0
- package/storybook-static/assets/README-BuMMG4_N.js +192 -0
- package/storybook-static/assets/README-BxjYCoYA.js +186 -0
- package/storybook-static/assets/{README-MzcO5Z_P.js → README-ByALXSEH.js} +1 -1
- package/storybook-static/assets/README-Byo6DxIF.js +101 -0
- package/storybook-static/assets/README-C3UcjOGB.js +208 -0
- package/storybook-static/assets/README-C6BOdXNV.js +322 -0
- package/storybook-static/assets/README-C8E1O7DQ.js +230 -0
- package/storybook-static/assets/README-C9eh0JLs.js +64 -0
- package/storybook-static/assets/README-CAGQnLsv.js +90 -0
- package/storybook-static/assets/README-CC00hlZK.js +527 -0
- package/storybook-static/assets/README-CH_6ZIO2.js +64 -0
- package/storybook-static/assets/README-CHbo4O3Z.js +75 -0
- package/storybook-static/assets/{README-CTIBG4zH.js → README-CIGfHKKE.js} +1 -1
- package/storybook-static/assets/{README-BHw6MVjD.js → README-CM-7E-Jf.js} +1 -1
- package/storybook-static/assets/{README-C0BwTe5N.js → README-CNHemCS2.js} +1 -1
- package/storybook-static/assets/{README-DzTc6XmY.js → README-CWfPiPIB.js} +1 -1
- package/storybook-static/assets/{README-Dx3cpFMr.js → README-CeK4kfFO.js} +1 -1
- package/storybook-static/assets/README-Cj2e6HrF.js +178 -0
- package/storybook-static/assets/README-CsoHGRve.js +1844 -0
- package/storybook-static/assets/README-D9OypaFB.js +208 -0
- package/storybook-static/assets/{README-CkWglKbS.js → README-DDBqoI-T.js} +1 -1
- package/storybook-static/assets/README-DE2wk9-v.js +1282 -0
- package/storybook-static/assets/README-DEj2wSK0.js +264 -0
- package/storybook-static/assets/{README-D-XjRtAE.js → README-DIbfpC-2.js} +1 -1
- package/storybook-static/assets/{README-Dki94Nf2.js → README-DJHVgrpj.js} +1 -1
- package/storybook-static/assets/README-DN9HKtp_.js +124 -0
- package/storybook-static/assets/README-DNricOkt.js +136 -0
- package/storybook-static/assets/README-DV4fCpqN.js +1146 -0
- package/storybook-static/assets/{README-BzVHwvgo.js → README-DjCArsA5.js} +1 -1
- package/storybook-static/assets/README-Dl92E69Z.js +1704 -0
- package/storybook-static/assets/README-DnA-4W65.js +226 -0
- package/storybook-static/assets/README-DoCA4JXf.js +273 -0
- package/storybook-static/assets/{README-DqQDgJN-.js → README-DvAlDsh9.js} +1 -1
- package/storybook-static/assets/README-Ss-3t1nX.js +158 -0
- package/storybook-static/assets/README-eHCINzP3.js +154 -0
- package/storybook-static/assets/README-qHKxXU95.js +98 -0
- package/storybook-static/assets/README-tm9QH9cF.js +103 -0
- package/storybook-static/assets/README-ui-uanyg.js +672 -0
- package/storybook-static/assets/{RadioButton-oSvQ-gQh.js → RadioButton-CWtjclwT.js} +1 -1
- package/storybook-static/assets/{RadioButton-DWbkCY8u.js → RadioButton-YIQXt0wx.js} +1 -1
- package/storybook-static/assets/{RadioButton.stories-GNQ9XJZT.js → RadioButton.stories-Ah-CBpeC.js} +1 -1
- package/storybook-static/assets/{RadioGroup-CvXjGXcV.js → RadioGroup-BnO-GL7A.js} +1 -1
- package/storybook-static/assets/{RadioGroup-eBYggurL.js → RadioGroup-CUS0etBD.js} +1 -1
- package/storybook-static/assets/{RadioGroup.stories-C77j_cPv.js → RadioGroup.stories-DGwCawtU.js} +1 -1
- package/storybook-static/assets/{Scrollable-De6SdhI3.js → Scrollable-D85fA6pO.js} +1 -1
- package/storybook-static/assets/{Select-Bwc0bEpt.js → Select-CGCxJjL9.js} +1 -1
- package/storybook-static/assets/{Select-DQMoVjn4.js → Select-gRnfvfGh.js} +1 -1
- package/storybook-static/assets/{Select.stories-BSIJKJnM.js → Select.stories-CMwt4F9i.js} +1 -1
- package/storybook-static/assets/{SerializableSelect-B73irNFR.js → SerializableSelect-BLXfKJ38.js} +1 -1
- package/storybook-static/assets/{SerializableSelect.stories-Z9q6g5v2.js → SerializableSelect.stories-Bca1a9ZU.js} +1 -1
- package/storybook-static/assets/{SingleDateTimeInput-Dq9LcjnS.js → SingleDateTimeInput-CyeQN0Rd.js} +1 -1
- package/storybook-static/assets/{SingleDateTimeInput-BHl6srqA.js → SingleDateTimeInput-xrmZckzw.js} +1 -1
- package/storybook-static/assets/SingleDateTimeInput.stories-BYFTQM9z.js +48 -0
- package/storybook-static/assets/{Slider-BiyKexKa.js → Slider-1yJ3uVeR.js} +1 -1
- package/storybook-static/assets/{Slider-CvM0N_kc.js → Slider-D8GtXVGI.js} +1 -1
- package/storybook-static/assets/{Slider.stories-CdHAMDmY.js → Slider.stories-CyQ3ns_C.js} +1 -1
- package/storybook-static/assets/{SliderInput-Bx_oHUCV.js → SliderInput-BOzHhEUA.js} +1 -1
- package/storybook-static/assets/{SliderInput-DqHotbhB.js → SliderInput-ISSx9vH_.js} +1 -1
- package/storybook-static/assets/{SliderInput.stories-R5yDhghM.js → SliderInput.stories-7ooTghrS.js} +1 -1
- package/storybook-static/assets/{Sortable-D7pjTHO0.js → Sortable-CCLiMmfZ.js} +1 -1
- package/storybook-static/assets/{Sortable.stories-CVLG6pSH.js → Sortable.stories-B36szI6t.js} +1 -1
- package/storybook-static/assets/{Splitter-B1Du6XI2.js → Splitter-DQGhgRwx.js} +1 -1
- package/storybook-static/assets/{Splitter.stories-D-FRLMCc.js → Splitter.stories-Hsq1wYaq.js} +1 -1
- package/storybook-static/assets/{StateSelect-zl-yZibY.js → StateSelect-C6hldFgO.js} +1 -1
- package/storybook-static/assets/{StateSelect-BJdUEUBc.js → StateSelect-DieNn4VC.js} +1 -1
- package/storybook-static/assets/{StateSelect.stories-DgidR5zR.js → StateSelect.stories-CvAhDMix.js} +1 -1
- package/storybook-static/assets/{StringToggle.stories-IucGrtIi.js → StringToggle.stories-CUT1tvt-.js} +1 -1
- package/storybook-static/assets/{Switch-BJrn2lIN.js → Switch-CX9p_uYU.js} +1 -1
- package/storybook-static/assets/{Switch-5dCshvVo.js → Switch-nEMRtcWe.js} +1 -1
- package/storybook-static/assets/{Switch.stories-Dp_l3_JL.js → Switch.stories-CPsHa2_m.js} +1 -1
- package/storybook-static/assets/{Table-BFAEcUde.js → Table-BhtITVtj.js} +1 -1
- package/storybook-static/assets/{Table.stories-CohejRQv.js → Table.stories-nWNhSydG.js} +2 -2
- package/storybook-static/assets/{Tabs-CI32QiHf.js → Tabs-DMQFh2BJ.js} +1 -1
- package/storybook-static/assets/{Tabs.stories-Cr9d9ipA.js → Tabs.stories-D23_xvom.js} +1 -1
- package/storybook-static/assets/{TabsBox-BlDOUDMF.js → TabsBox-B5BsD_j_.js} +1 -1
- package/storybook-static/assets/{TagInput-YZ7eSv8W.js → TagInput-DO17z100.js} +1 -1
- package/storybook-static/assets/{TagInput.stories-DrOvsiI5.js → TagInput.stories-CMMFnIzb.js} +1 -1
- package/storybook-static/assets/{Text-DK4jN26J.js → Text-ClnbDqRk.js} +1 -1
- package/storybook-static/assets/{Textarea-DxPuWBZj.js → Textarea-C2IO_zsP.js} +1 -1
- package/storybook-static/assets/{Textarea-CFh5f_lC.js → Textarea-DkhohiNc.js} +1 -1
- package/storybook-static/assets/{Textarea.stories-CUeOGKYc.js → Textarea.stories-NL6Aq8Vc.js} +1 -1
- package/storybook-static/assets/{TimePanel-BUhFtwlb.js → TimePanel-DNEPDlSW.js} +1 -1
- package/storybook-static/assets/{TimePanel.stories-CpXpMBDN.js → TimePanel.stories-DlfdPsz1.js} +1 -1
- package/storybook-static/assets/{Toggle-BtApzBNH.js → Toggle-3U5CceQN.js} +1 -1
- package/storybook-static/assets/{Toggle-l2AvDbRn.js → Toggle-Cc6Ca-HI.js} +1 -1
- package/storybook-static/assets/{Toggle.stories-Ca8otmAa.js → Toggle.stories-BR-hVLDp.js} +1 -1
- package/storybook-static/assets/{TreeMultiSelect-nXC4ZB5b.js → TreeMultiSelect-B0oBc-4y.js} +1 -1
- package/storybook-static/assets/{TreeMultiSelect-C9QDV63L.js → TreeMultiSelect-D9hMQN2O.js} +1 -1
- package/storybook-static/assets/{TreeMultiSelect.stories-6STRGJbF.js → TreeMultiSelect.stories-CslpbvPR.js} +1 -1
- package/storybook-static/assets/{TreePickerBase-Cq7fSw3x.js → TreePickerBase-B_dMCe45.js} +1 -1
- package/storybook-static/assets/{TreeSelect-CITef9rp.js → TreeSelect-2lj0Q8gm.js} +1 -1
- package/storybook-static/assets/{TreeSelect-rMNyu_KT.js → TreeSelect-DEKNYF2b.js} +1 -1
- package/storybook-static/assets/{TreeSelect.stories-B-Emz9yW.js → TreeSelect.stories-CVDxn8Vm.js} +1 -1
- package/storybook-static/assets/{TreeTable-CLiP0td3.js → TreeTable-CBIpzYRL.js} +1 -1
- package/storybook-static/assets/{TreeTable.stories-DJb9qt8k.js → TreeTable.stories-BMzrr2Kc.js} +2 -2
- package/storybook-static/assets/{blocks-DndFRxxW.js → blocks-B5YBxaaS.js} +3 -3
- package/storybook-static/assets/{check-CLkTJVXe.js → check-BjtdCRaW.js} +1 -1
- package/storybook-static/assets/{chevron-down-miCejSEn.js → chevron-down-B4u-y8Z1.js} +1 -1
- package/storybook-static/assets/{chevron-left-DhQIPej2.js → chevron-left-BQfWs7Ah.js} +1 -1
- package/storybook-static/assets/{chevron-right-DfBBx-fr.js → chevron-right-ChokKd-f.js} +1 -1
- package/storybook-static/assets/{chunk-W22LQPXL-IdwKKJUw.js → chunk-W22LQPXL-meOkhzk4.js} +1 -1
- package/storybook-static/assets/{circle-alert-DOmVf8am.js → circle-alert-B1AnDRf_.js} +1 -1
- package/storybook-static/assets/{circle-check-e7eSQ2VD.js → circle-check-JYnlcC1F.js} +1 -1
- package/storybook-static/assets/{components-Bm4Cw8Ap.js → components-C_wl1sL5.js} +3 -3
- package/storybook-static/assets/{contextMenu-DpIKeJju.js → contextMenu-B-TUGs_1.js} +1 -1
- package/storybook-static/assets/{defaultRenderers-m21aWJXz.js → defaultRenderers-DfmnIuod.js} +1 -1
- package/storybook-static/assets/{download-eAKjms6q.js → download-eR3X8I-h.js} +1 -1
- package/storybook-static/assets/{floating-ui.react-DmilONq6.js → floating-ui.react-D95VPQ0b.js} +1 -1
- package/storybook-static/assets/formatters-D33Uh3si-CxrG0jsB.js +1 -0
- package/storybook-static/assets/foundationApi-QhHXpYLB.js +59 -0
- package/storybook-static/assets/foundationLib-CEAjnstw.js +30 -0
- package/storybook-static/assets/{hooks-RI5_2AXI.js → hooks-awde7r2r.js} +1 -1
- package/storybook-static/assets/iframe-DzQq_POR.js +1 -0
- package/storybook-static/assets/{iframe-Sr0umHM6.js → iframe-FSp_AjJa.js} +4 -4
- package/storybook-static/assets/{info-DhJTzwcL.js → info-12vmb1sT.js} +1 -1
- package/storybook-static/assets/odata-C0Kpvttz.js +1 -0
- package/storybook-static/assets/odata-service-CWkHASdw-DlmSiioz.js +3 -0
- package/storybook-static/assets/{odataStoryFixtures-lgnWIUp7.js → odataStoryFixtures-BXZnk_C7.js} +1 -1
- package/storybook-static/assets/{react-YFbUKK0m.js → react-BlCqWuXr.js} +1 -1
- package/storybook-static/assets/{refresh-cw-C7WnxX9M.js → refresh-cw-Bf5ufPte.js} +1 -1
- package/storybook-static/assets/{settings-2-0NVvyKQl.js → settings-2-DR-dTXIC.js} +1 -1
- package/storybook-static/assets/{sortable-DDGG-Zfs.js → sortable-B5e5yb_-.js} +1 -1
- package/storybook-static/assets/{syntaxhighlighter-QEQV7K2Y-CxWm8nc8.js → syntaxhighlighter-QEQV7K2Y-EVJARTec.js} +1 -1
- package/storybook-static/assets/{trash-2-BnceCuhg.js → trash-2-QP7TS18H.js} +1 -1
- package/storybook-static/assets/{triangle-alert-MPi3GVgt.js → triangle-alert-qw19mxHr.js} +1 -1
- package/storybook-static/assets/{useODataSelectBase-hmjK6chS.js → useODataSelectBase-Csu_Cct9.js} +1 -1
- package/storybook-static/assets/useODataTreeData-BAv-Twqf.js +1 -0
- package/storybook-static/assets/{usePickerQuery-CtsGhieD.js → usePickerQuery-Da-XM_Y0.js} +1 -1
- package/storybook-static/assets/{usePickerTriggerController-EaI8W2G0.js → usePickerTriggerController-C0TdC2Pz.js} +1 -1
- package/storybook-static/assets/{x-CqPSvWfo.js → x-aCjYTirW.js} +1 -1
- package/storybook-static/iframe.html +2 -2
- package/storybook-static/index.json +1 -1
- package/storybook-static/project.json +1 -1
- package/storybook-static/assets/DateInput-05Iy69_a.js +0 -1
- package/storybook-static/assets/NotificationsHost.stories-CgbFboVD.js +0 -29
- package/storybook-static/assets/SingleDateTimeInput.stories-C2RuBRAF.js +0 -48
- package/storybook-static/assets/async-SjiCjIjO.js +0 -625
- package/storybook-static/assets/formatters-CBgrBeSA-CqB1pZxS.js +0 -1
- package/storybook-static/assets/foundationLib-DRrox3tN.js +0 -25
- package/storybook-static/assets/iframe-DQo-3eW2.js +0 -1
- package/storybook-static/assets/odata-DhISMZkE.js +0 -1
- package/storybook-static/assets/odata-service-B6TxBSLm-Bq8Ya67E.js +0 -3
- package/storybook-static/assets/odataFetchFn-Dv6Xi5CI.js +0 -763
- package/storybook-static/assets/persisted-CUFiw53N.js +0 -600
- package/storybook-static/assets/useODataTreeData-CKuavbWc.js +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{n as e,r as t}from"./rolldown-runtime-DkW27tQK.js";import{t as n}from"./react-BZJXY1be.js";import{n as r}from"./iframe-
|
|
1
|
+
import{n as e,r as t}from"./rolldown-runtime-DkW27tQK.js";import{t as n}from"./react-BZJXY1be.js";import{n as r}from"./iframe-FSp_AjJa.js";import{n as i,t as a}from"./Popover-C0NebUMz.js";import{n as o,t as s}from"./Button-DkDgfpHL.js";import{n as c,t as l}from"./createControlledStoryRender-BouhvX-R.js";import{l as u,t as d}from"./Input-CIPgijvW.js";var f=t({AnchorPlacement:()=>w,Controlled:()=>C,Default:()=>S,WithInteractiveContent:()=>T,__namedExportsOrder:()=>E,default:()=>x});function p({args:e,updateArgs:t,trigger:n,children:r}){return(0,_.jsxs)(a,{placement:e.placement,open:e.open,defaultOpen:e.defaultOpen,onOpenChange:n=>{e.onOpenChange?.(n),t({open:n})},children:[(0,_.jsx)(a.Trigger,{passive:e.passive,children:n(e.open===!0)}),(0,_.jsx)(a.Content,{onClose:()=>e.onClose?.(),closeOnOutside:e.closeOnOutside,closeOnEscape:e.closeOnEscape,disableOutsideClick:e.disableOutsideClick,background:e.background,children:r})]})}function m(e,t){return l((n,r)=>(0,_.jsx)(p,{args:n,updateArgs:r,trigger:e,children:t}))}function h({args:e,updateArgs:t}){let[n,r]=(0,g.useState)(``);return(0,_.jsx)(p,{args:e,updateArgs:t,trigger:()=>(0,_.jsx)(`button`,{type:`button`,children:`Форма`}),children:e=>(0,_.jsxs)(`form`,{onSubmit:t=>{t.preventDefault(),e.setClose()},style:{display:`flex`,flexDirection:`column`,gap:8,padding:12,width:180},children:[(0,_.jsx)(d,{label:`Имя`,placeholder:`Введите имя`,value:n,onChange:r}),(0,_.jsx)(s,{children:`Отправить`})]})})}var g,_,v,y,b,x,S,C,w,T,E;function D(){return(D=e((()=>{g=n(),o(),c(),u(),i(),_=r(),{useArgs:v}=__STORYBOOK_MODULE_PREVIEW_API__,{fn:y}=__STORYBOOK_MODULE_TEST__,b=[`top`,`top-start`,`top-end`,`right`,`right-start`,`right-end`,`bottom`,`bottom-start`,`bottom-end`,`left`,`left-start`,`left-end`],x={title:`Shared/UI/Popover`,component:a,args:{children:null,placement:`bottom`,open:!1,defaultOpen:!1,onOpenChange:y(),onClose:y(),closeOnOutside:!0,closeOnEscape:!0,disableOutsideClick:!1,background:`secondary`},parameters:{atomicCanvas:!0,layout:`centered`},argTypes:{children:{description:"Композиция из `Popover.Trigger` и `Popover.Content`.",control:!1},placement:{description:`Предпочтительное положение панели относительно trigger.`,control:`select`,options:b},open:{description:`Контролируемая видимость popover.`,control:`boolean`},defaultOpen:{description:`Начальная видимость в uncontrolled-режиме.`,control:`boolean`},onOpenChange:{description:`Вызывается при открытии и закрытии popover.`,control:!1},passive:{description:`Оставляет trigger пассивным: он получает reference, но не переключает popover по клику.`,control:`boolean`},onClose:{description:"Вызывается после закрытия Content через Escape, клик снаружи или `setClose`.",control:!1},closeOnOutside:{description:`Закрывает Content по клику снаружи.`,control:`boolean`},closeOnEscape:{description:`Закрывает Content по клавише Escape.`,control:`boolean`},disableOutsideClick:{description:`Игнорирует клики снаружи Content.`,control:`boolean`},background:{description:`Тема фона Content.`,control:`inline-radio`,options:[`primary`,`secondary`]}}},S={render:m(()=>(0,_.jsx)(`button`,{type:`button`,children:`Открыть`}),e=>(0,_.jsxs)(`div`,{style:{padding:12,maxWidth:160},children:[(0,_.jsx)(`p`,{children:`Пример простого поповера`}),(0,_.jsx)(`button`,{type:`button`,onClick:e.setClose,children:`Закрыть`})]}))},C={render:m(e=>(0,_.jsx)(`button`,{type:`button`,children:e?`Закрыть`:`Открыть`}),(0,_.jsx)(`div`,{style:{padding:12},children:`Контролируемый режим`}))},w={render:function(){let[e,t]=v(),n=(n,r)=>{e.onOpenChange?.(n),t(n?{open:!0,placement:r}:{open:!1})};return(0,_.jsx)(`div`,{style:{display:`flex`,gap:32,flexWrap:`wrap`,justifyContent:`center`},children:b.map(t=>(0,_.jsxs)(a,{placement:t,open:e.open===!0&&e.placement===t,defaultOpen:e.defaultOpen,onOpenChange:e=>n(e,t),children:[(0,_.jsx)(a.Trigger,{passive:e.passive,children:(0,_.jsx)(`button`,{type:`button`,children:t})}),(0,_.jsx)(a.Content,{onClose:()=>e.onClose?.(),closeOnOutside:e.closeOnOutside,closeOnEscape:e.closeOnEscape,disableOutsideClick:e.disableOutsideClick,background:e.background,children:(0,_.jsx)(`div`,{style:{padding:8},children:t})})]},t))})}},T={render:l((e,t)=>(0,_.jsx)(h,{args:e,updateArgs:t}))},S.parameters={...S.parameters,docs:{...S.parameters?.docs,source:{originalSource:`{
|
|
2
2
|
render: createPopoverStoryRender(() => <button type="button">Открыть</button>, ctx => <div style={{
|
|
3
3
|
padding: 12,
|
|
4
4
|
maxWidth: 160
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e}from"./rolldown-runtime-DkW27tQK.js";import{t}from"./react-BZJXY1be.js";import{n}from"./iframe-
|
|
1
|
+
import{n as e}from"./rolldown-runtime-DkW27tQK.js";import{t}from"./react-BZJXY1be.js";import{n}from"./iframe-FSp_AjJa.js";import{n as r,t as i}from"./FlexContainer-BWyPlTMB.js";import{r as a,t as o}from"./DateInput-BiUFIihm.js";import{a as s,c,l,n as u,o as d,r as f,s as p,t as m}from"./DateRangePresetSelect-RIyqNBk9.js";function h(e){return e??`__empty__`}function g({value:e,onChange:t,presetId:n,onPresetIdChange:r,referenceDate:a,presetIds:s,presetOptions:u,presetLabel:g,presetDescription:y,presetPlaceholder:b=`Выберите пресет диапазона`,presetDisabled:x,...S}){let[C]=(0,_.useState)(()=>new Date),w=a??C,T=(0,_.useMemo)(()=>u??c(d(s,f)),[s,u]),E=e??null,D=(0,_.useMemo)(()=>p(E,w,T),[E,T,w]),O=n??D??void 0,k=(0,_.useRef)(``),A=(0,_.useCallback)(e=>{if(!r)return;let t=h(e);t!==k.current&&(k.current=t,r(e))},[r]),j=e=>{let n=l(e,w,T);if(!n){A(null);return}A(n.id),t(n.range)},M=e=>{t(e),A(p(e,w,T))};return(0,v.jsxs)(i,{gap:`sm`,align:`end`,children:[(0,v.jsx)(m,{size:S.size,label:g,description:y,placeholder:b,disabled:x??S.disabled,value:O,onChange:j,options:T,referenceDate:w}),(0,v.jsx)(o,{...S,value:E,onChange:M})]})}var _,v;function y(){return(y=e((()=>{_=t(),a(),u(),s(),r(),v=n(),g.__docgenInfo={description:`Составной компонент выбора диапазона дат через пресет или ручной ввод.`,methods:[],displayName:`PresetRangeDateInput`,props:{presetId:{required:!1,tsType:{name:`union`,raw:`DateRangePresetOption["id"] | null`,elements:[{name:`DateRangePresetOption["id"]`,raw:`DateRangePresetOption["id"]`},{name:`null`}]},description:``},onPresetIdChange:{required:!1,tsType:{name:`signature`,type:`function`,raw:`(presetId: DateRangePresetOption["id"] | null) => void`,signature:{arguments:[{type:{name:`union`,raw:`DateRangePresetOption["id"] | null`,elements:[{name:`DateRangePresetOption["id"]`,raw:`DateRangePresetOption["id"]`},{name:`null`}]},name:`presetId`}],return:{name:`void`}}},description:``},referenceDate:{required:!1,tsType:{name:`Date`},description:``},presetIds:{required:!1,tsType:{name:`unknown`},description:``},presetOptions:{required:!1,tsType:{name:`unknown`},description:``},presetLabel:{required:!1,tsType:{name:`ReactNode`},description:``},presetDescription:{required:!1,tsType:{name:`string`},description:``},presetPlaceholder:{required:!1,tsType:{name:`string`},description:``,defaultValue:{value:`"Выберите пресет диапазона"`,computed:!1}},presetDisabled:{required:!1,tsType:{name:`boolean`},description:``}},composes:[`Omit`]}})))()}export{y as n,g as t};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{n as e}from"./rolldown-runtime-DkW27tQK.js";import{n as t}from"./iframe-
|
|
1
|
+
import{n as e}from"./rolldown-runtime-DkW27tQK.js";import{n as t}from"./iframe-FSp_AjJa.js";import{i as n,r}from"./react-Bl2r1tuC.js";import{a as i,d as a,f as o,l as s,m as c,n as l,p as u,r as d,u as f}from"./blocks-B5YBxaaS.js";import{n as p,r as m,t as h}from"./PresetRangeDateInput.stories-ClHM5Kah.js";function g(e){let t={code:`code`,h2:`h2`,h3:`h3`,li:`li`,p:`p`,pre:`pre`,ul:`ul`,...n(),...e.components};return(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(s,{of:p,parameters:{docs:{toc:!0}}}),`
|
|
2
2
|
`,(0,v.jsx)(u,{children:`PresetRangeDateInput`}),`
|
|
3
3
|
`,(0,v.jsx)(o,{children:`Составной контрол диапазона дат с синхронизацией ручного ввода и готовых пресетов`}),`
|
|
4
4
|
`,(0,v.jsx)(t.p,{children:`PresetRangeDateInput уже имеет живые stories, а эта страница собирает их в структурированную документацию с краткими рекомендациями, примерами подключения и API.
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{n as e,r as t}from"./rolldown-runtime-DkW27tQK.js";import{a as n,i as r,r as i}from"./CalendarView-
|
|
1
|
+
import{n as e,r as t}from"./rolldown-runtime-DkW27tQK.js";import{a as n,i as r,r as i}from"./CalendarView-CEqcrblx.js";import{n as a}from"./iframe-FSp_AjJa.js";import{n as o,t as s}from"./Text-ClnbDqRk.js";import{n as c,t as l}from"./FlexContainer-BWyPlTMB.js";import{n as u,t as d}from"./createControlledStoryRender-BouhvX-R.js";import{a as f,r as p}from"./DateRangePresetSelect-RIyqNBk9.js";import{n as m,t as h}from"./PresetRangeDateInput-BsgzPwCV.js";var g=t({Default:()=>x,__namedExportsOrder:()=>S,default:()=>y}),_,v,y,b,x,S;function C(){return(C=e((()=>{n(),f(),u(),c(),o(),m(),_=a(),{fn:v}=__STORYBOOK_MODULE_TEST__,y={title:`Shared/UI/PresetRangeDateInput`,component:h,args:{label:`Диапазон дат`,placeholder:`дд.мм.гггг - дд.мм.гггг`,value:[new Date(2026,2,10,0,0,0),new Date(2026,2,10,23,59,59)],onChange:v(),presetId:`today`,onPresetIdChange:v(),referenceDate:new Date(2026,2,10,12,0,0),presetLabel:`Быстрый диапазон`,size:`md`},parameters:{atomicCanvas:!0,layout:`padded`},argTypes:{presetId:{description:"Контролируемый ID выбранного быстрого пресета. `null` снимает внешний выбор.",control:`select`,options:[...p,null]},onPresetIdChange:{description:`Вызывается, когда выбор пресета меняется из-за preset или ручного диапазона.`,control:!1},referenceDate:{description:`Опорная дата для вычисления встроенных быстрых диапазонов.`,control:`date`},presetIds:{description:"Разрешённые встроенные ID пресетов, если не передан `presetOptions`.",control:`check`,options:p},presetOptions:{description:`Кастомный каталог быстрых диапазонов с функциями вычисления.`,control:!1},presetLabel:{description:`Заголовок поля быстрого выбора.`,control:`text`},presetDescription:{description:`Описание под полем быстрого выбора.`,control:`text`},presetPlaceholder:{description:`Текст до выбора быстрого диапазона.`,control:`text`},presetDisabled:{description:`Блокирует только выбор быстрого пресета.`,control:`boolean`},label:{description:`Заголовок ручного поля диапазона.`,control:`text`},description:{description:`Описание ручного поля диапазона.`,control:`text`},placeholder:{description:`Текст до выбора ручного диапазона.`,control:`text`},value:{description:`Текущий ручной диапазон дат.`,control:!1},onChange:{description:`Вызывается при изменении ручного диапазона или выборе пресета.`,control:!1},error:{description:`Текст внешней ошибки ручного поля.`,control:`text`},onClearError:{description:`Сбрасывает внешнюю ошибку после ввода или выбора.`,control:!1},minDate:{description:`Минимально доступная дата ручного диапазона.`,control:`date`},maxDate:{description:`Максимально доступная дата ручного диапазона.`,control:`date`},datePreset:{description:`Пресет форматирования выбранного ручного диапазона.`,control:`text`},datePickerLevel:{description:`Минимальный уровень навигации календаря ручного поля.`,control:`select`,options:[`day`,`month`,`year`]},selectionMode:{description:`Размер периода, который выбирает ручное поле.`,control:`select`,options:i},weekEndDay:{description:`Последний включённый день недели в режиме week.`,control:`select`,options:r},allowSelectionModeChange:{description:`Показывает runtime-переключатель размера периода.`,control:`boolean`},selectionModeOptions:{description:`Ограничивает доступные режимы в runtime-переключателе.`,control:`check`,options:i},onSelectionModeChange:{description:`Вызывается при runtime-смене размера периода.`,control:!1},disabled:{description:"Блокирует ручное поле и, если `presetDisabled` не задан, быстрый выбор.",control:`boolean`},size:{description:`Размер обоих полей.`,control:`select`,options:[`xs`,`sm`,`md`,`lg`,`xl`]}}},b=d((e,t)=>(0,_.jsxs)(_.Fragment,{children:[(0,_.jsx)(l,{gap:`sm`,align:`end`,children:(0,_.jsx)(h,{...e,value:e.value??null,onChange:n=>{e.onChange(n),t({value:n})},onPresetIdChange:n=>{e.onPresetIdChange?.(n),t({presetId:n})},onSelectionModeChange:n=>{e.onSelectionModeChange?.(n),t({selectionMode:n})},onClearError:()=>{e.onClearError?.(),t({error:void 0})}})}),(0,_.jsxs)(s,{as:`p`,className:`marginBlockSm`,children:[`Активный presetId: `,(0,_.jsx)(s,{as:`code`,children:e.presetId??`null`})]})]})),x={render:b},x.parameters={...x.parameters,docs:{...x.parameters?.docs,source:{originalSource:`{
|
|
2
2
|
render: renderPresetRangeDateInputStory
|
|
3
3
|
}`,...x.parameters?.docs?.source},description:{story:`Демонстрирует совместную работу пресета и ручного диапазона.`,...x.parameters?.docs?.description}}},S=[`Default`]})))()}export{g as n,C as r,x as t};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{n as e}from"./rolldown-runtime-DkW27tQK.js";import{n as t}from"./iframe-
|
|
1
|
+
import{n as e}from"./rolldown-runtime-DkW27tQK.js";import{n as t}from"./iframe-FSp_AjJa.js";import{n,t as r}from"./Select-CGCxJjL9.js";function i(e,t,n=[]){if(!Array.isArray(e))return[...n];let r=[];for(let n of e)!t(n)||r.includes(n)||r.push(n);return r}function a(e,t){let n=new Map(t.map(e=>[e.id,e])),r=[],i=new Set;for(let t of e){if(i.has(t))continue;let e=n.get(t);e&&(r.push(e),i.add(t))}return r}function o(e,t){return e?t.find(t=>t.id===e)??null:null}function s(){return(s=e((()=>{})))()}function c({options:e,value:t,onChange:n,getOptionDisabled:i,getOptionCode:a,getOptionAriaLabel:s,renderOption:c,renderValue:u,className:d,buttonClassName:f,optionsClassName:p,clearable:m,...h}){let g=o(t,e)??void 0;return(0,l.jsx)(r,{...h,options:e,value:g,onChange:e=>n(e?.id),getOptionKey:e=>e.id,getOptionLabel:e=>e.label,getOptionCode:a,getOptionDisabled:i,getOptionAriaLabel:s,renderOption:c,renderValue:u,className:d,buttonClassName:f,optionsClassName:p,clearable:m})}var l;function u(){return(u=e((()=>{n(),l=t(),c.__docgenInfo={description:"Базовый Select для пресетов с контрактом `id/label`.",methods:[],displayName:`PresetSelect`,props:{label:{required:!1,tsType:{name:`ReactNode`},description:``},description:{required:!1,tsType:{name:`string`},description:``},placeholder:{required:!1,tsType:{name:`string`},description:``},disabled:{required:!1,tsType:{name:`boolean`},description:``},size:{required:!1,tsType:{name:`union`,raw:`"xs" | "sm" | "md" | "lg" | "xl"`,elements:[{name:`literal`,value:`"xs"`},{name:`literal`,value:`"sm"`},{name:`literal`,value:`"md"`},{name:`literal`,value:`"lg"`},{name:`literal`,value:`"xl"`}]},description:``},value:{required:!0,tsType:{name:`V`},description:"Если начальное состояние может быть `null | undefined`\nзначит `onChange` тоже должен ументь сбрасывать.\nПоэтому такой контрол явно должен передавать `UiBaseProps<AnyType | undefined>`"},onChange:{required:!0,tsType:{name:`signature`,type:`function`,raw:`(value: T) => void`,signature:{arguments:[{type:{name:`C`},name:`value`}],return:{name:`void`}}},description:``},options:{required:!0,tsType:{name:`unknown`},description:``},getOptionDisabled:{required:!1,tsType:{name:`signature`,type:`function`,raw:`(option: TOption) => boolean`,signature:{arguments:[{type:{name:`TOption`},name:`option`}],return:{name:`boolean`}}},description:``},getOptionCode:{required:!1,tsType:{name:`signature`,type:`function`,raw:`(option: TOption) => string`,signature:{arguments:[{type:{name:`TOption`},name:`option`}],return:{name:`string`}}},description:``},getOptionAriaLabel:{required:!1,tsType:{name:`signature`,type:`function`,raw:`(option: TOption) => string`,signature:{arguments:[{type:{name:`TOption`},name:`option`}],return:{name:`string`}}},description:``},renderOption:{required:!1,tsType:{name:`signature`,type:`function`,raw:`(option: TOption, state: SelectOptionState) => ReactNode`,signature:{arguments:[{type:{name:`TOption`},name:`option`},{type:{name:`signature`,type:`object`,raw:`{
|
|
2
2
|
active: boolean;
|
|
3
3
|
selected: boolean;
|
|
4
4
|
disabled: boolean;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import{n as e}from"./rolldown-runtime-DkW27tQK.js";import{n as t}from"./iframe-FSp_AjJa.js";import{i as n,r}from"./react-Bl2r1tuC.js";import{l as i,m as a}from"./blocks-B5YBxaaS.js";function o(e){let t={a:`a`,code:`code`,h1:`h1`,h2:`h2`,li:`li`,ol:`ol`,p:`p`,pre:`pre`,table:`table`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,...n(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(i,{title:`Foundation API/SAP/ADT Transports`}),`
|
|
2
|
+
`,(0,c.jsxs)(t.h1,{id:`sap-adt-transports-через-ryuzaki13react-foundation-apiadt`,children:[`SAP ADT transports через `,(0,c.jsx)(t.code,{children:`@ryuzaki13/react-foundation-api/adt`})]}),`
|
|
3
|
+
`,(0,c.jsx)(t.p,{children:`Модуль получает transport requests текущего пользователя из SAP ADT endpoint и преобразует XML в простой массив объектов.`}),`
|
|
4
|
+
`,(0,c.jsx)(t.h2,{id:`содержание`,children:`Содержание`}),`
|
|
5
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
6
|
+
`,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#%D0%BA%D0%BE%D0%B3%D0%B4%D0%B0-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D1%8C`,children:`Когда использовать`})}),`
|
|
7
|
+
`,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0-%D0%B8-%D0%B8%D0%BC%D0%BF%D0%BE%D1%80%D1%82`,children:`Установка и импорт`})}),`
|
|
8
|
+
`,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#%D0%B1%D1%8B%D1%81%D1%82%D1%80%D1%8B%D0%B9-%D1%81%D1%82%D0%B0%D1%80%D1%82`,children:`Быстрый старт`})}),`
|
|
9
|
+
`,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#fetchusertransports`,children:(0,c.jsx)(t.code,{children:`fetchUserTransports`})})}),`
|
|
10
|
+
`,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#parseusertransportsxml`,children:(0,c.jsx)(t.code,{children:`parseUserTransportsXml`})})}),`
|
|
11
|
+
`,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82-%D1%80%D0%B5%D0%B7%D1%83%D0%BB%D1%8C%D1%82%D0%B0%D1%82%D0%B0`,children:`Формат результата`})}),`
|
|
12
|
+
`,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#%D0%BE%D1%88%D0%B8%D0%B1%D0%BA%D0%B8-%D0%B8-%D0%BE%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%B8%D1%8F`,children:`Ошибки и ограничения`})}),`
|
|
13
|
+
`,(0,c.jsx)(t.li,{children:(0,c.jsx)(t.a,{href:`#%D0%BF%D0%BE%D0%BB%D0%BD%D1%8B%D0%B9-api`,children:`Полный API`})}),`
|
|
14
|
+
`]}),`
|
|
15
|
+
`,(0,c.jsx)(t.h2,{id:`когда-использовать`,children:`Когда использовать`}),`
|
|
16
|
+
`,(0,c.jsxs)(t.p,{children:[`Используйте `,(0,c.jsx)(t.code,{children:`adt`}),`, если backend доступен по `,(0,c.jsx)(t.code,{children:`/sap/bc/adt/cts/transports`}),` и возвращает ADT XML. Если нужны отдельные UI2 списки workbench/customizing в JSON, используйте `,(0,c.jsx)(t.a,{href:`../transport/README.mdx`,children:(0,c.jsx)(t.code,{children:`@ryuzaki13/react-foundation-api/transport`})}),`.`]}),`
|
|
17
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-text`,children:`SAP ADT XML
|
|
18
|
+
│
|
|
19
|
+
▼
|
|
20
|
+
parseUserTransportsXml
|
|
21
|
+
│
|
|
22
|
+
▼
|
|
23
|
+
UserTransport[]
|
|
24
|
+
`})}),`
|
|
25
|
+
`,(0,c.jsx)(t.h2,{id:`установка-и-импорт`,children:`Установка и импорт`}),`
|
|
26
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-bash`,children:`npm install @ryuzaki13/react-foundation-api @ryuzaki13/react-foundation-lib fast-xml-parser
|
|
27
|
+
`})}),`
|
|
28
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`import { fetchUserTransports, parseUserTransportsXml } from "@ryuzaki13/react-foundation-api/adt";
|
|
29
|
+
|
|
30
|
+
import type { UserTransport } from "@ryuzaki13/react-foundation-api/adt";
|
|
31
|
+
`})}),`
|
|
32
|
+
`,(0,c.jsx)(t.h2,{id:`быстрый-старт`,children:`Быстрый старт`}),`
|
|
33
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`async function loadTransports() {
|
|
34
|
+
try {
|
|
35
|
+
const transports = await fetchUserTransports();
|
|
36
|
+
return transports;
|
|
37
|
+
} catch (error) {
|
|
38
|
+
console.error("Не удалось получить transports", error);
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
`})}),`
|
|
43
|
+
`,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`fetchUserTransports`}),` возвращает Promise. Пока он выполняется, данных ещё нет; ошибку нужно обработать через `,(0,c.jsx)(t.code,{children:`try/catch`}),`, TanStack Query или error boundary владельца сценария.`]}),`
|
|
44
|
+
`,(0,c.jsx)(t.h2,{id:`fetchusertransports`,children:(0,c.jsx)(t.code,{children:`fetchUserTransports`})}),`
|
|
45
|
+
`,(0,c.jsx)(t.p,{children:`Функция выполняет GET:`}),`
|
|
46
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-text`,children:`/sap/bc/adt/cts/transports?_action=FIND&trfunction=K
|
|
47
|
+
`})}),`
|
|
48
|
+
`,(0,c.jsx)(t.p,{children:`Запрос отправляется через SAP/OData transport пакета с:`}),`
|
|
49
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
50
|
+
`,(0,c.jsxs)(t.li,{children:[(0,c.jsx)(t.code,{children:`Accept: application/xml, text/xml, */*`}),`;`]}),`
|
|
51
|
+
`,(0,c.jsxs)(t.li,{children:[`cookies через `,(0,c.jsx)(t.code,{children:`credentials: include`}),`;`]}),`
|
|
52
|
+
`,(0,c.jsx)(t.li,{children:`SAP language/client и SSO policy общего OData transport;`}),`
|
|
53
|
+
`,(0,c.jsxs)(t.li,{children:[`пустым base URL, потому что ADT endpoint уже содержит `,(0,c.jsx)(t.code,{children:`/sap/...`}),`.`]}),`
|
|
54
|
+
`]}),`
|
|
55
|
+
`,(0,c.jsxs)(t.p,{children:[`Ответ читается как text и передаётся `,(0,c.jsx)(t.code,{children:`parseUserTransportsXml`}),`.`]}),`
|
|
56
|
+
`,(0,c.jsx)(t.p,{children:`Если сервер вместо XML вернул HTML login/error page, функция выбросит ошибку. Это защищает UI от ситуации, когда HTML ошибочно принимается за пустой список transports.`}),`
|
|
57
|
+
`,(0,c.jsx)(t.h2,{id:`parseusertransportsxml`,children:(0,c.jsx)(t.code,{children:`parseUserTransportsXml`})}),`
|
|
58
|
+
`,(0,c.jsx)(t.p,{children:`Parser можно использовать отдельно, например в тесте или при получении XML другим transport:`}),`
|
|
59
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const xml = \`
|
|
60
|
+
<root>
|
|
61
|
+
<CTS_REQ_HEADER>
|
|
62
|
+
<TRKORR>DEVK900001</TRKORR>
|
|
63
|
+
<AS4TEXT>Исправление отчёта</AS4TEXT>
|
|
64
|
+
<AS4USER>IVANOV</AS4USER>
|
|
65
|
+
<TARSYSTEM>QAS</TARSYSTEM>
|
|
66
|
+
<TRFUNCTION>K</TRFUNCTION>
|
|
67
|
+
<TRSTATUS>D</TRSTATUS>
|
|
68
|
+
</CTS_REQ_HEADER>
|
|
69
|
+
</root>\`;
|
|
70
|
+
|
|
71
|
+
const transports = parseUserTransportsXml(xml);
|
|
72
|
+
`})}),`
|
|
73
|
+
`,(0,c.jsx)(t.p,{children:`Алгоритм:`}),`
|
|
74
|
+
`,(0,c.jsxs)(t.ol,{children:[`
|
|
75
|
+
`,(0,c.jsxs)(t.li,{children:[`Пустая или состоящая из пробелов строка превращается в `,(0,c.jsx)(t.code,{children:`[]`}),`.`]}),`
|
|
76
|
+
`,(0,c.jsxs)(t.li,{children:[`XML разбирается `,(0,c.jsx)(t.code,{children:`fast-xml-parser`}),`.`]}),`
|
|
77
|
+
`,(0,c.jsxs)(t.li,{children:[`Во вложенной структуре рекурсивно ищутся узлы `,(0,c.jsx)(t.code,{children:`CTS_REQ_HEADER`}),`.`]}),`
|
|
78
|
+
`,(0,c.jsxs)(t.li,{children:[`Поля преобразуются в `,(0,c.jsx)(t.code,{children:`UserTransport`}),`.`]}),`
|
|
79
|
+
`,(0,c.jsxs)(t.li,{children:[`Записи без непустого `,(0,c.jsx)(t.code,{children:`TRKORR`}),` отбрасываются.`]}),`
|
|
80
|
+
`,(0,c.jsxs)(t.li,{children:[`Дубликаты `,(0,c.jsx)(t.code,{children:`transportNo`}),` удаляются; сохраняется первая запись.`]}),`
|
|
81
|
+
`,(0,c.jsxs)(t.li,{children:[`Если header-узлы не найдены, parser ищет вложенные `,(0,c.jsx)(t.code,{children:`TRKORR`}),` и создаёт минимальные записи.`]}),`
|
|
82
|
+
`]}),`
|
|
83
|
+
`,(0,c.jsxs)(t.p,{children:[`Parser делает `,(0,c.jsx)(t.code,{children:`trim`}),` строковых полей, но не декодирует бизнес-значения статуса/function и не проверяет их по справочнику SAP.`]}),`
|
|
84
|
+
`,(0,c.jsx)(t.p,{children:`Некорректный XML может привести к исключению parser-а. Функция не заменяет его пустым массивом: повреждённый ответ должен быть виден как ошибка.`}),`
|
|
85
|
+
`,(0,c.jsx)(t.h2,{id:`формат-результата`,children:`Формат результата`}),`
|
|
86
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`interface UserTransport {
|
|
87
|
+
transportNo: string;
|
|
88
|
+
description?: string;
|
|
89
|
+
owner?: string;
|
|
90
|
+
targetSystem?: string;
|
|
91
|
+
function?: string;
|
|
92
|
+
status?: string;
|
|
93
|
+
parentTransportNo?: string;
|
|
94
|
+
}
|
|
95
|
+
`})}),`
|
|
96
|
+
`,(0,c.jsx)(t.p,{children:`Соответствие XML:`}),`
|
|
97
|
+
`,(0,c.jsxs)(t.table,{children:[(0,c.jsx)(t.thead,{children:(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.th,{children:`XML`}),(0,c.jsx)(t.th,{children:`Поле`}),(0,c.jsx)(t.th,{children:`Значение`})]})}),(0,c.jsxs)(t.tbody,{children:[(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`TRKORR`})}),(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`transportNo`})}),(0,c.jsx)(t.td,{children:`Обязательный номер transport`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`AS4TEXT`})}),(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`description`})}),(0,c.jsx)(t.td,{children:`Описание`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`AS4USER`})}),(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`owner`})}),(0,c.jsx)(t.td,{children:`Владелец`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`TARSYSTEM`})}),(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`targetSystem`})}),(0,c.jsx)(t.td,{children:`Целевая система`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`TRFUNCTION`})}),(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`function`})}),(0,c.jsx)(t.td,{children:`SAP transport function`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`TRSTATUS`})}),(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`status`})}),(0,c.jsx)(t.td,{children:`SAP status`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`STRKORR`})}),(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`parentTransportNo`})}),(0,c.jsx)(t.td,{children:`Родительский request/task`})]})]})]}),`
|
|
98
|
+
`,(0,c.jsxs)(t.p,{children:[`Optional-поле может быть `,(0,c.jsx)(t.code,{children:`undefined`}),`. Проверяйте его перед отображением:`]}),`
|
|
99
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:"const label = transport.description\n ? `${transport.transportNo} — ${transport.description}`\n : transport.transportNo;\n"})}),`
|
|
100
|
+
`,(0,c.jsx)(t.h2,{id:`ошибки-и-ограничения`,children:`Ошибки и ограничения`}),`
|
|
101
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
102
|
+
`,(0,c.jsxs)(t.li,{children:[(0,c.jsx)(t.code,{children:`fast-xml-parser`}),` должен быть установлен в host, использующем этот entrypoint.`]}),`
|
|
103
|
+
`,(0,c.jsx)(t.li,{children:`Это не generic ADT client: endpoint и query parameters зафиксированы.`}),`
|
|
104
|
+
`,(0,c.jsx)(t.li,{children:`Функция не создаёт/не освобождает transport и не проверяет authorization.`}),`
|
|
105
|
+
`,(0,c.jsxs)(t.li,{children:[`SSO/cookies требуют browser/proxy окружения SAP. На server runtime поведение зависит от переданного глобального `,(0,c.jsx)(t.code,{children:`fetch`}),` и cookie boundary.`]}),`
|
|
106
|
+
`,(0,c.jsxs)(t.li,{children:[`HTML-response, HTTP error и XML parse error не превращаются в `,(0,c.jsx)(t.code,{children:`[]`}),`.`]}),`
|
|
107
|
+
`,(0,c.jsxs)(t.li,{children:[`Дедупликация выполняется только по `,(0,c.jsx)(t.code,{children:`transportNo`}),` и сохраняет первую найденную запись.`]}),`
|
|
108
|
+
`]}),`
|
|
109
|
+
`,(0,c.jsx)(t.h2,{id:`полный-api`,children:`Полный API`}),`
|
|
110
|
+
`,(0,c.jsxs)(t.table,{children:[(0,c.jsx)(t.thead,{children:(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.th,{children:`Export`}),(0,c.jsx)(t.th,{children:`Назначение`})]})}),(0,c.jsxs)(t.tbody,{children:[(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`fetchUserTransports`})}),(0,c.jsx)(t.td,{children:`Загружает и разбирает ADT XML`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`parseUserTransportsXml`})}),(0,c.jsx)(t.td,{children:`Преобразует XML string в массив`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`UserTransport`})}),(0,c.jsx)(t.td,{children:`Контракт результата`})]})]})]})]})}function s(e={}){let{wrapper:t}={...n(),...e.components};return t?(0,c.jsx)(t,{...e,children:(0,c.jsx)(o,{...e})}):o(e)}var c;function l(){return(l=e((()=>{c=t(),r(),a()})))()}l();export{s as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{n as e}from"./rolldown-runtime-DkW27tQK.js";import{n as t}from"./iframe-
|
|
1
|
+
import{n as e}from"./rolldown-runtime-DkW27tQK.js";import{n as t}from"./iframe-FSp_AjJa.js";import{i as n,r}from"./react-Bl2r1tuC.js";import{l as i,m as a}from"./blocks-B5YBxaaS.js";function o(e){let t={a:`a`,code:`code`,h1:`h1`,h2:`h2`,h3:`h3`,li:`li`,ol:`ol`,p:`p`,pre:`pre`,table:`table`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,...n(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(i,{title:`Foundation Lib/API/File`}),`
|
|
2
2
|
`,(0,c.jsxs)(t.h1,{id:`работа-с-пользовательскими-файлами-через-ryuzaki13react-foundation-libfile`,children:[`Работа с пользовательскими файлами через `,(0,c.jsx)(t.code,{children:`@ryuzaki13/react-foundation-lib/file`})]}),`
|
|
3
3
|
`,(0,c.jsxs)(t.p,{children:[`Модуль `,(0,c.jsx)(t.code,{children:`file`}),` содержит browser helpers для четырёх связанных задач:`]}),`
|
|
4
4
|
`,(0,c.jsxs)(t.ul,{children:[`
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import{n as e}from"./rolldown-runtime-DkW27tQK.js";import{n as t}from"./iframe-FSp_AjJa.js";import{i as n,r}from"./react-Bl2r1tuC.js";import{l as i,m as a}from"./blocks-B5YBxaaS.js";function o(e){let t={code:`code`,h1:`h1`,h2:`h2`,li:`li`,p:`p`,pre:`pre`,table:`table`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,...n(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(i,{title:`Foundation Lib/Data/Presets`}),`
|
|
2
|
+
`,(0,c.jsxs)(t.h1,{id:`общие-preset-helpers-через-ryuzaki13react-foundation-libpresets`,children:[`Общие preset helpers через `,(0,c.jsx)(t.code,{children:`@ryuzaki13/react-foundation-lib/presets`})]}),`
|
|
3
|
+
`,(0,c.jsx)(t.p,{children:`Модуль проверяет восстановленные preset ids, сопоставляет их с option objects и ищет одну option по id.`}),`
|
|
4
|
+
`,(0,c.jsx)(t.h2,{id:`установка-и-импорт`,children:`Установка и импорт`}),`
|
|
5
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`import { getPresetOption, normalizePresetIds, resolvePresetOptionsByIds } from "@ryuzaki13/react-foundation-lib/presets";
|
|
6
|
+
|
|
7
|
+
import type { PresetOption } from "@ryuzaki13/react-foundation-lib/presets";
|
|
8
|
+
`})}),`
|
|
9
|
+
`,(0,c.jsx)(t.p,{children:`Модуль не зависит от React/browser APIs.`}),`
|
|
10
|
+
`,(0,c.jsx)(t.h2,{id:`базовый-контракт`,children:`Базовый контракт`}),`
|
|
11
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`type PresetOption<TId extends string = string> = {
|
|
12
|
+
id: TId;
|
|
13
|
+
label: string;
|
|
14
|
+
};
|
|
15
|
+
`})}),`
|
|
16
|
+
`,(0,c.jsx)(t.p,{children:`Ваш тип может добавлять поля:`}),`
|
|
17
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`type ReportPreset = PresetOption<"daily" | "monthly"> & {
|
|
18
|
+
icon: string;
|
|
19
|
+
};
|
|
20
|
+
`})}),`
|
|
21
|
+
`,(0,c.jsx)(t.h2,{id:`normalizepresetids`,children:(0,c.jsx)(t.code,{children:`normalizePresetIds`})}),`
|
|
22
|
+
`,(0,c.jsxs)(t.p,{children:[`Функция предназначена для явной boundary восстановления сохранённого `,(0,c.jsx)(t.code,{children:`unknown`}),`:`]}),`
|
|
23
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`type PresetId = "first" | "second" | "third";
|
|
24
|
+
|
|
25
|
+
function isPresetId(value: unknown): value is PresetId {
|
|
26
|
+
return value === "first" || value === "second" || value === "third";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
normalizePresetIds(["second", "unknown", "second", "first"], isPresetId);
|
|
30
|
+
// ["second", "first"].
|
|
31
|
+
`})}),`
|
|
32
|
+
`,(0,c.jsx)(t.p,{children:`Алгоритм:`}),`
|
|
33
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
34
|
+
`,(0,c.jsxs)(t.li,{children:[`если `,(0,c.jsx)(t.code,{children:`value`}),` не массив — возвращается копия `,(0,c.jsx)(t.code,{children:`fallbackIds`}),`;`]}),`
|
|
35
|
+
`,(0,c.jsx)(t.li,{children:`если это массив — fallback не используется, даже для пустого массива;`}),`
|
|
36
|
+
`,(0,c.jsx)(t.li,{children:`элементы проверяются переданным type guard;`}),`
|
|
37
|
+
`,(0,c.jsx)(t.li,{children:`invalid ids пропускаются;`}),`
|
|
38
|
+
`,(0,c.jsx)(t.li,{children:`дубликаты удаляются;`}),`
|
|
39
|
+
`,(0,c.jsx)(t.li,{children:`сохраняется порядок первого допустимого вхождения.`}),`
|
|
40
|
+
`]}),`
|
|
41
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`normalizePresetIds(undefined, isPresetId, ["third"]); // ["third"].
|
|
42
|
+
normalizePresetIds([], isPresetId, ["third"]); // [].
|
|
43
|
+
`})}),`
|
|
44
|
+
`,(0,c.jsx)(t.p,{children:`Это normalizer сохранённого payload. Не вызывайте его внутри обычного input/store setter, если пользовательский draft должен храниться буквально.`}),`
|
|
45
|
+
`,(0,c.jsx)(t.h2,{id:`resolvepresetoptionsbyids`,children:(0,c.jsx)(t.code,{children:`resolvePresetOptionsByIds`})}),`
|
|
46
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const options = [
|
|
47
|
+
{ id: "first", label: "Первый" },
|
|
48
|
+
{ id: "second", label: "Второй" },
|
|
49
|
+
{ id: "third", label: "Третий" }
|
|
50
|
+
] as const;
|
|
51
|
+
|
|
52
|
+
const selected = resolvePresetOptionsByIds(["third", "first", "third", "missing"], options);
|
|
53
|
+
// objects third, first.
|
|
54
|
+
`})}),`
|
|
55
|
+
`,(0,c.jsx)(t.p,{children:`Правила:`}),`
|
|
56
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
57
|
+
`,(0,c.jsxs)(t.li,{children:[`порядок берётся из `,(0,c.jsx)(t.code,{children:`presetIds`}),`, а не из `,(0,c.jsx)(t.code,{children:`options`}),`;`]}),`
|
|
58
|
+
`,(0,c.jsx)(t.li,{children:`повторные ids добавляются один раз;`}),`
|
|
59
|
+
`,(0,c.jsxs)(t.li,{children:[`отсутствующие в `,(0,c.jsx)(t.code,{children:`options`}),` ids пропускаются;`]}),`
|
|
60
|
+
`,(0,c.jsx)(t.li,{children:`возвращается новый массив;`}),`
|
|
61
|
+
`,(0,c.jsx)(t.li,{children:`сами option objects не клонируются;`}),`
|
|
62
|
+
`,(0,c.jsxs)(t.li,{children:[`если в `,(0,c.jsx)(t.code,{children:`options`}),` повторяется id, `,(0,c.jsx)(t.code,{children:`Map`}),` оставляет последнюю option с этим id.`]}),`
|
|
63
|
+
`]}),`
|
|
64
|
+
`,(0,c.jsx)(t.h2,{id:`getpresetoption`,children:(0,c.jsx)(t.code,{children:`getPresetOption`})}),`
|
|
65
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`getPresetOption("second", options);
|
|
66
|
+
// { id: "second", label: "Второй" }.
|
|
67
|
+
|
|
68
|
+
getPresetOption("missing", options); // null.
|
|
69
|
+
getPresetOption(undefined, options); // null.
|
|
70
|
+
`})}),`
|
|
71
|
+
`,(0,c.jsxs)(t.p,{children:[`Функция использует первое совпадение `,(0,c.jsx)(t.code,{children:`options.find`}),`. Пустой id `,(0,c.jsx)(t.code,{children:`""`}),` считается отсутствующим и возвращает `,(0,c.jsx)(t.code,{children:`null`}),`.`]}),`
|
|
72
|
+
`,(0,c.jsx)(t.h2,{id:`saverestore-recipe`,children:`Save/restore recipe`}),`
|
|
73
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`function restorePresetIds(value: unknown): PresetId[] {
|
|
74
|
+
return normalizePresetIds(value, isPresetId, ["daily"]);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function buildPresetView(ids: readonly PresetId[]) {
|
|
78
|
+
return resolvePresetOptionsByIds(ids, PRESET_OPTIONS);
|
|
79
|
+
}
|
|
80
|
+
`})}),`
|
|
81
|
+
`,(0,c.jsx)(t.p,{children:`Разделяйте:`}),`
|
|
82
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-text`,children:`unknown persisted payload ── normalizePresetIds ──► canonical ids
|
|
83
|
+
literal UI draft ── clone only ──► literal copy
|
|
84
|
+
canonical ids ── resolve... ──► option objects for UI
|
|
85
|
+
`})}),`
|
|
86
|
+
`,(0,c.jsx)(t.h2,{id:`api-и-ошибки`,children:`API и ошибки`}),`
|
|
87
|
+
`,(0,c.jsxs)(t.table,{children:[(0,c.jsx)(t.thead,{children:(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.th,{children:`Export`}),(0,c.jsx)(t.th,{children:`Результат`})]})}),(0,c.jsxs)(t.tbody,{children:[(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`PresetOption`})}),(0,c.jsxs)(t.td,{children:[`Минимальный `,(0,c.jsx)(t.code,{children:`{ id, label }`}),` contract`]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`normalizePresetIds`})}),(0,c.jsx)(t.td,{children:`Проверенные уникальные ids`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`resolvePresetOptionsByIds`})}),(0,c.jsx)(t.td,{children:`Options в порядке ids`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`getPresetOption`})}),(0,c.jsxs)(t.td,{children:[`Option или `,(0,c.jsx)(t.code,{children:`null`})]})]})]})]}),`
|
|
88
|
+
`,(0,c.jsx)(t.p,{children:`Типичные ошибки:`}),`
|
|
89
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
90
|
+
`,(0,c.jsx)(t.li,{children:`Ожидать fallback для пустого массива.`}),`
|
|
91
|
+
`,(0,c.jsx)(t.li,{children:`Считать result options глубокими копиями.`}),`
|
|
92
|
+
`,(0,c.jsx)(t.li,{children:`Использовать normalizer во время пользовательского ввода.`}),`
|
|
93
|
+
`,(0,c.jsx)(t.li,{children:`Передавать type guard, который делает unsafe cast вместо runtime-проверки.`}),`
|
|
94
|
+
`,(0,c.jsx)(t.li,{children:`Ожидать, что неизвестный id будет создан автоматически.`}),`
|
|
95
|
+
`]})]})}function s(e={}){let{wrapper:t}={...n(),...e.components};return t?(0,c.jsx)(t,{...e,children:(0,c.jsx)(o,{...e})}):o(e)}var c;function l(){return(l=e((()=>{c=t(),r(),a()})))()}l();export{s as default};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import{n as e}from"./rolldown-runtime-DkW27tQK.js";import{n as t}from"./iframe-FSp_AjJa.js";import{i as n,r}from"./react-Bl2r1tuC.js";import{l as i,m as a}from"./blocks-B5YBxaaS.js";function o(e){let t={code:`code`,h1:`h1`,h2:`h2`,li:`li`,p:`p`,pre:`pre`,ul:`ul`,...n(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(i,{title:`Foundation Lib/Browser/Client Fingerprint`}),`
|
|
2
|
+
`,(0,c.jsxs)(t.h1,{id:`client-fingerprint-через-ryuzaki13react-foundation-libfingerprint`,children:[`Client fingerprint через `,(0,c.jsx)(t.code,{children:`@ryuzaki13/react-foundation-lib/fingerprint`})]}),`
|
|
3
|
+
`,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`getClientFingerprint`}),` лениво загружает FingerprintJS, получает `,(0,c.jsx)(t.code,{children:`visitorId`}),` и кеширует Promise на всё время жизни JavaScript-модуля.`]}),`
|
|
4
|
+
`,(0,c.jsx)(t.h2,{id:`установка-и-импорт`,children:`Установка и импорт`}),`
|
|
5
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-bash`,children:`npm install @ryuzaki13/react-foundation-lib @fingerprintjs/fingerprintjs
|
|
6
|
+
`})}),`
|
|
7
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`import { getClientFingerprint } from "@ryuzaki13/react-foundation-lib/fingerprint";
|
|
8
|
+
`})}),`
|
|
9
|
+
`,(0,c.jsxs)(t.p,{children:[`Host должен разрешить peer dependency `,(0,c.jsx)(t.code,{children:`@fingerprintjs/fingerprintjs >=5 <6`}),`.`]}),`
|
|
10
|
+
`,(0,c.jsx)(t.h2,{id:`использование`,children:`Использование`}),`
|
|
11
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const fingerprint = await getClientFingerprint();
|
|
12
|
+
|
|
13
|
+
if (fingerprint) {
|
|
14
|
+
attachAnonymousDiagnosticId(fingerprint);
|
|
15
|
+
}
|
|
16
|
+
`})}),`
|
|
17
|
+
`,(0,c.jsxs)(t.p,{children:[`Результат `,(0,c.jsx)(t.code,{children:`Promise<string | null>`}),`:`]}),`
|
|
18
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
19
|
+
`,(0,c.jsxs)(t.li,{children:[`непустой trimmed `,(0,c.jsx)(t.code,{children:`visitorId`}),`, если библиотека успешно отработала;`]}),`
|
|
20
|
+
`,(0,c.jsxs)(t.li,{children:[(0,c.jsx)(t.code,{children:`null`}),` вне browser;`]}),`
|
|
21
|
+
`,(0,c.jsxs)(t.li,{children:[(0,c.jsx)(t.code,{children:`null`}),`, если load/get завершились ошибкой;`]}),`
|
|
22
|
+
`,(0,c.jsxs)(t.li,{children:[(0,c.jsx)(t.code,{children:`null`}),`, если visitorId пустой после trim.`]}),`
|
|
23
|
+
`]}),`
|
|
24
|
+
`,(0,c.jsx)(t.h2,{id:`кеширование`,children:`Кеширование`}),`
|
|
25
|
+
`,(0,c.jsx)(t.p,{children:`Первый browser-вызов создаёт одну Promise:`}),`
|
|
26
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-text`,children:`первый вызов ──► load FingerprintJS ──► fp.get() ──► string/null
|
|
27
|
+
│
|
|
28
|
+
следующие вызовы ─────────────────────► та же Promise
|
|
29
|
+
`})}),`
|
|
30
|
+
`,(0,c.jsx)(t.p,{children:`Преимущества:`}),`
|
|
31
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
32
|
+
`,(0,c.jsx)(t.li,{children:`параллельные consumers не запускают повторное вычисление;`}),`
|
|
33
|
+
`,(0,c.jsx)(t.li,{children:`после успеха возвращается то же значение;`}),`
|
|
34
|
+
`,(0,c.jsxs)(t.li,{children:[`после ошибки `,(0,c.jsx)(t.code,{children:`null`}),` также кешируется и автоматического retry нет.`]}),`
|
|
35
|
+
`]}),`
|
|
36
|
+
`,(0,c.jsx)(t.p,{children:`Публичного reset/retry API нет. Reload страницы создаёт новый module runtime.`}),`
|
|
37
|
+
`,(0,c.jsxs)(t.p,{children:[`SSR-вызов возвращает `,(0,c.jsx)(t.code,{children:`null`}),` сразу и не заполняет browser promise cache. Поэтому последующий client runtime может выполнить настоящее вычисление.`]}),`
|
|
38
|
+
`,(0,c.jsx)(t.h2,{id:`правильная-react-boundary`,children:`Правильная React boundary`}),`
|
|
39
|
+
`,(0,c.jsx)(t.p,{children:`Не вызывайте async функцию во время render:`}),`
|
|
40
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-tsx`,children:`useEffect(() => {
|
|
41
|
+
let active = true;
|
|
42
|
+
|
|
43
|
+
void getClientFingerprint().then((value) => {
|
|
44
|
+
if (active) setFingerprint(value);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
return () => {
|
|
48
|
+
active = false;
|
|
49
|
+
};
|
|
50
|
+
}, []);
|
|
51
|
+
`})}),`
|
|
52
|
+
`,(0,c.jsx)(t.p,{children:`Если fingerprint нужен backend request, предпочтительнее интегрировать его в app/API boundary, а не дублировать state по компонентам.`}),`
|
|
53
|
+
`,(0,c.jsx)(t.h2,{id:`privacy-и-security`,children:`Privacy и security`}),`
|
|
54
|
+
`,(0,c.jsx)(t.p,{children:`Fingerprint:`}),`
|
|
55
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
56
|
+
`,(0,c.jsx)(t.li,{children:`не является authentication token;`}),`
|
|
57
|
+
`,(0,c.jsx)(t.li,{children:`не доказывает личность пользователя;`}),`
|
|
58
|
+
`,(0,c.jsx)(t.li,{children:`может меняться после обновления browser/device/settings;`}),`
|
|
59
|
+
`,(0,c.jsx)(t.li,{children:`может совпасть у разных клиентов;`}),`
|
|
60
|
+
`,(0,c.jsx)(t.li,{children:`не заменяет server session;`}),`
|
|
61
|
+
`,(0,c.jsx)(t.li,{children:`требует правового/продуктового решения о consent и retention;`}),`
|
|
62
|
+
`,(0,c.jsx)(t.li,{children:`не должен использоваться для скрытого tracking вопреки пользовательской политике.`}),`
|
|
63
|
+
`]}),`
|
|
64
|
+
`,(0,c.jsx)(t.p,{children:`Не помещайте fingerprint в публичный URL, DOM или logs без необходимости. При передаче на backend используйте HTTPS и установленную privacy policy.`}),`
|
|
65
|
+
`,(0,c.jsx)(t.h2,{id:`ошибки-и-тестирование`,children:`Ошибки и тестирование`}),`
|
|
66
|
+
`,(0,c.jsxs)(t.p,{children:[`Функция намеренно поглощает ошибки FingerprintJS и возвращает `,(0,c.jsx)(t.code,{children:`null`}),`. Это graceful optional capability; если fingerprint обязателен для business flow, host должен явно обработать `,(0,c.jsx)(t.code,{children:`null`}),`.`]}),`
|
|
67
|
+
`,(0,c.jsxs)(t.p,{children:[`Module-level cache усложняет повторные тесты. Используйте module reset (`,(0,c.jsx)(t.code,{children:`vi.resetModules`}),`) перед сценарием, которому нужен чистый первый вызов.`]}),`
|
|
68
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`function getClientFingerprint(): Promise<string | null>;
|
|
69
|
+
`})})]})}function s(e={}){let{wrapper:t}={...n(),...e.components};return t?(0,c.jsx)(t,{...e,children:(0,c.jsx)(o,{...e})}):o(e)}var c;function l(){return(l=e((()=>{c=t(),r(),a()})))()}l();export{s as default};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import{n as e}from"./rolldown-runtime-DkW27tQK.js";import{n as t}from"./iframe-FSp_AjJa.js";import{i as n,r}from"./react-Bl2r1tuC.js";import{l as i,m as a}from"./blocks-B5YBxaaS.js";function o(e){let t={code:`code`,h1:`h1`,h2:`h2`,li:`li`,p:`p`,pre:`pre`,ul:`ul`,...n(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(i,{title:`Foundation Lib/Browser/Session Storage ID`}),`
|
|
2
|
+
`,(0,c.jsxs)(t.h1,{id:`идентификатор-вкладочной-сессии-через-ryuzaki13react-foundation-libsession-storage`,children:[`Идентификатор вкладочной сессии через `,(0,c.jsx)(t.code,{children:`@ryuzaki13/react-foundation-lib/session-storage`})]}),`
|
|
3
|
+
`,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`getSessionStorageId`}),` возвращает стабильный id в пределах одной browser-вкладки. При первом вызове id создаётся и сохраняется в `,(0,c.jsx)(t.code,{children:`sessionStorage`}),`, при следующих — читается по тому же ключу.`]}),`
|
|
4
|
+
`,(0,c.jsx)(t.h2,{id:`установка-и-импорт`,children:`Установка и импорт`}),`
|
|
5
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`import { getSessionStorageId } from "@ryuzaki13/react-foundation-lib/session-storage";
|
|
6
|
+
`})}),`
|
|
7
|
+
`,(0,c.jsxs)(t.p,{children:[`Default generator — `,(0,c.jsx)(t.code,{children:`uuidv4`}),` из `,(0,c.jsx)(t.code,{children:`/crypto`}),`.`]}),`
|
|
8
|
+
`,(0,c.jsx)(t.h2,{id:`базовый-пример`,children:`Базовый пример`}),`
|
|
9
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const sessionId = getSessionStorageId("sales-app.error-report.session.v1");
|
|
10
|
+
`})}),`
|
|
11
|
+
`,(0,c.jsx)(t.p,{children:`Повторный вызов в той же вкладке:`}),`
|
|
12
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const first = getSessionStorageId("sales-app.session.v1");
|
|
13
|
+
const second = getSessionStorageId("sales-app.session.v1");
|
|
14
|
+
|
|
15
|
+
console.log(first === second); // true, если storage доступен.
|
|
16
|
+
`})}),`
|
|
17
|
+
`,(0,c.jsxs)(t.p,{children:[`Другая вкладка имеет отдельный `,(0,c.jsx)(t.code,{children:`sessionStorage`}),` и обычно получит другой id.`]}),`
|
|
18
|
+
`,(0,c.jsx)(t.h2,{id:`алгоритм`,children:`Алгоритм`}),`
|
|
19
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-text`,children:`sessionStorage недоступен ──► createId() без сохранения
|
|
20
|
+
│
|
|
21
|
+
▼
|
|
22
|
+
getItem(key)
|
|
23
|
+
├─ непустая строка ──────► вернуть её
|
|
24
|
+
└─ нет значения ─────────► createId() → setItem → вернуть id
|
|
25
|
+
|
|
26
|
+
ошибка getItem/setItem ─────► fallback createId()
|
|
27
|
+
`})}),`
|
|
28
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const id = getSessionStorageId("demo.session", () => "known-id");
|
|
29
|
+
`})}),`
|
|
30
|
+
`,(0,c.jsx)(t.p,{children:`Второй аргумент удобен для теста или другого генератора.`}),`
|
|
31
|
+
`,(0,c.jsx)(t.h2,{id:`граница-стабильности`,children:`Граница стабильности`}),`
|
|
32
|
+
`,(0,c.jsx)(t.p,{children:`Идентификатор стабилен только при успешном storage:`}),`
|
|
33
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
34
|
+
`,(0,c.jsx)(t.li,{children:`reload той же вкладки обычно сохраняет значение;`}),`
|
|
35
|
+
`,(0,c.jsx)(t.li,{children:`новая вкладка получает своё storage;`}),`
|
|
36
|
+
`,(0,c.jsx)(t.li,{children:`закрытие вкладки удаляет session storage по правилам браузера;`}),`
|
|
37
|
+
`,(0,c.jsx)(t.li,{children:`privacy policy, sandbox iframe или переполнение могут запретить доступ;`}),`
|
|
38
|
+
`,(0,c.jsx)(t.li,{children:`если storage недоступен, каждый вызов может создать новый fallback id.`}),`
|
|
39
|
+
`]}),`
|
|
40
|
+
`,(0,c.jsx)(t.p,{children:`Функция ловит ошибки чтения/записи и не ломает основной пользовательский сценарий.`}),`
|
|
41
|
+
`,(0,c.jsxs)(t.p,{children:[`Если `,(0,c.jsx)(t.code,{children:`setItem`}),` выбросил ошибку после первого вызова generator, fallback generator может быть вызван повторно. Не используйте `,(0,c.jsx)(t.code,{children:`createId`}),` с внешними необратимыми side effects.`]}),`
|
|
42
|
+
`,(0,c.jsx)(t.h2,{id:`ключ-storage`,children:`Ключ storage`}),`
|
|
43
|
+
`,(0,c.jsx)(t.p,{children:`Ключ полностью задаёт host. Рекомендуемый формат:`}),`
|
|
44
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-text`,children:`<app-id>.<purpose>.v<schema-version>
|
|
45
|
+
`})}),`
|
|
46
|
+
`,(0,c.jsx)(t.p,{children:`Примеры:`}),`
|
|
47
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-text`,children:`sales-app.error-report.session.v1
|
|
48
|
+
warehouse.telemetry.tab-session.v2
|
|
49
|
+
`})}),`
|
|
50
|
+
`,(0,c.jsx)(t.p,{children:`Не используйте один ключ для несвязанных подсистем. При изменении семантики меняйте версию.`}),`
|
|
51
|
+
`,(0,c.jsx)(t.h2,{id:`ssr-и-безопасность`,children:`SSR и безопасность`}),`
|
|
52
|
+
`,(0,c.jsxs)(t.p,{children:[`Вне browser `,(0,c.jsx)(t.code,{children:`sessionStorage`}),` отсутствует, поэтому функция просто возвращает новый id generator-а. Она не пытается создать server session.`]}),`
|
|
53
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`const id = getSessionStorageId("demo", () => "server-fallback");
|
|
54
|
+
`})}),`
|
|
55
|
+
`,(0,c.jsx)(t.p,{children:`Идентификатор:`}),`
|
|
56
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
57
|
+
`,(0,c.jsx)(t.li,{children:`не является authentication token;`}),`
|
|
58
|
+
`,(0,c.jsx)(t.li,{children:`не подтверждает пользователя;`}),`
|
|
59
|
+
`,(0,c.jsx)(t.li,{children:`не должен давать доступ к данным;`}),`
|
|
60
|
+
`,(0,c.jsx)(t.li,{children:`не является cross-tab device id;`}),`
|
|
61
|
+
`,(0,c.jsx)(t.li,{children:`не должен включать персональные данные.`}),`
|
|
62
|
+
`]}),`
|
|
63
|
+
`,(0,c.jsxs)(t.p,{children:[`Для долговременного client fingerprint используйте отдельный `,(0,c.jsx)(t.code,{children:`/fingerprint`}),`, понимая его privacy-границы.`]}),`
|
|
64
|
+
`,(0,c.jsx)(t.h2,{id:`тестирование`,children:`Тестирование`}),`
|
|
65
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`sessionStorage.clear();
|
|
66
|
+
|
|
67
|
+
const createId = vi.fn(() => "session-1");
|
|
68
|
+
|
|
69
|
+
expect(getSessionStorageId("test.session", createId)).toBe("session-1");
|
|
70
|
+
expect(getSessionStorageId("test.session", () => "session-2")).toBe("session-1");
|
|
71
|
+
expect(createId).toHaveBeenCalledOnce();
|
|
72
|
+
`})}),`
|
|
73
|
+
`,(0,c.jsxs)(t.p,{children:[`Очищайте `,(0,c.jsx)(t.code,{children:`sessionStorage`}),` между тестами.`]}),`
|
|
74
|
+
`,(0,c.jsx)(t.h2,{id:`api-и-ошибки`,children:`API и ошибки`}),`
|
|
75
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`function getSessionStorageId(key: string, createId?: () => string): string;
|
|
76
|
+
`})}),`
|
|
77
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
78
|
+
`,(0,c.jsx)(t.li,{children:`Пустой сохранённый string считается отсутствующим и заменяется.`}),`
|
|
79
|
+
`,(0,c.jsx)(t.li,{children:`Ключ и результат generator не валидируются.`}),`
|
|
80
|
+
`,(0,c.jsx)(t.li,{children:`Исключение самого fallback generator может быть проброшено.`}),`
|
|
81
|
+
`,(0,c.jsx)(t.li,{children:`Функция ничего не удаляет из storage.`}),`
|
|
82
|
+
`]})]})}function s(e={}){let{wrapper:t}={...n(),...e.components};return t?(0,c.jsx)(t,{...e,children:(0,c.jsx)(o,{...e})}):o(e)}var c;function l(){return(l=e((()=>{c=t(),r(),a()})))()}l();export{s as default};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import{n as e}from"./rolldown-runtime-DkW27tQK.js";import{n as t}from"./iframe-FSp_AjJa.js";import{i as n,r}from"./react-Bl2r1tuC.js";import{l as i,m as a}from"./blocks-B5YBxaaS.js";function o(e){let t={code:`code`,h1:`h1`,h2:`h2`,li:`li`,p:`p`,pre:`pre`,table:`table`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,...n(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(i,{title:`Foundation Lib/React/Virtualizer Pagination`}),`
|
|
2
|
+
`,(0,c.jsxs)(t.h1,{id:`дозагрузка-virtualized-списка-через-ryuzaki13react-foundation-libvirtualizer`,children:[`Дозагрузка virtualized списка через `,(0,c.jsx)(t.code,{children:`@ryuzaki13/react-foundation-lib/virtualizer`})]}),`
|
|
3
|
+
`,(0,c.jsxs)(t.p,{children:[(0,c.jsx)(t.code,{children:`useFetchNextPageEffect`}),` вызывает `,(0,c.jsx)(t.code,{children:`fetchNextPage`}),`, когда последняя отрендеренная virtual item достигает конца уже загруженного списка.`]}),`
|
|
4
|
+
`,(0,c.jsx)(t.h2,{id:`установка-и-импорт`,children:`Установка и импорт`}),`
|
|
5
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-bash`,children:`npm install react @tanstack/react-virtual @ryuzaki13/react-foundation-lib
|
|
6
|
+
`})}),`
|
|
7
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`import { useFetchNextPageEffect } from "@ryuzaki13/react-foundation-lib/virtualizer";
|
|
8
|
+
`})}),`
|
|
9
|
+
`,(0,c.jsxs)(t.p,{children:[`Host должен использовать совместимые peer dependencies React `,(0,c.jsx)(t.code,{children:`>=19.2 <20`}),` и `,(0,c.jsx)(t.code,{children:`@tanstack/react-virtual >=3.14 <4`}),`.`]}),`
|
|
10
|
+
`,(0,c.jsx)(t.h2,{id:`назначение-и-границы`,children:`Назначение и границы`}),`
|
|
11
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-text`,children:`virtualItems (видимый диапазон)
|
|
12
|
+
currentItemsCount (сколько уже загружено)
|
|
13
|
+
hasNextPage
|
|
14
|
+
│
|
|
15
|
+
последний virtual index >= currentItemsCount - 1
|
|
16
|
+
│
|
|
17
|
+
▼
|
|
18
|
+
fetchNextPage() один раз до завершения Promise
|
|
19
|
+
`})}),`
|
|
20
|
+
`,(0,c.jsx)(t.p,{children:`Hook не создаёт virtualizer, не хранит backend data, не строит query key и не решает server pagination. TanStack Query должен оставаться владельцем server snapshot.`}),`
|
|
21
|
+
`,(0,c.jsx)(t.h2,{id:`сигнатура`,children:`Сигнатура`}),`
|
|
22
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`useFetchNextPageEffect({
|
|
23
|
+
virtualItems,
|
|
24
|
+
currentItemsCount,
|
|
25
|
+
fetchNextPage,
|
|
26
|
+
hasNextPage
|
|
27
|
+
});
|
|
28
|
+
`})}),`
|
|
29
|
+
`,(0,c.jsxs)(t.table,{children:[(0,c.jsx)(t.thead,{children:(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.th,{children:`Поле`}),(0,c.jsx)(t.th,{children:`Значение`})]})}),(0,c.jsxs)(t.tbody,{children:[(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`virtualItems`})}),(0,c.jsxs)(t.td,{children:[`Текущий массив `,(0,c.jsx)(t.code,{children:`VirtualItem[]`})]})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`currentItemsCount`})}),(0,c.jsx)(t.td,{children:`Число реально загруженных data items`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`hasNextPage`})}),(0,c.jsx)(t.td,{children:`Есть ли следующая server page`})]}),(0,c.jsxs)(t.tr,{children:[(0,c.jsx)(t.td,{children:(0,c.jsx)(t.code,{children:`fetchNextPage`})}),(0,c.jsx)(t.td,{children:`Stable функция, возвращающая Promise`})]})]})]}),`
|
|
30
|
+
`,(0,c.jsx)(t.p,{children:`Hook ничего не возвращает.`}),`
|
|
31
|
+
`,(0,c.jsx)(t.h2,{id:`пример-с-tanstack-queryvirtual`,children:`Пример с TanStack Query/Virtual`}),`
|
|
32
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-tsx`,children:`const rows = query.data?.pages.flatMap((page) => page.rows) ?? [];
|
|
33
|
+
const virtualItems = virtualizer.getVirtualItems();
|
|
34
|
+
|
|
35
|
+
useFetchNextPageEffect({
|
|
36
|
+
virtualItems,
|
|
37
|
+
currentItemsCount: rows.length,
|
|
38
|
+
hasNextPage: query.hasNextPage,
|
|
39
|
+
fetchNextPage: async () => {
|
|
40
|
+
await query.fetchNextPage();
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
`})}),`
|
|
44
|
+
`,(0,c.jsx)(t.p,{children:`Передавайте количество загруженных строк, а не virtual total с loader row, group headers или estimated backend count.`}),`
|
|
45
|
+
`,(0,c.jsx)(t.h2,{id:`точный-trigger`,children:`Точный trigger`}),`
|
|
46
|
+
`,(0,c.jsx)(t.p,{children:`Fetch не запускается, если:`}),`
|
|
47
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
48
|
+
`,(0,c.jsxs)(t.li,{children:[(0,c.jsx)(t.code,{children:`virtualItems`}),` пуст;`]}),`
|
|
49
|
+
`,(0,c.jsxs)(t.li,{children:[(0,c.jsx)(t.code,{children:`currentItemsCount`}),` равен `,(0,c.jsx)(t.code,{children:`0`}),`;`]}),`
|
|
50
|
+
`,(0,c.jsxs)(t.li,{children:[`последняя virtual item ещё не достигла `,(0,c.jsx)(t.code,{children:`currentItemsCount - 1`}),`;`]}),`
|
|
51
|
+
`,(0,c.jsxs)(t.li,{children:[(0,c.jsx)(t.code,{children:`hasNextPage === false`}),`;`]}),`
|
|
52
|
+
`,(0,c.jsx)(t.li,{children:`предыдущий вызов ещё не завершился.`}),`
|
|
53
|
+
`]}),`
|
|
54
|
+
`,(0,c.jsx)(t.p,{children:`Trigger происходит строго на последнем загруженном индексе. Preload threshold «за N строк до конца» в API отсутствует.`}),`
|
|
55
|
+
`,(0,c.jsx)(t.h2,{id:`защита-от-параллельного-fetch`,children:`Защита от параллельного fetch`}),`
|
|
56
|
+
`,(0,c.jsxs)(t.p,{children:[`Внутренний `,(0,c.jsx)(t.code,{children:`useRef(false)`}),` устанавливается до вызова и сбрасывается в `,(0,c.jsx)(t.code,{children:`.finally()`}),`:`]}),`
|
|
57
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-text`,children:`idle ── trigger ──► fetchingRef=true
|
|
58
|
+
│
|
|
59
|
+
Promise pending
|
|
60
|
+
│
|
|
61
|
+
resolve или reject
|
|
62
|
+
▼
|
|
63
|
+
fetchingRef=false
|
|
64
|
+
`})}),`
|
|
65
|
+
`,(0,c.jsx)(t.p,{children:`Защита действует только внутри одного mounted hook instance. TanStack Query также должен владеть дедупликацией/network state.`}),`
|
|
66
|
+
`,(0,c.jsxs)(t.p,{children:[`Если `,(0,c.jsx)(t.code,{children:`fetchNextPage`}),` отклоняет Promise, hook не добавляет `,(0,c.jsx)(t.code,{children:`.catch`}),`; rejection может стать unhandled. Передавайте функцию с принятой error policy или wrapper, который корректно обрабатывает ожидаемую ошибку.`]}),`
|
|
67
|
+
`,(0,c.jsx)(t.h2,{id:`referential-stability`,children:`Referential stability`}),`
|
|
68
|
+
`,(0,c.jsxs)(t.p,{children:[`Effect зависит от `,(0,c.jsx)(t.code,{children:`virtualItems`}),`, `,(0,c.jsx)(t.code,{children:`currentItemsCount`}),`, `,(0,c.jsx)(t.code,{children:`hasNextPage`}),`, `,(0,c.jsx)(t.code,{children:`fetchNextPage`}),`.`]}),`
|
|
69
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
70
|
+
`,(0,c.jsx)(t.li,{children:`Используйте значение virtualizer как предусмотрено его API.`}),`
|
|
71
|
+
`,(0,c.jsx)(t.li,{children:`Не создавайте лишний async callback с новой identity без причины.`}),`
|
|
72
|
+
`,(0,c.jsx)(t.li,{children:`React Compiler не отменяет необходимость stable external contract.`}),`
|
|
73
|
+
`,(0,c.jsxs)(t.li,{children:[`После увеличения `,(0,c.jsx)(t.code,{children:`currentItemsCount`}),` новый fetch произойдёт только когда virtual range достигнет нового конца.`]}),`
|
|
74
|
+
`]}),`
|
|
75
|
+
`,(0,c.jsx)(t.h2,{id:`browser-ssr-и-lifecycle`,children:`Browser, SSR и lifecycle`}),`
|
|
76
|
+
`,(0,c.jsxs)(t.p,{children:[`Сам hook не читает `,(0,c.jsx)(t.code,{children:`window`}),`, но является React effect и не выполняет fetch во время server render. В browser effect запускается после commit.`]}),`
|
|
77
|
+
`,(0,c.jsxs)(t.p,{children:[`При unmount Promise не отменяется. Abort/cancel должен быть реализован query/transport owner. `,(0,c.jsx)(t.code,{children:`fetchingRef`}),` больше не влияет после удаления hook instance.`]}),`
|
|
78
|
+
`,(0,c.jsx)(t.h2,{id:`типичные-ошибки`,children:`Типичные ошибки`}),`
|
|
79
|
+
`,(0,c.jsxs)(t.ul,{children:[`
|
|
80
|
+
`,(0,c.jsx)(t.li,{children:`Передать total backend rows вместо количества загруженного массива.`}),`
|
|
81
|
+
`,(0,c.jsx)(t.li,{children:`Включить client-side sorting/filtering одной страницы при server-side модели.`}),`
|
|
82
|
+
`,(0,c.jsxs)(t.li,{children:[`Добавить фиктивный loader row в `,(0,c.jsx)(t.code,{children:`currentItemsCount`}),`.`]}),`
|
|
83
|
+
`,(0,c.jsx)(t.li,{children:`Ожидать preload заранее — trigger находится на самом конце.`}),`
|
|
84
|
+
`,(0,c.jsx)(t.li,{children:`Передать rejecting Promise без error handling.`}),`
|
|
85
|
+
`,(0,c.jsx)(t.li,{children:`Выполнять fetch прямо в row render вместо effect.`}),`
|
|
86
|
+
`,(0,c.jsx)(t.li,{children:`Использовать изменяемый index как domain identity строки.`}),`
|
|
87
|
+
`]}),`
|
|
88
|
+
`,(0,c.jsx)(t.h2,{id:`api`,children:`API`}),`
|
|
89
|
+
`,(0,c.jsx)(t.pre,{children:(0,c.jsx)(t.code,{className:`language-ts`,children:`function useFetchNextPageEffect(args: {
|
|
90
|
+
virtualItems: VirtualItem[];
|
|
91
|
+
currentItemsCount: number;
|
|
92
|
+
hasNextPage: boolean;
|
|
93
|
+
fetchNextPage: () => Promise<unknown>;
|
|
94
|
+
}): void;
|
|
95
|
+
`})})]})}function s(e={}){let{wrapper:t}={...n(),...e.components};return t?(0,c.jsx)(t,{...e,children:(0,c.jsx)(o,{...e})}):o(e)}var c;function l(){return(l=e((()=>{c=t(),r(),a()})))()}l();export{s as default};
|