@ryuzaki13/react-foundation-ui 1.3.2 → 1.4.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.
Files changed (241) hide show
  1. package/dist/advanced-search/index.js +1 -1
  2. package/dist/chunks/button-CC0Jdx1j.js.map +1 -1
  3. package/dist/chunks/{multi-select-DgSwr3Pf.js → multi-select-CWx12rgb.js} +2 -2
  4. package/dist/chunks/{multi-select-DgSwr3Pf.js.map → multi-select-CWx12rgb.js.map} +1 -1
  5. package/dist/chunks/{select-kZQRRj2e.js → select-BPb-eL3O.js} +2 -2
  6. package/dist/chunks/{select-kZQRRj2e.js.map → select-BPb-eL3O.js.map} +1 -1
  7. package/dist/chunks/{useODataSelectBase-CWBR3WCn.js → useODataSelectBase-CKe1AVMI.js} +4 -4
  8. package/dist/chunks/useODataSelectBase-CKe1AVMI.js.map +1 -0
  9. package/dist/multi-select/index.js +1 -1
  10. package/dist/preset-select/index.js +1 -1
  11. package/dist/select/SelectOptionContent.d.ts +5 -1
  12. package/dist/select/SelectOptionContent.d.ts.map +1 -1
  13. package/dist/select/index.js +1 -1
  14. package/dist/state-select/index.js +1 -1
  15. package/dist/styles.css +1 -1
  16. package/dist/tree-select/ODataTreeMultiSelect.d.ts +6 -1
  17. package/dist/tree-select/ODataTreeMultiSelect.d.ts.map +1 -1
  18. package/dist/tree-select/ODataTreeSelect.d.ts +6 -1
  19. package/dist/tree-select/ODataTreeSelect.d.ts.map +1 -1
  20. package/dist/tree-select/TreeMultiSelect.d.ts +6 -1
  21. package/dist/tree-select/TreeMultiSelect.d.ts.map +1 -1
  22. package/dist/tree-select/TreeNodeContent.d.ts.map +1 -1
  23. package/dist/tree-select/TreePickerBase.d.ts +2 -1
  24. package/dist/tree-select/TreePickerBase.d.ts.map +1 -1
  25. package/dist/tree-select/TreeSelect.d.ts +6 -1
  26. package/dist/tree-select/TreeSelect.d.ts.map +1 -1
  27. package/dist/tree-select/index.js +339 -239
  28. package/dist/tree-select/index.js.map +1 -1
  29. package/dist/tree-select/model/buildTreeColumnsLayoutDescriptor.d.ts +24 -0
  30. package/dist/tree-select/model/buildTreeColumnsLayoutDescriptor.d.ts.map +1 -0
  31. package/dist/tree-select/model/resolveBalancedTreeColumnsLayout.d.ts +26 -4
  32. package/dist/tree-select/model/resolveBalancedTreeColumnsLayout.d.ts.map +1 -1
  33. package/dist/tree-select/model/treeUtils.d.ts +8 -0
  34. package/dist/tree-select/model/treeUtils.d.ts.map +1 -1
  35. package/package.json +1 -1
  36. package/storybook-static/assets/{Badge-zkZEH9YA.js → Badge-gSh8l-os.js} +1 -1
  37. package/storybook-static/assets/{Badge.stories-DtP9p0kq.js → Badge.stories-BS7dTFrU.js} +1 -1
  38. package/storybook-static/assets/{Button-zPlrr4BS.js → Button-CIsa_NLR.js} +1 -1
  39. package/storybook-static/assets/{Button-DMl-6JIb.js → Button-YeLofqo6.js} +1 -1
  40. package/storybook-static/assets/Button-nI2z0h4X.css +1 -0
  41. package/storybook-static/assets/{Button.stories-D6RyOgsB.js → Button.stories-Bhb87Dqw.js} +1 -1
  42. package/storybook-static/assets/{CheckBox-BaG7s4Cz.js → CheckBox-BEkP7-_V.js} +1 -1
  43. package/storybook-static/assets/{CheckBox-DNBF3Ks-.js → CheckBox-zKT33Upg.js} +1 -1
  44. package/storybook-static/assets/{CheckBox.stories-9T8Rsd8X.js → CheckBox.stories-CoXcAm05.js} +1 -1
  45. package/storybook-static/assets/{Color-KMSTOMOX-DquhuvgS.js → Color-KMSTOMOX-hhoYimsF.js} +1 -1
  46. package/storybook-static/assets/{ContextMenu-B7nXceEQ.js → ContextMenu-DyY1tQ1E.js} +1 -1
  47. package/storybook-static/assets/{ContextMenu.stories-DbMPw1v9.js → ContextMenu.stories-x8GI34yZ.js} +1 -1
  48. package/storybook-static/assets/{DateInput-6tKLbofj.js → DateInput-BhFywEgL.js} +1 -1
  49. package/storybook-static/assets/{DateInput-CoUys1jD.js → DateInput-DKFrWLZc.js} +1 -1
  50. package/storybook-static/assets/{DateInput.stories-DsLpE_GF.js → DateInput.stories-CcGZPbRD.js} +1 -1
  51. package/storybook-static/assets/{DateRangePresetSelect-BOzYLOjf.js → DateRangePresetSelect-BUq-lz30.js} +1 -1
  52. package/storybook-static/assets/{DateRangePresetSelect-A3v5EWNz.js → DateRangePresetSelect-B_97NkVH.js} +1 -1
  53. package/storybook-static/assets/{DateRangePresetSelect.stories-BZvsBzQk.js → DateRangePresetSelect.stories-DiMDIy2Y.js} +1 -1
  54. package/storybook-static/assets/{Detail-DCJ4loww.js → Detail-CW2ecf5q.js} +1 -1
  55. package/storybook-static/assets/{Detail.stories-DyKJwUZa.js → Detail.stories-CuHf3Wue.js} +1 -1
  56. package/storybook-static/assets/{Dialog-BOJ3RYVz.js → Dialog-saV3OBaD.js} +1 -1
  57. package/storybook-static/assets/{Dialog.stories-CXbEj5L4.js → Dialog.stories-DJZjDZOj.js} +1 -1
  58. package/storybook-static/assets/{Disclosure--W-EAAIy.js → Disclosure-BnQsoyZ9.js} +1 -1
  59. package/storybook-static/assets/{Disclosure.stories-DoTRGvmn.js → Disclosure.stories-CleAOTAa.js} +1 -1
  60. package/storybook-static/assets/{DocsRenderer-JROSPFPF-DleaYdG7.js → DocsRenderer-JROSPFPF-Cb487wNy.js} +2 -2
  61. package/storybook-static/assets/{DropZone-CkQP6v9g.js → DropZone-DCYvv6oS.js} +1 -1
  62. package/storybook-static/assets/{DropZone.stories-C1zcVNPl.js → DropZone.stories-BN6UGMzJ.js} +1 -1
  63. package/storybook-static/assets/{DropdownMenu-DEvWFL4t.js → DropdownMenu-CwaWnh5v.js} +1 -1
  64. package/storybook-static/assets/{ExpandableActionPanel.stories-BqIC9qEA.js → ExpandableActionPanel.stories-BbTtL5H5.js} +1 -1
  65. package/storybook-static/assets/{Flex-15HLJkcx.js → Flex-BIhVP-gi.js} +1 -1
  66. package/storybook-static/assets/{Flex-DN99ulrp.js → Flex-bVf3Ey0I.js} +1 -1
  67. package/storybook-static/assets/{Flex.stories-Bo-WYa3I.js → Flex.stories-Bo516CcI.js} +1 -1
  68. package/storybook-static/assets/{Grid-DhDXoOVG.js → Grid-CZL3RCDH.js} +1 -1
  69. package/storybook-static/assets/{Grid-ocYYZDCx.js → Grid-D-XK8eGU.js} +1 -1
  70. package/storybook-static/assets/{Grid.stories-UoXOmqNN.js → Grid.stories-f_m-IAqH.js} +1 -1
  71. package/storybook-static/assets/{ImageCropper.stories-DC_sKrUG.js → ImageCropper.stories-C4u0eKX8.js} +1 -1
  72. package/storybook-static/assets/{ImageRenderer-DDphXIRV.js → ImageRenderer-Ctn8BFAc.js} +1 -1
  73. package/storybook-static/assets/{ImageRenderer.stories-Bc7FRacW.js → ImageRenderer.stories-k46-p7GH.js} +1 -1
  74. package/storybook-static/assets/{ImageView.stories-Dq7j_e-P.js → ImageView.stories-Dw9eCMdL.js} +1 -1
  75. package/storybook-static/assets/{ImageViewer.stories-C6uoxfbp.js → ImageViewer.stories-DN9QFJtR.js} +2 -2
  76. package/storybook-static/assets/{ImageViewerRuntime-C-Vsq4pT.js → ImageViewerRuntime-C2241xTn.js} +1 -1
  77. package/storybook-static/assets/{Input-5YkCA709.js → Input-BRLdK2Si.js} +1 -1
  78. package/storybook-static/assets/{Input-nC3liV_k.js → Input-sOZDjUSU.js} +1 -1
  79. package/storybook-static/assets/{Input.stories-DfupRT4g.js → Input.stories-DplzGk8u.js} +1 -1
  80. package/storybook-static/assets/{InputDateTime-D06IXa8m.js → InputDateTime-BTlRD6aj.js} +1 -1
  81. package/storybook-static/assets/{InputDateTime.stories-2m6J6PRF.js → InputDateTime.stories-B1UvUlhq.js} +1 -1
  82. package/storybook-static/assets/{InputFile-YjglC3BH.js → InputFile-BQ4vAM0P.js} +1 -1
  83. package/storybook-static/assets/{InputFile.stories-CEm2dCiL.js → InputFile.stories-CPdM_Emc.js} +1 -1
  84. package/storybook-static/assets/{InputFiles-Cvun794E.js → InputFiles-DQg_DoKH.js} +1 -1
  85. package/storybook-static/assets/{InputFiles-DnRctHku.js → InputFiles-WBqlWl_E.js} +1 -1
  86. package/storybook-static/assets/{InputFiles.stories-CLnAmDM0.js → InputFiles.stories-Dv1xaXgU.js} +1 -1
  87. package/storybook-static/assets/{InputImage-cTbxzy0x.js → InputImage-akZIEPgb.js} +1 -1
  88. package/storybook-static/assets/{InputImage.stories-DKrhqpIN.js → InputImage.stories-CH_DiWmh.js} +1 -1
  89. package/storybook-static/assets/{LayoutPicker-CTKmKJug.js → LayoutPicker-ERi6qIDR.js} +1 -1
  90. package/storybook-static/assets/{LayoutPicker.stories-BrlmXzKU.js → LayoutPicker.stories-BrtmW4CE.js} +1 -1
  91. package/storybook-static/assets/{Listbox-B6EQ_iO6.js → Listbox-DY72jU9z.js} +1 -1
  92. package/storybook-static/assets/{Listbox.stories-DabuvP5R.js → Listbox.stories-_QzDM1Ci.js} +1 -1
  93. package/storybook-static/assets/{Modal-DrK_HM-a.js → Modal-DncLyPfo.js} +1 -1
  94. package/storybook-static/assets/{Modal.stories-DgW1zX4p.js → Modal.stories-C4-NBAXw.js} +1 -1
  95. package/storybook-static/assets/{MultiSelect-EUq0nGvq.js → MultiSelect-B5N-STfq.js} +1 -1
  96. package/storybook-static/assets/{MultiSelect-DeSU5vf8.js → MultiSelect-ejIWp-Rz.js} +1 -1
  97. package/storybook-static/assets/{MultiSelect.stories-BDBoS2qV.js → MultiSelect.stories-XgDrwGuo.js} +1 -1
  98. package/storybook-static/assets/{NotificationsHost-BP-cQhdm.js → NotificationsHost-6b9kYvax.js} +1 -1
  99. package/storybook-static/assets/{NotificationsHost.stories-BvZapsLQ.js → NotificationsHost.stories-D09Wq0wZ.js} +1 -1
  100. package/storybook-static/assets/{ODataMultiSelect-CCxxhymC.js → ODataMultiSelect-BFKJRw5K.js} +3 -3
  101. package/storybook-static/assets/{ODataMultiSelect-Co9UuAvM.js → ODataMultiSelect-BIawkf_b.js} +1 -1
  102. package/storybook-static/assets/ODataMultiSelect.stories-CvsX2yER.js +73 -0
  103. package/storybook-static/assets/{ODataSelect-C7kAnrKY.js → ODataSelect-Cu6Tjx_s.js} +3 -2
  104. package/storybook-static/assets/{ODataSelect-BC3vCCte.js → ODataSelect-DIoiZucq.js} +1 -1
  105. package/storybook-static/assets/ODataSelect.stories-DjwSk6Uy.js +73 -0
  106. package/storybook-static/assets/ODataTreeMultiSelect-Bjhif1b9.js +19 -0
  107. package/storybook-static/assets/ODataTreeMultiSelect.stories-B3LvjLMX.js +30 -0
  108. package/storybook-static/assets/ODataTreeSelect-DjHtl_iC.js +17 -0
  109. package/storybook-static/assets/ODataTreeSelect.stories-BBJKEuMz.js +24 -0
  110. package/storybook-static/assets/{PeriodSelect-DjLvfYn8.js → PeriodSelect-D1AaJFeL.js} +1 -1
  111. package/storybook-static/assets/{PeriodSelect.stories-DVUw9Sg9.js → PeriodSelect.stories-CmbqFihE.js} +1 -1
  112. package/storybook-static/assets/{Popover-CdBZPGwi.js → Popover-DR8liz-v.js} +1 -1
  113. package/storybook-static/assets/{Popover.stories-CdiZ5xxZ.js → Popover.stories-DqUV0zog.js} +1 -1
  114. package/storybook-static/assets/{PresetRangeDateInput-vuxzGscI.js → PresetRangeDateInput-BLHAAOsi.js} +1 -1
  115. package/storybook-static/assets/{PresetRangeDateInput.stories-D78QUDvO.js → PresetRangeDateInput.stories-CYkMAT2P.js} +1 -1
  116. package/storybook-static/assets/{RadioButton-BwI6i1rE.js → RadioButton-C1XwSn49.js} +1 -1
  117. package/storybook-static/assets/{RadioButton.stories-IE0E96pS.js → RadioButton.stories-DEhd2--I.js} +1 -1
  118. package/storybook-static/assets/{RadioGroup-Bim0eupF.js → RadioGroup-C0kqI1LY.js} +1 -1
  119. package/storybook-static/assets/{RadioGroup-tryTiFtc.js → RadioGroup-C1SuOl8q.js} +1 -1
  120. package/storybook-static/assets/{RadioGroup.stories-Ceq0N-vt.js → RadioGroup.stories-B7fIJ67H.js} +1 -1
  121. package/storybook-static/assets/{Select-BCL2jNL8.js → Select-DJ5LrHt6.js} +1 -1
  122. package/storybook-static/assets/{Select-DMXjzkDO.js → Select-DLjAU3g8.js} +1 -1
  123. package/storybook-static/assets/{Select.stories-B_g_hOqR.js → Select.stories-_vkzIMCQ.js} +1 -1
  124. package/storybook-static/assets/SelectOptionContent-NnKgGdv9.js +1 -0
  125. package/storybook-static/assets/{SerializableSelect-AOkjv9yq.js → SerializableSelect-BR_nTkvZ.js} +1 -1
  126. package/storybook-static/assets/{SerializableSelect-BGChjWPB.js → SerializableSelect-DmJtvEpv.js} +1 -1
  127. package/storybook-static/assets/{SerializableSelect.stories-NYCIKA2l.js → SerializableSelect.stories-DbGF0LVI.js} +1 -1
  128. package/storybook-static/assets/{SingleDateTimeInput-7wU4lnCx.js → SingleDateTimeInput-DltYiswX.js} +1 -1
  129. package/storybook-static/assets/{SingleDateTimeInput.stories-Du0Bzxa9.js → SingleDateTimeInput.stories-DmcElJ7B.js} +1 -1
  130. package/storybook-static/assets/{Slider-B-EGHeZG.js → Slider-CRHuCUbB.js} +1 -1
  131. package/storybook-static/assets/{Slider.stories-xyE0ag0o.js → Slider.stories-B2Bnn8xW.js} +1 -1
  132. package/storybook-static/assets/{SliderInput-B5qr3f1G.js → SliderInput-Dv-_z_sZ.js} +1 -1
  133. package/storybook-static/assets/{SliderInput.stories-DawHF4zR.js → SliderInput.stories-BP9cwXe3.js} +1 -1
  134. package/storybook-static/assets/{Sortable-BgtK-JWo.js → Sortable-BDspkLd3.js} +1 -1
  135. package/storybook-static/assets/{Sortable.stories-BjWFWBd2.js → Sortable.stories-DqFu5ZAm.js} +1 -1
  136. package/storybook-static/assets/{Splitter-CAvtJptJ.js → Splitter-9N4ZumCX.js} +1 -1
  137. package/storybook-static/assets/{Splitter.stories-Cm8DHzNI.js → Splitter.stories-DgZFlDGy.js} +1 -1
  138. package/storybook-static/assets/{StateSelect-BR3D-VIm.js → StateSelect-DsqJaiKP.js} +1 -1
  139. package/storybook-static/assets/{StateSelect.stories-Cs0cD5IW.js → StateSelect.stories-Cte9B94C.js} +1 -1
  140. package/storybook-static/assets/{StringToggle.stories-pu8egCZ2.js → StringToggle.stories-DKJ11M4C.js} +1 -1
  141. package/storybook-static/assets/{Switch-C9uo4c37.js → Switch-DYaU9GG7.js} +1 -1
  142. package/storybook-static/assets/{Switch.stories-C3ghBhkq.js → Switch.stories-BtUzES0M.js} +1 -1
  143. package/storybook-static/assets/{Table-Bk-hBsI8.js → Table-D2BQ2oF-.js} +1 -1
  144. package/storybook-static/assets/{Table.stories--eah5PqC.js → Table.stories-BA4_3qL_.js} +1 -1
  145. package/storybook-static/assets/{Tabs-IRUImwhh.js → Tabs-Cm9HSlP4.js} +1 -1
  146. package/storybook-static/assets/{Tabs.stories-CUlplANQ.js → Tabs.stories-DrrusJOZ.js} +1 -1
  147. package/storybook-static/assets/{TagInput.stories-B6FPhOKm.js → TagInput.stories-BWDiTIHT.js} +1 -1
  148. package/storybook-static/assets/{Textarea-CiC0pZhh.js → Textarea-B4pxQFpd.js} +1 -1
  149. package/storybook-static/assets/{Textarea.stories-yvjUxFuQ.js → Textarea.stories-B6UkZhde.js} +1 -1
  150. package/storybook-static/assets/{TimePanel-Dgerz5If.js → TimePanel-D0bfeKGK.js} +1 -1
  151. package/storybook-static/assets/{TimePanel.stories-D6gcbXWL.js → TimePanel.stories-DKEdciW2.js} +1 -1
  152. package/storybook-static/assets/{Toggle-CXCTnnSV.js → Toggle-CdbQ9Xt3.js} +1 -1
  153. package/storybook-static/assets/{Toggle-8cLEtvUT.js → Toggle-CkbbGdLU.js} +1 -1
  154. package/storybook-static/assets/{Toggle.stories-DMiwsbGp.js → Toggle.stories-BgIudoad.js} +1 -1
  155. package/storybook-static/assets/{TreeMultiSelect-Codlm2j5.js → TreeMultiSelect-Cbkr4cDA.js} +1 -1
  156. package/storybook-static/assets/TreeMultiSelect-DiPWwhml.js +19 -0
  157. package/storybook-static/assets/TreeMultiSelect.stories-BBCAd6Gq.js +35 -0
  158. package/storybook-static/assets/TreePickerBase-Bh67Enrn.js +22 -0
  159. package/storybook-static/assets/TreePickerBase-DMs9EpFv.css +1 -0
  160. package/storybook-static/assets/TreeSelect-BnNzwMQT.js +1 -0
  161. package/storybook-static/assets/TreeSelect-CgvMcoPB.js +16 -0
  162. package/storybook-static/assets/TreeSelect.stories-S2zo4fAX.js +18 -0
  163. package/storybook-static/assets/{TreeTable-DiDzbNMx.js → TreeTable-FAzFcf-t.js} +1 -1
  164. package/storybook-static/assets/{TreeTable.stories-GziVUTaf.js → TreeTable.stories-DXxhWXqi.js} +1 -1
  165. package/storybook-static/assets/{WithTooltip-7X4HQR7L-vQhTSEvu.js → WithTooltip-7X4HQR7L-BeB8nhAE.js} +1 -1
  166. package/storybook-static/assets/{async-C5D1K82E.js → async-Bgo99s0E.js} +1 -1
  167. package/storybook-static/assets/{base-table-D971UHyZ.js → base-table-AmSzYs6_.js} +1 -1
  168. package/storybook-static/assets/{blocks-D3IlvJMm.js → blocks-Dmj58mhm.js} +6 -6
  169. package/storybook-static/assets/{button-ByG7LVhg.js → button-3eX4X1pF.js} +1 -1
  170. package/storybook-static/assets/{check-box-Bshfr00a.js → check-box-rktGSTee.js} +1 -1
  171. package/storybook-static/assets/{chunk-3LY4VQVK-BcD4_J-s.js → chunk-3LY4VQVK-JWq0LFl5.js} +1 -1
  172. package/storybook-static/assets/{chunk-LITCR56V-eYedee22.js → chunk-LITCR56V-BbahN_yV.js} +1 -1
  173. package/storybook-static/assets/{contextMenu-BTxGIdrx.js → contextMenu-CLL5WAxb.js} +1 -1
  174. package/storybook-static/assets/{date-Bx7K_8ZB.js → date-CkgxDok0.js} +1 -1
  175. package/storybook-static/assets/{error-nmUxd6Ys.js → error-Z7w1iONy.js} +1 -1
  176. package/storybook-static/assets/{file-BHDrAlNC.js → file-mHK2nrmr.js} +1 -1
  177. package/storybook-static/assets/{flex-BpqnRSxr.js → flex-DbByv7Hz.js} +1 -1
  178. package/storybook-static/assets/{floating-ui.react-C7ly6YFH.js → floating-ui.react-BcrUz8lJ.js} +1 -1
  179. package/storybook-static/assets/formatter-L2YTDE3Q-E-fuD8S9.js +1 -0
  180. package/storybook-static/assets/{formatters-CvqCBcOp.js → formatters-CqCEtV8w.js} +1 -1
  181. package/storybook-static/assets/{formulas-DKtSEXBn.js → formulas-BGZ9BxqL.js} +1 -1
  182. package/storybook-static/assets/grid-BIirsPdV.js +1 -0
  183. package/storybook-static/assets/{hooks-CE9rRN1m.js → hooks-B3m-jZHN.js} +1 -1
  184. package/storybook-static/assets/{iframe-CMLjY6eW.js → iframe-GalkF0Zs.js} +3 -3
  185. package/storybook-static/assets/{input-CCEUBfi5.js → input-BjhZOLSA.js} +1 -1
  186. package/storybook-static/assets/{mdx-react-shim-DzMf9EAg.js → mdx-react-shim-7A_ItrB6.js} +1 -1
  187. package/storybook-static/assets/{media-Xpom3JTM.js → media-Wv7jf1K7.js} +1 -1
  188. package/storybook-static/assets/{misc-DDShyfNn.js → misc-BdzvD5dq.js} +1 -1
  189. package/storybook-static/assets/{notifications-CnTOvE6M.js → notifications-CuN5DVHQ.js} +1 -1
  190. package/storybook-static/assets/{number-jvg5KgAt.js → number-JL9wEiuK.js} +1 -1
  191. package/storybook-static/assets/{odata-CaYek0XH.js → odata-BccFjFfw.js} +1 -1
  192. package/storybook-static/assets/odata-service-BNu0tuI7.js +1 -0
  193. package/storybook-static/assets/{odataFetchFn-DaFGY1h9.js → odataFetchFn-C8GFQND8.js} +1 -1
  194. package/storybook-static/assets/odataStoryFixtures-Dt2Vrdj6.js +25 -0
  195. package/storybook-static/assets/{persisted-C21zLLTr.js → persisted-D91MCfhx.js} +1 -1
  196. package/storybook-static/assets/{picker-9NUs0t2j.js → picker-x1g6PYwU.js} +1 -1
  197. package/storybook-static/assets/{popover-Cok2orIz.js → popover-DBLmjxtw.js} +1 -1
  198. package/storybook-static/assets/{preset-select-BKJU7Z15.js → preset-select-D2w5Mz9w.js} +1 -1
  199. package/storybook-static/assets/{pwa-8qqfGJq3.js → pwa-DjKFOgTI.js} +1 -1
  200. package/storybook-static/assets/{queryClient-DGAxuUPB.js → queryClient-Drw7gj9q.js} +1 -1
  201. package/storybook-static/assets/{react-18-BlyDfFu8.js → react-18-6hsRe9ic.js} +1 -1
  202. package/storybook-static/assets/{react-NOEzU_6K.js → react-C8N_JgBl.js} +1 -1
  203. package/storybook-static/assets/{react-dom-CVpgvhSC.js → react-dom-Bj91rBuY.js} +1 -1
  204. package/storybook-static/assets/select-D41ZbY27.js +1 -0
  205. package/storybook-static/assets/{slider-D3ATX0IT.js → slider-DUxUMuwH.js} +1 -1
  206. package/storybook-static/assets/{sortable-BL48OEDq.js → sortable-C-fGCbB6.js} +1 -1
  207. package/storybook-static/assets/{syntaxhighlighter-RTCFPKCB-CvruUeCc.js → syntaxhighlighter-RTCFPKCB-wu6kEAP5.js} +1 -1
  208. package/storybook-static/assets/{text-D19XuJeq.js → text-LYJNm5Vm.js} +1 -1
  209. package/storybook-static/assets/{theming-Dtq-a93s.js → theming-aB5M07PV.js} +1 -1
  210. package/storybook-static/assets/treeStoryFixtures-Y_nnjz0_.js +1 -0
  211. package/storybook-static/assets/ui-C5CglmiQ.js +1 -0
  212. package/storybook-static/assets/{useODataSelectBase-Dvnu67xy.js → useODataSelectBase-Conf0Fia.js} +1 -1
  213. package/storybook-static/assets/{useODataTreeData-Ck4VREaM.js → useODataTreeData-fEdbben5.js} +1 -1
  214. package/storybook-static/assets/{utils-PcgESe3m.js → utils-CPEyORfW.js} +1 -1
  215. package/storybook-static/assets/{valueState-BA_iqYhi.js → valueState-BqGCah-i.js} +1 -1
  216. package/storybook-static/iframe.html +1 -1
  217. package/storybook-static/index.json +1 -1
  218. package/storybook-static/project.json +1 -1
  219. package/dist/chunks/useODataSelectBase-CWBR3WCn.js.map +0 -1
  220. package/storybook-static/assets/Button-BN8Cuwsy.css +0 -1
  221. package/storybook-static/assets/ODataMultiSelect.stories-BrB1jJ2N.js +0 -73
  222. package/storybook-static/assets/ODataSelect.stories-CxhSfBxq.js +0 -73
  223. package/storybook-static/assets/ODataTreeMultiSelect-C7nvg88T.js +0 -17
  224. package/storybook-static/assets/ODataTreeMultiSelect.stories-DbQ9lOK_.js +0 -28
  225. package/storybook-static/assets/ODataTreeSelect-Cj2QXkos.js +0 -16
  226. package/storybook-static/assets/ODataTreeSelect.stories-CsOwUC4P.js +0 -21
  227. package/storybook-static/assets/SelectOptionContent-BDd8ltGY.js +0 -1
  228. package/storybook-static/assets/TreeMultiSelect-C8jqcnIV.js +0 -15
  229. package/storybook-static/assets/TreeMultiSelect.stories-DPjynkTo.js +0 -31
  230. package/storybook-static/assets/TreePickerBase-B35lReuv.css +0 -1
  231. package/storybook-static/assets/TreePickerBase-DCR2ymQN.js +0 -22
  232. package/storybook-static/assets/TreeSelect-CQ1Qc8zG.js +0 -15
  233. package/storybook-static/assets/TreeSelect-Dp9cZxwB.js +0 -1
  234. package/storybook-static/assets/TreeSelect.stories-DK-bK8lu.js +0 -16
  235. package/storybook-static/assets/formatter-L2YTDE3Q-CekaMrC5.js +0 -1
  236. package/storybook-static/assets/grid-pIXbJ1YW.js +0 -1
  237. package/storybook-static/assets/odata-service-CNHjiS2C.js +0 -1
  238. package/storybook-static/assets/odataStoryFixtures-Cu0CcqEL.js +0 -25
  239. package/storybook-static/assets/select-DhlrNWXm.js +0 -1
  240. package/storybook-static/assets/treeStoryFixtures-Cd984L7t.js +0 -1
  241. package/storybook-static/assets/ui-lVQZnhTj.js +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/tree-select/helpers.ts","../../src/tree-select/model/buildODataTreeNodes.ts","../../src/tree-select/model/resolveOrderedTreeSegmentItems.ts","../../src/tree-select/model/useODataTreeData.ts","../../src/tree-select/model/treeUtils.ts","../../src/tree-select/model/resolveBalancedTreeColumnsLayout.ts","../../src/tree-select/TreeSelect.module.scss","../../src/tree-select/TreeNodeContent.tsx","../../src/tree-select/TreePickerBase.tsx","../../src/tree-select/TreeMultiSelect.tsx","../../src/tree-select/ODataTreeMultiSelect.tsx","../../src/tree-select/TreeSelect.tsx","../../src/tree-select/ODataTreeSelect.tsx"],"sourcesContent":["import { TreeMultiSelectValue, TreeSelectValue } from \"./types\";\n\nexport function treeSelectValueToSelectedFilters(value: TreeSelectValue | undefined): TreeMultiSelectValue {\n\tif (!value) {\n\t\treturn {};\n\t}\n\n\treturn {\n\t\t[value.codeKey]: [value.value]\n\t};\n}\n","import { CollectionItem } from \"@ryuzaki13/react-foundation-lib/odata\";\nimport { compareStrings } from \"@ryuzaki13/react-foundation-lib/string-comparison\";\n\nimport { TreeSelectNode } from \"../types\";\n\ntype BuildODataTreeNodesArgs = {\n\titems: CollectionItem[];\n\torderedCodeKeys: string[];\n\tkeyPairsMap: Record<string, string>;\n\thiddenCodeKeys: Set<string>;\n\ttextValueCodeKeys?: Set<string>;\n\t/** Выбирает локальный порядок узлов: по исходному коду или отображаемому тексту. */\n\tsortByCode?: boolean;\n};\n\ntype MutableTreeNode = TreeSelectNode & {\n\t/**\n\t * Исходный код нужен только для локальной сортировки представления.\n\t * Он не зависит от hideCode/selectText и не попадает в публичный TreeSelectNode.\n\t */\n\tsortCode: string;\n\tchildren: MutableTreeNode[];\n\tchildByBranchKey: Map<string, MutableTreeNode>;\n};\n\nfunction createNodeId(parentId: string | undefined, codeKey: string, value: string) {\n\treturn parentId ? `${parentId}/${codeKey}:${value}` : `${codeKey}:${value}`;\n}\n\nfunction resolveNodeLabel(item: CollectionItem, codeKey: string, keyPairsMap: Record<string, string>) {\n\tconst textKey = keyPairsMap[codeKey];\n\treturn (textKey && item[textKey]) || item[codeKey];\n}\n\nfunction createSearchText(parts: Array<string | undefined>) {\n\treturn [...new Set(parts.filter(Boolean))].join(\" \");\n}\n\nfunction createMutableNode(args: {\n\tparentId?: string;\n\tcodeKey: string;\n\tvalue: string;\n\tlabel: string;\n\tcode?: string;\n\tsortCode: string;\n}): MutableTreeNode {\n\treturn {\n\t\tid: createNodeId(args.parentId, args.codeKey, args.value),\n\t\tcodeKey: args.codeKey,\n\t\tvalue: args.value,\n\t\tlabel: args.label,\n\t\tcode: args.code,\n\t\tsearchText: createSearchText([args.value, args.label, args.code]),\n\t\tsortCode: args.sortCode,\n\t\tchildren: [],\n\t\tchildByBranchKey: new Map()\n\t};\n}\n\n/**\n * Сортирует только массивы вновь построенного дерева, не меняя исходную OData-коллекцию\n * и не создавая отдельный Query cache для каждого способа отображения.\n */\nfunction sortMutableTree(nodes: MutableTreeNode[], sortByCode: boolean) {\n\tnodes.sort((left, right) => {\n\t\tconst leftValue = sortByCode ? left.sortCode : left.label;\n\t\tconst rightValue = sortByCode ? right.sortCode : right.label;\n\t\tconst valueOrder = compareStrings(leftValue, rightValue);\n\n\t\treturn valueOrder || compareStrings(left.sortCode, right.sortCode);\n\t});\n\n\tfor (const node of nodes) {\n\t\tsortMutableTree(node.children, sortByCode);\n\t}\n}\n\nfunction toPublicNode(node: MutableTreeNode): TreeSelectNode {\n\treturn {\n\t\tid: node.id,\n\t\tcodeKey: node.codeKey,\n\t\tvalue: node.value,\n\t\tlabel: node.label,\n\t\tcode: node.code,\n\t\tsearchText: node.searchText,\n\t\tchildren: node.children.length > 0 ? node.children.map(toPublicNode) : undefined\n\t};\n}\n\nexport function buildODataTreeNodes({\n\titems,\n\torderedCodeKeys,\n\tkeyPairsMap,\n\thiddenCodeKeys,\n\ttextValueCodeKeys,\n\tsortByCode = true\n}: BuildODataTreeNodesArgs): TreeSelectNode[] {\n\tif (orderedCodeKeys.length === 0 || items.length === 0) {\n\t\treturn [];\n\t}\n\n\tconst roots: MutableTreeNode[] = [];\n\tconst rootByBranchKey = new Map<string, MutableTreeNode>();\n\n\tfor (const item of items) {\n\t\tlet parentNode: MutableTreeNode | undefined;\n\n\t\tfor (const codeKey of orderedCodeKeys) {\n\t\t\tconst codeValue = String(item[codeKey] ?? \"\");\n\n\t\t\tif (!codeValue) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tconst label = String(resolveNodeLabel(item, codeKey, keyPairsMap) ?? \"\");\n\t\t\tconst value = textValueCodeKeys?.has(codeKey) ? label : codeValue;\n\t\t\tconst branchKey = `${codeKey}:${value}`;\n\t\t\tconst container = parentNode ? parentNode.childByBranchKey : rootByBranchKey;\n\t\t\tlet currentNode = container.get(branchKey);\n\n\t\t\tif (!currentNode) {\n\t\t\t\tcurrentNode = createMutableNode({\n\t\t\t\t\tparentId: parentNode?.id,\n\t\t\t\t\tcodeKey,\n\t\t\t\t\tvalue,\n\t\t\t\t\tlabel,\n\t\t\t\t\tcode: hiddenCodeKeys.has(codeKey) ? undefined : codeValue,\n\t\t\t\t\tsortCode: codeValue\n\t\t\t\t});\n\t\t\t\tcontainer.set(branchKey, currentNode);\n\n\t\t\t\tif (parentNode) {\n\t\t\t\t\tparentNode.children.push(currentNode);\n\t\t\t\t} else {\n\t\t\t\t\troots.push(currentNode);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tparentNode = currentNode;\n\t\t}\n\t}\n\n\tsortMutableTree(roots, sortByCode);\n\n\treturn roots.map(toPublicNode);\n}\n","import { ODataDependentSegmentItem, sortODataDependentSegmentItemsByChains } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { ODataChainsMap } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\nexport function resolveOrderedTreeSegmentItems(items: readonly ODataDependentSegmentItem[], chains: ODataChainsMap) {\n\treturn sortODataDependentSegmentItemsByChains(items, chains);\n}\n","import { useMemo } from \"react\";\n\nimport {\n\tflattenODataDependentServices,\n\tODataCollectionModel,\n\tODataDependentBaseProps,\n\tODataDependentSegmentItem,\n\tuseODataCollection,\n\tuseODataCollectionChains,\n\tuseODataCollectionModel\n} from \"@ryuzaki13/react-foundation-api/odata\";\n\nimport { buildODataTreeNodes } from \"./buildODataTreeNodes\";\nimport { resolveOrderedTreeSegmentItems } from \"./resolveOrderedTreeSegmentItems\";\n\nfunction buildOrderedSegmentItems(\n\todata: ODataDependentBaseProps[\"odata\"],\n\tsegments: ODataDependentBaseProps[\"segments\"],\n\tmodel?: Omit<ODataCollectionModel, \"codeKey\">\n) {\n\treturn flattenODataDependentServices([\n\t\t{\n\t\t\todata,\n\t\t\tsegments,\n\t\t\tmodel\n\t\t}\n\t]);\n}\n\nfunction getRootCodeKey(orderedSegmentItems: readonly ODataDependentSegmentItem[]) {\n\treturn orderedSegmentItems[0]?.id;\n}\n\nexport function useODataTreeData({ odata, segments, model }: Pick<ODataDependentBaseProps, \"odata\" | \"segments\" | \"model\">) {\n\tconst serviceKey = `${odata.service}.${odata.target}`;\n\tconst baseSegmentItems = useMemo(() => buildOrderedSegmentItems(odata, segments, model), [odata, segments, model]);\n\tconst chains = useODataCollectionChains([odata]);\n\tconst orderedSegmentItems = useMemo(() => resolveOrderedTreeSegmentItems(baseSegmentItems, chains), [baseSegmentItems, chains]);\n\tconst orderedCodeKeys = useMemo(() => orderedSegmentItems.map((item) => item.id), [orderedSegmentItems]);\n\tconst rootCodeKey = getRootCodeKey(orderedSegmentItems) ?? Object.keys(segments)[0];\n\tconst odataModel = useODataCollectionModel({\n\t\tcodeKey: rootCodeKey,\n\t\t...model\n\t});\n\tconst collection = useODataCollection({\n\t\todata,\n\t\tmodel: odataModel\n\t});\n\tconst { hiddenCodeKeys, textValueCodeKeys } = useMemo(() => {\n\t\tconst nextHiddenCodeKeys = new Set<string>();\n\t\tconst nextTextValueCodeKeys = new Set<string>();\n\n\t\tfor (const item of orderedSegmentItems) {\n\t\t\tif (item.segment.hideCode ?? odata.hideCode) {\n\t\t\t\tnextHiddenCodeKeys.add(item.id);\n\t\t\t}\n\t\t\tif (item.segment.selectText) {\n\t\t\t\tnextTextValueCodeKeys.add(item.id);\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\thiddenCodeKeys: nextHiddenCodeKeys,\n\t\t\ttextValueCodeKeys: nextTextValueCodeKeys\n\t\t};\n\t}, [odata.hideCode, orderedSegmentItems]);\n\tconst nodes = useMemo(\n\t\t() =>\n\t\t\tbuildODataTreeNodes({\n\t\t\t\titems: collection.data?.items ?? [],\n\t\t\t\torderedCodeKeys,\n\t\t\t\tkeyPairsMap: collection.data?.keyPairsMap ?? {},\n\t\t\t\thiddenCodeKeys,\n\t\t\t\ttextValueCodeKeys,\n\t\t\t\tsortByCode: odata.sortByCode\n\t\t\t}),\n\t\t[collection.data?.items, collection.data?.keyPairsMap, hiddenCodeKeys, odata.sortByCode, orderedCodeKeys, textValueCodeKeys]\n\t);\n\tconst placeholder = orderedSegmentItems[0]?.segment.placeholder ?? \"Выберите значение\";\n\tconst hasResolvedChain = Boolean(chains[serviceKey]?.length);\n\n\treturn {\n\t\tnodes,\n\t\torderedSegmentItems,\n\t\torderedCodeKeys,\n\t\tisLoading: collection.isLoading,\n\t\tisError: collection.isError,\n\t\tplaceholder,\n\t\thasResolvedChain\n\t};\n}\n","import { TreeMultiSelectValue, TreeSelectNode, TreeSelectValue } from \"../types\";\n\nexport type TreeNodeIndex = {\n\trootIds: string[];\n\tnodeById: Map<string, TreeSelectNode>;\n\tparentById: Map<string, string | undefined>;\n\tchildrenById: Map<string, string[]>;\n\tpreorderIndexById: Map<string, number>;\n\tnodeIdByCodeValue: Map<string, string>;\n};\n\nexport type TreeNodeSelectionState = {\n\tselectedIds: Set<string>;\n\tpartialIds: Set<string>;\n};\n\nexport type TreeVisibleEntry = {\n\tnode: TreeSelectNode;\n\tlevel: number;\n\tparentId?: string;\n\thasChildren: boolean;\n\tisExpanded: boolean;\n\tisLeaf: boolean;\n};\n\nfunction makeCodeValueKey(codeKey: string, value: string) {\n\treturn `${codeKey}::${value}`;\n}\n\nexport function createTreeNodeIndex(nodes: readonly TreeSelectNode[]): TreeNodeIndex {\n\tconst nodeById = new Map<string, TreeSelectNode>();\n\tconst parentById = new Map<string, string | undefined>();\n\tconst childrenById = new Map<string, string[]>();\n\tconst preorderIndexById = new Map<string, number>();\n\tconst nodeIdByCodeValue = new Map<string, string>();\n\tlet preorderIndex = 0;\n\n\tconst walk = (node: TreeSelectNode, parentId?: string) => {\n\t\tnodeById.set(node.id, node);\n\t\tparentById.set(node.id, parentId);\n\t\tpreorderIndexById.set(node.id, preorderIndex++);\n\t\tnodeIdByCodeValue.set(makeCodeValueKey(node.codeKey, node.value), node.id);\n\n\t\tconst childIds = (node.children ?? []).map((child) => child.id);\n\t\tchildrenById.set(node.id, childIds);\n\n\t\tfor (const child of node.children ?? []) {\n\t\t\twalk(child, node.id);\n\t\t}\n\t};\n\n\tfor (const node of nodes) {\n\t\twalk(node);\n\t}\n\n\treturn {\n\t\trootIds: nodes.map((node) => node.id),\n\t\tnodeById,\n\t\tparentById,\n\t\tchildrenById,\n\t\tpreorderIndexById,\n\t\tnodeIdByCodeValue\n\t};\n}\n\nexport function treeSelectValueToId(value: TreeSelectValue | undefined, index: TreeNodeIndex) {\n\tif (!value) return undefined;\n\treturn index.nodeIdByCodeValue.get(makeCodeValueKey(value.codeKey, value.value));\n}\n\nexport function treeMultiValueToSelectedIds(value: TreeMultiSelectValue | undefined, index: TreeNodeIndex) {\n\tconst selectedIds = new Set<string>();\n\n\tif (!value) {\n\t\treturn selectedIds;\n\t}\n\n\tfor (const [codeKey, values] of Object.entries(value)) {\n\t\tfor (const itemValue of values) {\n\t\t\tconst nodeId = index.nodeIdByCodeValue.get(makeCodeValueKey(codeKey, itemValue));\n\t\t\tif (nodeId) {\n\t\t\t\tselectedIds.add(nodeId);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn canonicalizeTreeSelection(selectedIds, index);\n}\n\nexport function treeSelectedIdsToMultiValue(selectedIds: Set<string>, index: TreeNodeIndex): TreeMultiSelectValue {\n\tconst orderedIds = [...selectedIds].sort(\n\t\t(leftId, rightId) =>\n\t\t\t(index.preorderIndexById.get(leftId) ?? Number.MAX_SAFE_INTEGER) -\n\t\t\t(index.preorderIndexById.get(rightId) ?? Number.MAX_SAFE_INTEGER)\n\t);\n\tconst result: TreeMultiSelectValue = {};\n\n\tfor (const nodeId of orderedIds) {\n\t\tconst node = index.nodeById.get(nodeId);\n\t\tif (!node) continue;\n\n\t\tresult[node.codeKey] = result[node.codeKey] ?? [];\n\t\tresult[node.codeKey].push(node.value);\n\t}\n\n\treturn result;\n}\n\nexport function treeSelectValueToMultiValue(value: TreeSelectValue | undefined): TreeMultiSelectValue {\n\tif (!value) {\n\t\treturn {};\n\t}\n\n\treturn {\n\t\t[value.codeKey]: [value.value]\n\t};\n}\n\nfunction getAncestorIds(nodeId: string, index: TreeNodeIndex) {\n\tconst ancestors: string[] = [];\n\tlet currentId = index.parentById.get(nodeId);\n\n\twhile (currentId) {\n\t\tancestors.push(currentId);\n\t\tcurrentId = index.parentById.get(currentId);\n\t}\n\n\treturn ancestors;\n}\n\nfunction isDescendantOf(nodeId: string, ancestorId: string, index: TreeNodeIndex) {\n\tlet currentId = index.parentById.get(nodeId);\n\n\twhile (currentId) {\n\t\tif (currentId === ancestorId) {\n\t\t\treturn true;\n\t\t}\n\n\t\tcurrentId = index.parentById.get(currentId);\n\t}\n\n\treturn false;\n}\n\nfunction removeDescendantSelections(selectedIds: Set<string>, nodeId: string, index: TreeNodeIndex) {\n\tfor (const selectedId of [...selectedIds]) {\n\t\tif (isDescendantOf(selectedId, nodeId, index)) {\n\t\t\tselectedIds.delete(selectedId);\n\t\t}\n\t}\n}\n\nfunction isNodeFullySelected(nodeId: string, selectedIds: Set<string>, index: TreeNodeIndex): boolean {\n\tif (selectedIds.has(nodeId)) {\n\t\treturn true;\n\t}\n\tif (index.nodeById.get(nodeId)?.disabled) {\n\t\treturn false;\n\t}\n\n\tconst children = index.childrenById.get(nodeId) ?? [];\n\tif (children.length === 0) {\n\t\treturn false;\n\t}\n\n\treturn children.every((childId) => isNodeFullySelected(childId, selectedIds, index));\n}\n\nexport function canonicalizeTreeSelection(selectedIds: Set<string>, index: TreeNodeIndex) {\n\tconst nextSelectedIds = new Set(selectedIds);\n\n\tfor (const selectedId of [...nextSelectedIds]) {\n\t\tif (getAncestorIds(selectedId, index).some((ancestorId) => nextSelectedIds.has(ancestorId))) {\n\t\t\tnextSelectedIds.delete(selectedId);\n\t\t}\n\t}\n\n\tconst orderedNodeIds = [...index.nodeById.keys()].sort(\n\t\t(leftId, rightId) => (index.preorderIndexById.get(rightId) ?? 0) - (index.preorderIndexById.get(leftId) ?? 0)\n\t);\n\n\tfor (const nodeId of orderedNodeIds) {\n\t\tconst children = index.childrenById.get(nodeId) ?? [];\n\n\t\tif (children.length === 0 || nextSelectedIds.has(nodeId) || index.nodeById.get(nodeId)?.disabled) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (children.every((childId) => isNodeFullySelected(childId, nextSelectedIds, index))) {\n\t\t\tremoveDescendantSelections(nextSelectedIds, nodeId, index);\n\t\t\tnextSelectedIds.add(nodeId);\n\t\t}\n\t}\n\n\treturn nextSelectedIds;\n}\n\nfunction expandNearestSelectedAncestor(selectedIds: Set<string>, nodeId: string, index: TreeNodeIndex) {\n\tlet currentId = index.parentById.get(nodeId);\n\n\twhile (currentId) {\n\t\tif (selectedIds.has(currentId)) {\n\t\t\tselectedIds.delete(currentId);\n\n\t\t\t/*\n\t\t\t * Узел мог стать disabled уже после сохранения выбора его ancestor.\n\t\t\t * При частичном снятии разворачиваем ancestor только в актуально\n\t\t\t * доступное покрытие, чтобы запрещённое значение не попало в onChange.\n\t\t\t */\n\t\t\tfor (const childId of getSelectableTreeNodeIds(index, index.childrenById.get(currentId) ?? [])) {\n\t\t\t\tselectedIds.add(childId);\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\tcurrentId = index.parentById.get(currentId);\n\t}\n\n\treturn false;\n}\n\nexport function isTreeNodeSelected(nodeId: string, selectedIds: Set<string>, index: TreeNodeIndex): boolean {\n\tif (selectedIds.has(nodeId)) {\n\t\treturn true;\n\t}\n\n\treturn getAncestorIds(nodeId, index).some((ancestorId) => selectedIds.has(ancestorId));\n}\n\nfunction resolveTreeSelectionState(nodeId: string, selectedIds: Set<string>, index: TreeNodeIndex, state: TreeNodeSelectionState) {\n\tconst children = index.childrenById.get(nodeId) ?? [];\n\n\tif (selectedIds.has(nodeId)) {\n\t\tstate.selectedIds.add(nodeId);\n\t\treturn { selected: true, partial: false };\n\t}\n\n\tif (children.length === 0) {\n\t\treturn { selected: false, partial: false };\n\t}\n\n\tconst childStates = children.map((childId) => resolveTreeSelectionState(childId, selectedIds, index, state));\n\tconst allSelected = childStates.every((childState) => childState.selected && !childState.partial);\n\tconst hasAnySelected = childStates.some((childState) => childState.selected || childState.partial);\n\n\tif (allSelected) {\n\t\tstate.selectedIds.add(nodeId);\n\t\treturn { selected: true, partial: false };\n\t}\n\n\tif (hasAnySelected) {\n\t\tstate.partialIds.add(nodeId);\n\t\treturn { selected: false, partial: true };\n\t}\n\n\treturn { selected: false, partial: false };\n}\n\nexport function getTreeNodeSelectionState(selectedIds: Set<string>, index: TreeNodeIndex): TreeNodeSelectionState {\n\tconst state: TreeNodeSelectionState = {\n\t\tselectedIds: new Set(),\n\t\tpartialIds: new Set()\n\t};\n\n\tfor (const rootId of index.rootIds) {\n\t\tresolveTreeSelectionState(rootId, selectedIds, index, state);\n\t}\n\n\treturn state;\n}\n\n/**\n * Строит каноническое покрытие всех доступных узлов для массового выбора.\n * Ветка схлопывается в parent только тогда, когда внутри неё нет disabled-узлов;\n * иначе выбираются доступные дочерние поддеревья, не затрагивая запреты.\n */\nexport function getSelectableTreeNodeIds(index: TreeNodeIndex, rootIds: readonly string[] = index.rootIds): Set<string> {\n\tconst collectSubtree = (nodeId: string): { containsDisabled: boolean; selectedIds: string[] } => {\n\t\tconst node = index.nodeById.get(nodeId);\n\t\tconst childSelections = (index.childrenById.get(nodeId) ?? []).map(collectSubtree);\n\t\tconst selectedChildIds = childSelections.flatMap((selection) => selection.selectedIds);\n\t\tconst containsDisabled = node?.disabled === true || childSelections.some((selection) => selection.containsDisabled);\n\n\t\tif (!node || node.disabled) {\n\t\t\treturn { containsDisabled: true, selectedIds: selectedChildIds };\n\t\t}\n\n\t\treturn containsDisabled\n\t\t\t? { containsDisabled: true, selectedIds: selectedChildIds }\n\t\t\t: { containsDisabled: false, selectedIds: [nodeId] };\n\t};\n\n\treturn new Set(rootIds.flatMap((rootId) => collectSubtree(rootId).selectedIds));\n}\n\nexport function toggleTreeMultiSelection(currentValue: TreeMultiSelectValue | undefined, targetNodeId: string, index: TreeNodeIndex) {\n\tconst selectedIds = treeMultiValueToSelectedIds(currentValue, index);\n\n\tconst toggle = (targetId: string) => {\n\t\tif (isTreeNodeSelected(targetId, selectedIds, index)) {\n\t\t\tif (selectedIds.has(targetId)) {\n\t\t\t\tselectedIds.delete(targetId);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (expandNearestSelectedAncestor(selectedIds, targetId, index)) {\n\t\t\t\ttoggle(targetId);\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tremoveDescendantSelections(selectedIds, targetId, index);\n\t\tselectedIds.add(targetId);\n\t};\n\n\tconst selectableTargetIds = [...getSelectableTreeNodeIds(index, [targetNodeId])];\n\tconst allSelectableTargetsSelected =\n\t\tselectableTargetIds.length > 0 && selectableTargetIds.every((nodeId) => isTreeNodeSelected(nodeId, selectedIds, index));\n\n\tfor (const selectableTargetId of selectableTargetIds) {\n\t\tconst selected = isTreeNodeSelected(selectableTargetId, selectedIds, index);\n\t\tif ((allSelectableTargetsSelected && selected) || (!allSelectableTargetsSelected && !selected)) {\n\t\t\ttoggle(selectableTargetId);\n\t\t}\n\t}\n\n\treturn treeSelectedIdsToMultiValue(canonicalizeTreeSelection(selectedIds, index), index);\n}\n\nfunction collectExpandedIds(nodeId: string, index: TreeNodeIndex, expandedIds: Set<string>) {\n\tlet currentId = index.parentById.get(nodeId);\n\n\twhile (currentId) {\n\t\texpandedIds.add(currentId);\n\t\tcurrentId = index.parentById.get(currentId);\n\t}\n}\n\nexport function getSelectionExpandedIds(selectedIds: Set<string>, index: TreeNodeIndex) {\n\tconst expandedIds = new Set<string>();\n\n\tfor (const selectedId of selectedIds) {\n\t\tcollectExpandedIds(selectedId, index, expandedIds);\n\t}\n\n\treturn expandedIds;\n}\n\nfunction filterTreeNode(node: TreeSelectNode, normalizedQuery: string, expandedIds: Set<string>): TreeSelectNode | null {\n\tconst filteredChildren = (node.children ?? [])\n\t\t.map((childNode) => filterTreeNode(childNode, normalizedQuery, expandedIds))\n\t\t.filter((childNode): childNode is TreeSelectNode => Boolean(childNode));\n\tconst isMatched = node.searchText.toLowerCase().includes(normalizedQuery);\n\n\tif (!isMatched && filteredChildren.length === 0) {\n\t\treturn null;\n\t}\n\n\tif (filteredChildren.length > 0) {\n\t\texpandedIds.add(node.id);\n\t}\n\n\tif (filteredChildren.length === 0) {\n\t\treturn node;\n\t}\n\n\treturn {\n\t\t...node,\n\t\tchildren: filteredChildren\n\t};\n}\n\nexport function filterTreeNodes(nodes: readonly TreeSelectNode[], query: string) {\n\tconst normalizedQuery = query.trim().toLowerCase();\n\n\tif (!normalizedQuery) {\n\t\treturn {\n\t\t\tnodes: [...nodes],\n\t\t\texpandedIds: new Set<string>()\n\t\t};\n\t}\n\n\tconst expandedIds = new Set<string>();\n\tconst filteredNodes = nodes\n\t\t.map((node) => filterTreeNode(node, normalizedQuery, expandedIds))\n\t\t.filter((node): node is TreeSelectNode => Boolean(node));\n\n\treturn {\n\t\tnodes: filteredNodes,\n\t\texpandedIds\n\t};\n}\n\nexport function flattenVisibleTreeNodes(nodes: readonly TreeSelectNode[], expandedIds: Set<string>): TreeVisibleEntry[] {\n\tconst entries: TreeVisibleEntry[] = [];\n\n\tconst walk = (node: TreeSelectNode, level: number, parentId?: string) => {\n\t\tconst hasChildren = (node.children?.length ?? 0) > 0;\n\t\tconst isExpanded = hasChildren && expandedIds.has(node.id);\n\n\t\tentries.push({\n\t\t\tnode,\n\t\t\tlevel,\n\t\t\tparentId,\n\t\t\thasChildren,\n\t\t\tisExpanded,\n\t\t\tisLeaf: !hasChildren\n\t\t});\n\n\t\tif (!isExpanded) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const childNode of node.children ?? []) {\n\t\t\twalk(childNode, level + 1, node.id);\n\t\t}\n\t};\n\n\tfor (const node of nodes) {\n\t\twalk(node, 0);\n\t}\n\n\treturn entries;\n}\n","export type BalancedTreeColumnsLayoutInput = {\n\titemCount: number;\n\tavailableWidth: number;\n\tavailableHeight: number;\n\tviewportWidth: number;\n\tviewportHeight: number;\n\treferenceWidth: number;\n};\n\nexport type BalancedTreeColumnsLayout = {\n\tcolumnCount: number;\n\trowCount: number;\n\twidth: number;\n\tminWidth: number;\n\tmaxHeight: number;\n};\n\nconst VIEWPORT_PADDING = 8;\nconst POPUP_HORIZONTAL_PADDING = 16;\nconst POPUP_CHROME_HEIGHT = 48;\nconst COLUMN_WIDTH = 224;\nconst COLUMN_GAP = 10;\nconst OPTION_HEIGHT = 32;\nconst MAX_COLUMN_COUNT = 6;\n\nfunction normalizePositiveDimension(value: number, fallback: number) {\n\treturn Number.isFinite(value) && value > 0 ? value : fallback;\n}\n\n/**\n * Выбирает количество колонок по фактически доступной Floating UI геометрии.\n * Оценка одновременно штрафует переполнение, вытянутую форму и пустые ячейки,\n * поэтому popup стремится к компактной средней пропорции, но не выходит за viewport.\n */\nexport function resolveBalancedTreeColumnsLayout({\n\titemCount,\n\tavailableWidth,\n\tavailableHeight,\n\tviewportWidth,\n\tviewportHeight,\n\treferenceWidth\n}: BalancedTreeColumnsLayoutInput): BalancedTreeColumnsLayout {\n\tconst normalizedItemCount = Math.max(0, Math.floor(Number.isFinite(itemCount) ? itemCount : 0));\n\tconst normalizedAvailableWidth = normalizePositiveDimension(availableWidth, COLUMN_WIDTH + POPUP_HORIZONTAL_PADDING);\n\tconst normalizedAvailableHeight = normalizePositiveDimension(availableHeight, OPTION_HEIGHT + POPUP_CHROME_HEIGHT);\n\tconst normalizedViewportWidth = normalizePositiveDimension(viewportWidth, normalizedAvailableWidth + VIEWPORT_PADDING * 2);\n\tconst normalizedViewportHeight = normalizePositiveDimension(viewportHeight, normalizedAvailableHeight);\n\tconst widthLimit = Math.max(1, Math.min(normalizedAvailableWidth, Math.max(1, normalizedViewportWidth - VIEWPORT_PADDING * 2)));\n\tconst heightLimit = Math.max(1, Math.min(normalizedAvailableHeight, normalizedViewportHeight * 0.75));\n\tconst normalizedReferenceWidth = Math.max(1, normalizePositiveDimension(referenceWidth, 1));\n\tconst minWidth = Math.min(widthLimit, normalizedReferenceWidth);\n\tconst maxColumnsByWidth = Math.max(1, Math.floor((widthLimit - POPUP_HORIZONTAL_PADDING + COLUMN_GAP) / (COLUMN_WIDTH + COLUMN_GAP)));\n\tconst maxColumnCount = Math.max(1, Math.min(MAX_COLUMN_COUNT, maxColumnsByWidth, normalizedItemCount || 1));\n\n\tlet bestColumnCount = 1;\n\tlet bestScore = Number.POSITIVE_INFINITY;\n\n\tfor (let columnCount = 1; columnCount <= maxColumnCount; columnCount += 1) {\n\t\tconst rowCount = Math.ceil(normalizedItemCount / columnCount);\n\t\tconst naturalWidth = Math.max(minWidth, POPUP_HORIZONTAL_PADDING + columnCount * COLUMN_WIDTH + (columnCount - 1) * COLUMN_GAP);\n\t\tconst naturalHeight = POPUP_CHROME_HEIGHT + rowCount * OPTION_HEIGHT;\n\t\tconst widthRatio = naturalWidth / widthLimit;\n\t\tconst heightRatio = naturalHeight / heightLimit;\n\t\tconst emptyCellPenalty = normalizedItemCount ? (columnCount * rowCount - normalizedItemCount) / normalizedItemCount : 0;\n\t\tconst score =\n\t\t\tMath.max(widthRatio, heightRatio) +\n\t\t\t0.25 * Math.abs(widthRatio - heightRatio) +\n\t\t\t0.01 * emptyCellPenalty +\n\t\t\t0.04 * (columnCount - 1);\n\n\t\tif (score < bestScore) {\n\t\t\tbestScore = score;\n\t\t\tbestColumnCount = columnCount;\n\t\t}\n\t}\n\n\tconst rowCount = Math.ceil(normalizedItemCount / bestColumnCount);\n\tconst naturalWidth = Math.max(minWidth, POPUP_HORIZONTAL_PADDING + bestColumnCount * COLUMN_WIDTH + (bestColumnCount - 1) * COLUMN_GAP);\n\n\treturn {\n\t\tcolumnCount: bestColumnCount,\n\t\trowCount,\n\t\twidth: Math.min(widthLimit, naturalWidth),\n\t\tminWidth,\n\t\tmaxHeight: heightLimit\n\t};\n}\n","@use \"@/styles/mixins\" as *;\n\n// .uiOptionRow\n.treeRow {\n\tdisplay: flex;\n\talign-items: stretch;\n\tborder-radius: var(--radius-sm);\n\tcursor: pointer;\n\n\t&:focus {\n\t\t@include focusVisible;\n\n\t\tbackground-color: var(--surface-accent);\n\t\tborder-color: var(--border-1);\n\t\tcursor: pointer;\n\t}\n\n\t&:hover {\n\t\tbackground-color: var(--surface-accent);\n\t\tcursor: pointer;\n\t}\n}\n\n// .uiOptionRowSelected\n.treeRowSelected {\n\tbackground-color: var(--surface-2);\n\tcolor: var(--content-accent);\n\tcursor: default;\n}\n\n// .uiOptionRowActive\n.treeRowActive {\n\tbackground-color: var(--surface-1);\n}\n\n// Недоступность принадлежит option целиком; вложенный checkbox только визуализирует то же состояние.\n.treeRowDisabled {\n\tcursor: not-allowed;\n\topacity: var(--disabled-opacity);\n\n\t&:hover {\n\t\tbackground-color: transparent;\n\t\tcursor: not-allowed;\n\t}\n}\n\n.treeNodeButton {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: var(--space-xs);\n\twidth: 100%;\n\tpadding: var(--space-xs) var(--space-xs) var(--space-xs) 0;\n\tbackground: transparent;\n\ttext-align: left;\n\tborder-radius: var(--radius-sm);\n}\n\n.treePopupHeader {\n\tdisplay: grid;\n\tgap: var(--space-sm);\n}\n\n.treeColumns {\n\tdisplay: grid;\n\tgrid-auto-flow: column;\n\tgrid-template-columns: repeat(var(--tree-column-count, 1), minmax(0, 1fr));\n\tgrid-template-rows: repeat(var(--tree-row-count, 1), minmax(var(--control-height), auto));\n\tcolumn-gap: var(--space-sm);\n\talign-content: start;\n\twidth: 100%;\n\tmin-width: 0;\n}\n\n.treeColumnRow {\n\tmin-width: 0;\n\tbreak-inside: avoid;\n}\n\n.treeColumnCheckBox {\n\tdisplay: inline-flex;\n\tflex-shrink: 0;\n}\n\n// Даёт общему option-content реальную сжимаемую ширину внутри колонки и включает ellipsis вместо выхода за границы.\n.treeNodeOptionContent {\n\tflex: 1 1 0;\n\tmin-width: 0;\n\theight: 100%;\n}\n\n.treeIndent {\n\tflex-shrink: 0;\n\twidth: calc(var(--tree-level) * 1em);\n}\n\n.treeExpander,\n.treeExpanderPlaceholder {\n\tflex-shrink: 0;\n\twidth: 1.5em;\n\theight: 1.5em;\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.treeExpander {\n\tbackground: transparent;\n\tborder: none;\n\tborder-radius: var(--radius-sm);\n\tcolor: var(--content-2);\n\n\t&:hover {\n\t\tcolor: var(--content-0);\n\t\tbackground-color: var(--surface-0);\n\t}\n}\n\n.treeExpanderIcon {\n\ttransition: transform var(--transition-fast) ease;\n}\n\n.treeExpanderIconExpanded {\n\ttransform: rotate(90deg);\n}\n\n.treeSelection {\n\tflex-shrink: 0;\n\twidth: 1em;\n\theight: 1em;\n\tborder: var(--border);\n\tborder-radius: var(--radius-xs);\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tbackground-color: var(--surface-0);\n\tcolor: transparent;\n}\n\n.treeSelectionChecked {\n\tbackground-color: var(--status-info-text);\n\tborder-color: var(--status-info-text);\n\tcolor: var(--white);\n\n\t// outline: 1px dashed rgb(255, 100, 141);\n\t// outline-offset: -1px;\n}\n\n.treeSelectionPartial {\n\tbackground-color: var(--surface-1);\n\tborder-color: var(--status-info-text);\n\tcolor: var(--status-info-text);\n}\n\n.treeSelectionIcon {\n\twidth: 0.75rem;\n\theight: 0.75rem;\n}\n\n.treeSummary {\n\tpadding-right: calc(var(--control-height) * 2);\n}\n\n.inputWithOverlay {\n\tcolor: transparent;\n\tcaret-color: transparent;\n}\n\n.valueOverlay {\n\tposition: absolute;\n\tinset: 0 calc(var(--control-height) * 2) 0 var(--space-md);\n\tdisplay: flex;\n\talign-items: center;\n\tpointer-events: none;\n\toverflow: hidden;\n}\n\n.treeActions {\n\tposition: absolute;\n\tright: 0;\n\ttop: 0;\n\theight: 100%;\n\tdisplay: flex;\n\talign-items: center;\n}\n\n.treeClearButton {\n\tcolor: var(--status-error-text);\n}\n","import { CSSProperties } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { CheckIcon, ChevronRightIcon, MinusIcon } from \"lucide-react\";\n\nimport { CheckBox } from \"../check-box\";\nimport { SelectOptionContent } from \"../select/SelectOptionContent\";\n\nimport styles from \"./TreeSelect.module.scss\";\nimport { TreeMultiSelectOptionsLayout, TreeSelectNode } from \"./types\";\n\ntype TreeNodeContentProps = {\n\tnode: TreeSelectNode;\n\tlevel: number;\n\thighlight?: string;\n\thasChildren: boolean;\n\tisExpanded: boolean;\n\tselected: boolean;\n\tpartial: boolean;\n\tselectionMode: \"single\" | \"multi\";\n\toptionsLayout?: TreeMultiSelectOptionsLayout;\n\tonToggleExpand?: () => void;\n\tonToggleSelection?: () => void;\n};\n\nexport function TreeNodeContent({\n\tnode,\n\tlevel,\n\thighlight,\n\thasChildren,\n\tisExpanded,\n\tselected,\n\tpartial,\n\tselectionMode,\n\toptionsLayout = \"tree\",\n\tonToggleExpand,\n\tonToggleSelection\n}: TreeNodeContentProps) {\n\tconst showExpansionControl = optionsLayout === \"tree\";\n\n\treturn (\n\t\t<>\n\t\t\t<span className={styles.treeIndent} style={{ \"--tree-level\": level } as CSSProperties} aria-hidden=\"true\" />\n\t\t\t{showExpansionControl && hasChildren ? (\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName={styles.treeExpander}\n\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\tonToggleExpand?.();\n\t\t\t\t\t}}\n\t\t\t\t\taria-label={isExpanded ? \"Свернуть ветку\" : \"Развернуть ветку\"}\n\t\t\t\t\tdata-ui=\"tree-select-expander\"\n\t\t\t\t\tdata-action={isExpanded ? \"collapse-tree-select-node\" : \"expand-tree-select-node\"}>\n\t\t\t\t\t<ChevronRightIcon className={cn(styles.treeExpanderIcon, isExpanded && styles.treeExpanderIconExpanded)} />\n\t\t\t\t</button>\n\t\t\t) : showExpansionControl ? (\n\t\t\t\t<span className={styles.treeExpanderPlaceholder} aria-hidden=\"true\" />\n\t\t\t) : null}\n\n\t\t\t{selectionMode === \"multi\" && optionsLayout === \"columns\" ? (\n\t\t\t\t<span\n\t\t\t\t\tclassName={styles.treeColumnCheckBox}\n\t\t\t\t\tonMouseDown={(event) => event.stopPropagation()}\n\t\t\t\t\tonClick={(event) => event.stopPropagation()}>\n\t\t\t\t\t<CheckBox\n\t\t\t\t\t\tvalue={selected}\n\t\t\t\t\t\tindeterminate={partial}\n\t\t\t\t\t\tdisabled={node.disabled}\n\t\t\t\t\t\taria-label={`Выбрать ${node.label}`}\n\t\t\t\t\t\tonChange={() => onToggleSelection?.()}\n\t\t\t\t\t/>\n\t\t\t\t</span>\n\t\t\t) : selectionMode === \"multi\" ? (\n\t\t\t\t<span\n\t\t\t\t\tclassName={cn(styles.treeSelection, selected && styles.treeSelectionChecked, partial && styles.treeSelectionPartial)}\n\t\t\t\t\taria-hidden=\"true\">\n\t\t\t\t\t{selected ? (\n\t\t\t\t\t\t<CheckIcon className={styles.treeSelectionIcon} />\n\t\t\t\t\t) : partial ? (\n\t\t\t\t\t\t<MinusIcon className={styles.treeSelectionIcon} />\n\t\t\t\t\t) : null}\n\t\t\t\t</span>\n\t\t\t) : null}\n\n\t\t\t<div className={styles.treeNodeOptionContent}>\n\t\t\t\t<SelectOptionContent label={node.label} code={node.code} highlight={highlight} />\n\t\t\t</div>\n\t\t</>\n\t);\n}\n","import { ReactNode, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { type FloatingListboxSizeResolver } from \"@ryuzaki13/react-foundation-lib/hooks\";\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { XIcon } from \"lucide-react\";\n\nimport { InputText } from \"../input\";\nimport {\n\tPickerField,\n\tPickerPopup,\n\tPickerSelectionToolbar,\n\tPickerStatus,\n\tPickerTriggerActions,\n\tPickerTriggerInput,\n\tusePickerFloatingListbox,\n\tusePickerQuery,\n\tusePickerTriggerController\n} from \"../picker\";\nimport { UiBaseProps } from \"../types\";\nimport uiStyles from \"../ui.module.scss\";\n\nimport { resolveBalancedTreeColumnsLayout } from \"./model/resolveBalancedTreeColumnsLayout\";\nimport {\n\tcreateTreeNodeIndex,\n\tfilterTreeNodes,\n\tflattenVisibleTreeNodes,\n\tgetSelectionExpandedIds,\n\tisTreeNodeSelected,\n\tTreeVisibleEntry\n} from \"./model/treeUtils\";\nimport { TreeNodeContent } from \"./TreeNodeContent\";\nimport styles from \"./TreeSelect.module.scss\";\nimport { TreeMultiSelectOptionsLayout, TreeSelectNode } from \"./types\";\n\ntype TreePickerBulkActions = {\n\tonSelectAll: () => void;\n\tonDeselectAll: () => void;\n};\n\ntype TreePickerBaseProps = Omit<UiBaseProps<never>, \"value\" | \"onChange\"> & {\n\tnodes: readonly TreeSelectNode[];\n\tselectedIds: Set<string>;\n\tpartialIds: Set<string>;\n\tselectionMode: \"single\" | \"multi\";\n\toptionsLayout?: TreeMultiSelectOptionsLayout;\n\topen?: boolean;\n\tonOpenChange?: (open: boolean) => void;\n\tbulkActions?: TreePickerBulkActions;\n\ttriggerMode?: \"display\" | \"search\";\n\tselectedSummary?: ReactNode;\n\tselectedSummaryText?: string;\n\tquery?: string;\n\tdefaultQuery?: string;\n\tonQuery?: (value: string) => void;\n\tonNodeActivate: (node: TreeSelectNode) => void;\n\tonClearSelection?: () => void;\n\tisLoading?: boolean;\n\terror?: string;\n};\n\nexport function TreePickerBase({\n\tlabel,\n\tdescription,\n\tdisabled,\n\tplaceholder,\n\tsize,\n\tnodes,\n\tselectedIds,\n\tpartialIds,\n\tselectionMode,\n\toptionsLayout = \"tree\",\n\topen: controlledOpen,\n\tonOpenChange,\n\tbulkActions,\n\ttriggerMode = \"display\",\n\tselectedSummary,\n\tselectedSummaryText,\n\tquery,\n\tdefaultQuery,\n\tonQuery,\n\tonNodeActivate,\n\tonClearSelection,\n\tisLoading,\n\terror\n}: TreePickerBaseProps) {\n\tconst inputRef = useRef<HTMLInputElement | null>(null);\n\tconst selectAllButtonRef = useRef<HTMLButtonElement | null>(null);\n\tconst previousOpenRef = useRef(false);\n\tconst [expandedIds, setExpandedIds] = useState<Set<string>>(() => new Set());\n\tconst resolvedTriggerMode = triggerMode === \"search\" ? (selectionMode === \"multi\" ? \"search-multi\" : \"search-single\") : \"display\";\n\tconst treeIndex = useMemo(() => createTreeNodeIndex(nodes), [nodes]);\n\tconst { query: currentQuery, setQuery } = usePickerQuery({\n\t\topen: true,\n\t\tquery,\n\t\tdefaultQuery,\n\t\tonQuery,\n\t\ttriggerMode: \"display\"\n\t});\n\tconst { nodes: filteredNodes, expandedIds: searchExpandedIds } = useMemo(\n\t\t() => filterTreeNodes(nodes, currentQuery),\n\t\t[nodes, currentQuery]\n\t);\n\tconst selectedExpandedIds = useMemo(() => getSelectionExpandedIds(selectedIds, treeIndex), [selectedIds, treeIndex]);\n\tconst allExpandedIds = useMemo(\n\t\t() => new Set([...treeIndex.childrenById].filter(([, childIds]) => childIds.length > 0).map(([nodeId]) => nodeId)),\n\t\t[treeIndex]\n\t);\n\tconst resolvedExpandedIds = useMemo(\n\t\t() => (optionsLayout === \"columns\" ? allExpandedIds : new Set([...expandedIds, ...searchExpandedIds, ...selectedExpandedIds])),\n\t\t[allExpandedIds, expandedIds, optionsLayout, searchExpandedIds, selectedExpandedIds]\n\t);\n\tconst visibleEntries = useMemo(() => flattenVisibleTreeNodes(filteredNodes, resolvedExpandedIds), [filteredNodes, resolvedExpandedIds]);\n\tconst selectedIndex = useMemo(() => visibleEntries.findIndex((entry) => selectedIds.has(entry.node.id)), [selectedIds, visibleEntries]);\n\tconst resolveColumnsFloatingSize = useCallback<FloatingListboxSizeResolver>(\n\t\t(context) => {\n\t\t\tconst layout = resolveBalancedTreeColumnsLayout({\n\t\t\t\t...context,\n\t\t\t\titemCount: visibleEntries.length\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\twidth: `${layout.width}px`,\n\t\t\t\tminWidth: `${layout.minWidth}px`,\n\t\t\t\tmaxWidth: `${layout.width}px`,\n\t\t\t\tmaxHeight: `${layout.maxHeight}px`,\n\t\t\t\t\"--tree-column-count\": String(layout.columnCount),\n\t\t\t\t\"--tree-row-count\": String(Math.max(layout.rowCount, 1))\n\t\t\t};\n\t\t},\n\t\t[visibleEntries.length]\n\t);\n\tconst {\n\t\topen,\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\thandleReferenceKeyDown,\n\t\thandleFloatingKeyDown,\n\t\tgetOptionId,\n\t\tgetActiveOptionId\n\t} = usePickerFloatingListbox({\n\t\toptions: visibleEntries,\n\t\tselectedIndex,\n\t\topen: controlledOpen,\n\t\tonOpenChange,\n\t\tonSelect: (entry) => onNodeActivate(entry.node),\n\t\tgetOptionDisabled: (entry) => entry.node.disabled === true,\n\t\tdisabled: disabled || isLoading,\n\t\tcloseOnSelect: selectionMode === \"single\",\n\t\tallowOpenWithoutOptions: true,\n\t\ttriggerMode: resolvedTriggerMode,\n\t\tplacementStrategy: optionsLayout === \"columns\" ? \"auto\" : \"flip\",\n\t\tresolveFloatingSize: optionsLayout === \"columns\" ? resolveColumnsFloatingSize : undefined\n\t});\n\tconst hasSelection = selectedIds.size > 0;\n\tconst showTriggerQuery = triggerMode === \"search\" && (open || currentQuery.length > 0);\n\tconst triggerValue = showTriggerQuery ? currentQuery : (selectedSummaryText ?? \"\");\n\tconst showSummaryOverlay = triggerMode === \"display\" && Boolean(selectedSummary);\n\tconst showSummaryToken = resolvedTriggerMode === \"search-multi\" && Boolean(selectedSummary);\n\tconst showTriggerPlaceholder =\n\t\t(resolvedTriggerMode === \"search-multi\" && !hasSelection) ||\n\t\t(resolvedTriggerMode === \"search-single\" && (!selectedSummaryText || showTriggerQuery)) ||\n\t\t(resolvedTriggerMode === \"display\" && !hasSelection);\n\tconst triggerController = usePickerTriggerController({\n\t\tmode: resolvedTriggerMode,\n\t\topen,\n\t\tcurrentQuery,\n\t\thasDisplayValue: Boolean(selectedSummaryText),\n\t\tinputRef,\n\t\tsetQuery,\n\t\topenList,\n\t\tclose,\n\t\ttoggleOpen\n\t});\n\tconst showBulkActions = optionsLayout === \"columns\" && selectionMode === \"multi\" && bulkActions;\n\tconst showPopupSearch = triggerMode === \"display\";\n\tconst popupHeader =\n\t\tshowBulkActions || showPopupSearch ? (\n\t\t\t<div className={styles.treePopupHeader}>\n\t\t\t\t{showBulkActions ? (\n\t\t\t\t\t<PickerSelectionToolbar\n\t\t\t\t\t\tonSelectAll={bulkActions.onSelectAll}\n\t\t\t\t\t\tonDeselectAll={bulkActions.onDeselectAll}\n\t\t\t\t\t\tselectAllButtonRef={selectAllButtonRef}\n\t\t\t\t\t/>\n\t\t\t\t) : null}\n\t\t\t\t{showPopupSearch ? (\n\t\t\t\t\t<InputText\n\t\t\t\t\t\tvalue={currentQuery}\n\t\t\t\t\t\tonChange={setQuery}\n\t\t\t\t\t\tonClear={() => setQuery(\"\")}\n\t\t\t\t\t\tplaceholder=\"Поиск по дереву\"\n\t\t\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\t\t\tif (event.key !== \"Escape\" && event.key !== \"Tab\") {\n\t\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t) : null}\n\t\t\t</div>\n\t\t) : undefined;\n\n\tuseEffect(() => {\n\t\tif (previousOpenRef.current && !open && triggerController.policy.resetQueryOnClose) {\n\t\t\tsetQuery(\"\");\n\t\t}\n\n\t\tpreviousOpenRef.current = open;\n\t}, [open, setQuery, triggerController.policy.resetQueryOnClose]);\n\n\tconst setInputNode = (node: HTMLInputElement | null) => {\n\t\tinputRef.current = node;\n\t};\n\tconst handleClearSelection = () => {\n\t\tonClearSelection?.();\n\t\tsetQuery(\"\");\n\n\t\tif (selectionMode === \"single\") {\n\t\t\tclose();\n\t\t}\n\t};\n\n\tconst toggleExpand = (entry: TreeVisibleEntry) => {\n\t\tif (!entry.hasChildren) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetExpandedIds((currentExpandedIds) => {\n\t\t\tconst nextExpandedIds = new Set(currentExpandedIds);\n\n\t\t\tif (nextExpandedIds.has(entry.node.id)) {\n\t\t\t\tnextExpandedIds.delete(entry.node.id);\n\t\t\t} else {\n\t\t\t\tnextExpandedIds.add(entry.node.id);\n\t\t\t}\n\n\t\t\treturn nextExpandedIds;\n\t\t});\n\t};\n\n\treturn (\n\t\t<PickerField label={label} description={description} disabled={disabled} placeholder={placeholder} size={size}>\n\t\t\t{({ controlId, labelId, describedBy }) => {\n\t\t\t\tconst listId = `${controlId}-listbox`;\n\t\t\t\tconst popupAriaLabel = typeof label === \"string\" ? label : placeholder;\n\n\t\t\t\treturn (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<PickerTriggerInput\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\trole=\"combobox\"\n\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\tdisabled={disabled || isLoading}\n\t\t\t\t\t\t\treadOnly={triggerMode !== \"search\"}\n\t\t\t\t\t\t\tvalue={triggerMode === \"display\" && showSummaryOverlay ? \"\" : triggerValue}\n\t\t\t\t\t\t\tplaceholder={showTriggerPlaceholder ? placeholder : undefined}\n\t\t\t\t\t\t\taria-labelledby={labelId}\n\t\t\t\t\t\t\taria-label={labelId ? undefined : placeholder}\n\t\t\t\t\t\t\taria-describedby={describedBy}\n\t\t\t\t\t\t\taria-haspopup={optionsLayout === \"columns\" ? \"dialog\" : \"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={optionsLayout !== \"columns\" && triggerMode === \"search\" ? \"list\" : \"none\"}\n\t\t\t\t\t\t\taria-activedescendant={\n\t\t\t\t\t\t\t\toptionsLayout !== \"columns\" && open && visibleEntries.length > 0 ? getActiveOptionId(listId) : undefined\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tinputClassName={cn(hasSelection && styles.treeSummary, showSummaryOverlay && styles.inputWithOverlay)}\n\t\t\t\t\t\t\toverlay={showSummaryOverlay ? <div className={styles.valueOverlay}>{selectedSummary}</div> : undefined}\n\t\t\t\t\t\t\tendAdornment={\n\t\t\t\t\t\t\t\t<PickerTriggerActions\n\t\t\t\t\t\t\t\t\topen={open}\n\t\t\t\t\t\t\t\t\tdisabled={disabled || isLoading}\n\t\t\t\t\t\t\t\t\tonToggleMouseDown={triggerController.handleToggleMouseDown}\n\t\t\t\t\t\t\t\t\tonToggleClick={triggerController.handleToggleClick}>\n\t\t\t\t\t\t\t\t\t{showSummaryToken ? selectedSummary : null}\n\n\t\t\t\t\t\t\t\t\t{hasSelection && onClearSelection ? (\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclassName={styles.treeClearButton}\n\t\t\t\t\t\t\t\t\t\t\tonMouseDown={(event) => {\n\t\t\t\t\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t\t\t\t\t\t\thandleClearSelection();\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\taria-label=\"Очистить выбор\">\n\t\t\t\t\t\t\t\t\t\t\t<XIcon />\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t</PickerTriggerActions>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\t\tif (triggerMode !== \"search\") {\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\tif (\n\t\t\t\t\t\t\t\t\toptionsLayout === \"columns\" &&\n\t\t\t\t\t\t\t\t\topen &&\n\t\t\t\t\t\t\t\t\tevent.key === \"Tab\" &&\n\t\t\t\t\t\t\t\t\t!event.shiftKey &&\n\t\t\t\t\t\t\t\t\tselectAllButtonRef.current\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\t\tselectAllButtonRef.current.focus();\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\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: () => {\n\t\t\t\t\t\t\t\t\t\tconst activeEntry = activeIndex >= 0 ? visibleEntries[activeIndex] : undefined;\n\t\t\t\t\t\t\t\t\t\tif (activeEntry) {\n\t\t\t\t\t\t\t\t\t\t\tselectOption(activeEntry);\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\tenableSpaceActivation: triggerMode === \"display\"\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\tpopupAriaLabel={popupAriaLabel}\n\t\t\t\t\t\t\tdescriptionId={describedBy}\n\t\t\t\t\t\t\tactiveOptionId={\n\t\t\t\t\t\t\t\toptionsLayout !== \"columns\" && visibleEntries.length > 0 ? getActiveOptionId(listId) : undefined\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tariaMultiselectable={optionsLayout !== \"columns\" && selectionMode === \"multi\"}\n\t\t\t\t\t\t\tpopupRole={optionsLayout === \"columns\" ? \"dialog\" : \"listbox\"}\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={uiStyles.uiPopupOptions}\n\t\t\t\t\t\t\tbodyClassName=\"scrollable\"\n\t\t\t\t\t\t\theader={popupHeader}>\n\t\t\t\t\t\t\t<div className={cn(optionsLayout === \"columns\" && styles.treeColumns)}>\n\t\t\t\t\t\t\t\t{visibleEntries.length === 0 ? (\n\t\t\t\t\t\t\t\t\t<PickerStatus\n\t\t\t\t\t\t\t\t\t\terrorState={error}\n\t\t\t\t\t\t\t\t\t\tloadingState={isLoading ? \"Загрузка...\" : undefined}\n\t\t\t\t\t\t\t\t\t\temptyState={!error && !isLoading ? \"Нет данных\" : undefined}\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\tvisibleEntries.map((entry, index) => {\n\t\t\t\t\t\t\t\t\t\tconst selected =\n\t\t\t\t\t\t\t\t\t\t\tselectionMode === \"multi\"\n\t\t\t\t\t\t\t\t\t\t\t\t? isTreeNodeSelected(entry.node.id, selectedIds, treeIndex)\n\t\t\t\t\t\t\t\t\t\t\t\t: selectedIds.has(entry.node.id);\n\t\t\t\t\t\t\t\t\t\tconst partial = selectionMode === \"multi\" && !selected && partialIds.has(entry.node.id);\n\t\t\t\t\t\t\t\t\t\tconst active = index === activeIndex;\n\t\t\t\t\t\t\t\t\t\tconst optionDisabled = entry.node.disabled === true;\n\n\t\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\t\tkey={entry.node.id}\n\t\t\t\t\t\t\t\t\t\t\t\tdata-ui=\"tree-select-option\"\n\t\t\t\t\t\t\t\t\t\t\t\tid={getOptionId(listId, index)}\n\t\t\t\t\t\t\t\t\t\t\t\tref={(node) => setOptionRef(index, node)}\n\t\t\t\t\t\t\t\t\t\t\t\trole={optionsLayout === \"columns\" ? undefined : \"option\"}\n\t\t\t\t\t\t\t\t\t\t\t\taria-selected={optionsLayout === \"columns\" ? undefined : selected}\n\t\t\t\t\t\t\t\t\t\t\t\taria-disabled={optionDisabled || undefined}\n\t\t\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\t\t\tstyles.treeRow,\n\t\t\t\t\t\t\t\t\t\t\t\t\toptionsLayout === \"columns\" && styles.treeColumnRow,\n\t\t\t\t\t\t\t\t\t\t\t\t\toptionDisabled && styles.treeRowDisabled,\n\t\t\t\t\t\t\t\t\t\t\t\t\tactive && styles.treeRowActive,\n\t\t\t\t\t\t\t\t\t\t\t\t\tselected && styles.treeRowSelected\n\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\tonMouseDown={(event) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\tonClick={() => selectOption(entry)}>\n\t\t\t\t\t\t\t\t\t\t\t\t<div className={styles.treeNodeButton}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<TreeNodeContent\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tnode={entry.node}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tlevel={entry.level}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\thighlight={currentQuery}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\thasChildren={entry.hasChildren}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tisExpanded={entry.isExpanded}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tselected={selected}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tpartial={partial}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tselectionMode={selectionMode}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\toptionsLayout={optionsLayout}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tonToggleExpand={() => toggleExpand(entry)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tonToggleSelection={() => selectOption(entry)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t/>\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</div>\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)}\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 { useMemo, useState } from \"react\";\n\nimport { MultiSelectToken } from \"../multi-select\";\nimport { usePickerSelectionLifecycle } from \"../picker\";\nimport { UiBaseProps } from \"../types\";\n\nimport {\n\tcreateTreeNodeIndex,\n\tgetSelectableTreeNodeIds,\n\tgetTreeNodeSelectionState,\n\ttoggleTreeMultiSelection,\n\ttreeMultiValueToSelectedIds,\n\ttreeSelectedIdsToMultiValue\n} from \"./model/treeUtils\";\nimport { TreePickerBase } from \"./TreePickerBase\";\nimport { TreeMultiSelectOptionsLayout, TreeMultiSelectValue, TreeSelectNode } from \"./types\";\n\nexport interface TreeMultiSelectProps extends Omit<UiBaseProps<TreeMultiSelectValue>, \"placeholder\"> {\n\tnodes: readonly TreeSelectNode[];\n\tplaceholder?: string;\n\tquery?: string;\n\tdefaultQuery?: string;\n\tonQuery?: (value: string) => void;\n\tisLoading?: boolean;\n\terror?: string;\n\t/** Определяет обычное раскрываемое дерево или полностью открытый адаптивный набор колонок. */\n\toptionsLayout?: TreeMultiSelectOptionsLayout;\n}\n\nfunction formatTreeMultiSummary(selectedIds: Set<string>, treeIndex: ReturnType<typeof createTreeNodeIndex>) {\n\tif (selectedIds.size === 0) {\n\t\treturn undefined;\n\t}\n\n\tif (selectedIds.size === 1) {\n\t\tconst selectedNode = treeIndex.nodeById.get([...selectedIds][0]);\n\n\t\tif (!selectedNode) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn selectedNode.label;\n\t}\n\n\treturn `${selectedIds.size} элементов`;\n}\n\n/**\n * Сравнивает семантический выбор по каноническим id дерева. Порядок ключей и\n * значений во внешнем Record не должен приводить к лишнему commit при закрытии.\n */\nfunction areTreeMultiSelectionsEqual(\n\tleft: TreeMultiSelectValue,\n\tright: TreeMultiSelectValue,\n\ttreeIndex: ReturnType<typeof createTreeNodeIndex>\n) {\n\tconst leftIds = treeMultiValueToSelectedIds(left, treeIndex);\n\tconst rightIds = treeMultiValueToSelectedIds(right, treeIndex);\n\n\treturn leftIds.size === rightIds.size && [...leftIds].every((nodeId) => rightIds.has(nodeId));\n}\n\nexport function TreeMultiSelect({\n\tlabel,\n\tdescription,\n\tdisabled,\n\tplaceholder = \"Выберите значения\",\n\tsize,\n\tnodes,\n\tvalue,\n\tonChange,\n\tquery,\n\tdefaultQuery,\n\tonQuery,\n\tisLoading,\n\terror,\n\toptionsLayout = \"tree\"\n}: TreeMultiSelectProps) {\n\tconst [open, setOpen] = useState(false);\n\tconst treeIndex = useMemo(() => createTreeNodeIndex(nodes), [nodes]);\n\tconst { draftValue, setDraftValue, prepareOpen } = usePickerSelectionLifecycle({\n\t\tvalue,\n\t\topen,\n\t\tonCommit: onChange,\n\t\tisEqual: (left, right) => areTreeMultiSelectionsEqual(left, right, treeIndex)\n\t});\n\tconst currentValue = open ? draftValue : value;\n\tconst selectedIds = useMemo(() => treeMultiValueToSelectedIds(currentValue, treeIndex), [currentValue, treeIndex]);\n\tconst selectionState = useMemo(() => getTreeNodeSelectionState(selectedIds, treeIndex), [selectedIds, treeIndex]);\n\tconst selectedSummary = useMemo(() => formatTreeMultiSummary(selectedIds, treeIndex), [selectedIds, treeIndex]);\n\tconst handleOpenChange = (nextOpen: boolean) => {\n\t\tif (nextOpen && !open) {\n\t\t\tprepareOpen();\n\t\t}\n\n\t\tsetOpen(nextOpen);\n\t};\n\tconst selectAll = () => {\n\t\tsetDraftValue(treeSelectedIdsToMultiValue(getSelectableTreeNodeIds(treeIndex), treeIndex));\n\t};\n\tconst clearSelection = () => {\n\t\tsetDraftValue({});\n\n\t\tif (!open) {\n\t\t\tonChange({});\n\t\t}\n\t};\n\n\treturn (\n\t\t<TreePickerBase\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\tdisabled={disabled}\n\t\t\tplaceholder={placeholder}\n\t\t\tsize={size}\n\t\t\tnodes={nodes}\n\t\t\tselectedIds={selectionState.selectedIds}\n\t\t\tpartialIds={selectionState.partialIds}\n\t\t\tselectionMode=\"multi\"\n\t\t\toptionsLayout={optionsLayout}\n\t\t\topen={open}\n\t\t\tonOpenChange={handleOpenChange}\n\t\t\tbulkActions={{\n\t\t\t\tonSelectAll: selectAll,\n\t\t\t\tonDeselectAll: () => setDraftValue({})\n\t\t\t}}\n\t\t\ttriggerMode=\"search\"\n\t\t\tselectedSummary={selectedSummary ? <MultiSelectToken value={selectedSummary} /> : undefined}\n\t\t\tquery={query}\n\t\t\tdefaultQuery={defaultQuery}\n\t\t\tonQuery={onQuery}\n\t\t\tonNodeActivate={(node) => {\n\t\t\t\tsetDraftValue((currentDraftValue) => toggleTreeMultiSelection(currentDraftValue, node.id, treeIndex));\n\t\t\t}}\n\t\t\tonClearSelection={clearSelection}\n\t\t\tisLoading={isLoading}\n\t\t\terror={error}\n\t\t/>\n\t);\n}\n","import { ODataDependentBaseProps } from \"@ryuzaki13/react-foundation-api/odata\";\n\nimport { UiBaseProps } from \"../types\";\n\nimport { useODataTreeData } from \"./model/useODataTreeData\";\nimport { TreeMultiSelect } from \"./TreeMultiSelect\";\nimport { TreeMultiSelectOptionsLayout, TreeMultiSelectValue } from \"./types\";\n\nexport interface ODataTreeMultiSelectProps\n\textends Omit<ODataDependentBaseProps, \"model\" | \"value\" | \"dependencies\">, Omit<UiBaseProps<TreeMultiSelectValue>, \"placeholder\"> {\n\tmodel?: ODataDependentBaseProps[\"model\"];\n\tplaceholder?: string;\n\tquery?: string;\n\tdefaultQuery?: string;\n\tonQuery?: (value: string) => void;\n\t/** Переключает способ показа загруженного OData-дерева, не меняя формат value и запросов. */\n\toptionsLayout?: TreeMultiSelectOptionsLayout;\n}\n\nexport function ODataTreeMultiSelect({\n\tlabel,\n\tdescription,\n\tdisabled,\n\tsize,\n\tplaceholder,\n\tquery,\n\tdefaultQuery,\n\tonQuery,\n\toptionsLayout,\n\tvalue,\n\tonChange,\n\todata,\n\tsegments,\n\tmodel\n}: ODataTreeMultiSelectProps) {\n\tconst treeData = useODataTreeData({\n\t\todata,\n\t\tsegments,\n\t\tmodel\n\t});\n\n\treturn (\n\t\t<TreeMultiSelect\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\tdisabled={disabled || treeData.isLoading}\n\t\t\tsize={size}\n\t\t\tplaceholder={placeholder ?? treeData.placeholder}\n\t\t\tnodes={treeData.nodes}\n\t\t\tvalue={value}\n\t\t\tonChange={onChange}\n\t\t\tquery={query}\n\t\t\tdefaultQuery={defaultQuery}\n\t\t\tonQuery={onQuery}\n\t\t\toptionsLayout={optionsLayout}\n\t\t\tisLoading={treeData.isLoading}\n\t\t\terror={treeData.isError ? \"Ошибка загрузки\" : undefined}\n\t\t/>\n\t);\n}\n","import { useMemo } from \"react\";\n\nimport { UiBaseProps } from \"../types\";\n\nimport { createTreeNodeIndex, treeSelectValueToId } from \"./model/treeUtils\";\nimport { TreePickerBase } from \"./TreePickerBase\";\nimport { TreeSelectNode, TreeSelectValue } from \"./types\";\n\nexport interface TreeSelectProps extends Omit<UiBaseProps<TreeSelectValue | undefined>, \"placeholder\"> {\n\tnodes: readonly TreeSelectNode[];\n\tplaceholder?: string;\n\tquery?: string;\n\tdefaultQuery?: string;\n\tonQuery?: (value: string) => void;\n\tisLoading?: boolean;\n\terror?: string;\n\tclearable?: boolean;\n}\n\nfunction formatTreeNodeSummary(node: TreeSelectNode | undefined) {\n\tif (!node) {\n\t\treturn undefined;\n\t}\n\n\tif (node.code && node.code !== node.label) {\n\t\treturn `${node.label} · ${node.code}`;\n\t}\n\n\treturn node.label;\n}\n\nexport function TreeSelect({\n\tlabel,\n\tdescription,\n\tdisabled,\n\tplaceholder = \"Выберите значение\",\n\tsize,\n\tnodes,\n\tvalue,\n\tonChange,\n\tquery,\n\tdefaultQuery,\n\tonQuery,\n\tisLoading,\n\terror,\n\tclearable = false\n}: TreeSelectProps) {\n\tconst treeIndex = useMemo(() => createTreeNodeIndex(nodes), [nodes]);\n\tconst selectedId = treeSelectValueToId(value, treeIndex);\n\tconst selectedNode = selectedId ? treeIndex.nodeById.get(selectedId) : undefined;\n\n\treturn (\n\t\t<TreePickerBase\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\tdisabled={disabled}\n\t\t\tplaceholder={placeholder}\n\t\t\tsize={size}\n\t\t\tnodes={nodes}\n\t\t\tselectedIds={selectedId ? new Set([selectedId]) : new Set()}\n\t\t\tpartialIds={new Set()}\n\t\t\tselectionMode=\"single\"\n\t\t\ttriggerMode=\"search\"\n\t\t\tselectedSummaryText={formatTreeNodeSummary(selectedNode)}\n\t\t\tquery={query}\n\t\t\tdefaultQuery={defaultQuery}\n\t\t\tonQuery={onQuery}\n\t\t\tonNodeActivate={(node) => onChange({ codeKey: node.codeKey, value: node.value })}\n\t\t\tonClearSelection={clearable ? () => onChange(undefined) : undefined}\n\t\t\tisLoading={isLoading}\n\t\t\terror={error}\n\t\t/>\n\t);\n}\n","import { ODataDependentBaseProps } from \"@ryuzaki13/react-foundation-api/odata\";\n\nimport { UiBaseProps } from \"../types\";\n\nimport { useODataTreeData } from \"./model/useODataTreeData\";\nimport { TreeSelect } from \"./TreeSelect\";\nimport { TreeSelectValue } from \"./types\";\n\nexport interface ODataTreeSelectProps\n\textends\n\t\tOmit<ODataDependentBaseProps, \"model\" | \"value\" | \"dependencies\">,\n\t\tOmit<UiBaseProps<TreeSelectValue | undefined>, \"placeholder\"> {\n\tmodel?: ODataDependentBaseProps[\"model\"];\n\tplaceholder?: string;\n\tquery?: string;\n\tdefaultQuery?: string;\n\tonQuery?: (value: string) => void;\n\tclearable?: boolean;\n}\n\nexport function ODataTreeSelect({\n\tlabel,\n\tdescription,\n\tdisabled,\n\tsize,\n\tplaceholder,\n\tquery,\n\tdefaultQuery,\n\tonQuery,\n\tvalue,\n\tonChange,\n\todata,\n\tsegments,\n\tmodel,\n\tclearable\n}: ODataTreeSelectProps) {\n\tconst treeData = useODataTreeData({\n\t\todata,\n\t\tsegments,\n\t\tmodel\n\t});\n\n\treturn (\n\t\t<TreeSelect\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\tdisabled={disabled || treeData.isLoading}\n\t\t\tsize={size}\n\t\t\tplaceholder={placeholder ?? treeData.placeholder}\n\t\t\tnodes={treeData.nodes}\n\t\t\tvalue={value}\n\t\t\tonChange={onChange}\n\t\t\tquery={query}\n\t\t\tdefaultQuery={defaultQuery}\n\t\t\tonQuery={onQuery}\n\t\t\tisLoading={treeData.isLoading}\n\t\t\terror={treeData.isError ? \"Ошибка загрузки\" : undefined}\n\t\t\tclearable={clearable}\n\t\t/>\n\t);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/tree-select/helpers.ts","../../src/tree-select/model/buildODataTreeNodes.ts","../../src/tree-select/model/resolveOrderedTreeSegmentItems.ts","../../src/tree-select/model/useODataTreeData.ts","../../src/tree-select/model/treeUtils.ts","../../src/tree-select/model/buildTreeColumnsLayoutDescriptor.ts","../../src/tree-select/model/resolveBalancedTreeColumnsLayout.ts","../../src/tree-select/TreeSelect.module.scss","../../src/tree-select/TreeNodeContent.tsx","../../src/tree-select/TreePickerBase.tsx","../../src/tree-select/TreeMultiSelect.tsx","../../src/tree-select/ODataTreeMultiSelect.tsx","../../src/tree-select/TreeSelect.tsx","../../src/tree-select/ODataTreeSelect.tsx"],"sourcesContent":["import { TreeMultiSelectValue, TreeSelectValue } from \"./types\";\n\nexport function treeSelectValueToSelectedFilters(value: TreeSelectValue | undefined): TreeMultiSelectValue {\n\tif (!value) {\n\t\treturn {};\n\t}\n\n\treturn {\n\t\t[value.codeKey]: [value.value]\n\t};\n}\n","import { CollectionItem } from \"@ryuzaki13/react-foundation-lib/odata\";\nimport { compareStrings } from \"@ryuzaki13/react-foundation-lib/string-comparison\";\n\nimport { TreeSelectNode } from \"../types\";\n\ntype BuildODataTreeNodesArgs = {\n\titems: CollectionItem[];\n\torderedCodeKeys: string[];\n\tkeyPairsMap: Record<string, string>;\n\thiddenCodeKeys: Set<string>;\n\ttextValueCodeKeys?: Set<string>;\n\t/** Выбирает локальный порядок узлов: по исходному коду или отображаемому тексту. */\n\tsortByCode?: boolean;\n};\n\ntype MutableTreeNode = TreeSelectNode & {\n\t/**\n\t * Исходный код нужен только для локальной сортировки представления.\n\t * Он не зависит от hideCode/selectText и не попадает в публичный TreeSelectNode.\n\t */\n\tsortCode: string;\n\tchildren: MutableTreeNode[];\n\tchildByBranchKey: Map<string, MutableTreeNode>;\n};\n\nfunction createNodeId(parentId: string | undefined, codeKey: string, value: string) {\n\treturn parentId ? `${parentId}/${codeKey}:${value}` : `${codeKey}:${value}`;\n}\n\nfunction resolveNodeLabel(item: CollectionItem, codeKey: string, keyPairsMap: Record<string, string>) {\n\tconst textKey = keyPairsMap[codeKey];\n\treturn (textKey && item[textKey]) || item[codeKey];\n}\n\nfunction createSearchText(parts: Array<string | undefined>) {\n\treturn [...new Set(parts.filter(Boolean))].join(\" \");\n}\n\nfunction createMutableNode(args: {\n\tparentId?: string;\n\tcodeKey: string;\n\tvalue: string;\n\tlabel: string;\n\tcode?: string;\n\tsortCode: string;\n}): MutableTreeNode {\n\treturn {\n\t\tid: createNodeId(args.parentId, args.codeKey, args.value),\n\t\tcodeKey: args.codeKey,\n\t\tvalue: args.value,\n\t\tlabel: args.label,\n\t\tcode: args.code,\n\t\tsearchText: createSearchText([args.value, args.label, args.code]),\n\t\tsortCode: args.sortCode,\n\t\tchildren: [],\n\t\tchildByBranchKey: new Map()\n\t};\n}\n\n/**\n * Сортирует только массивы вновь построенного дерева, не меняя исходную OData-коллекцию\n * и не создавая отдельный Query cache для каждого способа отображения.\n */\nfunction sortMutableTree(nodes: MutableTreeNode[], sortByCode: boolean) {\n\tnodes.sort((left, right) => {\n\t\tconst leftValue = sortByCode ? left.sortCode : left.label;\n\t\tconst rightValue = sortByCode ? right.sortCode : right.label;\n\t\tconst valueOrder = compareStrings(leftValue, rightValue);\n\n\t\treturn valueOrder || compareStrings(left.sortCode, right.sortCode);\n\t});\n\n\tfor (const node of nodes) {\n\t\tsortMutableTree(node.children, sortByCode);\n\t}\n}\n\nfunction toPublicNode(node: MutableTreeNode): TreeSelectNode {\n\treturn {\n\t\tid: node.id,\n\t\tcodeKey: node.codeKey,\n\t\tvalue: node.value,\n\t\tlabel: node.label,\n\t\tcode: node.code,\n\t\tsearchText: node.searchText,\n\t\tchildren: node.children.length > 0 ? node.children.map(toPublicNode) : undefined\n\t};\n}\n\nexport function buildODataTreeNodes({\n\titems,\n\torderedCodeKeys,\n\tkeyPairsMap,\n\thiddenCodeKeys,\n\ttextValueCodeKeys,\n\tsortByCode = true\n}: BuildODataTreeNodesArgs): TreeSelectNode[] {\n\tif (orderedCodeKeys.length === 0 || items.length === 0) {\n\t\treturn [];\n\t}\n\n\tconst roots: MutableTreeNode[] = [];\n\tconst rootByBranchKey = new Map<string, MutableTreeNode>();\n\n\tfor (const item of items) {\n\t\tlet parentNode: MutableTreeNode | undefined;\n\n\t\tfor (const codeKey of orderedCodeKeys) {\n\t\t\tconst codeValue = String(item[codeKey] ?? \"\");\n\n\t\t\tif (!codeValue) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tconst label = String(resolveNodeLabel(item, codeKey, keyPairsMap) ?? \"\");\n\t\t\tconst value = textValueCodeKeys?.has(codeKey) ? label : codeValue;\n\t\t\tconst branchKey = `${codeKey}:${value}`;\n\t\t\tconst container = parentNode ? parentNode.childByBranchKey : rootByBranchKey;\n\t\t\tlet currentNode = container.get(branchKey);\n\n\t\t\tif (!currentNode) {\n\t\t\t\tcurrentNode = createMutableNode({\n\t\t\t\t\tparentId: parentNode?.id,\n\t\t\t\t\tcodeKey,\n\t\t\t\t\tvalue,\n\t\t\t\t\tlabel,\n\t\t\t\t\tcode: hiddenCodeKeys.has(codeKey) ? undefined : codeValue,\n\t\t\t\t\tsortCode: codeValue\n\t\t\t\t});\n\t\t\t\tcontainer.set(branchKey, currentNode);\n\n\t\t\t\tif (parentNode) {\n\t\t\t\t\tparentNode.children.push(currentNode);\n\t\t\t\t} else {\n\t\t\t\t\troots.push(currentNode);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tparentNode = currentNode;\n\t\t}\n\t}\n\n\tsortMutableTree(roots, sortByCode);\n\n\treturn roots.map(toPublicNode);\n}\n","import { ODataDependentSegmentItem, sortODataDependentSegmentItemsByChains } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { ODataChainsMap } from \"@ryuzaki13/react-foundation-lib/odata-service\";\n\nexport function resolveOrderedTreeSegmentItems(items: readonly ODataDependentSegmentItem[], chains: ODataChainsMap) {\n\treturn sortODataDependentSegmentItemsByChains(items, chains);\n}\n","import { useMemo } from \"react\";\n\nimport {\n\tflattenODataDependentServices,\n\tODataCollectionModel,\n\tODataDependentBaseProps,\n\tODataDependentSegmentItem,\n\tuseODataCollection,\n\tuseODataCollectionChains,\n\tuseODataCollectionModel\n} from \"@ryuzaki13/react-foundation-api/odata\";\n\nimport { buildODataTreeNodes } from \"./buildODataTreeNodes\";\nimport { resolveOrderedTreeSegmentItems } from \"./resolveOrderedTreeSegmentItems\";\n\nfunction buildOrderedSegmentItems(\n\todata: ODataDependentBaseProps[\"odata\"],\n\tsegments: ODataDependentBaseProps[\"segments\"],\n\tmodel?: Omit<ODataCollectionModel, \"codeKey\">\n) {\n\treturn flattenODataDependentServices([\n\t\t{\n\t\t\todata,\n\t\t\tsegments,\n\t\t\tmodel\n\t\t}\n\t]);\n}\n\nfunction getRootCodeKey(orderedSegmentItems: readonly ODataDependentSegmentItem[]) {\n\treturn orderedSegmentItems[0]?.id;\n}\n\nexport function useODataTreeData({ odata, segments, model }: Pick<ODataDependentBaseProps, \"odata\" | \"segments\" | \"model\">) {\n\tconst serviceKey = `${odata.service}.${odata.target}`;\n\tconst baseSegmentItems = useMemo(() => buildOrderedSegmentItems(odata, segments, model), [odata, segments, model]);\n\tconst chains = useODataCollectionChains([odata]);\n\tconst orderedSegmentItems = useMemo(() => resolveOrderedTreeSegmentItems(baseSegmentItems, chains), [baseSegmentItems, chains]);\n\tconst orderedCodeKeys = useMemo(() => orderedSegmentItems.map((item) => item.id), [orderedSegmentItems]);\n\tconst rootCodeKey = getRootCodeKey(orderedSegmentItems) ?? Object.keys(segments)[0];\n\tconst odataModel = useODataCollectionModel({\n\t\tcodeKey: rootCodeKey,\n\t\t...model\n\t});\n\tconst collection = useODataCollection({\n\t\todata,\n\t\tmodel: odataModel\n\t});\n\tconst { hiddenCodeKeys, textValueCodeKeys } = useMemo(() => {\n\t\tconst nextHiddenCodeKeys = new Set<string>();\n\t\tconst nextTextValueCodeKeys = new Set<string>();\n\n\t\tfor (const item of orderedSegmentItems) {\n\t\t\tif (item.segment.hideCode ?? odata.hideCode) {\n\t\t\t\tnextHiddenCodeKeys.add(item.id);\n\t\t\t}\n\t\t\tif (item.segment.selectText) {\n\t\t\t\tnextTextValueCodeKeys.add(item.id);\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\thiddenCodeKeys: nextHiddenCodeKeys,\n\t\t\ttextValueCodeKeys: nextTextValueCodeKeys\n\t\t};\n\t}, [odata.hideCode, orderedSegmentItems]);\n\tconst nodes = useMemo(\n\t\t() =>\n\t\t\tbuildODataTreeNodes({\n\t\t\t\titems: collection.data?.items ?? [],\n\t\t\t\torderedCodeKeys,\n\t\t\t\tkeyPairsMap: collection.data?.keyPairsMap ?? {},\n\t\t\t\thiddenCodeKeys,\n\t\t\t\ttextValueCodeKeys,\n\t\t\t\tsortByCode: odata.sortByCode\n\t\t\t}),\n\t\t[collection.data?.items, collection.data?.keyPairsMap, hiddenCodeKeys, odata.sortByCode, orderedCodeKeys, textValueCodeKeys]\n\t);\n\tconst placeholder = orderedSegmentItems[0]?.segment.placeholder ?? \"Выберите значение\";\n\tconst hasResolvedChain = Boolean(chains[serviceKey]?.length);\n\n\treturn {\n\t\tnodes,\n\t\torderedSegmentItems,\n\t\torderedCodeKeys,\n\t\tisLoading: collection.isLoading,\n\t\tisError: collection.isError,\n\t\tplaceholder,\n\t\thasResolvedChain\n\t};\n}\n","import { TreeMultiSelectValue, TreeSelectNode, TreeSelectValue } from \"../types\";\n\nexport type TreeNodeIndex = {\n\trootIds: string[];\n\tnodeById: Map<string, TreeSelectNode>;\n\tparentById: Map<string, string | undefined>;\n\tchildrenById: Map<string, string[]>;\n\tpreorderIndexById: Map<string, number>;\n\tnodeIdByCodeValue: Map<string, string>;\n};\n\nexport type TreeNodeSelectionState = {\n\tselectedIds: Set<string>;\n\tpartialIds: Set<string>;\n};\n\nexport type TreeVisibleEntry = {\n\tnode: TreeSelectNode;\n\tlevel: number;\n\tparentId?: string;\n\thasChildren: boolean;\n\tisExpanded: boolean;\n\tisLeaf: boolean;\n};\n\nfunction makeCodeValueKey(codeKey: string, value: string) {\n\treturn `${codeKey}::${value}`;\n}\n\nexport function createTreeNodeIndex(nodes: readonly TreeSelectNode[]): TreeNodeIndex {\n\tconst nodeById = new Map<string, TreeSelectNode>();\n\tconst parentById = new Map<string, string | undefined>();\n\tconst childrenById = new Map<string, string[]>();\n\tconst preorderIndexById = new Map<string, number>();\n\tconst nodeIdByCodeValue = new Map<string, string>();\n\tlet preorderIndex = 0;\n\n\tconst walk = (node: TreeSelectNode, parentId?: string) => {\n\t\tnodeById.set(node.id, node);\n\t\tparentById.set(node.id, parentId);\n\t\tpreorderIndexById.set(node.id, preorderIndex++);\n\t\tnodeIdByCodeValue.set(makeCodeValueKey(node.codeKey, node.value), node.id);\n\n\t\tconst childIds = (node.children ?? []).map((child) => child.id);\n\t\tchildrenById.set(node.id, childIds);\n\n\t\tfor (const child of node.children ?? []) {\n\t\t\twalk(child, node.id);\n\t\t}\n\t};\n\n\tfor (const node of nodes) {\n\t\twalk(node);\n\t}\n\n\treturn {\n\t\trootIds: nodes.map((node) => node.id),\n\t\tnodeById,\n\t\tparentById,\n\t\tchildrenById,\n\t\tpreorderIndexById,\n\t\tnodeIdByCodeValue\n\t};\n}\n\nexport function treeSelectValueToId(value: TreeSelectValue | undefined, index: TreeNodeIndex) {\n\tif (!value) return undefined;\n\treturn index.nodeIdByCodeValue.get(makeCodeValueKey(value.codeKey, value.value));\n}\n\nexport function treeMultiValueToSelectedIds(value: TreeMultiSelectValue | undefined, index: TreeNodeIndex) {\n\tconst selectedIds = new Set<string>();\n\n\tif (!value) {\n\t\treturn selectedIds;\n\t}\n\n\tfor (const [codeKey, values] of Object.entries(value)) {\n\t\tfor (const itemValue of values) {\n\t\t\tconst nodeId = index.nodeIdByCodeValue.get(makeCodeValueKey(codeKey, itemValue));\n\t\t\tif (nodeId) {\n\t\t\t\tselectedIds.add(nodeId);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn canonicalizeTreeSelection(selectedIds, index);\n}\n\nexport function treeSelectedIdsToMultiValue(selectedIds: Set<string>, index: TreeNodeIndex): TreeMultiSelectValue {\n\tconst orderedIds = [...selectedIds].sort(\n\t\t(leftId, rightId) =>\n\t\t\t(index.preorderIndexById.get(leftId) ?? Number.MAX_SAFE_INTEGER) -\n\t\t\t(index.preorderIndexById.get(rightId) ?? Number.MAX_SAFE_INTEGER)\n\t);\n\tconst result: TreeMultiSelectValue = {};\n\n\tfor (const nodeId of orderedIds) {\n\t\tconst node = index.nodeById.get(nodeId);\n\t\tif (!node) continue;\n\n\t\tresult[node.codeKey] = result[node.codeKey] ?? [];\n\t\tresult[node.codeKey].push(node.value);\n\t}\n\n\treturn result;\n}\n\nexport function treeSelectValueToMultiValue(value: TreeSelectValue | undefined): TreeMultiSelectValue {\n\tif (!value) {\n\t\treturn {};\n\t}\n\n\treturn {\n\t\t[value.codeKey]: [value.value]\n\t};\n}\n\nfunction getAncestorIds(nodeId: string, index: TreeNodeIndex) {\n\tconst ancestors: string[] = [];\n\tlet currentId = index.parentById.get(nodeId);\n\n\twhile (currentId) {\n\t\tancestors.push(currentId);\n\t\tcurrentId = index.parentById.get(currentId);\n\t}\n\n\treturn ancestors;\n}\n\nfunction isDescendantOf(nodeId: string, ancestorId: string, index: TreeNodeIndex) {\n\tlet currentId = index.parentById.get(nodeId);\n\n\twhile (currentId) {\n\t\tif (currentId === ancestorId) {\n\t\t\treturn true;\n\t\t}\n\n\t\tcurrentId = index.parentById.get(currentId);\n\t}\n\n\treturn false;\n}\n\nfunction removeDescendantSelections(selectedIds: Set<string>, nodeId: string, index: TreeNodeIndex) {\n\tfor (const selectedId of [...selectedIds]) {\n\t\tif (isDescendantOf(selectedId, nodeId, index)) {\n\t\t\tselectedIds.delete(selectedId);\n\t\t}\n\t}\n}\n\nfunction isNodeFullySelected(nodeId: string, selectedIds: Set<string>, index: TreeNodeIndex): boolean {\n\tif (selectedIds.has(nodeId)) {\n\t\treturn true;\n\t}\n\tif (index.nodeById.get(nodeId)?.disabled) {\n\t\treturn false;\n\t}\n\n\tconst children = index.childrenById.get(nodeId) ?? [];\n\tif (children.length === 0) {\n\t\treturn false;\n\t}\n\n\treturn children.every((childId) => isNodeFullySelected(childId, selectedIds, index));\n}\n\nexport function canonicalizeTreeSelection(selectedIds: Set<string>, index: TreeNodeIndex) {\n\tconst nextSelectedIds = new Set(selectedIds);\n\n\tfor (const selectedId of [...nextSelectedIds]) {\n\t\tif (getAncestorIds(selectedId, index).some((ancestorId) => nextSelectedIds.has(ancestorId))) {\n\t\t\tnextSelectedIds.delete(selectedId);\n\t\t}\n\t}\n\n\tconst orderedNodeIds = [...index.nodeById.keys()].sort(\n\t\t(leftId, rightId) => (index.preorderIndexById.get(rightId) ?? 0) - (index.preorderIndexById.get(leftId) ?? 0)\n\t);\n\n\tfor (const nodeId of orderedNodeIds) {\n\t\tconst children = index.childrenById.get(nodeId) ?? [];\n\n\t\tif (children.length === 0 || nextSelectedIds.has(nodeId) || index.nodeById.get(nodeId)?.disabled) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (children.every((childId) => isNodeFullySelected(childId, nextSelectedIds, index))) {\n\t\t\tremoveDescendantSelections(nextSelectedIds, nodeId, index);\n\t\t\tnextSelectedIds.add(nodeId);\n\t\t}\n\t}\n\n\treturn nextSelectedIds;\n}\n\nfunction expandNearestSelectedAncestor(selectedIds: Set<string>, nodeId: string, index: TreeNodeIndex) {\n\tlet currentId = index.parentById.get(nodeId);\n\n\twhile (currentId) {\n\t\tif (selectedIds.has(currentId)) {\n\t\t\tselectedIds.delete(currentId);\n\n\t\t\t/*\n\t\t\t * Узел мог стать disabled уже после сохранения выбора его ancestor.\n\t\t\t * При частичном снятии разворачиваем ancestor только в актуально\n\t\t\t * доступное покрытие, чтобы запрещённое значение не попало в onChange.\n\t\t\t */\n\t\t\tfor (const childId of getSelectableTreeNodeIds(index, index.childrenById.get(currentId) ?? [])) {\n\t\t\t\tselectedIds.add(childId);\n\t\t\t}\n\n\t\t\treturn true;\n\t\t}\n\n\t\tcurrentId = index.parentById.get(currentId);\n\t}\n\n\treturn false;\n}\n\nexport function isTreeNodeSelected(nodeId: string, selectedIds: Set<string>, index: TreeNodeIndex): boolean {\n\tif (selectedIds.has(nodeId)) {\n\t\treturn true;\n\t}\n\n\treturn getAncestorIds(nodeId, index).some((ancestorId) => selectedIds.has(ancestorId));\n}\n\nfunction resolveTreeSelectionState(nodeId: string, selectedIds: Set<string>, index: TreeNodeIndex, state: TreeNodeSelectionState) {\n\tconst children = index.childrenById.get(nodeId) ?? [];\n\n\tif (selectedIds.has(nodeId)) {\n\t\tstate.selectedIds.add(nodeId);\n\t\treturn { selected: true, partial: false };\n\t}\n\n\tif (children.length === 0) {\n\t\treturn { selected: false, partial: false };\n\t}\n\n\tconst childStates = children.map((childId) => resolveTreeSelectionState(childId, selectedIds, index, state));\n\tconst allSelected = childStates.every((childState) => childState.selected && !childState.partial);\n\tconst hasAnySelected = childStates.some((childState) => childState.selected || childState.partial);\n\n\tif (allSelected) {\n\t\tstate.selectedIds.add(nodeId);\n\t\treturn { selected: true, partial: false };\n\t}\n\n\tif (hasAnySelected) {\n\t\tstate.partialIds.add(nodeId);\n\t\treturn { selected: false, partial: true };\n\t}\n\n\treturn { selected: false, partial: false };\n}\n\nexport function getTreeNodeSelectionState(selectedIds: Set<string>, index: TreeNodeIndex): TreeNodeSelectionState {\n\tconst state: TreeNodeSelectionState = {\n\t\tselectedIds: new Set(),\n\t\tpartialIds: new Set()\n\t};\n\n\tfor (const rootId of index.rootIds) {\n\t\tresolveTreeSelectionState(rootId, selectedIds, index, state);\n\t}\n\n\treturn state;\n}\n\n/**\n * Строит каноническое покрытие всех доступных узлов для массового выбора.\n * Ветка схлопывается в parent только тогда, когда внутри неё нет disabled-узлов;\n * иначе выбираются доступные дочерние поддеревья, не затрагивая запреты.\n */\nexport function getSelectableTreeNodeIds(index: TreeNodeIndex, rootIds: readonly string[] = index.rootIds): Set<string> {\n\tconst collectSubtree = (nodeId: string): { containsDisabled: boolean; selectedIds: string[] } => {\n\t\tconst node = index.nodeById.get(nodeId);\n\t\tconst childSelections = (index.childrenById.get(nodeId) ?? []).map(collectSubtree);\n\t\tconst selectedChildIds = childSelections.flatMap((selection) => selection.selectedIds);\n\t\tconst containsDisabled = node?.disabled === true || childSelections.some((selection) => selection.containsDisabled);\n\n\t\tif (!node || node.disabled) {\n\t\t\treturn { containsDisabled: true, selectedIds: selectedChildIds };\n\t\t}\n\n\t\treturn containsDisabled\n\t\t\t? { containsDisabled: true, selectedIds: selectedChildIds }\n\t\t\t: { containsDisabled: false, selectedIds: [nodeId] };\n\t};\n\n\treturn new Set(rootIds.flatMap((rootId) => collectSubtree(rootId).selectedIds));\n}\n\nexport function toggleTreeMultiSelection(currentValue: TreeMultiSelectValue | undefined, targetNodeId: string, index: TreeNodeIndex) {\n\tconst selectedIds = treeMultiValueToSelectedIds(currentValue, index);\n\n\tconst toggle = (targetId: string) => {\n\t\tif (isTreeNodeSelected(targetId, selectedIds, index)) {\n\t\t\tif (selectedIds.has(targetId)) {\n\t\t\t\tselectedIds.delete(targetId);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (expandNearestSelectedAncestor(selectedIds, targetId, index)) {\n\t\t\t\ttoggle(targetId);\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tremoveDescendantSelections(selectedIds, targetId, index);\n\t\tselectedIds.add(targetId);\n\t};\n\n\tconst selectableTargetIds = [...getSelectableTreeNodeIds(index, [targetNodeId])];\n\tconst allSelectableTargetsSelected =\n\t\tselectableTargetIds.length > 0 && selectableTargetIds.every((nodeId) => isTreeNodeSelected(nodeId, selectedIds, index));\n\n\tfor (const selectableTargetId of selectableTargetIds) {\n\t\tconst selected = isTreeNodeSelected(selectableTargetId, selectedIds, index);\n\t\tif ((allSelectableTargetsSelected && selected) || (!allSelectableTargetsSelected && !selected)) {\n\t\t\ttoggle(selectableTargetId);\n\t\t}\n\t}\n\n\treturn treeSelectedIdsToMultiValue(canonicalizeTreeSelection(selectedIds, index), index);\n}\n\nfunction collectExpandedIds(nodeId: string, index: TreeNodeIndex, expandedIds: Set<string>) {\n\tlet currentId = index.parentById.get(nodeId);\n\n\twhile (currentId) {\n\t\texpandedIds.add(currentId);\n\t\tcurrentId = index.parentById.get(currentId);\n\t}\n}\n\nexport function getSelectionExpandedIds(selectedIds: Set<string>, index: TreeNodeIndex) {\n\tconst expandedIds = new Set<string>();\n\n\tfor (const selectedId of selectedIds) {\n\t\tcollectExpandedIds(selectedId, index, expandedIds);\n\t}\n\n\treturn expandedIds;\n}\n\n/**\n * Вычисляет базовое раскрытие дерева из политики уровней и ручных действий.\n *\n * Ручное значение хранится отдельно для каждого node id и имеет приоритет над\n * default уровня. Благодаря вычислению по актуальному индексу узлы, загруженные\n * асинхронно, получают настройку без синхронизации props в React state.\n */\nexport function getConfiguredTreeExpandedIds(\n\tindex: TreeNodeIndex,\n\tdefaultExpandedCodeKeys: ReadonlySet<string>,\n\tmanualExpansionById: ReadonlyMap<string, boolean>\n) {\n\tconst expandedIds = new Set<string>();\n\n\tfor (const [nodeId, childIds] of index.childrenById) {\n\t\tif (childIds.length === 0) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst node = index.nodeById.get(nodeId);\n\t\tif (!node) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (manualExpansionById.get(nodeId) ?? defaultExpandedCodeKeys.has(node.codeKey)) {\n\t\t\texpandedIds.add(nodeId);\n\t\t}\n\t}\n\n\treturn expandedIds;\n}\n\nfunction filterTreeNode(node: TreeSelectNode, normalizedQuery: string, expandedIds: Set<string>): TreeSelectNode | null {\n\tconst filteredChildren = (node.children ?? [])\n\t\t.map((childNode) => filterTreeNode(childNode, normalizedQuery, expandedIds))\n\t\t.filter((childNode): childNode is TreeSelectNode => Boolean(childNode));\n\tconst isMatched = node.searchText.toLowerCase().includes(normalizedQuery);\n\n\tif (!isMatched && filteredChildren.length === 0) {\n\t\treturn null;\n\t}\n\n\tif (filteredChildren.length > 0) {\n\t\texpandedIds.add(node.id);\n\t}\n\n\tif (filteredChildren.length === 0) {\n\t\treturn node;\n\t}\n\n\treturn {\n\t\t...node,\n\t\tchildren: filteredChildren\n\t};\n}\n\nexport function filterTreeNodes(nodes: readonly TreeSelectNode[], query: string) {\n\tconst normalizedQuery = query.trim().toLowerCase();\n\n\tif (!normalizedQuery) {\n\t\treturn {\n\t\t\tnodes: [...nodes],\n\t\t\texpandedIds: new Set<string>()\n\t\t};\n\t}\n\n\tconst expandedIds = new Set<string>();\n\tconst filteredNodes = nodes\n\t\t.map((node) => filterTreeNode(node, normalizedQuery, expandedIds))\n\t\t.filter((node): node is TreeSelectNode => Boolean(node));\n\n\treturn {\n\t\tnodes: filteredNodes,\n\t\texpandedIds\n\t};\n}\n\nexport function flattenVisibleTreeNodes(nodes: readonly TreeSelectNode[], expandedIds: Set<string>): TreeVisibleEntry[] {\n\tconst entries: TreeVisibleEntry[] = [];\n\n\tconst walk = (node: TreeSelectNode, level: number, parentId?: string) => {\n\t\tconst hasChildren = (node.children?.length ?? 0) > 0;\n\t\tconst isExpanded = hasChildren && expandedIds.has(node.id);\n\n\t\tentries.push({\n\t\t\tnode,\n\t\t\tlevel,\n\t\t\tparentId,\n\t\t\thasChildren,\n\t\t\tisExpanded,\n\t\t\tisLeaf: !hasChildren\n\t\t});\n\n\t\tif (!isExpanded) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const childNode of node.children ?? []) {\n\t\t\twalk(childNode, level + 1, node.id);\n\t\t}\n\t};\n\n\tfor (const node of nodes) {\n\t\twalk(node, 0);\n\t}\n\n\treturn entries;\n}\n","export type TreeColumnsLayoutEntryDescriptor = {\n\tlevel: number;\n};\n\n/** Границы одной root-группы в исходном DOM preorder. */\nexport type TreeColumnsRootGroupDescriptor = {\n\tstartIndex: number;\n\tendIndexExclusive: number;\n\tprotectedPrefixEndIndexExclusive?: number;\n};\n\n/** Структурный вход columns-resolver и стабильная сигнатура для Floating UI. */\nexport type TreeColumnsLayoutDescriptor = {\n\titemCount: number;\n\tgroups: readonly TreeColumnsRootGroupDescriptor[];\n\tsignature: string;\n};\n\n/**\n * Описывает root-группы видимой части дерева, не меняя исходный preorder.\n *\n * Защищённый prefix создаётся только для root с более чем двумя прямыми\n * видимыми children. Его граница включает строку второго direct child, поэтому\n * вложенные descendants первого child не ошибочно считаются вторым child.\n */\nexport function buildTreeColumnsLayoutDescriptor(entries: readonly TreeColumnsLayoutEntryDescriptor[]): TreeColumnsLayoutDescriptor {\n\tconst groups: TreeColumnsRootGroupDescriptor[] = [];\n\tlet groupStartIndex = 0;\n\n\twhile (groupStartIndex < entries.length) {\n\t\tlet groupEndIndexExclusive = groupStartIndex + 1;\n\t\twhile (groupEndIndexExclusive < entries.length && entries[groupEndIndexExclusive]?.level !== 0) {\n\t\t\tgroupEndIndexExclusive += 1;\n\t\t}\n\n\t\tconst directChildIndexes: number[] = [];\n\t\tfor (let index = groupStartIndex + 1; index < groupEndIndexExclusive; index += 1) {\n\t\t\tif (entries[index]?.level === 1) {\n\t\t\t\tdirectChildIndexes.push(index);\n\t\t\t}\n\t\t}\n\n\t\tgroups.push({\n\t\t\tstartIndex: groupStartIndex,\n\t\t\tendIndexExclusive: groupEndIndexExclusive,\n\t\t\t...(directChildIndexes.length > 2 ? { protectedPrefixEndIndexExclusive: (directChildIndexes[1] ?? groupStartIndex) + 1 } : {})\n\t\t});\n\t\tgroupStartIndex = groupEndIndexExclusive;\n\t}\n\n\tconst signature = groups\n\t\t.map(\n\t\t\t({ startIndex, endIndexExclusive, protectedPrefixEndIndexExclusive }) =>\n\t\t\t\t`${startIndex}:${endIndexExclusive}:${protectedPrefixEndIndexExclusive ?? \"-\"}`\n\t\t)\n\t\t.join(\"|\");\n\n\treturn {\n\t\titemCount: entries.length,\n\t\tgroups,\n\t\tsignature: `${entries.length}|${signature}`\n\t};\n}\n","import type { TreeColumnsLayoutDescriptor, TreeColumnsRootGroupDescriptor } from \"./buildTreeColumnsLayoutDescriptor\";\n\nexport type BalancedTreeColumnsLayoutInput = {\n\tdescriptor: TreeColumnsLayoutDescriptor;\n\tavailableWidth: number;\n\tavailableHeight: number;\n\tviewportWidth: number;\n\tviewportHeight: number;\n\treferenceWidth: number;\n};\n\nexport type BalancedTreeColumnsLayout = {\n\tcolumnCount: number;\n\trowCount: number;\n\twidth: number;\n\tminWidth: number;\n\tmaxHeight: number;\n\tplacements: readonly TreeColumnPlacement[];\n};\n\n/** Явная 1-based CSS-grid координата строки с неизменным option index. */\nexport type TreeColumnPlacement = {\n\tcolumn: number;\n\trow: number;\n};\n\nconst VIEWPORT_PADDING = 8;\nconst POPUP_HORIZONTAL_PADDING = 16;\nconst POPUP_CHROME_HEIGHT = 48;\nconst COLUMN_WIDTH = 224;\nconst COLUMN_GAP = 10;\nconst OPTION_HEIGHT = 32;\nconst MAX_COLUMN_COUNT = 6;\n\nfunction normalizePositiveDimension(value: number, fallback: number) {\n\treturn Number.isFinite(value) && value > 0 ? value : fallback;\n}\n\n/** Результат одной симуляции packing для заданной логической высоты колонки. */\nexport type ResolvedTreeColumnsPlacements = {\n\tplacements: TreeColumnPlacement[];\n\tusedColumnCount: number;\n\tintentionalGapCount: number;\n};\n\n/**\n * Выбирает начало root-группы, которое нельзя оставлять в хвосте колонки.\n *\n * Целая группа имеет приоритет, затем используется prefix до второго прямого\n * child. Если глубокий subtree делает prefix выше колонки, защищаются первые\n * три визуальные строки — минимальная гарантия от одинокого root.\n */\nfunction resolveProtectedItemCount(group: TreeColumnsRootGroupDescriptor, rowCount: number) {\n\tconst groupSize = group.endIndexExclusive - group.startIndex;\n\tif (groupSize <= rowCount) return groupSize;\n\n\tif (group.protectedPrefixEndIndexExclusive === undefined) return 0;\n\n\tconst protectedPrefixSize = group.protectedPrefixEndIndexExclusive - group.startIndex;\n\treturn protectedPrefixSize <= rowCount ? protectedPrefixSize : Math.min(3, groupSize);\n}\n\n/**\n * Симулирует CSS-grid packing и сохраняет DOM preorder через явные координаты.\n *\n * Намеренный перенос оставляет хвост предыдущей колонки пустым: последующие\n * группы не заполняют gap, поэтому визуальная последовательность не расходится\n * с option indexes, refs и keyboard navigation.\n */\nexport function resolveTreeColumnsPlacements(descriptor: TreeColumnsLayoutDescriptor, rowCount: number): ResolvedTreeColumnsPlacements {\n\tconst normalizedRowCount = Math.max(1, rowCount);\n\tconst placements: TreeColumnPlacement[] = [];\n\tlet column = 1;\n\tlet row = 1;\n\tlet intentionalGapCount = 0;\n\n\tfor (const group of descriptor.groups) {\n\t\tconst protectedItemCount = resolveProtectedItemCount(group, normalizedRowCount);\n\t\tconst remainingRows = normalizedRowCount - row + 1;\n\n\t\tif (row > 1 && protectedItemCount > remainingRows) {\n\t\t\tintentionalGapCount += remainingRows;\n\t\t\tcolumn += 1;\n\t\t\trow = 1;\n\t\t}\n\n\t\tfor (let index = group.startIndex; index < group.endIndexExclusive; index += 1) {\n\t\t\tplacements[index] = { column, row };\n\t\t\trow += 1;\n\n\t\t\tif (row > normalizedRowCount) {\n\t\t\t\tcolumn += 1;\n\t\t\t\trow = 1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tplacements,\n\t\tusedColumnCount: placements.length ? Math.max(...placements.map((placement) => placement.column)) : 1,\n\t\tintentionalGapCount\n\t};\n}\n\n/**\n * Выбирает количество колонок по фактически доступной Floating UI геометрии.\n * Для каждого candidate сначала выполняется group-aware packing. Если защитные\n * переносы создали лишнюю колонку, высота логической колонки увеличивается до\n * тех пор, пока placements не попадут в объявленный template grid.\n */\nexport function resolveBalancedTreeColumnsLayout({\n\tdescriptor,\n\tavailableWidth,\n\tavailableHeight,\n\tviewportWidth,\n\tviewportHeight,\n\treferenceWidth\n}: BalancedTreeColumnsLayoutInput): BalancedTreeColumnsLayout {\n\tconst normalizedItemCount = Math.max(0, Math.floor(Number.isFinite(descriptor.itemCount) ? descriptor.itemCount : 0));\n\tconst normalizedAvailableWidth = normalizePositiveDimension(availableWidth, COLUMN_WIDTH + POPUP_HORIZONTAL_PADDING);\n\tconst normalizedAvailableHeight = normalizePositiveDimension(availableHeight, OPTION_HEIGHT + POPUP_CHROME_HEIGHT);\n\tconst normalizedViewportWidth = normalizePositiveDimension(viewportWidth, normalizedAvailableWidth + VIEWPORT_PADDING * 2);\n\tconst normalizedViewportHeight = normalizePositiveDimension(viewportHeight, normalizedAvailableHeight);\n\tconst widthLimit = Math.max(1, Math.min(normalizedAvailableWidth, Math.max(1, normalizedViewportWidth - VIEWPORT_PADDING * 2)));\n\tconst heightLimit = Math.max(1, Math.min(normalizedAvailableHeight, normalizedViewportHeight - VIEWPORT_PADDING * 2));\n\tconst normalizedReferenceWidth = Math.max(1, normalizePositiveDimension(referenceWidth, 1));\n\tconst minWidth = Math.min(widthLimit, normalizedReferenceWidth);\n\tconst maxColumnsByWidth = Math.max(1, Math.floor((widthLimit - POPUP_HORIZONTAL_PADDING + COLUMN_GAP) / (COLUMN_WIDTH + COLUMN_GAP)));\n\tconst maxColumnCount = Math.max(1, Math.min(MAX_COLUMN_COUNT, maxColumnsByWidth, normalizedItemCount || 1));\n\tconst minProtectedRows = descriptor.groups.some((group) => group.protectedPrefixEndIndexExclusive !== undefined) ? 3 : 1;\n\n\tif (normalizedItemCount === 0) {\n\t\treturn {\n\t\t\tcolumnCount: 1,\n\t\t\trowCount: 1,\n\t\t\twidth: minWidth,\n\t\t\tminWidth,\n\t\t\tmaxHeight: heightLimit,\n\t\t\tplacements: []\n\t\t};\n\t}\n\n\tlet bestLayout: BalancedTreeColumnsLayout | undefined;\n\tlet bestScore = Number.POSITIVE_INFINITY;\n\n\tfor (let candidateColumnCount = 1; candidateColumnCount <= maxColumnCount; candidateColumnCount += 1) {\n\t\tlet rowCount = Math.max(minProtectedRows, Math.ceil(normalizedItemCount / candidateColumnCount));\n\t\tlet packed = resolveTreeColumnsPlacements(descriptor, rowCount);\n\n\t\twhile (packed.usedColumnCount > candidateColumnCount && rowCount < normalizedItemCount) {\n\t\t\trowCount += 1;\n\t\t\tpacked = resolveTreeColumnsPlacements(descriptor, rowCount);\n\t\t}\n\n\t\tconst columnCount = packed.usedColumnCount;\n\t\tconst naturalWidth = Math.max(minWidth, POPUP_HORIZONTAL_PADDING + columnCount * COLUMN_WIDTH + (columnCount - 1) * COLUMN_GAP);\n\t\tconst naturalHeight = POPUP_CHROME_HEIGHT + rowCount * OPTION_HEIGHT;\n\t\tconst widthRatio = naturalWidth / widthLimit;\n\t\tconst heightRatio = naturalHeight / heightLimit;\n\t\tconst emptyCellPenalty = (columnCount * rowCount - normalizedItemCount) / normalizedItemCount;\n\t\tconst intentionalGapPenalty = packed.intentionalGapCount / normalizedItemCount;\n\t\tconst score =\n\t\t\tMath.max(widthRatio, heightRatio) +\n\t\t\t0.25 * Math.abs(widthRatio - heightRatio) +\n\t\t\t0.01 * emptyCellPenalty +\n\t\t\t0.02 * intentionalGapPenalty +\n\t\t\t0.04 * (columnCount - 1);\n\n\t\tif (score < bestScore) {\n\t\t\tbestScore = score;\n\t\t\tbestLayout = {\n\t\t\t\tcolumnCount,\n\t\t\t\trowCount,\n\t\t\t\twidth: Math.min(widthLimit, naturalWidth),\n\t\t\t\tminWidth,\n\t\t\t\tmaxHeight: heightLimit,\n\t\t\t\tplacements: packed.placements\n\t\t\t};\n\t\t}\n\t}\n\n\treturn (\n\t\tbestLayout ?? {\n\t\t\tcolumnCount: 1,\n\t\t\trowCount: normalizedItemCount,\n\t\t\twidth: minWidth,\n\t\t\tminWidth,\n\t\t\tmaxHeight: heightLimit,\n\t\t\tplacements: resolveTreeColumnsPlacements(descriptor, normalizedItemCount).placements\n\t\t}\n\t);\n}\n","@use \"@/styles/mixins\" as *;\n\n// .uiOptionRow\n.treeRow {\n\tdisplay: flex;\n\talign-items: stretch;\n\tborder-radius: var(--radius-sm);\n\tcursor: pointer;\n\n\t&:focus {\n\t\t@include focusVisible;\n\n\t\tbackground-color: var(--surface-accent);\n\t\tborder-color: var(--border-1);\n\t\tcursor: pointer;\n\t}\n\n\t&:hover {\n\t\tbackground-color: var(--surface-accent);\n\t\tcursor: pointer;\n\t}\n}\n\n// .uiOptionRowSelected\n.treeRowSelected {\n\tbackground-color: var(--surface-2);\n\tcolor: var(--content-accent);\n\tcursor: default;\n}\n\n// .uiOptionRowActive\n.treeRowActive {\n\tbackground-color: var(--surface-1);\n}\n\n// Недоступность принадлежит option целиком; вложенный checkbox только визуализирует то же состояние.\n.treeRowDisabled {\n\tcursor: not-allowed;\n\topacity: var(--disabled-opacity);\n\n\t&:hover {\n\t\tbackground-color: transparent;\n\t\tcursor: not-allowed;\n\t}\n}\n\n.treeNodeButton {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: var(--space-xs);\n\twidth: 100%;\n\tpadding: var(--space-xs) var(--space-xs) var(--space-xs) 0;\n\tbackground: transparent;\n\ttext-align: left;\n\tborder-radius: var(--radius-sm);\n}\n\n.treePopupHeader {\n\tdisplay: grid;\n\tgap: var(--space-sm);\n}\n\n.treeColumns {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(var(--tree-column-count, 1), minmax(0, 1fr));\n\tgrid-template-rows: repeat(var(--tree-row-count, 1), minmax(var(--control-height), auto));\n\tcolumn-gap: var(--space-sm);\n\talign-content: start;\n\twidth: 100%;\n\tmin-width: 0;\n}\n\n.treeColumnRow {\n\tmin-width: 0;\n\tgrid-column-start: var(--tree-option-column);\n\tgrid-row-start: var(--tree-option-row);\n}\n\n// В columns внешний floating maxHeight уже учитывает доступную сторону и safe area.\n.treeColumnsPopupLayout {\n\tmax-height: none;\n}\n\n// Label и code усиливаются отдельно: code имеет собственный variable-font weight.\n.treeColumnRootLabel {\n\tfont-weight: 600;\n\tfont-variation-settings: \"wght\" 600;\n}\n\n.treeColumnRootCode {\n\tfont-weight: 600;\n\tfont-variation-settings: \"wght\" 600;\n}\n\n.treeColumnCheckBox {\n\tdisplay: inline-flex;\n\tflex-shrink: 0;\n}\n\n// Даёт общему option-content реальную сжимаемую ширину внутри колонки и включает ellipsis вместо выхода за границы.\n.treeNodeOptionContent {\n\tflex: 1 1 0;\n\tmin-width: 0;\n\theight: 100%;\n}\n\n.treeIndent {\n\tflex-shrink: 0;\n\twidth: calc(var(--tree-level) * 1em);\n}\n\n.treeExpander,\n.treeExpanderPlaceholder {\n\tflex-shrink: 0;\n\twidth: 1.5em;\n\theight: 1.5em;\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.treeExpander {\n\tbackground: transparent;\n\tborder: none;\n\tborder-radius: var(--radius-sm);\n\tcolor: var(--content-2);\n\n\t&:hover {\n\t\tcolor: var(--content-0);\n\t\tbackground-color: var(--surface-0);\n\t}\n}\n\n.treeExpanderIcon {\n\ttransition: transform var(--transition-fast) ease;\n}\n\n.treeExpanderIconExpanded {\n\ttransform: rotate(90deg);\n}\n\n.treeSelection {\n\tflex-shrink: 0;\n\twidth: 1em;\n\theight: 1em;\n\tborder: var(--border);\n\tborder-radius: var(--radius-xs);\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tbackground-color: var(--surface-0);\n\tcolor: transparent;\n}\n\n.treeSelectionChecked {\n\tbackground-color: var(--status-info-text);\n\tborder-color: var(--status-info-text);\n\tcolor: var(--white);\n\n\t// outline: 1px dashed rgb(255, 100, 141);\n\t// outline-offset: -1px;\n}\n\n.treeSelectionPartial {\n\tbackground-color: var(--surface-1);\n\tborder-color: var(--status-info-text);\n\tcolor: var(--status-info-text);\n}\n\n.treeSelectionIcon {\n\twidth: 0.75rem;\n\theight: 0.75rem;\n}\n\n.treeSummary {\n\tpadding-right: calc(var(--control-height) * 2);\n}\n\n.inputWithOverlay {\n\tcolor: transparent;\n\tcaret-color: transparent;\n}\n\n.valueOverlay {\n\tposition: absolute;\n\tinset: 0 calc(var(--control-height) * 2) 0 var(--space-md);\n\tdisplay: flex;\n\talign-items: center;\n\tpointer-events: none;\n\toverflow: hidden;\n}\n\n.treeActions {\n\tposition: absolute;\n\tright: 0;\n\ttop: 0;\n\theight: 100%;\n\tdisplay: flex;\n\talign-items: center;\n}\n\n.treeClearButton {\n\tcolor: var(--status-error-text);\n}\n","import { CSSProperties } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { CheckIcon, ChevronRightIcon, MinusIcon } from \"lucide-react\";\n\nimport { CheckBox } from \"../check-box\";\nimport { SelectOptionContent } from \"../select/SelectOptionContent\";\n\nimport styles from \"./TreeSelect.module.scss\";\nimport { TreeMultiSelectOptionsLayout, TreeSelectNode } from \"./types\";\n\ntype TreeNodeContentProps = {\n\tnode: TreeSelectNode;\n\tlevel: number;\n\thighlight?: string;\n\thasChildren: boolean;\n\tisExpanded: boolean;\n\tselected: boolean;\n\tpartial: boolean;\n\tselectionMode: \"single\" | \"multi\";\n\toptionsLayout?: TreeMultiSelectOptionsLayout;\n\tonToggleExpand?: () => void;\n\tonToggleSelection?: () => void;\n};\n\nexport function TreeNodeContent({\n\tnode,\n\tlevel,\n\thighlight,\n\thasChildren,\n\tisExpanded,\n\tselected,\n\tpartial,\n\tselectionMode,\n\toptionsLayout = \"tree\",\n\tonToggleExpand,\n\tonToggleSelection\n}: TreeNodeContentProps) {\n\tconst showExpansionControl = optionsLayout === \"tree\";\n\tconst emphasizeRootContent = optionsLayout === \"columns\" && level === 0;\n\n\treturn (\n\t\t<>\n\t\t\t<span className={styles.treeIndent} style={{ \"--tree-level\": level } as CSSProperties} aria-hidden=\"true\" />\n\t\t\t{showExpansionControl && hasChildren ? (\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclassName={styles.treeExpander}\n\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\tonToggleExpand?.();\n\t\t\t\t\t}}\n\t\t\t\t\taria-label={isExpanded ? \"Свернуть ветку\" : \"Развернуть ветку\"}\n\t\t\t\t\tdata-ui=\"tree-select-expander\"\n\t\t\t\t\tdata-action={isExpanded ? \"collapse-tree-select-node\" : \"expand-tree-select-node\"}>\n\t\t\t\t\t<ChevronRightIcon className={cn(styles.treeExpanderIcon, isExpanded && styles.treeExpanderIconExpanded)} />\n\t\t\t\t</button>\n\t\t\t) : showExpansionControl ? (\n\t\t\t\t<span className={styles.treeExpanderPlaceholder} aria-hidden=\"true\" />\n\t\t\t) : null}\n\n\t\t\t{selectionMode === \"multi\" && optionsLayout === \"columns\" ? (\n\t\t\t\t<span\n\t\t\t\t\tclassName={styles.treeColumnCheckBox}\n\t\t\t\t\tonMouseDown={(event) => event.stopPropagation()}\n\t\t\t\t\tonClick={(event) => event.stopPropagation()}>\n\t\t\t\t\t<CheckBox\n\t\t\t\t\t\tvalue={selected}\n\t\t\t\t\t\tindeterminate={partial}\n\t\t\t\t\t\tdisabled={node.disabled}\n\t\t\t\t\t\taria-label={`Выбрать ${node.label}`}\n\t\t\t\t\t\tonChange={() => onToggleSelection?.()}\n\t\t\t\t\t/>\n\t\t\t\t</span>\n\t\t\t) : selectionMode === \"multi\" ? (\n\t\t\t\t<span\n\t\t\t\t\tclassName={cn(styles.treeSelection, selected && styles.treeSelectionChecked, partial && styles.treeSelectionPartial)}\n\t\t\t\t\taria-hidden=\"true\">\n\t\t\t\t\t{selected ? (\n\t\t\t\t\t\t<CheckIcon className={styles.treeSelectionIcon} />\n\t\t\t\t\t) : partial ? (\n\t\t\t\t\t\t<MinusIcon className={styles.treeSelectionIcon} />\n\t\t\t\t\t) : null}\n\t\t\t\t</span>\n\t\t\t) : null}\n\n\t\t\t<div className={styles.treeNodeOptionContent}>\n\t\t\t\t<SelectOptionContent\n\t\t\t\t\tlabel={node.label}\n\t\t\t\t\tcode={node.code}\n\t\t\t\t\thighlight={highlight}\n\t\t\t\t\tlabelClassName={emphasizeRootContent ? styles.treeColumnRootLabel : undefined}\n\t\t\t\t\tcodeClassName={emphasizeRootContent ? styles.treeColumnRootCode : undefined}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</>\n\t);\n}\n","import { type CSSProperties, ReactNode, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\n\nimport { type FloatingListboxSizeResolver } from \"@ryuzaki13/react-foundation-lib/hooks\";\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { XIcon } from \"lucide-react\";\n\nimport { InputText } from \"../input\";\nimport {\n\tPickerField,\n\tPickerPopup,\n\tPickerSelectionToolbar,\n\tPickerStatus,\n\tPickerTriggerActions,\n\tPickerTriggerInput,\n\tusePickerFloatingListbox,\n\tusePickerQuery,\n\tusePickerTriggerController\n} from \"../picker\";\nimport { UiBaseProps } from \"../types\";\nimport uiStyles from \"../ui.module.scss\";\n\nimport { buildTreeColumnsLayoutDescriptor } from \"./model/buildTreeColumnsLayoutDescriptor\";\nimport { resolveBalancedTreeColumnsLayout } from \"./model/resolveBalancedTreeColumnsLayout\";\nimport {\n\tcreateTreeNodeIndex,\n\tfilterTreeNodes,\n\tflattenVisibleTreeNodes,\n\tgetConfiguredTreeExpandedIds,\n\tgetSelectionExpandedIds,\n\tisTreeNodeSelected,\n\tTreeVisibleEntry\n} from \"./model/treeUtils\";\nimport { TreeNodeContent } from \"./TreeNodeContent\";\nimport styles from \"./TreeSelect.module.scss\";\nimport { TreeMultiSelectOptionsLayout, TreeSelectNode } from \"./types\";\n\ntype TreePickerBulkActions = {\n\tonSelectAll: () => void;\n\tonDeselectAll: () => void;\n};\n\ntype TreePickerBaseProps = Omit<UiBaseProps<never>, \"value\" | \"onChange\"> & {\n\tnodes: readonly TreeSelectNode[];\n\tselectedIds: Set<string>;\n\tpartialIds: Set<string>;\n\tselectionMode: \"single\" | \"multi\";\n\toptionsLayout?: TreeMultiSelectOptionsLayout;\n\tdefaultExpandedCodeKeys?: readonly string[];\n\topen?: boolean;\n\tonOpenChange?: (open: boolean) => void;\n\tbulkActions?: TreePickerBulkActions;\n\ttriggerMode?: \"display\" | \"search\";\n\tselectedSummary?: ReactNode;\n\tselectedSummaryText?: string;\n\tquery?: string;\n\tdefaultQuery?: string;\n\tonQuery?: (value: string) => void;\n\tonNodeActivate: (node: TreeSelectNode) => void;\n\tonClearSelection?: () => void;\n\tisLoading?: boolean;\n\terror?: string;\n};\n\nexport function TreePickerBase({\n\tlabel,\n\tdescription,\n\tdisabled,\n\tplaceholder,\n\tsize,\n\tnodes,\n\tselectedIds,\n\tpartialIds,\n\tselectionMode,\n\toptionsLayout = \"tree\",\n\tdefaultExpandedCodeKeys,\n\topen: controlledOpen,\n\tonOpenChange,\n\tbulkActions,\n\ttriggerMode = \"display\",\n\tselectedSummary,\n\tselectedSummaryText,\n\tquery,\n\tdefaultQuery,\n\tonQuery,\n\tonNodeActivate,\n\tonClearSelection,\n\tisLoading,\n\terror\n}: TreePickerBaseProps) {\n\tconst inputRef = useRef<HTMLInputElement | null>(null);\n\tconst selectAllButtonRef = useRef<HTMLButtonElement | null>(null);\n\tconst previousOpenRef = useRef(false);\n\tconst [manualExpansionById, setManualExpansionById] = useState<ReadonlyMap<string, boolean>>(() => new Map());\n\tconst resolvedTriggerMode = triggerMode === \"search\" ? (selectionMode === \"multi\" ? \"search-multi\" : \"search-single\") : \"display\";\n\tconst treeIndex = useMemo(() => createTreeNodeIndex(nodes), [nodes]);\n\tconst defaultExpandedCodeKeySet = useMemo(() => new Set(defaultExpandedCodeKeys), [defaultExpandedCodeKeys]);\n\tconst { query: currentQuery, setQuery } = usePickerQuery({\n\t\topen: true,\n\t\tquery,\n\t\tdefaultQuery,\n\t\tonQuery,\n\t\ttriggerMode: \"display\"\n\t});\n\tconst { nodes: filteredNodes, expandedIds: searchExpandedIds } = useMemo(\n\t\t() => filterTreeNodes(nodes, currentQuery),\n\t\t[nodes, currentQuery]\n\t);\n\tconst selectedExpandedIds = useMemo(() => getSelectionExpandedIds(selectedIds, treeIndex), [selectedIds, treeIndex]);\n\tconst configuredExpandedIds = useMemo(\n\t\t() => getConfiguredTreeExpandedIds(treeIndex, defaultExpandedCodeKeySet, manualExpansionById),\n\t\t[defaultExpandedCodeKeySet, manualExpansionById, treeIndex]\n\t);\n\tconst allExpandedIds = useMemo(\n\t\t() => new Set([...treeIndex.childrenById].filter(([, childIds]) => childIds.length > 0).map(([nodeId]) => nodeId)),\n\t\t[treeIndex]\n\t);\n\tconst resolvedExpandedIds = useMemo(\n\t\t() =>\n\t\t\toptionsLayout === \"columns\"\n\t\t\t\t? allExpandedIds\n\t\t\t\t: new Set([...configuredExpandedIds, ...searchExpandedIds, ...selectedExpandedIds]),\n\t\t[allExpandedIds, configuredExpandedIds, optionsLayout, searchExpandedIds, selectedExpandedIds]\n\t);\n\tconst visibleEntries = useMemo(() => flattenVisibleTreeNodes(filteredNodes, resolvedExpandedIds), [filteredNodes, resolvedExpandedIds]);\n\tconst selectedIndex = useMemo(() => visibleEntries.findIndex((entry) => selectedIds.has(entry.node.id)), [selectedIds, visibleEntries]);\n\tconst columnsLayoutDescriptor = useMemo(() => buildTreeColumnsLayoutDescriptor(visibleEntries), [visibleEntries]);\n\tconst resolveColumnsFloatingSize = useCallback<FloatingListboxSizeResolver>(\n\t\t(context) => {\n\t\t\tconst layout = resolveBalancedTreeColumnsLayout({\n\t\t\t\t...context,\n\t\t\t\tdescriptor: columnsLayoutDescriptor\n\t\t\t});\n\t\t\tconst placementProperties: { [customProperty: `--${string}`]: string | undefined } = {};\n\t\t\tlayout.placements.forEach((placement, index) => {\n\t\t\t\tplacementProperties[`--tree-option-${index}-column`] = String(placement.column);\n\t\t\t\tplacementProperties[`--tree-option-${index}-row`] = String(placement.row);\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\twidth: `${layout.width}px`,\n\t\t\t\tminWidth: `${layout.minWidth}px`,\n\t\t\t\tmaxWidth: `${layout.width}px`,\n\t\t\t\tmaxHeight: `${layout.maxHeight}px`,\n\t\t\t\t\"--tree-column-count\": String(layout.columnCount),\n\t\t\t\t\"--tree-row-count\": String(layout.rowCount),\n\t\t\t\t...placementProperties\n\t\t\t};\n\t\t},\n\t\t[columnsLayoutDescriptor]\n\t);\n\tconst {\n\t\topen,\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\thandleReferenceKeyDown,\n\t\thandleFloatingKeyDown,\n\t\tgetOptionId,\n\t\tgetActiveOptionId\n\t} = usePickerFloatingListbox({\n\t\toptions: visibleEntries,\n\t\tselectedIndex,\n\t\topen: controlledOpen,\n\t\tonOpenChange,\n\t\tonSelect: (entry) => onNodeActivate(entry.node),\n\t\tgetOptionDisabled: (entry) => entry.node.disabled === true,\n\t\tdisabled: disabled || isLoading,\n\t\tcloseOnSelect: selectionMode === \"single\",\n\t\tallowOpenWithoutOptions: true,\n\t\ttriggerMode: resolvedTriggerMode,\n\t\tplacementStrategy: optionsLayout === \"columns\" ? \"auto\" : \"flip\",\n\t\tresolveFloatingSize: optionsLayout === \"columns\" ? resolveColumnsFloatingSize : undefined\n\t});\n\tconst updateFloatingLayout = context.update;\n\tconst hasSelection = selectedIds.size > 0;\n\tconst showTriggerQuery = triggerMode === \"search\" && (open || currentQuery.length > 0);\n\tconst triggerValue = showTriggerQuery ? currentQuery : (selectedSummaryText ?? \"\");\n\tconst showSummaryOverlay = triggerMode === \"display\" && Boolean(selectedSummary);\n\tconst showSummaryToken = resolvedTriggerMode === \"search-multi\" && Boolean(selectedSummary);\n\tconst showTriggerPlaceholder =\n\t\t(resolvedTriggerMode === \"search-multi\" && !hasSelection) ||\n\t\t(resolvedTriggerMode === \"search-single\" && (!selectedSummaryText || showTriggerQuery)) ||\n\t\t(resolvedTriggerMode === \"display\" && !hasSelection);\n\tconst triggerController = usePickerTriggerController({\n\t\tmode: resolvedTriggerMode,\n\t\topen,\n\t\tcurrentQuery,\n\t\thasDisplayValue: Boolean(selectedSummaryText),\n\t\tinputRef,\n\t\tsetQuery,\n\t\topenList,\n\t\tclose,\n\t\ttoggleOpen\n\t});\n\tconst showBulkActions = optionsLayout === \"columns\" && selectionMode === \"multi\" && bulkActions;\n\tconst showPopupSearch = triggerMode === \"display\";\n\tconst popupHeader =\n\t\tshowBulkActions || showPopupSearch ? (\n\t\t\t<div className={styles.treePopupHeader}>\n\t\t\t\t{showBulkActions ? (\n\t\t\t\t\t<PickerSelectionToolbar\n\t\t\t\t\t\tonSelectAll={bulkActions.onSelectAll}\n\t\t\t\t\t\tonDeselectAll={bulkActions.onDeselectAll}\n\t\t\t\t\t\tselectAllButtonRef={selectAllButtonRef}\n\t\t\t\t\t/>\n\t\t\t\t) : null}\n\t\t\t\t{showPopupSearch ? (\n\t\t\t\t\t<InputText\n\t\t\t\t\t\tvalue={currentQuery}\n\t\t\t\t\t\tonChange={setQuery}\n\t\t\t\t\t\tonClear={() => setQuery(\"\")}\n\t\t\t\t\t\tplaceholder=\"Поиск по дереву\"\n\t\t\t\t\t\tonKeyDown={(event) => {\n\t\t\t\t\t\t\tif (event.key !== \"Escape\" && event.key !== \"Tab\") {\n\t\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t) : null}\n\t\t\t</div>\n\t\t) : undefined;\n\n\tuseEffect(() => {\n\t\tif (previousOpenRef.current && !open && triggerController.policy.resetQueryOnClose) {\n\t\t\tsetQuery(\"\");\n\t\t}\n\n\t\tpreviousOpenRef.current = open;\n\t}, [open, setQuery, triggerController.policy.resetQueryOnClose]);\n\n\tuseLayoutEffect(() => {\n\t\tif (open && optionsLayout === \"columns\") {\n\t\t\tupdateFloatingLayout();\n\t\t}\n\t}, [columnsLayoutDescriptor.signature, open, optionsLayout, updateFloatingLayout]);\n\n\tconst setInputNode = (node: HTMLInputElement | null) => {\n\t\tinputRef.current = node;\n\t};\n\tconst handleClearSelection = () => {\n\t\tonClearSelection?.();\n\t\tsetQuery(\"\");\n\n\t\tif (selectionMode === \"single\") {\n\t\t\tclose();\n\t\t}\n\t};\n\n\tconst toggleExpand = (entry: TreeVisibleEntry) => {\n\t\tif (!entry.hasChildren) {\n\t\t\treturn;\n\t\t}\n\n\t\tsetManualExpansionById((currentExpansionById) => {\n\t\t\tconst nextExpansionById = new Map(currentExpansionById);\n\t\t\tconst isConfiguredExpanded = currentExpansionById.get(entry.node.id) ?? defaultExpandedCodeKeySet.has(entry.node.codeKey);\n\n\t\t\tnextExpansionById.set(entry.node.id, !isConfiguredExpanded);\n\n\t\t\treturn nextExpansionById;\n\t\t});\n\t};\n\n\treturn (\n\t\t<PickerField label={label} description={description} disabled={disabled} placeholder={placeholder} size={size}>\n\t\t\t{({ controlId, labelId, describedBy }) => {\n\t\t\t\tconst listId = `${controlId}-listbox`;\n\t\t\t\tconst popupAriaLabel = typeof label === \"string\" ? label : placeholder;\n\n\t\t\t\treturn (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<PickerTriggerInput\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\trole=\"combobox\"\n\t\t\t\t\t\t\tautoComplete=\"off\"\n\t\t\t\t\t\t\tdisabled={disabled || isLoading}\n\t\t\t\t\t\t\treadOnly={triggerMode !== \"search\"}\n\t\t\t\t\t\t\tvalue={triggerMode === \"display\" && showSummaryOverlay ? \"\" : triggerValue}\n\t\t\t\t\t\t\tplaceholder={showTriggerPlaceholder ? placeholder : undefined}\n\t\t\t\t\t\t\taria-labelledby={labelId}\n\t\t\t\t\t\t\taria-label={labelId ? undefined : placeholder}\n\t\t\t\t\t\t\taria-describedby={describedBy}\n\t\t\t\t\t\t\taria-haspopup={optionsLayout === \"columns\" ? \"dialog\" : \"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={optionsLayout !== \"columns\" && triggerMode === \"search\" ? \"list\" : \"none\"}\n\t\t\t\t\t\t\taria-activedescendant={\n\t\t\t\t\t\t\t\toptionsLayout !== \"columns\" && open && visibleEntries.length > 0 ? getActiveOptionId(listId) : undefined\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tinputClassName={cn(hasSelection && styles.treeSummary, showSummaryOverlay && styles.inputWithOverlay)}\n\t\t\t\t\t\t\toverlay={showSummaryOverlay ? <div className={styles.valueOverlay}>{selectedSummary}</div> : undefined}\n\t\t\t\t\t\t\tendAdornment={\n\t\t\t\t\t\t\t\t<PickerTriggerActions\n\t\t\t\t\t\t\t\t\topen={open}\n\t\t\t\t\t\t\t\t\tdisabled={disabled || isLoading}\n\t\t\t\t\t\t\t\t\tonToggleMouseDown={triggerController.handleToggleMouseDown}\n\t\t\t\t\t\t\t\t\tonToggleClick={triggerController.handleToggleClick}>\n\t\t\t\t\t\t\t\t\t{showSummaryToken ? selectedSummary : null}\n\n\t\t\t\t\t\t\t\t\t{hasSelection && onClearSelection ? (\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclassName={styles.treeClearButton}\n\t\t\t\t\t\t\t\t\t\t\tonMouseDown={(event) => {\n\t\t\t\t\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t\t\t\t\t\t\thandleClearSelection();\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\taria-label=\"Очистить выбор\">\n\t\t\t\t\t\t\t\t\t\t\t<XIcon />\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t</PickerTriggerActions>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\t\tif (triggerMode !== \"search\") {\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\tif (\n\t\t\t\t\t\t\t\t\toptionsLayout === \"columns\" &&\n\t\t\t\t\t\t\t\t\topen &&\n\t\t\t\t\t\t\t\t\tevent.key === \"Tab\" &&\n\t\t\t\t\t\t\t\t\t!event.shiftKey &&\n\t\t\t\t\t\t\t\t\tselectAllButtonRef.current\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\t\tselectAllButtonRef.current.focus();\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\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: () => {\n\t\t\t\t\t\t\t\t\t\tconst activeEntry = activeIndex >= 0 ? visibleEntries[activeIndex] : undefined;\n\t\t\t\t\t\t\t\t\t\tif (activeEntry) {\n\t\t\t\t\t\t\t\t\t\t\tselectOption(activeEntry);\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\tenableSpaceActivation: triggerMode === \"display\"\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\tpopupAriaLabel={popupAriaLabel}\n\t\t\t\t\t\t\tdescriptionId={describedBy}\n\t\t\t\t\t\t\tactiveOptionId={\n\t\t\t\t\t\t\t\toptionsLayout !== \"columns\" && visibleEntries.length > 0 ? getActiveOptionId(listId) : undefined\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tariaMultiselectable={optionsLayout !== \"columns\" && selectionMode === \"multi\"}\n\t\t\t\t\t\t\tpopupRole={optionsLayout === \"columns\" ? \"dialog\" : \"listbox\"}\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={uiStyles.uiPopupOptions}\n\t\t\t\t\t\t\tlayoutClassName={optionsLayout === \"columns\" ? styles.treeColumnsPopupLayout : undefined}\n\t\t\t\t\t\t\tbodyClassName=\"scrollable\"\n\t\t\t\t\t\t\theader={popupHeader}>\n\t\t\t\t\t\t\t<div className={cn(optionsLayout === \"columns\" && styles.treeColumns)}>\n\t\t\t\t\t\t\t\t{visibleEntries.length === 0 ? (\n\t\t\t\t\t\t\t\t\t<PickerStatus\n\t\t\t\t\t\t\t\t\t\terrorState={error}\n\t\t\t\t\t\t\t\t\t\tloadingState={isLoading ? \"Загрузка...\" : undefined}\n\t\t\t\t\t\t\t\t\t\temptyState={!error && !isLoading ? \"Нет данных\" : undefined}\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\tvisibleEntries.map((entry, index) => {\n\t\t\t\t\t\t\t\t\t\tconst selected =\n\t\t\t\t\t\t\t\t\t\t\tselectionMode === \"multi\"\n\t\t\t\t\t\t\t\t\t\t\t\t? isTreeNodeSelected(entry.node.id, selectedIds, treeIndex)\n\t\t\t\t\t\t\t\t\t\t\t\t: selectedIds.has(entry.node.id);\n\t\t\t\t\t\t\t\t\t\tconst partial = selectionMode === \"multi\" && !selected && partialIds.has(entry.node.id);\n\t\t\t\t\t\t\t\t\t\tconst active = index === activeIndex;\n\t\t\t\t\t\t\t\t\t\tconst optionDisabled = entry.node.disabled === true;\n\n\t\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\t\tkey={entry.node.id}\n\t\t\t\t\t\t\t\t\t\t\t\tdata-ui=\"tree-select-option\"\n\t\t\t\t\t\t\t\t\t\t\t\tid={getOptionId(listId, index)}\n\t\t\t\t\t\t\t\t\t\t\t\tref={(node) => setOptionRef(index, node)}\n\t\t\t\t\t\t\t\t\t\t\t\trole={optionsLayout === \"columns\" ? undefined : \"option\"}\n\t\t\t\t\t\t\t\t\t\t\t\taria-selected={optionsLayout === \"columns\" ? undefined : selected}\n\t\t\t\t\t\t\t\t\t\t\t\taria-disabled={optionDisabled || undefined}\n\t\t\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\t\t\tstyles.treeRow,\n\t\t\t\t\t\t\t\t\t\t\t\t\toptionsLayout === \"columns\" && styles.treeColumnRow,\n\t\t\t\t\t\t\t\t\t\t\t\t\toptionDisabled && styles.treeRowDisabled,\n\t\t\t\t\t\t\t\t\t\t\t\t\tactive && styles.treeRowActive,\n\t\t\t\t\t\t\t\t\t\t\t\t\tselected && styles.treeRowSelected\n\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\tstyle={\n\t\t\t\t\t\t\t\t\t\t\t\t\toptionsLayout === \"columns\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t? ({\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"--tree-option-column\": `var(--tree-option-${index}-column, auto)`,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"--tree-option-row\": `var(--tree-option-${index}-row, auto)`\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t} as CSSProperties)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\tonMouseDown={(event) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\tonClick={() => selectOption(entry)}>\n\t\t\t\t\t\t\t\t\t\t\t\t<div className={styles.treeNodeButton}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<TreeNodeContent\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tnode={entry.node}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tlevel={entry.level}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\thighlight={currentQuery}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\thasChildren={entry.hasChildren}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tisExpanded={entry.isExpanded}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tselected={selected}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tpartial={partial}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tselectionMode={selectionMode}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\toptionsLayout={optionsLayout}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tonToggleExpand={() => toggleExpand(entry)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tonToggleSelection={() => selectOption(entry)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t/>\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</div>\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)}\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 { useMemo, useState } from \"react\";\n\nimport { MultiSelectToken } from \"../multi-select\";\nimport { usePickerSelectionLifecycle } from \"../picker\";\nimport { UiBaseProps } from \"../types\";\n\nimport {\n\tcreateTreeNodeIndex,\n\tgetSelectableTreeNodeIds,\n\tgetTreeNodeSelectionState,\n\ttoggleTreeMultiSelection,\n\ttreeMultiValueToSelectedIds,\n\ttreeSelectedIdsToMultiValue\n} from \"./model/treeUtils\";\nimport { TreePickerBase } from \"./TreePickerBase\";\nimport { TreeMultiSelectOptionsLayout, TreeMultiSelectValue, TreeSelectNode } from \"./types\";\n\nexport interface TreeMultiSelectProps extends Omit<UiBaseProps<TreeMultiSelectValue>, \"placeholder\"> {\n\tnodes: readonly TreeSelectNode[];\n\tplaceholder?: string;\n\tquery?: string;\n\tdefaultQuery?: string;\n\tonQuery?: (value: string) => void;\n\tisLoading?: boolean;\n\terror?: string;\n\t/** Определяет обычное раскрываемое дерево или полностью открытый адаптивный набор колонок. */\n\toptionsLayout?: TreeMultiSelectOptionsLayout;\n\t/**\n\t * Ключи уровней, узлы которых раскрываются до ручного действия пользователя.\n\t * В режиме `columns` дерево по-прежнему отображается полностью раскрытым.\n\t */\n\tdefaultExpandedCodeKeys?: readonly string[];\n}\n\nfunction formatTreeMultiSummary(selectedIds: Set<string>, treeIndex: ReturnType<typeof createTreeNodeIndex>) {\n\tif (selectedIds.size === 0) {\n\t\treturn undefined;\n\t}\n\n\tif (selectedIds.size === 1) {\n\t\tconst selectedNode = treeIndex.nodeById.get([...selectedIds][0]);\n\n\t\tif (!selectedNode) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn selectedNode.label;\n\t}\n\n\treturn `${selectedIds.size} элементов`;\n}\n\n/**\n * Сравнивает семантический выбор по каноническим id дерева. Порядок ключей и\n * значений во внешнем Record не должен приводить к лишнему commit при закрытии.\n */\nfunction areTreeMultiSelectionsEqual(\n\tleft: TreeMultiSelectValue,\n\tright: TreeMultiSelectValue,\n\ttreeIndex: ReturnType<typeof createTreeNodeIndex>\n) {\n\tconst leftIds = treeMultiValueToSelectedIds(left, treeIndex);\n\tconst rightIds = treeMultiValueToSelectedIds(right, treeIndex);\n\n\treturn leftIds.size === rightIds.size && [...leftIds].every((nodeId) => rightIds.has(nodeId));\n}\n\nexport function TreeMultiSelect({\n\tlabel,\n\tdescription,\n\tdisabled,\n\tplaceholder = \"Выберите значения\",\n\tsize,\n\tnodes,\n\tvalue,\n\tonChange,\n\tquery,\n\tdefaultQuery,\n\tonQuery,\n\tisLoading,\n\terror,\n\toptionsLayout = \"tree\",\n\tdefaultExpandedCodeKeys\n}: TreeMultiSelectProps) {\n\tconst [open, setOpen] = useState(false);\n\tconst treeIndex = useMemo(() => createTreeNodeIndex(nodes), [nodes]);\n\tconst { draftValue, setDraftValue, prepareOpen } = usePickerSelectionLifecycle({\n\t\tvalue,\n\t\topen,\n\t\tonCommit: onChange,\n\t\tisEqual: (left, right) => areTreeMultiSelectionsEqual(left, right, treeIndex)\n\t});\n\tconst currentValue = open ? draftValue : value;\n\tconst selectedIds = useMemo(() => treeMultiValueToSelectedIds(currentValue, treeIndex), [currentValue, treeIndex]);\n\tconst selectionState = useMemo(() => getTreeNodeSelectionState(selectedIds, treeIndex), [selectedIds, treeIndex]);\n\tconst selectedSummary = useMemo(() => formatTreeMultiSummary(selectedIds, treeIndex), [selectedIds, treeIndex]);\n\tconst handleOpenChange = (nextOpen: boolean) => {\n\t\tif (nextOpen && !open) {\n\t\t\tprepareOpen();\n\t\t}\n\n\t\tsetOpen(nextOpen);\n\t};\n\tconst selectAll = () => {\n\t\tsetDraftValue(treeSelectedIdsToMultiValue(getSelectableTreeNodeIds(treeIndex), treeIndex));\n\t};\n\tconst clearSelection = () => {\n\t\tsetDraftValue({});\n\n\t\tif (!open) {\n\t\t\tonChange({});\n\t\t}\n\t};\n\n\treturn (\n\t\t<TreePickerBase\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\tdisabled={disabled}\n\t\t\tplaceholder={placeholder}\n\t\t\tsize={size}\n\t\t\tnodes={nodes}\n\t\t\tselectedIds={selectionState.selectedIds}\n\t\t\tpartialIds={selectionState.partialIds}\n\t\t\tselectionMode=\"multi\"\n\t\t\toptionsLayout={optionsLayout}\n\t\t\tdefaultExpandedCodeKeys={defaultExpandedCodeKeys}\n\t\t\topen={open}\n\t\t\tonOpenChange={handleOpenChange}\n\t\t\tbulkActions={{\n\t\t\t\tonSelectAll: selectAll,\n\t\t\t\tonDeselectAll: () => setDraftValue({})\n\t\t\t}}\n\t\t\ttriggerMode=\"search\"\n\t\t\tselectedSummary={selectedSummary ? <MultiSelectToken value={selectedSummary} /> : undefined}\n\t\t\tquery={query}\n\t\t\tdefaultQuery={defaultQuery}\n\t\t\tonQuery={onQuery}\n\t\t\tonNodeActivate={(node) => {\n\t\t\t\tsetDraftValue((currentDraftValue) => toggleTreeMultiSelection(currentDraftValue, node.id, treeIndex));\n\t\t\t}}\n\t\t\tonClearSelection={clearSelection}\n\t\t\tisLoading={isLoading}\n\t\t\terror={error}\n\t\t/>\n\t);\n}\n","import { ODataDependentBaseProps } from \"@ryuzaki13/react-foundation-api/odata\";\n\nimport { UiBaseProps } from \"../types\";\n\nimport { useODataTreeData } from \"./model/useODataTreeData\";\nimport { TreeMultiSelect } from \"./TreeMultiSelect\";\nimport { TreeMultiSelectOptionsLayout, TreeMultiSelectValue } from \"./types\";\n\nexport interface ODataTreeMultiSelectProps\n\textends Omit<ODataDependentBaseProps, \"model\" | \"value\" | \"dependencies\">, Omit<UiBaseProps<TreeMultiSelectValue>, \"placeholder\"> {\n\tmodel?: ODataDependentBaseProps[\"model\"];\n\tplaceholder?: string;\n\tquery?: string;\n\tdefaultQuery?: string;\n\tonQuery?: (value: string) => void;\n\t/** Переключает способ показа загруженного OData-дерева, не меняя формат value и запросов. */\n\toptionsLayout?: TreeMultiSelectOptionsLayout;\n\t/**\n\t * Ключи OData-уровней, раскрываемых после появления загруженных узлов.\n\t * В режиме `columns` дерево по-прежнему отображается полностью раскрытым.\n\t */\n\tdefaultExpandedCodeKeys?: readonly string[];\n}\n\nexport function ODataTreeMultiSelect({\n\tlabel,\n\tdescription,\n\tdisabled,\n\tsize,\n\tplaceholder,\n\tquery,\n\tdefaultQuery,\n\tonQuery,\n\toptionsLayout,\n\tvalue,\n\tonChange,\n\todata,\n\tsegments,\n\tmodel,\n\tdefaultExpandedCodeKeys\n}: ODataTreeMultiSelectProps) {\n\tconst treeData = useODataTreeData({\n\t\todata,\n\t\tsegments,\n\t\tmodel\n\t});\n\n\treturn (\n\t\t<TreeMultiSelect\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\tdisabled={disabled || treeData.isLoading}\n\t\t\tsize={size}\n\t\t\tplaceholder={placeholder ?? treeData.placeholder}\n\t\t\tnodes={treeData.nodes}\n\t\t\tvalue={value}\n\t\t\tonChange={onChange}\n\t\t\tquery={query}\n\t\t\tdefaultQuery={defaultQuery}\n\t\t\tonQuery={onQuery}\n\t\t\toptionsLayout={optionsLayout}\n\t\t\tdefaultExpandedCodeKeys={defaultExpandedCodeKeys}\n\t\t\tisLoading={treeData.isLoading}\n\t\t\terror={treeData.isError ? \"Ошибка загрузки\" : undefined}\n\t\t/>\n\t);\n}\n","import { useMemo } from \"react\";\n\nimport { UiBaseProps } from \"../types\";\n\nimport { createTreeNodeIndex, treeSelectValueToId } from \"./model/treeUtils\";\nimport { TreePickerBase } from \"./TreePickerBase\";\nimport { TreeSelectNode, TreeSelectValue } from \"./types\";\n\nexport interface TreeSelectProps extends Omit<UiBaseProps<TreeSelectValue | undefined>, \"placeholder\"> {\n\tnodes: readonly TreeSelectNode[];\n\tplaceholder?: string;\n\tquery?: string;\n\tdefaultQuery?: string;\n\tonQuery?: (value: string) => void;\n\tisLoading?: boolean;\n\terror?: string;\n\tclearable?: boolean;\n\t/**\n\t * Ключи уровней, узлы которых раскрываются до ручного действия пользователя.\n\t * Значения сопоставляются с `TreeSelectNode.codeKey`.\n\t */\n\tdefaultExpandedCodeKeys?: readonly string[];\n}\n\nfunction formatTreeNodeSummary(node: TreeSelectNode | undefined) {\n\tif (!node) {\n\t\treturn undefined;\n\t}\n\n\tif (node.code && node.code !== node.label) {\n\t\treturn `${node.label} · ${node.code}`;\n\t}\n\n\treturn node.label;\n}\n\nexport function TreeSelect({\n\tlabel,\n\tdescription,\n\tdisabled,\n\tplaceholder = \"Выберите значение\",\n\tsize,\n\tnodes,\n\tvalue,\n\tonChange,\n\tquery,\n\tdefaultQuery,\n\tonQuery,\n\tisLoading,\n\terror,\n\tclearable = false,\n\tdefaultExpandedCodeKeys\n}: TreeSelectProps) {\n\tconst treeIndex = useMemo(() => createTreeNodeIndex(nodes), [nodes]);\n\tconst selectedId = treeSelectValueToId(value, treeIndex);\n\tconst selectedNode = selectedId ? treeIndex.nodeById.get(selectedId) : undefined;\n\n\treturn (\n\t\t<TreePickerBase\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\tdisabled={disabled}\n\t\t\tplaceholder={placeholder}\n\t\t\tsize={size}\n\t\t\tnodes={nodes}\n\t\t\tselectedIds={selectedId ? new Set([selectedId]) : new Set()}\n\t\t\tpartialIds={new Set()}\n\t\t\tselectionMode=\"single\"\n\t\t\tdefaultExpandedCodeKeys={defaultExpandedCodeKeys}\n\t\t\ttriggerMode=\"search\"\n\t\t\tselectedSummaryText={formatTreeNodeSummary(selectedNode)}\n\t\t\tquery={query}\n\t\t\tdefaultQuery={defaultQuery}\n\t\t\tonQuery={onQuery}\n\t\t\tonNodeActivate={(node) => onChange({ codeKey: node.codeKey, value: node.value })}\n\t\t\tonClearSelection={clearable ? () => onChange(undefined) : undefined}\n\t\t\tisLoading={isLoading}\n\t\t\terror={error}\n\t\t/>\n\t);\n}\n","import { ODataDependentBaseProps } from \"@ryuzaki13/react-foundation-api/odata\";\n\nimport { UiBaseProps } from \"../types\";\n\nimport { useODataTreeData } from \"./model/useODataTreeData\";\nimport { TreeSelect } from \"./TreeSelect\";\nimport { TreeSelectValue } from \"./types\";\n\nexport interface ODataTreeSelectProps\n\textends\n\t\tOmit<ODataDependentBaseProps, \"model\" | \"value\" | \"dependencies\">,\n\t\tOmit<UiBaseProps<TreeSelectValue | undefined>, \"placeholder\"> {\n\tmodel?: ODataDependentBaseProps[\"model\"];\n\tplaceholder?: string;\n\tquery?: string;\n\tdefaultQuery?: string;\n\tonQuery?: (value: string) => void;\n\tclearable?: boolean;\n\t/**\n\t * Ключи OData-уровней, раскрываемых после появления загруженных узлов.\n\t * Настройка влияет только на представление и не изменяет OData-запросы.\n\t */\n\tdefaultExpandedCodeKeys?: readonly string[];\n}\n\nexport function ODataTreeSelect({\n\tlabel,\n\tdescription,\n\tdisabled,\n\tsize,\n\tplaceholder,\n\tquery,\n\tdefaultQuery,\n\tonQuery,\n\tvalue,\n\tonChange,\n\todata,\n\tsegments,\n\tmodel,\n\tclearable,\n\tdefaultExpandedCodeKeys\n}: ODataTreeSelectProps) {\n\tconst treeData = useODataTreeData({\n\t\todata,\n\t\tsegments,\n\t\tmodel\n\t});\n\n\treturn (\n\t\t<TreeSelect\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\tdisabled={disabled || treeData.isLoading}\n\t\t\tsize={size}\n\t\t\tplaceholder={placeholder ?? treeData.placeholder}\n\t\t\tnodes={treeData.nodes}\n\t\t\tvalue={value}\n\t\t\tonChange={onChange}\n\t\t\tquery={query}\n\t\t\tdefaultQuery={defaultQuery}\n\t\t\tonQuery={onQuery}\n\t\t\tdefaultExpandedCodeKeys={defaultExpandedCodeKeys}\n\t\t\tisLoading={treeData.isLoading}\n\t\t\terror={treeData.isError ? \"Ошибка загрузки\" : undefined}\n\t\t\tclearable={clearable}\n\t\t/>\n\t);\n}\n"],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ export type TreeColumnsLayoutEntryDescriptor = {
2
+ level: number;
3
+ };
4
+ /** Границы одной root-группы в исходном DOM preorder. */
5
+ export type TreeColumnsRootGroupDescriptor = {
6
+ startIndex: number;
7
+ endIndexExclusive: number;
8
+ protectedPrefixEndIndexExclusive?: number;
9
+ };
10
+ /** Структурный вход columns-resolver и стабильная сигнатура для Floating UI. */
11
+ export type TreeColumnsLayoutDescriptor = {
12
+ itemCount: number;
13
+ groups: readonly TreeColumnsRootGroupDescriptor[];
14
+ signature: string;
15
+ };
16
+ /**
17
+ * Описывает root-группы видимой части дерева, не меняя исходный preorder.
18
+ *
19
+ * Защищённый prefix создаётся только для root с более чем двумя прямыми
20
+ * видимыми children. Его граница включает строку второго direct child, поэтому
21
+ * вложенные descendants первого child не ошибочно считаются вторым child.
22
+ */
23
+ export declare function buildTreeColumnsLayoutDescriptor(entries: readonly TreeColumnsLayoutEntryDescriptor[]): TreeColumnsLayoutDescriptor;
24
+ //# sourceMappingURL=buildTreeColumnsLayoutDescriptor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildTreeColumnsLayoutDescriptor.d.ts","sourceRoot":"","sources":["../../../src/tree-select/model/buildTreeColumnsLayoutDescriptor.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gCAAgC,GAAG;IAC9C,KAAK,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,yDAAyD;AACzD,MAAM,MAAM,8BAA8B,GAAG;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gCAAgC,CAAC,EAAE,MAAM,CAAC;CAC1C,CAAC;AAEF,gFAAgF;AAChF,MAAM,MAAM,2BAA2B,GAAG;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,8BAA8B,EAAE,CAAC;IAClD,SAAS,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAAC,OAAO,EAAE,SAAS,gCAAgC,EAAE,GAAG,2BAA2B,CAqClI"}
@@ -1,5 +1,6 @@
1
+ import type { TreeColumnsLayoutDescriptor } from "./buildTreeColumnsLayoutDescriptor";
1
2
  export type BalancedTreeColumnsLayoutInput = {
2
- itemCount: number;
3
+ descriptor: TreeColumnsLayoutDescriptor;
3
4
  availableWidth: number;
4
5
  availableHeight: number;
5
6
  viewportWidth: number;
@@ -12,11 +13,32 @@ export type BalancedTreeColumnsLayout = {
12
13
  width: number;
13
14
  minWidth: number;
14
15
  maxHeight: number;
16
+ placements: readonly TreeColumnPlacement[];
15
17
  };
18
+ /** Явная 1-based CSS-grid координата строки с неизменным option index. */
19
+ export type TreeColumnPlacement = {
20
+ column: number;
21
+ row: number;
22
+ };
23
+ /** Результат одной симуляции packing для заданной логической высоты колонки. */
24
+ export type ResolvedTreeColumnsPlacements = {
25
+ placements: TreeColumnPlacement[];
26
+ usedColumnCount: number;
27
+ intentionalGapCount: number;
28
+ };
29
+ /**
30
+ * Симулирует CSS-grid packing и сохраняет DOM preorder через явные координаты.
31
+ *
32
+ * Намеренный перенос оставляет хвост предыдущей колонки пустым: последующие
33
+ * группы не заполняют gap, поэтому визуальная последовательность не расходится
34
+ * с option indexes, refs и keyboard navigation.
35
+ */
36
+ export declare function resolveTreeColumnsPlacements(descriptor: TreeColumnsLayoutDescriptor, rowCount: number): ResolvedTreeColumnsPlacements;
16
37
  /**
17
38
  * Выбирает количество колонок по фактически доступной Floating UI геометрии.
18
- * Оценка одновременно штрафует переполнение, вытянутую форму и пустые ячейки,
19
- * поэтому popup стремится к компактной средней пропорции, но не выходит за viewport.
39
+ * Для каждого candidate сначала выполняется group-aware packing. Если защитные
40
+ * переносы создали лишнюю колонку, высота логической колонки увеличивается до
41
+ * тех пор, пока placements не попадут в объявленный template grid.
20
42
  */
21
- export declare function resolveBalancedTreeColumnsLayout({ itemCount, availableWidth, availableHeight, viewportWidth, viewportHeight, referenceWidth }: BalancedTreeColumnsLayoutInput): BalancedTreeColumnsLayout;
43
+ export declare function resolveBalancedTreeColumnsLayout({ descriptor, availableWidth, availableHeight, viewportWidth, viewportHeight, referenceWidth }: BalancedTreeColumnsLayoutInput): BalancedTreeColumnsLayout;
22
44
  //# sourceMappingURL=resolveBalancedTreeColumnsLayout.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolveBalancedTreeColumnsLayout.d.ts","sourceRoot":"","sources":["../../../src/tree-select/model/resolveBalancedTreeColumnsLayout.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,8BAA8B,GAAG;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CAClB,CAAC;AAcF;;;;GAIG;AACH,wBAAgB,gCAAgC,CAAC,EAChD,SAAS,EACT,cAAc,EACd,eAAe,EACf,aAAa,EACb,cAAc,EACd,cAAc,EACd,EAAE,8BAA8B,GAAG,yBAAyB,CA6C5D"}
1
+ {"version":3,"file":"resolveBalancedTreeColumnsLayout.d.ts","sourceRoot":"","sources":["../../../src/tree-select/model/resolveBalancedTreeColumnsLayout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAkC,MAAM,oCAAoC,CAAC;AAEtH,MAAM,MAAM,8BAA8B,GAAG;IAC5C,UAAU,EAAE,2BAA2B,CAAC;IACxC,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,SAAS,mBAAmB,EAAE,CAAC;CAC3C,CAAC;AAEF,0EAA0E;AAC1E,MAAM,MAAM,mBAAmB,GAAG;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACZ,CAAC;AAcF,gFAAgF;AAChF,MAAM,MAAM,6BAA6B,GAAG;IAC3C,UAAU,EAAE,mBAAmB,EAAE,CAAC;IAClC,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;CAC5B,CAAC;AAmBF;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,2BAA2B,EAAE,QAAQ,EAAE,MAAM,GAAG,6BAA6B,CAiCrI;AAED;;;;;GAKG;AACH,wBAAgB,gCAAgC,CAAC,EAChD,UAAU,EACV,cAAc,EACd,eAAe,EACf,aAAa,EACb,cAAc,EACd,cAAc,EACd,EAAE,8BAA8B,GAAG,yBAAyB,CA0E5D"}
@@ -35,6 +35,14 @@ export declare function getTreeNodeSelectionState(selectedIds: Set<string>, inde
35
35
  export declare function getSelectableTreeNodeIds(index: TreeNodeIndex, rootIds?: readonly string[]): Set<string>;
36
36
  export declare function toggleTreeMultiSelection(currentValue: TreeMultiSelectValue | undefined, targetNodeId: string, index: TreeNodeIndex): TreeMultiSelectValue;
37
37
  export declare function getSelectionExpandedIds(selectedIds: Set<string>, index: TreeNodeIndex): Set<string>;
38
+ /**
39
+ * Вычисляет базовое раскрытие дерева из политики уровней и ручных действий.
40
+ *
41
+ * Ручное значение хранится отдельно для каждого node id и имеет приоритет над
42
+ * default уровня. Благодаря вычислению по актуальному индексу узлы, загруженные
43
+ * асинхронно, получают настройку без синхронизации props в React state.
44
+ */
45
+ export declare function getConfiguredTreeExpandedIds(index: TreeNodeIndex, defaultExpandedCodeKeys: ReadonlySet<string>, manualExpansionById: ReadonlyMap<string, boolean>): Set<string>;
38
46
  export declare function filterTreeNodes(nodes: readonly TreeSelectNode[], query: string): {
39
47
  nodes: TreeSelectNode[];
40
48
  expandedIds: Set<string>;
@@ -1 +1 @@
1
- {"version":3,"file":"treeUtils.d.ts","sourceRoot":"","sources":["../../../src/tree-select/model/treeUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEjF,MAAM,MAAM,aAAa,GAAG;IAC3B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACtC,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC5C,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACpC,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACpC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC9B,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;CAChB,CAAC;AAMF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,GAAG,aAAa,CAkCnF;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,EAAE,KAAK,EAAE,aAAa,sBAG3F;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,oBAAoB,GAAG,SAAS,EAAE,KAAK,EAAE,aAAa,eAiBxG;AAED,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,aAAa,GAAG,oBAAoB,CAiBhH;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,GAAG,oBAAoB,CAQpG;AAoDD,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,aAAa,eA2BvF;AA2BD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAM1G;AA+BD,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,aAAa,GAAG,sBAAsB,CAWhH;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,GAAE,SAAS,MAAM,EAAkB,GAAG,GAAG,CAAC,MAAM,CAAC,CAiBtH;AAED,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,oBAAoB,GAAG,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,wBAiClI;AAWD,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,aAAa,eAQrF;AA0BD,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,EAAE,KAAK,EAAE,MAAM;;;EAmB9E;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,EAAE,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,gBAAgB,EAAE,CA8BtH"}
1
+ {"version":3,"file":"treeUtils.d.ts","sourceRoot":"","sources":["../../../src/tree-select/model/treeUtils.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ryuzaki13/react-foundation-ui",
3
- "version": "1.3.2",
3
+ "version": "1.4.0",
4
4
  "description": "Reusable React foundation UI primitives and Storybook stories.",
5
5
  "license": "MIT",
6
6
  "author": "Ryuzaki13",
@@ -1,4 +1,4 @@
1
- import{i as e}from"./preload-helper-B45gAKPr.js";import{t}from"./iframe-CMLjY6eW.js";import{E as n,a as r,d as i,f as a,l as o,m as s,n as c,p as l,r as u,u as d}from"./blocks-D3IlvJMm.js";import{t as f}from"./mdx-react-shim-DzMf9EAg.js";import{Appearances as p,Basic as m,RemovableList as h,Sizes as g,Tones as _,n as v,t as y}from"./Badge.stories-DtP9p0kq.js";function b(e){let t={code:`code`,h2:`h2`,h3:`h3`,li:`li`,p:`p`,pre:`pre`,ul:`ul`,...n(),...e.components};return(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(o,{of:y,parameters:{atomicCanvas:!0,layout:`padded`,docs:{toc:!0}}}),`
1
+ import{i as e}from"./preload-helper-B45gAKPr.js";import{t}from"./iframe-GalkF0Zs.js";import{E as n,a as r,d as i,f as a,l as o,m as s,n as c,p as l,r as u,u as d}from"./blocks-Dmj58mhm.js";import{t as f}from"./mdx-react-shim-7A_ItrB6.js";import{Appearances as p,Basic as m,RemovableList as h,Sizes as g,Tones as _,n as v,t as y}from"./Badge.stories-BS7dTFrU.js";function b(e){let t={code:`code`,h2:`h2`,h3:`h3`,li:`li`,p:`p`,pre:`pre`,ul:`ul`,...n(),...e.components};return(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(o,{of:y,parameters:{atomicCanvas:!0,layout:`padded`,docs:{toc:!0}}}),`
2
2
  `,(0,S.jsx)(l,{children:`Badge`}),`
3
3
  `,(0,S.jsx)(a,{children:`Компактная текстовая метка для статусов, категорий, фильтров и коротких служебных пометок`}),`
4
4
  `,(0,S.jsx)(t.p,{children:`Badge подходит для коротких подписей, которые должны быстро читаться и не перегружать интерфейс:`}),`
@@ -1,4 +1,4 @@
1
- import{a as e,c as t,i as n}from"./preload-helper-B45gAKPr.js";import{n as r,pn as i,s as a,t as o}from"./iframe-CMLjY6eW.js";import{a as s,i as c}from"./utils-PcgESe3m.js";import{n as l,t as u}from"./text-D19XuJeq.js";import{i as d,n as f,r as p,t as m}from"./uiClasses-CaHp0EWd.js";import{o as h}from"./Flex-15HLJkcx.js";import{t as g}from"./flex-BpqnRSxr.js";var _,v,y,b,x,S,C,w,T,E,D=n((()=>{_=`qBtmnH`,v=`p-HsHY`,y=`u9tQAE`,b=`FRScRz`,x=`W13uQO`,S=`_3IRcM9`,C=`R3ybI7`,w=`DdWAaC`,T=`_5cXBQF`,E={badge:_,passive:v,sizeXs:y,sizeSm:b,sizeMd:x,sizeLg:S,sizeXl:C,content:w,removeButton:T}}));function O({children:e,size:t=`sm`,tone:n,appearance:r,className:i,onRemove:o}){let c=n??`neutral`,u=d({tone:n,appearance:r,fallbackTone:c,fallbackAppearance:c===`neutral`?`outline`:`solid`});return(0,k.jsxs)(`div`,{className:s(E.badge,A[t],f(u.tone),m(u.appearance),!o&&E.passive,i),children:[(0,k.jsx)(l,{maxChar:25,placement:`top`,block:!0,textWrapProps:{className:E.content},children:String(e)}),o&&(0,k.jsx)(`button`,{type:`button`,onClick:o,className:E.removeButton,"aria-label":`Удалить бейдж`,"data-ui":`badge-remove-button`,"data-action":`remove-badge`,children:(0,k.jsx)(a,{})})]})}var k,A,j=n((()=>{c(),r(),u(),p(),D(),k=o(),A={xs:E.sizeXs,sm:E.sizeSm,md:E.sizeMd,lg:E.sizeLg,xl:E.sizeXl},O.__docgenInfo={description:`Компактный индикатор для статусов, категорий и коротких служебных меток.`,methods:[],displayName:`Badge`,props:{children:{required:!0,tsType:{name:`union`,raw:`string | number`,elements:[{name:`string`},{name:`number`}]},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:``,defaultValue:{value:`"sm"`,computed:!1}},tone:{required:!1,tsType:{name:`union`,raw:`"neutral" | "error" | "warning" | "success" | "info"`,elements:[{name:`literal`,value:`"neutral"`},{name:`literal`,value:`"error"`},{name:`literal`,value:`"warning"`},{name:`literal`,value:`"success"`},{name:`literal`,value:`"info"`}]},description:``},appearance:{required:!1,tsType:{name:`union`,raw:`"solid" | "outline" | "ghost" | "transparent"`,elements:[{name:`literal`,value:`"solid"`},{name:`literal`,value:`"outline"`},{name:`literal`,value:`"ghost"`},{name:`literal`,value:`"transparent"`}]},description:``},className:{required:!1,tsType:{name:`string`},description:``},onRemove:{required:!1,tsType:{name:`signature`,type:`function`,raw:`() => void`,signature:{arguments:[],return:{name:`void`}}},description:``}}}}));function M({children:e}){return(0,P.jsx)(h,{inline:!0,wrap:!0,gap:`sm`,align:`baseline`,children:N.Children.map(e,(e,t)=>(0,P.jsx)(N.Fragment,{children:e},t))})}var N,P,F=n((()=>{N=t(i(),1),g(),P=o(),M.__docgenInfo={description:"Контейнер для группы `Badge`, который выстраивает элементы в единый список с предсказуемыми отступами. Используется для компактного вывода набора меток или фильтров.",methods:[],displayName:`BadgeList`,props:{children:{required:!0,tsType:{name:`Array`,elements:[{name:`ReactElement`,elements:[{name:`union`,raw:`typeof Badge | null | undefined | false`,elements:[{name:`Badge`},{name:`null`},{name:`undefined`},{name:`literal`,value:`false`}]}],raw:`ReactElement<typeof Badge | null | undefined | false>`}],raw:`ReactElement<typeof Badge | null | undefined | false>[]`},description:``}}}})),I=e({Appearances:()=>H,Basic:()=>B,RemovableList:()=>W,Sizes:()=>U,Tones:()=>V,__namedExportsOrder:()=>G,default:()=>z}),L,R,z,B,V,H,U,W,G,K=n((()=>{L=t(i(),1),j(),F(),R=o(),z={title:`Shared/UI/Badge`,component:O,args:{children:`Новый`,size:`md`,tone:`info`,appearance:`solid`},parameters:{atomicCanvas:!0,layout:`padded`},argTypes:{children:{description:`Текст внутри бейджа.`,control:`text`},size:{description:`Размер бейджа.`,control:`inline-radio`,options:[`sm`,`md`,`lg`]},tone:{description:`Семантический тон бейджа.`,control:`inline-radio`,options:[`neutral`,`success`,`warning`,`error`,`info`]},appearance:{description:`Форма бейджа.`,control:`inline-radio`,options:[`solid`,`outline`,`ghost`,`transparent`]},onRemove:{description:`Показывает кнопку удаления и вызывает обработчик по клику.`,control:!1},className:{description:`Дополнительный CSS-класс контейнера.`,control:`text`}}},B={},V={render:()=>(0,R.jsxs)(M,{children:[(0,R.jsx)(O,{tone:`neutral`,appearance:`outline`,children:`Neutral`}),(0,R.jsx)(O,{tone:`success`,appearance:`solid`,children:`Успешно`}),(0,R.jsx)(O,{tone:`warning`,appearance:`solid`,children:`Внимание`}),(0,R.jsx)(O,{tone:`error`,appearance:`solid`,children:`Ошибка`}),(0,R.jsx)(O,{tone:`info`,appearance:`solid`,children:`Информация`})]})},H={render:()=>(0,R.jsxs)(M,{children:[(0,R.jsx)(O,{tone:`neutral`,appearance:`solid`,children:`Solid`}),(0,R.jsx)(O,{tone:`neutral`,appearance:`outline`,children:`Outline`}),(0,R.jsx)(O,{tone:`info`,appearance:`ghost`,children:`Ghost`}),(0,R.jsx)(O,{tone:`warning`,appearance:`transparent`,children:`Transparent`})]})},U={render:()=>(0,R.jsxs)(M,{children:[(0,R.jsx)(O,{size:`xs`,children:`Extra Small`}),(0,R.jsx)(O,{size:`sm`,children:`Small`}),(0,R.jsx)(O,{size:`md`,children:`Medium`}),(0,R.jsx)(O,{size:`lg`,children:`Large`}),(0,R.jsx)(O,{size:`xl`,children:`Extra Large`})]})},W={render:()=>{let[e,t]=(0,L.useState)([`Фильтр A`,`Фильтр B`,`Фильтр C`]);return(0,R.jsx)(M,{children:e.map(e=>(0,R.jsx)(O,{tone:`info`,appearance:`outline`,onRemove:()=>t(t=>t.filter(t=>t!==e)),children:e},e))})}},B.parameters={...B.parameters,docs:{...B.parameters?.docs,source:{originalSource:`{}`,...B.parameters?.docs?.source}}},V.parameters={...V.parameters,docs:{...V.parameters?.docs,source:{originalSource:`{
1
+ import{a as e,c as t,i as n}from"./preload-helper-B45gAKPr.js";import{n as r,pn as i,s as a,t as o}from"./iframe-GalkF0Zs.js";import{a as s,i as c}from"./utils-CPEyORfW.js";import{n as l,t as u}from"./text-LYJNm5Vm.js";import{i as d,n as f,r as p,t as m}from"./uiClasses-CaHp0EWd.js";import{o as h}from"./Flex-BIhVP-gi.js";import{t as g}from"./flex-DbByv7Hz.js";var _,v,y,b,x,S,C,w,T,E,D=n((()=>{_=`qBtmnH`,v=`p-HsHY`,y=`u9tQAE`,b=`FRScRz`,x=`W13uQO`,S=`_3IRcM9`,C=`R3ybI7`,w=`DdWAaC`,T=`_5cXBQF`,E={badge:_,passive:v,sizeXs:y,sizeSm:b,sizeMd:x,sizeLg:S,sizeXl:C,content:w,removeButton:T}}));function O({children:e,size:t=`sm`,tone:n,appearance:r,className:i,onRemove:o}){let c=n??`neutral`,u=d({tone:n,appearance:r,fallbackTone:c,fallbackAppearance:c===`neutral`?`outline`:`solid`});return(0,k.jsxs)(`div`,{className:s(E.badge,A[t],f(u.tone),m(u.appearance),!o&&E.passive,i),children:[(0,k.jsx)(l,{maxChar:25,placement:`top`,block:!0,textWrapProps:{className:E.content},children:String(e)}),o&&(0,k.jsx)(`button`,{type:`button`,onClick:o,className:E.removeButton,"aria-label":`Удалить бейдж`,"data-ui":`badge-remove-button`,"data-action":`remove-badge`,children:(0,k.jsx)(a,{})})]})}var k,A,j=n((()=>{c(),r(),u(),p(),D(),k=o(),A={xs:E.sizeXs,sm:E.sizeSm,md:E.sizeMd,lg:E.sizeLg,xl:E.sizeXl},O.__docgenInfo={description:`Компактный индикатор для статусов, категорий и коротких служебных меток.`,methods:[],displayName:`Badge`,props:{children:{required:!0,tsType:{name:`union`,raw:`string | number`,elements:[{name:`string`},{name:`number`}]},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:``,defaultValue:{value:`"sm"`,computed:!1}},tone:{required:!1,tsType:{name:`union`,raw:`"neutral" | "error" | "warning" | "success" | "info"`,elements:[{name:`literal`,value:`"neutral"`},{name:`literal`,value:`"error"`},{name:`literal`,value:`"warning"`},{name:`literal`,value:`"success"`},{name:`literal`,value:`"info"`}]},description:``},appearance:{required:!1,tsType:{name:`union`,raw:`"solid" | "outline" | "ghost" | "transparent"`,elements:[{name:`literal`,value:`"solid"`},{name:`literal`,value:`"outline"`},{name:`literal`,value:`"ghost"`},{name:`literal`,value:`"transparent"`}]},description:``},className:{required:!1,tsType:{name:`string`},description:``},onRemove:{required:!1,tsType:{name:`signature`,type:`function`,raw:`() => void`,signature:{arguments:[],return:{name:`void`}}},description:``}}}}));function M({children:e}){return(0,P.jsx)(h,{inline:!0,wrap:!0,gap:`sm`,align:`baseline`,children:N.Children.map(e,(e,t)=>(0,P.jsx)(N.Fragment,{children:e},t))})}var N,P,F=n((()=>{N=t(i(),1),g(),P=o(),M.__docgenInfo={description:"Контейнер для группы `Badge`, который выстраивает элементы в единый список с предсказуемыми отступами. Используется для компактного вывода набора меток или фильтров.",methods:[],displayName:`BadgeList`,props:{children:{required:!0,tsType:{name:`Array`,elements:[{name:`ReactElement`,elements:[{name:`union`,raw:`typeof Badge | null | undefined | false`,elements:[{name:`Badge`},{name:`null`},{name:`undefined`},{name:`literal`,value:`false`}]}],raw:`ReactElement<typeof Badge | null | undefined | false>`}],raw:`ReactElement<typeof Badge | null | undefined | false>[]`},description:``}}}})),I=e({Appearances:()=>H,Basic:()=>B,RemovableList:()=>W,Sizes:()=>U,Tones:()=>V,__namedExportsOrder:()=>G,default:()=>z}),L,R,z,B,V,H,U,W,G,K=n((()=>{L=t(i(),1),j(),F(),R=o(),z={title:`Shared/UI/Badge`,component:O,args:{children:`Новый`,size:`md`,tone:`info`,appearance:`solid`},parameters:{atomicCanvas:!0,layout:`padded`},argTypes:{children:{description:`Текст внутри бейджа.`,control:`text`},size:{description:`Размер бейджа.`,control:`inline-radio`,options:[`sm`,`md`,`lg`]},tone:{description:`Семантический тон бейджа.`,control:`inline-radio`,options:[`neutral`,`success`,`warning`,`error`,`info`]},appearance:{description:`Форма бейджа.`,control:`inline-radio`,options:[`solid`,`outline`,`ghost`,`transparent`]},onRemove:{description:`Показывает кнопку удаления и вызывает обработчик по клику.`,control:!1},className:{description:`Дополнительный CSS-класс контейнера.`,control:`text`}}},B={},V={render:()=>(0,R.jsxs)(M,{children:[(0,R.jsx)(O,{tone:`neutral`,appearance:`outline`,children:`Neutral`}),(0,R.jsx)(O,{tone:`success`,appearance:`solid`,children:`Успешно`}),(0,R.jsx)(O,{tone:`warning`,appearance:`solid`,children:`Внимание`}),(0,R.jsx)(O,{tone:`error`,appearance:`solid`,children:`Ошибка`}),(0,R.jsx)(O,{tone:`info`,appearance:`solid`,children:`Информация`})]})},H={render:()=>(0,R.jsxs)(M,{children:[(0,R.jsx)(O,{tone:`neutral`,appearance:`solid`,children:`Solid`}),(0,R.jsx)(O,{tone:`neutral`,appearance:`outline`,children:`Outline`}),(0,R.jsx)(O,{tone:`info`,appearance:`ghost`,children:`Ghost`}),(0,R.jsx)(O,{tone:`warning`,appearance:`transparent`,children:`Transparent`})]})},U={render:()=>(0,R.jsxs)(M,{children:[(0,R.jsx)(O,{size:`xs`,children:`Extra Small`}),(0,R.jsx)(O,{size:`sm`,children:`Small`}),(0,R.jsx)(O,{size:`md`,children:`Medium`}),(0,R.jsx)(O,{size:`lg`,children:`Large`}),(0,R.jsx)(O,{size:`xl`,children:`Extra Large`})]})},W={render:()=>{let[e,t]=(0,L.useState)([`Фильтр A`,`Фильтр B`,`Фильтр C`]);return(0,R.jsx)(M,{children:e.map(e=>(0,R.jsx)(O,{tone:`info`,appearance:`outline`,onRemove:()=>t(t=>t.filter(t=>t!==e)),children:e},e))})}},B.parameters={...B.parameters,docs:{...B.parameters?.docs,source:{originalSource:`{}`,...B.parameters?.docs?.source}}},V.parameters={...V.parameters,docs:{...V.parameters?.docs,source:{originalSource:`{
2
2
  render: () => <BadgeList>
3
3
  <Badge tone="neutral" appearance="outline">
4
4
  Neutral