@ryuzaki13/react-foundation-ui 1.4.1 → 1.4.3

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 (509) hide show
  1. package/dist/advanced-search/index.js +12 -11
  2. package/dist/advanced-search/index.js.map +1 -1
  3. package/dist/badge/index.js +1 -1
  4. package/dist/base-table/index.js +2 -2
  5. package/dist/button/index.js +1 -1
  6. package/dist/chunks/{CalendarView-KCkhCtK-.js → CalendarView-Z_XWk7aI.js} +8 -8
  7. package/dist/chunks/{CalendarView-KCkhCtK-.js.map → CalendarView-Z_XWk7aI.js.map} +1 -1
  8. package/dist/chunks/{ImageViewerRuntime-RN49by8Y.js → ImageViewerRuntime-BMs3BBkV.js} +4 -4
  9. package/dist/chunks/{ImageViewerRuntime-RN49by8Y.js.map → ImageViewerRuntime-BMs3BBkV.js.map} +1 -1
  10. package/dist/chunks/{TextEditorLexicalClient-CVTrglWP.js → TextEditorLexicalClient-CK8j3RA4.js} +16 -18
  11. package/dist/chunks/{TextEditorLexicalClient-CVTrglWP.js.map → TextEditorLexicalClient-CK8j3RA4.js.map} +1 -1
  12. package/dist/chunks/{badge-Cri0-kVK.js → badge-DwIUjH0a.js} +2 -2
  13. package/dist/chunks/{badge-Cri0-kVK.js.map → badge-DwIUjH0a.js.map} +1 -1
  14. package/dist/chunks/{base-table-D5IqsjQD.js → base-table-BFsVwXg3.js} +13 -12
  15. package/dist/chunks/{base-table-D5IqsjQD.js.map → base-table-BFsVwXg3.js.map} +1 -1
  16. package/dist/chunks/{button-CC0Jdx1j.js → button-BU2kRzwu.js} +2 -2
  17. package/dist/chunks/button-BU2kRzwu.js.map +1 -0
  18. package/dist/chunks/check-box-Dd3YFuxd.js.map +1 -1
  19. package/dist/chunks/{context-menu-DQeR3y7M.js → context-menu-C6RO7soI.js} +7 -2
  20. package/dist/chunks/{context-menu-DQeR3y7M.js.map → context-menu-C6RO7soI.js.map} +1 -1
  21. package/dist/chunks/{date-input-DBJisPRz.js → date-input-BzExUQnc.js} +5 -5
  22. package/dist/chunks/{date-input-DBJisPRz.js.map → date-input-BzExUQnc.js.map} +1 -1
  23. package/dist/chunks/{flex-DYZ0IbU6.js → flex-C7njxZ74.js} +10 -7
  24. package/dist/chunks/{flex-DYZ0IbU6.js.map → flex-C7njxZ74.js.map} +1 -1
  25. package/dist/chunks/floating-arrow-BE-z4QkE.js.map +1 -1
  26. package/dist/chunks/{input-BCJfUdK_.js → input-Bp6_Ucgr.js} +15 -15
  27. package/dist/chunks/{input-BCJfUdK_.js.map → input-Bp6_Ucgr.js.map} +1 -1
  28. package/dist/chunks/{input-files-Dcc5K-_1.js → input-files-D1JzSw_Y.js} +2 -2
  29. package/dist/chunks/{input-files-Dcc5K-_1.js.map → input-files-D1JzSw_Y.js.map} +1 -1
  30. package/dist/chunks/{input-search-B7HmrAM7.js → input-search-Bkhcinru.js} +2 -2
  31. package/dist/chunks/{input-search-B7HmrAM7.js.map → input-search-Bkhcinru.js.map} +1 -1
  32. package/dist/chunks/{misc-DIF5h9ba.js → misc-BYxxlJz6.js} +3 -3
  33. package/dist/chunks/{misc-DIF5h9ba.js.map → misc-BYxxlJz6.js.map} +1 -1
  34. package/dist/chunks/{modal-DXHX_sA-.js → modal-paexEF0j.js} +4 -5
  35. package/dist/chunks/{modal-DXHX_sA-.js.map → modal-paexEF0j.js.map} +1 -1
  36. package/dist/chunks/{multi-select-CWx12rgb.js → multi-select-COa6-owj.js} +3 -3
  37. package/dist/chunks/{multi-select-CWx12rgb.js.map → multi-select-COa6-owj.js.map} +1 -1
  38. package/dist/chunks/{picker-BAQ9NeHe.js → picker-e6IsrMUG.js} +3 -3
  39. package/dist/chunks/{picker-BAQ9NeHe.js.map → picker-e6IsrMUG.js.map} +1 -1
  40. package/dist/chunks/{popover-xJJqy1v6.js → popover-CGU3MlsH.js} +14 -14
  41. package/dist/chunks/{popover-xJJqy1v6.js.map → popover-CGU3MlsH.js.map} +1 -1
  42. package/dist/chunks/radio-group-CM9Lg_nc.js.map +1 -1
  43. package/dist/chunks/{select-BPb-eL3O.js → select-C95db02j.js} +32 -31
  44. package/dist/chunks/{select-BPb-eL3O.js.map → select-C95db02j.js.map} +1 -1
  45. package/dist/chunks/sortable-DcTIAbjD.js.map +1 -1
  46. package/dist/chunks/{table-xMAjqtcY.js → table-Dd5BcC0k.js} +3 -3
  47. package/dist/chunks/{table-xMAjqtcY.js.map → table-Dd5BcC0k.js.map} +1 -1
  48. package/dist/chunks/{table-column-interactions-BGd5Lwy9.js → table-column-interactions-DzEvVuXe.js} +8 -5
  49. package/dist/chunks/{table-column-interactions-BGd5Lwy9.js.map → table-column-interactions-DzEvVuXe.js.map} +1 -1
  50. package/dist/chunks/useODataSelectBase-CKe1AVMI.js.map +1 -1
  51. package/dist/chunks/wheel-picker-FS58cRsQ.js.map +1 -1
  52. package/dist/context-menu/index.js +1 -1
  53. package/dist/date-input/index.js +2 -2
  54. package/dist/date-time-input/index.js +4 -4
  55. package/dist/date-time-input/index.js.map +1 -1
  56. package/dist/detail/index.js.map +1 -1
  57. package/dist/dialog/index.js.map +1 -1
  58. package/dist/disclosure/index.js +1 -1
  59. package/dist/disclosure/index.js.map +1 -1
  60. package/dist/drop-zone/index.js +1 -1
  61. package/dist/drop-zone/index.js.map +1 -1
  62. package/dist/errors/index.js +1 -1
  63. package/dist/errors/index.js.map +1 -1
  64. package/dist/expandable-action-panel/index.js +2 -2
  65. package/dist/expandable-action-panel/index.js.map +1 -1
  66. package/dist/flex/index.js +1 -1
  67. package/dist/fullscreen-portal/index.js +3 -3
  68. package/dist/fullscreen-portal/index.js.map +1 -1
  69. package/dist/image/index.js +5 -5
  70. package/dist/image/index.js.map +1 -1
  71. package/dist/input/index.js +1 -1
  72. package/dist/input-date-time/index.js +1 -1
  73. package/dist/input-date-time/index.js.map +1 -1
  74. package/dist/input-file/index.js +1 -1
  75. package/dist/input-file/index.js.map +1 -1
  76. package/dist/input-files/index.js +1 -1
  77. package/dist/input-image/index.js +1 -1
  78. package/dist/input-image/index.js.map +1 -1
  79. package/dist/input-search/index.js +1 -1
  80. package/dist/layout-picker/index.js +3 -3
  81. package/dist/layout-picker/index.js.map +1 -1
  82. package/dist/list/index.js +7 -7
  83. package/dist/list/index.js.map +1 -1
  84. package/dist/listbox/index.js.map +1 -1
  85. package/dist/misc/index.js +1 -1
  86. package/dist/modal/index.js +1 -1
  87. package/dist/multi-select/index.js +1 -1
  88. package/dist/notifications/index.js +13 -11
  89. package/dist/notifications/index.js.map +1 -1
  90. package/dist/pages/index.js.map +1 -1
  91. package/dist/panel/index.js.map +1 -1
  92. package/dist/picker/index.js +1 -1
  93. package/dist/popover/index.js +1 -1
  94. package/dist/preset-range-date-input/index.js +2 -2
  95. package/dist/preset-range-date-input/index.js.map +1 -1
  96. package/dist/preset-select/index.js +1 -1
  97. package/dist/radio-button/index.js.map +1 -1
  98. package/dist/select/index.js +1 -1
  99. package/dist/simple-table/index.js +1 -1
  100. package/dist/slider/index.js +27 -24
  101. package/dist/slider/index.js.map +1 -1
  102. package/dist/splitter/index.js.map +1 -1
  103. package/dist/state-select/index.js +12 -10
  104. package/dist/state-select/index.js.map +1 -1
  105. package/dist/styles.css +1 -1
  106. package/dist/switch/index.js +1 -1
  107. package/dist/switch/index.js.map +1 -1
  108. package/dist/table/index.js +1 -1
  109. package/dist/table-column-interactions/index.js +1 -1
  110. package/dist/table-sorting/index.js +1 -1
  111. package/dist/table-sorting/index.js.map +1 -1
  112. package/dist/tabs/index.js +6 -6
  113. package/dist/tabs/index.js.map +1 -1
  114. package/dist/tag-input/index.js +1 -1
  115. package/dist/tag-input/index.js.map +1 -1
  116. package/dist/text/index.js +10 -8
  117. package/dist/text/index.js.map +1 -1
  118. package/dist/text-editor/index.js +2 -2
  119. package/dist/textarea/index.js +1 -1
  120. package/dist/textarea/index.js.map +1 -1
  121. package/dist/toggle/index.js.map +1 -1
  122. package/dist/toolbar/index.js +1 -2
  123. package/dist/toolbar/index.js.map +1 -1
  124. package/dist/tree/index.js.map +1 -1
  125. package/dist/tree-select/index.js +83 -80
  126. package/dist/tree-select/index.js.map +1 -1
  127. package/dist/tree-table/index.js +2 -2
  128. package/dist/tree-table/index.js.map +1 -1
  129. package/package.json +51 -59
  130. package/storybook-static/assets/{Badge-DrS-PqPt.js → Badge-DHexWW92.js} +11 -11
  131. package/storybook-static/assets/Badge.stories-CeWDekpP.js +54 -0
  132. package/storybook-static/assets/Button-DtU4kGzD.css +1 -0
  133. package/storybook-static/assets/Button-VdPdxcvG.js +12 -0
  134. package/storybook-static/assets/{Button-CIC4xzqW.js → Button-kybsFNS9.js} +10 -10
  135. package/storybook-static/assets/Button.stories-DhgYDM_q.js +75 -0
  136. package/storybook-static/assets/{DateInput-BfFTwd_P.css → CalendarView-DKvrkS40.css} +1 -1
  137. package/storybook-static/assets/CalendarView-DTX0eO8t.js +1 -0
  138. package/storybook-static/assets/CheckBox-B6rTemHK.js +2 -0
  139. package/storybook-static/assets/{CheckBox-B2HRisgL.js → CheckBox-CDwboiFD.js} +11 -11
  140. package/storybook-static/assets/CheckBox.module-BBzuj5He.js +1 -0
  141. package/storybook-static/assets/CheckBox.stories-BSMihxpY.js +60 -0
  142. package/storybook-static/assets/Color-6AOWCN3U-D5F38IUU.js +1 -0
  143. package/storybook-static/assets/{ContextMenu-BH2hpaXG.js → ContextMenu-2ZQAeo_p.js} +9 -9
  144. package/storybook-static/assets/ContextMenu-CQtvL8kx.js +1 -0
  145. package/storybook-static/assets/ContextMenu.stories-Dtz2YIGk.js +90 -0
  146. package/storybook-static/assets/{DateInput-DCJw3t_Z.js → DateInput-D41aWZ7_.js} +11 -11
  147. package/storybook-static/assets/DateInput-DBwgBhFj.js +1 -0
  148. package/storybook-static/assets/DateInput-pmGiwdvw.css +1 -0
  149. package/storybook-static/assets/{DateInput.stories-BG4-DoSj.js → DateInput.stories-CMV96t-8.js} +2 -2
  150. package/storybook-static/assets/{DateRangePresetSelect-KLRkhxJb.js → DateRangePresetSelect-BLKJkg8X.js} +8 -8
  151. package/storybook-static/assets/DateRangePresetSelect-DXYYFJJn.js +3 -0
  152. package/storybook-static/assets/DateRangePresetSelect.stories-BNtFx_iG.js +11 -0
  153. package/storybook-static/assets/{Detail-3XawxFBs.js → Detail-BHcGLZok.js} +11 -11
  154. package/storybook-static/assets/Detail.stories-C4smn8Uu.js +44 -0
  155. package/storybook-static/assets/{Dialog-CnolXXtD.js → Dialog-kji1ho-G.js} +9 -9
  156. package/storybook-static/assets/Dialog.stories-DYzrVcIT.js +31 -0
  157. package/storybook-static/assets/{Disclosure-BmQa9ejy.js → Disclosure-BVLfp53o.js} +10 -10
  158. package/storybook-static/assets/Disclosure.stories-DcV1pGCt.js +41 -0
  159. package/storybook-static/assets/DocsRenderer-JROSPFPF-CCwX0YiR.js +2 -0
  160. package/storybook-static/assets/{DropZone-BLqqXnAE.js → DropZone-6iWHt6C_.js} +10 -10
  161. package/storybook-static/assets/DropZone.stories-bASZNbD5.js +44 -0
  162. package/storybook-static/assets/ExpandableActionPanel.stories-CMMbHs_d.js +20 -0
  163. package/storybook-static/assets/{Flex-B1T5p8TC.js → Flex-BJViOwhH.js} +18 -18
  164. package/storybook-static/assets/Flex.stories-CI6DdxU7.js +300 -0
  165. package/storybook-static/assets/FlexContainer-LmZIdhq2.js +1 -0
  166. package/storybook-static/assets/FlexItem-vkDYa5tA.js +3 -0
  167. package/storybook-static/assets/FloatingPopover-CPLOruAY.js +1 -0
  168. package/storybook-static/assets/FloatingPopover-DC84VrV3.css +1 -0
  169. package/storybook-static/assets/FormattedTableCell-CV4yLuxl.js +18 -0
  170. package/storybook-static/assets/FormattedTableCell-CY3E21k8.css +1 -0
  171. package/storybook-static/assets/Grid-BCzygAqy.js +52 -0
  172. package/storybook-static/assets/{Grid-BNsFGran.js → Grid-CNEn2bRE.js} +18 -18
  173. package/storybook-static/assets/{Grid.stories-BtDwT-co.js → Grid.stories-qFo5E3qE.js} +2 -2
  174. package/storybook-static/assets/{Grid-DudjnKE7.js → GridContainer-qDguE1HS.js} +2 -53
  175. package/storybook-static/assets/ImageCropper.stories-BeQI7oKQ.js +115 -0
  176. package/storybook-static/assets/ImageRenderer-DK2ibQyr.js +2 -0
  177. package/storybook-static/assets/ImageRenderer.stories-C1T4ne0G.js +22 -0
  178. package/storybook-static/assets/ImageView.stories-D_Q-ZBtQ.js +9 -0
  179. package/storybook-static/assets/{ImageViewer.stories-CA-tcnt2.js → ImageViewer.stories-boombTJI.js} +5 -5
  180. package/storybook-static/assets/ImageViewerRuntime-D8KSESgf.js +51 -0
  181. package/storybook-static/assets/{Input-B6zekikL.js → Input-CGHba0oM.js} +11 -11
  182. package/storybook-static/assets/Input-DtOsW7ur.js +3 -0
  183. package/storybook-static/assets/Input.stories-C0qWd6SH.js +38 -0
  184. package/storybook-static/assets/{InputDateTime-EYsJkV-0.js → InputDateTime-CgYkmVYu.js} +11 -11
  185. package/storybook-static/assets/InputDateTime.stories-Brxo7Chn.js +35 -0
  186. package/storybook-static/assets/{InputFile-BizeGHyb.js → InputFile-Bsxafe88.js} +10 -10
  187. package/storybook-static/assets/InputFile.stories-BzEV7ybE.js +36 -0
  188. package/storybook-static/assets/{InputFiles-9tzXfyuT.js → InputFiles-KJFUsmSS.js} +10 -10
  189. package/storybook-static/assets/InputFiles.stories-ffjxiHSh.js +33 -0
  190. package/storybook-static/assets/InputFilesList-D6B5g99M.js +1 -0
  191. package/storybook-static/assets/{InputImage-uw3SMJNy.js → InputImage-Cd39V4Vc.js} +10 -10
  192. package/storybook-static/assets/InputImage.stories-n-tpY8OO.js +51 -0
  193. package/storybook-static/assets/{LayoutPicker-CeiyAZt7.js → LayoutPicker-CGQFfQk6.js} +13 -13
  194. package/storybook-static/assets/LayoutPicker.stories-xSL2qafC.js +449 -0
  195. package/storybook-static/assets/{Listbox-C-B_og6p.js → Listbox-CxISK8c5.js} +10 -10
  196. package/storybook-static/assets/Listbox.stories-BdQBmVFI.js +47 -0
  197. package/storybook-static/assets/{Modal-CsfpIg6C.js → Modal-BiaAWMdV.js} +12 -12
  198. package/storybook-static/assets/Modal.stories-GV7fGqyd.js +180 -0
  199. package/storybook-static/assets/MultiSelect-D5XFosSU.js +2 -0
  200. package/storybook-static/assets/{MultiSelect-Dt5HCrYP.js → MultiSelect-Df2CpyNH.js} +11 -11
  201. package/storybook-static/assets/MultiSelect.stories-BEVQF6hO.js +29 -0
  202. package/storybook-static/assets/MultiSelectToken-CrVawISu.js +1 -0
  203. package/storybook-static/assets/NoData-C7KqaHUh.css +1 -0
  204. package/storybook-static/assets/NoData-Fm23iF4n.js +1 -0
  205. package/storybook-static/assets/{NotificationsHost-CDI8mQh0.js → NotificationsHost-C2vSwAjz.js} +9 -9
  206. package/storybook-static/assets/NotificationsHost.stories-IbgayDlM.js +25 -0
  207. package/storybook-static/assets/{ODataMultiSelect-Bj1NtXx4.js → ODataMultiSelect-oW3kW0nO.js} +15 -15
  208. package/storybook-static/assets/ODataMultiSelect.stories-CP6_jGSr.js +73 -0
  209. package/storybook-static/assets/{ODataSelect-CalTWDdU.js → ODataSelect-CrGF8fyC.js} +15 -15
  210. package/storybook-static/assets/ODataSelect.stories-DTv31Rkv.js +73 -0
  211. package/storybook-static/assets/ODataTreeMultiSelect-D0h8H3gw.js +19 -0
  212. package/storybook-static/assets/ODataTreeMultiSelect.stories-CM8QjG8r.js +30 -0
  213. package/storybook-static/assets/ODataTreeSelect-PWn0-hI4.js +17 -0
  214. package/storybook-static/assets/ODataTreeSelect.stories-2UkFTnbE.js +24 -0
  215. package/storybook-static/assets/OneStepScroller-CH6K7wiO.js +5 -0
  216. package/storybook-static/assets/OneStepScroller-NRYd-egY.css +1 -0
  217. package/storybook-static/assets/{PeriodSelect--wEPFluW.js → PeriodSelect-BtwJuAO6.js} +13 -13
  218. package/storybook-static/assets/PeriodSelect.stories-BH8I5Wmg.js +64 -0
  219. package/storybook-static/assets/PickerSelectionToolbar-BcL8-O6n.js +2 -0
  220. package/storybook-static/assets/PickerTriggerActions-C8Asdp5e.js +1 -0
  221. package/storybook-static/assets/{Popover-CXlXO4Om.js → Popover-Ch5btFhR.js} +11 -11
  222. package/storybook-static/assets/Popover-DGX7JNNK.css +1 -0
  223. package/storybook-static/assets/Popover-Djns7yXR.js +2 -0
  224. package/storybook-static/assets/Popover.stories-Bask2I1I.js +69 -0
  225. package/storybook-static/assets/{PresetRangeDateInput-Ek_8-9jx.js → PresetRangeDateInput-DvsTjQNP.js} +8 -8
  226. package/storybook-static/assets/PresetRangeDateInput.stories-BNfOUWgp.js +15 -0
  227. package/storybook-static/assets/PresetSelect-9zitP0-V.js +5 -0
  228. package/storybook-static/assets/{RadioButton-CFyxweTk.js → RadioButton-Yb9bQKYe.js} +10 -10
  229. package/storybook-static/assets/RadioButton.stories-FIFxXFVP.js +36 -0
  230. package/storybook-static/assets/RadioGroup-CWsVqwtm.js +1 -0
  231. package/storybook-static/assets/{RadioGroup-BzgaB3tz.js → RadioGroup-Dn0zL838.js} +10 -10
  232. package/storybook-static/assets/RadioGroup.stories-B_drop9x.js +42 -0
  233. package/storybook-static/assets/Scrollable-3Z6b5g0Z.js +1 -0
  234. package/storybook-static/assets/{Select-CJTdiLLf.js → Select-BaR8D89E.js} +13 -13
  235. package/storybook-static/assets/Select-BiOxxy0y.js +12 -0
  236. package/storybook-static/assets/Select.stories-CMlWu7vC.js +46 -0
  237. package/storybook-static/assets/SelectOptionContent-DhtCMwz6.js +1 -0
  238. package/storybook-static/assets/{SerializableSelect-CsZnvsML.js → SerializableSelect-BDiZo_-M.js} +12 -12
  239. package/storybook-static/assets/SerializableSelect.stories-DgC6oiRx.js +46 -0
  240. package/storybook-static/assets/{SingleDateTimeInput-NGciSlUN.js → SingleDateTimeInput-Dx1fvzyr.js} +12 -12
  241. package/storybook-static/assets/SingleDateTimeInput.stories-NRUE7nnA.js +78 -0
  242. package/storybook-static/assets/Slider-DJpzPo7f.js +1 -0
  243. package/storybook-static/assets/{Slider-J-URo5p1.js → Slider-aiFcrSGY.js} +15 -15
  244. package/storybook-static/assets/Slider.stories-B0YHmFf5.js +77 -0
  245. package/storybook-static/assets/{SliderInput-D2IjNhE4.js → SliderInput-sOoxvdku.js} +16 -16
  246. package/storybook-static/assets/SliderInput.stories-BYk1V19Z.js +68 -0
  247. package/storybook-static/assets/{Sortable-Dut8-sKx.js → Sortable-CuVT40f8.js} +13 -13
  248. package/storybook-static/assets/Sortable.stories-KSWGoKrN.js +141 -0
  249. package/storybook-static/assets/{Splitter-Bid56cjA.js → Splitter-EoNOj4XF.js} +11 -11
  250. package/storybook-static/assets/Splitter.stories-CuAZab2y.js +22 -0
  251. package/storybook-static/assets/{StateSelect-C0z6JyBe.js → StateSelect-B_M50HZl.js} +10 -10
  252. package/storybook-static/assets/StateSelect.stories-DQ_MzvL4.js +47 -0
  253. package/storybook-static/assets/StringToggle.stories-BbRysCKA.js +6 -0
  254. package/storybook-static/assets/{Switch-Di-v9u1A.js → Switch-DO_tyZIc.js} +10 -10
  255. package/storybook-static/assets/Switch.stories-BQakMoPp.js +26 -0
  256. package/storybook-static/assets/{Table-DrsB0gBG.js → Table-CVK5rwmT.js} +22 -22
  257. package/storybook-static/assets/Table.stories-IZaleOjp.js +122 -0
  258. package/storybook-static/assets/{Tabs-DkY_hPxX.js → Tabs-DAaWUQb4.js} +15 -15
  259. package/storybook-static/assets/Tabs.stories-BC8LwG22.js +58 -0
  260. package/storybook-static/assets/TagInput.stories-CrXD57LV.js +18 -0
  261. package/storybook-static/assets/Text-cVBcGheg.js +1 -0
  262. package/storybook-static/assets/{Textarea-CwA3jBjr.js → Textarea-9VdIC6G0.js} +10 -10
  263. package/storybook-static/assets/Textarea.stories-CEaMwEau.js +27 -0
  264. package/storybook-static/assets/TimePanel-vx1aOwT4.js +1 -0
  265. package/storybook-static/assets/TimePanel.stories-BKyiLEgy.js +25 -0
  266. package/storybook-static/assets/Toggle-CyajrRVE.js +1 -0
  267. package/storybook-static/assets/{Toggle-Bo4KR3MN.js → Toggle-DrNoVpGe.js} +10 -10
  268. package/storybook-static/assets/Toggle.stories-CT0mQbdm.js +30 -0
  269. package/storybook-static/assets/TreeMultiSelect-CtDZ1cXU.js +1 -0
  270. package/storybook-static/assets/TreeMultiSelect-ag5i_Hw_.js +19 -0
  271. package/storybook-static/assets/TreeMultiSelect.stories-BxrbKopS.js +35 -0
  272. package/storybook-static/assets/TreePickerBase-DQzUtuAm.js +22 -0
  273. package/storybook-static/assets/TreeSelect-BNuJBo9x.js +1 -0
  274. package/storybook-static/assets/TreeSelect-CL8REXC5.js +16 -0
  275. package/storybook-static/assets/TreeSelect.stories-CsWGc9X0.js +18 -0
  276. package/storybook-static/assets/{TreeTable-rbcFU6RL.js → TreeTable-DrIFC4Oh.js} +22 -22
  277. package/storybook-static/assets/TreeTable.stories-Dq5c4_qe.js +83 -0
  278. package/storybook-static/assets/WithTooltip-7X4HQR7L-Cakt_JaX.js +9 -0
  279. package/storybook-static/assets/array-BBSjoTRy-CIRmlF93.js +1 -0
  280. package/storybook-static/assets/{async-DoYCd2O1.js → async-0-Te_uje.js} +3 -3
  281. package/storybook-static/assets/axe-Bq-2xuso.js +20 -0
  282. package/storybook-static/assets/blocks-Dz3dJBcm.js +48 -0
  283. package/storybook-static/assets/browserAndReact-kZBm3nQe.js +105 -0
  284. package/storybook-static/assets/check-BMyoSD8F.js +1 -0
  285. package/storybook-static/assets/chevron-down-QDFtnGcg.js +1 -0
  286. package/storybook-static/assets/chevron-left-BoVuWD4h.js +1 -0
  287. package/storybook-static/assets/chevron-right-DS62_o_9.js +1 -0
  288. package/storybook-static/assets/chunk-242VQQM5-BMWWiybC.js +1 -0
  289. package/storybook-static/assets/chunk-DRQKCCAG-CqE-Zrl9.js +1 -0
  290. package/storybook-static/assets/chunk-IMSF75WX-yvVUwIQZ.js +6 -0
  291. package/storybook-static/assets/chunk-KJHJLCBK-D-yQfkOi.js +1 -0
  292. package/storybook-static/assets/chunk-QQBDHPVZ-B98qboss.js +1 -0
  293. package/storybook-static/assets/chunk-W22LQPXL-DDIvKskF.js +18 -0
  294. package/storybook-static/assets/circle-alert-CXg50Gb0.js +1 -0
  295. package/storybook-static/assets/circle-check-BPfYNWmz.js +1 -0
  296. package/storybook-static/assets/components-BejapTpU.js +241 -0
  297. package/storybook-static/assets/contextMenu-DtXkMNr6.js +2 -0
  298. package/storybook-static/assets/date-segments-D3HouZ37.js +1 -0
  299. package/storybook-static/assets/dom-B3G_GtJw.js +1 -0
  300. package/storybook-static/assets/download-DnZ6jhvY.js +1 -0
  301. package/storybook-static/assets/error-BZrNlEUO.js +1 -0
  302. package/storybook-static/assets/file-vPGnhPr-.js +1 -0
  303. package/storybook-static/assets/filesAndExcel-CXMXtMjq.js +122 -0
  304. package/storybook-static/assets/floating-ui.react-PN45KvBS.js +1 -0
  305. package/storybook-static/assets/formatter-L2YTDE3Q-x0raBH34.js +1 -0
  306. package/storybook-static/assets/formatters--mhLir82-v41eaI4a.js +1 -0
  307. package/storybook-static/assets/formatters-DGXR8csR.js +291 -0
  308. package/storybook-static/assets/formatters-runtime-GsS-hTg9.js +384 -0
  309. package/storybook-static/assets/foundationLib-XrLbqi3r.js +82 -0
  310. package/storybook-static/assets/hooks-Ddmw7JMF.js +5 -0
  311. package/storybook-static/assets/iframe-CrnMVMTc.js +1151 -0
  312. package/storybook-static/assets/iframe-FUHzX0Mr.js +1 -0
  313. package/storybook-static/assets/info-Dqq5QHG7.js +1 -0
  314. package/storybook-static/assets/{matchers-JIUQ3HVY-BPS-eazD.js → matchers-JIUQ3HVY-DvR2XErZ.js} +3 -3
  315. package/storybook-static/assets/media-BycWpjAl.js +1 -0
  316. package/storybook-static/assets/odata-BaxgzNGj.js +1 -0
  317. package/storybook-static/assets/odata-service-DnPlNGpU-Bpd4Zh9L.js +3 -0
  318. package/storybook-static/assets/odataAndTables-OEVW-gFK.js +126 -0
  319. package/storybook-static/assets/{odataFetchFn-DDErUu7H.js → odataFetchFn-BLWeF0ZQ.js} +3 -3
  320. package/storybook-static/assets/odataStoryFixtures-BbswaX_5.js +25 -0
  321. package/storybook-static/assets/{persisted-DphnlPy-.js → persisted-BpFojVXw.js} +3 -3
  322. package/storybook-static/assets/preload-helper-BHmFeTtP.js +1 -0
  323. package/storybook-static/assets/pureUtilities-3afQk5ld.js +69 -0
  324. package/storybook-static/assets/react-18-CgkwBzTo.js +9 -0
  325. package/storybook-static/assets/react-C21x__mS.js +1 -0
  326. package/storybook-static/assets/react-CpOcCp9T.js +9 -0
  327. package/storybook-static/assets/react-CvkUhHUq.js +1 -0
  328. package/storybook-static/assets/react-dom-2o2phaJG.js +1 -0
  329. package/storybook-static/assets/react-qN2cStNd.js +1 -0
  330. package/storybook-static/assets/refresh-cw-B2VU4UNA.js +1 -0
  331. package/storybook-static/assets/rolldown-runtime-C0FnF6B9.js +1 -0
  332. package/storybook-static/assets/runtimeAndState-BEFDbOiZ.js +117 -0
  333. package/storybook-static/assets/settings-2-CLJhjWJl.js +1 -0
  334. package/storybook-static/assets/sortable-DW_Veba0.js +1 -0
  335. package/storybook-static/assets/syntaxhighlighter-T5IQBZDB-D0RhvxXU.js +6 -0
  336. package/storybook-static/assets/theming-mTWhffkp.js +39 -0
  337. package/storybook-static/assets/trash-2-yLqdtpz8.js +1 -0
  338. package/storybook-static/assets/treeStoryFixtures-Ci7STpiz.js +1 -0
  339. package/storybook-static/assets/triangle-alert-wI8Cd8tI.js +1 -0
  340. package/storybook-static/assets/ui.module-DoMIk8Oc.js +1 -0
  341. package/storybook-static/assets/uiClasses-CO3Cdv1E.js +1 -0
  342. package/storybook-static/assets/useFlexClasses-Gn9spXEB.js +1 -0
  343. package/storybook-static/assets/useODataSelectBase-WnxdcAM4.js +1 -0
  344. package/storybook-static/assets/useODataTreeData-C7L5TOjl.js +1 -0
  345. package/storybook-static/assets/usePickerDefaultFilter-DdxyE_i8.js +1 -0
  346. package/storybook-static/assets/usePickerQuery-CAWYFpCv.js +1 -0
  347. package/storybook-static/assets/usePickerTriggerController-BRXUlggw.js +1 -0
  348. package/storybook-static/assets/utils-DUM89eIj.js +1 -0
  349. package/storybook-static/assets/x-CyFk00QC.js +1 -0
  350. package/storybook-static/iframe.html +8 -3
  351. package/storybook-static/index.html +6 -0
  352. package/storybook-static/index.json +1 -1
  353. package/storybook-static/project.json +1 -1
  354. package/storybook-static/sb-addons/a11y-3/manager-bundle.js +3 -3
  355. package/storybook-static/sb-addons/chromatic-com-storybook-1/manager-bundle.js +17 -17
  356. package/storybook-static/sb-addons/docs-2/manager-bundle.js +16 -1
  357. package/storybook-static/sb-addons/storybook-core-server-presets-0/common-manager-bundle.js +85 -83
  358. package/storybook-static/sb-addons/vitest-4/manager-bundle.js +1 -1
  359. package/storybook-static/sb-manager/globals-runtime.js +9939 -7695
  360. package/storybook-static/sb-manager/runtime.js +16128 -15326
  361. package/storybook-static/vite-inject-mocker-entry.js +2 -2
  362. package/dist/chunks/button-CC0Jdx1j.js.map +0 -1
  363. package/storybook-static/assets/Badge.stories-DwBMjWuT.js +0 -51
  364. package/storybook-static/assets/Button-Dpi111u7.js +0 -12
  365. package/storybook-static/assets/Button-nI2z0h4X.css +0 -1
  366. package/storybook-static/assets/Button.stories-DZmRqHrE.js +0 -75
  367. package/storybook-static/assets/CheckBox-DHWs_MEe.js +0 -2
  368. package/storybook-static/assets/CheckBox.module-ezWPE2pa.js +0 -1
  369. package/storybook-static/assets/CheckBox.stories-ChxWTQwY.js +0 -60
  370. package/storybook-static/assets/Color-KMSTOMOX-Ct0gfrkd.js +0 -1
  371. package/storybook-static/assets/ContextMenu.stories-D8QOi68M.js +0 -90
  372. package/storybook-static/assets/DateInput-aifcbvnl.js +0 -1
  373. package/storybook-static/assets/DateRangePresetSelect-lWDa-_zo.js +0 -3
  374. package/storybook-static/assets/DateRangePresetSelect.stories-DyxuSPt4.js +0 -11
  375. package/storybook-static/assets/Detail.stories-r0AG6eiC.js +0 -44
  376. package/storybook-static/assets/Dialog.stories-DyLAEjua.js +0 -31
  377. package/storybook-static/assets/Disclosure.stories-DHFMH6SZ.js +0 -41
  378. package/storybook-static/assets/DocsRenderer-JROSPFPF-OVZNUiiY.js +0 -2
  379. package/storybook-static/assets/DropZone.stories-C6iXDzpC.js +0 -44
  380. package/storybook-static/assets/DropdownMenu-BPIWC5Fe.js +0 -1
  381. package/storybook-static/assets/ExpandableActionPanel.stories-DeBP2SL6.js +0 -20
  382. package/storybook-static/assets/Flex-BvUI9OtR.js +0 -3
  383. package/storybook-static/assets/Flex.stories-DjHfItG6.js +0 -300
  384. package/storybook-static/assets/ImageCropper.stories-D1ZTKaL2.js +0 -115
  385. package/storybook-static/assets/ImageRenderer-C_UGYN2n.js +0 -2
  386. package/storybook-static/assets/ImageRenderer.stories-BRm7cNQQ.js +0 -22
  387. package/storybook-static/assets/ImageView.stories-DbPfP9Vk.js +0 -9
  388. package/storybook-static/assets/ImageViewerRuntime-FOJk41Ia.js +0 -51
  389. package/storybook-static/assets/Input-Cd3vgy0g.js +0 -3
  390. package/storybook-static/assets/Input.stories-DdEsalmK.js +0 -38
  391. package/storybook-static/assets/InputDateTime.stories-CWRMF1Uz.js +0 -35
  392. package/storybook-static/assets/InputFile.stories-DSMEa0Hb.js +0 -36
  393. package/storybook-static/assets/InputFiles-CL38ESTc.js +0 -1
  394. package/storybook-static/assets/InputFiles.stories-Baq4MwqA.js +0 -33
  395. package/storybook-static/assets/InputImage.stories-CosbCY9j.js +0 -51
  396. package/storybook-static/assets/LayoutPicker.stories-Dyqys3DQ.js +0 -449
  397. package/storybook-static/assets/Listbox.stories-YIJrMp0t.js +0 -47
  398. package/storybook-static/assets/Modal.stories-BFDuVpN3.js +0 -180
  399. package/storybook-static/assets/MultiSelect-DY6u4L61.js +0 -2
  400. package/storybook-static/assets/MultiSelect.stories-bYuh54Fu.js +0 -29
  401. package/storybook-static/assets/NotificationsHost.stories-DYvkJ2cU.js +0 -25
  402. package/storybook-static/assets/ODataMultiSelect-dD4o0805.js +0 -1
  403. package/storybook-static/assets/ODataMultiSelect.stories-BS2NR6_9.js +0 -73
  404. package/storybook-static/assets/ODataSelect-BggbU-2c.js +0 -1
  405. package/storybook-static/assets/ODataSelect.stories-vTrv4d9z.js +0 -73
  406. package/storybook-static/assets/ODataTreeMultiSelect-CMhyGXwM.js +0 -19
  407. package/storybook-static/assets/ODataTreeMultiSelect.stories-BZ-NN4dI.js +0 -30
  408. package/storybook-static/assets/ODataTreeSelect-mJe6gYMX.js +0 -17
  409. package/storybook-static/assets/ODataTreeSelect.stories-DhSjFMeQ.js +0 -24
  410. package/storybook-static/assets/PeriodSelect.stories-CZUB8olq.js +0 -64
  411. package/storybook-static/assets/Popover.stories-DpZzhK2O.js +0 -69
  412. package/storybook-static/assets/PresetRangeDateInput.stories-qn-B1IOD.js +0 -15
  413. package/storybook-static/assets/RadioButton.stories-DwNfCMGS.js +0 -36
  414. package/storybook-static/assets/RadioGroup-DE_bpBiS.js +0 -1
  415. package/storybook-static/assets/RadioGroup.stories-DVqgV_4W.js +0 -42
  416. package/storybook-static/assets/Select-CelCWR4u.js +0 -12
  417. package/storybook-static/assets/Select.stories-Cgw1rh4h.js +0 -46
  418. package/storybook-static/assets/SelectOptionContent-Bjy9USsA.js +0 -1
  419. package/storybook-static/assets/SerializableSelect-D8YCGkPD.js +0 -4
  420. package/storybook-static/assets/SerializableSelect.stories-R2stgrdq.js +0 -43
  421. package/storybook-static/assets/SingleDateTimeInput.stories-CBsxKb4w.js +0 -78
  422. package/storybook-static/assets/Slider.stories-BCpR-FX3.js +0 -77
  423. package/storybook-static/assets/SliderInput.stories-56IQYe6a.js +0 -67
  424. package/storybook-static/assets/Sortable.stories-DUCcvgKr.js +0 -141
  425. package/storybook-static/assets/Splitter.stories-D4odwrXg.js +0 -22
  426. package/storybook-static/assets/StateSelect.stories-DXdcVPG0.js +0 -47
  427. package/storybook-static/assets/StringToggle.stories-C8RhgIJd.js +0 -6
  428. package/storybook-static/assets/Switch.stories-Cfkb4wPd.js +0 -26
  429. package/storybook-static/assets/Table.stories-C24_nZ5H.js +0 -122
  430. package/storybook-static/assets/Tabs.stories-CicNE4cs.js +0 -58
  431. package/storybook-static/assets/TagInput.stories-C3766Yv0.js +0 -18
  432. package/storybook-static/assets/Textarea.stories-CrRB7fzB.js +0 -27
  433. package/storybook-static/assets/TimePanel-DoveAQla.js +0 -1
  434. package/storybook-static/assets/TimePanel.stories-D2vUL6s0.js +0 -25
  435. package/storybook-static/assets/Toggle-ClOUAjaj.js +0 -1
  436. package/storybook-static/assets/Toggle.stories-Dnt25rG3.js +0 -30
  437. package/storybook-static/assets/TreeMultiSelect-CPtnpliv.js +0 -19
  438. package/storybook-static/assets/TreeMultiSelect-DE3AQOZl.js +0 -1
  439. package/storybook-static/assets/TreeMultiSelect.stories-BVo2A9HK.js +0 -35
  440. package/storybook-static/assets/TreePickerBase-DiMmn5I3.js +0 -22
  441. package/storybook-static/assets/TreeSelect-Cs_tb930.js +0 -1
  442. package/storybook-static/assets/TreeSelect-JTI9tQ4C.js +0 -16
  443. package/storybook-static/assets/TreeSelect.stories-C6Gm2YfT.js +0 -18
  444. package/storybook-static/assets/TreeTable.stories-CXJMSxQu.js +0 -83
  445. package/storybook-static/assets/WithTooltip-7X4HQR7L-DVJE2Dqb.js +0 -9
  446. package/storybook-static/assets/axe-GLfyhAYL.js +0 -20
  447. package/storybook-static/assets/base-table-BNO0lnTL.css +0 -1
  448. package/storybook-static/assets/base-table-_WBb2IZM.js +0 -18
  449. package/storybook-static/assets/blocks-kCueRzKM.js +0 -285
  450. package/storybook-static/assets/button-BfP43NV5.js +0 -1
  451. package/storybook-static/assets/check-box-jgZW0_tB.js +0 -1
  452. package/storybook-static/assets/chunk-242VQQM5-Dtm7LRbQ.js +0 -1
  453. package/storybook-static/assets/chunk-3LY4VQVK-DgbtId2R.js +0 -6
  454. package/storybook-static/assets/chunk-LITCR56V-C-pEySCh.js +0 -18
  455. package/storybook-static/assets/contextMenu-BY8W9e2R.js +0 -2
  456. package/storybook-static/assets/date-CuKkMWak.js +0 -461
  457. package/storybook-static/assets/date-segments-CzU9k5bl.js +0 -1
  458. package/storybook-static/assets/error-BkkZrYYA.js +0 -1
  459. package/storybook-static/assets/file-CfhfQiKL.js +0 -291
  460. package/storybook-static/assets/file-hArYcyES.js +0 -1
  461. package/storybook-static/assets/flex-DYnuC3Jl.js +0 -1
  462. package/storybook-static/assets/floating-ui.react-fJcp4ywX.js +0 -1
  463. package/storybook-static/assets/formatter-L2YTDE3Q-CQmzS1Ku.js +0 -1
  464. package/storybook-static/assets/formatters-Bt3ef0VX.js +0 -3
  465. package/storybook-static/assets/formulas-C5ifYPhi.js +0 -2
  466. package/storybook-static/assets/grid-DLQc0tY5.js +0 -1
  467. package/storybook-static/assets/hooks-COY2kUuX.js +0 -5
  468. package/storybook-static/assets/iframe-CqfP7aF1.js +0 -1119
  469. package/storybook-static/assets/input-DNF627Va.js +0 -1
  470. package/storybook-static/assets/mdx-react-shim-4LHuzuKu.js +0 -1
  471. package/storybook-static/assets/media-CbWC9XZs.js +0 -1
  472. package/storybook-static/assets/misc-BElIqBdV.css +0 -1
  473. package/storybook-static/assets/misc-D0Mkvmw8.js +0 -5
  474. package/storybook-static/assets/notifications-CRagNLgf.js +0 -1
  475. package/storybook-static/assets/number-Da4Ulq9E.js +0 -2
  476. package/storybook-static/assets/odata-DUcjBQqp.js +0 -1
  477. package/storybook-static/assets/odata-service-Rl9UYgzA.js +0 -1
  478. package/storybook-static/assets/odataStoryFixtures-BY3DnLbL.js +0 -25
  479. package/storybook-static/assets/picker-D2lWKGk-.js +0 -2
  480. package/storybook-static/assets/popover-BiQHI7Wi.css +0 -1
  481. package/storybook-static/assets/popover-D7McA5RG.js +0 -2
  482. package/storybook-static/assets/preload-helper-B45gAKPr.js +0 -1
  483. package/storybook-static/assets/preset-select-FySDZYno.js +0 -5
  484. package/storybook-static/assets/pwa-QKsIz2U4.js +0 -640
  485. package/storybook-static/assets/queryClient-Cf_KN496.js +0 -567
  486. package/storybook-static/assets/react-18-Dyh2Pzaa.js +0 -9
  487. package/storybook-static/assets/react-BonvwE5R.js +0 -9
  488. package/storybook-static/assets/react-dom--kz57wTp.js +0 -1
  489. package/storybook-static/assets/select-DsPUjSXp.js +0 -1
  490. package/storybook-static/assets/slider-D93-bn3E.js +0 -2
  491. package/storybook-static/assets/sortable-B2Ihqi-W.js +0 -1
  492. package/storybook-static/assets/syntaxhighlighter-RTCFPKCB-Bh8qQ71X.js +0 -6
  493. package/storybook-static/assets/text-BCUxHWs4.js +0 -4
  494. package/storybook-static/assets/theming-KsQ_vHzM.js +0 -39
  495. package/storybook-static/assets/treeStoryFixtures-Y_nnjz0_.js +0 -1
  496. package/storybook-static/assets/ui-D39u6Dhv.js +0 -1
  497. package/storybook-static/assets/ui.module-wFHXkJzp.js +0 -1
  498. package/storybook-static/assets/uiClasses-CaHp0EWd.js +0 -1
  499. package/storybook-static/assets/useODataSelectBase-BWIM1yqH.js +0 -1
  500. package/storybook-static/assets/useODataTreeData-CnmOnxqb.js +0 -1
  501. package/storybook-static/assets/utils-BfYZ9Iv_.js +0 -1
  502. package/storybook-static/assets/valueState-CV4TgbM9.js +0 -277
  503. /package/storybook-static/assets/{DropdownMenu-BgzIzwzM.css → ContextMenu-BgzIzwzM.css} +0 -0
  504. /package/storybook-static/assets/{Grid-K9R_IHaw.css → GridContainer-K9R_IHaw.css} +0 -0
  505. /package/storybook-static/assets/{InputFiles-ByK52qUe.css → InputFilesList-ByK52qUe.css} +0 -0
  506. /package/storybook-static/assets/{MultiSelect-BoIwmje6.css → MultiSelectToken-BoIwmje6.css} +0 -0
  507. /package/storybook-static/assets/{slider-DMDFRH6B.css → Slider-DMDFRH6B.css} +0 -0
  508. /package/storybook-static/assets/{Flex-IXK2se1Y.css → useFlexClasses-IXK2se1Y.css} +0 -0
  509. /package/storybook-static/assets/{picker-DzBkX15M.css → usePickerTriggerController-DzBkX15M.css} +0 -0
@@ -1,14 +1,14 @@
1
1
  import { t as e } from "../chunks/ui.module-BisoTevy.js";
2
- import { n as t, t as n } from "../chunks/badge-Cri0-kVK.js";
3
- import { o as r } from "../chunks/flex-DYZ0IbU6.js";
4
- import { n as i } from "../chunks/button-CC0Jdx1j.js";
2
+ import { n as t, t as n } from "../chunks/badge-DwIUjH0a.js";
3
+ import { o as r } from "../chunks/flex-C7njxZ74.js";
4
+ import { n as i } from "../chunks/button-BU2kRzwu.js";
5
5
  import { r as a } from "../chunks/grid-dI94AAbi.js";
6
- import { l as o, u as s } from "../chunks/input-BCJfUdK_.js";
7
- import { t as c } from "../chunks/input-search-B7HmrAM7.js";
8
- import { c as l } from "../chunks/misc-DIF5h9ba.js";
9
- import { a as u, i as d, n as f, r as p } from "../chunks/modal-DXHX_sA-.js";
10
- import { n as m } from "../chunks/multi-select-CWx12rgb.js";
11
- import { t as h } from "../chunks/table-xMAjqtcY.js";
6
+ import { l as o, u as s } from "../chunks/input-Bp6_Ucgr.js";
7
+ import { t as c } from "../chunks/input-search-Bkhcinru.js";
8
+ import { c as l } from "../chunks/misc-BYxxlJz6.js";
9
+ import { a as u, i as d, n as f, r as p } from "../chunks/modal-paexEF0j.js";
10
+ import { n as m } from "../chunks/multi-select-COa6-owj.js";
11
+ import { t as h } from "../chunks/table-Dd5BcC0k.js";
12
12
  import { useCallback as g, useEffect as _, useMemo as v, useState as y } from "react";
13
13
  import { odataQueryFn as b, useODataTableColumns as x } from "@ryuzaki13/react-foundation-api/odata";
14
14
  import { createFilterContains as S, createFilterEqual as C, unwrapODataQueryResult as w } from "@ryuzaki13/react-foundation-lib/odata-service";
@@ -98,7 +98,7 @@ function I(e) {
98
98
  //#endregion
99
99
  //#region src/advanced-search/model/useAdvancedSearchInitialSelected.ts
100
100
  function L(e, t = []) {
101
- return w(E({
101
+ let n = E({
102
102
  queryKey: [
103
103
  "searchSelected",
104
104
  e.odata.service,
@@ -126,7 +126,8 @@ function L(e, t = []) {
126
126
  });
127
127
  },
128
128
  enabled: t.length > 0
129
- }));
129
+ });
130
+ return w(n);
130
131
  }
131
132
  //#endregion
132
133
  //#region src/advanced-search/model/useAdvancedSearchSelection.ts
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/advanced-search/lib/searchParts.ts","../../src/advanced-search/model/useAdvancedSearch.ts","../../src/advanced-search/model/useAdvancedSearchInitialSelected.ts","../../src/advanced-search/model/useAdvancedSearchSelection.ts","../../src/advanced-search/ui/AdvancedSearchModal.tsx","../../src/advanced-search/ui/AdvancedSearchSelectUI.tsx","../../src/advanced-search/ui/AdvancedSearchSelect.tsx"],"sourcesContent":["export function buildSearchParts(searchTerm: string) {\n\tconst term = searchTerm.trim();\n\tif (!term) {\n\t\treturn [];\n\t}\n\n\tconst searchParts = term\n\t\t.split(\"*\")\n\t\t.map((part) => part.trim())\n\t\t.filter((part) => part.length);\n\n\treturn searchParts;\n\n\t// const filterConditions = searchKeys.map((key) => {\n\t// \treturn searchParts.map((part) => `substringof('${part}',${String(key)})`).join(\" and \");\n\t// });\n\n\t// return `(${filterConditions.join(\" or \")})`;\n}\n\nexport function filterBySearchParts<T extends Record<string, string>>(items: T[], searchParts: string[], searchKeys: (keyof T)[]) {\n\tconst lowerSearchParts = searchParts.map((part) => part.toLowerCase());\n\n\treturn items.filter((item) => {\n\t\tfor (const key of searchKeys) {\n\t\t\tconst value = String(item[key] || \"\").toLowerCase();\n\n\t\t\tlet lastIndex = 0;\n\t\t\tlet allPartsFound = true;\n\n\t\t\t// Ищем каждую часть строго после предыдущей\n\t\t\tfor (const part of lowerSearchParts) {\n\t\t\t\tconst index = value.indexOf(part, lastIndex);\n\t\t\t\tif (index === -1) {\n\t\t\t\t\tallPartsFound = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlastIndex = index + part.length; // следующая часть после найденной\n\t\t\t}\n\n\t\t\tif (allPartsFound) return true;\n\t\t}\n\t\treturn false;\n\t});\n\n\t// С регуляркой медленнее в 2-3 раза\n\n\t// // Паттерн: первая часть, затем любое количество символов, затем вторая часть\n\t// const searchPattern = searchParts.join(\".*?\");\n\t// const regExp = new RegExp(searchPattern, \"i\");\n\n\t// return items.filter((item) => {\n\t// \tfor (const key of searchKeys) {\n\t// \t\tif (regExp.test(item[key])) {\n\t// \t\t\treturn true;\n\t// \t\t}\n\t// \t}\n\t// \treturn false;\n\t// });\n}\n","import { useCallback, useMemo, useState } from \"react\";\n\nimport { odataQueryFn } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { createFilterContains, createFilterEqual } from \"@ryuzaki13/react-foundation-lib/odata-service\";\nimport { useInfiniteQuery } from \"@tanstack/react-query\";\n\nimport { buildSearchParts, filterBySearchParts } from \"../lib\";\n\nimport { SearchConfig } from \"./types\";\n\nconst PAGE_SIZE = 50;\n\nexport function useAdvancedSearch<T extends Record<string, string>>(config: SearchConfig<T>) {\n\tconst [term, setTerm] = useState(\"\");\n\tconst [filters, setFilters] = useState<Record<string, string[]>>(() =>\n\t\tObject.keys(config.segments ?? {}).reduce(\n\t\t\t(acc, key) => {\n\t\t\t\tacc[key] = [];\n\t\t\t\treturn acc;\n\t\t\t},\n\t\t\t{} as Record<string, string[]>\n\t\t)\n\t);\n\n\tconst searchParts = buildSearchParts(term);\n\tconst isComplexSearch = searchParts.length > 1;\n\n\tconst top = isComplexSearch ? 5000 : PAGE_SIZE;\n\n\tconst query = useInfiniteQuery({\n\t\tqueryKey: [\"search\", config.odata.service, config.odata.target, filters, term],\n\t\tqueryFn: async ({ pageParam = 0, signal, client }) => {\n\t\t\tconst columnKeys = config.columns.map((col) => col.key);\n\n\t\t\tconst result = await odataQueryFn<T>({\n\t\t\t\todata: {\n\t\t\t\t\tservice: config.odata.service,\n\t\t\t\t\ttarget: config.odata.target\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\ttop: top,\n\t\t\t\t\tskip: pageParam,\n\t\t\t\t\tselect: columnKeys,\n\t\t\t\t\texpression: {\n\t\t\t\t\t\tand: true,\n\t\t\t\t\t\tfilters: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfilters: searchParts\n\t\t\t\t\t\t\t\t\t? config.searchKeys.map((key) => ({\n\t\t\t\t\t\t\t\t\t\t\tfilters: searchParts.map((part) => createFilterContains(key, part))\n\t\t\t\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t\t\t\t: []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tand: true,\n\t\t\t\t\t\t\t\tfilters: Object.keys(filters).map((key) => createFilterEqual(key, filters[key]))\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\tsorts: [{ key: config.leadingKey }]\n\t\t\t\t}\n\t\t\t})({ signal, client });\n\n\t\t\tif (isComplexSearch) {\n\t\t\t\treturn filterBySearchParts(result.data, searchParts, config.searchKeys);\n\t\t\t}\n\n\t\t\treturn result.data;\n\t\t},\n\t\tgetNextPageParam: (lastPage, allPages) => {\n\t\t\tif (lastPage.length < top) return undefined;\n\t\t\treturn allPages.length * top;\n\t\t},\n\t\tinitialPageParam: 0\n\t});\n\n\tconst search = useCallback((term: string) => {\n\t\tsetTerm(term);\n\t}, []);\n\n\tconst clearSearch = useCallback(() => {\n\t\tsetTerm(\"\");\n\t}, []);\n\n\tconst items = useMemo(() => {\n\t\treturn query.data?.pages.flatMap((page) => page) ?? [];\n\t}, [query.data?.pages]);\n\n\treturn {\n\t\tquery,\n\t\titems,\n\t\tsearchTerm: term,\n\t\tsetSearch: search,\n\t\tclearSearch,\n\t\tfilters,\n\t\tsetFilters\n\t};\n}\n","import { odataQueryFn } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { createFilterEqual, unwrapODataQueryResult } from \"@ryuzaki13/react-foundation-lib/odata-service\";\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport { SearchConfig } from \"./types\";\n\n/**\n * Хук для поиска клиентов с поддержкой бесконечной прокрутки через OData\n */\nexport function useAdvancedSearchInitialSelected<T extends Record<string, string>>(\n\tconfig: SearchConfig<T>,\n\tinitialSelectedKeys: string[] = []\n) {\n\tconst query = useQuery({\n\t\tqueryKey: [\"searchSelected\", config.odata.service, config.odata.target, initialSelectedKeys],\n\t\tqueryFn: async ({ client, signal }) => {\n\t\t\tif (initialSelectedKeys.length === 0) {\n\t\t\t\treturn { data: [] as T[], totalCount: undefined };\n\t\t\t}\n\n\t\t\t// Получаем ключи колонок для select параметра\n\t\t\tconst columnKeys = config.columns.map((col) => col.key);\n\n\t\t\t// Выполняем OData запрос\n\t\t\treturn await odataQueryFn<T>({\n\t\t\t\todata: { service: config.odata.service, target: config.odata.target },\n\t\t\t\toptions: {\n\t\t\t\t\tselect: columnKeys,\n\t\t\t\t\texpression: {\n\t\t\t\t\t\tfilters: initialSelectedKeys.map((key) => createFilterEqual(config.leadingKey, key))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})({ client, signal });\n\t\t},\n\t\tenabled: initialSelectedKeys.length > 0\n\t});\n\n\treturn unwrapODataQueryResult(query);\n}\n","import { useCallback, useState } from \"react\";\n\nimport { SearchConfig } from \"./types\";\n\n/**\n * Хук для управления выбором клиентов\n */\nexport function useAdvancedSearchSelection<T extends Record<string, string>>(config: SearchConfig<T>) {\n\tconst [selectedItems, setSelectedItems] = useState<T[]>([]);\n\n\t/**\n\t * Сравнивает наборы выбранных элементов по ведущему ключу без учёта порядка.\n\t */\n\tconst areSelectionsEqual = useCallback(\n\t\t(left: readonly T[], right: readonly T[]) => {\n\t\t\tif (left.length !== right.length) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst rightIds = new Set(right.map((item) => String(item[config.leadingKey])));\n\n\t\t\treturn left.every((item) => rightIds.has(String(item[config.leadingKey])));\n\t\t},\n\t\t[config.leadingKey]\n\t);\n\n\t/**\n\t * Нормализует новый набор выбора и удаляет дубликаты по ведущему ключу.\n\t */\n\tconst replaceSelection = useCallback(\n\t\t(nextItems: readonly T[]) => {\n\t\t\tsetSelectedItems((prev) => {\n\t\t\t\tconst nextSelectionMap = new Map<string, T>();\n\n\t\t\t\tfor (const item of nextItems) {\n\t\t\t\t\tnextSelectionMap.set(String(item[config.leadingKey]), item);\n\t\t\t\t}\n\n\t\t\t\tconst normalizedItems = Array.from(nextSelectionMap.values());\n\n\t\t\t\treturn areSelectionsEqual(prev, normalizedItems) ? prev : normalizedItems;\n\t\t\t});\n\t\t},\n\t\t[areSelectionsEqual, config.leadingKey]\n\t);\n\n\tconst select = useCallback(\n\t\t(item: T) => {\n\t\t\tsetSelectedItems((prev) => {\n\t\t\t\t// Проверяем, не выбран ли уже этот клиент\n\t\t\t\tif (prev.some((c) => c[config.leadingKey] === item[config.leadingKey])) {\n\t\t\t\t\treturn prev;\n\t\t\t\t}\n\t\t\t\treturn [...prev, item];\n\t\t\t});\n\t\t},\n\t\t[config.leadingKey]\n\t);\n\n\tconst deselect = useCallback(\n\t\t(id: string) => {\n\t\t\tsetSelectedItems((prev) => prev.filter((item) => item[config.leadingKey] !== id));\n\t\t},\n\t\t[config.leadingKey]\n\t);\n\n\tconst clearSelection = useCallback(() => {\n\t\tsetSelectedItems([]);\n\t}, []);\n\n\tconst isSelected = useCallback(\n\t\t(id: string) => {\n\t\t\treturn selectedItems.some((item) => item[config.leadingKey] === id);\n\t\t},\n\t\t[config.leadingKey, selectedItems]\n\t);\n\n\treturn {\n\t\tselectedItems,\n\t\tselect,\n\t\tdeselect,\n\t\treplaceSelection,\n\t\tclearSelection,\n\t\tisSelected\n\t};\n}\n","import { useCallback, useEffect, useMemo } from \"react\";\n\nimport { useODataTableColumns } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { type TableColumnDef } from \"@ryuzaki13/react-foundation-lib/table\";\n\nimport { Badge, BadgeList } from \"../../badge\";\nimport { Button } from \"../../button\";\nimport { FlexContainer } from \"../../flex\";\nimport { GridContainer } from \"../../grid\";\nimport { InputSearch } from \"../../input-search\";\nimport { Scrollable } from \"../../misc\";\nimport { Modal, ModalContent, ModalFooter, ModalToolbar } from \"../../modal\";\nimport { ODataDependentMultiSelect } from \"../../multi-select\";\nimport { Table } from \"../../table\";\nimport { SearchConfig, useAdvancedSearch, useAdvancedSearchSelection } from \"../model\";\n\ninterface SearchModalProps<T extends Record<string, string>> {\n\tonClose: () => void;\n\tonItemsSelect: (items: T[]) => void;\n\tinitialSelectedItems?: T[];\n\tconfig: SearchConfig<T>;\n}\n\n/**\n * Модальное окно поиска клиентов\n */\nexport function AdvancedSearchModal<T extends Record<string, string>>({\n\tonClose,\n\tonItemsSelect,\n\tconfig,\n\tinitialSelectedItems = []\n}: SearchModalProps<T>) {\n\tconst tableColumns: TableColumnDef<T>[] = useMemo(\n\t\t() =>\n\t\t\tconfig.columns.map(\n\t\t\t\t(col) =>\n\t\t\t\t\t({\n\t\t\t\t\t\tid: col.key as keyof T,\n\t\t\t\t\t\taccessorKey: col.key as keyof T,\n\t\t\t\t\t\theader: col.label,\n\t\t\t\t\t\tmeta: {\n\t\t\t\t\t\t\twidth: col.width || \"auto\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}) as TableColumnDef<T>\n\t\t\t),\n\t\t[config.columns]\n\t);\n\n\tconst { columns, isLoading } = useODataTableColumns<T>({\n\t\tservice: config.odata.service,\n\t\ttarget: config.odata.target,\n\t\tmode: \"enrich\",\n\t\tcolumns: tableColumns\n\t});\n\n\tconst { query, items, searchTerm, setSearch, clearSearch, filters, setFilters } = useAdvancedSearch(config);\n\tconst { selectedItems, deselect, replaceSelection } = useAdvancedSearchSelection(config);\n\tconst getRowId = useCallback((item: T) => String(item[config.leadingKey]), [config.leadingKey]);\n\tconst selectedRowIds = useMemo(() => selectedItems.map((item) => String(item[config.leadingKey])), [selectedItems, config.leadingKey]);\n\tconst visibleItemIds = useMemo(() => new Set(items.map((item) => String(item[config.leadingKey]))), [items, config.leadingKey]);\n\n\t// До изменения: пустой внешний набор не очищал внутренний выбор.\n\t// После изменения: модальное окно синхронизирует выбор с внешним набором полностью.\n\tuseEffect(() => {\n\t\treplaceSelection(initialSelectedItems);\n\t}, [initialSelectedItems, replaceSelection]);\n\n\tconst handleReachEnd = useCallback(() => {\n\t\tif (query.hasNextPage && !query.isFetchingNextPage) {\n\t\t\tquery.fetchNextPage();\n\t\t}\n\t}, [query]);\n\n\t// До изменения: выбор собирался чекбоксами по строкам.\n\t// После изменения: таблица управляет multi-selection, а модалка сохраняет скрытые фильтрами элементы.\n\tconst handleSelect = useCallback(\n\t\t(selectedVisibleItems: T[]) => {\n\t\t\tconst selectedVisibleIds = new Set(selectedVisibleItems.map((item) => String(item[config.leadingKey])));\n\t\t\tconst hiddenSelectedItems = selectedItems.filter((item) => !visibleItemIds.has(String(item[config.leadingKey])));\n\t\t\tconst nextVisibleSelectedItems = items.filter((item) => selectedVisibleIds.has(String(item[config.leadingKey])));\n\n\t\t\treplaceSelection([...hiddenSelectedItems, ...nextVisibleSelectedItems]);\n\t\t},\n\t\t[config.leadingKey, items, replaceSelection, selectedItems, visibleItemIds]\n\t);\n\n\t/**\n\t * Удаляет отдельный элемент из общего выбора.\n\t */\n\tconst handleRemoveSelectedItem = useCallback(\n\t\t(item: T) => {\n\t\t\tdeselect(String(item[config.leadingKey]));\n\t\t},\n\t\t[config.leadingKey, deselect]\n\t);\n\n\t// Обработчик подтверждения выбора\n\tconst handleConfirmSelection = useCallback(() => {\n\t\tonItemsSelect(selectedItems);\n\t\tonClose();\n\t}, [selectedItems, onItemsSelect, onClose]);\n\n\tconst filterConfig = useMemo(() => {\n\t\tif (\"segments\" in config && config.segments) {\n\t\t\tconst limitedKeys = Object.keys(config.segments);\n\t\t\tif (limitedKeys.length) {\n\t\t\t\treturn {\n\t\t\t\t\todata: { ...config.odata, limitedKeys },\n\t\t\t\t\tsegments: config.segments,\n\t\t\t\t\tmodel: config.model\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}, [config]);\n\n\treturn (\n\t\t<Modal isOpen onClose={onClose} title={config.title} size=\"lg\" height=\"min(50em, 80dvh)\">\n\t\t\t<ModalToolbar>\n\t\t\t\t<FlexContainer gap=\"sm\">\n\t\t\t\t\t{filterConfig && (\n\t\t\t\t\t\t<ODataDependentMultiSelect\n\t\t\t\t\t\t\todata={filterConfig.odata}\n\t\t\t\t\t\t\tsegments={filterConfig.segments}\n\t\t\t\t\t\t\tmodel={filterConfig.model}\n\t\t\t\t\t\t\tvalues={filters}\n\t\t\t\t\t\t\tonChange={setFilters}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<InputSearch\n\t\t\t\t\t\tsize=\"md\"\n\t\t\t\t\t\tplaceholder={config.searchLabel ?? \"Введите поисковый запрос\"}\n\t\t\t\t\t\tvalue={searchTerm}\n\t\t\t\t\t\tonChange={setSearch}\n\t\t\t\t\t\tonClear={clearSearch}\n\t\t\t\t\t\tclassName=\"flexGrow\"\n\t\t\t\t\t/>\n\t\t\t\t</FlexContainer>\n\t\t\t</ModalToolbar>\n\n\t\t\t<ModalContent>\n\t\t\t\t<GridContainer gap=\"md\" templateRows=\"1fr auto\" className=\"h100\">\n\t\t\t\t\t<Table\n\t\t\t\t\t\tcolumns={columns}\n\t\t\t\t\t\tdata={items}\n\t\t\t\t\t\tselectionMode=\"multi\"\n\t\t\t\t\t\tselectedRowIds={selectedRowIds}\n\t\t\t\t\t\tgetRowId={getRowId}\n\t\t\t\t\t\tisLoading={query.isLoading || isLoading}\n\t\t\t\t\t\tisFetching={query.isFetching} // или query.isFetchingNextPage\n\t\t\t\t\t\tonRowSelectionChange={handleSelect}\n\t\t\t\t\t\tonReachEnd={handleReachEnd}\n\t\t\t\t\t\tclassName=\"w100\"\n\t\t\t\t\t/>\n\n\t\t\t\t\t<div className=\"marginBlockMd border\">\n\t\t\t\t\t\t<Scrollable className=\"paddingSm\" height=\"6em\">\n\t\t\t\t\t\t\t<BadgeList>\n\t\t\t\t\t\t\t\t{selectedItems.map((item) => (\n\t\t\t\t\t\t\t\t\t<Badge\n\t\t\t\t\t\t\t\t\t\tkey={item[config.leadingKey]}\n\t\t\t\t\t\t\t\t\t\tsize=\"md\"\n\t\t\t\t\t\t\t\t\t\ttone=\"info\"\n\t\t\t\t\t\t\t\t\t\tappearance=\"outline\"\n\t\t\t\t\t\t\t\t\t\tonRemove={() => handleRemoveSelectedItem(item)}>\n\t\t\t\t\t\t\t\t\t\t{config.leadingText ? item[config.leadingText] || item[config.leadingKey] : item[config.leadingKey]}\n\t\t\t\t\t\t\t\t\t</Badge>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</BadgeList>\n\t\t\t\t\t\t</Scrollable>\n\t\t\t\t\t</div>\n\t\t\t\t</GridContainer>\n\t\t\t</ModalContent>\n\n\t\t\t<ModalFooter>\n\t\t\t\t<Button onClick={onClose}>Отмена</Button>\n\t\t\t\t<Button variant=\"successOutline\" onClick={handleConfirmSelection}>\n\t\t\t\t\tВыбрать\n\t\t\t\t</Button>\n\t\t\t</ModalFooter>\n\t\t</Modal>\n\t);\n}\n","import { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { ChevronRightIcon, XIcon } from \"lucide-react\";\n\nimport { FlexContainer } from \"../../flex\";\nimport { useInputFieldIds } from \"../../input\";\nimport inputStyles from \"../../input/Input.module.scss\";\nimport { UiBaseProps } from \"../../types\";\nimport uiStyles from \"../../ui.module.scss\";\n\ninterface AdvancedSearchSelectUIProps extends Omit<UiBaseProps<string[]>, \"value\" | \"onChange\"> {\n\ttoken: string | undefined;\n\tonOpen: () => void;\n\tonClear: () => void;\n}\n\nexport const AdvancedSearchSelectUI = ({\n\tlabel,\n\tdescription,\n\tdisabled,\n\tsize,\n\tplaceholder = \"Выбрать\",\n\ttoken,\n\tonOpen,\n\tonClear\n}: AdvancedSearchSelectUIProps) => {\n\tconst { controlId, labelId, descriptionId } = useInputFieldIds({\n\t\thasLabel: label !== undefined && label !== null,\n\t\thasDescription: !!description\n\t});\n\tconst hasToken = Boolean(token);\n\n\treturn (\n\t\t<div aria-disabled={disabled || undefined} className={cn(uiStyles.uiElement, uiStyles.uiSizable, size && uiStyles[size])}>\n\t\t\t{label && (\n\t\t\t\t<label id={labelId} htmlFor={controlId} className={uiStyles.uiLabel}>\n\t\t\t\t\t{label}\n\t\t\t\t</label>\n\t\t\t)}\n\t\t\t{description && (\n\t\t\t\t<p id={descriptionId} className={uiStyles.uiDescription}>\n\t\t\t\t\t{description}\n\t\t\t\t</p>\n\t\t\t)}\n\n\t\t\t<div className={uiStyles.uiInputContainer}>\n\t\t\t\t<div className={uiStyles.uiInputWithToggle}>\n\t\t\t\t\t{!hasToken && (\n\t\t\t\t\t\t<FlexContainer align=\"center\" className=\"h100\">\n\t\t\t\t\t\t\t<div className={uiStyles.uiPlaceholder}>{placeholder}</div>\n\t\t\t\t\t\t</FlexContainer>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\n\t\t\t\t<div className={inputStyles.controlEndAdornment}>\n\t\t\t\t\t<div className={uiStyles.uiToggleButtonContainer}>\n\t\t\t\t\t\t<div className=\"flexEllipsis\" style={{ maxWidth: \"100%\" }}>\n\t\t\t\t\t\t\t{token}\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tdisabled={!token}\n\t\t\t\t\t\t\tclassName={uiStyles.uiClearButton}\n\t\t\t\t\t\t\tonClick={onClear}\n\t\t\t\t\t\t\taria-label=\"Очистить все\">\n\t\t\t\t\t\t\t<XIcon />\n\t\t\t\t\t\t</button>\n\n\t\t\t\t\t\t<div className={uiStyles.uiButtonSeparator} />\n\n\t\t\t\t\t\t<button type=\"button\" onClick={onOpen} className={uiStyles.uiToggleButton}>\n\t\t\t\t\t\t\t<ChevronRightIcon className={uiStyles.uiToggleIcon} />\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n","import { useCallback, useState } from \"react\";\n\nimport { UiBaseProps } from \"../../types\";\nimport { SearchConfig, useAdvancedSearchInitialSelected } from \"../model\";\n\nimport { AdvancedSearchModal } from \"./AdvancedSearchModal\";\nimport { AdvancedSearchSelectUI } from \"./AdvancedSearchSelectUI\";\n\ntype AdvancedSearchSelectProps<T extends Record<string, string>> = UiBaseProps<string[]> & {\n\tconfig: SearchConfig<T>;\n};\n\nexport function AdvancedSearchSelect<T extends Record<string, string>>({\n\tvalue = [],\n\tonChange,\n\tconfig,\n\t...props\n}: AdvancedSearchSelectProps<T>) {\n\tconst [isModalOpen, setIsModalOpen] = useState(false);\n\n\tconst { data: selectedItems } = useAdvancedSearchInitialSelected(config, value);\n\n\tconst handleOpen = useCallback(() => setIsModalOpen(true), []);\n\tconst handleClose = useCallback(() => setIsModalOpen(false), []);\n\tconst handleRemove = useCallback(() => onChange([]), [onChange]);\n\tconst handleSelect = useCallback(\n\t\t(items: T[]) => onChange(items.map((item) => String(item[config.leadingKey]))),\n\t\t[config.leadingKey, onChange]\n\t);\n\tconst getDisplayText = useCallback(\n\t\t(items: T[] | undefined) => {\n\t\t\tif (!items?.length) return;\n\t\t\tif (items.length > 1) return `Выбрано ${items.length} элем.`;\n\t\t\treturn `${(config.leadingText && items[0][config.leadingText]) || items[0][config.leadingKey]}`;\n\t\t},\n\t\t[config.leadingKey, config.leadingText]\n\t);\n\n\treturn (\n\t\t<>\n\t\t\t<AdvancedSearchSelectUI {...props} token={getDisplayText(selectedItems)} onOpen={handleOpen} onClear={handleRemove} />\n\n\t\t\t{isModalOpen && (\n\t\t\t\t<AdvancedSearchModal\n\t\t\t\t\tconfig={config}\n\t\t\t\t\tonClose={handleClose}\n\t\t\t\t\tonItemsSelect={handleSelect}\n\t\t\t\t\tinitialSelectedItems={selectedItems}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</>\n\t);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/advanced-search/lib/searchParts.ts","../../src/advanced-search/model/useAdvancedSearch.ts","../../src/advanced-search/model/useAdvancedSearchInitialSelected.ts","../../src/advanced-search/model/useAdvancedSearchSelection.ts","../../src/advanced-search/ui/AdvancedSearchModal.tsx","../../src/advanced-search/ui/AdvancedSearchSelectUI.tsx","../../src/advanced-search/ui/AdvancedSearchSelect.tsx"],"sourcesContent":["export function buildSearchParts(searchTerm: string) {\n\tconst term = searchTerm.trim();\n\tif (!term) {\n\t\treturn [];\n\t}\n\n\tconst searchParts = term\n\t\t.split(\"*\")\n\t\t.map((part) => part.trim())\n\t\t.filter((part) => part.length);\n\n\treturn searchParts;\n\n\t// const filterConditions = searchKeys.map((key) => {\n\t// \treturn searchParts.map((part) => `substringof('${part}',${String(key)})`).join(\" and \");\n\t// });\n\n\t// return `(${filterConditions.join(\" or \")})`;\n}\n\nexport function filterBySearchParts<T extends Record<string, string>>(items: T[], searchParts: string[], searchKeys: (keyof T)[]) {\n\tconst lowerSearchParts = searchParts.map((part) => part.toLowerCase());\n\n\treturn items.filter((item) => {\n\t\tfor (const key of searchKeys) {\n\t\t\tconst value = String(item[key] || \"\").toLowerCase();\n\n\t\t\tlet lastIndex = 0;\n\t\t\tlet allPartsFound = true;\n\n\t\t\t// Ищем каждую часть строго после предыдущей\n\t\t\tfor (const part of lowerSearchParts) {\n\t\t\t\tconst index = value.indexOf(part, lastIndex);\n\t\t\t\tif (index === -1) {\n\t\t\t\t\tallPartsFound = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tlastIndex = index + part.length; // следующая часть после найденной\n\t\t\t}\n\n\t\t\tif (allPartsFound) return true;\n\t\t}\n\t\treturn false;\n\t});\n\n\t// С регуляркой медленнее в 2-3 раза\n\n\t// // Паттерн: первая часть, затем любое количество символов, затем вторая часть\n\t// const searchPattern = searchParts.join(\".*?\");\n\t// const regExp = new RegExp(searchPattern, \"i\");\n\n\t// return items.filter((item) => {\n\t// \tfor (const key of searchKeys) {\n\t// \t\tif (regExp.test(item[key])) {\n\t// \t\t\treturn true;\n\t// \t\t}\n\t// \t}\n\t// \treturn false;\n\t// });\n}\n","import { useCallback, useMemo, useState } from \"react\";\n\nimport { odataQueryFn } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { createFilterContains, createFilterEqual } from \"@ryuzaki13/react-foundation-lib/odata-service\";\nimport { useInfiniteQuery } from \"@tanstack/react-query\";\n\nimport { buildSearchParts, filterBySearchParts } from \"../lib\";\n\nimport { SearchConfig } from \"./types\";\n\nconst PAGE_SIZE = 50;\n\nexport function useAdvancedSearch<T extends Record<string, string>>(config: SearchConfig<T>) {\n\tconst [term, setTerm] = useState(\"\");\n\tconst [filters, setFilters] = useState<Record<string, string[]>>(() =>\n\t\tObject.keys(config.segments ?? {}).reduce(\n\t\t\t(acc, key) => {\n\t\t\t\tacc[key] = [];\n\t\t\t\treturn acc;\n\t\t\t},\n\t\t\t{} as Record<string, string[]>\n\t\t)\n\t);\n\n\tconst searchParts = buildSearchParts(term);\n\tconst isComplexSearch = searchParts.length > 1;\n\n\tconst top = isComplexSearch ? 5000 : PAGE_SIZE;\n\n\tconst query = useInfiniteQuery({\n\t\tqueryKey: [\"search\", config.odata.service, config.odata.target, filters, term],\n\t\tqueryFn: async ({ pageParam = 0, signal, client }) => {\n\t\t\tconst columnKeys = config.columns.map((col) => col.key);\n\n\t\t\tconst result = await odataQueryFn<T>({\n\t\t\t\todata: {\n\t\t\t\t\tservice: config.odata.service,\n\t\t\t\t\ttarget: config.odata.target\n\t\t\t\t},\n\t\t\t\toptions: {\n\t\t\t\t\ttop: top,\n\t\t\t\t\tskip: pageParam,\n\t\t\t\t\tselect: columnKeys,\n\t\t\t\t\texpression: {\n\t\t\t\t\t\tand: true,\n\t\t\t\t\t\tfilters: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfilters: searchParts\n\t\t\t\t\t\t\t\t\t? config.searchKeys.map((key) => ({\n\t\t\t\t\t\t\t\t\t\t\tfilters: searchParts.map((part) => createFilterContains(key, part))\n\t\t\t\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t\t\t\t: []\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tand: true,\n\t\t\t\t\t\t\t\tfilters: Object.keys(filters).map((key) => createFilterEqual(key, filters[key]))\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\tsorts: [{ key: config.leadingKey }]\n\t\t\t\t}\n\t\t\t})({ signal, client });\n\n\t\t\tif (isComplexSearch) {\n\t\t\t\treturn filterBySearchParts(result.data, searchParts, config.searchKeys);\n\t\t\t}\n\n\t\t\treturn result.data;\n\t\t},\n\t\tgetNextPageParam: (lastPage, allPages) => {\n\t\t\tif (lastPage.length < top) return undefined;\n\t\t\treturn allPages.length * top;\n\t\t},\n\t\tinitialPageParam: 0\n\t});\n\n\tconst search = useCallback((term: string) => {\n\t\tsetTerm(term);\n\t}, []);\n\n\tconst clearSearch = useCallback(() => {\n\t\tsetTerm(\"\");\n\t}, []);\n\n\tconst items = useMemo(() => {\n\t\treturn query.data?.pages.flatMap((page) => page) ?? [];\n\t}, [query.data?.pages]);\n\n\treturn {\n\t\tquery,\n\t\titems,\n\t\tsearchTerm: term,\n\t\tsetSearch: search,\n\t\tclearSearch,\n\t\tfilters,\n\t\tsetFilters\n\t};\n}\n","import { odataQueryFn } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { createFilterEqual, unwrapODataQueryResult } from \"@ryuzaki13/react-foundation-lib/odata-service\";\nimport { useQuery } from \"@tanstack/react-query\";\n\nimport { SearchConfig } from \"./types\";\n\n/**\n * Хук для поиска клиентов с поддержкой бесконечной прокрутки через OData\n */\nexport function useAdvancedSearchInitialSelected<T extends Record<string, string>>(\n\tconfig: SearchConfig<T>,\n\tinitialSelectedKeys: string[] = []\n) {\n\tconst query = useQuery({\n\t\tqueryKey: [\"searchSelected\", config.odata.service, config.odata.target, initialSelectedKeys],\n\t\tqueryFn: async ({ client, signal }) => {\n\t\t\tif (initialSelectedKeys.length === 0) {\n\t\t\t\treturn { data: [] as T[], totalCount: undefined };\n\t\t\t}\n\n\t\t\t// Получаем ключи колонок для select параметра\n\t\t\tconst columnKeys = config.columns.map((col) => col.key);\n\n\t\t\t// Выполняем OData запрос\n\t\t\treturn await odataQueryFn<T>({\n\t\t\t\todata: { service: config.odata.service, target: config.odata.target },\n\t\t\t\toptions: {\n\t\t\t\t\tselect: columnKeys,\n\t\t\t\t\texpression: {\n\t\t\t\t\t\tfilters: initialSelectedKeys.map((key) => createFilterEqual(config.leadingKey, key))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})({ client, signal });\n\t\t},\n\t\tenabled: initialSelectedKeys.length > 0\n\t});\n\n\treturn unwrapODataQueryResult(query);\n}\n","import { useCallback, useState } from \"react\";\n\nimport { SearchConfig } from \"./types\";\n\n/**\n * Хук для управления выбором клиентов\n */\nexport function useAdvancedSearchSelection<T extends Record<string, string>>(config: SearchConfig<T>) {\n\tconst [selectedItems, setSelectedItems] = useState<T[]>([]);\n\n\t/**\n\t * Сравнивает наборы выбранных элементов по ведущему ключу без учёта порядка.\n\t */\n\tconst areSelectionsEqual = useCallback(\n\t\t(left: readonly T[], right: readonly T[]) => {\n\t\t\tif (left.length !== right.length) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst rightIds = new Set(right.map((item) => String(item[config.leadingKey])));\n\n\t\t\treturn left.every((item) => rightIds.has(String(item[config.leadingKey])));\n\t\t},\n\t\t[config.leadingKey]\n\t);\n\n\t/**\n\t * Нормализует новый набор выбора и удаляет дубликаты по ведущему ключу.\n\t */\n\tconst replaceSelection = useCallback(\n\t\t(nextItems: readonly T[]) => {\n\t\t\tsetSelectedItems((prev) => {\n\t\t\t\tconst nextSelectionMap = new Map<string, T>();\n\n\t\t\t\tfor (const item of nextItems) {\n\t\t\t\t\tnextSelectionMap.set(String(item[config.leadingKey]), item);\n\t\t\t\t}\n\n\t\t\t\tconst normalizedItems = Array.from(nextSelectionMap.values());\n\n\t\t\t\treturn areSelectionsEqual(prev, normalizedItems) ? prev : normalizedItems;\n\t\t\t});\n\t\t},\n\t\t[areSelectionsEqual, config.leadingKey]\n\t);\n\n\tconst select = useCallback(\n\t\t(item: T) => {\n\t\t\tsetSelectedItems((prev) => {\n\t\t\t\t// Проверяем, не выбран ли уже этот клиент\n\t\t\t\tif (prev.some((c) => c[config.leadingKey] === item[config.leadingKey])) {\n\t\t\t\t\treturn prev;\n\t\t\t\t}\n\t\t\t\treturn [...prev, item];\n\t\t\t});\n\t\t},\n\t\t[config.leadingKey]\n\t);\n\n\tconst deselect = useCallback(\n\t\t(id: string) => {\n\t\t\tsetSelectedItems((prev) => prev.filter((item) => item[config.leadingKey] !== id));\n\t\t},\n\t\t[config.leadingKey]\n\t);\n\n\tconst clearSelection = useCallback(() => {\n\t\tsetSelectedItems([]);\n\t}, []);\n\n\tconst isSelected = useCallback(\n\t\t(id: string) => {\n\t\t\treturn selectedItems.some((item) => item[config.leadingKey] === id);\n\t\t},\n\t\t[config.leadingKey, selectedItems]\n\t);\n\n\treturn {\n\t\tselectedItems,\n\t\tselect,\n\t\tdeselect,\n\t\treplaceSelection,\n\t\tclearSelection,\n\t\tisSelected\n\t};\n}\n","import { useCallback, useEffect, useMemo } from \"react\";\n\nimport { useODataTableColumns } from \"@ryuzaki13/react-foundation-api/odata\";\nimport { type TableColumnDef } from \"@ryuzaki13/react-foundation-lib/table\";\n\nimport { Badge, BadgeList } from \"../../badge\";\nimport { Button } from \"../../button\";\nimport { FlexContainer } from \"../../flex\";\nimport { GridContainer } from \"../../grid\";\nimport { InputSearch } from \"../../input-search\";\nimport { Scrollable } from \"../../misc\";\nimport { Modal, ModalContent, ModalFooter, ModalToolbar } from \"../../modal\";\nimport { ODataDependentMultiSelect } from \"../../multi-select\";\nimport { Table } from \"../../table\";\nimport { SearchConfig, useAdvancedSearch, useAdvancedSearchSelection } from \"../model\";\n\ninterface SearchModalProps<T extends Record<string, string>> {\n\tonClose: () => void;\n\tonItemsSelect: (items: T[]) => void;\n\tinitialSelectedItems?: T[];\n\tconfig: SearchConfig<T>;\n}\n\n/**\n * Модальное окно поиска клиентов\n */\nexport function AdvancedSearchModal<T extends Record<string, string>>({\n\tonClose,\n\tonItemsSelect,\n\tconfig,\n\tinitialSelectedItems = []\n}: SearchModalProps<T>) {\n\tconst tableColumns: TableColumnDef<T>[] = useMemo(\n\t\t() =>\n\t\t\tconfig.columns.map(\n\t\t\t\t(col) =>\n\t\t\t\t\t({\n\t\t\t\t\t\tid: col.key as keyof T,\n\t\t\t\t\t\taccessorKey: col.key as keyof T,\n\t\t\t\t\t\theader: col.label,\n\t\t\t\t\t\tmeta: {\n\t\t\t\t\t\t\twidth: col.width || \"auto\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}) as TableColumnDef<T>\n\t\t\t),\n\t\t[config.columns]\n\t);\n\n\tconst { columns, isLoading } = useODataTableColumns<T>({\n\t\tservice: config.odata.service,\n\t\ttarget: config.odata.target,\n\t\tmode: \"enrich\",\n\t\tcolumns: tableColumns\n\t});\n\n\tconst { query, items, searchTerm, setSearch, clearSearch, filters, setFilters } = useAdvancedSearch(config);\n\tconst { selectedItems, deselect, replaceSelection } = useAdvancedSearchSelection(config);\n\tconst getRowId = useCallback((item: T) => String(item[config.leadingKey]), [config.leadingKey]);\n\tconst selectedRowIds = useMemo(() => selectedItems.map((item) => String(item[config.leadingKey])), [selectedItems, config.leadingKey]);\n\tconst visibleItemIds = useMemo(() => new Set(items.map((item) => String(item[config.leadingKey]))), [items, config.leadingKey]);\n\n\t// До изменения: пустой внешний набор не очищал внутренний выбор.\n\t// После изменения: модальное окно синхронизирует выбор с внешним набором полностью.\n\tuseEffect(() => {\n\t\treplaceSelection(initialSelectedItems);\n\t}, [initialSelectedItems, replaceSelection]);\n\n\tconst handleReachEnd = useCallback(() => {\n\t\tif (query.hasNextPage && !query.isFetchingNextPage) {\n\t\t\tquery.fetchNextPage();\n\t\t}\n\t}, [query]);\n\n\t// До изменения: выбор собирался чекбоксами по строкам.\n\t// После изменения: таблица управляет multi-selection, а модалка сохраняет скрытые фильтрами элементы.\n\tconst handleSelect = useCallback(\n\t\t(selectedVisibleItems: T[]) => {\n\t\t\tconst selectedVisibleIds = new Set(selectedVisibleItems.map((item) => String(item[config.leadingKey])));\n\t\t\tconst hiddenSelectedItems = selectedItems.filter((item) => !visibleItemIds.has(String(item[config.leadingKey])));\n\t\t\tconst nextVisibleSelectedItems = items.filter((item) => selectedVisibleIds.has(String(item[config.leadingKey])));\n\n\t\t\treplaceSelection([...hiddenSelectedItems, ...nextVisibleSelectedItems]);\n\t\t},\n\t\t[config.leadingKey, items, replaceSelection, selectedItems, visibleItemIds]\n\t);\n\n\t/**\n\t * Удаляет отдельный элемент из общего выбора.\n\t */\n\tconst handleRemoveSelectedItem = useCallback(\n\t\t(item: T) => {\n\t\t\tdeselect(String(item[config.leadingKey]));\n\t\t},\n\t\t[config.leadingKey, deselect]\n\t);\n\n\t// Обработчик подтверждения выбора\n\tconst handleConfirmSelection = useCallback(() => {\n\t\tonItemsSelect(selectedItems);\n\t\tonClose();\n\t}, [selectedItems, onItemsSelect, onClose]);\n\n\tconst filterConfig = useMemo(() => {\n\t\tif (\"segments\" in config && config.segments) {\n\t\t\tconst limitedKeys = Object.keys(config.segments);\n\t\t\tif (limitedKeys.length) {\n\t\t\t\treturn {\n\t\t\t\t\todata: { ...config.odata, limitedKeys },\n\t\t\t\t\tsegments: config.segments,\n\t\t\t\t\tmodel: config.model\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}, [config]);\n\n\treturn (\n\t\t<Modal isOpen onClose={onClose} title={config.title} size=\"lg\" height=\"min(50em, 80dvh)\">\n\t\t\t<ModalToolbar>\n\t\t\t\t<FlexContainer gap=\"sm\">\n\t\t\t\t\t{filterConfig && (\n\t\t\t\t\t\t<ODataDependentMultiSelect\n\t\t\t\t\t\t\todata={filterConfig.odata}\n\t\t\t\t\t\t\tsegments={filterConfig.segments}\n\t\t\t\t\t\t\tmodel={filterConfig.model}\n\t\t\t\t\t\t\tvalues={filters}\n\t\t\t\t\t\t\tonChange={setFilters}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<InputSearch\n\t\t\t\t\t\tsize=\"md\"\n\t\t\t\t\t\tplaceholder={config.searchLabel ?? \"Введите поисковый запрос\"}\n\t\t\t\t\t\tvalue={searchTerm}\n\t\t\t\t\t\tonChange={setSearch}\n\t\t\t\t\t\tonClear={clearSearch}\n\t\t\t\t\t\tclassName=\"flexGrow\"\n\t\t\t\t\t/>\n\t\t\t\t</FlexContainer>\n\t\t\t</ModalToolbar>\n\n\t\t\t<ModalContent>\n\t\t\t\t<GridContainer gap=\"md\" templateRows=\"1fr auto\" className=\"h100\">\n\t\t\t\t\t<Table\n\t\t\t\t\t\tcolumns={columns}\n\t\t\t\t\t\tdata={items}\n\t\t\t\t\t\tselectionMode=\"multi\"\n\t\t\t\t\t\tselectedRowIds={selectedRowIds}\n\t\t\t\t\t\tgetRowId={getRowId}\n\t\t\t\t\t\tisLoading={query.isLoading || isLoading}\n\t\t\t\t\t\tisFetching={query.isFetching} // или query.isFetchingNextPage\n\t\t\t\t\t\tonRowSelectionChange={handleSelect}\n\t\t\t\t\t\tonReachEnd={handleReachEnd}\n\t\t\t\t\t\tclassName=\"w100\"\n\t\t\t\t\t/>\n\n\t\t\t\t\t<div className=\"marginBlockMd border\">\n\t\t\t\t\t\t<Scrollable className=\"paddingSm\" height=\"6em\">\n\t\t\t\t\t\t\t<BadgeList>\n\t\t\t\t\t\t\t\t{selectedItems.map((item) => (\n\t\t\t\t\t\t\t\t\t<Badge\n\t\t\t\t\t\t\t\t\t\tkey={item[config.leadingKey]}\n\t\t\t\t\t\t\t\t\t\tsize=\"md\"\n\t\t\t\t\t\t\t\t\t\ttone=\"info\"\n\t\t\t\t\t\t\t\t\t\tappearance=\"outline\"\n\t\t\t\t\t\t\t\t\t\tonRemove={() => handleRemoveSelectedItem(item)}>\n\t\t\t\t\t\t\t\t\t\t{config.leadingText ? item[config.leadingText] || item[config.leadingKey] : item[config.leadingKey]}\n\t\t\t\t\t\t\t\t\t</Badge>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</BadgeList>\n\t\t\t\t\t\t</Scrollable>\n\t\t\t\t\t</div>\n\t\t\t\t</GridContainer>\n\t\t\t</ModalContent>\n\n\t\t\t<ModalFooter>\n\t\t\t\t<Button onClick={onClose}>Отмена</Button>\n\t\t\t\t<Button variant=\"successOutline\" onClick={handleConfirmSelection}>\n\t\t\t\t\tВыбрать\n\t\t\t\t</Button>\n\t\t\t</ModalFooter>\n\t\t</Modal>\n\t);\n}\n","import { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport { ChevronRightIcon, XIcon } from \"lucide-react\";\n\nimport { FlexContainer } from \"../../flex\";\nimport { useInputFieldIds } from \"../../input\";\nimport inputStyles from \"../../input/Input.module.scss\";\nimport { UiBaseProps } from \"../../types\";\nimport uiStyles from \"../../ui.module.scss\";\n\ninterface AdvancedSearchSelectUIProps extends Omit<UiBaseProps<string[]>, \"value\" | \"onChange\"> {\n\ttoken: string | undefined;\n\tonOpen: () => void;\n\tonClear: () => void;\n}\n\nexport const AdvancedSearchSelectUI = ({\n\tlabel,\n\tdescription,\n\tdisabled,\n\tsize,\n\tplaceholder = \"Выбрать\",\n\ttoken,\n\tonOpen,\n\tonClear\n}: AdvancedSearchSelectUIProps) => {\n\tconst { controlId, labelId, descriptionId } = useInputFieldIds({\n\t\thasLabel: label !== undefined && label !== null,\n\t\thasDescription: !!description\n\t});\n\tconst hasToken = Boolean(token);\n\n\treturn (\n\t\t<div aria-disabled={disabled || undefined} className={cn(uiStyles.uiElement, uiStyles.uiSizable, size && uiStyles[size])}>\n\t\t\t{label && (\n\t\t\t\t<label id={labelId} htmlFor={controlId} className={uiStyles.uiLabel}>\n\t\t\t\t\t{label}\n\t\t\t\t</label>\n\t\t\t)}\n\t\t\t{description && (\n\t\t\t\t<p id={descriptionId} className={uiStyles.uiDescription}>\n\t\t\t\t\t{description}\n\t\t\t\t</p>\n\t\t\t)}\n\n\t\t\t<div className={uiStyles.uiInputContainer}>\n\t\t\t\t<div className={uiStyles.uiInputWithToggle}>\n\t\t\t\t\t{!hasToken && (\n\t\t\t\t\t\t<FlexContainer align=\"center\" className=\"h100\">\n\t\t\t\t\t\t\t<div className={uiStyles.uiPlaceholder}>{placeholder}</div>\n\t\t\t\t\t\t</FlexContainer>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\n\t\t\t\t<div className={inputStyles.controlEndAdornment}>\n\t\t\t\t\t<div className={uiStyles.uiToggleButtonContainer}>\n\t\t\t\t\t\t<div className=\"flexEllipsis\" style={{ maxWidth: \"100%\" }}>\n\t\t\t\t\t\t\t{token}\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tdisabled={!token}\n\t\t\t\t\t\t\tclassName={uiStyles.uiClearButton}\n\t\t\t\t\t\t\tonClick={onClear}\n\t\t\t\t\t\t\taria-label=\"Очистить все\">\n\t\t\t\t\t\t\t<XIcon />\n\t\t\t\t\t\t</button>\n\n\t\t\t\t\t\t<div className={uiStyles.uiButtonSeparator} />\n\n\t\t\t\t\t\t<button type=\"button\" onClick={onOpen} className={uiStyles.uiToggleButton}>\n\t\t\t\t\t\t\t<ChevronRightIcon className={uiStyles.uiToggleIcon} />\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n","import { useCallback, useState } from \"react\";\n\nimport { UiBaseProps } from \"../../types\";\nimport { SearchConfig, useAdvancedSearchInitialSelected } from \"../model\";\n\nimport { AdvancedSearchModal } from \"./AdvancedSearchModal\";\nimport { AdvancedSearchSelectUI } from \"./AdvancedSearchSelectUI\";\n\ntype AdvancedSearchSelectProps<T extends Record<string, string>> = UiBaseProps<string[]> & {\n\tconfig: SearchConfig<T>;\n};\n\nexport function AdvancedSearchSelect<T extends Record<string, string>>({\n\tvalue = [],\n\tonChange,\n\tconfig,\n\t...props\n}: AdvancedSearchSelectProps<T>) {\n\tconst [isModalOpen, setIsModalOpen] = useState(false);\n\n\tconst { data: selectedItems } = useAdvancedSearchInitialSelected(config, value);\n\n\tconst handleOpen = useCallback(() => setIsModalOpen(true), []);\n\tconst handleClose = useCallback(() => setIsModalOpen(false), []);\n\tconst handleRemove = useCallback(() => onChange([]), [onChange]);\n\tconst handleSelect = useCallback(\n\t\t(items: T[]) => onChange(items.map((item) => String(item[config.leadingKey]))),\n\t\t[config.leadingKey, onChange]\n\t);\n\tconst getDisplayText = useCallback(\n\t\t(items: T[] | undefined) => {\n\t\t\tif (!items?.length) return;\n\t\t\tif (items.length > 1) return `Выбрано ${items.length} элем.`;\n\t\t\treturn `${(config.leadingText && items[0][config.leadingText]) || items[0][config.leadingKey]}`;\n\t\t},\n\t\t[config.leadingKey, config.leadingText]\n\t);\n\n\treturn (\n\t\t<>\n\t\t\t<AdvancedSearchSelectUI {...props} token={getDisplayText(selectedItems)} onOpen={handleOpen} onClear={handleRemove} />\n\n\t\t\t{isModalOpen && (\n\t\t\t\t<AdvancedSearchModal\n\t\t\t\t\tconfig={config}\n\t\t\t\t\tonClose={handleClose}\n\t\t\t\t\tonItemsSelect={handleSelect}\n\t\t\t\t\tinitialSelectedItems={selectedItems}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</>\n\t);\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { n as e, t } from "../chunks/badge-Cri0-kVK.js";
1
+ import { n as e, t } from "../chunks/badge-DwIUjH0a.js";
2
2
  export { e as Badge, t as BadgeList };
@@ -1,3 +1,3 @@
1
- import { n as e, t } from "../chunks/table-column-interactions-BGd5Lwy9.js";
2
- import { a as n, c as r, d as i, f as a, g as o, h as s, i as c, l, m as u, n as d, o as f, p, r as m, s as h, t as g, u as _ } from "../chunks/base-table-D5IqsjQD.js";
1
+ import { n as e, t } from "../chunks/table-column-interactions-DzEvVuXe.js";
2
+ import { a as n, c as r, d as i, f as a, g as o, h as s, i as c, l, m as u, n as d, o as f, p, r as m, s as h, t as g, u as _ } from "../chunks/base-table-BFsVwXg3.js";
3
3
  export { d as BaseTable, g as FormattedTableCell, e as TableColumnResizeHandle, t as TableHeaderInteractionCell, a as buildBaseTableColumnLayout, h as buildBaseTableMergedCellsLayout, r as buildTableFormattingSnapshot, p as getLeftPinnedColumnOffsets, u as getOrderedVisibleLeafColumns, l as hasTableColumnCustomCellRenderer, s as normalizeTableColumnPinning, o as resolveBaseTableColumnWidth, _ as resolveTableFormattingColumnId, i as shouldUseTableFormatting, f as useTableColumnOrder, n as useTableColumnPinning, c as useTableColumnSizing, m as useTableColumnVisibility };
@@ -1,2 +1,2 @@
1
- import { n as e, t } from "../chunks/button-CC0Jdx1j.js";
1
+ import { n as e, t } from "../chunks/button-BU2kRzwu.js";
2
2
  export { e as Button, t as ButtonRemove };
@@ -1,4 +1,4 @@
1
- import { n as e } from "./button-CC0Jdx1j.js";
1
+ import { n as e } from "./button-BU2kRzwu.js";
2
2
  import { useEffect as t, useEffectEvent as n, useState as r } from "react";
3
3
  import { cn as i } from "@ryuzaki13/react-foundation-lib/utils";
4
4
  import { ChevronLeft as a, ChevronRight as o } from "lucide-react";
@@ -38,19 +38,19 @@ function T(e, t, n) {
38
38
  return e.start.getTime() >= r && e.end.getTime() <= i;
39
39
  }
40
40
  function E({ date: e, value: t, hoveredDate: n, selectsRange: r, selectionOptions: i }) {
41
- let a = f(e, i), o = f(!r && t instanceof Date ? t : null, i);
41
+ let a = f(e, i), o = !r && t instanceof Date ? t : null, s = f(o, i);
42
42
  if (!r || !Array.isArray(t)) return {
43
- selected: h(e, o),
43
+ selected: h(e, s),
44
44
  range: !1,
45
45
  rangeStart: !1,
46
46
  rangeEnd: !1
47
47
  };
48
- let [s, c] = t, l = f(s, i), u = f(c ?? (s ? n : null), i), d = w(a, l), p = w(a, u);
48
+ let [c, l] = t, u = f(c, i), d = f(l ?? (c ? n : null), i), p = w(a, u), m = w(a, d);
49
49
  return {
50
50
  selected: !1,
51
- range: T(a, l, u) && !d && !p,
52
- rangeStart: d,
53
- rangeEnd: p
51
+ range: T(a, u, d) && !p && !m,
52
+ rangeStart: p,
53
+ rangeEnd: m
54
54
  };
55
55
  }
56
56
  var D = {
@@ -436,4 +436,4 @@ function R({ view: i, datePickerLevel: d, selectionMode: h = "day", weekEndDay:
436
436
  //#endregion
437
437
  export { x as a, E as c, v as i, y as n, S as o, b as r, C as s, R as t };
438
438
 
439
- //# sourceMappingURL=CalendarView-KCkhCtK-.js.map
439
+ //# sourceMappingURL=CalendarView-Z_XWk7aI.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CalendarView-KCkhCtK-.js","names":[],"sources":["../../src/date-input/lib/dateInputCalendar.ts","../../src/date-input/ui/CalendarDayView.module.scss","../../src/date-input/ui/CalendarDayView.tsx","../../src/date-input/ui/CalendarMonthView.module.scss","../../src/date-input/ui/CalendarMonthView.tsx","../../src/date-input/ui/CalendarView.module.scss","../../src/date-input/ui/CalendarYearView.module.scss","../../src/date-input/ui/CalendarYearView.tsx","../../src/date-input/ui/CalendarView.tsx"],"sourcesContent":["import {\n\tgetCalendarPeriod,\n\tisDateInsideCalendarPeriod,\n\ttype CalendarPeriod,\n\ttype CalendarPeriodOptions,\n\ttype DateRangeInput,\n\ttype NullableDateRange\n} from \"@ryuzaki13/react-foundation-lib/formatters\";\n\nimport type { DateInputSelectionMode, DateInputWeekEndDay, DatePickerLevel } from \"./types\";\n\nexport const DATE_PICKER_LEVELS = [\"day\", \"month\", \"year\"] as const satisfies readonly DatePickerLevel[];\nexport const DATE_INPUT_SELECTION_MODES = [\"day\", \"week\", \"month\", \"year\"] as const satisfies readonly DateInputSelectionMode[];\nexport const DATE_INPUT_WEEK_END_DAYS = [\"friday\", \"saturday\", \"sunday\"] as const satisfies readonly DateInputWeekEndDay[];\n\n/**\n * Возвращает календарный вид, который удобнее всего открывать для выбранного размера периода.\n */\nexport function getDatePickerLevelForSelectionMode(selectionMode: DateInputSelectionMode): DatePickerLevel {\n\tif (selectionMode === \"month\") return \"month\";\n\tif (selectionMode === \"year\") return \"year\";\n\n\treturn \"day\";\n}\n\n/**\n * Проверяет, разрешён ли календарный вид относительно минимального уровня навигации.\n */\nexport function isDatePickerLevelAvailable(level: DatePickerLevel, minLevel: DatePickerLevel): boolean {\n\treturn DATE_PICKER_LEVELS.indexOf(level) >= DATE_PICKER_LEVELS.indexOf(minLevel);\n}\n\n/**\n * Подбирает вид календаря для режима выбора с учётом ограничения `datePickerLevel`.\n */\nexport function resolveAvailableDatePickerLevel(selectionMode: DateInputSelectionMode, minLevel: DatePickerLevel): DatePickerLevel {\n\tconst preferredLevel = getDatePickerLevelForSelectionMode(selectionMode);\n\n\treturn isDatePickerLevelAvailable(preferredLevel, minLevel) ? preferredLevel : minLevel;\n}\n\nexport interface DateInputPeriodRangeStateOptions {\n\treadonly date: Date;\n\treadonly value: DateRangeInput;\n\treadonly hoveredDate?: Date | null;\n\treadonly selectsRange?: boolean;\n\treadonly selectionOptions?: CalendarPeriodOptions;\n}\n\nexport interface DateInputPeriodRangeState {\n\treadonly selected: boolean;\n\treadonly range: boolean;\n\treadonly rangeStart: boolean;\n\treadonly rangeEnd: boolean;\n}\n\nfunction isSameCalendarPeriod(left: CalendarPeriod | null, right: CalendarPeriod | null): boolean {\n\tif (!left || !right) return false;\n\n\treturn left.start.getTime() === right.start.getTime() && left.end.getTime() === right.end.getTime();\n}\n\nfunction isCalendarPeriodInsideRange(\n\tperiod: CalendarPeriod | null,\n\tstartPeriod: CalendarPeriod | null,\n\tendPeriod: CalendarPeriod | null\n): boolean {\n\tif (!period || !startPeriod || !endPeriod) return false;\n\n\tconst startTime = Math.min(startPeriod.start.getTime(), endPeriod.start.getTime());\n\tconst endTime = Math.max(startPeriod.end.getTime(), endPeriod.end.getTime());\n\n\treturn period.start.getTime() >= startTime && period.end.getTime() <= endTime;\n}\n\n/**\n * Рассчитывает visual-state ячейки календарного периода для single/range режима.\n */\nexport function resolveDateInputPeriodRangeState({\n\tdate,\n\tvalue,\n\thoveredDate,\n\tselectsRange,\n\tselectionOptions\n}: DateInputPeriodRangeStateOptions): DateInputPeriodRangeState {\n\tconst period = getCalendarPeriod(date, selectionOptions);\n\tconst selectedDate = !selectsRange && value instanceof Date ? value : null;\n\tconst selectedSinglePeriod = getCalendarPeriod(selectedDate, selectionOptions);\n\n\tif (!selectsRange || !Array.isArray(value)) {\n\t\treturn {\n\t\t\tselected: isDateInsideCalendarPeriod(date, selectedSinglePeriod),\n\t\t\trange: false,\n\t\t\trangeStart: false,\n\t\t\trangeEnd: false\n\t\t};\n\t}\n\n\tconst [selectedStartDate, selectedEndDate] = value as NullableDateRange;\n\tconst selectedStartPeriod = getCalendarPeriod(selectedStartDate, selectionOptions);\n\tconst previewEndPeriod = getCalendarPeriod(selectedEndDate ?? (selectedStartDate ? hoveredDate : null), selectionOptions);\n\tconst rangeStart = isSameCalendarPeriod(period, selectedStartPeriod);\n\tconst rangeEnd = isSameCalendarPeriod(period, previewEndPeriod);\n\tconst range = isCalendarPeriodInsideRange(period, selectedStartPeriod, previewEndPeriod);\n\n\treturn {\n\t\tselected: false,\n\t\trange: range && !rangeStart && !rangeEnd,\n\t\trangeStart,\n\t\trangeEnd\n\t};\n}\n",".dayView {\n\tpadding: 0;\n}\n\n.weekdays {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(7, 1fr);\n\ttext-align: center;\n\tmargin-bottom: var(--space-sm);\n\tcolor: var(--content-1);\n}\n\n.weekday {\n\tfont-size: var(--font-size-xs);\n}\n\n.daysGrid {\n\tdisplay: grid;\n\tgap: var(--border-width);\n}\n\n.week {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(7, 1fr);\n\tgap: var(--border-width);\n}\n\n.day {\n\t--range-radius: calc(var(--control-height) / 2);\n\n\theight: var(--control-height);\n\tcursor: pointer;\n\tborder-radius: var(--radius-xs);\n\t// font-size: var(--font-size-sm);\n\n\tbackground-color: var(--surface-1);\n\n\t&:hover:not(.disabled) {\n\t\tbackground-color: var(--surface-accent);\n\t}\n\n\t&.outsideMonth {\n\t\tbackground-color: transparent;\n\t\tcolor: var(--content-2);\n\t}\n\n\t&.periodSelection:hover:not(.disabled):not(.periodPreview):not(.selected) {\n\t\tbackground-color: var(--surface-1);\n\t}\n\n\t&.periodSelection.outsideMonth:hover:not(.disabled):not(.periodPreview):not(.selected) {\n\t\tbackground-color: transparent;\n\t}\n\n\t&.periodPreview {\n\t\tbackground-color: var(--surface-accent);\n\t\tcolor: var(--content-0);\n\t}\n\n\t&.range {\n\t\tbackground-color: var(--surface-accent);\n\t\tcolor: var(--content-0);\n\t}\n\n\t&.rangeStart {\n\t\t// border-top-left-radius: var(--range-radius);\n\t\t// border-bottom-left-radius: var(--range-radius);\n\t}\n\n\t&.rangeEnd {\n\t\t// border-top-right-radius: var(--range-radius);\n\t\t// border-bottom-right-radius: var(--range-radius);\n\t}\n\n\t&.selected,\n\t&.rangeStart,\n\t&.rangeEnd {\n\t\tbackground-color: var(--surface-accent);\n\t\tcolor: var(--content-accent);\n\t\tfont-weight: 600;\n\t\tfont-variation-settings: \"wght\" 600;\n\t}\n\n\t&.weekend:not(.selected):not(.range):not(.rangeStart):not(.rangeEnd) {\n\t\tcolor: var(--status-error-fill);\n\t}\n\n\t&.disabled {\n\t\tcolor: var(--content-2);\n\t\tcursor: not-allowed;\n\n\t\t&:hover {\n\t\t\tbackground: none;\n\t\t}\n\t}\n\n\t&.now {\n\t\tborder: var(--border);\n\t\tcolor: var(--status-info-text);\n\t\tborder-color: var(--status-info-text);\n\t}\n}\n","import { useState } from \"react\";\n\nimport {\n\tcreateCalendarDate,\n\tgetCalendarPeriod,\n\tgetStartOfDay,\n\tisCalendarPeriodWithinDateBounds,\n\tisDateInsideCalendarPeriod,\n\tisSameCalendarDay,\n\ttype CalendarPeriodOptions,\n\ttype DateRangeInput\n} from \"@ryuzaki13/react-foundation-lib/formatters\";\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { type DateInputSelectionMode, type DateInputWeekEndDay } from \"../lib\";\n\nimport styles from \"./CalendarDayView.module.scss\";\n\nconst weekDays = [\"Пн\", \"Вт\", \"Ср\", \"Чт\", \"Пт\", \"Сб\", \"Вс\"];\nconst dayLabelFormatter = new Intl.DateTimeFormat(\"ru-RU\", {\n\tweekday: \"long\",\n\tyear: \"numeric\",\n\tmonth: \"long\",\n\tday: \"numeric\"\n});\n\ninterface DayViewProps {\n\tnow: Date;\n\tcurrentDate: Date;\n\tvalue: DateRangeInput;\n\tonChange: (date: Date) => void;\n\tminDate?: Date;\n\tmaxDate?: Date;\n\tselectsRange?: boolean;\n\tselectionMode?: DateInputSelectionMode;\n\tweekEndDay?: DateInputWeekEndDay;\n}\n\n/**\n * Отображает сетку дней месяца в календарной семантике без timezone-сдвига.\n */\nexport const CalendarDayView: React.FC<DayViewProps> = ({\n\tnow,\n\tcurrentDate,\n\tvalue,\n\tonChange,\n\tminDate,\n\tmaxDate,\n\tselectsRange,\n\tselectionMode = \"day\",\n\tweekEndDay = \"sunday\"\n}) => {\n\tconst [hoveredDate, setHoveredDate] = useState<Date | null>(null);\n\tconst selectionOptions: CalendarPeriodOptions = {\n\t\tselectionMode,\n\t\tweekEndDay\n\t};\n\n\t/**\n\t * Генерирует недели для текущего месяца с учётом дней соседних месяцев.\n\t */\n\tconst generateCalendarDays = () => {\n\t\tconst year = currentDate.getFullYear();\n\t\tconst month = currentDate.getMonth();\n\n\t\tconst firstDay = createCalendarDate(year, month, 1);\n\t\tconst lastDay = createCalendarDate(year, month + 1, 0);\n\t\tconst prevMonthDays = firstDay.getDay() === 0 ? 6 : firstDay.getDay() - 1;\n\t\tconst nextMonthDays = 6 * 7 - (prevMonthDays + lastDay.getDate());\n\n\t\tconst days: Date[] = [];\n\t\tconst prevMonthLastDay = createCalendarDate(year, month, 0).getDate();\n\n\t\tfor (let index = prevMonthDays; index > 0; index -= 1) {\n\t\t\tdays.push(createCalendarDate(year, month - 1, prevMonthLastDay - index + 1));\n\t\t}\n\n\t\tfor (let day = 1; day <= lastDay.getDate(); day += 1) {\n\t\t\tdays.push(createCalendarDate(year, month, day));\n\t\t}\n\n\t\tfor (let day = 1; day <= nextMonthDays; day += 1) {\n\t\t\tdays.push(createCalendarDate(year, month + 1, day));\n\t\t}\n\n\t\tconst weeks: Date[][] = [];\n\t\tfor (let index = 0; index < days.length; index += 7) {\n\t\t\tweeks.push(days.slice(index, index + 7));\n\t\t}\n\n\t\treturn weeks;\n\t};\n\n\tconst weeks = generateCalendarDays();\n\tconst selectedStartDate = selectsRange && Array.isArray(value) ? value[0] : null;\n\tconst selectedEndDate = selectsRange && Array.isArray(value) ? value[1] : null;\n\tconst selectedDate = !selectsRange ? (value as Date | null) : null;\n\tconst selectedSinglePeriod = getCalendarPeriod(selectedDate, selectionOptions);\n\tconst hoveredPeriod = getCalendarPeriod(hoveredDate, selectionOptions);\n\tconst previewEndDate = selectedEndDate ?? (selectedStartDate ? (hoveredPeriod?.end ?? null) : null);\n\tconst previewsWeekPeriod = selectionMode === \"week\";\n\tconst previewsStandalonePeriod = previewsWeekPeriod && (!selectsRange || !selectedStartDate);\n\n\t/**\n\t * Проверяет, лежит ли день внутри выбранного или preview-диапазона.\n\t */\n\tconst isInRange = (date: Date) => {\n\t\tif (!selectsRange || !selectedStartDate || !previewEndDate) return false;\n\n\t\tconst dateMs = getStartOfDay(date).getTime();\n\t\tconst startMs = selectedStartDate.getTime();\n\t\tconst endMs = previewEndDate.getTime();\n\n\t\treturn dateMs >= Math.min(startMs, endMs) && dateMs <= Math.max(startMs, endMs);\n\t};\n\n\t/**\n\t * Проверяет ограничения на выбор даты.\n\t */\n\tconst isDisabled = (date: Date) => {\n\t\treturn !isCalendarPeriodWithinDateBounds(getCalendarPeriod(date, selectionOptions), { minDate, maxDate });\n\t};\n\n\t/**\n\t * Обновляет preview-конец диапазона при движении мыши.\n\t */\n\tconst handleDayHover = (date: Date, disabled: boolean) => {\n\t\tif (disabled) return;\n\n\t\tif (previewsWeekPeriod) {\n\t\t\tsetHoveredDate(date);\n\t\t}\n\n\t\tif (!selectsRange || !selectedStartDate || selectedEndDate) return;\n\t\tif (!previewsWeekPeriod) setHoveredDate(date);\n\t};\n\n\t/**\n\t * Сбрасывает preview незавершённого диапазона при уходе курсора.\n\t */\n\tconst handleGridLeave = () => {\n\t\tif (previewsWeekPeriod || !selectedEndDate) {\n\t\t\tsetHoveredDate(null);\n\t\t}\n\t};\n\n\treturn (\n\t\t<div className={styles.dayView}>\n\t\t\t<div className={styles.weekdays}>\n\t\t\t\t{weekDays.map((day) => (\n\t\t\t\t\t<div key={day} className={styles.weekday}>\n\t\t\t\t\t\t{day}\n\t\t\t\t\t</div>\n\t\t\t\t))}\n\t\t\t</div>\n\n\t\t\t<div className={styles.daysGrid} onMouseLeave={handleGridLeave}>\n\t\t\t\t{weeks.map((week, weekIndex) => (\n\t\t\t\t\t<div key={weekIndex} className={styles.week}>\n\t\t\t\t\t\t{week.map((day, dayIndex) => {\n\t\t\t\t\t\t\tconst isCurrentMonth = day.getMonth() === currentDate.getMonth();\n\t\t\t\t\t\t\tconst isSelected = isDateInsideCalendarPeriod(day, selectedSinglePeriod);\n\t\t\t\t\t\t\tconst isPeriodPreview = previewsStandalonePeriod && isDateInsideCalendarPeriod(day, hoveredPeriod);\n\t\t\t\t\t\t\tconst isRange = isInRange(day);\n\t\t\t\t\t\t\tconst isStart = isSameCalendarDay(day, selectedStartDate);\n\t\t\t\t\t\t\tconst isEnd = isSameCalendarDay(day, previewEndDate);\n\t\t\t\t\t\t\tconst isNow = isSameCalendarDay(day, now);\n\t\t\t\t\t\t\tconst disabled = isDisabled(day);\n\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tkey={`${weekIndex}-${dayIndex}`}\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tonClick={() => !disabled && onChange(day)}\n\t\t\t\t\t\t\t\t\tonMouseEnter={() => handleDayHover(day, disabled)}\n\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\tdata-ui=\"calendar-day-button\"\n\t\t\t\t\t\t\t\t\tdata-action=\"select-calendar-day\"\n\t\t\t\t\t\t\t\t\tclassName={cn(styles.day, {\n\t\t\t\t\t\t\t\t\t\t[styles.outsideMonth]: !isCurrentMonth,\n\t\t\t\t\t\t\t\t\t\t[styles.periodSelection]: selectionMode === \"week\",\n\t\t\t\t\t\t\t\t\t\t[styles.periodPreview]: isPeriodPreview && !isSelected,\n\t\t\t\t\t\t\t\t\t\t[styles.selected]: isSelected,\n\t\t\t\t\t\t\t\t\t\t[styles.range]: isRange && !isStart && !isEnd,\n\t\t\t\t\t\t\t\t\t\t[styles.rangeStart]: isStart,\n\t\t\t\t\t\t\t\t\t\t[styles.rangeEnd]: isEnd,\n\t\t\t\t\t\t\t\t\t\t[styles.disabled]: disabled,\n\t\t\t\t\t\t\t\t\t\t[styles.weekend]: dayIndex > 4,\n\t\t\t\t\t\t\t\t\t\t[styles.now]: isNow\n\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\taria-label={dayLabelFormatter.format(day)}\n\t\t\t\t\t\t\t\t\taria-pressed={isSelected || isRange || isStart || isEnd}>\n\t\t\t\t\t\t\t\t\t{day.getDate()}\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t</div>\n\t\t\t\t))}\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n",".monthView {\n\tpadding: 0;\n}\n\n.monthsGrid {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(3, 1fr);\n\tgap: var(--border-width);\n\talign-content: center;\n\n\t// min-height: calc(12em * var(--line-height));\n}\n\n.month {\n\theight: var(--control-height);\n\tcursor: pointer;\n\tborder-radius: var(--radius-xs);\n\t// font-size: var(--font-size-sm);\n\ttext-transform: capitalize;\n\n\tbackground-color: var(--surface-1);\n\n\t&:hover:not(.disabled) {\n\t\tbackground-color: var(--surface-accent);\n\t}\n\n\t&.range {\n\t\tbackground-color: var(--surface-accent);\n\t\tcolor: var(--content-0);\n\t}\n\n\t&.selected,\n\t&.rangeStart,\n\t&.rangeEnd {\n\t\tbackground-color: var(--surface-accent);\n\t\tcolor: var(--content-accent);\n\t\tfont-weight: 600;\n\t\tfont-variation-settings: \"wght\" 600;\n\t}\n\n\t&.disabled {\n\t\tcolor: var(--content-2);\n\t\tcursor: not-allowed;\n\n\t\t&:hover {\n\t\t\tbackground: none;\n\t\t}\n\t}\n}\n","import { useState } from \"react\";\n\nimport {\n\tcreateCalendarDate,\n\tgetCalendarPeriod,\n\tisCalendarPeriodWithinDateBounds,\n\ttype CalendarPeriodOptions,\n\ttype DateRangeInput\n} from \"@ryuzaki13/react-foundation-lib/formatters\";\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { resolveDateInputPeriodRangeState } from \"../lib\";\n\nimport styles from \"./CalendarMonthView.module.scss\";\n\nimport type { DateInputSelectionMode, DateInputWeekEndDay } from \"../lib\";\n\nconst monthLabelFormatter = new Intl.DateTimeFormat(\"ru-RU\", { month: \"short\" });\nconst monthAriaFormatter = new Intl.DateTimeFormat(\"ru-RU\", { month: \"long\", year: \"numeric\" });\n\ninterface MonthViewProps {\n\tcurrentDate: Date;\n\tvalue: DateRangeInput;\n\tonChange: (date: Date) => void;\n\tminDate?: Date;\n\tmaxDate?: Date;\n\tselectsRange?: boolean;\n\tselectsPeriod?: boolean;\n\tselectionMode?: DateInputSelectionMode;\n\tweekEndDay?: DateInputWeekEndDay;\n}\n\n/**\n * Отображает выбор месяца в календарной семантике без timezone-сдвига.\n */\nexport const CalendarMonthView: React.FC<MonthViewProps> = ({\n\tcurrentDate,\n\tvalue,\n\tonChange,\n\tminDate,\n\tmaxDate,\n\tselectsRange,\n\tselectsPeriod,\n\tselectionMode = \"day\",\n\tweekEndDay = \"sunday\"\n}) => {\n\tconst [hoveredDate, setHoveredDate] = useState<Date | null>(null);\n\tconst months = Array.from({ length: 12 }, (_, index) => index);\n\tconst currentYear = currentDate.getFullYear();\n\tconst selectionOptions: CalendarPeriodOptions = {\n\t\tselectionMode,\n\t\tweekEndDay\n\t};\n\tconst selectedStartDate = selectsRange && Array.isArray(value) ? value[0] : null;\n\tconst selectedEndDate = selectsRange && Array.isArray(value) ? value[1] : null;\n\n\t/**\n\t * Возвращает сокращённое имя месяца.\n\t */\n\tconst getMonthName = (monthIndex: number) => monthLabelFormatter.format(createCalendarDate(currentYear, monthIndex, 1));\n\n\t/**\n\t * Проверяет, запрещён ли выбор месяца по ограничениям.\n\t */\n\tconst isDisabled = (monthIndex: number) => {\n\t\tif (!minDate && !maxDate) return false;\n\n\t\tconst monthStart = createCalendarDate(currentYear, monthIndex, 1);\n\t\tconst monthEnd = createCalendarDate(currentYear, monthIndex + 1, 0, 23, 59, 59);\n\n\t\tif (selectsPeriod) {\n\t\t\treturn !isCalendarPeriodWithinDateBounds(getCalendarPeriod(monthStart, selectionOptions), { minDate, maxDate });\n\t\t}\n\n\t\tif (minDate && monthEnd < minDate) return true;\n\t\tif (maxDate && monthStart > maxDate) return true;\n\n\t\treturn false;\n\t};\n\n\t/**\n\t * Обновляет preview-конец диапазона при движении мыши.\n\t */\n\tconst handleMonthHover = (date: Date, disabled: boolean) => {\n\t\tif (!selectsRange || !selectedStartDate || selectedEndDate || disabled) return;\n\t\tsetHoveredDate(date);\n\t};\n\n\t/**\n\t * Сбрасывает preview незавершённого диапазона при уходе курсора.\n\t */\n\tconst handleGridLeave = () => {\n\t\tif (!selectedEndDate) {\n\t\t\tsetHoveredDate(null);\n\t\t}\n\t};\n\n\treturn (\n\t\t<div className={styles.monthView}>\n\t\t\t<div className={styles.monthsGrid} onMouseLeave={handleGridLeave}>\n\t\t\t\t{months.map((monthIndex) => {\n\t\t\t\t\tconst disabled = isDisabled(monthIndex);\n\t\t\t\t\tconst monthDate = createCalendarDate(currentYear, monthIndex, 1);\n\t\t\t\t\tconst rangeState = resolveDateInputPeriodRangeState({\n\t\t\t\t\t\tdate: monthDate,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\thoveredDate,\n\t\t\t\t\t\tselectsRange,\n\t\t\t\t\t\tselectionOptions\n\t\t\t\t\t});\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\tkey={monthIndex}\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={() => !disabled && onChange(monthDate)}\n\t\t\t\t\t\t\tonMouseEnter={() => handleMonthHover(monthDate, disabled)}\n\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\tdata-ui=\"calendar-month-button\"\n\t\t\t\t\t\t\tdata-action=\"select-calendar-month\"\n\t\t\t\t\t\t\tclassName={cn(styles.month, {\n\t\t\t\t\t\t\t\t[styles.selected]: rangeState.selected,\n\t\t\t\t\t\t\t\t[styles.range]: rangeState.range,\n\t\t\t\t\t\t\t\t[styles.rangeStart]: rangeState.rangeStart,\n\t\t\t\t\t\t\t\t[styles.rangeEnd]: rangeState.rangeEnd,\n\t\t\t\t\t\t\t\t[styles.disabled]: disabled\n\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\taria-label={monthAriaFormatter.format(monthDate)}\n\t\t\t\t\t\t\taria-pressed={rangeState.selected || rangeState.range || rangeState.rangeStart || rangeState.rangeEnd}>\n\t\t\t\t\t\t\t{getMonthName(monthIndex)}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n",".calendarView {\n\twidth: calc(18em + var(--width-add));\n}\n\n.calendarHeader {\n\tdisplay: flex;\n\tjustify-content: space-between;\n\talign-items: center;\n\tpadding-bottom: var(--space-sm);\n\tmargin-bottom: var(--space-sm);\n\tgap: var(--space-sm);\n\tborder-bottom: var(--border);\n}\n",".yearView {\n\tpadding: 0;\n}\n\n.yearsGrid {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(3, 1fr);\n\tgap: var(--border-width);\n}\n\n.year {\n\theight: var(--control-height);\n\tcursor: pointer;\n\tborder-radius: var(--radius-xs);\n\t// font-size: var(--font-size-sm);\n\n\tbackground-color: var(--surface-1);\n\n\t&:hover:not(.disabled) {\n\t\tbackground-color: var(--surface-accent);\n\t}\n\n\t&.range {\n\t\tbackground-color: var(--surface-accent);\n\t\tcolor: var(--content-0);\n\t}\n\n\t&.selected,\n\t&.rangeStart,\n\t&.rangeEnd {\n\t\tbackground-color: var(--surface-accent);\n\t\tcolor: var(--content-accent);\n\t\tfont-weight: 600;\n\t\tfont-variation-settings: \"wght\" 600;\n\t}\n\n\t&.disabled {\n\t\tcolor: var(--content-2);\n\t\tcursor: not-allowed;\n\n\t\t&:hover {\n\t\t\tbackground: none;\n\t\t}\n\t}\n}\n","import { useState } from \"react\";\n\nimport {\n\tcreateCalendarDate,\n\tgetCalendarPeriod,\n\tisCalendarPeriodWithinDateBounds,\n\ttype CalendarPeriodOptions,\n\ttype DateRangeInput\n} from \"@ryuzaki13/react-foundation-lib/formatters\";\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { resolveDateInputPeriodRangeState } from \"../lib\";\n\nimport styles from \"./CalendarYearView.module.scss\";\n\nimport type { DateInputSelectionMode, DateInputWeekEndDay } from \"../lib\";\n\ninterface YearViewProps {\n\tcurrentDate: Date;\n\tvalue: DateRangeInput;\n\tonChange: (date: Date) => void;\n\tminDate?: Date;\n\tmaxDate?: Date;\n\tselectsRange?: boolean;\n\tselectsPeriod?: boolean;\n\tselectionMode?: DateInputSelectionMode;\n\tweekEndDay?: DateInputWeekEndDay;\n}\n\n/**\n * Отображает выбор года в календарной семантике без timezone-сдвига.\n */\nexport const CalendarYearView: React.FC<YearViewProps> = ({\n\tcurrentDate,\n\tvalue,\n\tonChange,\n\tminDate,\n\tmaxDate,\n\tselectsRange,\n\tselectsPeriod,\n\tselectionMode = \"day\",\n\tweekEndDay = \"sunday\"\n}) => {\n\tconst [hoveredDate, setHoveredDate] = useState<Date | null>(null);\n\tconst startYear = Math.floor(currentDate.getFullYear() / 12) * 12;\n\tconst years = Array.from({ length: 12 }, (_, index) => startYear + index);\n\tconst selectionOptions: CalendarPeriodOptions = {\n\t\tselectionMode,\n\t\tweekEndDay\n\t};\n\tconst selectedStartDate = selectsRange && Array.isArray(value) ? value[0] : null;\n\tconst selectedEndDate = selectsRange && Array.isArray(value) ? value[1] : null;\n\n\t/**\n\t * Проверяет ограничения на выбор года.\n\t */\n\tconst isDisabled = (year: number) => {\n\t\tif (!minDate && !maxDate) return false;\n\n\t\tconst yearStart = createCalendarDate(year, 0, 1);\n\t\tconst yearEnd = createCalendarDate(year, 11, 31, 23, 59, 59);\n\n\t\tif (selectsPeriod) {\n\t\t\treturn !isCalendarPeriodWithinDateBounds(getCalendarPeriod(yearStart, selectionOptions), { minDate, maxDate });\n\t\t}\n\n\t\tif (minDate && yearEnd < minDate) return true;\n\t\tif (maxDate && yearStart > maxDate) return true;\n\n\t\treturn false;\n\t};\n\n\t/**\n\t * Обновляет preview-конец диапазона при движении мыши.\n\t */\n\tconst handleYearHover = (date: Date, disabled: boolean) => {\n\t\tif (!selectsRange || !selectedStartDate || selectedEndDate || disabled) return;\n\t\tsetHoveredDate(date);\n\t};\n\n\t/**\n\t * Сбрасывает preview незавершённого диапазона при уходе курсора.\n\t */\n\tconst handleGridLeave = () => {\n\t\tif (!selectedEndDate) {\n\t\t\tsetHoveredDate(null);\n\t\t}\n\t};\n\n\treturn (\n\t\t<div className={styles.yearView}>\n\t\t\t<div className={styles.yearsGrid} onMouseLeave={handleGridLeave}>\n\t\t\t\t{years.map((year) => {\n\t\t\t\t\tconst disabled = isDisabled(year);\n\t\t\t\t\tconst yearDate = createCalendarDate(year, 0, 1);\n\t\t\t\t\tconst rangeState = resolveDateInputPeriodRangeState({\n\t\t\t\t\t\tdate: yearDate,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\thoveredDate,\n\t\t\t\t\t\tselectsRange,\n\t\t\t\t\t\tselectionOptions\n\t\t\t\t\t});\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\tkey={year}\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={() => !disabled && onChange(yearDate)}\n\t\t\t\t\t\t\tonMouseEnter={() => handleYearHover(yearDate, disabled)}\n\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\tdata-ui=\"calendar-year-button\"\n\t\t\t\t\t\t\tdata-action=\"select-calendar-year\"\n\t\t\t\t\t\t\tclassName={cn(styles.year, {\n\t\t\t\t\t\t\t\t[styles.selected]: rangeState.selected,\n\t\t\t\t\t\t\t\t[styles.range]: rangeState.range,\n\t\t\t\t\t\t\t\t[styles.rangeStart]: rangeState.rangeStart,\n\t\t\t\t\t\t\t\t[styles.rangeEnd]: rangeState.rangeEnd,\n\t\t\t\t\t\t\t\t[styles.disabled]: disabled\n\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\taria-label={year.toString()}\n\t\t\t\t\t\t\taria-pressed={rangeState.selected || rangeState.range || rangeState.rangeStart || rangeState.rangeEnd}>\n\t\t\t\t\t\t\t{year}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n","import { useEffect, useEffectEvent, useState } from \"react\";\n\nimport {\n\taddCalendarMonths,\n\taddCalendarYears,\n\tgetCalendarPeriod,\n\tgetStartOfDay,\n\tisCalendarPeriodWithinDateBounds,\n\tisDateRangeTuple,\n\ttype CalendarPeriodOptions,\n\ttype NullableDateRange\n} from \"@ryuzaki13/react-foundation-lib/formatters\";\nimport { ChevronLeft, ChevronRight } from \"lucide-react\";\n\nimport { Button } from \"../../button\";\nimport { isDatePickerLevelAvailable, type CalendarType, type DateInputSelectionMode, type DateInputWeekEndDay } from \"../lib\";\n\nimport { CalendarDayView } from \"./CalendarDayView\";\nimport { CalendarMonthView } from \"./CalendarMonthView\";\nimport styles from \"./CalendarView.module.scss\";\nimport { CalendarYearView } from \"./CalendarYearView\";\n\ninterface BaseCalendarViewProps {\n\tview: CalendarType;\n\tdatePickerLevel: CalendarType;\n\tselectionMode?: DateInputSelectionMode;\n\tweekEndDay?: DateInputWeekEndDay;\n\tonViewChange: (view: CalendarType) => void;\n}\n\ninterface CalendarViewProps extends BaseCalendarViewProps {\n\tselectsRange?: boolean;\n\tvalue: Date | NullableDateRange | null;\n\tonChange: (date: Date | NullableDateRange) => void;\n\tminDate?: Date;\n\tmaxDate?: Date;\n\tcurrentDate?: Date;\n\tonCurrentDateChange?: (date: Date) => void;\n}\n\n/**\n * Отображает календарь выбора даты в календарной семантике без timezone-сдвига.\n */\nexport function CalendarView({\n\tview,\n\tdatePickerLevel,\n\tselectionMode = \"day\",\n\tweekEndDay = \"sunday\",\n\tonViewChange,\n\t...props\n}: CalendarViewProps) {\n\tconst [dateNow] = useState(() => getStartOfDay(new Date()));\n\tconst [uncontrolledCurrentDate, setUncontrolledCurrentDate] = useState<Date>(() => {\n\t\tif (props.selectsRange && isDateRangeTuple(props.value) && props.value[0] instanceof Date) {\n\t\t\treturn props.value[0];\n\t\t}\n\n\t\tif (!props.selectsRange && props.value instanceof Date) {\n\t\t\treturn props.value;\n\t\t}\n\n\t\treturn getStartOfDay(new Date());\n\t});\n\tconst currentDate = props.currentDate ?? uncontrolledCurrentDate;\n\tconst selectionOptions: CalendarPeriodOptions = {\n\t\tselectionMode,\n\t\tweekEndDay\n\t};\n\n\t/**\n\t * Обновляет видимую календарную дату в управляемом или неуправляемом режиме.\n\t */\n\tconst setCurrentDate = (value: Date | ((prevValue: Date) => Date)) => {\n\t\tconst nextValue = typeof value === \"function\" ? value(currentDate) : value;\n\n\t\tif (props.currentDate === undefined) {\n\t\t\tsetUncontrolledCurrentDate(nextValue);\n\t\t}\n\n\t\tprops.onCurrentDateChange?.(nextValue);\n\t};\n\n\t/**\n\t * Синхронизирует видимый месяц/год с внешним значением поля.\n\t */\n\tconst syncCurrentDate = useEffectEvent((nextValue: Date | NullableDateRange | null) => {\n\t\tif (props.selectsRange && Array.isArray(nextValue) && nextValue[0] instanceof Date) {\n\t\t\tsetCurrentDate(nextValue[0]);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!props.selectsRange && nextValue instanceof Date) {\n\t\t\tsetCurrentDate(nextValue);\n\t\t}\n\t});\n\n\tuseEffect(() => {\n\t\tsyncCurrentDate(props.value);\n\t}, [props.value]);\n\n\t/**\n\t * Переключает видимую область календаря назад.\n\t */\n\tconst goToPrevious = () => {\n\t\tif (view === \"day\") {\n\t\t\tsetCurrentDate((prev) => addCalendarMonths(prev, -1));\n\t\t\treturn;\n\t\t}\n\n\t\tif (view === \"month\") {\n\t\t\tsetCurrentDate((prev) => addCalendarYears(prev, -1));\n\t\t\treturn;\n\t\t}\n\n\t\tsetCurrentDate((prev) => addCalendarYears(prev, -12));\n\t};\n\n\t/**\n\t * Переключает видимую область календаря вперёд.\n\t */\n\tconst goToNext = () => {\n\t\tif (view === \"day\") {\n\t\t\tsetCurrentDate((prev) => addCalendarMonths(prev, 1));\n\t\t\treturn;\n\t\t}\n\n\t\tif (view === \"month\") {\n\t\t\tsetCurrentDate((prev) => addCalendarYears(prev, 1));\n\t\t\treturn;\n\t\t}\n\n\t\tsetCurrentDate((prev) => addCalendarYears(prev, 12));\n\t};\n\n\t/**\n\t * Возвращает заголовок текущего календарного вида.\n\t */\n\tconst renderHeader = () => {\n\t\tlet title = \"\";\n\t\tif (view === \"day\") {\n\t\t\ttitle = currentDate.toLocaleDateString(\"ru-RU\", {\n\t\t\t\tmonth: \"long\",\n\t\t\t\tyear: \"numeric\"\n\t\t\t});\n\t\t} else if (view === \"month\") {\n\t\t\ttitle = currentDate.getFullYear().toString();\n\t\t} else {\n\t\t\tconst startYear = Math.floor(currentDate.getFullYear() / 12) * 12;\n\t\t\tconst endYear = startYear + 11;\n\t\t\ttitle = `${startYear} - ${endYear}`;\n\t\t}\n\n\t\treturn (\n\t\t\t<div className={styles.calendarHeader}>\n\t\t\t\t<Button\n\t\t\t\t\ticon={<ChevronLeft />}\n\t\t\t\t\tonClick={goToPrevious}\n\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\taria-label=\"Предыдущий\"\n\t\t\t\t\tdata-action=\"calendar-previous\"\n\t\t\t\t/>\n\n\t\t\t\t<Button\n\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\tif (view === \"day\") onViewChange(\"month\");\n\t\t\t\t\t\telse if (view === \"month\") onViewChange(\"year\");\n\t\t\t\t\t}}\n\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\tclassName=\"flex1\"\n\t\t\t\t\tdata-ui=\"calendar-view-switch-button\"\n\t\t\t\t\tdata-action=\"calendar-switch-view\">\n\t\t\t\t\t{title}\n\t\t\t\t</Button>\n\n\t\t\t\t<Button\n\t\t\t\t\ticon={<ChevronRight />}\n\t\t\t\t\tonClick={goToNext}\n\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\taria-label=\"Следующий\"\n\t\t\t\t\tdata-ui=\"calendar-next-button\"\n\t\t\t\t\tdata-action=\"calendar-next\"\n\t\t\t\t/>\n\t\t\t</div>\n\t\t);\n\t};\n\n\t/**\n\t * Отрисовывает активный режим календаря.\n\t */\n\tconst renderView = () => {\n\t\tconst handleDateSelect = (date: Date) => {\n\t\t\tconst selectedPeriod = getCalendarPeriod(date, selectionOptions);\n\t\t\tif (!selectedPeriod || !isCalendarPeriodWithinDateBounds(selectedPeriod, { minDate: props.minDate, maxDate: props.maxDate }))\n\t\t\t\treturn;\n\n\t\t\tif (props.selectsRange) {\n\t\t\t\tlet selectedStartDate: Date | null = null;\n\t\t\t\tlet selectedEndDate: Date | null = null;\n\n\t\t\t\tif (Array.isArray(props.value)) {\n\t\t\t\t\t[selectedStartDate, selectedEndDate] = props.value;\n\t\t\t\t}\n\n\t\t\t\tif (!selectedStartDate || selectedEndDate) {\n\t\t\t\t\tprops.onChange([selectedPeriod.start, null]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst startPeriod = getCalendarPeriod(selectedStartDate, selectionOptions);\n\t\t\t\tif (!startPeriod) return;\n\n\t\t\t\tif (selectedPeriod.start < startPeriod.start) {\n\t\t\t\t\tprops.onChange([selectedPeriod.start, startPeriod.end]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tprops.onChange([startPeriod.start, selectedPeriod.end]);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tprops.onChange(selectedPeriod.start);\n\t\t};\n\n\t\tconst handleMonthSelect = (date: Date) => {\n\t\t\tsetCurrentDate(date);\n\n\t\t\tif (selectionMode === \"month\" || !isDatePickerLevelAvailable(\"day\", datePickerLevel)) {\n\t\t\t\thandleDateSelect(date);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tonViewChange(\"day\");\n\t\t};\n\n\t\tconst handleYearSelect = (date: Date) => {\n\t\t\tsetCurrentDate(date);\n\n\t\t\tif (selectionMode === \"year\" || !isDatePickerLevelAvailable(\"month\", datePickerLevel)) {\n\t\t\t\thandleDateSelect(date);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tonViewChange(\"month\");\n\t\t};\n\n\t\tswitch (view) {\n\t\t\tcase \"day\":\n\t\t\t\treturn (\n\t\t\t\t\t<CalendarDayView\n\t\t\t\t\t\tnow={dateNow}\n\t\t\t\t\t\tcurrentDate={currentDate}\n\t\t\t\t\t\tvalue={props.value}\n\t\t\t\t\t\tonChange={handleDateSelect}\n\t\t\t\t\t\tminDate={props.minDate}\n\t\t\t\t\t\tmaxDate={props.maxDate}\n\t\t\t\t\t\tselectsRange={props.selectsRange}\n\t\t\t\t\t\tselectionMode={selectionMode}\n\t\t\t\t\t\tweekEndDay={weekEndDay}\n\t\t\t\t\t/>\n\t\t\t\t);\n\t\t\tcase \"month\":\n\t\t\t\treturn (\n\t\t\t\t\t<CalendarMonthView\n\t\t\t\t\t\tcurrentDate={currentDate}\n\t\t\t\t\t\tvalue={props.value}\n\t\t\t\t\t\tonChange={handleMonthSelect}\n\t\t\t\t\t\tminDate={props.minDate}\n\t\t\t\t\t\tmaxDate={props.maxDate}\n\t\t\t\t\t\tselectsRange={props.selectsRange}\n\t\t\t\t\t\tselectsPeriod={selectionMode === \"month\" || !isDatePickerLevelAvailable(\"day\", datePickerLevel)}\n\t\t\t\t\t\tselectionMode={selectionMode}\n\t\t\t\t\t\tweekEndDay={weekEndDay}\n\t\t\t\t\t/>\n\t\t\t\t);\n\t\t\tcase \"year\":\n\t\t\t\treturn (\n\t\t\t\t\t<CalendarYearView\n\t\t\t\t\t\tcurrentDate={currentDate}\n\t\t\t\t\t\tvalue={props.value}\n\t\t\t\t\t\tonChange={handleYearSelect}\n\t\t\t\t\t\tminDate={props.minDate}\n\t\t\t\t\t\tmaxDate={props.maxDate}\n\t\t\t\t\t\tselectsRange={props.selectsRange}\n\t\t\t\t\t\tselectsPeriod={selectionMode === \"year\" || !isDatePickerLevelAvailable(\"month\", datePickerLevel)}\n\t\t\t\t\t\tselectionMode={selectionMode}\n\t\t\t\t\t\tweekEndDay={weekEndDay}\n\t\t\t\t\t/>\n\t\t\t\t);\n\t\t\tdefault:\n\t\t\t\treturn null;\n\t\t}\n\t};\n\n\treturn (\n\t\t<div className={styles.calendarView}>\n\t\t\t{renderHeader()}\n\t\t\t{renderView()}\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CalendarView-Z_XWk7aI.js","names":[],"sources":["../../src/date-input/lib/dateInputCalendar.ts","../../src/date-input/ui/CalendarDayView.module.scss","../../src/date-input/ui/CalendarDayView.tsx","../../src/date-input/ui/CalendarMonthView.module.scss","../../src/date-input/ui/CalendarMonthView.tsx","../../src/date-input/ui/CalendarView.module.scss","../../src/date-input/ui/CalendarYearView.module.scss","../../src/date-input/ui/CalendarYearView.tsx","../../src/date-input/ui/CalendarView.tsx"],"sourcesContent":["import {\n\tgetCalendarPeriod,\n\tisDateInsideCalendarPeriod,\n\ttype CalendarPeriod,\n\ttype CalendarPeriodOptions,\n\ttype DateRangeInput,\n\ttype NullableDateRange\n} from \"@ryuzaki13/react-foundation-lib/formatters\";\n\nimport type { DateInputSelectionMode, DateInputWeekEndDay, DatePickerLevel } from \"./types\";\n\nexport const DATE_PICKER_LEVELS = [\"day\", \"month\", \"year\"] as const satisfies readonly DatePickerLevel[];\nexport const DATE_INPUT_SELECTION_MODES = [\"day\", \"week\", \"month\", \"year\"] as const satisfies readonly DateInputSelectionMode[];\nexport const DATE_INPUT_WEEK_END_DAYS = [\"friday\", \"saturday\", \"sunday\"] as const satisfies readonly DateInputWeekEndDay[];\n\n/**\n * Возвращает календарный вид, который удобнее всего открывать для выбранного размера периода.\n */\nexport function getDatePickerLevelForSelectionMode(selectionMode: DateInputSelectionMode): DatePickerLevel {\n\tif (selectionMode === \"month\") return \"month\";\n\tif (selectionMode === \"year\") return \"year\";\n\n\treturn \"day\";\n}\n\n/**\n * Проверяет, разрешён ли календарный вид относительно минимального уровня навигации.\n */\nexport function isDatePickerLevelAvailable(level: DatePickerLevel, minLevel: DatePickerLevel): boolean {\n\treturn DATE_PICKER_LEVELS.indexOf(level) >= DATE_PICKER_LEVELS.indexOf(minLevel);\n}\n\n/**\n * Подбирает вид календаря для режима выбора с учётом ограничения `datePickerLevel`.\n */\nexport function resolveAvailableDatePickerLevel(selectionMode: DateInputSelectionMode, minLevel: DatePickerLevel): DatePickerLevel {\n\tconst preferredLevel = getDatePickerLevelForSelectionMode(selectionMode);\n\n\treturn isDatePickerLevelAvailable(preferredLevel, minLevel) ? preferredLevel : minLevel;\n}\n\nexport interface DateInputPeriodRangeStateOptions {\n\treadonly date: Date;\n\treadonly value: DateRangeInput;\n\treadonly hoveredDate?: Date | null;\n\treadonly selectsRange?: boolean;\n\treadonly selectionOptions?: CalendarPeriodOptions;\n}\n\nexport interface DateInputPeriodRangeState {\n\treadonly selected: boolean;\n\treadonly range: boolean;\n\treadonly rangeStart: boolean;\n\treadonly rangeEnd: boolean;\n}\n\nfunction isSameCalendarPeriod(left: CalendarPeriod | null, right: CalendarPeriod | null): boolean {\n\tif (!left || !right) return false;\n\n\treturn left.start.getTime() === right.start.getTime() && left.end.getTime() === right.end.getTime();\n}\n\nfunction isCalendarPeriodInsideRange(\n\tperiod: CalendarPeriod | null,\n\tstartPeriod: CalendarPeriod | null,\n\tendPeriod: CalendarPeriod | null\n): boolean {\n\tif (!period || !startPeriod || !endPeriod) return false;\n\n\tconst startTime = Math.min(startPeriod.start.getTime(), endPeriod.start.getTime());\n\tconst endTime = Math.max(startPeriod.end.getTime(), endPeriod.end.getTime());\n\n\treturn period.start.getTime() >= startTime && period.end.getTime() <= endTime;\n}\n\n/**\n * Рассчитывает visual-state ячейки календарного периода для single/range режима.\n */\nexport function resolveDateInputPeriodRangeState({\n\tdate,\n\tvalue,\n\thoveredDate,\n\tselectsRange,\n\tselectionOptions\n}: DateInputPeriodRangeStateOptions): DateInputPeriodRangeState {\n\tconst period = getCalendarPeriod(date, selectionOptions);\n\tconst selectedDate = !selectsRange && value instanceof Date ? value : null;\n\tconst selectedSinglePeriod = getCalendarPeriod(selectedDate, selectionOptions);\n\n\tif (!selectsRange || !Array.isArray(value)) {\n\t\treturn {\n\t\t\tselected: isDateInsideCalendarPeriod(date, selectedSinglePeriod),\n\t\t\trange: false,\n\t\t\trangeStart: false,\n\t\t\trangeEnd: false\n\t\t};\n\t}\n\n\tconst [selectedStartDate, selectedEndDate] = value as NullableDateRange;\n\tconst selectedStartPeriod = getCalendarPeriod(selectedStartDate, selectionOptions);\n\tconst previewEndPeriod = getCalendarPeriod(selectedEndDate ?? (selectedStartDate ? hoveredDate : null), selectionOptions);\n\tconst rangeStart = isSameCalendarPeriod(period, selectedStartPeriod);\n\tconst rangeEnd = isSameCalendarPeriod(period, previewEndPeriod);\n\tconst range = isCalendarPeriodInsideRange(period, selectedStartPeriod, previewEndPeriod);\n\n\treturn {\n\t\tselected: false,\n\t\trange: range && !rangeStart && !rangeEnd,\n\t\trangeStart,\n\t\trangeEnd\n\t};\n}\n",".dayView {\n\tpadding: 0;\n}\n\n.weekdays {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(7, 1fr);\n\ttext-align: center;\n\tmargin-bottom: var(--space-sm);\n\tcolor: var(--content-1);\n}\n\n.weekday {\n\tfont-size: var(--font-size-xs);\n}\n\n.daysGrid {\n\tdisplay: grid;\n\tgap: var(--border-width);\n}\n\n.week {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(7, 1fr);\n\tgap: var(--border-width);\n}\n\n.day {\n\t--range-radius: calc(var(--control-height) / 2);\n\n\theight: var(--control-height);\n\tcursor: pointer;\n\tborder-radius: var(--radius-xs);\n\t// font-size: var(--font-size-sm);\n\n\tbackground-color: var(--surface-1);\n\n\t&:hover:not(.disabled) {\n\t\tbackground-color: var(--surface-accent);\n\t}\n\n\t&.outsideMonth {\n\t\tbackground-color: transparent;\n\t\tcolor: var(--content-2);\n\t}\n\n\t&.periodSelection:hover:not(.disabled):not(.periodPreview):not(.selected) {\n\t\tbackground-color: var(--surface-1);\n\t}\n\n\t&.periodSelection.outsideMonth:hover:not(.disabled):not(.periodPreview):not(.selected) {\n\t\tbackground-color: transparent;\n\t}\n\n\t&.periodPreview {\n\t\tbackground-color: var(--surface-accent);\n\t\tcolor: var(--content-0);\n\t}\n\n\t&.range {\n\t\tbackground-color: var(--surface-accent);\n\t\tcolor: var(--content-0);\n\t}\n\n\t&.rangeStart {\n\t\t// border-top-left-radius: var(--range-radius);\n\t\t// border-bottom-left-radius: var(--range-radius);\n\t}\n\n\t&.rangeEnd {\n\t\t// border-top-right-radius: var(--range-radius);\n\t\t// border-bottom-right-radius: var(--range-radius);\n\t}\n\n\t&.selected,\n\t&.rangeStart,\n\t&.rangeEnd {\n\t\tbackground-color: var(--surface-accent);\n\t\tcolor: var(--content-accent);\n\t\tfont-weight: 600;\n\t\tfont-variation-settings: \"wght\" 600;\n\t}\n\n\t&.weekend:not(.selected):not(.range):not(.rangeStart):not(.rangeEnd) {\n\t\tcolor: var(--status-error-fill);\n\t}\n\n\t&.disabled {\n\t\tcolor: var(--content-2);\n\t\tcursor: not-allowed;\n\n\t\t&:hover {\n\t\t\tbackground: none;\n\t\t}\n\t}\n\n\t&.now {\n\t\tborder: var(--border);\n\t\tcolor: var(--status-info-text);\n\t\tborder-color: var(--status-info-text);\n\t}\n}\n","import { useState } from \"react\";\n\nimport {\n\tcreateCalendarDate,\n\tgetCalendarPeriod,\n\tgetStartOfDay,\n\tisCalendarPeriodWithinDateBounds,\n\tisDateInsideCalendarPeriod,\n\tisSameCalendarDay,\n\ttype CalendarPeriodOptions,\n\ttype DateRangeInput\n} from \"@ryuzaki13/react-foundation-lib/formatters\";\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { type DateInputSelectionMode, type DateInputWeekEndDay } from \"../lib\";\n\nimport styles from \"./CalendarDayView.module.scss\";\n\nconst weekDays = [\"Пн\", \"Вт\", \"Ср\", \"Чт\", \"Пт\", \"Сб\", \"Вс\"];\nconst dayLabelFormatter = new Intl.DateTimeFormat(\"ru-RU\", {\n\tweekday: \"long\",\n\tyear: \"numeric\",\n\tmonth: \"long\",\n\tday: \"numeric\"\n});\n\ninterface DayViewProps {\n\tnow: Date;\n\tcurrentDate: Date;\n\tvalue: DateRangeInput;\n\tonChange: (date: Date) => void;\n\tminDate?: Date;\n\tmaxDate?: Date;\n\tselectsRange?: boolean;\n\tselectionMode?: DateInputSelectionMode;\n\tweekEndDay?: DateInputWeekEndDay;\n}\n\n/**\n * Отображает сетку дней месяца в календарной семантике без timezone-сдвига.\n */\nexport const CalendarDayView: React.FC<DayViewProps> = ({\n\tnow,\n\tcurrentDate,\n\tvalue,\n\tonChange,\n\tminDate,\n\tmaxDate,\n\tselectsRange,\n\tselectionMode = \"day\",\n\tweekEndDay = \"sunday\"\n}) => {\n\tconst [hoveredDate, setHoveredDate] = useState<Date | null>(null);\n\tconst selectionOptions: CalendarPeriodOptions = {\n\t\tselectionMode,\n\t\tweekEndDay\n\t};\n\n\t/**\n\t * Генерирует недели для текущего месяца с учётом дней соседних месяцев.\n\t */\n\tconst generateCalendarDays = () => {\n\t\tconst year = currentDate.getFullYear();\n\t\tconst month = currentDate.getMonth();\n\n\t\tconst firstDay = createCalendarDate(year, month, 1);\n\t\tconst lastDay = createCalendarDate(year, month + 1, 0);\n\t\tconst prevMonthDays = firstDay.getDay() === 0 ? 6 : firstDay.getDay() - 1;\n\t\tconst nextMonthDays = 6 * 7 - (prevMonthDays + lastDay.getDate());\n\n\t\tconst days: Date[] = [];\n\t\tconst prevMonthLastDay = createCalendarDate(year, month, 0).getDate();\n\n\t\tfor (let index = prevMonthDays; index > 0; index -= 1) {\n\t\t\tdays.push(createCalendarDate(year, month - 1, prevMonthLastDay - index + 1));\n\t\t}\n\n\t\tfor (let day = 1; day <= lastDay.getDate(); day += 1) {\n\t\t\tdays.push(createCalendarDate(year, month, day));\n\t\t}\n\n\t\tfor (let day = 1; day <= nextMonthDays; day += 1) {\n\t\t\tdays.push(createCalendarDate(year, month + 1, day));\n\t\t}\n\n\t\tconst weeks: Date[][] = [];\n\t\tfor (let index = 0; index < days.length; index += 7) {\n\t\t\tweeks.push(days.slice(index, index + 7));\n\t\t}\n\n\t\treturn weeks;\n\t};\n\n\tconst weeks = generateCalendarDays();\n\tconst selectedStartDate = selectsRange && Array.isArray(value) ? value[0] : null;\n\tconst selectedEndDate = selectsRange && Array.isArray(value) ? value[1] : null;\n\tconst selectedDate = !selectsRange ? (value as Date | null) : null;\n\tconst selectedSinglePeriod = getCalendarPeriod(selectedDate, selectionOptions);\n\tconst hoveredPeriod = getCalendarPeriod(hoveredDate, selectionOptions);\n\tconst previewEndDate = selectedEndDate ?? (selectedStartDate ? (hoveredPeriod?.end ?? null) : null);\n\tconst previewsWeekPeriod = selectionMode === \"week\";\n\tconst previewsStandalonePeriod = previewsWeekPeriod && (!selectsRange || !selectedStartDate);\n\n\t/**\n\t * Проверяет, лежит ли день внутри выбранного или preview-диапазона.\n\t */\n\tconst isInRange = (date: Date) => {\n\t\tif (!selectsRange || !selectedStartDate || !previewEndDate) return false;\n\n\t\tconst dateMs = getStartOfDay(date).getTime();\n\t\tconst startMs = selectedStartDate.getTime();\n\t\tconst endMs = previewEndDate.getTime();\n\n\t\treturn dateMs >= Math.min(startMs, endMs) && dateMs <= Math.max(startMs, endMs);\n\t};\n\n\t/**\n\t * Проверяет ограничения на выбор даты.\n\t */\n\tconst isDisabled = (date: Date) => {\n\t\treturn !isCalendarPeriodWithinDateBounds(getCalendarPeriod(date, selectionOptions), { minDate, maxDate });\n\t};\n\n\t/**\n\t * Обновляет preview-конец диапазона при движении мыши.\n\t */\n\tconst handleDayHover = (date: Date, disabled: boolean) => {\n\t\tif (disabled) return;\n\n\t\tif (previewsWeekPeriod) {\n\t\t\tsetHoveredDate(date);\n\t\t}\n\n\t\tif (!selectsRange || !selectedStartDate || selectedEndDate) return;\n\t\tif (!previewsWeekPeriod) setHoveredDate(date);\n\t};\n\n\t/**\n\t * Сбрасывает preview незавершённого диапазона при уходе курсора.\n\t */\n\tconst handleGridLeave = () => {\n\t\tif (previewsWeekPeriod || !selectedEndDate) {\n\t\t\tsetHoveredDate(null);\n\t\t}\n\t};\n\n\treturn (\n\t\t<div className={styles.dayView}>\n\t\t\t<div className={styles.weekdays}>\n\t\t\t\t{weekDays.map((day) => (\n\t\t\t\t\t<div key={day} className={styles.weekday}>\n\t\t\t\t\t\t{day}\n\t\t\t\t\t</div>\n\t\t\t\t))}\n\t\t\t</div>\n\n\t\t\t<div className={styles.daysGrid} onMouseLeave={handleGridLeave}>\n\t\t\t\t{weeks.map((week, weekIndex) => (\n\t\t\t\t\t<div key={weekIndex} className={styles.week}>\n\t\t\t\t\t\t{week.map((day, dayIndex) => {\n\t\t\t\t\t\t\tconst isCurrentMonth = day.getMonth() === currentDate.getMonth();\n\t\t\t\t\t\t\tconst isSelected = isDateInsideCalendarPeriod(day, selectedSinglePeriod);\n\t\t\t\t\t\t\tconst isPeriodPreview = previewsStandalonePeriod && isDateInsideCalendarPeriod(day, hoveredPeriod);\n\t\t\t\t\t\t\tconst isRange = isInRange(day);\n\t\t\t\t\t\t\tconst isStart = isSameCalendarDay(day, selectedStartDate);\n\t\t\t\t\t\t\tconst isEnd = isSameCalendarDay(day, previewEndDate);\n\t\t\t\t\t\t\tconst isNow = isSameCalendarDay(day, now);\n\t\t\t\t\t\t\tconst disabled = isDisabled(day);\n\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tkey={`${weekIndex}-${dayIndex}`}\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tonClick={() => !disabled && onChange(day)}\n\t\t\t\t\t\t\t\t\tonMouseEnter={() => handleDayHover(day, disabled)}\n\t\t\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\t\t\tdata-ui=\"calendar-day-button\"\n\t\t\t\t\t\t\t\t\tdata-action=\"select-calendar-day\"\n\t\t\t\t\t\t\t\t\tclassName={cn(styles.day, {\n\t\t\t\t\t\t\t\t\t\t[styles.outsideMonth]: !isCurrentMonth,\n\t\t\t\t\t\t\t\t\t\t[styles.periodSelection]: selectionMode === \"week\",\n\t\t\t\t\t\t\t\t\t\t[styles.periodPreview]: isPeriodPreview && !isSelected,\n\t\t\t\t\t\t\t\t\t\t[styles.selected]: isSelected,\n\t\t\t\t\t\t\t\t\t\t[styles.range]: isRange && !isStart && !isEnd,\n\t\t\t\t\t\t\t\t\t\t[styles.rangeStart]: isStart,\n\t\t\t\t\t\t\t\t\t\t[styles.rangeEnd]: isEnd,\n\t\t\t\t\t\t\t\t\t\t[styles.disabled]: disabled,\n\t\t\t\t\t\t\t\t\t\t[styles.weekend]: dayIndex > 4,\n\t\t\t\t\t\t\t\t\t\t[styles.now]: isNow\n\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\taria-label={dayLabelFormatter.format(day)}\n\t\t\t\t\t\t\t\t\taria-pressed={isSelected || isRange || isStart || isEnd}>\n\t\t\t\t\t\t\t\t\t{day.getDate()}\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t</div>\n\t\t\t\t))}\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n",".monthView {\n\tpadding: 0;\n}\n\n.monthsGrid {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(3, 1fr);\n\tgap: var(--border-width);\n\talign-content: center;\n\n\t// min-height: calc(12em * var(--line-height));\n}\n\n.month {\n\theight: var(--control-height);\n\tcursor: pointer;\n\tborder-radius: var(--radius-xs);\n\t// font-size: var(--font-size-sm);\n\ttext-transform: capitalize;\n\n\tbackground-color: var(--surface-1);\n\n\t&:hover:not(.disabled) {\n\t\tbackground-color: var(--surface-accent);\n\t}\n\n\t&.range {\n\t\tbackground-color: var(--surface-accent);\n\t\tcolor: var(--content-0);\n\t}\n\n\t&.selected,\n\t&.rangeStart,\n\t&.rangeEnd {\n\t\tbackground-color: var(--surface-accent);\n\t\tcolor: var(--content-accent);\n\t\tfont-weight: 600;\n\t\tfont-variation-settings: \"wght\" 600;\n\t}\n\n\t&.disabled {\n\t\tcolor: var(--content-2);\n\t\tcursor: not-allowed;\n\n\t\t&:hover {\n\t\t\tbackground: none;\n\t\t}\n\t}\n}\n","import { useState } from \"react\";\n\nimport {\n\tcreateCalendarDate,\n\tgetCalendarPeriod,\n\tisCalendarPeriodWithinDateBounds,\n\ttype CalendarPeriodOptions,\n\ttype DateRangeInput\n} from \"@ryuzaki13/react-foundation-lib/formatters\";\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { resolveDateInputPeriodRangeState } from \"../lib\";\n\nimport styles from \"./CalendarMonthView.module.scss\";\n\nimport type { DateInputSelectionMode, DateInputWeekEndDay } from \"../lib\";\n\nconst monthLabelFormatter = new Intl.DateTimeFormat(\"ru-RU\", { month: \"short\" });\nconst monthAriaFormatter = new Intl.DateTimeFormat(\"ru-RU\", { month: \"long\", year: \"numeric\" });\n\ninterface MonthViewProps {\n\tcurrentDate: Date;\n\tvalue: DateRangeInput;\n\tonChange: (date: Date) => void;\n\tminDate?: Date;\n\tmaxDate?: Date;\n\tselectsRange?: boolean;\n\tselectsPeriod?: boolean;\n\tselectionMode?: DateInputSelectionMode;\n\tweekEndDay?: DateInputWeekEndDay;\n}\n\n/**\n * Отображает выбор месяца в календарной семантике без timezone-сдвига.\n */\nexport const CalendarMonthView: React.FC<MonthViewProps> = ({\n\tcurrentDate,\n\tvalue,\n\tonChange,\n\tminDate,\n\tmaxDate,\n\tselectsRange,\n\tselectsPeriod,\n\tselectionMode = \"day\",\n\tweekEndDay = \"sunday\"\n}) => {\n\tconst [hoveredDate, setHoveredDate] = useState<Date | null>(null);\n\tconst months = Array.from({ length: 12 }, (_, index) => index);\n\tconst currentYear = currentDate.getFullYear();\n\tconst selectionOptions: CalendarPeriodOptions = {\n\t\tselectionMode,\n\t\tweekEndDay\n\t};\n\tconst selectedStartDate = selectsRange && Array.isArray(value) ? value[0] : null;\n\tconst selectedEndDate = selectsRange && Array.isArray(value) ? value[1] : null;\n\n\t/**\n\t * Возвращает сокращённое имя месяца.\n\t */\n\tconst getMonthName = (monthIndex: number) => monthLabelFormatter.format(createCalendarDate(currentYear, monthIndex, 1));\n\n\t/**\n\t * Проверяет, запрещён ли выбор месяца по ограничениям.\n\t */\n\tconst isDisabled = (monthIndex: number) => {\n\t\tif (!minDate && !maxDate) return false;\n\n\t\tconst monthStart = createCalendarDate(currentYear, monthIndex, 1);\n\t\tconst monthEnd = createCalendarDate(currentYear, monthIndex + 1, 0, 23, 59, 59);\n\n\t\tif (selectsPeriod) {\n\t\t\treturn !isCalendarPeriodWithinDateBounds(getCalendarPeriod(monthStart, selectionOptions), { minDate, maxDate });\n\t\t}\n\n\t\tif (minDate && monthEnd < minDate) return true;\n\t\tif (maxDate && monthStart > maxDate) return true;\n\n\t\treturn false;\n\t};\n\n\t/**\n\t * Обновляет preview-конец диапазона при движении мыши.\n\t */\n\tconst handleMonthHover = (date: Date, disabled: boolean) => {\n\t\tif (!selectsRange || !selectedStartDate || selectedEndDate || disabled) return;\n\t\tsetHoveredDate(date);\n\t};\n\n\t/**\n\t * Сбрасывает preview незавершённого диапазона при уходе курсора.\n\t */\n\tconst handleGridLeave = () => {\n\t\tif (!selectedEndDate) {\n\t\t\tsetHoveredDate(null);\n\t\t}\n\t};\n\n\treturn (\n\t\t<div className={styles.monthView}>\n\t\t\t<div className={styles.monthsGrid} onMouseLeave={handleGridLeave}>\n\t\t\t\t{months.map((monthIndex) => {\n\t\t\t\t\tconst disabled = isDisabled(monthIndex);\n\t\t\t\t\tconst monthDate = createCalendarDate(currentYear, monthIndex, 1);\n\t\t\t\t\tconst rangeState = resolveDateInputPeriodRangeState({\n\t\t\t\t\t\tdate: monthDate,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\thoveredDate,\n\t\t\t\t\t\tselectsRange,\n\t\t\t\t\t\tselectionOptions\n\t\t\t\t\t});\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\tkey={monthIndex}\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={() => !disabled && onChange(monthDate)}\n\t\t\t\t\t\t\tonMouseEnter={() => handleMonthHover(monthDate, disabled)}\n\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\tdata-ui=\"calendar-month-button\"\n\t\t\t\t\t\t\tdata-action=\"select-calendar-month\"\n\t\t\t\t\t\t\tclassName={cn(styles.month, {\n\t\t\t\t\t\t\t\t[styles.selected]: rangeState.selected,\n\t\t\t\t\t\t\t\t[styles.range]: rangeState.range,\n\t\t\t\t\t\t\t\t[styles.rangeStart]: rangeState.rangeStart,\n\t\t\t\t\t\t\t\t[styles.rangeEnd]: rangeState.rangeEnd,\n\t\t\t\t\t\t\t\t[styles.disabled]: disabled\n\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\taria-label={monthAriaFormatter.format(monthDate)}\n\t\t\t\t\t\t\taria-pressed={rangeState.selected || rangeState.range || rangeState.rangeStart || rangeState.rangeEnd}>\n\t\t\t\t\t\t\t{getMonthName(monthIndex)}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n",".calendarView {\n\twidth: calc(18em + var(--width-add));\n}\n\n.calendarHeader {\n\tdisplay: flex;\n\tjustify-content: space-between;\n\talign-items: center;\n\tpadding-bottom: var(--space-sm);\n\tmargin-bottom: var(--space-sm);\n\tgap: var(--space-sm);\n\tborder-bottom: var(--border);\n}\n",".yearView {\n\tpadding: 0;\n}\n\n.yearsGrid {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(3, 1fr);\n\tgap: var(--border-width);\n}\n\n.year {\n\theight: var(--control-height);\n\tcursor: pointer;\n\tborder-radius: var(--radius-xs);\n\t// font-size: var(--font-size-sm);\n\n\tbackground-color: var(--surface-1);\n\n\t&:hover:not(.disabled) {\n\t\tbackground-color: var(--surface-accent);\n\t}\n\n\t&.range {\n\t\tbackground-color: var(--surface-accent);\n\t\tcolor: var(--content-0);\n\t}\n\n\t&.selected,\n\t&.rangeStart,\n\t&.rangeEnd {\n\t\tbackground-color: var(--surface-accent);\n\t\tcolor: var(--content-accent);\n\t\tfont-weight: 600;\n\t\tfont-variation-settings: \"wght\" 600;\n\t}\n\n\t&.disabled {\n\t\tcolor: var(--content-2);\n\t\tcursor: not-allowed;\n\n\t\t&:hover {\n\t\t\tbackground: none;\n\t\t}\n\t}\n}\n","import { useState } from \"react\";\n\nimport {\n\tcreateCalendarDate,\n\tgetCalendarPeriod,\n\tisCalendarPeriodWithinDateBounds,\n\ttype CalendarPeriodOptions,\n\ttype DateRangeInput\n} from \"@ryuzaki13/react-foundation-lib/formatters\";\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\n\nimport { resolveDateInputPeriodRangeState } from \"../lib\";\n\nimport styles from \"./CalendarYearView.module.scss\";\n\nimport type { DateInputSelectionMode, DateInputWeekEndDay } from \"../lib\";\n\ninterface YearViewProps {\n\tcurrentDate: Date;\n\tvalue: DateRangeInput;\n\tonChange: (date: Date) => void;\n\tminDate?: Date;\n\tmaxDate?: Date;\n\tselectsRange?: boolean;\n\tselectsPeriod?: boolean;\n\tselectionMode?: DateInputSelectionMode;\n\tweekEndDay?: DateInputWeekEndDay;\n}\n\n/**\n * Отображает выбор года в календарной семантике без timezone-сдвига.\n */\nexport const CalendarYearView: React.FC<YearViewProps> = ({\n\tcurrentDate,\n\tvalue,\n\tonChange,\n\tminDate,\n\tmaxDate,\n\tselectsRange,\n\tselectsPeriod,\n\tselectionMode = \"day\",\n\tweekEndDay = \"sunday\"\n}) => {\n\tconst [hoveredDate, setHoveredDate] = useState<Date | null>(null);\n\tconst startYear = Math.floor(currentDate.getFullYear() / 12) * 12;\n\tconst years = Array.from({ length: 12 }, (_, index) => startYear + index);\n\tconst selectionOptions: CalendarPeriodOptions = {\n\t\tselectionMode,\n\t\tweekEndDay\n\t};\n\tconst selectedStartDate = selectsRange && Array.isArray(value) ? value[0] : null;\n\tconst selectedEndDate = selectsRange && Array.isArray(value) ? value[1] : null;\n\n\t/**\n\t * Проверяет ограничения на выбор года.\n\t */\n\tconst isDisabled = (year: number) => {\n\t\tif (!minDate && !maxDate) return false;\n\n\t\tconst yearStart = createCalendarDate(year, 0, 1);\n\t\tconst yearEnd = createCalendarDate(year, 11, 31, 23, 59, 59);\n\n\t\tif (selectsPeriod) {\n\t\t\treturn !isCalendarPeriodWithinDateBounds(getCalendarPeriod(yearStart, selectionOptions), { minDate, maxDate });\n\t\t}\n\n\t\tif (minDate && yearEnd < minDate) return true;\n\t\tif (maxDate && yearStart > maxDate) return true;\n\n\t\treturn false;\n\t};\n\n\t/**\n\t * Обновляет preview-конец диапазона при движении мыши.\n\t */\n\tconst handleYearHover = (date: Date, disabled: boolean) => {\n\t\tif (!selectsRange || !selectedStartDate || selectedEndDate || disabled) return;\n\t\tsetHoveredDate(date);\n\t};\n\n\t/**\n\t * Сбрасывает preview незавершённого диапазона при уходе курсора.\n\t */\n\tconst handleGridLeave = () => {\n\t\tif (!selectedEndDate) {\n\t\t\tsetHoveredDate(null);\n\t\t}\n\t};\n\n\treturn (\n\t\t<div className={styles.yearView}>\n\t\t\t<div className={styles.yearsGrid} onMouseLeave={handleGridLeave}>\n\t\t\t\t{years.map((year) => {\n\t\t\t\t\tconst disabled = isDisabled(year);\n\t\t\t\t\tconst yearDate = createCalendarDate(year, 0, 1);\n\t\t\t\t\tconst rangeState = resolveDateInputPeriodRangeState({\n\t\t\t\t\t\tdate: yearDate,\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\thoveredDate,\n\t\t\t\t\t\tselectsRange,\n\t\t\t\t\t\tselectionOptions\n\t\t\t\t\t});\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\tkey={year}\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={() => !disabled && onChange(yearDate)}\n\t\t\t\t\t\t\tonMouseEnter={() => handleYearHover(yearDate, disabled)}\n\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\tdata-ui=\"calendar-year-button\"\n\t\t\t\t\t\t\tdata-action=\"select-calendar-year\"\n\t\t\t\t\t\t\tclassName={cn(styles.year, {\n\t\t\t\t\t\t\t\t[styles.selected]: rangeState.selected,\n\t\t\t\t\t\t\t\t[styles.range]: rangeState.range,\n\t\t\t\t\t\t\t\t[styles.rangeStart]: rangeState.rangeStart,\n\t\t\t\t\t\t\t\t[styles.rangeEnd]: rangeState.rangeEnd,\n\t\t\t\t\t\t\t\t[styles.disabled]: disabled\n\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\taria-label={year.toString()}\n\t\t\t\t\t\t\taria-pressed={rangeState.selected || rangeState.range || rangeState.rangeStart || rangeState.rangeEnd}>\n\t\t\t\t\t\t\t{year}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n","import { useEffect, useEffectEvent, useState } from \"react\";\n\nimport {\n\taddCalendarMonths,\n\taddCalendarYears,\n\tgetCalendarPeriod,\n\tgetStartOfDay,\n\tisCalendarPeriodWithinDateBounds,\n\tisDateRangeTuple,\n\ttype CalendarPeriodOptions,\n\ttype NullableDateRange\n} from \"@ryuzaki13/react-foundation-lib/formatters\";\nimport { ChevronLeft, ChevronRight } from \"lucide-react\";\n\nimport { Button } from \"../../button\";\nimport { isDatePickerLevelAvailable, type CalendarType, type DateInputSelectionMode, type DateInputWeekEndDay } from \"../lib\";\n\nimport { CalendarDayView } from \"./CalendarDayView\";\nimport { CalendarMonthView } from \"./CalendarMonthView\";\nimport styles from \"./CalendarView.module.scss\";\nimport { CalendarYearView } from \"./CalendarYearView\";\n\ninterface BaseCalendarViewProps {\n\tview: CalendarType;\n\tdatePickerLevel: CalendarType;\n\tselectionMode?: DateInputSelectionMode;\n\tweekEndDay?: DateInputWeekEndDay;\n\tonViewChange: (view: CalendarType) => void;\n}\n\ninterface CalendarViewProps extends BaseCalendarViewProps {\n\tselectsRange?: boolean;\n\tvalue: Date | NullableDateRange | null;\n\tonChange: (date: Date | NullableDateRange) => void;\n\tminDate?: Date;\n\tmaxDate?: Date;\n\tcurrentDate?: Date;\n\tonCurrentDateChange?: (date: Date) => void;\n}\n\n/**\n * Отображает календарь выбора даты в календарной семантике без timezone-сдвига.\n */\nexport function CalendarView({\n\tview,\n\tdatePickerLevel,\n\tselectionMode = \"day\",\n\tweekEndDay = \"sunday\",\n\tonViewChange,\n\t...props\n}: CalendarViewProps) {\n\tconst [dateNow] = useState(() => getStartOfDay(new Date()));\n\tconst [uncontrolledCurrentDate, setUncontrolledCurrentDate] = useState<Date>(() => {\n\t\tif (props.selectsRange && isDateRangeTuple(props.value) && props.value[0] instanceof Date) {\n\t\t\treturn props.value[0];\n\t\t}\n\n\t\tif (!props.selectsRange && props.value instanceof Date) {\n\t\t\treturn props.value;\n\t\t}\n\n\t\treturn getStartOfDay(new Date());\n\t});\n\tconst currentDate = props.currentDate ?? uncontrolledCurrentDate;\n\tconst selectionOptions: CalendarPeriodOptions = {\n\t\tselectionMode,\n\t\tweekEndDay\n\t};\n\n\t/**\n\t * Обновляет видимую календарную дату в управляемом или неуправляемом режиме.\n\t */\n\tconst setCurrentDate = (value: Date | ((prevValue: Date) => Date)) => {\n\t\tconst nextValue = typeof value === \"function\" ? value(currentDate) : value;\n\n\t\tif (props.currentDate === undefined) {\n\t\t\tsetUncontrolledCurrentDate(nextValue);\n\t\t}\n\n\t\tprops.onCurrentDateChange?.(nextValue);\n\t};\n\n\t/**\n\t * Синхронизирует видимый месяц/год с внешним значением поля.\n\t */\n\tconst syncCurrentDate = useEffectEvent((nextValue: Date | NullableDateRange | null) => {\n\t\tif (props.selectsRange && Array.isArray(nextValue) && nextValue[0] instanceof Date) {\n\t\t\tsetCurrentDate(nextValue[0]);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!props.selectsRange && nextValue instanceof Date) {\n\t\t\tsetCurrentDate(nextValue);\n\t\t}\n\t});\n\n\tuseEffect(() => {\n\t\tsyncCurrentDate(props.value);\n\t}, [props.value]);\n\n\t/**\n\t * Переключает видимую область календаря назад.\n\t */\n\tconst goToPrevious = () => {\n\t\tif (view === \"day\") {\n\t\t\tsetCurrentDate((prev) => addCalendarMonths(prev, -1));\n\t\t\treturn;\n\t\t}\n\n\t\tif (view === \"month\") {\n\t\t\tsetCurrentDate((prev) => addCalendarYears(prev, -1));\n\t\t\treturn;\n\t\t}\n\n\t\tsetCurrentDate((prev) => addCalendarYears(prev, -12));\n\t};\n\n\t/**\n\t * Переключает видимую область календаря вперёд.\n\t */\n\tconst goToNext = () => {\n\t\tif (view === \"day\") {\n\t\t\tsetCurrentDate((prev) => addCalendarMonths(prev, 1));\n\t\t\treturn;\n\t\t}\n\n\t\tif (view === \"month\") {\n\t\t\tsetCurrentDate((prev) => addCalendarYears(prev, 1));\n\t\t\treturn;\n\t\t}\n\n\t\tsetCurrentDate((prev) => addCalendarYears(prev, 12));\n\t};\n\n\t/**\n\t * Возвращает заголовок текущего календарного вида.\n\t */\n\tconst renderHeader = () => {\n\t\tlet title = \"\";\n\t\tif (view === \"day\") {\n\t\t\ttitle = currentDate.toLocaleDateString(\"ru-RU\", {\n\t\t\t\tmonth: \"long\",\n\t\t\t\tyear: \"numeric\"\n\t\t\t});\n\t\t} else if (view === \"month\") {\n\t\t\ttitle = currentDate.getFullYear().toString();\n\t\t} else {\n\t\t\tconst startYear = Math.floor(currentDate.getFullYear() / 12) * 12;\n\t\t\tconst endYear = startYear + 11;\n\t\t\ttitle = `${startYear} - ${endYear}`;\n\t\t}\n\n\t\treturn (\n\t\t\t<div className={styles.calendarHeader}>\n\t\t\t\t<Button\n\t\t\t\t\ticon={<ChevronLeft />}\n\t\t\t\t\tonClick={goToPrevious}\n\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\taria-label=\"Предыдущий\"\n\t\t\t\t\tdata-action=\"calendar-previous\"\n\t\t\t\t/>\n\n\t\t\t\t<Button\n\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\tif (view === \"day\") onViewChange(\"month\");\n\t\t\t\t\t\telse if (view === \"month\") onViewChange(\"year\");\n\t\t\t\t\t}}\n\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\tclassName=\"flex1\"\n\t\t\t\t\tdata-ui=\"calendar-view-switch-button\"\n\t\t\t\t\tdata-action=\"calendar-switch-view\">\n\t\t\t\t\t{title}\n\t\t\t\t</Button>\n\n\t\t\t\t<Button\n\t\t\t\t\ticon={<ChevronRight />}\n\t\t\t\t\tonClick={goToNext}\n\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\taria-label=\"Следующий\"\n\t\t\t\t\tdata-ui=\"calendar-next-button\"\n\t\t\t\t\tdata-action=\"calendar-next\"\n\t\t\t\t/>\n\t\t\t</div>\n\t\t);\n\t};\n\n\t/**\n\t * Отрисовывает активный режим календаря.\n\t */\n\tconst renderView = () => {\n\t\tconst handleDateSelect = (date: Date) => {\n\t\t\tconst selectedPeriod = getCalendarPeriod(date, selectionOptions);\n\t\t\tif (!selectedPeriod || !isCalendarPeriodWithinDateBounds(selectedPeriod, { minDate: props.minDate, maxDate: props.maxDate }))\n\t\t\t\treturn;\n\n\t\t\tif (props.selectsRange) {\n\t\t\t\tlet selectedStartDate: Date | null = null;\n\t\t\t\tlet selectedEndDate: Date | null = null;\n\n\t\t\t\tif (Array.isArray(props.value)) {\n\t\t\t\t\t[selectedStartDate, selectedEndDate] = props.value;\n\t\t\t\t}\n\n\t\t\t\tif (!selectedStartDate || selectedEndDate) {\n\t\t\t\t\tprops.onChange([selectedPeriod.start, null]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst startPeriod = getCalendarPeriod(selectedStartDate, selectionOptions);\n\t\t\t\tif (!startPeriod) return;\n\n\t\t\t\tif (selectedPeriod.start < startPeriod.start) {\n\t\t\t\t\tprops.onChange([selectedPeriod.start, startPeriod.end]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tprops.onChange([startPeriod.start, selectedPeriod.end]);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tprops.onChange(selectedPeriod.start);\n\t\t};\n\n\t\tconst handleMonthSelect = (date: Date) => {\n\t\t\tsetCurrentDate(date);\n\n\t\t\tif (selectionMode === \"month\" || !isDatePickerLevelAvailable(\"day\", datePickerLevel)) {\n\t\t\t\thandleDateSelect(date);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tonViewChange(\"day\");\n\t\t};\n\n\t\tconst handleYearSelect = (date: Date) => {\n\t\t\tsetCurrentDate(date);\n\n\t\t\tif (selectionMode === \"year\" || !isDatePickerLevelAvailable(\"month\", datePickerLevel)) {\n\t\t\t\thandleDateSelect(date);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tonViewChange(\"month\");\n\t\t};\n\n\t\tswitch (view) {\n\t\t\tcase \"day\":\n\t\t\t\treturn (\n\t\t\t\t\t<CalendarDayView\n\t\t\t\t\t\tnow={dateNow}\n\t\t\t\t\t\tcurrentDate={currentDate}\n\t\t\t\t\t\tvalue={props.value}\n\t\t\t\t\t\tonChange={handleDateSelect}\n\t\t\t\t\t\tminDate={props.minDate}\n\t\t\t\t\t\tmaxDate={props.maxDate}\n\t\t\t\t\t\tselectsRange={props.selectsRange}\n\t\t\t\t\t\tselectionMode={selectionMode}\n\t\t\t\t\t\tweekEndDay={weekEndDay}\n\t\t\t\t\t/>\n\t\t\t\t);\n\t\t\tcase \"month\":\n\t\t\t\treturn (\n\t\t\t\t\t<CalendarMonthView\n\t\t\t\t\t\tcurrentDate={currentDate}\n\t\t\t\t\t\tvalue={props.value}\n\t\t\t\t\t\tonChange={handleMonthSelect}\n\t\t\t\t\t\tminDate={props.minDate}\n\t\t\t\t\t\tmaxDate={props.maxDate}\n\t\t\t\t\t\tselectsRange={props.selectsRange}\n\t\t\t\t\t\tselectsPeriod={selectionMode === \"month\" || !isDatePickerLevelAvailable(\"day\", datePickerLevel)}\n\t\t\t\t\t\tselectionMode={selectionMode}\n\t\t\t\t\t\tweekEndDay={weekEndDay}\n\t\t\t\t\t/>\n\t\t\t\t);\n\t\t\tcase \"year\":\n\t\t\t\treturn (\n\t\t\t\t\t<CalendarYearView\n\t\t\t\t\t\tcurrentDate={currentDate}\n\t\t\t\t\t\tvalue={props.value}\n\t\t\t\t\t\tonChange={handleYearSelect}\n\t\t\t\t\t\tminDate={props.minDate}\n\t\t\t\t\t\tmaxDate={props.maxDate}\n\t\t\t\t\t\tselectsRange={props.selectsRange}\n\t\t\t\t\t\tselectsPeriod={selectionMode === \"year\" || !isDatePickerLevelAvailable(\"month\", datePickerLevel)}\n\t\t\t\t\t\tselectionMode={selectionMode}\n\t\t\t\t\t\tweekEndDay={weekEndDay}\n\t\t\t\t\t/>\n\t\t\t\t);\n\t\t\tdefault:\n\t\t\t\treturn null;\n\t\t}\n\t};\n\n\treturn (\n\t\t<div className={styles.calendarView}>\n\t\t\t{renderHeader()}\n\t\t\t{renderView()}\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
@@ -122,8 +122,7 @@ function N({ open: T, images: E, index: D = 0, onClose: k, onIndexChange: N, fea
122
122
  Y,
123
123
  X,
124
124
  Z
125
- ]), $ = t(() => A(R), [R]);
126
- return /* @__PURE__ */ g(_, {
125
+ ]), $ = t(() => A(R), [R]), ee = {
127
126
  open: T && H.length > 0,
128
127
  close: k,
129
128
  index: W,
@@ -217,9 +216,10 @@ function N({ open: T, images: E, index: D = 0, onClose: k, onIndexChange: N, fea
217
216
  className: j.icon
218
217
  })
219
218
  }
220
- });
219
+ };
220
+ return /* @__PURE__ */ g(_, { ...ee });
221
221
  }
222
222
  //#endregion
223
223
  export { N as default };
224
224
 
225
- //# sourceMappingURL=ImageViewerRuntime-RN49by8Y.js.map
225
+ //# sourceMappingURL=ImageViewerRuntime-BMs3BBkV.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ImageViewerRuntime-RN49by8Y.js","names":[],"sources":["../../src/image/lib/buildImageViewerSlides.ts","../../src/image/lib/resolveImageViewerLabels.ts","../../src/image/ui/ImageViewer.module.scss","../../src/image/ui/ImageViewerRuntime.tsx"],"sourcesContent":["import { type Slide } from \"yet-another-react-lightbox\";\n\nimport { type ImageCandidate } from \"../model/imageTypes\";\nimport { type ImageViewerImage } from \"../model/imageViewerTypes\";\n\n/** Проверяет размер до передачи в srcset внешней lightbox-библиотеки. */\nfunction isPositiveFinite(value: number): boolean {\n\treturn Number.isFinite(value) && value > 0;\n}\n\n/**\n * Преобразует width- и density-кандидат в физическую ширину.\n * Density имеет смысл только вместе с известной intrinsic-шириной базового изображения.\n */\nfunction resolveCandidateWidth(candidate: ImageCandidate, intrinsicWidth: number): number | null {\n\tconst width =\n\t\tcandidate.width !== undefined ? candidate.width : candidate.density !== undefined ? intrinsicWidth * candidate.density : 0;\n\n\treturn isPositiveFinite(width) ? Math.round(width) : null;\n}\n\n/**\n * Строит srcSet YARL, которому для каждого варианта нужны одновременно width и height.\n * Альтернативные picture sources намеренно остаются контрактом ImageView: YARL 3.x не поддерживает их\n * в стандартном image slide, а custom slide лишает viewer встроенного responsive preload и Zoom.\n */\nfunction buildLightboxSrcSet(image: ImageViewerImage): Slide[\"srcSet\"] {\n\tconst { intrinsicWidth, intrinsicHeight } = image;\n\n\tif (\n\t\tintrinsicWidth === undefined ||\n\t\tintrinsicHeight === undefined ||\n\t\t!isPositiveFinite(intrinsicWidth) ||\n\t\t!isPositiveFinite(intrinsicHeight)\n\t) {\n\t\treturn undefined;\n\t}\n\n\tconst candidatesByWidth = new Map<number, { src: string; width: number; height: number }>();\n\n\tfor (const candidate of image.candidates ?? []) {\n\t\tconst candidateWidth = resolveCandidateWidth(candidate, intrinsicWidth);\n\n\t\tif (candidateWidth === null || candidatesByWidth.has(candidateWidth)) continue;\n\n\t\tcandidatesByWidth.set(candidateWidth, {\n\t\t\tsrc: candidate.src,\n\t\t\twidth: candidateWidth,\n\t\t\theight: Math.max(1, Math.round((candidateWidth * intrinsicHeight) / intrinsicWidth))\n\t\t});\n\t}\n\n\tconst candidates = [...candidatesByWidth.values()].sort((left, right) => left.width - right.width);\n\treturn candidates.length > 0 ? candidates : undefined;\n}\n\n/**\n * Адаптирует storage-agnostic ResponsiveImageData к image slides Yet Another React Lightbox.\n * Функция остаётся приватной для `/image`, чтобы vendor contract не становился public API пакета.\n */\nexport function buildImageViewerSlides(images: readonly ImageViewerImage[]): Slide[] {\n\treturn images.map((image) => {\n\t\tconst hasIntrinsicSize = isPositiveFinite(image.intrinsicWidth ?? 0) && isPositiveFinite(image.intrinsicHeight ?? 0);\n\n\t\treturn {\n\t\t\tsrc: image.src,\n\t\t\talt: image.alt,\n\t\t\twidth: hasIntrinsicSize ? image.intrinsicWidth : undefined,\n\t\t\theight: hasIntrinsicSize ? image.intrinsicHeight : undefined,\n\t\t\tsrcSet: buildLightboxSrcSet(image),\n\t\t\ttitle: image.title === undefined ? image.alt : image.title,\n\t\t\tdescription: image.description,\n\t\t\tthumbnail: image.thumbnail,\n\t\t\tdownload: image.download\n\t\t};\n\t});\n}\n","import { type ImageViewerLabels } from \"../model/imageViewerTypes\";\n\nconst DEFAULT_IMAGE_VIEWER_LABELS: ImageViewerLabels = {\n\tprevious: \"Предыдущее изображение\",\n\tnext: \"Следующее изображение\",\n\tclose: \"Закрыть просмотр\",\n\tslide: \"Изображение\",\n\tcarousel: \"Карусель изображений\",\n\tlightbox: \"Просмотр изображений\",\n\tphotoGallery: \"Галерея изображений\",\n\tslideCounter: \"{index} из {total}\",\n\tzoomIn: \"Увеличить\",\n\tzoomOut: \"Уменьшить\",\n\tenterFullscreen: \"Перейти в полноэкранный режим\",\n\texitFullscreen: \"Выйти из полноэкранного режима\",\n\tthumbnails: \"Миниатюры\",\n\tshowThumbnails: \"Показать миниатюры\",\n\thideThumbnails: \"Скрыть миниатюры\",\n\tcaption: \"Подпись изображения\",\n\tshowCaptions: \"Показать подписи\",\n\thideCaptions: \"Скрыть подписи\",\n\tdownload: \"Скачать изображение\"\n};\n\n/** Преобразует стабильные semantic labels foundation в ключи локализации YARL. */\nexport function resolveImageViewerLabels(overrides: Partial<ImageViewerLabels> | undefined) {\n\tconst labels = { ...DEFAULT_IMAGE_VIEWER_LABELS, ...overrides };\n\n\treturn {\n\t\tPrevious: labels.previous,\n\t\tNext: labels.next,\n\t\tClose: labels.close,\n\t\tSlide: labels.slide,\n\t\tCarousel: labels.carousel,\n\t\tLightbox: labels.lightbox,\n\t\t\"Photo gallery\": labels.photoGallery,\n\t\t\"{index} of {total}\": labels.slideCounter,\n\t\t\"Zoom in\": labels.zoomIn,\n\t\t\"Zoom out\": labels.zoomOut,\n\t\t\"Enter Fullscreen\": labels.enterFullscreen,\n\t\t\"Exit Fullscreen\": labels.exitFullscreen,\n\t\tThumbnails: labels.thumbnails,\n\t\t\"Show thumbnails\": labels.showThumbnails,\n\t\t\"Hide thumbnails\": labels.hideThumbnails,\n\t\tCaption: labels.caption,\n\t\t\"Show captions\": labels.showCaptions,\n\t\t\"Hide captions\": labels.hideCaptions,\n\t\tDownload: labels.download\n\t};\n}\n",".viewer {\n\t// Переменные YARL остаются внутренней деталью; потребители настраивают только стабильное пространство image-viewer.\n\t--_image-viewer-top-row-height: calc(\n\t\tvar(--image-viewer-icon-size, 1.75rem) + var(--image-viewer-toolbar-padding, var(--space-md, 0.625rem)) +\n\t\t\tvar(--image-viewer-toolbar-padding, var(--space-md, 0.625rem)) + 1rem\n\t);\n\t--yarl__portal_zindex: var(--image-viewer-z-index, var(--z-image-viewer, 300));\n\t--yarl__color_backdrop: var(--image-viewer-backdrop, rgb(0 0 0 / 92%));\n\t--yarl__container_background_color: var(--image-viewer-backdrop, rgb(0 0 0 / 92%));\n\t--yarl__color_button: var(--image-viewer-control-color, rgb(255 255 255 / 82%));\n\t--yarl__color_button_active: var(--image-viewer-control-active-color, var(--white, #fff));\n\t--yarl__color_button_disabled: var(--image-viewer-control-disabled-color, rgb(255 255 255 / 38%));\n\t--yarl__button_background_color: var(--image-viewer-control-background, transparent);\n\t--yarl__button_border: var(--image-viewer-control-border, 0);\n\t--yarl__button_filter: var(--image-viewer-control-filter, drop-shadow(0 0.125rem 0.25rem rgb(0 0 0 / 70%)));\n\t--yarl__icon_size: var(--image-viewer-icon-size, 1.75rem);\n\t--yarl__toolbar_padding: var(--image-viewer-toolbar-padding, var(--space-md, 0.625rem));\n\t--yarl__slide_icon_loading_color: var(--image-viewer-loading-color, var(--image-viewer-control-color, rgb(255 255 255 / 82%)));\n\t--yarl__slide_icon_error_color: var(--image-viewer-error-color, var(--status-error-fill, #d32f2f));\n\t--yarl__slide_captions_container_background: var(--image-viewer-caption-background, rgb(0 0 0 / 62%));\n\t--yarl__slide_title_color: var(--image-viewer-caption-color, var(--white, #fff));\n\t--yarl__slide_description_color: var(--image-viewer-caption-color, var(--white, #fff));\n\t--yarl__counter_color: var(--image-viewer-counter-color, var(--image-viewer-control-color, rgb(255 255 255 / 82%)));\n\t--yarl__thumbnails_container_background_color: var(--image-viewer-backdrop, rgb(0 0 0 / 92%));\n\t--yarl__thumbnails_thumbnail_background: var(--image-viewer-thumbnail-background, rgb(255 255 255 / 8%));\n\t--yarl__thumbnails_thumbnail_border_color: var(\n\t\t--image-viewer-thumbnail-border-color,\n\t\tvar(--image-viewer-control-color, rgb(255 255 255 / 82%))\n\t);\n\t--yarl__thumbnails_thumbnail_active_border_color: var(\n\t\t--image-viewer-thumbnail-active-border-color,\n\t\tvar(--image-viewer-control-active-color, var(--white, #fff))\n\t);\n\n\tfont-family: var(--font-family-base, sans-serif);\n}\n\n.viewer :global(.yarl__button) {\n\tborder-radius: var(--image-viewer-control-radius, var(--radius-sm, 0.3125rem));\n\ttransition:\n\t\tcolor var(--transition-fast, 0.2s) ease,\n\t\tbackground-color var(--transition-fast, 0.2s) ease;\n}\n\n.viewer :global(.yarl__button):focus-visible,\n.viewer :global(.yarl__thumbnails_thumbnail):focus-visible {\n\toutline: var(--image-viewer-focus, var(--focus, 0.125rem solid currentColor));\n\toutline-offset: var(--image-viewer-focus-offset, var(--focus-offset, 0.125rem));\n}\n\n.viewer :global(.yarl__thumbnails_thumbnail):focus-visible {\n\tbox-shadow: none;\n}\n\n.viewer :global(.yarl__slide_image) {\n\tborder-radius: var(--image-viewer-image-radius, var(--radius-sm, 0.3125rem));\n}\n\n.viewer :global(.yarl__slide_title_container) {\n\tbox-sizing: border-box;\n\theight: var(--_image-viewer-top-row-height);\n\toverflow: hidden;\n}\n\n.icon {\n\twidth: var(--image-viewer-icon-size, 1.75rem);\n\theight: var(--image-viewer-icon-size, 1.75rem);\n\tstroke-width: var(--image-viewer-icon-stroke-width, 2);\n}\n\n.loadingIcon {\n\tanimation: imageViewerSpin 1s linear infinite;\n}\n\n@keyframes imageViewerSpin {\n\tto {\n\t\ttransform: rotate(1turn);\n\t}\n}\n\n@media (prefers-reduced-motion: reduce) {\n\t.loadingIcon {\n\t\tanimation: none;\n\t}\n}\n","import { useEffect, useMemo } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport {\n\tCaptionsIcon,\n\tCaptionsOffIcon,\n\tChevronLeftIcon,\n\tChevronRightIcon,\n\tDownloadIcon,\n\tGalleryThumbnailsIcon,\n\tImageOffIcon,\n\tLoaderCircleIcon,\n\tMaximize2Icon,\n\tMinimize2Icon,\n\tXIcon,\n\tZoomInIcon,\n\tZoomOutIcon\n} from \"lucide-react\";\nimport Lightbox, { isImageSlide, type LightboxExternalProps, type Plugin } from \"yet-another-react-lightbox\";\nimport Captions from \"yet-another-react-lightbox/plugins/captions\";\nimport Counter from \"yet-another-react-lightbox/plugins/counter\";\nimport Download from \"yet-another-react-lightbox/plugins/download\";\nimport Fullscreen from \"yet-another-react-lightbox/plugins/fullscreen\";\nimport Thumbnails from \"yet-another-react-lightbox/plugins/thumbnails\";\nimport Zoom from \"yet-another-react-lightbox/plugins/zoom\";\n\nimport { buildImageViewerSlides } from \"../lib/buildImageViewerSlides\";\nimport { resolveImageViewerLabels } from \"../lib/resolveImageViewerLabels\";\nimport { type ImageViewerProps } from \"../model/imageViewerTypes\";\n\nimport styles from \"./ImageViewer.module.scss\";\n\ntype ImageViewerRuntimeProps = ImageViewerProps & {\n\treadonly onRuntimeMounted: () => void;\n};\n\n/** Внутренняя высота резервируемой верхней строки не является публичной CSS-переменной viewer. */\nconst IMAGE_VIEWER_TOP_ROW_HEIGHT = \"var(--_image-viewer-top-row-height)\";\n\n/**\n * Тяжёлый runtime ImageViewer, изолированный в отдельном динамическом chunk.\n * Компонент приватен для `/image`: YARL-типы и plugin-контракты не должны становиться API foundation.\n */\nexport default function ImageViewerRuntime({\n\topen,\n\timages,\n\tindex = 0,\n\tonClose,\n\tonIndexChange,\n\tfeatures,\n\tloop = false,\n\tcloseOnBackdropClick = true,\n\tcloseOnPullDown = true,\n\tlabels,\n\tclassName,\n\tstyle,\n\tonRuntimeMounted\n}: ImageViewerRuntimeProps) {\n\tuseEffect(() => {\n\t\t// Оболочка сохраняет runtime после первого commit, чтобы не прерывать внутренний close lifecycle YARL.\n\t\tonRuntimeMounted();\n\t}, [onRuntimeMounted]);\n\n\t// Стабильная ссылка предотвращает внешний reset текущего slide при несвязанном rerender родителя.\n\tconst slides = useMemo(() => buildImageViewerSlides(images), [images]);\n\tconst requestedIndex = Number.isFinite(index) ? Math.trunc(index) : 0;\n\tconst resolvedIndex = slides.length > 0 ? Math.min(Math.max(requestedIndex, 0), slides.length - 1) : 0;\n\tconst hasCaptions = images.some((image) => {\n\t\tconst title = image.title === undefined ? image.alt : image.title;\n\t\treturn (title !== undefined && title !== null) || (image.description !== undefined && image.description !== null);\n\t});\n\tconst captionsEnabled = features?.captions ?? hasCaptions;\n\tconst counterEnabled = features?.counter ?? slides.length > 1;\n\tconst downloadEnabled = features?.download ?? false;\n\tconst fullscreenEnabled = features?.fullscreen ?? true;\n\tconst thumbnailsEnabled = features?.thumbnails ?? slides.length > 1;\n\tconst zoomEnabled = features?.zoom ?? true;\n\tconst plugins = useMemo<Plugin[]>(\n\t\t() => [\n\t\t\t...(captionsEnabled ? [Captions] : []),\n\t\t\t...(counterEnabled ? [Counter] : []),\n\t\t\t...(downloadEnabled ? [Download] : []),\n\t\t\t...(fullscreenEnabled ? [Fullscreen] : []),\n\t\t\t...(thumbnailsEnabled ? [Thumbnails] : []),\n\t\t\t...(zoomEnabled ? [Zoom] : [])\n\t\t],\n\t\t[captionsEnabled, counterEnabled, downloadEnabled, fullscreenEnabled, thumbnailsEnabled, zoomEnabled]\n\t);\n\tconst resolvedLabels = useMemo(() => resolveImageViewerLabels(labels), [labels]);\n\tconst lightboxProps: LightboxExternalProps = {\n\t\topen: open && slides.length > 0,\n\t\tclose: onClose,\n\t\tindex: resolvedIndex,\n\t\tslides,\n\t\tplugins,\n\t\tclassName: cn(styles.viewer, className),\n\t\tportal: { container: { style } },\n\t\tlabels: resolvedLabels,\n\t\tcarousel: { finite: !loop },\n\t\tcontroller: { closeOnBackdropClick, closeOnPullDown },\n\t\tcaptions: { showToggle: true },\n\t\tcounter: {\n\t\t\tseparator: \" / \",\n\t\t\tcontainer: {\n\t\t\t\t// При captions счётчик занимает отдельную строку и не пересекается с title в левом верхнем углу.\n\t\t\t\tstyle: captionsEnabled ? { top: IMAGE_VIEWER_TOP_ROW_HEIGHT } : undefined\n\t\t\t}\n\t\t},\n\t\tthumbnails: { showToggle: true },\n\t\tdownload: {\n\t\t\tdownload: ({ slide, saveAs }) => {\n\t\t\t\tif (!isImageSlide(slide) || slide.download === false) return;\n\n\t\t\t\tif (typeof slide.download === \"string\") {\n\t\t\t\t\tsaveAs(slide.download);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (typeof slide.download === \"object\") {\n\t\t\t\t\tsaveAs(slide.download.url, slide.download.filename);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tsaveAs(slide.src);\n\t\t\t}\n\t\t},\n\t\ton: {\n\t\t\tview: ({ index: nextIndex }) => {\n\t\t\t\tif (nextIndex !== resolvedIndex) onIndexChange?.(nextIndex);\n\t\t\t}\n\t\t},\n\t\trender: {\n\t\t\ticonPrev: () => <ChevronLeftIcon aria-hidden=\"true\" className={styles.icon} />,\n\t\t\ticonNext: () => <ChevronRightIcon aria-hidden=\"true\" className={styles.icon} />,\n\t\t\ticonClose: () => <XIcon aria-hidden=\"true\" className={styles.icon} />,\n\t\t\ticonLoading: () => <LoaderCircleIcon aria-hidden=\"true\" className={cn(styles.icon, styles.loadingIcon)} />,\n\t\t\ticonError: () => <ImageOffIcon aria-hidden=\"true\" className={styles.icon} />,\n\t\t\ticonZoomIn: () => <ZoomInIcon aria-hidden=\"true\" className={styles.icon} />,\n\t\t\ticonZoomOut: () => <ZoomOutIcon aria-hidden=\"true\" className={styles.icon} />,\n\t\t\ticonEnterFullscreen: () => <Maximize2Icon aria-hidden=\"true\" className={styles.icon} />,\n\t\t\ticonExitFullscreen: () => <Minimize2Icon aria-hidden=\"true\" className={styles.icon} />,\n\t\t\ticonThumbnailsVisible: () => <GalleryThumbnailsIcon aria-hidden=\"true\" className={styles.icon} />,\n\t\t\ticonThumbnailsHidden: () => <GalleryThumbnailsIcon aria-hidden=\"true\" className={styles.icon} />,\n\t\t\ticonCaptionsVisible: () => <CaptionsIcon aria-hidden=\"true\" className={styles.icon} />,\n\t\t\ticonCaptionsHidden: () => <CaptionsOffIcon aria-hidden=\"true\" className={styles.icon} />,\n\t\t\ticonDownload: () => <DownloadIcon aria-hidden=\"true\" className={styles.icon} />\n\t\t}\n\t};\n\n\treturn <Lightbox {...lightboxProps} />;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ImageViewerRuntime-BMs3BBkV.js","names":[],"sources":["../../src/image/lib/buildImageViewerSlides.ts","../../src/image/lib/resolveImageViewerLabels.ts","../../src/image/ui/ImageViewer.module.scss","../../src/image/ui/ImageViewerRuntime.tsx"],"sourcesContent":["import { type Slide } from \"yet-another-react-lightbox\";\n\nimport { type ImageCandidate } from \"../model/imageTypes\";\nimport { type ImageViewerImage } from \"../model/imageViewerTypes\";\n\n/** Проверяет размер до передачи в srcset внешней lightbox-библиотеки. */\nfunction isPositiveFinite(value: number): boolean {\n\treturn Number.isFinite(value) && value > 0;\n}\n\n/**\n * Преобразует width- и density-кандидат в физическую ширину.\n * Density имеет смысл только вместе с известной intrinsic-шириной базового изображения.\n */\nfunction resolveCandidateWidth(candidate: ImageCandidate, intrinsicWidth: number): number | null {\n\tconst width =\n\t\tcandidate.width !== undefined ? candidate.width : candidate.density !== undefined ? intrinsicWidth * candidate.density : 0;\n\n\treturn isPositiveFinite(width) ? Math.round(width) : null;\n}\n\n/**\n * Строит srcSet YARL, которому для каждого варианта нужны одновременно width и height.\n * Альтернативные picture sources намеренно остаются контрактом ImageView: YARL 3.x не поддерживает их\n * в стандартном image slide, а custom slide лишает viewer встроенного responsive preload и Zoom.\n */\nfunction buildLightboxSrcSet(image: ImageViewerImage): Slide[\"srcSet\"] {\n\tconst { intrinsicWidth, intrinsicHeight } = image;\n\n\tif (\n\t\tintrinsicWidth === undefined ||\n\t\tintrinsicHeight === undefined ||\n\t\t!isPositiveFinite(intrinsicWidth) ||\n\t\t!isPositiveFinite(intrinsicHeight)\n\t) {\n\t\treturn undefined;\n\t}\n\n\tconst candidatesByWidth = new Map<number, { src: string; width: number; height: number }>();\n\n\tfor (const candidate of image.candidates ?? []) {\n\t\tconst candidateWidth = resolveCandidateWidth(candidate, intrinsicWidth);\n\n\t\tif (candidateWidth === null || candidatesByWidth.has(candidateWidth)) continue;\n\n\t\tcandidatesByWidth.set(candidateWidth, {\n\t\t\tsrc: candidate.src,\n\t\t\twidth: candidateWidth,\n\t\t\theight: Math.max(1, Math.round((candidateWidth * intrinsicHeight) / intrinsicWidth))\n\t\t});\n\t}\n\n\tconst candidates = [...candidatesByWidth.values()].sort((left, right) => left.width - right.width);\n\treturn candidates.length > 0 ? candidates : undefined;\n}\n\n/**\n * Адаптирует storage-agnostic ResponsiveImageData к image slides Yet Another React Lightbox.\n * Функция остаётся приватной для `/image`, чтобы vendor contract не становился public API пакета.\n */\nexport function buildImageViewerSlides(images: readonly ImageViewerImage[]): Slide[] {\n\treturn images.map((image) => {\n\t\tconst hasIntrinsicSize = isPositiveFinite(image.intrinsicWidth ?? 0) && isPositiveFinite(image.intrinsicHeight ?? 0);\n\n\t\treturn {\n\t\t\tsrc: image.src,\n\t\t\talt: image.alt,\n\t\t\twidth: hasIntrinsicSize ? image.intrinsicWidth : undefined,\n\t\t\theight: hasIntrinsicSize ? image.intrinsicHeight : undefined,\n\t\t\tsrcSet: buildLightboxSrcSet(image),\n\t\t\ttitle: image.title === undefined ? image.alt : image.title,\n\t\t\tdescription: image.description,\n\t\t\tthumbnail: image.thumbnail,\n\t\t\tdownload: image.download\n\t\t};\n\t});\n}\n","import { type ImageViewerLabels } from \"../model/imageViewerTypes\";\n\nconst DEFAULT_IMAGE_VIEWER_LABELS: ImageViewerLabels = {\n\tprevious: \"Предыдущее изображение\",\n\tnext: \"Следующее изображение\",\n\tclose: \"Закрыть просмотр\",\n\tslide: \"Изображение\",\n\tcarousel: \"Карусель изображений\",\n\tlightbox: \"Просмотр изображений\",\n\tphotoGallery: \"Галерея изображений\",\n\tslideCounter: \"{index} из {total}\",\n\tzoomIn: \"Увеличить\",\n\tzoomOut: \"Уменьшить\",\n\tenterFullscreen: \"Перейти в полноэкранный режим\",\n\texitFullscreen: \"Выйти из полноэкранного режима\",\n\tthumbnails: \"Миниатюры\",\n\tshowThumbnails: \"Показать миниатюры\",\n\thideThumbnails: \"Скрыть миниатюры\",\n\tcaption: \"Подпись изображения\",\n\tshowCaptions: \"Показать подписи\",\n\thideCaptions: \"Скрыть подписи\",\n\tdownload: \"Скачать изображение\"\n};\n\n/** Преобразует стабильные semantic labels foundation в ключи локализации YARL. */\nexport function resolveImageViewerLabels(overrides: Partial<ImageViewerLabels> | undefined) {\n\tconst labels = { ...DEFAULT_IMAGE_VIEWER_LABELS, ...overrides };\n\n\treturn {\n\t\tPrevious: labels.previous,\n\t\tNext: labels.next,\n\t\tClose: labels.close,\n\t\tSlide: labels.slide,\n\t\tCarousel: labels.carousel,\n\t\tLightbox: labels.lightbox,\n\t\t\"Photo gallery\": labels.photoGallery,\n\t\t\"{index} of {total}\": labels.slideCounter,\n\t\t\"Zoom in\": labels.zoomIn,\n\t\t\"Zoom out\": labels.zoomOut,\n\t\t\"Enter Fullscreen\": labels.enterFullscreen,\n\t\t\"Exit Fullscreen\": labels.exitFullscreen,\n\t\tThumbnails: labels.thumbnails,\n\t\t\"Show thumbnails\": labels.showThumbnails,\n\t\t\"Hide thumbnails\": labels.hideThumbnails,\n\t\tCaption: labels.caption,\n\t\t\"Show captions\": labels.showCaptions,\n\t\t\"Hide captions\": labels.hideCaptions,\n\t\tDownload: labels.download\n\t};\n}\n",".viewer {\n\t// Переменные YARL остаются внутренней деталью; потребители настраивают только стабильное пространство image-viewer.\n\t--_image-viewer-top-row-height: calc(\n\t\tvar(--image-viewer-icon-size, 1.75rem) + var(--image-viewer-toolbar-padding, var(--space-md, 0.625rem)) +\n\t\t\tvar(--image-viewer-toolbar-padding, var(--space-md, 0.625rem)) + 1rem\n\t);\n\t--yarl__portal_zindex: var(--image-viewer-z-index, var(--z-image-viewer, 300));\n\t--yarl__color_backdrop: var(--image-viewer-backdrop, rgb(0 0 0 / 92%));\n\t--yarl__container_background_color: var(--image-viewer-backdrop, rgb(0 0 0 / 92%));\n\t--yarl__color_button: var(--image-viewer-control-color, rgb(255 255 255 / 82%));\n\t--yarl__color_button_active: var(--image-viewer-control-active-color, var(--white, #fff));\n\t--yarl__color_button_disabled: var(--image-viewer-control-disabled-color, rgb(255 255 255 / 38%));\n\t--yarl__button_background_color: var(--image-viewer-control-background, transparent);\n\t--yarl__button_border: var(--image-viewer-control-border, 0);\n\t--yarl__button_filter: var(--image-viewer-control-filter, drop-shadow(0 0.125rem 0.25rem rgb(0 0 0 / 70%)));\n\t--yarl__icon_size: var(--image-viewer-icon-size, 1.75rem);\n\t--yarl__toolbar_padding: var(--image-viewer-toolbar-padding, var(--space-md, 0.625rem));\n\t--yarl__slide_icon_loading_color: var(--image-viewer-loading-color, var(--image-viewer-control-color, rgb(255 255 255 / 82%)));\n\t--yarl__slide_icon_error_color: var(--image-viewer-error-color, var(--status-error-fill, #d32f2f));\n\t--yarl__slide_captions_container_background: var(--image-viewer-caption-background, rgb(0 0 0 / 62%));\n\t--yarl__slide_title_color: var(--image-viewer-caption-color, var(--white, #fff));\n\t--yarl__slide_description_color: var(--image-viewer-caption-color, var(--white, #fff));\n\t--yarl__counter_color: var(--image-viewer-counter-color, var(--image-viewer-control-color, rgb(255 255 255 / 82%)));\n\t--yarl__thumbnails_container_background_color: var(--image-viewer-backdrop, rgb(0 0 0 / 92%));\n\t--yarl__thumbnails_thumbnail_background: var(--image-viewer-thumbnail-background, rgb(255 255 255 / 8%));\n\t--yarl__thumbnails_thumbnail_border_color: var(\n\t\t--image-viewer-thumbnail-border-color,\n\t\tvar(--image-viewer-control-color, rgb(255 255 255 / 82%))\n\t);\n\t--yarl__thumbnails_thumbnail_active_border_color: var(\n\t\t--image-viewer-thumbnail-active-border-color,\n\t\tvar(--image-viewer-control-active-color, var(--white, #fff))\n\t);\n\n\tfont-family: var(--font-family-base, sans-serif);\n}\n\n.viewer :global(.yarl__button) {\n\tborder-radius: var(--image-viewer-control-radius, var(--radius-sm, 0.3125rem));\n\ttransition:\n\t\tcolor var(--transition-fast, 0.2s) ease,\n\t\tbackground-color var(--transition-fast, 0.2s) ease;\n}\n\n.viewer :global(.yarl__button):focus-visible,\n.viewer :global(.yarl__thumbnails_thumbnail):focus-visible {\n\toutline: var(--image-viewer-focus, var(--focus, 0.125rem solid currentColor));\n\toutline-offset: var(--image-viewer-focus-offset, var(--focus-offset, 0.125rem));\n}\n\n.viewer :global(.yarl__thumbnails_thumbnail):focus-visible {\n\tbox-shadow: none;\n}\n\n.viewer :global(.yarl__slide_image) {\n\tborder-radius: var(--image-viewer-image-radius, var(--radius-sm, 0.3125rem));\n}\n\n.viewer :global(.yarl__slide_title_container) {\n\tbox-sizing: border-box;\n\theight: var(--_image-viewer-top-row-height);\n\toverflow: hidden;\n}\n\n.icon {\n\twidth: var(--image-viewer-icon-size, 1.75rem);\n\theight: var(--image-viewer-icon-size, 1.75rem);\n\tstroke-width: var(--image-viewer-icon-stroke-width, 2);\n}\n\n.loadingIcon {\n\tanimation: imageViewerSpin 1s linear infinite;\n}\n\n@keyframes imageViewerSpin {\n\tto {\n\t\ttransform: rotate(1turn);\n\t}\n}\n\n@media (prefers-reduced-motion: reduce) {\n\t.loadingIcon {\n\t\tanimation: none;\n\t}\n}\n","import { useEffect, useMemo } from \"react\";\n\nimport { cn } from \"@ryuzaki13/react-foundation-lib/utils\";\nimport {\n\tCaptionsIcon,\n\tCaptionsOffIcon,\n\tChevronLeftIcon,\n\tChevronRightIcon,\n\tDownloadIcon,\n\tGalleryThumbnailsIcon,\n\tImageOffIcon,\n\tLoaderCircleIcon,\n\tMaximize2Icon,\n\tMinimize2Icon,\n\tXIcon,\n\tZoomInIcon,\n\tZoomOutIcon\n} from \"lucide-react\";\nimport Lightbox, { isImageSlide, type LightboxExternalProps, type Plugin } from \"yet-another-react-lightbox\";\nimport Captions from \"yet-another-react-lightbox/plugins/captions\";\nimport Counter from \"yet-another-react-lightbox/plugins/counter\";\nimport Download from \"yet-another-react-lightbox/plugins/download\";\nimport Fullscreen from \"yet-another-react-lightbox/plugins/fullscreen\";\nimport Thumbnails from \"yet-another-react-lightbox/plugins/thumbnails\";\nimport Zoom from \"yet-another-react-lightbox/plugins/zoom\";\n\nimport { buildImageViewerSlides } from \"../lib/buildImageViewerSlides\";\nimport { resolveImageViewerLabels } from \"../lib/resolveImageViewerLabels\";\nimport { type ImageViewerProps } from \"../model/imageViewerTypes\";\n\nimport styles from \"./ImageViewer.module.scss\";\n\ntype ImageViewerRuntimeProps = ImageViewerProps & {\n\treadonly onRuntimeMounted: () => void;\n};\n\n/** Внутренняя высота резервируемой верхней строки не является публичной CSS-переменной viewer. */\nconst IMAGE_VIEWER_TOP_ROW_HEIGHT = \"var(--_image-viewer-top-row-height)\";\n\n/**\n * Тяжёлый runtime ImageViewer, изолированный в отдельном динамическом chunk.\n * Компонент приватен для `/image`: YARL-типы и plugin-контракты не должны становиться API foundation.\n */\nexport default function ImageViewerRuntime({\n\topen,\n\timages,\n\tindex = 0,\n\tonClose,\n\tonIndexChange,\n\tfeatures,\n\tloop = false,\n\tcloseOnBackdropClick = true,\n\tcloseOnPullDown = true,\n\tlabels,\n\tclassName,\n\tstyle,\n\tonRuntimeMounted\n}: ImageViewerRuntimeProps) {\n\tuseEffect(() => {\n\t\t// Оболочка сохраняет runtime после первого commit, чтобы не прерывать внутренний close lifecycle YARL.\n\t\tonRuntimeMounted();\n\t}, [onRuntimeMounted]);\n\n\t// Стабильная ссылка предотвращает внешний reset текущего slide при несвязанном rerender родителя.\n\tconst slides = useMemo(() => buildImageViewerSlides(images), [images]);\n\tconst requestedIndex = Number.isFinite(index) ? Math.trunc(index) : 0;\n\tconst resolvedIndex = slides.length > 0 ? Math.min(Math.max(requestedIndex, 0), slides.length - 1) : 0;\n\tconst hasCaptions = images.some((image) => {\n\t\tconst title = image.title === undefined ? image.alt : image.title;\n\t\treturn (title !== undefined && title !== null) || (image.description !== undefined && image.description !== null);\n\t});\n\tconst captionsEnabled = features?.captions ?? hasCaptions;\n\tconst counterEnabled = features?.counter ?? slides.length > 1;\n\tconst downloadEnabled = features?.download ?? false;\n\tconst fullscreenEnabled = features?.fullscreen ?? true;\n\tconst thumbnailsEnabled = features?.thumbnails ?? slides.length > 1;\n\tconst zoomEnabled = features?.zoom ?? true;\n\tconst plugins = useMemo<Plugin[]>(\n\t\t() => [\n\t\t\t...(captionsEnabled ? [Captions] : []),\n\t\t\t...(counterEnabled ? [Counter] : []),\n\t\t\t...(downloadEnabled ? [Download] : []),\n\t\t\t...(fullscreenEnabled ? [Fullscreen] : []),\n\t\t\t...(thumbnailsEnabled ? [Thumbnails] : []),\n\t\t\t...(zoomEnabled ? [Zoom] : [])\n\t\t],\n\t\t[captionsEnabled, counterEnabled, downloadEnabled, fullscreenEnabled, thumbnailsEnabled, zoomEnabled]\n\t);\n\tconst resolvedLabels = useMemo(() => resolveImageViewerLabels(labels), [labels]);\n\tconst lightboxProps: LightboxExternalProps = {\n\t\topen: open && slides.length > 0,\n\t\tclose: onClose,\n\t\tindex: resolvedIndex,\n\t\tslides,\n\t\tplugins,\n\t\tclassName: cn(styles.viewer, className),\n\t\tportal: { container: { style } },\n\t\tlabels: resolvedLabels,\n\t\tcarousel: { finite: !loop },\n\t\tcontroller: { closeOnBackdropClick, closeOnPullDown },\n\t\tcaptions: { showToggle: true },\n\t\tcounter: {\n\t\t\tseparator: \" / \",\n\t\t\tcontainer: {\n\t\t\t\t// При captions счётчик занимает отдельную строку и не пересекается с title в левом верхнем углу.\n\t\t\t\tstyle: captionsEnabled ? { top: IMAGE_VIEWER_TOP_ROW_HEIGHT } : undefined\n\t\t\t}\n\t\t},\n\t\tthumbnails: { showToggle: true },\n\t\tdownload: {\n\t\t\tdownload: ({ slide, saveAs }) => {\n\t\t\t\tif (!isImageSlide(slide) || slide.download === false) return;\n\n\t\t\t\tif (typeof slide.download === \"string\") {\n\t\t\t\t\tsaveAs(slide.download);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (typeof slide.download === \"object\") {\n\t\t\t\t\tsaveAs(slide.download.url, slide.download.filename);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tsaveAs(slide.src);\n\t\t\t}\n\t\t},\n\t\ton: {\n\t\t\tview: ({ index: nextIndex }) => {\n\t\t\t\tif (nextIndex !== resolvedIndex) onIndexChange?.(nextIndex);\n\t\t\t}\n\t\t},\n\t\trender: {\n\t\t\ticonPrev: () => <ChevronLeftIcon aria-hidden=\"true\" className={styles.icon} />,\n\t\t\ticonNext: () => <ChevronRightIcon aria-hidden=\"true\" className={styles.icon} />,\n\t\t\ticonClose: () => <XIcon aria-hidden=\"true\" className={styles.icon} />,\n\t\t\ticonLoading: () => <LoaderCircleIcon aria-hidden=\"true\" className={cn(styles.icon, styles.loadingIcon)} />,\n\t\t\ticonError: () => <ImageOffIcon aria-hidden=\"true\" className={styles.icon} />,\n\t\t\ticonZoomIn: () => <ZoomInIcon aria-hidden=\"true\" className={styles.icon} />,\n\t\t\ticonZoomOut: () => <ZoomOutIcon aria-hidden=\"true\" className={styles.icon} />,\n\t\t\ticonEnterFullscreen: () => <Maximize2Icon aria-hidden=\"true\" className={styles.icon} />,\n\t\t\ticonExitFullscreen: () => <Minimize2Icon aria-hidden=\"true\" className={styles.icon} />,\n\t\t\ticonThumbnailsVisible: () => <GalleryThumbnailsIcon aria-hidden=\"true\" className={styles.icon} />,\n\t\t\ticonThumbnailsHidden: () => <GalleryThumbnailsIcon aria-hidden=\"true\" className={styles.icon} />,\n\t\t\ticonCaptionsVisible: () => <CaptionsIcon aria-hidden=\"true\" className={styles.icon} />,\n\t\t\ticonCaptionsHidden: () => <CaptionsOffIcon aria-hidden=\"true\" className={styles.icon} />,\n\t\t\ticonDownload: () => <DownloadIcon aria-hidden=\"true\" className={styles.icon} />\n\t\t}\n\t};\n\n\treturn <Lightbox {...lightboxProps} />;\n}\n"],"mappings":"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"}