@ryuzaki13/react-foundation-ui 3.1.7 → 3.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (295) hide show
  1. package/dist/chunks/{TextEditorLexicalClient-C5AV8Fcu.js → TextEditorLexicalClient-C8nSoz85.js} +321 -266
  2. package/dist/chunks/TextEditorLexicalClient-C8nSoz85.js.map +1 -0
  3. package/dist/chunks/context-menu-DgvXGCuI.js.map +1 -1
  4. package/dist/chunks/picker-lvm82d0A.js.map +1 -1
  5. package/dist/listbox/Listbox.d.ts +6 -4
  6. package/dist/listbox/Listbox.d.ts.map +1 -1
  7. package/dist/listbox/index.js +34 -33
  8. package/dist/listbox/index.js.map +1 -1
  9. package/dist/styles.css +1 -1
  10. package/dist/text-editor/LinkDialog.d.ts.map +1 -1
  11. package/dist/text-editor/SemanticDialog.d.ts.map +1 -1
  12. package/dist/text-editor/TextEditorDialogs.d.ts +7 -6
  13. package/dist/text-editor/TextEditorDialogs.d.ts.map +1 -1
  14. package/dist/text-editor/TimeDialog.d.ts +1 -6
  15. package/dist/text-editor/TimeDialog.d.ts.map +1 -1
  16. package/dist/text-editor/index.js +1 -1
  17. package/dist/text-editor/lib/selection/findSelectedInlineNode.d.ts +4 -0
  18. package/dist/text-editor/lib/selection/findSelectedInlineNode.d.ts.map +1 -0
  19. package/dist/text-editor/lib/selection/{restoreLinkDialogSelection.d.ts → restoreEditorDialogSelection.d.ts} +4 -4
  20. package/dist/text-editor/lib/selection/restoreEditorDialogSelection.d.ts.map +1 -0
  21. package/dist/text-editor/lib/semantic/getTimeDialogInitialState.d.ts +4 -0
  22. package/dist/text-editor/lib/semantic/getTimeDialogInitialState.d.ts.map +1 -0
  23. package/dist/text-editor/lib/semantic/isSemanticDateTime.d.ts +3 -0
  24. package/dist/text-editor/lib/semantic/isSemanticDateTime.d.ts.map +1 -0
  25. package/dist/text-editor/model/hooks/useTextEditorLexicalActions.d.ts +3 -2
  26. package/dist/text-editor/model/hooks/useTextEditorLexicalActions.d.ts.map +1 -1
  27. package/dist/text-editor/model/semanticDialogState.d.ts +6 -0
  28. package/dist/text-editor/model/semanticDialogState.d.ts.map +1 -0
  29. package/dist/text-editor/model/timeDialogState.d.ts +8 -0
  30. package/dist/text-editor/model/timeDialogState.d.ts.map +1 -0
  31. package/dist/text-editor/semanticTagConfigs.d.ts.map +1 -1
  32. package/package.json +1 -1
  33. package/storybook-static/assets/{Badge-CGKgoaOT.js → Badge-cD8IF21z.js} +1 -1
  34. package/storybook-static/assets/{Badge.stories-i9aNoJyv.js → Badge.stories-ChIaIP7u.js} +1 -1
  35. package/storybook-static/assets/{BadgeList-DGuIP0LP.js → BadgeList-iS-RUmI9.js} +1 -1
  36. package/storybook-static/assets/{BarcodeScannerDialog.stories-DoBmeXbI.js → BarcodeScannerDialog.stories-DlXDWqlt.js} +1 -1
  37. package/storybook-static/assets/{Button-BRUZ_IGh.js → Button-1yd7C2rC.js} +1 -1
  38. package/storybook-static/assets/{Button-DiJ6oS7B.js → Button-CwkuEJRI.js} +1 -1
  39. package/storybook-static/assets/{Button.stories-C61UJ0UZ.js → Button.stories-DRLZgAc-.js} +1 -1
  40. package/storybook-static/assets/{CalendarView-RAiUoboD.js → CalendarView-C1fvABPO.js} +1 -1
  41. package/storybook-static/assets/{CheckBox-C5a-2KKy.js → CheckBox-CXEY0VzR.js} +1 -1
  42. package/storybook-static/assets/{CheckBox-D0uqOjIv.js → CheckBox-t8TfgV3v.js} +1 -1
  43. package/storybook-static/assets/{CheckBox.stories-C0T2kCPz.js → CheckBox.stories-B6PC48ma.js} +1 -1
  44. package/storybook-static/assets/{Color-6AOWCN3U-CvYJNQrT.js → Color-6AOWCN3U-CqBazhKG.js} +1 -1
  45. package/storybook-static/assets/{ContextMenu-DqvtEW9u.js → ContextMenu-Bbsspzh9.js} +1 -1
  46. package/storybook-static/assets/ContextMenu-D3qBnj7o.css +1 -0
  47. package/storybook-static/assets/{ContextMenu-Iv5pmyEC.js → ContextMenu-ZW9_VMgy.js} +1 -1
  48. package/storybook-static/assets/{ContextMenu.stories-B5Ht0lJ2.js → ContextMenu.stories-DAwMbD95.js} +1 -1
  49. package/storybook-static/assets/{CustomOptionButton-3GcvPdc2.js → CustomOptionButton-CRPk0jjj.js} +1 -1
  50. package/storybook-static/assets/{DateInput-by2R6A6q.js → DateInput-BarPS0lf.js} +1 -1
  51. package/storybook-static/assets/{DateInput-CHcIWgKG.js → DateInput-DlIpO1bS.js} +1 -1
  52. package/storybook-static/assets/{DateInput.stories-D70t88Sg.js → DateInput.stories-CP-OSU7c.js} +1 -1
  53. package/storybook-static/assets/{DateRangePresetSelect-Dh-v2Qkl.js → DateRangePresetSelect--9PqaSO3.js} +1 -1
  54. package/storybook-static/assets/{DateRangePresetSelect-DUJN_TNv.js → DateRangePresetSelect-CQfbnvF0.js} +1 -1
  55. package/storybook-static/assets/{DateRangePresetSelect.stories-BeLMGpM0.js → DateRangePresetSelect.stories-CutX8jfo.js} +1 -1
  56. package/storybook-static/assets/{Detail-Th1wT04G.js → Detail-VdWVGH78.js} +1 -1
  57. package/storybook-static/assets/{Detail.stories-BbSMHAPR.js → Detail.stories-BwI0jxnH.js} +1 -1
  58. package/storybook-static/assets/{Dialog-DzGq_rLA.js → Dialog-7LtWvEGc.js} +1 -1
  59. package/storybook-static/assets/{Dialog-CxRQ69iW.js → Dialog-CBUnMYDs.js} +1 -1
  60. package/storybook-static/assets/{Dialog.stories-B3GuNpQj.js → Dialog.stories-st_xEXXE.js} +1 -1
  61. package/storybook-static/assets/{Disclosure-CYksrXLX.js → Disclosure-7mGo3lfl.js} +1 -1
  62. package/storybook-static/assets/{Disclosure.stories-CKcR0hTV.js → Disclosure.stories-4uNEgvwO.js} +1 -1
  63. package/storybook-static/assets/{DisclosureGroup-C5D7hPT1.js → DisclosureGroup-DzFgYXKG.js} +1 -1
  64. package/storybook-static/assets/{DocsRenderer-JROSPFPF-BWC3spk3.js → DocsRenderer-JROSPFPF-C7p5q3c5.js} +1 -1
  65. package/storybook-static/assets/{DropZone-CPNBiUzj.js → DropZone-60u06WCE.js} +1 -1
  66. package/storybook-static/assets/{DropZone-Crt0HKOd.js → DropZone-Cl9emJbX.js} +1 -1
  67. package/storybook-static/assets/{DropZone.stories-D5NyRYy2.js → DropZone.stories-Cdz1iWSH.js} +1 -1
  68. package/storybook-static/assets/{DropdownMenu-D2e_ccAs.js → DropdownMenu-Bt2bIKXK.js} +1 -1
  69. package/storybook-static/assets/{ExpandableActionPanel-BM0P1W9f.js → ExpandableActionPanel-DeGknbmm.js} +1 -1
  70. package/storybook-static/assets/{ExpandableActionPanel.stories-BFSoZUxl.js → ExpandableActionPanel.stories-CMTpWJh0.js} +1 -1
  71. package/storybook-static/assets/{Flex-QsiLUb9i.js → Flex-BrHRbW3d.js} +1 -1
  72. package/storybook-static/assets/{Flex.stories-pn6ASHJz.js → Flex.stories-DGQrIltr.js} +1 -1
  73. package/storybook-static/assets/{FloatingPopover-BtDieyRu.js → FloatingPopover-DClYkKZN.js} +1 -1
  74. package/storybook-static/assets/{FormattedTableCell-BbWhFlYw.js → FormattedTableCell-BWQ-r4_U.js} +1 -1
  75. package/storybook-static/assets/{Grid-Dm6QeLBk.js → Grid-hWhBWWmV.js} +1 -1
  76. package/storybook-static/assets/{Grid.stories-D4nnxkIL.js → Grid.stories-DsACUdaZ.js} +1 -1
  77. package/storybook-static/assets/{ImageCropper.stories-coYi48Mc.js → ImageCropper.stories-D244J3Ja.js} +1 -1
  78. package/storybook-static/assets/{ImageRenderer-B1Trwu0E.js → ImageRenderer-D7i5SCvC.js} +1 -1
  79. package/storybook-static/assets/{ImageRenderer.stories-CsOTPsZO.js → ImageRenderer.stories-B7HRNaKg.js} +1 -1
  80. package/storybook-static/assets/{ImageView.stories-wc6BsWWh.js → ImageView.stories-Dj2AVo4v.js} +1 -1
  81. package/storybook-static/assets/{ImageViewer.stories-Sy88ikfh.js → ImageViewer.stories-BJwhpVLQ.js} +2 -2
  82. package/storybook-static/assets/{ImageViewerRuntime-sy7ps8-7.js → ImageViewerRuntime-Nf6uEU-3.js} +1 -1
  83. package/storybook-static/assets/{Input-BUVF08VR.js → Input-BJurqF_e.js} +1 -1
  84. package/storybook-static/assets/{Input-CT9sLrCJ.js → Input-CDgqmNqL.js} +1 -1
  85. package/storybook-static/assets/{Input.stories-8kUFLjlM.js → Input.stories-CX69MuO9.js} +1 -1
  86. package/storybook-static/assets/{InputDateTime-2Nauz9MM.js → InputDateTime-BmrVy39q.js} +1 -1
  87. package/storybook-static/assets/{InputDateTime.stories-BMyb52Xd.js → InputDateTime.stories-CjPNjE-j.js} +1 -1
  88. package/storybook-static/assets/{InputFile-DPKTxgu5.js → InputFile-DZ5Y1tFo.js} +1 -1
  89. package/storybook-static/assets/{InputFile-DujqGE1f.js → InputFile-yoXpCuas.js} +1 -1
  90. package/storybook-static/assets/{InputFile.stories-BE6y42w-.js → InputFile.stories-BxJO8XIo.js} +1 -1
  91. package/storybook-static/assets/{InputFiles-CMKKDgOp.js → InputFiles-BcOSB6Zh.js} +1 -1
  92. package/storybook-static/assets/{InputFiles-BGDkGF82.js → InputFiles-Bl4vARDM.js} +1 -1
  93. package/storybook-static/assets/{InputFiles.stories-BXiiB_vN.js → InputFiles.stories-AnjhADoO.js} +1 -1
  94. package/storybook-static/assets/{InputFilesList-Ct4wyqhc.js → InputFilesList-C-s0YB-b.js} +1 -1
  95. package/storybook-static/assets/{InputImage-Cq0HuN_r.js → InputImage-CJ4DyeZ_.js} +1 -1
  96. package/storybook-static/assets/{InputImage-B9T9DRvO.js → InputImage-CxDisozx.js} +1 -1
  97. package/storybook-static/assets/{InputImage.stories-CxUEJeEk.js → InputImage.stories-CBZQvzsL.js} +1 -1
  98. package/storybook-static/assets/{InteractiveComponents-BTJQRW4N.js → InteractiveComponents-USZSFDKU.js} +3 -3
  99. package/storybook-static/assets/{InteractiveComponents.stories-DP2zq7AQ.js → InteractiveComponents.stories-CQKoVvHQ.js} +1 -1
  100. package/storybook-static/assets/{LayoutPicker-C0VV2U3U.js → LayoutPicker-Ckht-F4t.js} +1 -1
  101. package/storybook-static/assets/{LayoutPicker-BYaNFZ7r.js → LayoutPicker-cwChjQBK.js} +1 -1
  102. package/storybook-static/assets/{LayoutPicker.stories-BTeQtDNX.js → LayoutPicker.stories-Cfe6qz2E.js} +1 -1
  103. package/storybook-static/assets/Listbox-B1vBprsk.js +58 -0
  104. package/storybook-static/assets/Listbox-DFF7wZ2w.js +1 -0
  105. package/storybook-static/assets/Listbox.stories-CZVFAF33.js +79 -0
  106. package/storybook-static/assets/{Modal-O8LKBLnY.js → Modal--yQHPDaV.js} +1 -1
  107. package/storybook-static/assets/{Modal-BNhb1SS7.js → Modal-DdICfkeu.js} +1 -1
  108. package/storybook-static/assets/{Modal.stories-St9IEb_s.js → Modal.stories-ycR63jVk.js} +1 -1
  109. package/storybook-static/assets/{ModalManagerProvider-B2vDDcbl.js → ModalManagerProvider-CR2nRIRb.js} +1 -1
  110. package/storybook-static/assets/{MultiSelect-DCnAlvuc.js → MultiSelect-BEXzFoFl.js} +1 -1
  111. package/storybook-static/assets/{MultiSelect-Cxld2Hu4.js → MultiSelect-BWnr3sww.js} +1 -1
  112. package/storybook-static/assets/{MultiSelect.stories-DY7gdIj8.js → MultiSelect.stories-_2cvw3LS.js} +1 -1
  113. package/storybook-static/assets/{NoData-DzxXkKzF.js → NoData-iTlhsjzm.js} +1 -1
  114. package/storybook-static/assets/{NotificationsHost-BMit8cBh.js → NotificationsHost-ma6z2Npq.js} +1 -1
  115. package/storybook-static/assets/{NotificationsHost.stories-CBNjvTz8.js → NotificationsHost.stories-DCMAll2N.js} +1 -1
  116. package/storybook-static/assets/{ODataMultiSelect-BNqAqnqH.js → ODataMultiSelect-o2P5WdI0.js} +1 -1
  117. package/storybook-static/assets/{ODataMultiSelect.stories-DeNeHZqJ.js → ODataMultiSelect.stories-C7ql3uUR.js} +1 -1
  118. package/storybook-static/assets/{ODataSelect-BvZOTc8b.js → ODataSelect-BTgvHPL1.js} +1 -1
  119. package/storybook-static/assets/{ODataSelect.stories-B0Sqy2-f.js → ODataSelect.stories-k-TptXe6.js} +1 -1
  120. package/storybook-static/assets/{ODataTreeMultiSelect-Bte_2QXh.js → ODataTreeMultiSelect-BBU_XOB1.js} +1 -1
  121. package/storybook-static/assets/{ODataTreeMultiSelect.stories-CrgIg1HR.js → ODataTreeMultiSelect.stories-CK6s2kAx.js} +1 -1
  122. package/storybook-static/assets/{ODataTreeSelect-BjyH-uB-.js → ODataTreeSelect-BgksQhBW.js} +1 -1
  123. package/storybook-static/assets/{ODataTreeSelect.stories-BSIyG21o.js → ODataTreeSelect.stories-DkVBvdbz.js} +1 -1
  124. package/storybook-static/assets/{OneStepScroller-CJHeiy3o.js → OneStepScroller-CZeEIQRr.js} +1 -1
  125. package/storybook-static/assets/Option-Cgep24M5.css +1 -0
  126. package/storybook-static/assets/{Option-CK-LHNXk.js → Option-DEgrC04Q.js} +1 -1
  127. package/storybook-static/assets/{OptionButton-DPqMza2z.js → OptionButton-CMX7xMiS.js} +1 -1
  128. package/storybook-static/assets/{PeriodSelect-S5Czecu2.js → PeriodSelect-Bvb0a7VE.js} +1 -1
  129. package/storybook-static/assets/{PeriodSelect-CKHLTmIk.js → PeriodSelect-CubgTCyh.js} +1 -1
  130. package/storybook-static/assets/{PeriodSelect.stories-BOBLCzVf.js → PeriodSelect.stories-CrQMdtjt.js} +1 -1
  131. package/storybook-static/assets/{PickerField-TUtQIm63.js → PickerField-DmaPEE37.js} +1 -1
  132. package/storybook-static/assets/{PickerTriggerActions-wMALj9-p.js → PickerTriggerActions-CT-vzHLo.js} +1 -1
  133. package/storybook-static/assets/{Popover-BdclceiF.js → Popover-BaIskgCH.js} +1 -1
  134. package/storybook-static/assets/{Popover-5ne8M-Zd.js → Popover-DnS1fu-J.js} +1 -1
  135. package/storybook-static/assets/{Popover.stories-C51wGati.js → Popover.stories-Br4QG6Qc.js} +1 -1
  136. package/storybook-static/assets/{PresetRangeDateInput-B_-CDJon.js → PresetRangeDateInput-CLh8nWwI.js} +1 -1
  137. package/storybook-static/assets/{PresetRangeDateInput-BXnxuAmk.js → PresetRangeDateInput-D3ep0j14.js} +1 -1
  138. package/storybook-static/assets/{PresetRangeDateInput.stories-BUjmXD68.js → PresetRangeDateInput.stories-Drcwlbbd.js} +1 -1
  139. package/storybook-static/assets/{PresetSelect-Bd4FUHIi.js → PresetSelect-CUUBmkH9.js} +1 -1
  140. package/storybook-static/assets/{README-CjRdw4MT.js → README-B8HzVkdG.js} +1 -1
  141. package/storybook-static/assets/{README-CAIBz2Pu.js → README-BD1FjMQJ.js} +1 -1
  142. package/storybook-static/assets/{README-DaQkCBRs.js → README-BHTJnmUY.js} +1 -1
  143. package/storybook-static/assets/{README-CJFJvC1n.js → README-BOJyiN47.js} +1 -1
  144. package/storybook-static/assets/{README-qj4Gd-W-.js → README-BQmQciX_.js} +1 -1
  145. package/storybook-static/assets/{README-y_Ddsi4l.js → README-BWPNblv6.js} +1 -1
  146. package/storybook-static/assets/{README-BSVseuTL.js → README-BZTGgZ4N.js} +1 -1
  147. package/storybook-static/assets/{README-Cg_7RN5U.js → README-BavT_N0h.js} +1 -1
  148. package/storybook-static/assets/{README-mQnpOAU8.js → README-Bi0AfxuN.js} +1 -1
  149. package/storybook-static/assets/{README-DmLvQmWp.js → README-BiOiYeiW.js} +1 -1
  150. package/storybook-static/assets/{README-DS24mdf2.js → README-BmlOzcVB.js} +1 -1
  151. package/storybook-static/assets/{README-DQ__Q7Ey.js → README-BpDwioAV.js} +1 -1
  152. package/storybook-static/assets/{README-DdgLvBsx.js → README-C1Lj2Cb8.js} +1 -1
  153. package/storybook-static/assets/{README-CQhQk1LE.js → README-C8MsS4-Q.js} +1 -1
  154. package/storybook-static/assets/{README-CdJril4I.js → README-CBRGDSK3.js} +1 -1
  155. package/storybook-static/assets/{README-DRUmaTJT.js → README-CMyKIRdF.js} +1 -1
  156. package/storybook-static/assets/{README-5KE99TF2.js → README-COmJUcr2.js} +1 -1
  157. package/storybook-static/assets/{README-BwOKJQXr.js → README-CP2uvCiX.js} +1 -1
  158. package/storybook-static/assets/{README-DW4XJxBH.js → README-CYL_Hb6U.js} +1 -1
  159. package/storybook-static/assets/{README-D9XuOQkQ.js → README-C_A0E8h7.js} +1 -1
  160. package/storybook-static/assets/{README-DMLYR9xF.js → README-Ch3diYbl.js} +1 -1
  161. package/storybook-static/assets/{README-CDTtRpZD.js → README-CjhQ6nID.js} +1 -1
  162. package/storybook-static/assets/{README-OiHYHOl_.js → README-CtHazL9o.js} +1 -1
  163. package/storybook-static/assets/{README-C__cHg9V.js → README-CvfMD-yX.js} +1 -1
  164. package/storybook-static/assets/{README-e4yZUXj6.js → README-CwVWZvw8.js} +1 -1
  165. package/storybook-static/assets/{README-Cc3HEb4Y.js → README-CxEF1QRp.js} +1 -1
  166. package/storybook-static/assets/{README-CHLnNblC.js → README-CxbvEqKi.js} +1 -1
  167. package/storybook-static/assets/{README-C0Me54f2.js → README-D15ZOm6o.js} +1 -1
  168. package/storybook-static/assets/{README-rUdZkaA1.js → README-D4eR7Npj.js} +1 -1
  169. package/storybook-static/assets/{README-BkkUFzXi.js → README-D8L_x4ty.js} +1 -1
  170. package/storybook-static/assets/{README-DMHOfLH5.js → README-D97fnWM_.js} +1 -1
  171. package/storybook-static/assets/{README-C98k-qzm.js → README-DHIkbZig.js} +1 -1
  172. package/storybook-static/assets/{README-CIendGsK.js → README-DHv9Dk8f.js} +1 -1
  173. package/storybook-static/assets/{README-DRfAs-wk.js → README-DKeN0vn3.js} +1 -1
  174. package/storybook-static/assets/{README-BL0yiwEU.js → README-DPXelFLx.js} +1 -1
  175. package/storybook-static/assets/{README-BefKCPhg.js → README-DXwKVRp1.js} +1 -1
  176. package/storybook-static/assets/{README-CmXresuq.js → README-Df73Vz0K.js} +1 -1
  177. package/storybook-static/assets/{README-IGC3se8f.js → README-DjlXldzj.js} +1 -1
  178. package/storybook-static/assets/{README-DIoZ6_Nt.js → README-DodyavXM.js} +1 -1
  179. package/storybook-static/assets/{README-D48E1qmm.js → README-DvXLNKpe.js} +1 -1
  180. package/storybook-static/assets/{README-DiemVtPJ.js → README-DysSSWiq.js} +1 -1
  181. package/storybook-static/assets/{README-BiAx5NSA.js → README-LkvdY68j.js} +1 -1
  182. package/storybook-static/assets/{README-v2tTAEez.js → README-PMWTK2SF.js} +1 -1
  183. package/storybook-static/assets/{README-CIDXaDcb.js → README-QDDKQVUx.js} +1 -1
  184. package/storybook-static/assets/{README-DklY30z7.js → README-W3SkU5lE.js} +1 -1
  185. package/storybook-static/assets/{README-Cr6jZrGX.js → README-YPUYya9i.js} +1 -1
  186. package/storybook-static/assets/{README-45v65tgb.js → README-cpnfb1RN.js} +1 -1
  187. package/storybook-static/assets/{README-DUipcgoY.js → README-gU29w4X1.js} +1 -1
  188. package/storybook-static/assets/{README-CIvbWbRp.js → README-hod6n1FG.js} +1 -1
  189. package/storybook-static/assets/{README-CbrUszxE.js → README-kE-pA524.js} +1 -1
  190. package/storybook-static/assets/{README-SlTaZ2xs.js → README-ljRJAU2U.js} +1 -1
  191. package/storybook-static/assets/{README-vYsEhLrp.js → README-wQqmD8AW.js} +1 -1
  192. package/storybook-static/assets/{README-CUyldYwH.js → README-zbuaV3u5.js} +1 -1
  193. package/storybook-static/assets/{RadioButton-BDM8BzFQ.js → RadioButton-D-u-ibJw.js} +1 -1
  194. package/storybook-static/assets/{RadioButton-QuMmeBZH.js → RadioButton-Tljm-gx4.js} +1 -1
  195. package/storybook-static/assets/{RadioButton.stories-BeqREYcm.js → RadioButton.stories-DlRGtMVf.js} +1 -1
  196. package/storybook-static/assets/{RadioGroup-D8dI118U.js → RadioGroup-B6b-X1jB.js} +1 -1
  197. package/storybook-static/assets/{RadioGroup-BbbewnoI.js → RadioGroup-G7BEQbtm.js} +1 -1
  198. package/storybook-static/assets/{RadioGroup.stories-Ddq5l2jE.js → RadioGroup.stories-Bk1w4-Xc.js} +1 -1
  199. package/storybook-static/assets/{Scrollable-EZ9ebrsL.js → Scrollable-DC9i0mYW.js} +1 -1
  200. package/storybook-static/assets/{Select-CUfuYdMM.js → Select-BMqBCgE-.js} +1 -1
  201. package/storybook-static/assets/{Select-BU63Qvsd.js → Select-C0ZL6uUp.js} +1 -1
  202. package/storybook-static/assets/{Select.stories-B44LsEJc.js → Select.stories-DYE8bzE4.js} +1 -1
  203. package/storybook-static/assets/{SerializableSelect-CZezimfR.js → SerializableSelect-CG3zetyF.js} +1 -1
  204. package/storybook-static/assets/{SerializableSelect.stories-v-Cy4wXF.js → SerializableSelect.stories-DgeMGMGi.js} +1 -1
  205. package/storybook-static/assets/{SingleDateTimeInput-D8BjD3KJ.js → SingleDateTimeInput-3_6weg8k.js} +1 -1
  206. package/storybook-static/assets/{SingleDateTimeInput-DQsZg3ir.js → SingleDateTimeInput-BXmFvQF5.js} +1 -1
  207. package/storybook-static/assets/{SingleDateTimeInput.stories-BoAa-w6A.js → SingleDateTimeInput.stories-CHUnjUDG.js} +1 -1
  208. package/storybook-static/assets/{Slider-BsZcj3de.js → Slider-B8XknFoe.js} +1 -1
  209. package/storybook-static/assets/{Slider-CzVEaZ28.js → Slider-w2yJesB6.js} +1 -1
  210. package/storybook-static/assets/{Slider.stories-rCGq72D5.js → Slider.stories-DVw84J73.js} +1 -1
  211. package/storybook-static/assets/{SliderInput-BA25fKid.js → SliderInput-DSb0AuKk.js} +1 -1
  212. package/storybook-static/assets/{SliderInput-ByuiRYq-.js → SliderInput-dwZvklce.js} +1 -1
  213. package/storybook-static/assets/{SliderInput.stories-C9YMDv4u.js → SliderInput.stories-Bdpb0dFy.js} +1 -1
  214. package/storybook-static/assets/{Sortable-wc6ia9-O.js → Sortable-B2jRK-hs.js} +1 -1
  215. package/storybook-static/assets/{Sortable.stories-Ck4ldBYa.js → Sortable.stories-CPhyZP7A.js} +1 -1
  216. package/storybook-static/assets/{Splitter-CYpgvy19.js → Splitter-Du6xLn8R.js} +1 -1
  217. package/storybook-static/assets/{Splitter.stories-B946w9ZI.js → Splitter.stories-DGTZFFwx.js} +1 -1
  218. package/storybook-static/assets/{StateSelect-Ci3jE-ct.js → StateSelect-BG-UO5Eq.js} +1 -1
  219. package/storybook-static/assets/{StateSelect-BN5YEuPs.js → StateSelect-BOajtdq4.js} +1 -1
  220. package/storybook-static/assets/{StateSelect.stories-CNhTn2Cz.js → StateSelect.stories-DVb_qjCW.js} +1 -1
  221. package/storybook-static/assets/{StatusIndicator-BuMfqi1u.js → StatusIndicator-BYljJe48.js} +1 -1
  222. package/storybook-static/assets/{StatusIndicator.stories-DzxeAwiN.js → StatusIndicator.stories-DgCsuevz.js} +1 -1
  223. package/storybook-static/assets/{StringToggle.stories-Deadq_Ls.js → StringToggle.stories-D9Mgl79r.js} +1 -1
  224. package/storybook-static/assets/{Switch-BFYG_WKE.js → Switch-9_3tdZzh.js} +1 -1
  225. package/storybook-static/assets/{Switch-YwxYXJTM.js → Switch-UIcoDT_b.js} +1 -1
  226. package/storybook-static/assets/{Switch.stories-NJITAhqS.js → Switch.stories-DCblrg7K.js} +1 -1
  227. package/storybook-static/assets/{Table-DbNz25Cw.js → Table-DI5AmKzC.js} +1 -1
  228. package/storybook-static/assets/{Table.stories-C_D5lF-r.js → Table.stories-DtueWbab.js} +1 -1
  229. package/storybook-static/assets/{TableEditor.stories-DY8bnNmE.js → TableEditor.stories-C32GrFqZ.js} +1 -1
  230. package/storybook-static/assets/{Tabs-CyUUot0Z.js → Tabs-BkvkkxZi.js} +1 -1
  231. package/storybook-static/assets/{Tabs.stories-DVP5hAtb.js → Tabs.stories-CW3_6cyY.js} +1 -1
  232. package/storybook-static/assets/{TabsBox-Cr256gqh.js → TabsBox-BFt4jD0B.js} +1 -1
  233. package/storybook-static/assets/{TagInput-8u-Uqj6U.js → TagInput-Aic7iZ-y.js} +1 -1
  234. package/storybook-static/assets/{TagInput.stories-DkGtiXYT.js → TagInput.stories-DsWVUSFJ.js} +1 -1
  235. package/storybook-static/assets/{Text-DNniRzyg.js → Text-STwJhH5H.js} +1 -1
  236. package/storybook-static/assets/{Textarea-B35HiX_5.js → Textarea-Ba8vhwfR.js} +1 -1
  237. package/storybook-static/assets/{Textarea-Des9OzN2.js → Textarea-CKeoq23U.js} +1 -1
  238. package/storybook-static/assets/{Textarea.stories-DjZpaa7v.js → Textarea.stories-DoDIGoDg.js} +1 -1
  239. package/storybook-static/assets/{TimePanel-Bn7j0COY.js → TimePanel-BD90gNq1.js} +1 -1
  240. package/storybook-static/assets/{TimePanel.stories-DyE2b3rT.js → TimePanel.stories-tLwJv68U.js} +1 -1
  241. package/storybook-static/assets/{Toggle-BwMUAyJ1.js → Toggle-BpjhNO96.js} +1 -1
  242. package/storybook-static/assets/{Toggle-DEZVxAUT.js → Toggle-wagPPfpy.js} +1 -1
  243. package/storybook-static/assets/{Toggle.stories-CSA1M-Rk.js → Toggle.stories-4pCCaAds.js} +1 -1
  244. package/storybook-static/assets/{TreeMultiSelect-BkdyhB5h.js → TreeMultiSelect-D2Qt0ZIh.js} +1 -1
  245. package/storybook-static/assets/{TreeMultiSelect-DVU4eyct.js → TreeMultiSelect-gBLLncde.js} +1 -1
  246. package/storybook-static/assets/{TreeMultiSelect.stories-DNXLQ6AI.js → TreeMultiSelect.stories-DzBHH5CW.js} +1 -1
  247. package/storybook-static/assets/{TreePickerBase-BdcMGcih.js → TreePickerBase-BY4Cg0fo.js} +1 -1
  248. package/storybook-static/assets/{TreeSelect-Db0euK3o.js → TreeSelect-CXs1Avbe.js} +1 -1
  249. package/storybook-static/assets/{TreeSelect-6ppKxxsm.js → TreeSelect-DRrws6n7.js} +1 -1
  250. package/storybook-static/assets/{TreeSelect.stories-CSyuSzu3.js → TreeSelect.stories-BNQnsynu.js} +1 -1
  251. package/storybook-static/assets/{TreeTable-BoHkmEek.js → TreeTable-hw_ZOGUo.js} +1 -1
  252. package/storybook-static/assets/{TreeTable.stories-CyIiIbvQ.js → TreeTable.stories-D70Gx8ye.js} +1 -1
  253. package/storybook-static/assets/{blocks-CwQtiknB.js → blocks-D3JUer2A.js} +3 -3
  254. package/storybook-static/assets/{check-yyiWhN4R.js → check-B8rUpKkH.js} +1 -1
  255. package/storybook-static/assets/{chevron-down-D4IkLqEW.js → chevron-down-walqi17H.js} +1 -1
  256. package/storybook-static/assets/{chevron-left-UNLm4Da9.js → chevron-left-gEnQEyKV.js} +1 -1
  257. package/storybook-static/assets/{chevron-right-B5GJn-EI.js → chevron-right-C35Q9_r0.js} +1 -1
  258. package/storybook-static/assets/{chunk-W22LQPXL-B41qNp-A.js → chunk-W22LQPXL-C5YiQcXT.js} +1 -1
  259. package/storybook-static/assets/{circle-alert-Brsq6PwN.js → circle-alert-s_ZiUdvd.js} +1 -1
  260. package/storybook-static/assets/{circle-check-fqVfpv7F.js → circle-check-Dr2TRkga.js} +1 -1
  261. package/storybook-static/assets/{components-J99iJoYh.js → components-mKwy5UuZ.js} +3 -3
  262. package/storybook-static/assets/{contextMenu-BX57n-PU.js → contextMenu-DIXTPy8N.js} +1 -1
  263. package/storybook-static/assets/{download-lJE1ywiU.js → download-DcsgqgZ3.js} +1 -1
  264. package/storybook-static/assets/{floating-ui.react-C-VmYdHj.js → floating-ui.react-CR3rb6W2.js} +1 -1
  265. package/storybook-static/assets/{foundationApi-BqI9blJ6.js → foundationApi-CyNTkkgT.js} +1 -1
  266. package/storybook-static/assets/{foundationLib-p2ar8jpg.js → foundationLib-zU0-QZoU.js} +1 -1
  267. package/storybook-static/assets/{hooks-DiCw5pD1.js → hooks-BXSlITjA.js} +1 -1
  268. package/storybook-static/assets/{iframe-TCiPQfyU.js → iframe-C7Kz5KQm.js} +3 -3
  269. package/storybook-static/assets/iframe-qGC25hE8.js +1 -0
  270. package/storybook-static/assets/{info-CFEXTNzF.js → info-BrejI783.js} +1 -1
  271. package/storybook-static/assets/{odata-D489EHOE.js → odata-BvqDWAke.js} +1 -1
  272. package/storybook-static/assets/{odataStoryFixtures-CafTJzup.js → odataStoryFixtures-DxjRFmdK.js} +1 -1
  273. package/storybook-static/assets/{react-amiS04cs.js → react-BYMcHP_H.js} +1 -1
  274. package/storybook-static/assets/{refresh-cw-Czxt9fW4.js → refresh-cw-C1HJCbfI.js} +1 -1
  275. package/storybook-static/assets/{settings-2-4HvlFCuc.js → settings-2-vVR3d5fZ.js} +1 -1
  276. package/storybook-static/assets/{sortable-6vA6sgYr.js → sortable-DqiufSwe.js} +1 -1
  277. package/storybook-static/assets/{syntaxhighlighter-QEQV7K2Y-DZZSX2Qc.js → syntaxhighlighter-QEQV7K2Y-Cbm6Hwpi.js} +1 -1
  278. package/storybook-static/assets/{trash-2-Dn-ATsbs.js → trash-2-DlwVSewJ.js} +1 -1
  279. package/storybook-static/assets/{triangle-alert-uQuwfpAB.js → triangle-alert-B6O7hGwO.js} +1 -1
  280. package/storybook-static/assets/{useODataSelectBase-DSz_GEHP.js → useODataSelectBase-Bb3WCZUa.js} +1 -1
  281. package/storybook-static/assets/{useODataTreeData-BSjVKhMe.js → useODataTreeData-CTmvDRCK.js} +1 -1
  282. package/storybook-static/assets/{usePickerQuery-ivq6xAU-.js → usePickerQuery-CYbInhrJ.js} +1 -1
  283. package/storybook-static/assets/{usePickerTriggerController-C3jPyuwu.js → usePickerTriggerController-B6yHzM_q.js} +1 -1
  284. package/storybook-static/assets/{x-CEk3emXH.js → x-BmgkqY7j.js} +1 -1
  285. package/storybook-static/iframe.html +2 -2
  286. package/storybook-static/index.json +1 -1
  287. package/storybook-static/project.json +1 -1
  288. package/dist/chunks/TextEditorLexicalClient-C5AV8Fcu.js.map +0 -1
  289. package/dist/text-editor/lib/selection/restoreLinkDialogSelection.d.ts.map +0 -1
  290. package/storybook-static/assets/ContextMenu-yhWq2uJ3.css +0 -1
  291. package/storybook-static/assets/Listbox-Ccn3QRv2.js +0 -53
  292. package/storybook-static/assets/Listbox-DmN74-p1.js +0 -1
  293. package/storybook-static/assets/Listbox.stories-D-uh5Nn_.js +0 -68
  294. package/storybook-static/assets/Option-DD2t6DLq.css +0 -1
  295. package/storybook-static/assets/iframe-Cpjz8S9A.js +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"picker-lvm82d0A.js","names":[],"sources":["../../src/picker/PickerField.tsx","../../src/picker/PickerClearButton.tsx","../../src/picker/Picker.module.scss","../../src/picker/PickerSelectionToolbar.tsx","../../src/picker/PickerOptions.tsx","../../src/picker/model/extractPickerTextContent.ts","../../src/picker/PickerPlaceholder.ts","../../src/picker/PickerPopup.tsx","../../src/picker/PickerSelectedToken.tsx","../../src/picker/PickerStatus.tsx","../../src/picker/PickerTriggerActions.tsx","../../src/picker/PickerTriggerInput.tsx","../../src/picker/PickerTrigger.tsx","../../src/picker/model/createPickerTriggerPolicy.ts","../../src/picker/model/usePickerDefaultFilter.ts","../../src/picker/model/usePickerFloatingListbox.ts","../../src/picker/model/usePickerQuery.ts","../../src/picker/model/usePickerSelectionLifecycle.ts","../../src/picker/model/usePickerTriggerController.ts"],"sourcesContent":["import { InputType } from \"@ryuzaki13/react-foundation-lib/types\";\n\nimport { InputUI } from \"../input\";\nimport { useInputFieldIds } from \"../input/lib/useInputFieldIds\";\n\nimport { PickerFieldProps } from \"./types\";\n\nexport function PickerField<TValue extends InputType>({\n\tid,\n\tlabel,\n\tdescription,\n\tdisabled,\n\tsize,\n\tclassName,\n\terror,\n\tchildren\n}: PickerFieldProps<TValue>) {\n\tconst { controlId, labelId, descriptionId, errorId, describedBy } = useInputFieldIds({\n\t\tid,\n\t\thasLabel: label !== undefined && label !== null,\n\t\thasDescription: !!description,\n\t\thasError: !!error\n\t});\n\n\treturn (\n\t\t<InputUI\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\tdisabled={disabled}\n\t\t\tsize={size}\n\t\t\tclassName={className}\n\t\t\terror={error}\n\t\t\tcontrolId={controlId}\n\t\t\tlabelId={labelId}\n\t\t\tdescriptionId={descriptionId}\n\t\t\terrorId={errorId}>\n\t\t\t{children({ controlId, labelId, descriptionId, errorId, describedBy })}\n\t\t</InputUI>\n\t);\n}\n","import { type MouseEvent } from \"react\";\n\nimport { XIcon } from \"lucide-react\";\n\nimport uiStyles from \"../ui.module.scss\";\n\ntype PickerClearButtonProps = {\n\tdisabled?: boolean;\n\tariaLabel?: string;\n\tonClear: () => void;\n};\n\n/** Единое действие очистки выбранного значения во всех clearable picker-компонентах. */\nexport function PickerClearButton({ disabled, ariaLabel = \"Очистить выбор\", onClear }: PickerClearButtonProps) {\n\tconst stopTriggerInteraction = (event: MouseEvent<HTMLButtonElement>) => {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t};\n\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdisabled={disabled}\n\t\t\tclassName={uiStyles.uiClearButton}\n\t\t\tdata-ui=\"picker-clear-button\"\n\t\t\tdata-action=\"clear-picker\"\n\t\t\tonMouseDown={stopTriggerInteraction}\n\t\t\tonClick={(event) => {\n\t\t\t\tstopTriggerInteraction(event);\n\t\t\t\tonClear();\n\t\t\t}}\n\t\t\taria-label={ariaLabel}>\n\t\t\t<XIcon />\n\t\t</button>\n\t);\n}\n","@use \"@/styles/mixins\" as *;\n\n.popupPositioner,\n.options {\n\toverflow: hidden;\n\tdisplay: grid;\n\tgrid-template-rows: minmax(0, 1fr);\n\tborder-radius: var(--radius-sm);\n}\n\n.popupPositioner {\n\t--anchor-gap: var(--space-xs);\n\t--anchor-padding: var(--space-xs);\n\t--anchor-offset: 0;\n\n\tmin-width: 0;\n\tz-index: var(--z-dropdown);\n\tbox-shadow: var(--shadow-md);\n}\n\n.options {\n\t--input-width: min(100vw, var(--base-width, 15em));\n\n\twidth: 100%;\n\tmin-width: var(--input-width);\n\tmin-height: 0;\n\tmax-height: 75vh;\n\n\tpadding: var(--space-sm);\n\tbackground-color: var(--surface-0);\n\tborder: var(--border);\n\n\t&:empty {\n\t\tvisibility: hidden;\n\t}\n\n\t&[data-has-toolbar=\"true\"] {\n\t\tgrid-template-rows: auto minmax(0, 1fr);\n\t}\n}\n\n.optionsToolbar {\n\tdisplay: grid;\n\tgap: var(--space-xs);\n\tpadding: var(--space-xs);\n}\n\n.optionsBody {\n\tmin-height: 0;\n}\n\n.status {\n\tpadding: var(--space-xs) var(--space-sm);\n\tcolor: var(--content-2);\n}\n\n.statusError {\n\tcolor: var(--error-text);\n}\n\n.triggerContainer {\n\tposition: relative;\n\n\t&[data-has-overlay=\"true\"] input {\n\t\t--ui-color: transparent;\n\t\t--ui-color-hover: transparent;\n\t\t--ui-color-active: transparent;\n\n\t\tcolor: transparent;\n\t\tcaret-color: transparent;\n\t\t-webkit-text-fill-color: transparent;\n\t}\n}\n\n.triggerHasClear {\n\t--trigger-count: 2;\n\t// Резервирует в input место для кнопок очистки и открытия списка.\n\t--input-end-adornment-width: calc(var(--control-height) * 2);\n}\n\n.selectedToken {\n\tposition: absolute;\n\tinset: 0 calc(var(--control-height) * var(--trigger-count, 1) + var(--space-sm)) 0 var(--space-sm);\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: flex-end;\n\tmin-width: 0;\n\tpointer-events: none;\n}\n\n.selectedTokenText {\n\toverflow: hidden;\n\twhite-space: nowrap;\n\ttext-overflow: ellipsis;\n}\n\n@include mobile {\n\t.options {\n\t\t--input-width: calc(100dvw - var(--space-xl));\n\t}\n}\n\n.selectionActionButton {\n\tpadding-block: var(--space-xs);\n\tborder-radius: var(--radius-sm);\n\n\t&:hover {\n\t\tbackground-color: var(--surface-2);\n\t}\n}\n","import { type Ref } from \"react\";\n\nimport { Grid } from \"../grid\";\n\nimport styles from \"./Picker.module.scss\";\n\ntype PickerSelectionToolbarProps = {\n\tonSelectAll: () => void;\n\tonDeselectAll: () => void;\n\tselectAllButtonRef?: Ref<HTMLButtonElement>;\n};\n\n/**\n * Общая панель массовых действий для picker-компонентов с множественным выбором.\n * Компонент не знает формат значения и делегирует изменение владельцу selection-модели.\n */\nexport function PickerSelectionToolbar({ onSelectAll, onDeselectAll, selectAllButtonRef }: PickerSelectionToolbarProps) {\n\treturn (\n\t\t<Grid.Container gap=\"xs\" templateColumns=\"1fr 1fr\">\n\t\t\t<button\n\t\t\t\tref={selectAllButtonRef}\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName={styles.selectionActionButton}\n\t\t\t\tonClick={onSelectAll}\n\t\t\t\tdata-ui=\"picker-select-all\"\n\t\t\t\tdata-action=\"select-all\">\n\t\t\t\tВыбрать все\n\t\t\t</button>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName={styles.selectionActionButton}\n\t\t\t\tonClick={onDeselectAll}\n\t\t\t\tdata-ui=\"picker-deselect-all\"\n\t\t\t\tdata-action=\"deselect-all\">\n\t\t\t\tСнять выбор\n\t\t\t</button>\n\t\t</Grid.Container>\n\t);\n}\n","import { type HTMLAttributes, type ReactNode, type Ref } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { Separator } from \"../separator\";\n\nimport styles from \"./Picker.module.scss\";\nimport { PickerSelectionToolbar } from \"./PickerSelectionToolbar\";\n\nexport type PickerSelectionActions = {\n\tonSelectAll: () => void;\n\tonDeselectAll: () => void;\n\tselectAllButtonRef?: Ref<HTMLButtonElement>;\n};\n\nexport interface PickerOptionsProps extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n\trootRef?: Ref<HTMLDivElement>;\n\tchildren: ReactNode;\n\ttoolbar?: ReactNode | false;\n\tselectionActions?: PickerSelectionActions;\n\tlayoutClassName?: string;\n\tbodyClassName?: string;\n\tscrollable?: boolean;\n}\n\n/**\n * Единая оболочка списка опций для picker, listbox и menu. Если переданы\n * selectionActions, но не передан toolbar, компонент показывает стандартные\n * действия выбора и снятия выбора.\n */\nexport function PickerOptions({\n\trootRef,\n\tchildren,\n\ttoolbar,\n\tselectionActions,\n\tlayoutClassName,\n\tbodyClassName,\n\tscrollable = true,\n\tclassName,\n\t...props\n}: PickerOptionsProps) {\n\tconst resolvedToolbar = toolbar === undefined && selectionActions ? <PickerSelectionToolbar {...selectionActions} /> : toolbar || null;\n\n\treturn (\n\t\t<div\n\t\t\t{...props}\n\t\t\tref={rootRef}\n\t\t\tclassName={cn(styles.options, layoutClassName, className)}\n\t\t\tdata-ui=\"picker-options\"\n\t\t\tdata-has-toolbar={resolvedToolbar ? \"true\" : undefined}>\n\t\t\t{resolvedToolbar ? (\n\t\t\t\t<div className={styles.optionsToolbar}>\n\t\t\t\t\t{resolvedToolbar}\n\t\t\t\t\t<Separator />\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t<div className={cn(styles.optionsBody, scrollable ? \"scrollable overscroll\" : \"overflowHidden\", bodyClassName)}>{children}</div>\n\t\t</div>\n\t);\n}\n","import { isValidElement, type ReactNode } from \"react\";\n\nexport function extractPickerTextContent(node: ReactNode): string | undefined {\n\tif (typeof node === \"string\" || typeof node === \"number\") {\n\t\treturn String(node);\n\t}\n\n\tif (Array.isArray(node)) {\n\t\tconst values = node\n\t\t\t.map(extractPickerTextContent)\n\t\t\t.filter((value): value is string => Boolean(value))\n\t\t\t.map((value) => value.trim())\n\t\t\t.filter(Boolean);\n\t\treturn values.length ? values.join(\" \") : undefined;\n\t}\n\n\tif (isValidElement<{ children?: ReactNode; searchText?: unknown }>(node)) {\n\t\tif (typeof node.props.searchText === \"string\") {\n\t\t\treturn node.props.searchText;\n\t\t}\n\n\t\treturn extractPickerTextContent(node.props.children);\n\t}\n\n\treturn undefined;\n}\n","import { type ReactNode } from \"react\";\n\nimport { extractPickerTextContent } from \"./model/extractPickerTextContent\";\n\ntype PickerPlaceholderParams = {\n\tplaceholder?: string;\n\tlabel?: ReactNode;\n\toptionCount: number;\n\tfallback?: string;\n};\n\n/**\n * Формирует единый текст placeholder для picker-компонентов и всегда показывает\n * актуальное количество доступных вариантов.\n */\nexport function getPickerPlaceholder({ placeholder, label, optionCount, fallback = \"Выберите значение\" }: PickerPlaceholderParams) {\n\tconst labelText = extractPickerTextContent(label);\n\tconst text = placeholder ?? labelText ?? fallback;\n\n\treturn `${text} <${optionCount}>`;\n}\n","import { type CSSProperties, type KeyboardEvent, type MouseEvent, type ReactNode } from \"react\";\n\nimport { FloatingContext, FloatingFocusManager, FloatingPortal } from \"@floating-ui/react\";\nimport { AnimatePresence, motion } from \"motion/react\";\n\nimport styles from \"./Picker.module.scss\";\nimport { PickerOptions, type PickerSelectionActions } from \"./PickerOptions\";\n\ninterface PickerPopupProps {\n\topen: boolean;\n\tcontext: FloatingContext;\n\tfloatingStyles: CSSProperties;\n\tlistId: string;\n\tlabelId?: string;\n\tpopupAriaLabel?: string;\n\tdescriptionId?: string;\n\tactiveOptionId?: string;\n\tariaMultiselectable?: boolean;\n\tpopupRole?: \"listbox\" | \"dialog\";\n\tsetFloating: (node: HTMLElement | null) => void;\n\tgetFloatingProps: (userProps?: Record<string, unknown>) => Record<string, unknown>;\n\tonKeyDown: (event: KeyboardEvent<HTMLElement>) => void;\n\tinitialFocus?: number;\n\treturnFocus?: boolean;\n\ttabIndex?: number;\n\tclassName?: string;\n\tmaxWidth?: CSSProperties[\"maxWidth\"];\n\tlayoutClassName?: string;\n\tbodyClassName?: string;\n\ttoolbar?: ReactNode | false;\n\tselectionActions?: PickerSelectionActions;\n\tchildren: ReactNode;\n}\n\nfunction stopNestedFloatingMouseDown(event: MouseEvent<HTMLElement>): void {\n\tevent.stopPropagation();\n}\n\nexport function PickerPopup({\n\topen,\n\tcontext,\n\tfloatingStyles,\n\tlistId,\n\tlabelId,\n\tpopupAriaLabel,\n\tdescriptionId,\n\tactiveOptionId,\n\tariaMultiselectable,\n\tpopupRole = \"listbox\",\n\tsetFloating,\n\tgetFloatingProps,\n\tonKeyDown,\n\tinitialFocus = -1,\n\treturnFocus = false,\n\ttabIndex = 0,\n\tclassName,\n\tmaxWidth,\n\tlayoutClassName,\n\tbodyClassName,\n\ttoolbar,\n\tselectionActions,\n\tchildren\n}: PickerPopupProps) {\n\treturn (\n\t\t<AnimatePresence>\n\t\t\t{open && (\n\t\t\t\t<FloatingPortal>\n\t\t\t\t\t<FloatingFocusManager context={context} modal={false} initialFocus={initialFocus} returnFocus={returnFocus}>\n\t\t\t\t\t\t<motion.div\n\t\t\t\t\t\t\tref={setFloating}\n\t\t\t\t\t\t\tstyle={{ ...floatingStyles, maxWidth }}\n\t\t\t\t\t\t\tinitial={{ opacity: 0, scale: 0.95 }}\n\t\t\t\t\t\t\tanimate={{ opacity: 1, scale: 1 }}\n\t\t\t\t\t\t\texit={{ opacity: 0, scale: 0.95 }}\n\t\t\t\t\t\t\t{...getFloatingProps({\n\t\t\t\t\t\t\t\tid: listId,\n\t\t\t\t\t\t\t\trole: popupRole,\n\t\t\t\t\t\t\t\ttabIndex,\n\t\t\t\t\t\t\t\t\"aria-labelledby\": labelId,\n\t\t\t\t\t\t\t\t\"aria-label\": labelId ? undefined : popupAriaLabel,\n\t\t\t\t\t\t\t\t\"aria-describedby\": descriptionId,\n\t\t\t\t\t\t\t\t\"aria-activedescendant\": activeOptionId,\n\t\t\t\t\t\t\t\t\"aria-multiselectable\": ariaMultiselectable || undefined,\n\t\t\t\t\t\t\t\tonMouseDown: stopNestedFloatingMouseDown,\n\t\t\t\t\t\t\t\tonKeyDown,\n\t\t\t\t\t\t\t\tclassName: styles.popupPositioner\n\t\t\t\t\t\t\t})}>\n\t\t\t\t\t\t\t<PickerOptions\n\t\t\t\t\t\t\t\tclassName={className}\n\t\t\t\t\t\t\t\tlayoutClassName={layoutClassName}\n\t\t\t\t\t\t\t\tbodyClassName={bodyClassName}\n\t\t\t\t\t\t\t\ttoolbar={toolbar}\n\t\t\t\t\t\t\t\tselectionActions={selectionActions}\n\t\t\t\t\t\t\t\tscrollable={false}>\n\t\t\t\t\t\t\t\t{children}\n\t\t\t\t\t\t\t</PickerOptions>\n\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t</FloatingFocusManager>\n\t\t\t\t</FloatingPortal>\n\t\t\t)}\n\t\t</AnimatePresence>\n\t);\n}\n","import { type HTMLAttributes, type ReactNode } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport styles from \"./Picker.module.scss\";\n\nexport interface PickerSelectedTokenProps extends Omit<HTMLAttributes<HTMLSpanElement>, \"children\"> {\n\tchildren: ReactNode;\n}\n\n/** Единое визуальное представление выбранного значения внутри picker-trigger. */\nexport function PickerSelectedToken({ children, className, ...props }: PickerSelectedTokenProps) {\n\treturn (\n\t\t<span {...props} className={cn(styles.selectedToken, className)} data-ui=\"picker-selected-token\">\n\t\t\t<span className={styles.selectedTokenText}>{children}</span>\n\t\t</span>\n\t);\n}\n","import { ReactNode } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport uiStyles from \"../ui.module.scss\";\n\nimport styles from \"./Picker.module.scss\";\n\ninterface PickerStatusProps {\n\temptyState?: ReactNode;\n\t// loadingState?: ReactNode;\n\terrorState?: ReactNode;\n}\n\nexport function PickerStatus({ emptyState, errorState }: PickerStatusProps) {\n\tconst content = errorState ?? emptyState;\n\n\tif (content === undefined || content === null) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<div className={cn(uiStyles.uiPopupOption, styles.status, errorState !== undefined && styles.statusError)} aria-disabled={true}>\n\t\t\t{content}\n\t\t</div>\n\t);\n}\n","import { MouseEvent, ReactNode } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { ChevronDownIcon } from \"lucide-react\";\n\nimport uiStyles from \"../ui.module.scss\";\n\ninterface PickerTriggerActionsProps {\n\topen: boolean;\n\tdisabled?: boolean;\n\tchildren?: ReactNode;\n\tonToggleMouseDown?: (event: MouseEvent<HTMLButtonElement>) => void;\n\tonToggleClick: () => void;\n\topenAriaLabel?: string;\n\tcloseAriaLabel?: string;\n}\n\nexport function PickerTriggerActions({\n\topen,\n\tdisabled,\n\tchildren,\n\tonToggleMouseDown,\n\tonToggleClick,\n\topenAriaLabel = \"Открыть список\",\n\tcloseAriaLabel = \"Закрыть список\"\n}: PickerTriggerActionsProps) {\n\treturn (\n\t\t<div className={uiStyles.uiToggleButtonContainer} data-disabled={disabled || undefined}>\n\t\t\t{children}\n\n\t\t\t<div className={uiStyles.uiButtonSeparator} />\n\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tdisabled={disabled}\n\t\t\t\taria-label={open ? closeAriaLabel : openAriaLabel}\n\t\t\t\tclassName={uiStyles.uiToggleButton}\n\t\t\t\tonMouseDown={onToggleMouseDown}\n\t\t\t\tonClick={onToggleClick}>\n\t\t\t\t<ChevronDownIcon className={cn(uiStyles.uiToggleIcon, open && uiStyles.uiToggleIconOpen)} />\n\t\t\t</button>\n\t\t</div>\n\t);\n}\n","import { ComponentPropsWithoutRef, forwardRef, ReactNode } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { InputControl, InputLoadingFrame } from \"../input\";\nimport uiStyles from \"../ui.module.scss\";\n\nimport styles from \"./Picker.module.scss\";\n\nexport interface PickerTriggerInputProps extends Omit<ComponentPropsWithoutRef<\"input\">, \"size\"> {\n\trootRef?: (node: HTMLDivElement | null) => void;\n\tendAdornment?: ReactNode;\n\toverlay?: ReactNode;\n\trootClassName?: string;\n\tinputClassName?: string;\n\tisLoading?: boolean;\n}\n\nexport const PickerTriggerInput = forwardRef<HTMLInputElement, PickerTriggerInputProps>(\n\t({ rootRef, endAdornment, overlay, rootClassName, inputClassName, isLoading, ...props }, ref) => {\n\t\tconst hasOverlay = overlay !== undefined && overlay !== null;\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={rootRef}\n\t\t\t\tclassName={cn(uiStyles.uiInputContainer, styles.triggerContainer, rootClassName)}\n\t\t\t\tdata-has-overlay={hasOverlay || undefined}>\n\t\t\t\t{isLoading ? (\n\t\t\t\t\t<InputLoadingFrame />\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<InputControl endAdornment={endAdornment}>\n\t\t\t\t\t\t\t{({ controlClassName }) => (\n\t\t\t\t\t\t\t\t<input {...props} ref={ref} className={cn(uiStyles.uiInputWithToggle, controlClassName, inputClassName)} />\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</InputControl>\n\t\t\t\t\t\t{hasOverlay ? overlay : null}\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t);\n\t}\n);\n\nPickerTriggerInput.displayName = \"PickerTriggerInput\";\n","import { type ReactNode, type Ref } from \"react\";\n\nimport styles from \"./Picker.module.scss\";\nimport { PickerClearButton } from \"./PickerClearButton\";\nimport { getPickerPlaceholder } from \"./PickerPlaceholder\";\nimport { PickerSelectedToken } from \"./PickerSelectedToken\";\nimport { PickerTriggerActions } from \"./PickerTriggerActions\";\nimport { PickerTriggerInput, type PickerTriggerInputProps } from \"./PickerTriggerInput\";\n\nexport interface PickerTriggerProps extends Omit<PickerTriggerInputProps, \"placeholder\" | \"overlay\" | \"endAdornment\"> {\n\tref?: Ref<HTMLInputElement>;\n\topen: boolean;\n\toptionCount: number;\n\tplaceholder?: string;\n\tlabel?: ReactNode;\n\tplaceholderFallback?: string;\n\tselectedValue?: ReactNode;\n\thasSelection?: boolean;\n\tshowSelectedValue?: boolean;\n\tclearable?: boolean;\n\tonClear?: () => void;\n\tclearAriaLabel?: string;\n\tonToggleMouseDown?: PickerTriggerActionsProps[\"onToggleMouseDown\"];\n\tonToggleClick: PickerTriggerActionsProps[\"onToggleClick\"];\n\topenAriaLabel?: string;\n\tcloseAriaLabel?: string;\n}\n\ntype PickerTriggerActionsProps = Parameters<typeof PickerTriggerActions>[0];\n\n/**\n * Общая композиция picker-trigger: input, выбранное значение, очистка и кнопка\n * открытия. Владельцы picker-моделей передают только состояние и обработчики.\n */\nexport function PickerTrigger({\n\tref,\n\topen,\n\toptionCount,\n\tplaceholder,\n\tlabel,\n\tplaceholderFallback,\n\tselectedValue,\n\thasSelection,\n\tshowSelectedValue = selectedValue !== undefined && selectedValue !== null,\n\tclearable = false,\n\tonClear,\n\tclearAriaLabel,\n\tonToggleMouseDown,\n\tonToggleClick,\n\topenAriaLabel,\n\tcloseAriaLabel,\n\tdisabled,\n\tinputClassName,\n\t...inputProps\n}: PickerTriggerProps) {\n\tconst hasSelectedValue = hasSelection ?? (selectedValue !== undefined && selectedValue !== null);\n\tconst canClear = clearable && hasSelectedValue && onClear !== undefined && !disabled;\n\n\treturn (\n\t\t<PickerTriggerInput\n\t\t\t{...inputProps}\n\t\t\tref={ref}\n\t\t\tdisabled={disabled}\n\t\t\tplaceholder={\n\t\t\t\tshowSelectedValue ? undefined : getPickerPlaceholder({ placeholder, label, optionCount, fallback: placeholderFallback })\n\t\t\t}\n\t\t\tinputClassName={inputClassName}\n\t\t\trootClassName={clearable ? styles.triggerHasClear : undefined}\n\t\t\toverlay={showSelectedValue ? <PickerSelectedToken>{selectedValue}</PickerSelectedToken> : undefined}\n\t\t\tendAdornment={\n\t\t\t\t<PickerTriggerActions\n\t\t\t\t\topen={open}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tonToggleMouseDown={onToggleMouseDown}\n\t\t\t\t\tonToggleClick={onToggleClick}\n\t\t\t\t\topenAriaLabel={openAriaLabel}\n\t\t\t\t\tcloseAriaLabel={closeAriaLabel}>\n\t\t\t\t\t{canClear ? <PickerClearButton ariaLabel={clearAriaLabel} onClear={onClear} /> : null}\n\t\t\t\t</PickerTriggerActions>\n\t\t\t}\n\t\t/>\n\t);\n}\n","export type PickerTriggerMode = \"display\" | \"search-single\" | \"search-multi\";\n\ninterface PickerTriggerTextFocusParams {\n\topen: boolean;\n\tcurrentQuery: string;\n\thasDisplayValue: boolean;\n}\n\nexport interface PickerTriggerPolicy {\n\tfocusFloatingOnOpen: boolean;\n\trestoreFocusOnClose: boolean;\n\tresetQueryOnClose: boolean;\n\tshouldOpenOnTriggerClick: (open: boolean) => boolean;\n\tshouldOpenOnInputChange: (open: boolean) => boolean;\n\tshouldFocusReferenceOnToggle: (open: boolean) => boolean;\n\tshouldSelectTriggerTextOnFocus: (params: PickerTriggerTextFocusParams) => boolean;\n}\n\n/**\n * Единая политика поведения trigger-input для picker-компонентов.\n * Нормализует различия между display-режимом, single-search и multi-search.\n */\nexport function createPickerTriggerPolicy(mode: PickerTriggerMode): PickerTriggerPolicy {\n\tswitch (mode) {\n\t\tcase \"search-single\":\n\t\t\treturn {\n\t\t\t\tfocusFloatingOnOpen: false,\n\t\t\t\trestoreFocusOnClose: false,\n\t\t\t\tresetQueryOnClose: true,\n\t\t\t\tshouldOpenOnTriggerClick: () => false,\n\t\t\t\tshouldOpenOnInputChange: (open) => !open,\n\t\t\t\tshouldFocusReferenceOnToggle: (open) => !open,\n\t\t\t\tshouldSelectTriggerTextOnFocus: ({ open, currentQuery, hasDisplayValue }) =>\n\t\t\t\t\t!open && currentQuery.length === 0 && hasDisplayValue\n\t\t\t};\n\t\tcase \"search-multi\":\n\t\t\treturn {\n\t\t\t\tfocusFloatingOnOpen: false,\n\t\t\t\trestoreFocusOnClose: false,\n\t\t\t\tresetQueryOnClose: true,\n\t\t\t\tshouldOpenOnTriggerClick: () => false,\n\t\t\t\tshouldOpenOnInputChange: (open) => !open,\n\t\t\t\tshouldFocusReferenceOnToggle: (open) => !open,\n\t\t\t\tshouldSelectTriggerTextOnFocus: () => false\n\t\t\t};\n\t\tcase \"display\":\n\t\tdefault:\n\t\t\treturn {\n\t\t\t\tfocusFloatingOnOpen: true,\n\t\t\t\trestoreFocusOnClose: true,\n\t\t\t\tresetQueryOnClose: false,\n\t\t\t\tshouldOpenOnTriggerClick: (open) => !open,\n\t\t\t\tshouldOpenOnInputChange: () => false,\n\t\t\t\tshouldFocusReferenceOnToggle: () => false,\n\t\t\t\tshouldSelectTriggerTextOnFocus: () => false\n\t\t\t};\n\t}\n}\n","import { useMemo } from \"react\";\n\nimport { normalizeTextToLower } from \"@ryuzaki13/react-foundation-lib/formatters\";\n\ninterface UsePickerDefaultFilterOptions<T> {\n\toptions: readonly T[];\n\tquery: string;\n\tenabled?: boolean;\n\tgetSearchText: (option: T) => unknown;\n}\n\nfunction normalizeSearchText(value: unknown) {\n\tconst parts = Array.isArray(value) ? value : [value];\n\n\treturn normalizeTextToLower(parts.filter(Boolean).join(\" \"));\n}\n\nexport function usePickerDefaultFilter<T>({ options, query, enabled = true, getSearchText }: UsePickerDefaultFilterOptions<T>) {\n\tconst normalizedQuery = normalizeTextToLower(query);\n\n\treturn useMemo(() => {\n\t\tif (!enabled || !normalizedQuery) {\n\t\t\treturn [...options];\n\t\t}\n\n\t\treturn options.filter((option) => normalizeSearchText(getSearchText(option)).includes(normalizedQuery));\n\t}, [enabled, getSearchText, normalizedQuery, options]);\n}\n","import { Placement } from \"@floating-ui/react\";\nimport {\n\ttype FloatingListboxPlacementStrategy,\n\ttype FloatingListboxSizeResolver,\n\tuseFloatingListbox\n} from \"@ryuzaki13/react-foundation-lib/hooks\";\n\nimport { PickerTriggerMode, createPickerTriggerPolicy } from \"./createPickerTriggerPolicy\";\n\ninterface UsePickerFloatingListboxParams<T> {\n\toptions: readonly T[];\n\tselectedIndex: number;\n\topen?: boolean;\n\tonOpenChange?: (open: boolean) => void;\n\tgetOptionDisabled?: (option: T) => boolean;\n\tonSelect?: (option: T) => void;\n\tdisabled?: boolean;\n\tplacement?: Placement;\n\tplacementStrategy?: FloatingListboxPlacementStrategy;\n\tcloseOnSelect?: boolean;\n\tfocusFloatingOnOpen?: boolean;\n\tallowOpenWithoutOptions?: boolean;\n\trestoreFocusOnClose?: boolean;\n\ttriggerMode?: PickerTriggerMode;\n\tresolveFloatingSize?: FloatingListboxSizeResolver;\n}\n\n/**\n * Единая точка входа для popup/listbox поведения во всех picker-компонентах.\n */\nexport function usePickerFloatingListbox<T>(params: UsePickerFloatingListboxParams<T>) {\n\tconst triggerPolicy = params.triggerMode ? createPickerTriggerPolicy(params.triggerMode) : undefined;\n\n\treturn useFloatingListbox({\n\t\t...params,\n\t\tfocusFloatingOnOpen: params.focusFloatingOnOpen ?? triggerPolicy?.focusFloatingOnOpen,\n\t\trestoreFocusOnClose: params.restoreFocusOnClose ?? triggerPolicy?.restoreFocusOnClose\n\t});\n}\n","import { useState } from \"react\";\n\nimport { PickerTriggerMode, createPickerTriggerPolicy } from \"./createPickerTriggerPolicy\";\n\ninterface UsePickerQueryOptions {\n\tquery?: string;\n\tdefaultQuery?: string;\n\tonQuery?: (value: string) => void;\n\tresetOnClose?: boolean;\n\ttriggerMode?: PickerTriggerMode;\n}\n\n/**\n * Управляет controlled/uncontrolled query и возвращает policy закрытия владельцу open-state.\n * Сброс выполняется самим владельцем в событии close, поэтому hook не зеркалит lifecycle через effect.\n */\nexport function usePickerQuery({ query, defaultQuery, onQuery, resetOnClose, triggerMode }: UsePickerQueryOptions) {\n\tconst isControlled = query !== undefined;\n\tconst [internalQuery, setInternalQuery] = useState(defaultQuery ?? \"\");\n\tconst currentQuery = isControlled ? (query ?? \"\") : internalQuery;\n\tconst resolvedResetOnClose = resetOnClose ?? (triggerMode ? createPickerTriggerPolicy(triggerMode).resetQueryOnClose : true);\n\n\tconst setQuery = (nextValue: string) => {\n\t\tif (!isControlled) {\n\t\t\tsetInternalQuery(nextValue);\n\t\t}\n\n\t\tonQuery?.(nextValue);\n\t};\n\n\treturn {\n\t\tquery: currentQuery,\n\t\tsetQuery,\n\t\tclearQuery: () => setQuery(\"\"),\n\t\tresetQueryOnClose: resolvedResetOnClose\n\t};\n}\n","import { useEffect, useRef, useState } from \"react\";\n\ninterface UsePickerSelectionLifecycleOptions<TValue> {\n\tvalue: TValue;\n\topen: boolean;\n\tonCommit: (value: TValue) => void;\n\tonOpen?: () => void;\n\tonClose?: (value: TValue) => void;\n\tisEqual: (left: TValue, right: TValue) => boolean;\n}\n\n/**\n * Общий жизненный цикл чернового выбора для picker-компонентов,\n * где изменения подтверждаются при закрытии popup.\n */\nexport function usePickerSelectionLifecycle<TValue>({\n\tvalue,\n\topen,\n\tonCommit,\n\tonOpen,\n\tonClose,\n\tisEqual\n}: UsePickerSelectionLifecycleOptions<TValue>) {\n\tconst previousOpenRef = useRef(false);\n\tconst [draftValue, setDraftValue] = useState(value);\n\n\tuseEffect(() => {\n\t\tif (previousOpenRef.current && !open) {\n\t\t\tif (!isEqual(draftValue, value)) {\n\t\t\t\tonCommit(draftValue);\n\t\t\t}\n\n\t\t\tonClose?.(draftValue);\n\t\t}\n\n\t\tpreviousOpenRef.current = open;\n\t}, [draftValue, isEqual, onClose, onCommit, open, value]);\n\n\tconst prepareOpen = () => {\n\t\tsetDraftValue(value);\n\t\tonOpen?.();\n\t};\n\n\treturn {\n\t\tdraftValue,\n\t\tsetDraftValue,\n\t\tprepareOpen\n\t};\n}\n","import { MouseEvent, RefObject } from \"react\";\n\nimport { PickerTriggerMode, createPickerTriggerPolicy } from \"./createPickerTriggerPolicy\";\n\ninterface UsePickerTriggerControllerOptions {\n\tmode: PickerTriggerMode;\n\topen: boolean;\n\tcurrentQuery: string;\n\thasDisplayValue: boolean;\n\tinputRef: RefObject<HTMLInputElement | null>;\n\tsetQuery?: (value: string) => void;\n\topenList?: () => void;\n\tclose?: () => void;\n\ttoggleOpen?: () => void;\n\tonBeforeOpen?: () => void;\n}\n\ninterface HandleTriggerKeyDownOptions {\n\tevent: React.KeyboardEvent<HTMLElement>;\n\tonActivateWhenOpen?: () => void;\n\tenableSpaceActivation?: boolean;\n\tenableClosedArrowDownOpen?: boolean;\n\tsuppressClosedArrowUp?: boolean;\n}\n\nfunction focusInput(inputRef: RefObject<HTMLInputElement | null>) {\n\trequestAnimationFrame(() => {\n\t\tinputRef.current?.focus();\n\t});\n}\n\n/**\n * Единый контроллер пользовательских действий на trigger-input.\n * Держит поведение display/search-single/search-multi в одном месте.\n */\nexport function usePickerTriggerController({\n\tmode,\n\topen,\n\tcurrentQuery,\n\thasDisplayValue,\n\tinputRef,\n\tsetQuery,\n\topenList,\n\tclose,\n\ttoggleOpen,\n\tonBeforeOpen\n}: UsePickerTriggerControllerOptions) {\n\tconst policy = createPickerTriggerPolicy(mode);\n\n\tconst openTrigger = () => {\n\t\tonBeforeOpen?.();\n\n\t\tif (openList) {\n\t\t\topenList();\n\t\t\treturn;\n\t\t}\n\n\t\ttoggleOpen?.();\n\t};\n\n\tconst closeTrigger = () => {\n\t\tif (close) {\n\t\t\tclose();\n\t\t\treturn;\n\t\t}\n\n\t\ttoggleOpen?.();\n\t};\n\n\tconst toggleTrigger = () => {\n\t\tif (open) {\n\t\t\tcloseTrigger();\n\t\t} else {\n\t\t\topenTrigger();\n\t\t}\n\n\t\tif (policy.shouldFocusReferenceOnToggle(open)) {\n\t\t\tfocusInput(inputRef);\n\t\t}\n\t};\n\n\treturn {\n\t\tpolicy,\n\t\thandleTriggerInputChange: (nextValue: string) => {\n\t\t\tsetQuery?.(nextValue);\n\n\t\t\tif (policy.shouldOpenOnInputChange(open)) {\n\t\t\t\topenTrigger();\n\t\t\t}\n\t\t},\n\t\thandleTriggerClick: () => {\n\t\t\tif (policy.shouldOpenOnTriggerClick(open)) {\n\t\t\t\topenTrigger();\n\t\t\t}\n\t\t},\n\t\thandleTriggerFocus: (input: HTMLInputElement) => {\n\t\t\tif (\n\t\t\t\tpolicy.shouldSelectTriggerTextOnFocus({\n\t\t\t\t\topen,\n\t\t\t\t\tcurrentQuery,\n\t\t\t\t\thasDisplayValue\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\tinput.select();\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\thandleToggleMouseDown: (event: MouseEvent<HTMLButtonElement>) => {\n\t\t\tevent.preventDefault();\n\t\t},\n\t\thandleToggleClick: () => {\n\t\t\ttoggleTrigger();\n\t\t},\n\t\thandleTriggerKeyDown: ({\n\t\t\tevent,\n\t\t\tonActivateWhenOpen,\n\t\t\tenableSpaceActivation = false,\n\t\t\tenableClosedArrowDownOpen = false,\n\t\t\tsuppressClosedArrowUp = false\n\t\t}: HandleTriggerKeyDownOptions) => {\n\t\t\tif (!open && suppressClosedArrowUp && event.key === \"ArrowUp\") {\n\t\t\t\tevent.preventDefault();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!open && enableClosedArrowDownOpen && event.key === \"ArrowDown\") {\n\t\t\t\tevent.preventDefault();\n\t\t\t\ttoggleTrigger();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (event.key === \"Enter\") {\n\t\t\t\tevent.preventDefault();\n\n\t\t\t\tif (open) {\n\t\t\t\t\tonActivateWhenOpen?.();\n\t\t\t\t} else {\n\t\t\t\t\ttoggleTrigger();\n\t\t\t\t}\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (enableSpaceActivation && event.key === \" \") {\n\t\t\t\tevent.preventDefault();\n\n\t\t\t\tif (open) {\n\t\t\t\t\tonActivateWhenOpen?.();\n\t\t\t\t} else {\n\t\t\t\t\ttoggleTrigger();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\ttoggleTrigger\n\t};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"picker-lvm82d0A.js","names":[],"sources":["../../src/picker/PickerField.tsx","../../src/picker/PickerClearButton.tsx","../../src/picker/Picker.module.scss","../../src/picker/PickerSelectionToolbar.tsx","../../src/picker/PickerOptions.tsx","../../src/picker/model/extractPickerTextContent.ts","../../src/picker/PickerPlaceholder.ts","../../src/picker/PickerPopup.tsx","../../src/picker/PickerSelectedToken.tsx","../../src/picker/PickerStatus.tsx","../../src/picker/PickerTriggerActions.tsx","../../src/picker/PickerTriggerInput.tsx","../../src/picker/PickerTrigger.tsx","../../src/picker/model/createPickerTriggerPolicy.ts","../../src/picker/model/usePickerDefaultFilter.ts","../../src/picker/model/usePickerFloatingListbox.ts","../../src/picker/model/usePickerQuery.ts","../../src/picker/model/usePickerSelectionLifecycle.ts","../../src/picker/model/usePickerTriggerController.ts"],"sourcesContent":["import { InputType } from \"@ryuzaki13/react-foundation-lib/types\";\n\nimport { InputUI } from \"../input\";\nimport { useInputFieldIds } from \"../input/lib/useInputFieldIds\";\n\nimport { PickerFieldProps } from \"./types\";\n\nexport function PickerField<TValue extends InputType>({\n\tid,\n\tlabel,\n\tdescription,\n\tdisabled,\n\tsize,\n\tclassName,\n\terror,\n\tchildren\n}: PickerFieldProps<TValue>) {\n\tconst { controlId, labelId, descriptionId, errorId, describedBy } = useInputFieldIds({\n\t\tid,\n\t\thasLabel: label !== undefined && label !== null,\n\t\thasDescription: !!description,\n\t\thasError: !!error\n\t});\n\n\treturn (\n\t\t<InputUI\n\t\t\tlabel={label}\n\t\t\tdescription={description}\n\t\t\tdisabled={disabled}\n\t\t\tsize={size}\n\t\t\tclassName={className}\n\t\t\terror={error}\n\t\t\tcontrolId={controlId}\n\t\t\tlabelId={labelId}\n\t\t\tdescriptionId={descriptionId}\n\t\t\terrorId={errorId}>\n\t\t\t{children({ controlId, labelId, descriptionId, errorId, describedBy })}\n\t\t</InputUI>\n\t);\n}\n","import { type MouseEvent } from \"react\";\n\nimport { XIcon } from \"lucide-react\";\n\nimport uiStyles from \"../ui.module.scss\";\n\ntype PickerClearButtonProps = {\n\tdisabled?: boolean;\n\tariaLabel?: string;\n\tonClear: () => void;\n};\n\n/** Единое действие очистки выбранного значения во всех clearable picker-компонентах. */\nexport function PickerClearButton({ disabled, ariaLabel = \"Очистить выбор\", onClear }: PickerClearButtonProps) {\n\tconst stopTriggerInteraction = (event: MouseEvent<HTMLButtonElement>) => {\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t};\n\n\treturn (\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tdisabled={disabled}\n\t\t\tclassName={uiStyles.uiClearButton}\n\t\t\tdata-ui=\"picker-clear-button\"\n\t\t\tdata-action=\"clear-picker\"\n\t\t\tonMouseDown={stopTriggerInteraction}\n\t\t\tonClick={(event) => {\n\t\t\t\tstopTriggerInteraction(event);\n\t\t\t\tonClear();\n\t\t\t}}\n\t\t\taria-label={ariaLabel}>\n\t\t\t<XIcon />\n\t\t</button>\n\t);\n}\n","@use \"@/styles/mixins\" as *;\n\n.popupPositioner,\n.options {\n\toverflow: hidden;\n\tdisplay: grid;\n\tgrid-template-rows: minmax(0, 1fr);\n\tborder-radius: var(--radius-sm);\n}\n\n.popupPositioner {\n\t--anchor-gap: var(--space-xs);\n\t--anchor-padding: var(--space-xs);\n\t--anchor-offset: 0;\n\t// Минимальная ширина нужна только floating-панели. Встроенный Listbox получает ширину от UiBaseProps.size.\n\t--input-width: min(100vw, var(--base-width, 15em));\n\n\tmin-width: 0;\n\tz-index: var(--z-dropdown);\n\tbox-shadow: var(--shadow-md);\n\n\t.options {\n\t\tmin-width: var(--input-width);\n\t}\n}\n\n.options {\n\twidth: 100%;\n\tmin-height: 0;\n\tmax-height: 75vh;\n\n\tpadding: var(--space-sm);\n\tbackground-color: var(--surface-0);\n\tborder: var(--border);\n\n\t&:empty {\n\t\tvisibility: hidden;\n\t}\n\n\t&[data-has-toolbar=\"true\"] {\n\t\tgrid-template-rows: auto minmax(0, 1fr);\n\t}\n}\n\n.optionsToolbar {\n\tdisplay: grid;\n\tgap: var(--space-xs);\n\tpadding: var(--space-xs);\n}\n\n.optionsBody {\n\tmin-height: 0;\n}\n\n.status {\n\tpadding: var(--space-xs) var(--space-sm);\n\tcolor: var(--content-2);\n}\n\n.statusError {\n\tcolor: var(--error-text);\n}\n\n.triggerContainer {\n\tposition: relative;\n\n\t&[data-has-overlay=\"true\"] input {\n\t\t--ui-color: transparent;\n\t\t--ui-color-hover: transparent;\n\t\t--ui-color-active: transparent;\n\n\t\tcolor: transparent;\n\t\tcaret-color: transparent;\n\t\t-webkit-text-fill-color: transparent;\n\t}\n}\n\n.triggerHasClear {\n\t--trigger-count: 2;\n\t// Резервирует в input место для кнопок очистки и открытия списка.\n\t--input-end-adornment-width: calc(var(--control-height) * 2);\n}\n\n.selectedToken {\n\tposition: absolute;\n\tinset: 0 calc(var(--control-height) * var(--trigger-count, 1) + var(--space-sm)) 0 var(--space-sm);\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: flex-end;\n\tmin-width: 0;\n\tpointer-events: none;\n}\n\n.selectedTokenText {\n\toverflow: hidden;\n\twhite-space: nowrap;\n\ttext-overflow: ellipsis;\n}\n\n@include mobile {\n\t.popupPositioner {\n\t\t--input-width: calc(100dvw - var(--space-xl));\n\t}\n}\n\n.selectionActionButton {\n\tpadding-block: var(--space-xs);\n\tborder-radius: var(--radius-sm);\n\n\t&:hover {\n\t\tbackground-color: var(--surface-2);\n\t}\n}\n","import { type Ref } from \"react\";\n\nimport { Grid } from \"../grid\";\n\nimport styles from \"./Picker.module.scss\";\n\ntype PickerSelectionToolbarProps = {\n\tonSelectAll: () => void;\n\tonDeselectAll: () => void;\n\tselectAllButtonRef?: Ref<HTMLButtonElement>;\n};\n\n/**\n * Общая панель массовых действий для picker-компонентов с множественным выбором.\n * Компонент не знает формат значения и делегирует изменение владельцу selection-модели.\n */\nexport function PickerSelectionToolbar({ onSelectAll, onDeselectAll, selectAllButtonRef }: PickerSelectionToolbarProps) {\n\treturn (\n\t\t<Grid.Container gap=\"xs\" templateColumns=\"1fr 1fr\">\n\t\t\t<button\n\t\t\t\tref={selectAllButtonRef}\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName={styles.selectionActionButton}\n\t\t\t\tonClick={onSelectAll}\n\t\t\t\tdata-ui=\"picker-select-all\"\n\t\t\t\tdata-action=\"select-all\">\n\t\t\t\tВыбрать все\n\t\t\t</button>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName={styles.selectionActionButton}\n\t\t\t\tonClick={onDeselectAll}\n\t\t\t\tdata-ui=\"picker-deselect-all\"\n\t\t\t\tdata-action=\"deselect-all\">\n\t\t\t\tСнять выбор\n\t\t\t</button>\n\t\t</Grid.Container>\n\t);\n}\n","import { type HTMLAttributes, type ReactNode, type Ref } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { Separator } from \"../separator\";\n\nimport styles from \"./Picker.module.scss\";\nimport { PickerSelectionToolbar } from \"./PickerSelectionToolbar\";\n\nexport type PickerSelectionActions = {\n\tonSelectAll: () => void;\n\tonDeselectAll: () => void;\n\tselectAllButtonRef?: Ref<HTMLButtonElement>;\n};\n\nexport interface PickerOptionsProps extends Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n\trootRef?: Ref<HTMLDivElement>;\n\tchildren: ReactNode;\n\ttoolbar?: ReactNode | false;\n\tselectionActions?: PickerSelectionActions;\n\tlayoutClassName?: string;\n\tbodyClassName?: string;\n\tscrollable?: boolean;\n}\n\n/**\n * Единая оболочка списка опций для picker, listbox и menu. Если переданы\n * selectionActions, но не передан toolbar, компонент показывает стандартные\n * действия выбора и снятия выбора.\n */\nexport function PickerOptions({\n\trootRef,\n\tchildren,\n\ttoolbar,\n\tselectionActions,\n\tlayoutClassName,\n\tbodyClassName,\n\tscrollable = true,\n\tclassName,\n\t...props\n}: PickerOptionsProps) {\n\tconst resolvedToolbar = toolbar === undefined && selectionActions ? <PickerSelectionToolbar {...selectionActions} /> : toolbar || null;\n\n\treturn (\n\t\t<div\n\t\t\t{...props}\n\t\t\tref={rootRef}\n\t\t\tclassName={cn(styles.options, layoutClassName, className)}\n\t\t\tdata-ui=\"picker-options\"\n\t\t\tdata-has-toolbar={resolvedToolbar ? \"true\" : undefined}>\n\t\t\t{resolvedToolbar ? (\n\t\t\t\t<div className={styles.optionsToolbar}>\n\t\t\t\t\t{resolvedToolbar}\n\t\t\t\t\t<Separator />\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t<div className={cn(styles.optionsBody, scrollable ? \"scrollable overscroll\" : \"overflowHidden\", bodyClassName)}>{children}</div>\n\t\t</div>\n\t);\n}\n","import { isValidElement, type ReactNode } from \"react\";\n\nexport function extractPickerTextContent(node: ReactNode): string | undefined {\n\tif (typeof node === \"string\" || typeof node === \"number\") {\n\t\treturn String(node);\n\t}\n\n\tif (Array.isArray(node)) {\n\t\tconst values = node\n\t\t\t.map(extractPickerTextContent)\n\t\t\t.filter((value): value is string => Boolean(value))\n\t\t\t.map((value) => value.trim())\n\t\t\t.filter(Boolean);\n\t\treturn values.length ? values.join(\" \") : undefined;\n\t}\n\n\tif (isValidElement<{ children?: ReactNode; searchText?: unknown }>(node)) {\n\t\tif (typeof node.props.searchText === \"string\") {\n\t\t\treturn node.props.searchText;\n\t\t}\n\n\t\treturn extractPickerTextContent(node.props.children);\n\t}\n\n\treturn undefined;\n}\n","import { type ReactNode } from \"react\";\n\nimport { extractPickerTextContent } from \"./model/extractPickerTextContent\";\n\ntype PickerPlaceholderParams = {\n\tplaceholder?: string;\n\tlabel?: ReactNode;\n\toptionCount: number;\n\tfallback?: string;\n};\n\n/**\n * Формирует единый текст placeholder для picker-компонентов и всегда показывает\n * актуальное количество доступных вариантов.\n */\nexport function getPickerPlaceholder({ placeholder, label, optionCount, fallback = \"Выберите значение\" }: PickerPlaceholderParams) {\n\tconst labelText = extractPickerTextContent(label);\n\tconst text = placeholder ?? labelText ?? fallback;\n\n\treturn `${text} <${optionCount}>`;\n}\n","import { type CSSProperties, type KeyboardEvent, type MouseEvent, type ReactNode } from \"react\";\n\nimport { FloatingContext, FloatingFocusManager, FloatingPortal } from \"@floating-ui/react\";\nimport { AnimatePresence, motion } from \"motion/react\";\n\nimport styles from \"./Picker.module.scss\";\nimport { PickerOptions, type PickerSelectionActions } from \"./PickerOptions\";\n\ninterface PickerPopupProps {\n\topen: boolean;\n\tcontext: FloatingContext;\n\tfloatingStyles: CSSProperties;\n\tlistId: string;\n\tlabelId?: string;\n\tpopupAriaLabel?: string;\n\tdescriptionId?: string;\n\tactiveOptionId?: string;\n\tariaMultiselectable?: boolean;\n\tpopupRole?: \"listbox\" | \"dialog\";\n\tsetFloating: (node: HTMLElement | null) => void;\n\tgetFloatingProps: (userProps?: Record<string, unknown>) => Record<string, unknown>;\n\tonKeyDown: (event: KeyboardEvent<HTMLElement>) => void;\n\tinitialFocus?: number;\n\treturnFocus?: boolean;\n\ttabIndex?: number;\n\tclassName?: string;\n\tmaxWidth?: CSSProperties[\"maxWidth\"];\n\tlayoutClassName?: string;\n\tbodyClassName?: string;\n\ttoolbar?: ReactNode | false;\n\tselectionActions?: PickerSelectionActions;\n\tchildren: ReactNode;\n}\n\nfunction stopNestedFloatingMouseDown(event: MouseEvent<HTMLElement>): void {\n\tevent.stopPropagation();\n}\n\nexport function PickerPopup({\n\topen,\n\tcontext,\n\tfloatingStyles,\n\tlistId,\n\tlabelId,\n\tpopupAriaLabel,\n\tdescriptionId,\n\tactiveOptionId,\n\tariaMultiselectable,\n\tpopupRole = \"listbox\",\n\tsetFloating,\n\tgetFloatingProps,\n\tonKeyDown,\n\tinitialFocus = -1,\n\treturnFocus = false,\n\ttabIndex = 0,\n\tclassName,\n\tmaxWidth,\n\tlayoutClassName,\n\tbodyClassName,\n\ttoolbar,\n\tselectionActions,\n\tchildren\n}: PickerPopupProps) {\n\treturn (\n\t\t<AnimatePresence>\n\t\t\t{open && (\n\t\t\t\t<FloatingPortal>\n\t\t\t\t\t<FloatingFocusManager context={context} modal={false} initialFocus={initialFocus} returnFocus={returnFocus}>\n\t\t\t\t\t\t<motion.div\n\t\t\t\t\t\t\tref={setFloating}\n\t\t\t\t\t\t\tstyle={{ ...floatingStyles, maxWidth }}\n\t\t\t\t\t\t\tinitial={{ opacity: 0, scale: 0.95 }}\n\t\t\t\t\t\t\tanimate={{ opacity: 1, scale: 1 }}\n\t\t\t\t\t\t\texit={{ opacity: 0, scale: 0.95 }}\n\t\t\t\t\t\t\t{...getFloatingProps({\n\t\t\t\t\t\t\t\tid: listId,\n\t\t\t\t\t\t\t\trole: popupRole,\n\t\t\t\t\t\t\t\ttabIndex,\n\t\t\t\t\t\t\t\t\"aria-labelledby\": labelId,\n\t\t\t\t\t\t\t\t\"aria-label\": labelId ? undefined : popupAriaLabel,\n\t\t\t\t\t\t\t\t\"aria-describedby\": descriptionId,\n\t\t\t\t\t\t\t\t\"aria-activedescendant\": activeOptionId,\n\t\t\t\t\t\t\t\t\"aria-multiselectable\": ariaMultiselectable || undefined,\n\t\t\t\t\t\t\t\tonMouseDown: stopNestedFloatingMouseDown,\n\t\t\t\t\t\t\t\tonKeyDown,\n\t\t\t\t\t\t\t\tclassName: styles.popupPositioner\n\t\t\t\t\t\t\t})}>\n\t\t\t\t\t\t\t<PickerOptions\n\t\t\t\t\t\t\t\tclassName={className}\n\t\t\t\t\t\t\t\tlayoutClassName={layoutClassName}\n\t\t\t\t\t\t\t\tbodyClassName={bodyClassName}\n\t\t\t\t\t\t\t\ttoolbar={toolbar}\n\t\t\t\t\t\t\t\tselectionActions={selectionActions}\n\t\t\t\t\t\t\t\tscrollable={false}>\n\t\t\t\t\t\t\t\t{children}\n\t\t\t\t\t\t\t</PickerOptions>\n\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t</FloatingFocusManager>\n\t\t\t\t</FloatingPortal>\n\t\t\t)}\n\t\t</AnimatePresence>\n\t);\n}\n","import { type HTMLAttributes, type ReactNode } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport styles from \"./Picker.module.scss\";\n\nexport interface PickerSelectedTokenProps extends Omit<HTMLAttributes<HTMLSpanElement>, \"children\"> {\n\tchildren: ReactNode;\n}\n\n/** Единое визуальное представление выбранного значения внутри picker-trigger. */\nexport function PickerSelectedToken({ children, className, ...props }: PickerSelectedTokenProps) {\n\treturn (\n\t\t<span {...props} className={cn(styles.selectedToken, className)} data-ui=\"picker-selected-token\">\n\t\t\t<span className={styles.selectedTokenText}>{children}</span>\n\t\t</span>\n\t);\n}\n","import { ReactNode } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport uiStyles from \"../ui.module.scss\";\n\nimport styles from \"./Picker.module.scss\";\n\ninterface PickerStatusProps {\n\temptyState?: ReactNode;\n\t// loadingState?: ReactNode;\n\terrorState?: ReactNode;\n}\n\nexport function PickerStatus({ emptyState, errorState }: PickerStatusProps) {\n\tconst content = errorState ?? emptyState;\n\n\tif (content === undefined || content === null) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<div className={cn(uiStyles.uiPopupOption, styles.status, errorState !== undefined && styles.statusError)} aria-disabled={true}>\n\t\t\t{content}\n\t\t</div>\n\t);\n}\n","import { MouseEvent, ReactNode } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { ChevronDownIcon } from \"lucide-react\";\n\nimport uiStyles from \"../ui.module.scss\";\n\ninterface PickerTriggerActionsProps {\n\topen: boolean;\n\tdisabled?: boolean;\n\tchildren?: ReactNode;\n\tonToggleMouseDown?: (event: MouseEvent<HTMLButtonElement>) => void;\n\tonToggleClick: () => void;\n\topenAriaLabel?: string;\n\tcloseAriaLabel?: string;\n}\n\nexport function PickerTriggerActions({\n\topen,\n\tdisabled,\n\tchildren,\n\tonToggleMouseDown,\n\tonToggleClick,\n\topenAriaLabel = \"Открыть список\",\n\tcloseAriaLabel = \"Закрыть список\"\n}: PickerTriggerActionsProps) {\n\treturn (\n\t\t<div className={uiStyles.uiToggleButtonContainer} data-disabled={disabled || undefined}>\n\t\t\t{children}\n\n\t\t\t<div className={uiStyles.uiButtonSeparator} />\n\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tdisabled={disabled}\n\t\t\t\taria-label={open ? closeAriaLabel : openAriaLabel}\n\t\t\t\tclassName={uiStyles.uiToggleButton}\n\t\t\t\tonMouseDown={onToggleMouseDown}\n\t\t\t\tonClick={onToggleClick}>\n\t\t\t\t<ChevronDownIcon className={cn(uiStyles.uiToggleIcon, open && uiStyles.uiToggleIconOpen)} />\n\t\t\t</button>\n\t\t</div>\n\t);\n}\n","import { ComponentPropsWithoutRef, forwardRef, ReactNode } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { InputControl, InputLoadingFrame } from \"../input\";\nimport uiStyles from \"../ui.module.scss\";\n\nimport styles from \"./Picker.module.scss\";\n\nexport interface PickerTriggerInputProps extends Omit<ComponentPropsWithoutRef<\"input\">, \"size\"> {\n\trootRef?: (node: HTMLDivElement | null) => void;\n\tendAdornment?: ReactNode;\n\toverlay?: ReactNode;\n\trootClassName?: string;\n\tinputClassName?: string;\n\tisLoading?: boolean;\n}\n\nexport const PickerTriggerInput = forwardRef<HTMLInputElement, PickerTriggerInputProps>(\n\t({ rootRef, endAdornment, overlay, rootClassName, inputClassName, isLoading, ...props }, ref) => {\n\t\tconst hasOverlay = overlay !== undefined && overlay !== null;\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={rootRef}\n\t\t\t\tclassName={cn(uiStyles.uiInputContainer, styles.triggerContainer, rootClassName)}\n\t\t\t\tdata-has-overlay={hasOverlay || undefined}>\n\t\t\t\t{isLoading ? (\n\t\t\t\t\t<InputLoadingFrame />\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<InputControl endAdornment={endAdornment}>\n\t\t\t\t\t\t\t{({ controlClassName }) => (\n\t\t\t\t\t\t\t\t<input {...props} ref={ref} className={cn(uiStyles.uiInputWithToggle, controlClassName, inputClassName)} />\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</InputControl>\n\t\t\t\t\t\t{hasOverlay ? overlay : null}\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t);\n\t}\n);\n\nPickerTriggerInput.displayName = \"PickerTriggerInput\";\n","import { type ReactNode, type Ref } from \"react\";\n\nimport styles from \"./Picker.module.scss\";\nimport { PickerClearButton } from \"./PickerClearButton\";\nimport { getPickerPlaceholder } from \"./PickerPlaceholder\";\nimport { PickerSelectedToken } from \"./PickerSelectedToken\";\nimport { PickerTriggerActions } from \"./PickerTriggerActions\";\nimport { PickerTriggerInput, type PickerTriggerInputProps } from \"./PickerTriggerInput\";\n\nexport interface PickerTriggerProps extends Omit<PickerTriggerInputProps, \"placeholder\" | \"overlay\" | \"endAdornment\"> {\n\tref?: Ref<HTMLInputElement>;\n\topen: boolean;\n\toptionCount: number;\n\tplaceholder?: string;\n\tlabel?: ReactNode;\n\tplaceholderFallback?: string;\n\tselectedValue?: ReactNode;\n\thasSelection?: boolean;\n\tshowSelectedValue?: boolean;\n\tclearable?: boolean;\n\tonClear?: () => void;\n\tclearAriaLabel?: string;\n\tonToggleMouseDown?: PickerTriggerActionsProps[\"onToggleMouseDown\"];\n\tonToggleClick: PickerTriggerActionsProps[\"onToggleClick\"];\n\topenAriaLabel?: string;\n\tcloseAriaLabel?: string;\n}\n\ntype PickerTriggerActionsProps = Parameters<typeof PickerTriggerActions>[0];\n\n/**\n * Общая композиция picker-trigger: input, выбранное значение, очистка и кнопка\n * открытия. Владельцы picker-моделей передают только состояние и обработчики.\n */\nexport function PickerTrigger({\n\tref,\n\topen,\n\toptionCount,\n\tplaceholder,\n\tlabel,\n\tplaceholderFallback,\n\tselectedValue,\n\thasSelection,\n\tshowSelectedValue = selectedValue !== undefined && selectedValue !== null,\n\tclearable = false,\n\tonClear,\n\tclearAriaLabel,\n\tonToggleMouseDown,\n\tonToggleClick,\n\topenAriaLabel,\n\tcloseAriaLabel,\n\tdisabled,\n\tinputClassName,\n\t...inputProps\n}: PickerTriggerProps) {\n\tconst hasSelectedValue = hasSelection ?? (selectedValue !== undefined && selectedValue !== null);\n\tconst canClear = clearable && hasSelectedValue && onClear !== undefined && !disabled;\n\n\treturn (\n\t\t<PickerTriggerInput\n\t\t\t{...inputProps}\n\t\t\tref={ref}\n\t\t\tdisabled={disabled}\n\t\t\tplaceholder={\n\t\t\t\tshowSelectedValue ? undefined : getPickerPlaceholder({ placeholder, label, optionCount, fallback: placeholderFallback })\n\t\t\t}\n\t\t\tinputClassName={inputClassName}\n\t\t\trootClassName={clearable ? styles.triggerHasClear : undefined}\n\t\t\toverlay={showSelectedValue ? <PickerSelectedToken>{selectedValue}</PickerSelectedToken> : undefined}\n\t\t\tendAdornment={\n\t\t\t\t<PickerTriggerActions\n\t\t\t\t\topen={open}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tonToggleMouseDown={onToggleMouseDown}\n\t\t\t\t\tonToggleClick={onToggleClick}\n\t\t\t\t\topenAriaLabel={openAriaLabel}\n\t\t\t\t\tcloseAriaLabel={closeAriaLabel}>\n\t\t\t\t\t{canClear ? <PickerClearButton ariaLabel={clearAriaLabel} onClear={onClear} /> : null}\n\t\t\t\t</PickerTriggerActions>\n\t\t\t}\n\t\t/>\n\t);\n}\n","export type PickerTriggerMode = \"display\" | \"search-single\" | \"search-multi\";\n\ninterface PickerTriggerTextFocusParams {\n\topen: boolean;\n\tcurrentQuery: string;\n\thasDisplayValue: boolean;\n}\n\nexport interface PickerTriggerPolicy {\n\tfocusFloatingOnOpen: boolean;\n\trestoreFocusOnClose: boolean;\n\tresetQueryOnClose: boolean;\n\tshouldOpenOnTriggerClick: (open: boolean) => boolean;\n\tshouldOpenOnInputChange: (open: boolean) => boolean;\n\tshouldFocusReferenceOnToggle: (open: boolean) => boolean;\n\tshouldSelectTriggerTextOnFocus: (params: PickerTriggerTextFocusParams) => boolean;\n}\n\n/**\n * Единая политика поведения trigger-input для picker-компонентов.\n * Нормализует различия между display-режимом, single-search и multi-search.\n */\nexport function createPickerTriggerPolicy(mode: PickerTriggerMode): PickerTriggerPolicy {\n\tswitch (mode) {\n\t\tcase \"search-single\":\n\t\t\treturn {\n\t\t\t\tfocusFloatingOnOpen: false,\n\t\t\t\trestoreFocusOnClose: false,\n\t\t\t\tresetQueryOnClose: true,\n\t\t\t\tshouldOpenOnTriggerClick: () => false,\n\t\t\t\tshouldOpenOnInputChange: (open) => !open,\n\t\t\t\tshouldFocusReferenceOnToggle: (open) => !open,\n\t\t\t\tshouldSelectTriggerTextOnFocus: ({ open, currentQuery, hasDisplayValue }) =>\n\t\t\t\t\t!open && currentQuery.length === 0 && hasDisplayValue\n\t\t\t};\n\t\tcase \"search-multi\":\n\t\t\treturn {\n\t\t\t\tfocusFloatingOnOpen: false,\n\t\t\t\trestoreFocusOnClose: false,\n\t\t\t\tresetQueryOnClose: true,\n\t\t\t\tshouldOpenOnTriggerClick: () => false,\n\t\t\t\tshouldOpenOnInputChange: (open) => !open,\n\t\t\t\tshouldFocusReferenceOnToggle: (open) => !open,\n\t\t\t\tshouldSelectTriggerTextOnFocus: () => false\n\t\t\t};\n\t\tcase \"display\":\n\t\tdefault:\n\t\t\treturn {\n\t\t\t\tfocusFloatingOnOpen: true,\n\t\t\t\trestoreFocusOnClose: true,\n\t\t\t\tresetQueryOnClose: false,\n\t\t\t\tshouldOpenOnTriggerClick: (open) => !open,\n\t\t\t\tshouldOpenOnInputChange: () => false,\n\t\t\t\tshouldFocusReferenceOnToggle: () => false,\n\t\t\t\tshouldSelectTriggerTextOnFocus: () => false\n\t\t\t};\n\t}\n}\n","import { useMemo } from \"react\";\n\nimport { normalizeTextToLower } from \"@ryuzaki13/react-foundation-lib/formatters\";\n\ninterface UsePickerDefaultFilterOptions<T> {\n\toptions: readonly T[];\n\tquery: string;\n\tenabled?: boolean;\n\tgetSearchText: (option: T) => unknown;\n}\n\nfunction normalizeSearchText(value: unknown) {\n\tconst parts = Array.isArray(value) ? value : [value];\n\n\treturn normalizeTextToLower(parts.filter(Boolean).join(\" \"));\n}\n\nexport function usePickerDefaultFilter<T>({ options, query, enabled = true, getSearchText }: UsePickerDefaultFilterOptions<T>) {\n\tconst normalizedQuery = normalizeTextToLower(query);\n\n\treturn useMemo(() => {\n\t\tif (!enabled || !normalizedQuery) {\n\t\t\treturn [...options];\n\t\t}\n\n\t\treturn options.filter((option) => normalizeSearchText(getSearchText(option)).includes(normalizedQuery));\n\t}, [enabled, getSearchText, normalizedQuery, options]);\n}\n","import { Placement } from \"@floating-ui/react\";\nimport {\n\ttype FloatingListboxPlacementStrategy,\n\ttype FloatingListboxSizeResolver,\n\tuseFloatingListbox\n} from \"@ryuzaki13/react-foundation-lib/hooks\";\n\nimport { PickerTriggerMode, createPickerTriggerPolicy } from \"./createPickerTriggerPolicy\";\n\ninterface UsePickerFloatingListboxParams<T> {\n\toptions: readonly T[];\n\tselectedIndex: number;\n\topen?: boolean;\n\tonOpenChange?: (open: boolean) => void;\n\tgetOptionDisabled?: (option: T) => boolean;\n\tonSelect?: (option: T) => void;\n\tdisabled?: boolean;\n\tplacement?: Placement;\n\tplacementStrategy?: FloatingListboxPlacementStrategy;\n\tcloseOnSelect?: boolean;\n\tfocusFloatingOnOpen?: boolean;\n\tallowOpenWithoutOptions?: boolean;\n\trestoreFocusOnClose?: boolean;\n\ttriggerMode?: PickerTriggerMode;\n\tresolveFloatingSize?: FloatingListboxSizeResolver;\n}\n\n/**\n * Единая точка входа для popup/listbox поведения во всех picker-компонентах.\n */\nexport function usePickerFloatingListbox<T>(params: UsePickerFloatingListboxParams<T>) {\n\tconst triggerPolicy = params.triggerMode ? createPickerTriggerPolicy(params.triggerMode) : undefined;\n\n\treturn useFloatingListbox({\n\t\t...params,\n\t\tfocusFloatingOnOpen: params.focusFloatingOnOpen ?? triggerPolicy?.focusFloatingOnOpen,\n\t\trestoreFocusOnClose: params.restoreFocusOnClose ?? triggerPolicy?.restoreFocusOnClose\n\t});\n}\n","import { useState } from \"react\";\n\nimport { PickerTriggerMode, createPickerTriggerPolicy } from \"./createPickerTriggerPolicy\";\n\ninterface UsePickerQueryOptions {\n\tquery?: string;\n\tdefaultQuery?: string;\n\tonQuery?: (value: string) => void;\n\tresetOnClose?: boolean;\n\ttriggerMode?: PickerTriggerMode;\n}\n\n/**\n * Управляет controlled/uncontrolled query и возвращает policy закрытия владельцу open-state.\n * Сброс выполняется самим владельцем в событии close, поэтому hook не зеркалит lifecycle через effect.\n */\nexport function usePickerQuery({ query, defaultQuery, onQuery, resetOnClose, triggerMode }: UsePickerQueryOptions) {\n\tconst isControlled = query !== undefined;\n\tconst [internalQuery, setInternalQuery] = useState(defaultQuery ?? \"\");\n\tconst currentQuery = isControlled ? (query ?? \"\") : internalQuery;\n\tconst resolvedResetOnClose = resetOnClose ?? (triggerMode ? createPickerTriggerPolicy(triggerMode).resetQueryOnClose : true);\n\n\tconst setQuery = (nextValue: string) => {\n\t\tif (!isControlled) {\n\t\t\tsetInternalQuery(nextValue);\n\t\t}\n\n\t\tonQuery?.(nextValue);\n\t};\n\n\treturn {\n\t\tquery: currentQuery,\n\t\tsetQuery,\n\t\tclearQuery: () => setQuery(\"\"),\n\t\tresetQueryOnClose: resolvedResetOnClose\n\t};\n}\n","import { useEffect, useRef, useState } from \"react\";\n\ninterface UsePickerSelectionLifecycleOptions<TValue> {\n\tvalue: TValue;\n\topen: boolean;\n\tonCommit: (value: TValue) => void;\n\tonOpen?: () => void;\n\tonClose?: (value: TValue) => void;\n\tisEqual: (left: TValue, right: TValue) => boolean;\n}\n\n/**\n * Общий жизненный цикл чернового выбора для picker-компонентов,\n * где изменения подтверждаются при закрытии popup.\n */\nexport function usePickerSelectionLifecycle<TValue>({\n\tvalue,\n\topen,\n\tonCommit,\n\tonOpen,\n\tonClose,\n\tisEqual\n}: UsePickerSelectionLifecycleOptions<TValue>) {\n\tconst previousOpenRef = useRef(false);\n\tconst [draftValue, setDraftValue] = useState(value);\n\n\tuseEffect(() => {\n\t\tif (previousOpenRef.current && !open) {\n\t\t\tif (!isEqual(draftValue, value)) {\n\t\t\t\tonCommit(draftValue);\n\t\t\t}\n\n\t\t\tonClose?.(draftValue);\n\t\t}\n\n\t\tpreviousOpenRef.current = open;\n\t}, [draftValue, isEqual, onClose, onCommit, open, value]);\n\n\tconst prepareOpen = () => {\n\t\tsetDraftValue(value);\n\t\tonOpen?.();\n\t};\n\n\treturn {\n\t\tdraftValue,\n\t\tsetDraftValue,\n\t\tprepareOpen\n\t};\n}\n","import { MouseEvent, RefObject } from \"react\";\n\nimport { PickerTriggerMode, createPickerTriggerPolicy } from \"./createPickerTriggerPolicy\";\n\ninterface UsePickerTriggerControllerOptions {\n\tmode: PickerTriggerMode;\n\topen: boolean;\n\tcurrentQuery: string;\n\thasDisplayValue: boolean;\n\tinputRef: RefObject<HTMLInputElement | null>;\n\tsetQuery?: (value: string) => void;\n\topenList?: () => void;\n\tclose?: () => void;\n\ttoggleOpen?: () => void;\n\tonBeforeOpen?: () => void;\n}\n\ninterface HandleTriggerKeyDownOptions {\n\tevent: React.KeyboardEvent<HTMLElement>;\n\tonActivateWhenOpen?: () => void;\n\tenableSpaceActivation?: boolean;\n\tenableClosedArrowDownOpen?: boolean;\n\tsuppressClosedArrowUp?: boolean;\n}\n\nfunction focusInput(inputRef: RefObject<HTMLInputElement | null>) {\n\trequestAnimationFrame(() => {\n\t\tinputRef.current?.focus();\n\t});\n}\n\n/**\n * Единый контроллер пользовательских действий на trigger-input.\n * Держит поведение display/search-single/search-multi в одном месте.\n */\nexport function usePickerTriggerController({\n\tmode,\n\topen,\n\tcurrentQuery,\n\thasDisplayValue,\n\tinputRef,\n\tsetQuery,\n\topenList,\n\tclose,\n\ttoggleOpen,\n\tonBeforeOpen\n}: UsePickerTriggerControllerOptions) {\n\tconst policy = createPickerTriggerPolicy(mode);\n\n\tconst openTrigger = () => {\n\t\tonBeforeOpen?.();\n\n\t\tif (openList) {\n\t\t\topenList();\n\t\t\treturn;\n\t\t}\n\n\t\ttoggleOpen?.();\n\t};\n\n\tconst closeTrigger = () => {\n\t\tif (close) {\n\t\t\tclose();\n\t\t\treturn;\n\t\t}\n\n\t\ttoggleOpen?.();\n\t};\n\n\tconst toggleTrigger = () => {\n\t\tif (open) {\n\t\t\tcloseTrigger();\n\t\t} else {\n\t\t\topenTrigger();\n\t\t}\n\n\t\tif (policy.shouldFocusReferenceOnToggle(open)) {\n\t\t\tfocusInput(inputRef);\n\t\t}\n\t};\n\n\treturn {\n\t\tpolicy,\n\t\thandleTriggerInputChange: (nextValue: string) => {\n\t\t\tsetQuery?.(nextValue);\n\n\t\t\tif (policy.shouldOpenOnInputChange(open)) {\n\t\t\t\topenTrigger();\n\t\t\t}\n\t\t},\n\t\thandleTriggerClick: () => {\n\t\t\tif (policy.shouldOpenOnTriggerClick(open)) {\n\t\t\t\topenTrigger();\n\t\t\t}\n\t\t},\n\t\thandleTriggerFocus: (input: HTMLInputElement) => {\n\t\t\tif (\n\t\t\t\tpolicy.shouldSelectTriggerTextOnFocus({\n\t\t\t\t\topen,\n\t\t\t\t\tcurrentQuery,\n\t\t\t\t\thasDisplayValue\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\tinput.select();\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\thandleToggleMouseDown: (event: MouseEvent<HTMLButtonElement>) => {\n\t\t\tevent.preventDefault();\n\t\t},\n\t\thandleToggleClick: () => {\n\t\t\ttoggleTrigger();\n\t\t},\n\t\thandleTriggerKeyDown: ({\n\t\t\tevent,\n\t\t\tonActivateWhenOpen,\n\t\t\tenableSpaceActivation = false,\n\t\t\tenableClosedArrowDownOpen = false,\n\t\t\tsuppressClosedArrowUp = false\n\t\t}: HandleTriggerKeyDownOptions) => {\n\t\t\tif (!open && suppressClosedArrowUp && event.key === \"ArrowUp\") {\n\t\t\t\tevent.preventDefault();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (!open && enableClosedArrowDownOpen && event.key === \"ArrowDown\") {\n\t\t\t\tevent.preventDefault();\n\t\t\t\ttoggleTrigger();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (event.key === \"Enter\") {\n\t\t\t\tevent.preventDefault();\n\n\t\t\t\tif (open) {\n\t\t\t\t\tonActivateWhenOpen?.();\n\t\t\t\t} else {\n\t\t\t\t\ttoggleTrigger();\n\t\t\t\t}\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (enableSpaceActivation && event.key === \" \") {\n\t\t\t\tevent.preventDefault();\n\n\t\t\t\tif (open) {\n\t\t\t\t\tonActivateWhenOpen?.();\n\t\t\t\t} else {\n\t\t\t\t\ttoggleTrigger();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\ttoggleTrigger\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;AAOA,SAAgB,EAAsC,EACrD,OACA,UACA,gBACA,aACA,SACA,cACA,UACA,eAC4B;CAC5B,IAAM,EAAE,cAAW,YAAS,kBAAe,YAAS,mBAAgB,EAAiB;EACpF;EACA,UAAU,KAAiC;EAC3C,gBAAgB,CAAC,CAAC;EAClB,UAAU,CAAC,CAAC;CACb,CAAC;CAED,OACC,kBAAC,GAAD;EACQ;EACM;EACH;EACJ;EACK;EACJ;EACI;EACF;EACM;EACN;EACR,UAAA,EAAS;GAAE;GAAW;GAAS;GAAe;GAAS;EAAY,CAAC;CAC7D,CAAA;AAEX;;;AC1BA,SAAgB,EAAkB,EAAE,aAAU,eAAY,kBAAkB,cAAmC;CAC9G,IAAM,KAA0B,MAAyC;EAExE,AADA,EAAM,eAAe,GACrB,EAAM,gBAAgB;CACvB;CAEA,OACC,kBAAC,UAAD;EACC,MAAK;EACK;EACV,WAAW,EAAS;EACpB,WAAQ;EACR,eAAY;EACZ,aAAa;EACb,UAAU,MAAU;GAEnB,AADA,EAAuB,CAAK,GAC5B,EAAQ;EACT;EACA,cAAY;EACZ,UAAA,kBAAC,GAAD,CAAQ,CAAA;CACD,CAAA;AAEV;;;;;;;;;;;;;;;;AEnBA,SAAgB,EAAuB,EAAE,gBAAa,kBAAe,yBAAmD;CACvH,OACC,kBAAC,EAAK,WAAN;EAAgB,KAAI;EAAK,iBAAgB;EAAzC,UAAA,CACC,kBAAC,UAAD;GACC,KAAK;GACL,MAAK;GACL,WAAW,EAAO;GAClB,SAAS;GACT,WAAQ;GACR,eAAY;GAAa,UAAA;EAElB,CAAA,GACR,kBAAC,UAAD;GACC,MAAK;GACL,WAAW,EAAO;GAClB,SAAS;GACT,WAAQ;GACR,eAAY;GAAe,UAAA;EAEpB,CAAA,CACO;;AAElB;;;ACRA,SAAgB,EAAc,EAC7B,YACA,aACA,YACA,qBACA,oBACA,kBACA,gBAAa,IACb,cACA,GAAG,KACmB;CACtB,IAAM,IAAkB,MAAY,KAAA,KAAa,IAAmB,kBAAC,GAAD,EAAwB,GAAI,EAAmB,CAAA,IAAI,KAAW;CAElI,OACC,kBAAC,OAAD;EACC,GAAI;EACJ,KAAK;EACL,WAAW,EAAG,EAAO,SAAS,GAAiB,CAAS;EACxD,WAAQ;EACR,oBAAkB,IAAkB,SAAS,KAAA;EAL9C,UAAA,CAME,IACA,kBAAC,OAAD;GAAK,WAAW,EAAO;GAAvB,UAAA,CACE,GACD,kBAAC,GAAD,CAAY,CAAA,CACR;EACF,CAAA,IAAA,MACJ,kBAAC,OAAD;GAAK,WAAW,EAAG,EAAO,aAAa,IAAa,0BAA0B,kBAAkB,CAAa;GAAI;EAAc,CAAA,CAC3H;;AAEP;;;ACzDA,SAAgB,EAAyB,GAAqC;CAC7E,IAAI,OAAO,KAAS,YAAY,OAAO,KAAS,UAC/C,OAAO,OAAO,CAAI;CAGnB,IAAI,MAAM,QAAQ,CAAI,GAAG;EACxB,IAAM,IAAS,EACb,IAAI,CAAwB,CAAC,CAC7B,QAAQ,MAA2B,EAAQ,CAAM,CAAC,CAClD,KAAK,MAAU,EAAM,KAAK,CAAC,CAAC,CAC5B,OAAO,OAAO;EAChB,OAAO,EAAO,SAAS,EAAO,KAAK,GAAG,IAAI,KAAA;CAC3C;CAEA,IAAI,EAA+D,CAAI,GAKtE,OAJI,OAAO,EAAK,MAAM,cAAe,WAC7B,EAAK,MAAM,aAGZ,EAAyB,EAAK,MAAM,QAAQ;AAIrD;;;ACVA,SAAgB,EAAqB,EAAE,gBAAa,UAAO,gBAAa,cAAW,uBAAgD;CAClI,IAAM,IAAY,EAAyB,CAAK;CAGhD,OAAO,GAFM,KAAe,KAAa,EAE1B,IAAI,EAAY;AAChC;;;ACcA,SAAS,EAA4B,GAAsC;CAC1E,EAAM,gBAAgB;AACvB;AAEA,SAAgB,EAAY,EAC3B,SACA,YACA,mBACA,WACA,YACA,mBACA,kBACA,mBACA,wBACA,eAAY,WACZ,gBACA,qBACA,cACA,kBAAe,IACf,iBAAc,IACd,cAAW,GACX,cACA,aACA,oBACA,kBACA,YACA,qBACA,eACoB;CACpB,OACC,kBAAC,GAAD,EAAA,UACE,KACA,kBAAC,GAAD,EAAA,UACC,kBAAC,GAAD;EAA+B;EAAS,OAAO;EAAqB;EAA2B;EAC9F,UAAA,kBAAC,EAAO,KAAR;GACC,KAAK;GACL,OAAO;IAAE,GAAG;IAAgB;GAAS;GACrC,SAAS;IAAE,SAAS;IAAG,OAAO;GAAK;GACnC,SAAS;IAAE,SAAS;IAAG,OAAO;GAAE;GAChC,MAAM;IAAE,SAAS;IAAG,OAAO;GAAK;GAChC,GAAI,EAAiB;IACpB,IAAI;IACJ,MAAM;IACN;IACA,mBAAmB;IACnB,cAAc,IAAU,KAAA,IAAY;IACpC,oBAAoB;IACpB,yBAAyB;IACzB,wBAAwB,KAAuB,KAAA;IAC/C,aAAa;IACb;IACA,WAAW,EAAO;GACnB,CAAC;GACD,UAAA,kBAAC,GAAD;IACY;IACM;IACF;IACN;IACS;IAClB,YAAY;IACX;GACa,CAAA;EACJ,CAAA;CACS,CAAA,EACP,CAAA,EAED,CAAA;AAEnB;;;AC3FA,SAAgB,EAAoB,EAAE,aAAU,cAAW,GAAG,KAAmC;CAChG,OACC,kBAAC,QAAD;EAAM,GAAI;EAAO,WAAW,EAAG,EAAO,eAAe,CAAS;EAAG,WAAQ;EACxE,UAAA,kBAAC,QAAD;GAAM,WAAW,EAAO;GAAoB;EAAe,CAAA;CACtD,CAAA;AAER;;;ACHA,SAAgB,EAAa,EAAE,eAAY,iBAAiC;CAC3E,IAAM,IAAU,KAAc;CAM9B,OAJI,KAAqC,OACjC,OAIP,kBAAC,OAAD;EAAK,WAAW,EAAG,EAAS,eAAe,EAAO,QAAQ,MAAe,KAAA,KAAa,EAAO,WAAW;EAAG,iBAAe;EACxH,UAAA;CACG,CAAA;AAEP;;;ACTA,SAAgB,EAAqB,EACpC,SACA,aACA,aACA,sBACA,kBACA,mBAAgB,kBAChB,oBAAiB,oBACY;CAC7B,OACC,kBAAC,OAAD;EAAK,WAAW,EAAS;EAAyB,iBAAe,KAAY,KAAA;EAA7E,UAAA;GACE;GAED,kBAAC,OAAD,EAAK,WAAW,EAAS,kBAAoB,CAAA;GAE7C,kBAAC,UAAD;IACC,MAAK;IACK;IACV,cAAY,IAAO,IAAiB;IACpC,WAAW,EAAS;IACpB,aAAa;IACb,SAAS;IACT,UAAA,kBAAC,GAAD,EAAiB,WAAW,EAAG,EAAS,cAAc,KAAQ,EAAS,gBAAgB,EAAI,CAAA;GACpF,CAAA;EACJ;;AAEP;;;ACzBA,IAAa,IAAqB,GAChC,EAAE,YAAS,iBAAc,YAAS,kBAAe,mBAAgB,cAAW,GAAG,KAAS,MAAQ;CAChG,IAAM,IAAa,KAAqC;CAExD,OACC,kBAAC,OAAD;EACC,KAAK;EACL,WAAW,EAAG,EAAS,kBAAkB,EAAO,kBAAkB,CAAa;EAC/E,oBAAkB,KAAc,KAAA;EAC/B,UAAA,IACA,kBAAC,GAAD,CAAoB,CAAA,IAEpB,kBAAA,GAAA,EAAA,UAAA,CACC,kBAAC,GAAD;GAA4B;GACzB,WAAA,EAAE,0BACH,kBAAC,SAAD;IAAO,GAAI;IAAY;IAAK,WAAW,EAAG,EAAS,mBAAmB,GAAkB,CAAc;GAAI,CAAA;EAE9F,CAAA,GACb,IAAa,IAAU,IACvB,EAAA,CAAA;CAEC,CAAA;AAEP,CACD;AAEA,EAAmB,cAAc;;;ACVjC,SAAgB,EAAc,EAC7B,QACA,SACA,gBACA,gBACA,UACA,wBACA,kBACA,iBACA,uBAAoB,KAAiD,MACrE,eAAY,IACZ,YACA,mBACA,sBACA,kBACA,kBACA,mBACA,aACA,mBACA,GAAG,KACmB;CAEtB,IAAM,IAAW,MADQ,KAAiB,KAAiD,SACzC,MAAY,KAAA,KAAa,CAAC;CAE5E,OACC,kBAAC,GAAD;EACC,GAAI;EACC;EACK;EACV,aACC,IAAoB,KAAA,IAAY,EAAqB;GAAE;GAAa;GAAO;GAAa,UAAU;EAAoB,CAAC;EAExG;EAChB,eAAe,IAAY,EAAO,kBAAkB,KAAA;EACpD,SAAS,IAAoB,kBAAC,GAAD,EAAA,UAAsB,EAAmC,CAAA,IAAI,KAAA;EAC1F,cACC,kBAAC,GAAD;GACO;GACI;GACS;GACJ;GACA;GACC;GACf,UAAA,IAAW,kBAAC,GAAD;IAAmB,WAAW;IAAyB;GAAU,CAAA,IAAI;EAC5D,CAAA;CAEvB,CAAA;AAEH;;;AC5DA,SAAgB,EAA0B,GAA8C;CACvF,QAAQ,GAAR;EACC,KAAK,iBACJ,OAAO;GACN,qBAAqB;GACrB,qBAAqB;GACrB,mBAAmB;GACnB,gCAAgC;GAChC,0BAA0B,MAAS,CAAC;GACpC,+BAA+B,MAAS,CAAC;GACzC,iCAAiC,EAAE,SAAM,iBAAc,yBACtD,CAAC,KAAQ,EAAa,WAAW,KAAK;EACxC;EACD,KAAK,gBACJ,OAAO;GACN,qBAAqB;GACrB,qBAAqB;GACrB,mBAAmB;GACnB,gCAAgC;GAChC,0BAA0B,MAAS,CAAC;GACpC,+BAA+B,MAAS,CAAC;GACzC,sCAAsC;EACvC;EAED,SACC,OAAO;GACN,qBAAqB;GACrB,qBAAqB;GACrB,mBAAmB;GACnB,2BAA2B,MAAS,CAAC;GACrC,+BAA+B;GAC/B,oCAAoC;GACpC,sCAAsC;EACvC;CACF;AACD;;;AC9CA,SAAS,EAAoB,GAAgB;CAG5C,OAAO,GAFO,MAAM,QAAQ,CAAK,IAAI,IAAQ,CAAC,CAAK,EAAA,CAEjB,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC;AAC5D;AAEA,SAAgB,EAA0B,EAAE,YAAS,UAAO,aAAU,IAAM,oBAAmD;CAC9H,IAAM,IAAkB,EAAqB,CAAK;CAElD,OAAO,QACF,CAAC,KAAW,CAAC,IACT,CAAC,GAAG,CAAO,IAGZ,EAAQ,QAAQ,MAAW,EAAoB,EAAc,CAAM,CAAC,CAAC,CAAC,SAAS,CAAe,CAAC,GACpG;EAAC;EAAS;EAAe;EAAiB;CAAO,CAAC;AACtD;;;ACGA,SAAgB,EAA4B,GAA2C;CACtF,IAAM,IAAgB,EAAO,cAAc,EAA0B,EAAO,WAAW,IAAI,KAAA;CAE3F,OAAO,EAAmB;EACzB,GAAG;EACH,qBAAqB,EAAO,uBAAuB,GAAe;EAClE,qBAAqB,EAAO,uBAAuB,GAAe;CACnE,CAAC;AACF;;;ACtBA,SAAgB,EAAe,EAAE,UAAO,iBAAc,YAAS,iBAAc,kBAAsC;CAClH,IAAM,IAAe,MAAU,KAAA,GACzB,CAAC,GAAe,KAAoB,EAAS,KAAgB,EAAE,GAC/D,IAAe,IAAgB,KAAS,KAAM,GAC9C,IAAuB,MAAiB,MAAc,EAA0B,CAAW,CAAC,CAAC,oBAE7F,KAAY,MAAsB;EAKvC,AAJK,KACJ,EAAiB,CAAS,GAG3B,IAAU,CAAS;CACpB;CAEA,OAAO;EACN,OAAO;EACP;EACA,kBAAkB,EAAS,EAAE;EAC7B,mBAAmB;CACpB;AACD;;;ACrBA,SAAgB,EAAoC,EACnD,UACA,SACA,aACA,WACA,YACA,cAC8C;CAC9C,IAAM,IAAkB,EAAO,EAAK,GAC9B,CAAC,GAAY,KAAiB,EAAS,CAAK;CAmBlD,OAjBA,QAAgB;EASf,AARI,EAAgB,WAAW,CAAC,MAC1B,EAAQ,GAAY,CAAK,KAC7B,EAAS,CAAU,GAGpB,IAAU,CAAU,IAGrB,EAAgB,UAAU;CAC3B,GAAG;EAAC;EAAY;EAAS;EAAS;EAAU;EAAM;CAAK,CAAC,GAOjD;EACN;EACA;EACA,mBARyB;GAEzB,AADA,EAAc,CAAK,GACnB,IAAS;EACV;CAMA;AACD;;;ACvBA,SAAS,EAAW,GAA8C;CACjE,4BAA4B;EAC3B,EAAS,SAAS,MAAM;CACzB,CAAC;AACF;AAMA,SAAgB,EAA2B,EAC1C,SACA,SACA,iBACA,oBACA,aACA,aACA,aACA,UACA,eACA,mBACqC;CACrC,IAAM,IAAS,EAA0B,CAAI,GAEvC,UAAoB;EAGzB,IAFA,IAAe,GAEX,GAAU;GACb,EAAS;GACT;EACD;EAEA,IAAa;CACd,GAEM,UAAqB;EAC1B,IAAI,GAAO;GACV,EAAM;GACN;EACD;EAEA,IAAa;CACd,GAEM,UAAsB;EAO3B,AANI,IACH,EAAa,IAEb,EAAY,GAGT,EAAO,6BAA6B,CAAI,KAC3C,EAAW,CAAQ;CAErB;CAEA,OAAO;EACN;EACA,2BAA2B,MAAsB;GAGhD,AAFA,IAAW,CAAS,GAEhB,EAAO,wBAAwB,CAAI,KACtC,EAAY;EAEd;EACA,0BAA0B;GACzB,AAAI,EAAO,yBAAyB,CAAI,KACvC,EAAY;EAEd;EACA,qBAAqB,MAA4B;GAChD,AACC,EAAO,+BAA+B;IACrC;IACA;IACA;GACD,CAAC,KAED,4BAA4B;IAC3B,EAAM,OAAO;GACd,CAAC;EAEH;EACA,wBAAwB,MAAyC;GAChE,EAAM,eAAe;EACtB;EACA,yBAAyB;GACxB,EAAc;EACf;EACA,uBAAuB,EACtB,UACA,uBACA,2BAAwB,IACxB,+BAA4B,IAC5B,2BAAwB,SACU;GAClC,IAAI,CAAC,KAAQ,KAAyB,EAAM,QAAQ,WAAW;IAC9D,EAAM,eAAe;IACrB;GACD;GAEA,IAAI,CAAC,KAAQ,KAA6B,EAAM,QAAQ,aAAa;IAEpE,AADA,EAAM,eAAe,GACrB,EAAc;IACd;GACD;GAEA,IAAI,EAAM,QAAQ,SAAS;IAG1B,AAFA,EAAM,eAAe,GAEjB,IACH,IAAqB,IAErB,EAAc;IAGf;GACD;GAEA,AAAI,KAAyB,EAAM,QAAQ,QAC1C,EAAM,eAAe,GAEjB,IACH,IAAqB,IAErB,EAAc;EAGjB;EACA;CACD;AACD"}
@@ -1,14 +1,16 @@
1
1
  import { type HTMLAttributes, type JSX, type ReactNode } from "react";
2
+ import { UiBaseProps } from "../types";
2
3
  type ListboxOption<T> = {
3
4
  value: T;
4
5
  label?: string;
5
6
  disabled?: boolean;
6
7
  };
7
- interface ListboxBaseProps<T> extends Omit<HTMLAttributes<HTMLDivElement>, "onChange" | "defaultValue" | "value"> {
8
+ /**
9
+ * Общие свойства Listbox берутся из UiBaseProps, чтобы подпись, состояние и
10
+ * размер поля оставались согласованными с остальными контролами библиотеки.
11
+ */
12
+ interface ListboxBaseProps<T> extends Omit<UiBaseProps<T>, "value" | "onChange" | "placeholder">, Omit<HTMLAttributes<HTMLDivElement>, "onChange" | "defaultValue" | "value"> {
8
13
  options: ListboxOption<T>[];
9
- label?: ReactNode;
10
- description?: string;
11
- disabled?: boolean;
12
14
  focusOnMount?: boolean;
13
15
  renderItem?: (option: ListboxOption<T>, selected: boolean, active: boolean) => ReactNode;
14
16
  getKey?: (option: ListboxOption<T>, index: number) => string;
@@ -1 +1 @@
1
- {"version":3,"file":"Listbox.d.ts","sourceRoot":"","sources":["../../src/listbox/Listbox.tsx"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,GAAG,EAGR,KAAK,SAAS,EAMd,MAAM,OAAO,CAAC;AAaf,KAAK,aAAa,CAAC,CAAC,IAAI;IACvB,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,UAAU,gBAAgB,CAAC,CAAC,CAAE,SAAQ,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,GAAG,cAAc,GAAG,OAAO,CAAC;IAChH,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5B,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,KAAK,SAAS,CAAC;IACzF,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CAC7D;AAGD,UAAU,kBAAkB,CAAC,CAAC,CAAE,SAAQ,gBAAgB,CAAC,CAAC,CAAC;IAC1D,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,KAAK,CAAC,EAAE,CAAC,CAAC;IACV,YAAY,CAAC,EAAE,CAAC,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;CACxD;AAGD,UAAU,iBAAiB,CAAC,CAAC,CAAE,SAAQ,gBAAgB,CAAC,CAAC,CAAC;IACzD,QAAQ,EAAE,IAAI,CAAC;IACf,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;IACZ,YAAY,CAAC,EAAE,CAAC,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;CAC1D;AA4BD;;GAEG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC;AACtE,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC"}
1
+ {"version":3,"file":"Listbox.d.ts","sourceRoot":"","sources":["../../src/listbox/Listbox.tsx"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,cAAc,EACnB,KAAK,GAAG,EAGR,KAAK,SAAS,EAMd,MAAM,OAAO,CAAC;AAYf,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvC,KAAK,aAAa,CAAC,CAAC,IAAI;IACvB,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF;;;GAGG;AACH,UAAU,gBAAgB,CAAC,CAAC,CAC3B,SACC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,aAAa,CAAC,EAC1D,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,GAAG,cAAc,GAAG,OAAO,CAAC;IAC5E,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,KAAK,SAAS,CAAC;IACzF,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CAC7D;AAGD,UAAU,kBAAkB,CAAC,CAAC,CAAE,SAAQ,gBAAgB,CAAC,CAAC,CAAC;IAC1D,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,KAAK,CAAC,EAAE,CAAC,CAAC;IACV,YAAY,CAAC,EAAE,CAAC,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;CACxD;AAGD,UAAU,iBAAiB,CAAC,CAAC,CAAE,SAAQ,gBAAgB,CAAC,CAAC,CAAC;IACzD,QAAQ,EAAE,IAAI,CAAC;IACf,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;IACZ,YAAY,CAAC,EAAE,CAAC,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;CAC1D;AA4BD;;GAEG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC;AACtE,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC"}
@@ -21,60 +21,61 @@ function _(e, t, n) {
21
21
  return u(e, g);
22
22
  }
23
23
  function v(v) {
24
- let { value: y, defaultValue: b, multiple: x, label: S, description: C, disabled: w, focusOnMount: T, renderItem: E, getKey: D, options: O, onChange: k, id: A, ...j } = v, M = y !== void 0, [N, P] = l(b), F = c(null), [I, L] = l(() => _(O, y ?? b, x)), R = c(!1), z = s(() => (M ? y : N) ?? (x ? [] : null), [
24
+ let { value: y, defaultValue: b, multiple: x, label: S, description: C, disabled: w, size: T, focusOnMount: E, renderItem: D, getKey: O, options: k, onChange: A, id: j, ...M } = v, N = y !== void 0, [P, F] = l(b), I = c(null), [L, R] = l(() => _(k, y ?? b, x)), z = c(!1), B = s(() => (N ? y : P) ?? (x ? [] : null), [
25
+ P,
25
26
  N,
26
- M,
27
27
  x,
28
28
  y
29
- ]), B = I, V = (e) => {
29
+ ]), V = L, H = (e) => {
30
30
  if (!(w || e.disabled)) {
31
31
  if (x) {
32
- let t = Array.isArray(z) ? z : [], n = t.includes(e.value) ? t.filter((t) => t !== e.value) : [...t, e.value];
33
- k?.(n, e), M || P(n);
32
+ let t = Array.isArray(B) ? B : [], n = t.includes(e.value) ? t.filter((t) => t !== e.value) : [...t, e.value];
33
+ A?.(n, e), N || F(n);
34
34
  return;
35
35
  }
36
- k?.(e.value, e), M || P(e.value);
36
+ A?.(e.value, e), N || F(e.value);
37
37
  }
38
- }, H = (e) => {
38
+ }, U = (e) => {
39
39
  if (!w) {
40
- if (e.key === "ArrowDown") e.preventDefault(), R.current = !0, L((e) => f(O, e, 1, g));
41
- else if (e.key === "ArrowUp") e.preventDefault(), R.current = !0, L((e) => f(O, e, -1, g));
42
- else if (e.key === "Home") e.preventDefault(), R.current = !0, L(u(O, g));
43
- else if (e.key === "End") e.preventDefault(), R.current = !0, L(d(O, g));
40
+ if (e.key === "ArrowDown") e.preventDefault(), z.current = !0, R((e) => f(k, e, 1, g));
41
+ else if (e.key === "ArrowUp") e.preventDefault(), z.current = !0, R((e) => f(k, e, -1, g));
42
+ else if (e.key === "Home") e.preventDefault(), z.current = !0, R(u(k, g));
43
+ else if (e.key === "End") e.preventDefault(), z.current = !0, R(d(k, g));
44
44
  else if (p(e, () => {
45
- let e = O[B];
46
- e && V(e);
45
+ let e = k[V];
46
+ e && H(e);
47
47
  })) return;
48
48
  }
49
49
  };
50
50
  return a(() => {
51
- if (!R.current) return;
52
- R.current = !1;
53
- let e = F.current?.querySelectorAll("[role=\"option\"]")[B];
51
+ if (!z.current) return;
52
+ z.current = !1;
53
+ let e = I.current?.querySelectorAll("[role=\"option\"]")[V];
54
54
  e && e.scrollIntoView({ block: "nearest" });
55
- }, [B]), o(() => {
56
- T && F.current?.focus();
57
- }, [T]), /* @__PURE__ */ m(i, {
58
- id: A,
55
+ }, [V]), o(() => {
56
+ E && I.current?.focus();
57
+ }, [E]), /* @__PURE__ */ m(i, {
58
+ id: j,
59
59
  label: S,
60
60
  description: C,
61
61
  disabled: w,
62
+ size: T,
62
63
  children: ({ controlId: i, labelId: a, describedBy: o }) => /* @__PURE__ */ m(r, {
63
- rootRef: F,
64
+ rootRef: I,
64
65
  id: i,
65
66
  role: "listbox",
66
67
  "aria-multiselectable": x || void 0,
67
- "aria-activedescendant": B >= 0 ? `${i}-option-${B}` : void 0,
68
- onKeyDown: H,
69
- ...j,
70
- "aria-labelledby": a ?? j["aria-labelledby"],
71
- "aria-describedby": o ?? j["aria-describedby"],
68
+ "aria-activedescendant": V >= 0 ? `${i}-option-${V}` : void 0,
69
+ onKeyDown: U,
70
+ ...M,
71
+ "aria-labelledby": a ?? M["aria-labelledby"],
72
+ "aria-describedby": o ?? M["aria-describedby"],
72
73
  "aria-disabled": w || void 0,
73
74
  tabIndex: w ? -1 : 0,
74
- className: j.className,
75
- children: O.map((r, a) => {
76
- let o = x ? Array.isArray(z) && z.includes(r.value) : z === r.value, s = a === B, c = w || r.disabled || void 0, l = (e) => {
77
- e.preventDefault(), !c && (L(a), V(r));
75
+ className: M.className,
76
+ children: k.map((r, a) => {
77
+ let o = x ? Array.isArray(B) && B.includes(r.value) : B === r.value, s = a === V, c = w || r.disabled || void 0, l = (e) => {
78
+ e.preventDefault(), !c && (R(a), H(r));
78
79
  };
79
80
  return /* @__PURE__ */ m(t, {
80
81
  id: `${i}-option-${a}`,
@@ -84,11 +85,11 @@ function v(v) {
84
85
  disabled: c,
85
86
  active: s,
86
87
  selected: o,
87
- children: E ? /* @__PURE__ */ m(e, {
88
+ children: D ? /* @__PURE__ */ m(e, {
88
89
  tabIndex: -1,
89
90
  disabled: c,
90
91
  onMouseDown: l,
91
- children: E(r, o, s)
92
+ children: D(r, o, s)
92
93
  }) : /* @__PURE__ */ m(n, {
93
94
  tabIndex: -1,
94
95
  disabled: c,
@@ -96,7 +97,7 @@ function v(v) {
96
97
  icon: m(o ? h : "span", {}),
97
98
  text: r.label ?? String(r.value)
98
99
  })
99
- }, D ? D(r, a) : a);
100
+ }, O ? O(r, a) : a);
100
101
  })
101
102
  })
102
103
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/listbox/Listbox.tsx"],"sourcesContent":["import {\n\ttype HTMLAttributes,\n\ttype JSX,\n\ttype KeyboardEvent,\n\ttype MouseEvent,\n\ttype ReactNode,\n\tuseEffect,\n\tuseLayoutEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState\n} from \"react\";\n\nimport {\n\tfindFirstEnabledIndex,\n\tfindLastEnabledIndex,\n\tfindNextEnabledIndex,\n\thandleKeyboardActivation\n} from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { CheckIcon } from \"lucide-react\";\n\nimport { CustomOptionButton, Option, OptionButton } from \"../option\";\nimport { PickerField, PickerOptions } from \"../picker\";\n\ntype ListboxOption<T> = {\n\tvalue: T;\n\tlabel?: string;\n\tdisabled?: boolean;\n};\n\ninterface ListboxBaseProps<T> extends Omit<HTMLAttributes<HTMLDivElement>, \"onChange\" | \"defaultValue\" | \"value\"> {\n\toptions: ListboxOption<T>[];\n\tlabel?: ReactNode;\n\tdescription?: string;\n\tdisabled?: boolean;\n\tfocusOnMount?: boolean;\n\trenderItem?: (option: ListboxOption<T>, selected: boolean, active: boolean) => ReactNode;\n\tgetKey?: (option: ListboxOption<T>, index: number) => string;\n}\n\n// Вариант для single-select\ninterface ListboxSingleProps<T> extends ListboxBaseProps<T> {\n\tmultiple?: false;\n\tvalue?: T;\n\tdefaultValue?: T;\n\tonChange?: (value: T, option: ListboxOption<T>) => void;\n}\n\n// Вариант для multi-select\ninterface ListboxMultiProps<T> extends ListboxBaseProps<T> {\n\tmultiple: true;\n\tvalue?: T[];\n\tdefaultValue?: T[];\n\tonChange?: (value: T[], option: ListboxOption<T>) => void;\n}\n\ntype ListboxProps<T> = ListboxSingleProps<T> | ListboxMultiProps<T>;\n\nconst isOptionDisabled = <T,>(option: ListboxOption<T>) => option.disabled === true;\n\nfunction getInitialFocusIndex<T>(options: ListboxOption<T>[], value: T | T[] | undefined, multiple: boolean | undefined) {\n\tif (multiple) {\n\t\tif (Array.isArray(value) && value.length > 0) {\n\t\t\tconst selectedIndex = options.findIndex((option) => value.includes(option.value) && !option.disabled);\n\t\t\tif (selectedIndex >= 0) {\n\t\t\t\treturn selectedIndex;\n\t\t\t}\n\t\t}\n\n\t\treturn findFirstEnabledIndex(options, isOptionDisabled);\n\t}\n\n\tif (value !== undefined) {\n\t\tconst selectedIndex = options.findIndex((option) => option.value === value && !option.disabled);\n\t\tif (selectedIndex >= 0) {\n\t\t\treturn selectedIndex;\n\t\t}\n\t}\n\n\treturn findFirstEnabledIndex(options, isOptionDisabled);\n}\n\n/**\n * Компонент выбора одного или нескольких элементов из списка. Поддерживает controlled API, поиск по данным и рендер кастомных опций.\n */\nexport function Listbox<T>(props: ListboxSingleProps<T>): JSX.Element;\nexport function Listbox<T>(props: ListboxMultiProps<T>): JSX.Element;\nexport function Listbox<T>(props: ListboxProps<T>): JSX.Element {\n\tconst {\n\t\tvalue,\n\t\tdefaultValue,\n\t\tmultiple,\n\t\tlabel,\n\t\tdescription,\n\t\tdisabled,\n\t\tfocusOnMount,\n\t\trenderItem,\n\t\tgetKey,\n\t\toptions,\n\t\tonChange,\n\t\tid: externalId,\n\t\t...rest\n\t} = props;\n\n\tconst isControlled = value !== undefined;\n\tconst [internalValue, setInternalValue] = useState<T | T[] | undefined>(defaultValue);\n\tconst listRef = useRef<HTMLDivElement>(null);\n\tconst [focusedIndex, setFocusedIndex] = useState(() => getInitialFocusIndex(options, value ?? defaultValue, multiple));\n\t/**\n\t * Прокрутка нужна только после клавиатурной навигации. Это не даёт монтированию и Fast Refresh\n\t * вызывать scrollIntoView, который иначе прокручивает внешнюю страницу до Listbox.\n\t */\n\tconst shouldScrollActiveOptionRef = useRef(false);\n\n\tconst selectedValues = useMemo(\n\t\t() => (isControlled ? value : internalValue) ?? (multiple ? [] : null),\n\t\t[internalValue, isControlled, multiple, value]\n\t);\n\tconst activeIndex = focusedIndex;\n\n\tconst handleSelect = (option: ListboxOption<T>) => {\n\t\tif (disabled || option.disabled) return;\n\n\t\tif (multiple) {\n\t\t\tconst arr = Array.isArray(selectedValues) ? selectedValues : [];\n\t\t\tconst newValue = arr.includes(option.value) ? arr.filter((v) => v !== option.value) : [...arr, option.value];\n\n\t\t\tonChange?.(newValue, option);\n\t\t\tif (!isControlled) setInternalValue(newValue);\n\t\t\treturn;\n\t\t}\n\n\t\tonChange?.(option.value, option);\n\n\t\tif (!isControlled) setInternalValue(option.value);\n\t};\n\n\tconst handleKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n\t\tif (disabled) return;\n\n\t\tif (e.key === \"ArrowDown\") {\n\t\t\te.preventDefault();\n\t\t\tshouldScrollActiveOptionRef.current = true;\n\t\t\t// setHoveredIndex(null);\n\t\t\tsetFocusedIndex((index) => findNextEnabledIndex(options, index, 1, isOptionDisabled));\n\t\t} else if (e.key === \"ArrowUp\") {\n\t\t\te.preventDefault();\n\t\t\tshouldScrollActiveOptionRef.current = true;\n\t\t\t// setHoveredIndex(null);\n\t\t\tsetFocusedIndex((index) => findNextEnabledIndex(options, index, -1, isOptionDisabled));\n\t\t} else if (e.key === \"Home\") {\n\t\t\te.preventDefault();\n\t\t\tshouldScrollActiveOptionRef.current = true;\n\t\t\t// setHoveredIndex(null);\n\t\t\tsetFocusedIndex(findFirstEnabledIndex(options, isOptionDisabled));\n\t\t} else if (e.key === \"End\") {\n\t\t\te.preventDefault();\n\t\t\tshouldScrollActiveOptionRef.current = true;\n\t\t\t// setHoveredIndex(null);\n\t\t\tsetFocusedIndex(findLastEnabledIndex(options, isOptionDisabled));\n\t\t} else if (\n\t\t\thandleKeyboardActivation(e, () => {\n\t\t\t\tconst activeOption = options[activeIndex];\n\t\t\t\tif (activeOption) {\n\t\t\t\t\thandleSelect(activeOption);\n\t\t\t\t}\n\t\t\t})\n\t\t) {\n\t\t\treturn;\n\t\t}\n\t};\n\n\tuseEffect(() => {\n\t\tif (!shouldScrollActiveOptionRef.current) return;\n\n\t\tshouldScrollActiveOptionRef.current = false;\n\t\tconst el = listRef.current?.querySelectorAll<HTMLElement>('[role=\"option\"]')[activeIndex];\n\t\tif (el) el.scrollIntoView({ block: \"nearest\" });\n\t}, [activeIndex]);\n\n\tuseLayoutEffect(() => {\n\t\tif (focusOnMount) {\n\t\t\tlistRef.current?.focus();\n\t\t}\n\t}, [focusOnMount]);\n\n\treturn (\n\t\t<PickerField id={externalId} label={label} description={description} disabled={disabled}>\n\t\t\t{({ controlId: listId, labelId, describedBy }) => (\n\t\t\t\t<PickerOptions\n\t\t\t\t\trootRef={listRef}\n\t\t\t\t\tid={listId}\n\t\t\t\t\trole=\"listbox\"\n\t\t\t\t\taria-multiselectable={multiple || undefined}\n\t\t\t\t\taria-activedescendant={activeIndex >= 0 ? `${listId}-option-${activeIndex}` : undefined}\n\t\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\t\t{...rest}\n\t\t\t\t\taria-labelledby={labelId ?? rest[\"aria-labelledby\"]}\n\t\t\t\t\taria-describedby={describedBy ?? rest[\"aria-describedby\"]}\n\t\t\t\t\taria-disabled={disabled || undefined}\n\t\t\t\t\ttabIndex={disabled ? -1 : 0}\n\t\t\t\t\tclassName={rest.className}>\n\t\t\t\t\t{options.map((option, index) => {\n\t\t\t\t\t\tconst selected = multiple\n\t\t\t\t\t\t\t? Array.isArray(selectedValues) && selectedValues.includes(option.value)\n\t\t\t\t\t\t\t: selectedValues === option.value;\n\t\t\t\t\t\tconst active = index === activeIndex;\n\t\t\t\t\t\tconst optionDisabled = disabled || option.disabled || undefined;\n\n\t\t\t\t\t\tconst handleMouseDown = (e: MouseEvent<HTMLButtonElement>) => {\n\t\t\t\t\t\t\te.preventDefault(); // чтобы не сбрасывался фокус listbox\n\t\t\t\t\t\t\tif (optionDisabled) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsetFocusedIndex(index);\n\t\t\t\t\t\t\thandleSelect(option);\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<Option\n\t\t\t\t\t\t\t\tkey={getKey ? getKey(option, index) : index}\n\t\t\t\t\t\t\t\tid={`${listId}-option-${index}`}\n\t\t\t\t\t\t\t\trole=\"option\"\n\t\t\t\t\t\t\t\taria-selected={selected}\n\t\t\t\t\t\t\t\taria-disabled={optionDisabled}\n\t\t\t\t\t\t\t\tdisabled={optionDisabled}\n\t\t\t\t\t\t\t\tactive={active}\n\t\t\t\t\t\t\t\tselected={selected}>\n\t\t\t\t\t\t\t\t{renderItem ? (\n\t\t\t\t\t\t\t\t\t<CustomOptionButton tabIndex={-1} disabled={optionDisabled} onMouseDown={handleMouseDown}>\n\t\t\t\t\t\t\t\t\t\t{renderItem(option, selected, active)}\n\t\t\t\t\t\t\t\t\t</CustomOptionButton>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<OptionButton\n\t\t\t\t\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\t\t\t\t\tdisabled={optionDisabled}\n\t\t\t\t\t\t\t\t\t\tonMouseDown={handleMouseDown}\n\t\t\t\t\t\t\t\t\t\ticon={selected ? <CheckIcon /> : <span />}\n\t\t\t\t\t\t\t\t\t\ttext={option.label ?? String(option.value)}\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</Option>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</PickerOptions>\n\t\t\t)}\n\t\t</PickerField>\n\t);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/listbox/Listbox.tsx"],"sourcesContent":["import {\n\ttype HTMLAttributes,\n\ttype JSX,\n\ttype KeyboardEvent,\n\ttype MouseEvent,\n\ttype ReactNode,\n\tuseEffect,\n\tuseLayoutEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState\n} from \"react\";\n\nimport {\n\tfindFirstEnabledIndex,\n\tfindLastEnabledIndex,\n\tfindNextEnabledIndex,\n\thandleKeyboardActivation\n} from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { CheckIcon } from \"lucide-react\";\n\nimport { CustomOptionButton, Option, OptionButton } from \"../option\";\nimport { PickerField, PickerOptions } from \"../picker\";\nimport { UiBaseProps } from \"../types\";\n\ntype ListboxOption<T> = {\n\tvalue: T;\n\tlabel?: string;\n\tdisabled?: boolean;\n};\n\n/**\n * Общие свойства Listbox берутся из UiBaseProps, чтобы подпись, состояние и\n * размер поля оставались согласованными с остальными контролами библиотеки.\n */\ninterface ListboxBaseProps<T>\n\textends\n\t\tOmit<UiBaseProps<T>, \"value\" | \"onChange\" | \"placeholder\">,\n\t\tOmit<HTMLAttributes<HTMLDivElement>, \"onChange\" | \"defaultValue\" | \"value\"> {\n\toptions: ListboxOption<T>[];\n\tfocusOnMount?: boolean;\n\trenderItem?: (option: ListboxOption<T>, selected: boolean, active: boolean) => ReactNode;\n\tgetKey?: (option: ListboxOption<T>, index: number) => string;\n}\n\n// Вариант для single-select\ninterface ListboxSingleProps<T> extends ListboxBaseProps<T> {\n\tmultiple?: false;\n\tvalue?: T;\n\tdefaultValue?: T;\n\tonChange?: (value: T, option: ListboxOption<T>) => void;\n}\n\n// Вариант для multi-select\ninterface ListboxMultiProps<T> extends ListboxBaseProps<T> {\n\tmultiple: true;\n\tvalue?: T[];\n\tdefaultValue?: T[];\n\tonChange?: (value: T[], option: ListboxOption<T>) => void;\n}\n\ntype ListboxProps<T> = ListboxSingleProps<T> | ListboxMultiProps<T>;\n\nconst isOptionDisabled = <T,>(option: ListboxOption<T>) => option.disabled === true;\n\nfunction getInitialFocusIndex<T>(options: ListboxOption<T>[], value: T | T[] | undefined, multiple: boolean | undefined) {\n\tif (multiple) {\n\t\tif (Array.isArray(value) && value.length > 0) {\n\t\t\tconst selectedIndex = options.findIndex((option) => value.includes(option.value) && !option.disabled);\n\t\t\tif (selectedIndex >= 0) {\n\t\t\t\treturn selectedIndex;\n\t\t\t}\n\t\t}\n\n\t\treturn findFirstEnabledIndex(options, isOptionDisabled);\n\t}\n\n\tif (value !== undefined) {\n\t\tconst selectedIndex = options.findIndex((option) => option.value === value && !option.disabled);\n\t\tif (selectedIndex >= 0) {\n\t\t\treturn selectedIndex;\n\t\t}\n\t}\n\n\treturn findFirstEnabledIndex(options, isOptionDisabled);\n}\n\n/**\n * Компонент выбора одного или нескольких элементов из списка. Поддерживает controlled API, поиск по данным и рендер кастомных опций.\n */\nexport function Listbox<T>(props: ListboxSingleProps<T>): JSX.Element;\nexport function Listbox<T>(props: ListboxMultiProps<T>): JSX.Element;\nexport function Listbox<T>(props: ListboxProps<T>): JSX.Element {\n\tconst {\n\t\tvalue,\n\t\tdefaultValue,\n\t\tmultiple,\n\t\tlabel,\n\t\tdescription,\n\t\tdisabled,\n\t\tsize,\n\t\tfocusOnMount,\n\t\trenderItem,\n\t\tgetKey,\n\t\toptions,\n\t\tonChange,\n\t\tid: externalId,\n\t\t...rest\n\t} = props;\n\n\tconst isControlled = value !== undefined;\n\tconst [internalValue, setInternalValue] = useState<T | T[] | undefined>(defaultValue);\n\tconst listRef = useRef<HTMLDivElement>(null);\n\tconst [focusedIndex, setFocusedIndex] = useState(() => getInitialFocusIndex(options, value ?? defaultValue, multiple));\n\t/**\n\t * Прокрутка нужна только после клавиатурной навигации. Это не даёт монтированию и Fast Refresh\n\t * вызывать scrollIntoView, который иначе прокручивает внешнюю страницу до Listbox.\n\t */\n\tconst shouldScrollActiveOptionRef = useRef(false);\n\n\tconst selectedValues = useMemo(\n\t\t() => (isControlled ? value : internalValue) ?? (multiple ? [] : null),\n\t\t[internalValue, isControlled, multiple, value]\n\t);\n\tconst activeIndex = focusedIndex;\n\n\tconst handleSelect = (option: ListboxOption<T>) => {\n\t\tif (disabled || option.disabled) return;\n\n\t\tif (multiple) {\n\t\t\tconst arr = Array.isArray(selectedValues) ? selectedValues : [];\n\t\t\tconst newValue = arr.includes(option.value) ? arr.filter((v) => v !== option.value) : [...arr, option.value];\n\n\t\t\tonChange?.(newValue, option);\n\t\t\tif (!isControlled) setInternalValue(newValue);\n\t\t\treturn;\n\t\t}\n\n\t\tonChange?.(option.value, option);\n\n\t\tif (!isControlled) setInternalValue(option.value);\n\t};\n\n\tconst handleKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n\t\tif (disabled) return;\n\n\t\tif (e.key === \"ArrowDown\") {\n\t\t\te.preventDefault();\n\t\t\tshouldScrollActiveOptionRef.current = true;\n\t\t\t// setHoveredIndex(null);\n\t\t\tsetFocusedIndex((index) => findNextEnabledIndex(options, index, 1, isOptionDisabled));\n\t\t} else if (e.key === \"ArrowUp\") {\n\t\t\te.preventDefault();\n\t\t\tshouldScrollActiveOptionRef.current = true;\n\t\t\t// setHoveredIndex(null);\n\t\t\tsetFocusedIndex((index) => findNextEnabledIndex(options, index, -1, isOptionDisabled));\n\t\t} else if (e.key === \"Home\") {\n\t\t\te.preventDefault();\n\t\t\tshouldScrollActiveOptionRef.current = true;\n\t\t\t// setHoveredIndex(null);\n\t\t\tsetFocusedIndex(findFirstEnabledIndex(options, isOptionDisabled));\n\t\t} else if (e.key === \"End\") {\n\t\t\te.preventDefault();\n\t\t\tshouldScrollActiveOptionRef.current = true;\n\t\t\t// setHoveredIndex(null);\n\t\t\tsetFocusedIndex(findLastEnabledIndex(options, isOptionDisabled));\n\t\t} else if (\n\t\t\thandleKeyboardActivation(e, () => {\n\t\t\t\tconst activeOption = options[activeIndex];\n\t\t\t\tif (activeOption) {\n\t\t\t\t\thandleSelect(activeOption);\n\t\t\t\t}\n\t\t\t})\n\t\t) {\n\t\t\treturn;\n\t\t}\n\t};\n\n\tuseEffect(() => {\n\t\tif (!shouldScrollActiveOptionRef.current) return;\n\n\t\tshouldScrollActiveOptionRef.current = false;\n\t\tconst el = listRef.current?.querySelectorAll<HTMLElement>('[role=\"option\"]')[activeIndex];\n\t\tif (el) el.scrollIntoView({ block: \"nearest\" });\n\t}, [activeIndex]);\n\n\tuseLayoutEffect(() => {\n\t\tif (focusOnMount) {\n\t\t\tlistRef.current?.focus();\n\t\t}\n\t}, [focusOnMount]);\n\n\treturn (\n\t\t<PickerField id={externalId} label={label} description={description} disabled={disabled} size={size}>\n\t\t\t{({ controlId: listId, labelId, describedBy }) => (\n\t\t\t\t<PickerOptions\n\t\t\t\t\trootRef={listRef}\n\t\t\t\t\tid={listId}\n\t\t\t\t\trole=\"listbox\"\n\t\t\t\t\taria-multiselectable={multiple || undefined}\n\t\t\t\t\taria-activedescendant={activeIndex >= 0 ? `${listId}-option-${activeIndex}` : undefined}\n\t\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\t\t{...rest}\n\t\t\t\t\taria-labelledby={labelId ?? rest[\"aria-labelledby\"]}\n\t\t\t\t\taria-describedby={describedBy ?? rest[\"aria-describedby\"]}\n\t\t\t\t\taria-disabled={disabled || undefined}\n\t\t\t\t\ttabIndex={disabled ? -1 : 0}\n\t\t\t\t\tclassName={rest.className}>\n\t\t\t\t\t{options.map((option, index) => {\n\t\t\t\t\t\tconst selected = multiple\n\t\t\t\t\t\t\t? Array.isArray(selectedValues) && selectedValues.includes(option.value)\n\t\t\t\t\t\t\t: selectedValues === option.value;\n\t\t\t\t\t\tconst active = index === activeIndex;\n\t\t\t\t\t\tconst optionDisabled = disabled || option.disabled || undefined;\n\n\t\t\t\t\t\tconst handleMouseDown = (e: MouseEvent<HTMLButtonElement>) => {\n\t\t\t\t\t\t\te.preventDefault(); // чтобы не сбрасывался фокус listbox\n\t\t\t\t\t\t\tif (optionDisabled) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsetFocusedIndex(index);\n\t\t\t\t\t\t\thandleSelect(option);\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<Option\n\t\t\t\t\t\t\t\tkey={getKey ? getKey(option, index) : index}\n\t\t\t\t\t\t\t\tid={`${listId}-option-${index}`}\n\t\t\t\t\t\t\t\trole=\"option\"\n\t\t\t\t\t\t\t\taria-selected={selected}\n\t\t\t\t\t\t\t\taria-disabled={optionDisabled}\n\t\t\t\t\t\t\t\tdisabled={optionDisabled}\n\t\t\t\t\t\t\t\tactive={active}\n\t\t\t\t\t\t\t\tselected={selected}>\n\t\t\t\t\t\t\t\t{renderItem ? (\n\t\t\t\t\t\t\t\t\t<CustomOptionButton tabIndex={-1} disabled={optionDisabled} onMouseDown={handleMouseDown}>\n\t\t\t\t\t\t\t\t\t\t{renderItem(option, selected, active)}\n\t\t\t\t\t\t\t\t\t</CustomOptionButton>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<OptionButton\n\t\t\t\t\t\t\t\t\t\ttabIndex={-1}\n\t\t\t\t\t\t\t\t\t\tdisabled={optionDisabled}\n\t\t\t\t\t\t\t\t\t\tonMouseDown={handleMouseDown}\n\t\t\t\t\t\t\t\t\t\ticon={selected ? <CheckIcon /> : <span />}\n\t\t\t\t\t\t\t\t\t\ttext={option.label ?? String(option.value)}\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</Option>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</PickerOptions>\n\t\t\t)}\n\t\t</PickerField>\n\t);\n}\n"],"mappings":"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"}