@vkontakte/vkui 7.3.8 → 7.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (351) hide show
  1. package/dist/components/ActionSheet/ActionSheet.d.ts +1 -1
  2. package/dist/components/ActionSheet/ActionSheet.d.ts.map +1 -1
  3. package/dist/components/ActionSheet/ActionSheet.js.map +1 -1
  4. package/dist/components/AppRoot/ScrollContext.js +2 -2
  5. package/dist/components/AppRoot/ScrollContext.js.map +1 -1
  6. package/dist/components/Banner/Banner.d.ts +2 -2
  7. package/dist/components/Banner/Banner.d.ts.map +1 -1
  8. package/dist/components/Banner/Banner.js.map +1 -1
  9. package/dist/components/Button/Button.d.ts +2 -2
  10. package/dist/components/Button/Button.d.ts.map +1 -1
  11. package/dist/components/Button/Button.js.map +1 -1
  12. package/dist/components/Calendar/Calendar.d.ts.map +1 -1
  13. package/dist/components/Calendar/Calendar.js +9 -7
  14. package/dist/components/Calendar/Calendar.js.map +1 -1
  15. package/dist/components/CalendarRange/CalendarRange.d.ts +9 -2
  16. package/dist/components/CalendarRange/CalendarRange.d.ts.map +1 -1
  17. package/dist/components/CalendarRange/CalendarRange.js +48 -35
  18. package/dist/components/CalendarRange/CalendarRange.js.map +1 -1
  19. package/dist/components/CalendarRange/types.d.ts +2 -0
  20. package/dist/components/CalendarRange/types.d.ts.map +1 -0
  21. package/dist/components/CalendarRange/types.js +3 -0
  22. package/dist/components/CalendarRange/types.js.map +1 -0
  23. package/dist/components/CalendarRange/utils.d.ts +29 -0
  24. package/dist/components/CalendarRange/utils.d.ts.map +1 -0
  25. package/dist/components/CalendarRange/utils.js +123 -0
  26. package/dist/components/CalendarRange/utils.js.map +1 -0
  27. package/dist/components/Checkbox/Checkbox.d.ts +2 -2
  28. package/dist/components/Checkbox/Checkbox.d.ts.map +1 -1
  29. package/dist/components/Checkbox/Checkbox.js.map +1 -1
  30. package/dist/components/ChipsInput/useChipsInput.d.ts.map +1 -1
  31. package/dist/components/ChipsInput/useChipsInput.js +21 -2
  32. package/dist/components/ChipsInput/useChipsInput.js.map +1 -1
  33. package/dist/components/ChipsInputBase/types.d.ts +5 -1
  34. package/dist/components/ChipsInputBase/types.d.ts.map +1 -1
  35. package/dist/components/ChipsInputBase/types.js.map +1 -1
  36. package/dist/components/Clickable/Clickable.d.ts +4 -0
  37. package/dist/components/Clickable/Clickable.d.ts.map +1 -1
  38. package/dist/components/Clickable/Clickable.js +9 -5
  39. package/dist/components/Clickable/Clickable.js.map +1 -1
  40. package/dist/components/Clickable/RealClickable.d.ts +1 -1
  41. package/dist/components/Clickable/RealClickable.d.ts.map +1 -1
  42. package/dist/components/Clickable/RealClickable.js +3 -2
  43. package/dist/components/Clickable/RealClickable.js.map +1 -1
  44. package/dist/components/ContentCard/ContentCard.d.ts +2 -2
  45. package/dist/components/ContentCard/ContentCard.d.ts.map +1 -1
  46. package/dist/components/ContentCard/ContentCard.js.map +1 -1
  47. package/dist/components/CustomSelect/CustomSelect.d.ts +4 -1
  48. package/dist/components/CustomSelect/CustomSelect.d.ts.map +1 -1
  49. package/dist/components/CustomSelect/CustomSelect.js.map +1 -1
  50. package/dist/components/DateInput/DateInput.d.ts +1 -1
  51. package/dist/components/DateInput/DateInput.d.ts.map +1 -1
  52. package/dist/components/DateInput/DateInput.js +48 -50
  53. package/dist/components/DateInput/DateInput.js.map +1 -1
  54. package/dist/components/DateRangeInput/DateRangeInput.d.ts +22 -2
  55. package/dist/components/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  56. package/dist/components/DateRangeInput/DateRangeInput.js +159 -66
  57. package/dist/components/DateRangeInput/DateRangeInput.js.map +1 -1
  58. package/dist/components/FocusTrap/FocusTrap.d.ts +1 -1
  59. package/dist/components/FocusTrap/FocusTrap.d.ts.map +1 -1
  60. package/dist/components/FocusTrap/FocusTrap.js +6 -3
  61. package/dist/components/FocusTrap/FocusTrap.js.map +1 -1
  62. package/dist/components/HorizontalCell/HorizontalCell.d.ts +2 -2
  63. package/dist/components/HorizontalCell/HorizontalCell.d.ts.map +1 -1
  64. package/dist/components/HorizontalCell/HorizontalCell.js.map +1 -1
  65. package/dist/components/HorizontalScroll/HorizontalCellShowMore/HorizontalCellShowMore.d.ts +2 -2
  66. package/dist/components/HorizontalScroll/HorizontalCellShowMore/HorizontalCellShowMore.d.ts.map +1 -1
  67. package/dist/components/HorizontalScroll/HorizontalCellShowMore/HorizontalCellShowMore.js.map +1 -1
  68. package/dist/components/IconButton/IconButton.d.ts +2 -2
  69. package/dist/components/IconButton/IconButton.d.ts.map +1 -1
  70. package/dist/components/IconButton/IconButton.js.map +1 -1
  71. package/dist/components/InputLike/InputLike.d.ts +1 -1
  72. package/dist/components/InputLike/InputLike.d.ts.map +1 -1
  73. package/dist/components/InputLike/InputLike.js +7 -6
  74. package/dist/components/InputLike/InputLike.js.map +1 -1
  75. package/dist/components/Link/Link.d.ts +2 -2
  76. package/dist/components/Link/Link.d.ts.map +1 -1
  77. package/dist/components/Link/Link.js +2 -1
  78. package/dist/components/Link/Link.js.map +1 -1
  79. package/dist/components/MiniInfoCell/MiniInfoCell.d.ts.map +1 -1
  80. package/dist/components/MiniInfoCell/MiniInfoCell.js +1 -8
  81. package/dist/components/MiniInfoCell/MiniInfoCell.js.map +1 -1
  82. package/dist/components/ModalOutsideButton/ModalOutsideButton.d.ts +2 -2
  83. package/dist/components/ModalOutsideButton/ModalOutsideButton.d.ts.map +1 -1
  84. package/dist/components/ModalOutsideButton/ModalOutsideButton.js.map +1 -1
  85. package/dist/components/NumberInputLike/NumberInputLike.d.ts +8 -0
  86. package/dist/components/NumberInputLike/NumberInputLike.d.ts.map +1 -0
  87. package/dist/components/NumberInputLike/NumberInputLike.js +45 -0
  88. package/dist/components/NumberInputLike/NumberInputLike.js.map +1 -0
  89. package/dist/components/Pagination/PaginationPage/PaginationPageButton.d.ts +2 -2
  90. package/dist/components/Pagination/PaginationPage/PaginationPageButton.d.ts.map +1 -1
  91. package/dist/components/Pagination/PaginationPage/PaginationPageButton.js.map +1 -1
  92. package/dist/components/PanelHeader/PanelHeader.d.ts +3 -1
  93. package/dist/components/PanelHeader/PanelHeader.d.ts.map +1 -1
  94. package/dist/components/PanelHeader/PanelHeader.js.map +1 -1
  95. package/dist/components/PanelHeaderButton/PanelHeaderButton.d.ts +2 -2
  96. package/dist/components/PanelHeaderButton/PanelHeaderButton.d.ts.map +1 -1
  97. package/dist/components/PanelHeaderButton/PanelHeaderButton.js.map +1 -1
  98. package/dist/components/Radio/Radio.d.ts +2 -2
  99. package/dist/components/Radio/Radio.d.ts.map +1 -1
  100. package/dist/components/Radio/Radio.js.map +1 -1
  101. package/dist/components/Removable/Removable.d.ts +1 -4
  102. package/dist/components/Removable/Removable.d.ts.map +1 -1
  103. package/dist/components/Removable/Removable.js +39 -116
  104. package/dist/components/Removable/Removable.js.map +1 -1
  105. package/dist/components/Removable/RemovableIos.d.ts +10 -0
  106. package/dist/components/Removable/RemovableIos.d.ts.map +1 -0
  107. package/dist/components/Removable/RemovableIos.js +124 -0
  108. package/dist/components/Removable/RemovableIos.js.map +1 -0
  109. package/dist/components/RichCell/RichCell.d.ts +2 -2
  110. package/dist/components/RichCell/RichCell.d.ts.map +1 -1
  111. package/dist/components/RichCell/RichCell.js.map +1 -1
  112. package/dist/components/ScreenSpinner/ScreenSpinner.d.ts.map +1 -1
  113. package/dist/components/ScreenSpinner/ScreenSpinner.js +4 -2
  114. package/dist/components/ScreenSpinner/ScreenSpinner.js.map +1 -1
  115. package/dist/components/ScreenSpinner/ScreenSpinnerContainer.d.ts +2 -2
  116. package/dist/components/ScreenSpinner/ScreenSpinnerContainer.d.ts.map +1 -1
  117. package/dist/components/ScreenSpinner/ScreenSpinnerContainer.js +4 -3
  118. package/dist/components/ScreenSpinner/ScreenSpinnerContainer.js.map +1 -1
  119. package/dist/components/SelectionControl/SelectionControl.d.ts +2 -2
  120. package/dist/components/SelectionControl/SelectionControl.d.ts.map +1 -1
  121. package/dist/components/SelectionControl/SelectionControl.js.map +1 -1
  122. package/dist/components/SimpleCell/SimpleCell.d.ts +2 -2
  123. package/dist/components/SimpleCell/SimpleCell.d.ts.map +1 -1
  124. package/dist/components/SimpleCell/SimpleCell.js.map +1 -1
  125. package/dist/components/Skeleton/Skeleton.d.ts +5 -1
  126. package/dist/components/Skeleton/Skeleton.d.ts.map +1 -1
  127. package/dist/components/Skeleton/Skeleton.js +7 -4
  128. package/dist/components/Skeleton/Skeleton.js.map +1 -1
  129. package/dist/components/Spinner/Spinner.d.ts +5 -1
  130. package/dist/components/Spinner/Spinner.d.ts.map +1 -1
  131. package/dist/components/Spinner/Spinner.js +6 -3
  132. package/dist/components/Spinner/Spinner.js.map +1 -1
  133. package/dist/components/SubnavigationButton/SubnavigationButton.d.ts +2 -2
  134. package/dist/components/SubnavigationButton/SubnavigationButton.d.ts.map +1 -1
  135. package/dist/components/SubnavigationButton/SubnavigationButton.js.map +1 -1
  136. package/dist/components/Tabs/Tabs.d.ts +13 -9
  137. package/dist/components/Tabs/Tabs.d.ts.map +1 -1
  138. package/dist/components/Tabs/Tabs.js +14 -10
  139. package/dist/components/Tabs/Tabs.js.map +1 -1
  140. package/dist/components/Tabs/TabsController.d.ts +7 -0
  141. package/dist/components/Tabs/TabsController.d.ts.map +1 -0
  142. package/dist/components/Tabs/TabsController.js +19 -0
  143. package/dist/components/Tabs/TabsController.js.map +1 -0
  144. package/dist/components/Tabs/TabsModeContext.d.ts +13 -0
  145. package/dist/components/Tabs/TabsModeContext.d.ts.map +1 -0
  146. package/dist/components/Tabs/TabsModeContext.js +11 -0
  147. package/dist/components/Tabs/TabsModeContext.js.map +1 -0
  148. package/dist/components/TabsItem/TabsItem.d.ts +3 -3
  149. package/dist/components/TabsItem/TabsItem.d.ts.map +1 -1
  150. package/dist/components/TabsItem/TabsItem.js +21 -6
  151. package/dist/components/TabsItem/TabsItem.js.map +1 -1
  152. package/dist/components/Tappable/Tappable.d.ts +1 -0
  153. package/dist/components/Tappable/Tappable.d.ts.map +1 -1
  154. package/dist/components/Tappable/Tappable.js.map +1 -1
  155. package/dist/components/ToolButton/ToolButton.d.ts +2 -2
  156. package/dist/components/ToolButton/ToolButton.d.ts.map +1 -1
  157. package/dist/components/ToolButton/ToolButton.js.map +1 -1
  158. package/dist/components/View/ViewInfinite.js.map +1 -1
  159. package/dist/components.css +1 -1
  160. package/dist/components.css.map +1 -1
  161. package/dist/cssm/components/ActionSheet/ActionSheet.js.map +1 -1
  162. package/dist/cssm/components/AppRoot/ScrollContext.js +2 -2
  163. package/dist/cssm/components/AppRoot/ScrollContext.js.map +1 -1
  164. package/dist/cssm/components/Banner/Banner.js.map +1 -1
  165. package/dist/cssm/components/Button/Button.js.map +1 -1
  166. package/dist/cssm/components/Calendar/Calendar.js +9 -7
  167. package/dist/cssm/components/Calendar/Calendar.js.map +1 -1
  168. package/dist/cssm/components/CalendarRange/CalendarRange.js +44 -31
  169. package/dist/cssm/components/CalendarRange/CalendarRange.js.map +1 -1
  170. package/dist/cssm/components/CalendarRange/types.js +3 -0
  171. package/dist/cssm/components/CalendarRange/types.js.map +1 -0
  172. package/dist/cssm/components/CalendarRange/utils.js +122 -0
  173. package/dist/cssm/components/CalendarRange/utils.js.map +1 -0
  174. package/dist/cssm/components/Checkbox/Checkbox.js.map +1 -1
  175. package/dist/cssm/components/ChipsInput/useChipsInput.js +21 -2
  176. package/dist/cssm/components/ChipsInput/useChipsInput.js.map +1 -1
  177. package/dist/cssm/components/ChipsInputBase/types.js.map +1 -1
  178. package/dist/cssm/components/Clickable/Clickable.js +4 -3
  179. package/dist/cssm/components/Clickable/Clickable.js.map +1 -1
  180. package/dist/cssm/components/Clickable/RealClickable.js +1 -1
  181. package/dist/cssm/components/Clickable/RealClickable.js.map +1 -1
  182. package/dist/cssm/components/ContentCard/ContentCard.js.map +1 -1
  183. package/dist/cssm/components/CustomSelect/CustomSelect.js.map +1 -1
  184. package/dist/cssm/components/DateInput/DateInput.js +45 -46
  185. package/dist/cssm/components/DateInput/DateInput.js.map +1 -1
  186. package/dist/cssm/components/DateRangeInput/DateRangeInput.js +148 -58
  187. package/dist/cssm/components/DateRangeInput/DateRangeInput.js.map +1 -1
  188. package/dist/cssm/components/FocusTrap/FocusTrap.js +4 -2
  189. package/dist/cssm/components/FocusTrap/FocusTrap.js.map +1 -1
  190. package/dist/cssm/components/HorizontalCell/HorizontalCell.js.map +1 -1
  191. package/dist/cssm/components/HorizontalScroll/HorizontalCellShowMore/HorizontalCellShowMore.js.map +1 -1
  192. package/dist/cssm/components/IconButton/IconButton.js.map +1 -1
  193. package/dist/cssm/components/InputLike/InputLike.js +3 -3
  194. package/dist/cssm/components/InputLike/InputLike.js.map +1 -1
  195. package/dist/cssm/components/Link/Link.js +1 -0
  196. package/dist/cssm/components/Link/Link.js.map +1 -1
  197. package/dist/cssm/components/MiniInfoCell/MiniInfoCell.js +1 -8
  198. package/dist/cssm/components/MiniInfoCell/MiniInfoCell.js.map +1 -1
  199. package/dist/cssm/components/ModalOutsideButton/ModalOutsideButton.js.map +1 -1
  200. package/dist/cssm/components/NumberInputLike/NumberInputLike.js +33 -0
  201. package/dist/cssm/components/NumberInputLike/NumberInputLike.js.map +1 -0
  202. package/dist/cssm/components/Pagination/PaginationPage/PaginationPageButton.js.map +1 -1
  203. package/dist/cssm/components/PanelHeader/PanelHeader.js.map +1 -1
  204. package/dist/cssm/components/PanelHeaderButton/PanelHeaderButton.js.map +1 -1
  205. package/dist/cssm/components/Radio/Radio.js.map +1 -1
  206. package/dist/cssm/components/Removable/Removable.js +39 -115
  207. package/dist/cssm/components/Removable/Removable.js.map +1 -1
  208. package/dist/cssm/components/Removable/Removable.module.css +9 -0
  209. package/dist/cssm/components/Removable/RemovableIos.js +118 -0
  210. package/dist/cssm/components/Removable/RemovableIos.js.map +1 -0
  211. package/dist/cssm/components/RichCell/RichCell.js.map +1 -1
  212. package/dist/cssm/components/ScreenSpinner/ScreenSpinner.js +2 -1
  213. package/dist/cssm/components/ScreenSpinner/ScreenSpinner.js.map +1 -1
  214. package/dist/cssm/components/ScreenSpinner/ScreenSpinnerContainer.js +3 -2
  215. package/dist/cssm/components/ScreenSpinner/ScreenSpinnerContainer.js.map +1 -1
  216. package/dist/cssm/components/SelectionControl/SelectionControl.js.map +1 -1
  217. package/dist/cssm/components/SimpleCell/SimpleCell.js.map +1 -1
  218. package/dist/cssm/components/Skeleton/Skeleton.js +6 -3
  219. package/dist/cssm/components/Skeleton/Skeleton.js.map +1 -1
  220. package/dist/cssm/components/Spinner/Spinner.js +5 -2
  221. package/dist/cssm/components/Spinner/Spinner.js.map +1 -1
  222. package/dist/cssm/components/SubnavigationButton/SubnavigationButton.js.map +1 -1
  223. package/dist/cssm/components/Tabs/Tabs.js +10 -9
  224. package/dist/cssm/components/Tabs/Tabs.js.map +1 -1
  225. package/dist/cssm/components/Tabs/TabsController.js +19 -0
  226. package/dist/cssm/components/Tabs/TabsController.js.map +1 -0
  227. package/dist/cssm/components/Tabs/TabsModeContext.js +11 -0
  228. package/dist/cssm/components/Tabs/TabsModeContext.js.map +1 -0
  229. package/dist/cssm/components/TabsItem/TabsItem.js +17 -4
  230. package/dist/cssm/components/TabsItem/TabsItem.js.map +1 -1
  231. package/dist/cssm/components/Tappable/Tappable.js.map +1 -1
  232. package/dist/cssm/components/ToolButton/ToolButton.js.map +1 -1
  233. package/dist/cssm/components/View/ViewInfinite.js.map +1 -1
  234. package/dist/cssm/hooks/useCalendar.js +0 -10
  235. package/dist/cssm/hooks/useCalendar.js.map +1 -1
  236. package/dist/cssm/hooks/useDateInput.js +28 -17
  237. package/dist/cssm/hooks/useDateInput.js.map +1 -1
  238. package/dist/cssm/hooks/useEventListener.js.map +1 -1
  239. package/dist/cssm/hooks/useExternRef.js.map +1 -1
  240. package/dist/cssm/hooks/useFocusTrap.js +2 -2
  241. package/dist/cssm/hooks/useFocusTrap.js.map +1 -1
  242. package/dist/cssm/hooks/useMutationObserver.js +6 -5
  243. package/dist/cssm/hooks/useMutationObserver.js.map +1 -1
  244. package/dist/cssm/lib/dom.js +7 -1
  245. package/dist/cssm/lib/dom.js.map +1 -1
  246. package/dist/cssm/lib/floating/customResizeObserver.js.map +1 -1
  247. package/dist/cssm/lib/floating/index.js.map +1 -1
  248. package/dist/cssm/lib/floating/types/common.js.map +1 -1
  249. package/dist/cssm/lib/sheet/controllers/BottomSheetController.js.map +1 -1
  250. package/dist/cssm/lib/sheet/controllers/CSSTransitionController.js.map +1 -1
  251. package/dist/cssm/styles/animationVisibilityDelay.js +10 -0
  252. package/dist/cssm/styles/animationVisibilityDelay.js.map +1 -0
  253. package/dist/cssm/styles/animationVisibilityDelay.module.css +13 -0
  254. package/dist/cssm/styles/themes.css +4 -2
  255. package/dist/hooks/useCalendar.d.ts +0 -3
  256. package/dist/hooks/useCalendar.d.ts.map +1 -1
  257. package/dist/hooks/useCalendar.js +0 -10
  258. package/dist/hooks/useCalendar.js.map +1 -1
  259. package/dist/hooks/useDateInput.d.ts.map +1 -1
  260. package/dist/hooks/useDateInput.js +29 -18
  261. package/dist/hooks/useDateInput.js.map +1 -1
  262. package/dist/hooks/useEventListener.js.map +1 -1
  263. package/dist/hooks/useExternRef.js.map +1 -1
  264. package/dist/hooks/useFocusTrap.d.ts +5 -1
  265. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  266. package/dist/hooks/useFocusTrap.js +2 -2
  267. package/dist/hooks/useFocusTrap.js.map +1 -1
  268. package/dist/hooks/useMutationObserver.d.ts +2 -1
  269. package/dist/hooks/useMutationObserver.d.ts.map +1 -1
  270. package/dist/hooks/useMutationObserver.js +6 -5
  271. package/dist/hooks/useMutationObserver.js.map +1 -1
  272. package/dist/lib/dom.d.ts.map +1 -1
  273. package/dist/lib/dom.js +7 -1
  274. package/dist/lib/dom.js.map +1 -1
  275. package/dist/lib/floating/customResizeObserver.js.map +1 -1
  276. package/dist/lib/floating/index.d.ts +1 -1
  277. package/dist/lib/floating/index.d.ts.map +1 -1
  278. package/dist/lib/floating/index.js.map +1 -1
  279. package/dist/lib/floating/types/common.d.ts +1 -1
  280. package/dist/lib/floating/types/common.d.ts.map +1 -1
  281. package/dist/lib/floating/types/common.js.map +1 -1
  282. package/dist/lib/sheet/controllers/BottomSheetController.js.map +1 -1
  283. package/dist/lib/sheet/controllers/CSSTransitionController.js.map +1 -1
  284. package/dist/styles/animationVisibilityDelay.d.ts +3 -0
  285. package/dist/styles/animationVisibilityDelay.d.ts.map +1 -0
  286. package/dist/styles/animationVisibilityDelay.js +10 -0
  287. package/dist/styles/animationVisibilityDelay.js.map +1 -0
  288. package/dist/vkui.css +1 -1
  289. package/dist/vkui.css.map +1 -1
  290. package/package.json +3 -6
  291. package/src/components/ActionSheet/ActionSheet.tsx +4 -1
  292. package/src/components/AppRoot/AppRoot.mdx +1 -1
  293. package/src/components/AppRoot/ScrollContext.tsx +2 -2
  294. package/src/components/Banner/Banner.tsx +2 -2
  295. package/src/components/Button/Button.tsx +2 -2
  296. package/src/components/Calendar/Calendar.tsx +8 -7
  297. package/src/components/CalendarRange/CalendarRange.tsx +65 -42
  298. package/src/components/CalendarRange/types.ts +1 -0
  299. package/src/components/CalendarRange/utils.ts +190 -0
  300. package/src/components/Checkbox/Checkbox.tsx +2 -2
  301. package/src/components/ChipsInput/useChipsInput.ts +23 -2
  302. package/src/components/ChipsInputBase/types.ts +5 -1
  303. package/src/components/Clickable/Clickable.tsx +12 -4
  304. package/src/components/Clickable/RealClickable.tsx +1 -0
  305. package/src/components/ContentCard/ContentCard.tsx +2 -2
  306. package/src/components/CustomSelect/CustomSelect.tsx +11 -7
  307. package/src/components/DateInput/DateInput.tsx +41 -43
  308. package/src/components/DateRangeInput/DateRangeInput.tsx +183 -65
  309. package/src/components/FocusTrap/FocusTrap.tsx +3 -0
  310. package/src/components/FormItem/FormItemTop/FormItemTop.mdx +1 -1
  311. package/src/components/HorizontalCell/HorizontalCell.tsx +2 -2
  312. package/src/components/HorizontalScroll/HorizontalCellShowMore/HorizontalCellShowMore.tsx +2 -2
  313. package/src/components/IconButton/IconButton.tsx +2 -2
  314. package/src/components/InputLike/InputLike.tsx +4 -3
  315. package/src/components/Link/Link.tsx +3 -2
  316. package/src/components/MiniInfoCell/MiniInfoCell.tsx +2 -7
  317. package/src/components/ModalOutsideButton/ModalOutsideButton.tsx +2 -2
  318. package/src/components/NumberInputLike/NumberInputLike.tsx +56 -0
  319. package/src/components/Pagination/PaginationPage/PaginationPageButton.tsx +2 -2
  320. package/src/components/PanelHeader/PanelHeader.tsx +3 -1
  321. package/src/components/PanelHeaderButton/PanelHeaderButton.tsx +2 -2
  322. package/src/components/Radio/Radio.tsx +2 -2
  323. package/src/components/Removable/Removable.module.css +9 -0
  324. package/src/components/Removable/Removable.module.css.d.ts.map +1 -1
  325. package/src/components/Removable/Removable.tsx +50 -120
  326. package/src/components/Removable/RemovableIos.tsx +135 -0
  327. package/src/components/RichCell/RichCell.tsx +2 -2
  328. package/src/components/ScreenSpinner/ScreenSpinner.tsx +8 -1
  329. package/src/components/ScreenSpinner/ScreenSpinnerContainer.tsx +4 -1
  330. package/src/components/SelectionControl/SelectionControl.tsx +2 -2
  331. package/src/components/SimpleCell/SimpleCell.tsx +2 -2
  332. package/src/components/Skeleton/Skeleton.tsx +15 -2
  333. package/src/components/Spinner/Spinner.tsx +13 -1
  334. package/src/components/SubnavigationButton/SubnavigationButton.tsx +2 -2
  335. package/src/components/Tabs/Tabs.tsx +23 -19
  336. package/src/components/Tabs/TabsController.ts +37 -0
  337. package/src/components/Tabs/TabsModeContext.ts +24 -0
  338. package/src/components/TabsItem/TabsItem.tsx +22 -5
  339. package/src/components/Tappable/Tappable.tsx +5 -0
  340. package/src/components/ToolButton/ToolButton.tsx +2 -2
  341. package/src/components/UnstyledTextField/UnstyledTextField.mdx +1 -1
  342. package/src/hooks/useCalendar.ts +0 -12
  343. package/src/hooks/useDateInput.ts +21 -12
  344. package/src/hooks/useFocusTrap.ts +10 -1
  345. package/src/hooks/useMutationObserver.ts +7 -4
  346. package/src/lib/dom.tsx +7 -1
  347. package/src/lib/floating/index.ts +2 -0
  348. package/src/lib/floating/types/common.ts +2 -0
  349. package/src/styles/animationVisibilityDelay.module.css +13 -0
  350. package/src/styles/animationVisibilityDelay.module.css.d.ts.map +1 -0
  351. package/src/styles/animationVisibilityDelay.ts +13 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/ActionSheet/ActionSheet.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { noop } from '@vkontakte/vkjs';\nimport { useAdaptivityWithJSMediaQueries } from '../../hooks/useAdaptivityWithJSMediaQueries';\nimport { type UseFocusTrapProps } from '../../hooks/useFocusTrap';\nimport { usePlatform } from '../../hooks/usePlatform';\nimport { useCSSKeyframesAnimationController } from '../../lib/animation';\nimport { AppRootPortal } from '../AppRoot/AppRootPortal';\nimport { useScrollLock } from '../AppRoot/ScrollContext';\nimport { PopoutWrapper } from '../PopoutWrapper/PopoutWrapper';\nimport { Footnote } from '../Typography/Footnote/Footnote';\nimport { ActionSheetContext, type ItemClickHandler } from './ActionSheetContext';\nimport { ActionSheetDefaultIosCloseItem } from './ActionSheetDefaultIosCloseItem';\nimport { ActionSheetDropdownMenu } from './ActionSheetDropdownMenu';\nimport { ActionSheetDropdownSheet } from './ActionSheetDropdownSheet';\nimport type { SharedDropdownProps } from './types';\nimport styles from './ActionSheet.module.css';\n\ntype CloseInitiators = 'action-item' | 'cancel-item' | 'other';\nexport interface ActionSheetOnCloseOptions {\n /**\n * Причина закрытия всплывающего элемента.\n */\n closedBy: CloseInitiators;\n}\n\nexport interface ActionSheetProps\n extends Pick<\n SharedDropdownProps,\n 'toggleRef' | 'popupOffsetDistance' | 'placement' | 'allowClickPropagation'\n >,\n Omit<UseFocusTrapProps, 'onClose' | 'mount' | 'disabled' | 'captureEscapeKeyboardEvent'>,\n Omit<React.HTMLAttributes<HTMLDivElement>, 'autoFocus' | 'title'> {\n /**\n * Заголовок всплыващего окна.\n */\n title?: React.ReactNode;\n /**\n * Описание всплыващего окна, под заголовком.\n */\n description?: React.ReactNode;\n /**\n * Закрыть всплыващее окно по нажатию снаружи.\n */\n onClose: (options: ActionSheetOnCloseOptions) => void;\n /**\n * Только мобильный iOS.\n */\n iosCloseItem?: React.ReactNode;\n /**\n * Режим отображения компонента:\n *\n * - `sheet` – отображение снизу экрана в виде всплывающего окна, подходит для мобильных устройств\n * - `menu` – отображение в виде всплывающего элемента, относительно якорного элемента.\n */\n mode?: 'sheet' | 'menu';\n /**\n * @deprecated Since 7.3.0.\n *\n * Свойство не используется и будет удалено в `v8`.\n */\n mount?: boolean;\n /**\n * @deprecated Since 7.3.0.\n *\n * Свойство не используется и будет удалено в `v8`.\n */\n disabled?: boolean;\n}\n\n/**\n * @see https://vkcom.github.io/VKUI/#/ActionSheet\n */\nexport const ActionSheet = ({\n children,\n className,\n title,\n description,\n style,\n iosCloseItem,\n popupOffsetDistance,\n placement,\n mode: modeProp,\n onClose,\n ...restProps\n}: ActionSheetProps): React.ReactNode => {\n const platform = usePlatform();\n const [closingBy, setClosingBy] = React.useState<undefined | CloseInitiators>(undefined);\n const onCloseWithOther = React.useCallback(() => setClosingBy('other'), []);\n const actionCallbackRef = React.useRef(noop);\n\n const [animationState, animationHandlers] = useCSSKeyframesAnimationController(\n closingBy !== undefined ? 'exit' : 'enter',\n {\n onExited() {\n onClose({ closedBy: closingBy || 'other' });\n actionCallbackRef.current();\n actionCallbackRef.current = noop;\n },\n },\n );\n\n const { isDesktop } = useAdaptivityWithJSMediaQueries();\n const mode = modeProp ?? (isDesktop ? 'menu' : 'sheet');\n\n useScrollLock(mode === 'sheet');\n\n const onItemClick = React.useCallback<ItemClickHandler>(\n ({ action, immediateAction, autoClose, isCancelItem }) =>\n (event) => {\n event.persist();\n immediateAction && immediateAction(event);\n if (autoClose) {\n if (action) {\n actionCallbackRef.current = () => action(event);\n }\n setClosingBy(isCancelItem ? 'cancel-item' : 'action-item');\n } else {\n action && action(event);\n }\n },\n [],\n );\n const contextValue = React.useMemo(\n () => ({ onItemClick, mode, onClose: onCloseWithOther }),\n [mode, onCloseWithOther, onItemClick],\n );\n\n const DropdownComponent = mode === 'menu' ? ActionSheetDropdownMenu : ActionSheetDropdownSheet;\n\n const dropdownProps =\n mode === 'menu' ? Object.assign(restProps, { popupOffsetDistance, placement }) : restProps;\n\n const actionSheet = (\n <ActionSheetContext.Provider value={contextValue}>\n <DropdownComponent\n closing={Boolean(closingBy)}\n role=\"dialog\"\n aria-modal=\"true\"\n autoFocus={animationState === 'entered'}\n {...dropdownProps}\n {...animationHandlers}\n onClose={onCloseWithOther}\n className={mode === 'menu' ? className : undefined}\n style={mode === 'menu' ? style : undefined}\n >\n <div className={styles.contentWrapper}>\n {(title || description) && (\n <div className={styles.header}>\n {title && (\n <Footnote weight=\"2\" className={styles.title}>\n {title}\n </Footnote>\n )}\n {description && <Footnote className={styles.description}>{description}</Footnote>}\n </div>\n )}\n {children}\n </div>\n {platform === 'ios' && mode === 'sheet' && (\n <div className={styles.closeItemWrapperIos}>\n {iosCloseItem ?? <ActionSheetDefaultIosCloseItem />}\n </div>\n )}\n </DropdownComponent>\n </ActionSheetContext.Provider>\n );\n\n return (\n <AppRootPortal>\n <PopoutWrapper\n noBackground={mode === 'menu'}\n closing={Boolean(closingBy)}\n alignY=\"bottom\"\n className={className}\n style={style}\n onClick={onCloseWithOther}\n strategy=\"fixed\"\n >\n {actionSheet}\n </PopoutWrapper>\n </AppRootPortal>\n );\n};\n"],"names":["React","noop","useAdaptivityWithJSMediaQueries","usePlatform","useCSSKeyframesAnimationController","AppRootPortal","useScrollLock","PopoutWrapper","Footnote","ActionSheetContext","ActionSheetDefaultIosCloseItem","ActionSheetDropdownMenu","ActionSheetDropdownSheet","styles","ActionSheet","children","className","title","description","style","iosCloseItem","popupOffsetDistance","placement","mode","modeProp","onClose","restProps","platform","closingBy","setClosingBy","useState","undefined","onCloseWithOther","useCallback","actionCallbackRef","useRef","animationState","animationHandlers","onExited","closedBy","current","isDesktop","onItemClick","action","immediateAction","autoClose","isCancelItem","event","persist","contextValue","useMemo","DropdownComponent","dropdownProps","Object","assign","actionSheet","Provider","value","closing","Boolean","role","aria-modal","autoFocus","div","contentWrapper","header","weight","closeItemWrapperIos","noBackground","alignY","onClick","strategy"],"mappings":"AAAA;;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,IAAI,QAAQ,kBAAkB;AACvC,SAASC,+BAA+B,QAAQ,iDAA8C;AAE9F,SAASC,WAAW,QAAQ,6BAA0B;AACtD,SAASC,kCAAkC,QAAQ,+BAAsB;AACzE,SAASC,aAAa,QAAQ,8BAA2B;AACzD,SAASC,aAAa,QAAQ,8BAA2B;AACzD,SAASC,aAAa,QAAQ,oCAAiC;AAC/D,SAASC,QAAQ,QAAQ,qCAAkC;AAC3D,SAASC,kBAAkB,QAA+B,0BAAuB;AACjF,SAASC,8BAA8B,QAAQ,sCAAmC;AAClF,SAASC,uBAAuB,QAAQ,+BAA4B;AACpE,SAASC,wBAAwB,QAAQ,gCAA6B;AAEtE,OAAOC,YAAY,2BAA2B;AAsD9C;;CAEC,GACD,OAAO,MAAMC,cAAc,CAAC,EAC1BC,QAAQ,EACRC,SAAS,EACTC,KAAK,EACLC,WAAW,EACXC,KAAK,EACLC,YAAY,EACZC,mBAAmB,EACnBC,SAAS,EACTC,MAAMC,QAAQ,EACdC,OAAO,EACP,GAAGC,WACc;IACjB,MAAMC,WAAWxB;IACjB,MAAM,CAACyB,WAAWC,aAAa,GAAG7B,MAAM8B,QAAQ,CAA8BC;IAC9E,MAAMC,mBAAmBhC,MAAMiC,WAAW,CAAC,IAAMJ,aAAa,UAAU,EAAE;IAC1E,MAAMK,oBAAoBlC,MAAMmC,MAAM,CAAClC;IAEvC,MAAM,CAACmC,gBAAgBC,kBAAkB,GAAGjC,mCAC1CwB,cAAcG,YAAY,SAAS,SACnC;QACEO;YACEb,QAAQ;gBAAEc,UAAUX,aAAa;YAAQ;YACzCM,kBAAkBM,OAAO;YACzBN,kBAAkBM,OAAO,GAAGvC;QAC9B;IACF;IAGF,MAAM,EAAEwC,SAAS,EAAE,GAAGvC;IACtB,MAAMqB,OAAOC,YAAaiB,CAAAA,YAAY,SAAS,OAAM;IAErDnC,cAAciB,SAAS;IAEvB,MAAMmB,cAAc1C,MAAMiC,WAAW,CACnC,CAAC,EAAEU,MAAM,EAAEC,eAAe,EAAEC,SAAS,EAAEC,YAAY,EAAE,GACnD,CAACC;YACCA,MAAMC,OAAO;YACbJ,mBAAmBA,gBAAgBG;YACnC,IAAIF,WAAW;gBACb,IAAIF,QAAQ;oBACVT,kBAAkBM,OAAO,GAAG,IAAMG,OAAOI;gBAC3C;gBACAlB,aAAaiB,eAAe,gBAAgB;YAC9C,OAAO;gBACLH,UAAUA,OAAOI;YACnB;QACF,GACF,EAAE;IAEJ,MAAME,eAAejD,MAAMkD,OAAO,CAChC,IAAO,CAAA;YAAER;YAAanB;YAAME,SAASO;QAAiB,CAAA,GACtD;QAACT;QAAMS;QAAkBU;KAAY;IAGvC,MAAMS,oBAAoB5B,SAAS,SAASZ,0BAA0BC;IAEtE,MAAMwC,gBACJ7B,SAAS,SAAS8B,OAAOC,MAAM,CAAC5B,WAAW;QAAEL;QAAqBC;IAAU,KAAKI;IAEnF,MAAM6B,4BACJ,KAAC9C,mBAAmB+C,QAAQ;QAACC,OAAOR;kBAClC,cAAA,MAACE;YACCO,SAASC,QAAQ/B;YACjBgC,MAAK;YACLC,cAAW;YACXC,WAAW1B,mBAAmB;YAC7B,GAAGgB,aAAa;YAChB,GAAGf,iBAAiB;YACrBZ,SAASO;YACThB,WAAWO,SAAS,SAASP,YAAYe;YACzCZ,OAAOI,SAAS,SAASJ,QAAQY;;8BAEjC,MAACgC;oBAAI/C,WAAWH,OAAOmD,cAAc;;wBACjC/C,CAAAA,SAASC,WAAU,mBACnB,MAAC6C;4BAAI/C,WAAWH,OAAOoD,MAAM;;gCAC1BhD,uBACC,KAACT;oCAAS0D,QAAO;oCAAIlD,WAAWH,OAAOI,KAAK;8CACzCA;;gCAGJC,6BAAe,KAACV;oCAASQ,WAAWH,OAAOK,WAAW;8CAAGA;;;;wBAG7DH;;;gBAEFY,aAAa,SAASJ,SAAS,yBAC9B,KAACwC;oBAAI/C,WAAWH,OAAOsD,mBAAmB;8BACvC/C,8BAAgB,KAACV;;;;;IAO5B,qBACE,KAACL;kBACC,cAAA,KAACE;YACC6D,cAAc7C,SAAS;YACvBmC,SAASC,QAAQ/B;YACjByC,QAAO;YACPrD,WAAWA;YACXG,OAAOA;YACPmD,SAAStC;YACTuC,UAAS;sBAERhB;;;AAIT,EAAE"}
1
+ {"version":3,"sources":["../../../../src/components/ActionSheet/ActionSheet.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { noop } from '@vkontakte/vkjs';\nimport { useAdaptivityWithJSMediaQueries } from '../../hooks/useAdaptivityWithJSMediaQueries';\nimport { type UseFocusTrapProps } from '../../hooks/useFocusTrap';\nimport { usePlatform } from '../../hooks/usePlatform';\nimport { useCSSKeyframesAnimationController } from '../../lib/animation';\nimport { AppRootPortal } from '../AppRoot/AppRootPortal';\nimport { useScrollLock } from '../AppRoot/ScrollContext';\nimport { PopoutWrapper } from '../PopoutWrapper/PopoutWrapper';\nimport { Footnote } from '../Typography/Footnote/Footnote';\nimport { ActionSheetContext, type ItemClickHandler } from './ActionSheetContext';\nimport { ActionSheetDefaultIosCloseItem } from './ActionSheetDefaultIosCloseItem';\nimport { ActionSheetDropdownMenu } from './ActionSheetDropdownMenu';\nimport { ActionSheetDropdownSheet } from './ActionSheetDropdownSheet';\nimport type { SharedDropdownProps } from './types';\nimport styles from './ActionSheet.module.css';\n\ntype CloseInitiators = 'action-item' | 'cancel-item' | 'other';\nexport interface ActionSheetOnCloseOptions {\n /**\n * Причина закрытия всплывающего элемента.\n */\n closedBy: CloseInitiators;\n}\n\nexport interface ActionSheetProps\n extends Pick<\n SharedDropdownProps,\n 'toggleRef' | 'popupOffsetDistance' | 'placement' | 'allowClickPropagation'\n >,\n Omit<\n UseFocusTrapProps,\n 'onClose' | 'mount' | 'disabled' | 'captureEscapeKeyboardEvent' | 'mutationObserverOptions'\n >,\n Omit<React.HTMLAttributes<HTMLDivElement>, 'autoFocus' | 'title'> {\n /**\n * Заголовок всплыващего окна.\n */\n title?: React.ReactNode;\n /**\n * Описание всплыващего окна, под заголовком.\n */\n description?: React.ReactNode;\n /**\n * Закрыть всплыващее окно по нажатию снаружи.\n */\n onClose: (options: ActionSheetOnCloseOptions) => void;\n /**\n * Только мобильный iOS.\n */\n iosCloseItem?: React.ReactNode;\n /**\n * Режим отображения компонента:\n *\n * - `sheet` – отображение снизу экрана в виде всплывающего окна, подходит для мобильных устройств\n * - `menu` – отображение в виде всплывающего элемента, относительно якорного элемента.\n */\n mode?: 'sheet' | 'menu';\n /**\n * @deprecated Since 7.3.0.\n *\n * Свойство не используется и будет удалено в `v8`.\n */\n mount?: boolean;\n /**\n * @deprecated Since 7.3.0.\n *\n * Свойство не используется и будет удалено в `v8`.\n */\n disabled?: boolean;\n}\n\n/**\n * @see https://vkcom.github.io/VKUI/#/ActionSheet\n */\nexport const ActionSheet = ({\n children,\n className,\n title,\n description,\n style,\n iosCloseItem,\n popupOffsetDistance,\n placement,\n mode: modeProp,\n onClose,\n ...restProps\n}: ActionSheetProps): React.ReactNode => {\n const platform = usePlatform();\n const [closingBy, setClosingBy] = React.useState<undefined | CloseInitiators>(undefined);\n const onCloseWithOther = React.useCallback(() => setClosingBy('other'), []);\n const actionCallbackRef = React.useRef(noop);\n\n const [animationState, animationHandlers] = useCSSKeyframesAnimationController(\n closingBy !== undefined ? 'exit' : 'enter',\n {\n onExited() {\n onClose({ closedBy: closingBy || 'other' });\n actionCallbackRef.current();\n actionCallbackRef.current = noop;\n },\n },\n );\n\n const { isDesktop } = useAdaptivityWithJSMediaQueries();\n const mode = modeProp ?? (isDesktop ? 'menu' : 'sheet');\n\n useScrollLock(mode === 'sheet');\n\n const onItemClick = React.useCallback<ItemClickHandler>(\n ({ action, immediateAction, autoClose, isCancelItem }) =>\n (event) => {\n event.persist();\n immediateAction && immediateAction(event);\n if (autoClose) {\n if (action) {\n actionCallbackRef.current = () => action(event);\n }\n setClosingBy(isCancelItem ? 'cancel-item' : 'action-item');\n } else {\n action && action(event);\n }\n },\n [],\n );\n const contextValue = React.useMemo(\n () => ({ onItemClick, mode, onClose: onCloseWithOther }),\n [mode, onCloseWithOther, onItemClick],\n );\n\n const DropdownComponent = mode === 'menu' ? ActionSheetDropdownMenu : ActionSheetDropdownSheet;\n\n const dropdownProps =\n mode === 'menu' ? Object.assign(restProps, { popupOffsetDistance, placement }) : restProps;\n\n const actionSheet = (\n <ActionSheetContext.Provider value={contextValue}>\n <DropdownComponent\n closing={Boolean(closingBy)}\n role=\"dialog\"\n aria-modal=\"true\"\n autoFocus={animationState === 'entered'}\n {...dropdownProps}\n {...animationHandlers}\n onClose={onCloseWithOther}\n className={mode === 'menu' ? className : undefined}\n style={mode === 'menu' ? style : undefined}\n >\n <div className={styles.contentWrapper}>\n {(title || description) && (\n <div className={styles.header}>\n {title && (\n <Footnote weight=\"2\" className={styles.title}>\n {title}\n </Footnote>\n )}\n {description && <Footnote className={styles.description}>{description}</Footnote>}\n </div>\n )}\n {children}\n </div>\n {platform === 'ios' && mode === 'sheet' && (\n <div className={styles.closeItemWrapperIos}>\n {iosCloseItem ?? <ActionSheetDefaultIosCloseItem />}\n </div>\n )}\n </DropdownComponent>\n </ActionSheetContext.Provider>\n );\n\n return (\n <AppRootPortal>\n <PopoutWrapper\n noBackground={mode === 'menu'}\n closing={Boolean(closingBy)}\n alignY=\"bottom\"\n className={className}\n style={style}\n onClick={onCloseWithOther}\n strategy=\"fixed\"\n >\n {actionSheet}\n </PopoutWrapper>\n </AppRootPortal>\n );\n};\n"],"names":["React","noop","useAdaptivityWithJSMediaQueries","usePlatform","useCSSKeyframesAnimationController","AppRootPortal","useScrollLock","PopoutWrapper","Footnote","ActionSheetContext","ActionSheetDefaultIosCloseItem","ActionSheetDropdownMenu","ActionSheetDropdownSheet","styles","ActionSheet","children","className","title","description","style","iosCloseItem","popupOffsetDistance","placement","mode","modeProp","onClose","restProps","platform","closingBy","setClosingBy","useState","undefined","onCloseWithOther","useCallback","actionCallbackRef","useRef","animationState","animationHandlers","onExited","closedBy","current","isDesktop","onItemClick","action","immediateAction","autoClose","isCancelItem","event","persist","contextValue","useMemo","DropdownComponent","dropdownProps","Object","assign","actionSheet","Provider","value","closing","Boolean","role","aria-modal","autoFocus","div","contentWrapper","header","weight","closeItemWrapperIos","noBackground","alignY","onClick","strategy"],"mappings":"AAAA;;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,IAAI,QAAQ,kBAAkB;AACvC,SAASC,+BAA+B,QAAQ,iDAA8C;AAE9F,SAASC,WAAW,QAAQ,6BAA0B;AACtD,SAASC,kCAAkC,QAAQ,+BAAsB;AACzE,SAASC,aAAa,QAAQ,8BAA2B;AACzD,SAASC,aAAa,QAAQ,8BAA2B;AACzD,SAASC,aAAa,QAAQ,oCAAiC;AAC/D,SAASC,QAAQ,QAAQ,qCAAkC;AAC3D,SAASC,kBAAkB,QAA+B,0BAAuB;AACjF,SAASC,8BAA8B,QAAQ,sCAAmC;AAClF,SAASC,uBAAuB,QAAQ,+BAA4B;AACpE,SAASC,wBAAwB,QAAQ,gCAA6B;AAEtE,OAAOC,YAAY,2BAA2B;AAyD9C;;CAEC,GACD,OAAO,MAAMC,cAAc,CAAC,EAC1BC,QAAQ,EACRC,SAAS,EACTC,KAAK,EACLC,WAAW,EACXC,KAAK,EACLC,YAAY,EACZC,mBAAmB,EACnBC,SAAS,EACTC,MAAMC,QAAQ,EACdC,OAAO,EACP,GAAGC,WACc;IACjB,MAAMC,WAAWxB;IACjB,MAAM,CAACyB,WAAWC,aAAa,GAAG7B,MAAM8B,QAAQ,CAA8BC;IAC9E,MAAMC,mBAAmBhC,MAAMiC,WAAW,CAAC,IAAMJ,aAAa,UAAU,EAAE;IAC1E,MAAMK,oBAAoBlC,MAAMmC,MAAM,CAAClC;IAEvC,MAAM,CAACmC,gBAAgBC,kBAAkB,GAAGjC,mCAC1CwB,cAAcG,YAAY,SAAS,SACnC;QACEO;YACEb,QAAQ;gBAAEc,UAAUX,aAAa;YAAQ;YACzCM,kBAAkBM,OAAO;YACzBN,kBAAkBM,OAAO,GAAGvC;QAC9B;IACF;IAGF,MAAM,EAAEwC,SAAS,EAAE,GAAGvC;IACtB,MAAMqB,OAAOC,YAAaiB,CAAAA,YAAY,SAAS,OAAM;IAErDnC,cAAciB,SAAS;IAEvB,MAAMmB,cAAc1C,MAAMiC,WAAW,CACnC,CAAC,EAAEU,MAAM,EAAEC,eAAe,EAAEC,SAAS,EAAEC,YAAY,EAAE,GACnD,CAACC;YACCA,MAAMC,OAAO;YACbJ,mBAAmBA,gBAAgBG;YACnC,IAAIF,WAAW;gBACb,IAAIF,QAAQ;oBACVT,kBAAkBM,OAAO,GAAG,IAAMG,OAAOI;gBAC3C;gBACAlB,aAAaiB,eAAe,gBAAgB;YAC9C,OAAO;gBACLH,UAAUA,OAAOI;YACnB;QACF,GACF,EAAE;IAEJ,MAAME,eAAejD,MAAMkD,OAAO,CAChC,IAAO,CAAA;YAAER;YAAanB;YAAME,SAASO;QAAiB,CAAA,GACtD;QAACT;QAAMS;QAAkBU;KAAY;IAGvC,MAAMS,oBAAoB5B,SAAS,SAASZ,0BAA0BC;IAEtE,MAAMwC,gBACJ7B,SAAS,SAAS8B,OAAOC,MAAM,CAAC5B,WAAW;QAAEL;QAAqBC;IAAU,KAAKI;IAEnF,MAAM6B,4BACJ,KAAC9C,mBAAmB+C,QAAQ;QAACC,OAAOR;kBAClC,cAAA,MAACE;YACCO,SAASC,QAAQ/B;YACjBgC,MAAK;YACLC,cAAW;YACXC,WAAW1B,mBAAmB;YAC7B,GAAGgB,aAAa;YAChB,GAAGf,iBAAiB;YACrBZ,SAASO;YACThB,WAAWO,SAAS,SAASP,YAAYe;YACzCZ,OAAOI,SAAS,SAASJ,QAAQY;;8BAEjC,MAACgC;oBAAI/C,WAAWH,OAAOmD,cAAc;;wBACjC/C,CAAAA,SAASC,WAAU,mBACnB,MAAC6C;4BAAI/C,WAAWH,OAAOoD,MAAM;;gCAC1BhD,uBACC,KAACT;oCAAS0D,QAAO;oCAAIlD,WAAWH,OAAOI,KAAK;8CACzCA;;gCAGJC,6BAAe,KAACV;oCAASQ,WAAWH,OAAOK,WAAW;8CAAGA;;;;wBAG7DH;;;gBAEFY,aAAa,SAASJ,SAAS,yBAC9B,KAACwC;oBAAI/C,WAAWH,OAAOsD,mBAAmB;8BACvC/C,8BAAgB,KAACV;;;;;IAO5B,qBACE,KAACL;kBACC,cAAA,KAACE;YACC6D,cAAc7C,SAAS;YACvBmC,SAASC,QAAQ/B;YACjByC,QAAO;YACPrD,WAAWA;YACXG,OAAOA;YACPmD,SAAStC;YACTuC,UAAS;sBAERhB;;;AAIT,EAAE"}
@@ -100,8 +100,8 @@ const _getScroll = ({ xOffset, yOffset, element, scrollLockEnabled, customCalcY
100
100
  yOffset
101
101
  ];
102
102
  return {
103
- x: scrollLeft,
104
- y: customCalcY(scrollTop)
103
+ x: scrollLeft || 0,
104
+ y: customCalcY(scrollTop) || 0
105
105
  };
106
106
  };
107
107
  export const GlobalScrollController = ({ children })=>{
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/AppRoot/ScrollContext.tsx"],"sourcesContent":["'use client';\n/* eslint-disable jsdoc/require-jsdoc */\n\nimport * as React from 'react';\nimport { noop } from '@vkontakte/vkjs';\nimport { clamp } from '../../helpers/math';\nimport { useDOM } from '../../lib/dom';\nimport type { HasChildren } from '../../types';\n\nconst clearDisableScrollStyle = (node: HTMLElement) => {\n Object.assign(node.style, {\n position: '',\n top: '',\n left: '',\n right: '',\n overscrollBehavior: '',\n overflowY: '',\n overflowX: '',\n });\n};\n\nconst getPageYOffsetWithoutKeyboardHeight = (window: Window, scrollTop: number) => {\n // Note: здесь расчёт на то, что `clientHeight` равен `window.innerHeight`.\n // Это достигается тем, что тегу `html` задали`height: 100%` и у него нет отступов сверху и снизу. Если есть отступы,\n // то надо задать `box-sizing: border-box`, чтобы они не учитывались.\n const diffOfClientHeightAndViewportHeight =\n window.document.documentElement.clientHeight - window.innerHeight;\n return scrollTop - diffOfClientHeightAndViewportHeight;\n};\n\nexport type GetScrollOptions = {\n compensateKeyboardHeight?: boolean;\n};\n\nexport interface ScrollContextInterface {\n getScroll: (this: void, options?: GetScrollOptions) => { x: number; y: number };\n scrollTo: (this: void, x?: number, y?: number) => void;\n /**\n * Увеличивает счетчик блокировки прокрутки.\n */\n incrementScrollLockCounter: (this: void) => void;\n /**\n * Уменьшает счетчик блокировки прокрутки.\n */\n decrementScrollLockCounter: (this: void) => void;\n beforeScrollLockFnSetRef?: React.RefObject<Set<() => void>>;\n}\n\nexport const ScrollContext: React.Context<ScrollContextInterface> =\n React.createContext<ScrollContextInterface>({\n getScroll: () => ({ x: 0, y: 0 }),\n scrollTo: noop,\n incrementScrollLockCounter: noop,\n decrementScrollLockCounter: noop,\n });\n\nexport const useScroll = (): ScrollContextInterface => React.useContext(ScrollContext);\n\n/**\n * Управляет блокировкой окна в зависимости от внутреннего счетчика.\n * Если счетчик больше нуля, требуется заблокировать прокрутку.\n */\nfunction useScrollLockController(enableScrollLock: () => void, disableScrollLock: () => void) {\n const countRef = React.useRef(0);\n\n const updateScrollLock = React.useCallback(() => {\n if (countRef.current > 0) {\n enableScrollLock();\n } else {\n disableScrollLock();\n }\n }, [enableScrollLock, disableScrollLock]);\n\n const incrementScrollLockCounter = React.useCallback(() => {\n countRef.current += 1;\n updateScrollLock();\n }, [updateScrollLock]);\n\n const decrementScrollLockCounter = React.useCallback(() => {\n countRef.current -= 1;\n updateScrollLock();\n }, [updateScrollLock]);\n\n return [incrementScrollLockCounter, decrementScrollLockCounter];\n}\n\nexport function useManualScroll(): Pick<ScrollContextInterface, 'scrollTo' | 'getScroll'> {\n const { scrollTo, getScroll } = React.useContext(ScrollContext);\n return React.useMemo(\n () => ({\n scrollTo,\n getScroll,\n }),\n [getScroll, scrollTo],\n );\n}\n\nexport interface ScrollControllerProps extends HasChildren {\n elRef: React.RefObject<HTMLElement | null>;\n}\n\nconst _scrollTo = ({\n x,\n y,\n scrollWidth,\n clientWidth,\n scrollHeight,\n clientHeight,\n scrollLockEnabled,\n lockedElement,\n elementToScroll,\n}: {\n x: number;\n y: number;\n scrollWidth: number;\n clientWidth: number;\n scrollHeight: number;\n clientHeight: number;\n scrollLockEnabled: boolean;\n lockedElement: HTMLElement;\n elementToScroll: Window | HTMLElement;\n}) => {\n // Some iOS versions do not normalize scroll — do it manually.\n const left = x ? clamp(x, 0, scrollWidth - clientWidth) : 0;\n const top = y ? clamp(y, 0, scrollHeight - clientHeight) : 0;\n\n if (scrollLockEnabled) {\n Object.assign(lockedElement.style, {\n left: `-${left}px`,\n top: `-${top}px`,\n });\n } else {\n elementToScroll.scrollTo({\n left,\n top,\n });\n }\n};\n\nconst _getScroll = ({\n xOffset,\n yOffset,\n element,\n scrollLockEnabled,\n customCalcY = (v) => v,\n}: {\n xOffset: number;\n yOffset: number;\n element: HTMLElement;\n scrollLockEnabled: boolean;\n customCalcY?: (scrollTop: number) => number;\n}) => {\n const elementStyles = element.style;\n const [scrollLeft, scrollTop] = scrollLockEnabled\n ? [-parseFloat(elementStyles.left || '0'), -parseFloat(elementStyles.top || '0')]\n : [xOffset, yOffset];\n return {\n x: scrollLeft,\n y: customCalcY(scrollTop),\n };\n};\n\nexport const GlobalScrollController = ({ children }: ScrollControllerProps): React.ReactNode => {\n const { window, document } = useDOM();\n const beforeScrollLockFnSetRef = React.useRef<Set<() => void>>(new Set());\n const scrollLockEnabledRef = React.useRef(false);\n\n const getScroll = React.useCallback<ScrollContextInterface['getScroll']>(\n (options = { compensateKeyboardHeight: true }) => {\n if (!window || !document) {\n return { x: 0, y: 0 };\n }\n return _getScroll({\n xOffset: window.pageXOffset,\n yOffset: window.pageYOffset,\n element: document.documentElement,\n scrollLockEnabled: scrollLockEnabledRef.current,\n customCalcY: (scrollTop) =>\n options.compensateKeyboardHeight\n ? getPageYOffsetWithoutKeyboardHeight(window, scrollTop)\n : scrollTop,\n });\n },\n [document, window],\n );\n const scrollTo = React.useCallback<ScrollContextInterface['scrollTo']>(\n (x = 0, y = 0) => {\n if (!window || !document) {\n return;\n }\n _scrollTo({\n x,\n y,\n\n scrollWidth: document.body.scrollWidth,\n clientWidth: window.innerWidth,\n\n scrollHeight: document.body.scrollHeight,\n clientHeight: window.innerHeight,\n\n scrollLockEnabled: scrollLockEnabledRef.current,\n lockedElement: document.documentElement,\n elementToScroll: window,\n });\n },\n [document, window],\n );\n\n const enableScrollLock = React.useCallback(() => {\n beforeScrollLockFnSetRef.current.forEach((fn) => {\n fn();\n });\n const { x: scrollX, y: scrollY } = getScroll({ compensateKeyboardHeight: false });\n const overflowY = window!.innerWidth > document!.documentElement.clientWidth ? 'scroll' : '';\n const overflowX = window!.innerHeight > document!.documentElement.clientHeight ? 'scroll' : '';\n\n Object.assign(document!.documentElement.style, {\n position: 'fixed',\n top: `-${scrollY}px`,\n left: `-${scrollX}px`,\n right: '0',\n overscrollBehavior: 'none',\n overflowY,\n overflowX,\n });\n\n scrollLockEnabledRef.current = true;\n }, [document, getScroll, window]);\n\n const disableScrollLock = React.useCallback(() => {\n const scrollData = getScroll({ compensateKeyboardHeight: false });\n clearDisableScrollStyle(document!.documentElement);\n scrollLockEnabledRef.current = false;\n\n scrollTo(scrollData.x, scrollData.y);\n }, [document, getScroll, scrollTo]);\n\n const [incrementScrollLockCounter, decrementScrollLockCounter] = useScrollLockController(\n enableScrollLock,\n disableScrollLock,\n );\n\n const scrollController = React.useMemo<ScrollContextInterface>(\n () => ({\n getScroll,\n scrollTo,\n incrementScrollLockCounter,\n decrementScrollLockCounter,\n beforeScrollLockFnSetRef: beforeScrollLockFnSetRef,\n }),\n [getScroll, scrollTo, incrementScrollLockCounter, decrementScrollLockCounter],\n );\n\n return <ScrollContext.Provider value={scrollController}>{children}</ScrollContext.Provider>;\n};\n\nexport const ElementScrollController = ({\n elRef,\n children,\n}: ScrollControllerProps): React.ReactNode => {\n const beforeScrollLockFnSetRef = React.useRef<Set<() => void>>(new Set());\n const scrollLockEnabledRef = React.useRef(false);\n\n const getScroll = React.useCallback<ScrollContextInterface['getScroll']>(() => {\n const element = elRef.current;\n if (!element) {\n return { x: 0, y: 0 };\n }\n return _getScroll({\n xOffset: element.scrollLeft,\n yOffset: element.scrollTop,\n element: element,\n scrollLockEnabled: scrollLockEnabledRef.current,\n });\n }, [elRef]);\n\n const scrollTo = React.useCallback<ScrollContextInterface['scrollTo']>(\n (x = 0, y = 0) => {\n const el = elRef.current;\n if (!el) {\n return;\n }\n _scrollTo({\n x,\n y,\n\n scrollWidth: el.scrollWidth,\n clientWidth: el.clientWidth,\n\n scrollHeight: el.scrollHeight,\n clientHeight: el.clientHeight,\n\n scrollLockEnabled: scrollLockEnabledRef.current,\n lockedElement: el,\n elementToScroll: el,\n });\n },\n [elRef],\n );\n\n const enableScrollLock = React.useCallback(() => {\n const el = elRef.current;\n if (!el) {\n return;\n }\n beforeScrollLockFnSetRef.current.forEach((fn) => {\n fn();\n });\n\n const { x: scrollX, y: scrollY } = getScroll();\n\n const overflowY = el.scrollWidth > el.clientWidth ? 'scroll' : '';\n const overflowX = el.scrollHeight > el.clientHeight ? 'scroll' : '';\n\n Object.assign(el.style, {\n position: 'absolute',\n right: '0',\n top: `-${scrollY}px`,\n left: `-${scrollX}px`,\n overflowY,\n overflowX,\n });\n scrollLockEnabledRef.current = true;\n }, [elRef, getScroll]);\n\n const disableScrollLock = React.useCallback(() => {\n const el = elRef.current;\n if (!el) {\n return;\n }\n\n const scrollData = getScroll();\n clearDisableScrollStyle(el);\n scrollLockEnabledRef.current = false;\n\n scrollTo(scrollData.x, scrollData.y);\n }, [elRef, getScroll, scrollTo]);\n\n const [incrementScrollLockCounter, decrementScrollLockCounter] = useScrollLockController(\n enableScrollLock,\n disableScrollLock,\n );\n\n const scrollController = React.useMemo<ScrollContextInterface>(\n () => ({\n getScroll,\n scrollTo,\n incrementScrollLockCounter,\n decrementScrollLockCounter,\n beforeScrollLockFnSetRef,\n }),\n [getScroll, scrollTo, incrementScrollLockCounter, decrementScrollLockCounter],\n );\n\n return <ScrollContext.Provider value={scrollController}>{children}</ScrollContext.Provider>;\n};\n\n/**\n * Блокирует прокрутку окна.\n *\n * @param enabled - Если false то не будет блокировать.\n */\nexport const useScrollLock = (enabled = true): void => {\n const { incrementScrollLockCounter, decrementScrollLockCounter } = useScroll();\n\n React.useEffect(() => {\n if (enabled) {\n incrementScrollLockCounter();\n return decrementScrollLockCounter;\n }\n\n return noop;\n }, [enabled, incrementScrollLockCounter, decrementScrollLockCounter]);\n};\n"],"names":["React","noop","clamp","useDOM","clearDisableScrollStyle","node","Object","assign","style","position","top","left","right","overscrollBehavior","overflowY","overflowX","getPageYOffsetWithoutKeyboardHeight","window","scrollTop","diffOfClientHeightAndViewportHeight","document","documentElement","clientHeight","innerHeight","ScrollContext","createContext","getScroll","x","y","scrollTo","incrementScrollLockCounter","decrementScrollLockCounter","useScroll","useContext","useScrollLockController","enableScrollLock","disableScrollLock","countRef","useRef","updateScrollLock","useCallback","current","useManualScroll","useMemo","_scrollTo","scrollWidth","clientWidth","scrollHeight","scrollLockEnabled","lockedElement","elementToScroll","_getScroll","xOffset","yOffset","element","customCalcY","v","elementStyles","scrollLeft","parseFloat","GlobalScrollController","children","beforeScrollLockFnSetRef","Set","scrollLockEnabledRef","options","compensateKeyboardHeight","pageXOffset","pageYOffset","body","innerWidth","forEach","fn","scrollX","scrollY","scrollData","scrollController","Provider","value","ElementScrollController","elRef","el","useScrollLock","enabled","useEffect"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/components/AppRoot/ScrollContext.tsx"],"sourcesContent":["'use client';\n/* eslint-disable jsdoc/require-jsdoc */\n\nimport * as React from 'react';\nimport { noop } from '@vkontakte/vkjs';\nimport { clamp } from '../../helpers/math';\nimport { useDOM } from '../../lib/dom';\nimport type { HasChildren } from '../../types';\n\nconst clearDisableScrollStyle = (node: HTMLElement) => {\n Object.assign(node.style, {\n position: '',\n top: '',\n left: '',\n right: '',\n overscrollBehavior: '',\n overflowY: '',\n overflowX: '',\n });\n};\n\nconst getPageYOffsetWithoutKeyboardHeight = (window: Window, scrollTop: number) => {\n // Note: здесь расчёт на то, что `clientHeight` равен `window.innerHeight`.\n // Это достигается тем, что тегу `html` задали`height: 100%` и у него нет отступов сверху и снизу. Если есть отступы,\n // то надо задать `box-sizing: border-box`, чтобы они не учитывались.\n const diffOfClientHeightAndViewportHeight =\n window.document.documentElement.clientHeight - window.innerHeight;\n return scrollTop - diffOfClientHeightAndViewportHeight;\n};\n\nexport type GetScrollOptions = {\n compensateKeyboardHeight?: boolean;\n};\n\nexport interface ScrollContextInterface {\n getScroll: (this: void, options?: GetScrollOptions) => { x: number; y: number };\n scrollTo: (this: void, x?: number, y?: number) => void;\n /**\n * Увеличивает счетчик блокировки прокрутки.\n */\n incrementScrollLockCounter: (this: void) => void;\n /**\n * Уменьшает счетчик блокировки прокрутки.\n */\n decrementScrollLockCounter: (this: void) => void;\n beforeScrollLockFnSetRef?: React.RefObject<Set<() => void>>;\n}\n\nexport const ScrollContext: React.Context<ScrollContextInterface> =\n React.createContext<ScrollContextInterface>({\n getScroll: () => ({ x: 0, y: 0 }),\n scrollTo: noop,\n incrementScrollLockCounter: noop,\n decrementScrollLockCounter: noop,\n });\n\nexport const useScroll = (): ScrollContextInterface => React.useContext(ScrollContext);\n\n/**\n * Управляет блокировкой окна в зависимости от внутреннего счетчика.\n * Если счетчик больше нуля, требуется заблокировать прокрутку.\n */\nfunction useScrollLockController(enableScrollLock: () => void, disableScrollLock: () => void) {\n const countRef = React.useRef(0);\n\n const updateScrollLock = React.useCallback(() => {\n if (countRef.current > 0) {\n enableScrollLock();\n } else {\n disableScrollLock();\n }\n }, [enableScrollLock, disableScrollLock]);\n\n const incrementScrollLockCounter = React.useCallback(() => {\n countRef.current += 1;\n updateScrollLock();\n }, [updateScrollLock]);\n\n const decrementScrollLockCounter = React.useCallback(() => {\n countRef.current -= 1;\n updateScrollLock();\n }, [updateScrollLock]);\n\n return [incrementScrollLockCounter, decrementScrollLockCounter];\n}\n\nexport function useManualScroll(): Pick<ScrollContextInterface, 'scrollTo' | 'getScroll'> {\n const { scrollTo, getScroll } = React.useContext(ScrollContext);\n return React.useMemo(\n () => ({\n scrollTo,\n getScroll,\n }),\n [getScroll, scrollTo],\n );\n}\n\nexport interface ScrollControllerProps extends HasChildren {\n elRef: React.RefObject<HTMLElement | null>;\n}\n\nconst _scrollTo = ({\n x,\n y,\n scrollWidth,\n clientWidth,\n scrollHeight,\n clientHeight,\n scrollLockEnabled,\n lockedElement,\n elementToScroll,\n}: {\n x: number;\n y: number;\n scrollWidth: number;\n clientWidth: number;\n scrollHeight: number;\n clientHeight: number;\n scrollLockEnabled: boolean;\n lockedElement: HTMLElement;\n elementToScroll: Window | HTMLElement;\n}) => {\n // Some iOS versions do not normalize scroll — do it manually.\n const left = x ? clamp(x, 0, scrollWidth - clientWidth) : 0;\n const top = y ? clamp(y, 0, scrollHeight - clientHeight) : 0;\n\n if (scrollLockEnabled) {\n Object.assign(lockedElement.style, {\n left: `-${left}px`,\n top: `-${top}px`,\n });\n } else {\n elementToScroll.scrollTo({\n left,\n top,\n });\n }\n};\n\nconst _getScroll = ({\n xOffset,\n yOffset,\n element,\n scrollLockEnabled,\n customCalcY = (v) => v,\n}: {\n xOffset: number;\n yOffset: number;\n element: HTMLElement;\n scrollLockEnabled: boolean;\n customCalcY?: (scrollTop: number) => number;\n}) => {\n const elementStyles = element.style;\n const [scrollLeft, scrollTop] = scrollLockEnabled\n ? [-parseFloat(elementStyles.left || '0'), -parseFloat(elementStyles.top || '0')]\n : [xOffset, yOffset];\n return {\n x: scrollLeft || 0,\n y: customCalcY(scrollTop) || 0,\n };\n};\n\nexport const GlobalScrollController = ({ children }: ScrollControllerProps): React.ReactNode => {\n const { window, document } = useDOM();\n const beforeScrollLockFnSetRef = React.useRef<Set<() => void>>(new Set());\n const scrollLockEnabledRef = React.useRef(false);\n\n const getScroll = React.useCallback<ScrollContextInterface['getScroll']>(\n (options = { compensateKeyboardHeight: true }) => {\n if (!window || !document) {\n return { x: 0, y: 0 };\n }\n return _getScroll({\n xOffset: window.pageXOffset,\n yOffset: window.pageYOffset,\n element: document.documentElement,\n scrollLockEnabled: scrollLockEnabledRef.current,\n customCalcY: (scrollTop) =>\n options.compensateKeyboardHeight\n ? getPageYOffsetWithoutKeyboardHeight(window, scrollTop)\n : scrollTop,\n });\n },\n [document, window],\n );\n const scrollTo = React.useCallback<ScrollContextInterface['scrollTo']>(\n (x = 0, y = 0) => {\n if (!window || !document) {\n return;\n }\n _scrollTo({\n x,\n y,\n\n scrollWidth: document.body.scrollWidth,\n clientWidth: window.innerWidth,\n\n scrollHeight: document.body.scrollHeight,\n clientHeight: window.innerHeight,\n\n scrollLockEnabled: scrollLockEnabledRef.current,\n lockedElement: document.documentElement,\n elementToScroll: window,\n });\n },\n [document, window],\n );\n\n const enableScrollLock = React.useCallback(() => {\n beforeScrollLockFnSetRef.current.forEach((fn) => {\n fn();\n });\n const { x: scrollX, y: scrollY } = getScroll({ compensateKeyboardHeight: false });\n const overflowY = window!.innerWidth > document!.documentElement.clientWidth ? 'scroll' : '';\n const overflowX = window!.innerHeight > document!.documentElement.clientHeight ? 'scroll' : '';\n\n Object.assign(document!.documentElement.style, {\n position: 'fixed',\n top: `-${scrollY}px`,\n left: `-${scrollX}px`,\n right: '0',\n overscrollBehavior: 'none',\n overflowY,\n overflowX,\n });\n\n scrollLockEnabledRef.current = true;\n }, [document, getScroll, window]);\n\n const disableScrollLock = React.useCallback(() => {\n const scrollData = getScroll({ compensateKeyboardHeight: false });\n clearDisableScrollStyle(document!.documentElement);\n scrollLockEnabledRef.current = false;\n\n scrollTo(scrollData.x, scrollData.y);\n }, [document, getScroll, scrollTo]);\n\n const [incrementScrollLockCounter, decrementScrollLockCounter] = useScrollLockController(\n enableScrollLock,\n disableScrollLock,\n );\n\n const scrollController = React.useMemo<ScrollContextInterface>(\n () => ({\n getScroll,\n scrollTo,\n incrementScrollLockCounter,\n decrementScrollLockCounter,\n beforeScrollLockFnSetRef: beforeScrollLockFnSetRef,\n }),\n [getScroll, scrollTo, incrementScrollLockCounter, decrementScrollLockCounter],\n );\n\n return <ScrollContext.Provider value={scrollController}>{children}</ScrollContext.Provider>;\n};\n\nexport const ElementScrollController = ({\n elRef,\n children,\n}: ScrollControllerProps): React.ReactNode => {\n const beforeScrollLockFnSetRef = React.useRef<Set<() => void>>(new Set());\n const scrollLockEnabledRef = React.useRef(false);\n\n const getScroll = React.useCallback<ScrollContextInterface['getScroll']>(() => {\n const element = elRef.current;\n if (!element) {\n return { x: 0, y: 0 };\n }\n return _getScroll({\n xOffset: element.scrollLeft,\n yOffset: element.scrollTop,\n element: element,\n scrollLockEnabled: scrollLockEnabledRef.current,\n });\n }, [elRef]);\n\n const scrollTo = React.useCallback<ScrollContextInterface['scrollTo']>(\n (x = 0, y = 0) => {\n const el = elRef.current;\n if (!el) {\n return;\n }\n _scrollTo({\n x,\n y,\n\n scrollWidth: el.scrollWidth,\n clientWidth: el.clientWidth,\n\n scrollHeight: el.scrollHeight,\n clientHeight: el.clientHeight,\n\n scrollLockEnabled: scrollLockEnabledRef.current,\n lockedElement: el,\n elementToScroll: el,\n });\n },\n [elRef],\n );\n\n const enableScrollLock = React.useCallback(() => {\n const el = elRef.current;\n if (!el) {\n return;\n }\n beforeScrollLockFnSetRef.current.forEach((fn) => {\n fn();\n });\n\n const { x: scrollX, y: scrollY } = getScroll();\n\n const overflowY = el.scrollWidth > el.clientWidth ? 'scroll' : '';\n const overflowX = el.scrollHeight > el.clientHeight ? 'scroll' : '';\n\n Object.assign(el.style, {\n position: 'absolute',\n right: '0',\n top: `-${scrollY}px`,\n left: `-${scrollX}px`,\n overflowY,\n overflowX,\n });\n scrollLockEnabledRef.current = true;\n }, [elRef, getScroll]);\n\n const disableScrollLock = React.useCallback(() => {\n const el = elRef.current;\n if (!el) {\n return;\n }\n\n const scrollData = getScroll();\n clearDisableScrollStyle(el);\n scrollLockEnabledRef.current = false;\n\n scrollTo(scrollData.x, scrollData.y);\n }, [elRef, getScroll, scrollTo]);\n\n const [incrementScrollLockCounter, decrementScrollLockCounter] = useScrollLockController(\n enableScrollLock,\n disableScrollLock,\n );\n\n const scrollController = React.useMemo<ScrollContextInterface>(\n () => ({\n getScroll,\n scrollTo,\n incrementScrollLockCounter,\n decrementScrollLockCounter,\n beforeScrollLockFnSetRef,\n }),\n [getScroll, scrollTo, incrementScrollLockCounter, decrementScrollLockCounter],\n );\n\n return <ScrollContext.Provider value={scrollController}>{children}</ScrollContext.Provider>;\n};\n\n/**\n * Блокирует прокрутку окна.\n *\n * @param enabled - Если false то не будет блокировать.\n */\nexport const useScrollLock = (enabled = true): void => {\n const { incrementScrollLockCounter, decrementScrollLockCounter } = useScroll();\n\n React.useEffect(() => {\n if (enabled) {\n incrementScrollLockCounter();\n return decrementScrollLockCounter;\n }\n\n return noop;\n }, [enabled, incrementScrollLockCounter, decrementScrollLockCounter]);\n};\n"],"names":["React","noop","clamp","useDOM","clearDisableScrollStyle","node","Object","assign","style","position","top","left","right","overscrollBehavior","overflowY","overflowX","getPageYOffsetWithoutKeyboardHeight","window","scrollTop","diffOfClientHeightAndViewportHeight","document","documentElement","clientHeight","innerHeight","ScrollContext","createContext","getScroll","x","y","scrollTo","incrementScrollLockCounter","decrementScrollLockCounter","useScroll","useContext","useScrollLockController","enableScrollLock","disableScrollLock","countRef","useRef","updateScrollLock","useCallback","current","useManualScroll","useMemo","_scrollTo","scrollWidth","clientWidth","scrollHeight","scrollLockEnabled","lockedElement","elementToScroll","_getScroll","xOffset","yOffset","element","customCalcY","v","elementStyles","scrollLeft","parseFloat","GlobalScrollController","children","beforeScrollLockFnSetRef","Set","scrollLockEnabledRef","options","compensateKeyboardHeight","pageXOffset","pageYOffset","body","innerWidth","forEach","fn","scrollX","scrollY","scrollData","scrollController","Provider","value","ElementScrollController","elRef","el","useScrollLock","enabled","useEffect"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/Banner/Banner.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Icon24Cancel, Icon24Chevron, Icon24Dismiss, Icon24DismissDark } from '@vkontakte/icons';\nimport { classNames, hasReactNode } from '@vkontakte/vkjs';\nimport { usePlatform } from '../../hooks/usePlatform';\nimport { IconButton } from '../IconButton/IconButton';\nimport { Tappable, type TappableProps } from '../Tappable/Tappable';\nimport { Headline } from '../Typography/Headline/Headline';\nimport { Subhead } from '../Typography/Subhead/Subhead';\nimport { Text } from '../Typography/Text/Text';\nimport { Title } from '../Typography/Title/Title';\nimport styles from './Banner.module.css';\n\nexport interface BannerProps extends Omit<TappableProps, 'title' | 'size'> {\n /**\n * Тип баннера.\n */\n mode?: 'tint' | 'image';\n /**\n * Размер баннера.\n */\n size?: 's' | 'm';\n /**\n * Тип действия в правой части баннера.\n *\n * - `dismiss` – отображается иконка крестика, при нажатии на неё сработает свойство `onDismiss`.\n * - `chevron` – отображается иконка шеврона, которая подразумевает, что при нажатии на баннер можно куда-то перейти.\n */\n after?: 'dismiss' | 'chevron' | React.ReactNode;\n /**\n * Срабатывает при нажатии на иконку крестика при `after=\"dismiss\"`.\n */\n onDismiss?: React.MouseEventHandler<HTMLButtonElement>;\n /**\n * Текст кнопки закрытия. Делает ее доступной для ассистивных технологий.\n */\n dismissLabel?: string;\n /**\n * Содержимое, отображаемое в левой части баннера.\n */\n before?: React.ReactNode;\n /**\n * Заголовок.\n */\n title?: React.ReactNode;\n /**\n * Подзаголовок.\n */\n subtitle?: React.ReactNode;\n /**\n * Дополнительный подзаголовок баннера.\n */\n extraSubtitle?: React.ReactNode;\n /**\n * При использовании `mode=\"image\"`.\n *\n * - `light` – в качестве фона используется светлое изображение, цвет текста в баннере будет тёмным.\n * - `dark` – в качестве фона используется тёмное изображение, цвет текста будет светлым.\n */\n imageTheme?: 'light' | 'dark';\n /**\n * При использовании `mode=\"image\"`.\n *\n * Элемент, который нужно стилизовать цветом и/или фоном. Этот элемент будет растянут на 100% ширины и высоты баннера.\n */\n background?: React.ReactNode;\n /**\n * Кнопки-действия. Принимает [`Button`](https://vkcom.github.io/VKUI/#/Button).\n *\n * - В режиме `tint` или `image` со светлым фоном используйте только с параметрами:\n * - `mode=\"primary\"`\n * - `mode=\"secondary\"`\n * - В режиме `image` с тёмным фоном используйте с параметрами:\n * - `appearance=\"overlay\"`.\n *\n * Для набора кнопок используйте [`ButtonGroup`](https://vkcom.github.io/VKUI/#/ButtonGroup) с параметрами:\n *\n * - `gap=\"m\" mode=\"horizontal\" stretched`\n * - `gap=\"m\" mode=\"vertical\" stretched`.\n */\n actions?: React.ReactNode;\n}\n\n/**\n * @see https://vkcom.github.io/VKUI/#/Banner\n */\nexport const Banner = ({\n mode = 'tint',\n imageTheme = 'dark',\n size = 's',\n before,\n after: afterProp,\n title,\n subtitle,\n extraSubtitle,\n children,\n background,\n actions,\n onDismiss,\n dismissLabel = 'Скрыть',\n Component,\n ...restProps\n}: BannerProps): React.ReactNode => {\n const platform = usePlatform();\n\n const HeaderTypography = size === 'm' ? Title : Headline;\n const SubheadTypography = size === 'm' ? Text : Subhead;\n\n const IconDismissIOS = mode === 'image' ? Icon24DismissDark : Icon24Dismiss;\n\n const content = (\n <>\n {mode === 'image' && background && (\n <div aria-hidden className={styles.bg}>\n {background}\n </div>\n )}\n\n {before && <div className={styles.before}>{before}</div>}\n\n <div className={styles.content}>\n {hasReactNode(title) && (\n <HeaderTypography Component=\"div\" weight=\"2\" level={size === 'm' ? '2' : '1'}>\n {title}\n </HeaderTypography>\n )}\n {hasReactNode(subtitle) && (\n <SubheadTypography Component=\"div\" className={styles.subtitle}>\n {subtitle}\n </SubheadTypography>\n )}\n {hasReactNode(extraSubtitle) && (\n <Text Component=\"div\" className={styles.extraSubtitle}>\n {extraSubtitle}\n </Text>\n )}\n {hasReactNode(actions) && React.Children.count(actions) > 0 && (\n <div className={styles.actions}>{actions}</div>\n )}\n </div>\n </>\n );\n\n const afterMap: Record<string, React.ReactNode> = {\n chevron: <Icon24Chevron className={styles.chevron} />,\n dismiss: (\n <IconButton\n label={dismissLabel}\n className={styles.dismiss}\n onClick={onDismiss}\n hoverMode=\"opacity\"\n hasActive={false}\n >\n {platform === 'ios' ? <IconDismissIOS /> : <Icon24Cancel />}\n </IconButton>\n ),\n };\n\n const after = afterProp && (\n <div className={styles.after}>\n {typeof afterProp === 'string' ? afterMap[afterProp] : afterProp}\n </div>\n );\n\n const isClickable = restProps.onClick || restProps.onClickCapture || restProps.href;\n\n return (\n <Tappable\n Component={Component || (!isClickable ? 'section' : undefined)}\n activeMode={platform === 'ios' ? 'opacity' : 'background'}\n baseClassName={classNames(\n styles.host,\n platform === 'ios' && styles.ios,\n mode === 'image' && styles.modeImage,\n size === 'm' && styles.sizeM,\n mode === 'image' && imageTheme === 'dark' && styles.inverted,\n )}\n {...restProps}\n >\n {content}\n {after}\n </Tappable>\n );\n};\n"],"names":["React","Icon24Cancel","Icon24Chevron","Icon24Dismiss","Icon24DismissDark","classNames","hasReactNode","usePlatform","IconButton","Tappable","Headline","Subhead","Text","Title","styles","Banner","mode","imageTheme","size","before","after","afterProp","title","subtitle","extraSubtitle","children","background","actions","onDismiss","dismissLabel","Component","restProps","platform","HeaderTypography","SubheadTypography","IconDismissIOS","content","div","aria-hidden","className","bg","weight","level","Children","count","afterMap","chevron","dismiss","label","onClick","hoverMode","hasActive","isClickable","onClickCapture","href","undefined","activeMode","baseClassName","host","ios","modeImage","sizeM","inverted"],"mappings":"AAAA;;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,YAAY,EAAEC,aAAa,EAAEC,aAAa,EAAEC,iBAAiB,QAAQ,mBAAmB;AACjG,SAASC,UAAU,EAAEC,YAAY,QAAQ,kBAAkB;AAC3D,SAASC,WAAW,QAAQ,6BAA0B;AACtD,SAASC,UAAU,QAAQ,8BAA2B;AACtD,SAASC,QAAQ,QAA4B,0BAAuB;AACpE,SAASC,QAAQ,QAAQ,qCAAkC;AAC3D,SAASC,OAAO,QAAQ,mCAAgC;AACxD,SAASC,IAAI,QAAQ,6BAA0B;AAC/C,SAASC,KAAK,QAAQ,+BAA4B;AAClD,OAAOC,YAAY,sBAAsB;AAwEzC;;CAEC,GACD,OAAO,MAAMC,SAAS,CAAC,EACrBC,OAAO,MAAM,EACbC,aAAa,MAAM,EACnBC,OAAO,GAAG,EACVC,MAAM,EACNC,OAAOC,SAAS,EAChBC,KAAK,EACLC,QAAQ,EACRC,aAAa,EACbC,QAAQ,EACRC,UAAU,EACVC,OAAO,EACPC,SAAS,EACTC,eAAe,QAAQ,EACvBC,SAAS,EACT,GAAGC,WACS;IACZ,MAAMC,WAAWzB;IAEjB,MAAM0B,mBAAmBf,SAAS,MAAML,QAAQH;IAChD,MAAMwB,oBAAoBhB,SAAS,MAAMN,OAAOD;IAEhD,MAAMwB,iBAAiBnB,SAAS,UAAUZ,oBAAoBD;IAE9D,MAAMiC,wBACJ;;YACGpB,SAAS,WAAWU,4BACnB,KAACW;gBAAIC,aAAW;gBAACC,WAAWzB,OAAO0B,EAAE;0BAClCd;;YAIJP,wBAAU,KAACkB;gBAAIE,WAAWzB,OAAOK,MAAM;0BAAGA;;0BAE3C,MAACkB;gBAAIE,WAAWzB,OAAOsB,OAAO;;oBAC3B9B,aAAagB,wBACZ,KAACW;wBAAiBH,WAAU;wBAAMW,QAAO;wBAAIC,OAAOxB,SAAS,MAAM,MAAM;kCACtEI;;oBAGJhB,aAAaiB,2BACZ,KAACW;wBAAkBJ,WAAU;wBAAMS,WAAWzB,OAAOS,QAAQ;kCAC1DA;;oBAGJjB,aAAakB,gCACZ,KAACZ;wBAAKkB,WAAU;wBAAMS,WAAWzB,OAAOU,aAAa;kCAClDA;;oBAGJlB,aAAaqB,YAAY3B,MAAM2C,QAAQ,CAACC,KAAK,CAACjB,WAAW,mBACxD,KAACU;wBAAIE,WAAWzB,OAAOa,OAAO;kCAAGA;;;;;;IAMzC,MAAMkB,WAA4C;QAChDC,uBAAS,KAAC5C;YAAcqC,WAAWzB,OAAOgC,OAAO;;QACjDC,uBACE,KAACvC;YACCwC,OAAOnB;YACPU,WAAWzB,OAAOiC,OAAO;YACzBE,SAASrB;YACTsB,WAAU;YACVC,WAAW;sBAEVnB,aAAa,sBAAQ,KAACG,oCAAoB,KAAClC;;IAGlD;IAEA,MAAMmB,QAAQC,2BACZ,KAACgB;QAAIE,WAAWzB,OAAOM,KAAK;kBACzB,OAAOC,cAAc,WAAWwB,QAAQ,CAACxB,UAAU,GAAGA;;IAI3D,MAAM+B,cAAcrB,UAAUkB,OAAO,IAAIlB,UAAUsB,cAAc,IAAItB,UAAUuB,IAAI;IAEnF,qBACE,MAAC7C;QACCqB,WAAWA,aAAc,CAAA,CAACsB,cAAc,YAAYG,SAAQ;QAC5DC,YAAYxB,aAAa,QAAQ,YAAY;QAC7CyB,eAAepD,WACbS,OAAO4C,IAAI,EACX1B,aAAa,SAASlB,OAAO6C,GAAG,EAChC3C,SAAS,WAAWF,OAAO8C,SAAS,EACpC1C,SAAS,OAAOJ,OAAO+C,KAAK,EAC5B7C,SAAS,WAAWC,eAAe,UAAUH,OAAOgD,QAAQ;QAE7D,GAAG/B,SAAS;;YAEZK;YACAhB;;;AAGP,EAAE"}
1
+ {"version":3,"sources":["../../../../src/components/Banner/Banner.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Icon24Cancel, Icon24Chevron, Icon24Dismiss, Icon24DismissDark } from '@vkontakte/icons';\nimport { classNames, hasReactNode } from '@vkontakte/vkjs';\nimport { usePlatform } from '../../hooks/usePlatform';\nimport { IconButton } from '../IconButton/IconButton';\nimport { Tappable, type TappableOmitProps } from '../Tappable/Tappable';\nimport { Headline } from '../Typography/Headline/Headline';\nimport { Subhead } from '../Typography/Subhead/Subhead';\nimport { Text } from '../Typography/Text/Text';\nimport { Title } from '../Typography/Title/Title';\nimport styles from './Banner.module.css';\n\nexport interface BannerProps extends Omit<TappableOmitProps, 'title' | 'size'> {\n /**\n * Тип баннера.\n */\n mode?: 'tint' | 'image';\n /**\n * Размер баннера.\n */\n size?: 's' | 'm';\n /**\n * Тип действия в правой части баннера.\n *\n * - `dismiss` – отображается иконка крестика, при нажатии на неё сработает свойство `onDismiss`.\n * - `chevron` – отображается иконка шеврона, которая подразумевает, что при нажатии на баннер можно куда-то перейти.\n */\n after?: 'dismiss' | 'chevron' | React.ReactNode;\n /**\n * Срабатывает при нажатии на иконку крестика при `after=\"dismiss\"`.\n */\n onDismiss?: React.MouseEventHandler<HTMLButtonElement>;\n /**\n * Текст кнопки закрытия. Делает ее доступной для ассистивных технологий.\n */\n dismissLabel?: string;\n /**\n * Содержимое, отображаемое в левой части баннера.\n */\n before?: React.ReactNode;\n /**\n * Заголовок.\n */\n title?: React.ReactNode;\n /**\n * Подзаголовок.\n */\n subtitle?: React.ReactNode;\n /**\n * Дополнительный подзаголовок баннера.\n */\n extraSubtitle?: React.ReactNode;\n /**\n * При использовании `mode=\"image\"`.\n *\n * - `light` – в качестве фона используется светлое изображение, цвет текста в баннере будет тёмным.\n * - `dark` – в качестве фона используется тёмное изображение, цвет текста будет светлым.\n */\n imageTheme?: 'light' | 'dark';\n /**\n * При использовании `mode=\"image\"`.\n *\n * Элемент, который нужно стилизовать цветом и/или фоном. Этот элемент будет растянут на 100% ширины и высоты баннера.\n */\n background?: React.ReactNode;\n /**\n * Кнопки-действия. Принимает [`Button`](https://vkcom.github.io/VKUI/#/Button).\n *\n * - В режиме `tint` или `image` со светлым фоном используйте только с параметрами:\n * - `mode=\"primary\"`\n * - `mode=\"secondary\"`\n * - В режиме `image` с тёмным фоном используйте с параметрами:\n * - `appearance=\"overlay\"`.\n *\n * Для набора кнопок используйте [`ButtonGroup`](https://vkcom.github.io/VKUI/#/ButtonGroup) с параметрами:\n *\n * - `gap=\"m\" mode=\"horizontal\" stretched`\n * - `gap=\"m\" mode=\"vertical\" stretched`.\n */\n actions?: React.ReactNode;\n}\n\n/**\n * @see https://vkcom.github.io/VKUI/#/Banner\n */\nexport const Banner = ({\n mode = 'tint',\n imageTheme = 'dark',\n size = 's',\n before,\n after: afterProp,\n title,\n subtitle,\n extraSubtitle,\n children,\n background,\n actions,\n onDismiss,\n dismissLabel = 'Скрыть',\n Component,\n ...restProps\n}: BannerProps): React.ReactNode => {\n const platform = usePlatform();\n\n const HeaderTypography = size === 'm' ? Title : Headline;\n const SubheadTypography = size === 'm' ? Text : Subhead;\n\n const IconDismissIOS = mode === 'image' ? Icon24DismissDark : Icon24Dismiss;\n\n const content = (\n <>\n {mode === 'image' && background && (\n <div aria-hidden className={styles.bg}>\n {background}\n </div>\n )}\n\n {before && <div className={styles.before}>{before}</div>}\n\n <div className={styles.content}>\n {hasReactNode(title) && (\n <HeaderTypography Component=\"div\" weight=\"2\" level={size === 'm' ? '2' : '1'}>\n {title}\n </HeaderTypography>\n )}\n {hasReactNode(subtitle) && (\n <SubheadTypography Component=\"div\" className={styles.subtitle}>\n {subtitle}\n </SubheadTypography>\n )}\n {hasReactNode(extraSubtitle) && (\n <Text Component=\"div\" className={styles.extraSubtitle}>\n {extraSubtitle}\n </Text>\n )}\n {hasReactNode(actions) && React.Children.count(actions) > 0 && (\n <div className={styles.actions}>{actions}</div>\n )}\n </div>\n </>\n );\n\n const afterMap: Record<string, React.ReactNode> = {\n chevron: <Icon24Chevron className={styles.chevron} />,\n dismiss: (\n <IconButton\n label={dismissLabel}\n className={styles.dismiss}\n onClick={onDismiss}\n hoverMode=\"opacity\"\n hasActive={false}\n >\n {platform === 'ios' ? <IconDismissIOS /> : <Icon24Cancel />}\n </IconButton>\n ),\n };\n\n const after = afterProp && (\n <div className={styles.after}>\n {typeof afterProp === 'string' ? afterMap[afterProp] : afterProp}\n </div>\n );\n\n const isClickable = restProps.onClick || restProps.onClickCapture || restProps.href;\n\n return (\n <Tappable\n Component={Component || (!isClickable ? 'section' : undefined)}\n activeMode={platform === 'ios' ? 'opacity' : 'background'}\n baseClassName={classNames(\n styles.host,\n platform === 'ios' && styles.ios,\n mode === 'image' && styles.modeImage,\n size === 'm' && styles.sizeM,\n mode === 'image' && imageTheme === 'dark' && styles.inverted,\n )}\n {...restProps}\n >\n {content}\n {after}\n </Tappable>\n );\n};\n"],"names":["React","Icon24Cancel","Icon24Chevron","Icon24Dismiss","Icon24DismissDark","classNames","hasReactNode","usePlatform","IconButton","Tappable","Headline","Subhead","Text","Title","styles","Banner","mode","imageTheme","size","before","after","afterProp","title","subtitle","extraSubtitle","children","background","actions","onDismiss","dismissLabel","Component","restProps","platform","HeaderTypography","SubheadTypography","IconDismissIOS","content","div","aria-hidden","className","bg","weight","level","Children","count","afterMap","chevron","dismiss","label","onClick","hoverMode","hasActive","isClickable","onClickCapture","href","undefined","activeMode","baseClassName","host","ios","modeImage","sizeM","inverted"],"mappings":"AAAA;;AAEA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,YAAY,EAAEC,aAAa,EAAEC,aAAa,EAAEC,iBAAiB,QAAQ,mBAAmB;AACjG,SAASC,UAAU,EAAEC,YAAY,QAAQ,kBAAkB;AAC3D,SAASC,WAAW,QAAQ,6BAA0B;AACtD,SAASC,UAAU,QAAQ,8BAA2B;AACtD,SAASC,QAAQ,QAAgC,0BAAuB;AACxE,SAASC,QAAQ,QAAQ,qCAAkC;AAC3D,SAASC,OAAO,QAAQ,mCAAgC;AACxD,SAASC,IAAI,QAAQ,6BAA0B;AAC/C,SAASC,KAAK,QAAQ,+BAA4B;AAClD,OAAOC,YAAY,sBAAsB;AAwEzC;;CAEC,GACD,OAAO,MAAMC,SAAS,CAAC,EACrBC,OAAO,MAAM,EACbC,aAAa,MAAM,EACnBC,OAAO,GAAG,EACVC,MAAM,EACNC,OAAOC,SAAS,EAChBC,KAAK,EACLC,QAAQ,EACRC,aAAa,EACbC,QAAQ,EACRC,UAAU,EACVC,OAAO,EACPC,SAAS,EACTC,eAAe,QAAQ,EACvBC,SAAS,EACT,GAAGC,WACS;IACZ,MAAMC,WAAWzB;IAEjB,MAAM0B,mBAAmBf,SAAS,MAAML,QAAQH;IAChD,MAAMwB,oBAAoBhB,SAAS,MAAMN,OAAOD;IAEhD,MAAMwB,iBAAiBnB,SAAS,UAAUZ,oBAAoBD;IAE9D,MAAMiC,wBACJ;;YACGpB,SAAS,WAAWU,4BACnB,KAACW;gBAAIC,aAAW;gBAACC,WAAWzB,OAAO0B,EAAE;0BAClCd;;YAIJP,wBAAU,KAACkB;gBAAIE,WAAWzB,OAAOK,MAAM;0BAAGA;;0BAE3C,MAACkB;gBAAIE,WAAWzB,OAAOsB,OAAO;;oBAC3B9B,aAAagB,wBACZ,KAACW;wBAAiBH,WAAU;wBAAMW,QAAO;wBAAIC,OAAOxB,SAAS,MAAM,MAAM;kCACtEI;;oBAGJhB,aAAaiB,2BACZ,KAACW;wBAAkBJ,WAAU;wBAAMS,WAAWzB,OAAOS,QAAQ;kCAC1DA;;oBAGJjB,aAAakB,gCACZ,KAACZ;wBAAKkB,WAAU;wBAAMS,WAAWzB,OAAOU,aAAa;kCAClDA;;oBAGJlB,aAAaqB,YAAY3B,MAAM2C,QAAQ,CAACC,KAAK,CAACjB,WAAW,mBACxD,KAACU;wBAAIE,WAAWzB,OAAOa,OAAO;kCAAGA;;;;;;IAMzC,MAAMkB,WAA4C;QAChDC,uBAAS,KAAC5C;YAAcqC,WAAWzB,OAAOgC,OAAO;;QACjDC,uBACE,KAACvC;YACCwC,OAAOnB;YACPU,WAAWzB,OAAOiC,OAAO;YACzBE,SAASrB;YACTsB,WAAU;YACVC,WAAW;sBAEVnB,aAAa,sBAAQ,KAACG,oCAAoB,KAAClC;;IAGlD;IAEA,MAAMmB,QAAQC,2BACZ,KAACgB;QAAIE,WAAWzB,OAAOM,KAAK;kBACzB,OAAOC,cAAc,WAAWwB,QAAQ,CAACxB,UAAU,GAAGA;;IAI3D,MAAM+B,cAAcrB,UAAUkB,OAAO,IAAIlB,UAAUsB,cAAc,IAAItB,UAAUuB,IAAI;IAEnF,qBACE,MAAC7C;QACCqB,WAAWA,aAAc,CAAA,CAACsB,cAAc,YAAYG,SAAQ;QAC5DC,YAAYxB,aAAa,QAAQ,YAAY;QAC7CyB,eAAepD,WACbS,OAAO4C,IAAI,EACX1B,aAAa,SAASlB,OAAO6C,GAAG,EAChC3C,SAAS,WAAWF,OAAO8C,SAAS,EACpC1C,SAAS,OAAOJ,OAAO+C,KAAK,EAC5B7C,SAAS,WAAWC,eAAe,UAAUH,OAAOgD,QAAQ;QAE7D,GAAG/B,SAAS;;YAEZK;YACAhB;;;AAGP,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/Button/Button.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { classNames, hasReactNode } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { usePlatform } from '../../hooks/usePlatform';\nimport type { HasAlign } from '../../types';\nimport { Spinner } from '../Spinner/Spinner';\nimport { Tappable, type TappableProps } from '../Tappable/Tappable';\nimport '../Tappable/Tappable.module.css';\nimport '../Spinner/Spinner.module.css';\nimport styles from './Button.module.css';\n\nconst stylesSize = {\n s: styles.sizeS,\n m: styles.sizeM,\n l: styles.sizeL,\n};\n\nconst stylesMode = {\n primary: styles.modePrimary,\n secondary: styles.modeSecondary,\n tertiary: styles.modeTertiary,\n outline: styles.modeOutline,\n link: styles.modeLink,\n};\n\nconst stylesAppearance = {\n 'accent': styles.appearanceAccent,\n 'positive': styles.appearancePositive,\n 'negative': styles.appearanceNegative,\n 'neutral': styles.appearanceNeutral,\n 'overlay': styles.appearanceOverlay,\n 'accent-invariable': styles.appearanceAccentInvariable,\n};\n\nconst stylesAlign = {\n left: styles.alignLeft,\n right: styles.alignRight,\n};\n\nconst sizeYClassNames = {\n none: styles.sizeYNone,\n regular: styles.sizeYRegular,\n};\n\nexport interface VKUIButtonProps extends HasAlign {\n /**\n * Режим отображения кнопки.\n */\n mode?: 'primary' | 'secondary' | 'tertiary' | 'outline' | 'link';\n /**\n * Цветовая схема кнопки.\n */\n appearance?: 'accent' | 'positive' | 'negative' | 'neutral' | 'overlay' | 'accent-invariable';\n /**\n * Размер кнопки.\n */\n size?: 's' | 'm' | 'l';\n /**\n * Растягивает кнопку на всю ширину контейнера.\n */\n stretched?: boolean;\n /**\n * Контент, отображаемый перед основным содержимым кнопки.\n */\n before?: React.ReactNode;\n /**\n * Контент, отображаемый после основного содержимого кнопки.\n */\n after?: React.ReactNode;\n /**\n * Включает состояние загрузки (отображает спиннер).\n */\n loading?: boolean;\n /**\n * Отключает анимацию спиннера загрузки.\n */\n disableSpinnerAnimation?: boolean;\n /**\n * Добавляет скругленные углы кнопке.\n */\n rounded?: boolean;\n}\n\nexport interface ButtonProps extends Omit<TappableProps, 'size'>, VKUIButtonProps {}\n\n/**\n * @see https://vkcom.github.io/VKUI/#/Button\n */\nexport const Button = ({\n size = 's',\n mode = 'primary',\n appearance = 'accent',\n stretched = false,\n align = 'center',\n children,\n before,\n after,\n getRootRef,\n loading,\n onClick,\n disableSpinnerAnimation,\n rounded,\n disabled,\n ...restProps\n}: ButtonProps): React.ReactNode => {\n const hasIconOnly = !children && Boolean(after) !== Boolean(before);\n const { sizeY = 'none' } = useAdaptivity();\n const platform = usePlatform();\n\n return (\n <Tappable\n hoverMode={styles.hover}\n activeMode={styles.active}\n Component={restProps.href ? 'a' : 'button'}\n focusVisibleMode=\"outside\"\n disabled={loading || disabled}\n {...restProps}\n onClick={loading ? undefined : onClick}\n baseClassName={classNames(\n styles.host,\n stylesSize[size],\n stylesMode[mode],\n stylesAppearance[appearance],\n align !== 'center' && stylesAlign[align],\n sizeY !== 'compact' && sizeYClassNames[sizeY],\n platform === 'ios' && styles.ios,\n stretched && styles.stretched,\n hasIconOnly && !stretched && styles.singleIcon,\n loading && styles.loading,\n rounded && styles.rounded,\n disabled && styles.disabled,\n )}\n getRootRef={getRootRef}\n >\n {loading && (\n <Spinner\n size=\"s\"\n className={styles.spinner}\n disableAnimation={disableSpinnerAnimation}\n noColor\n />\n )}\n <span className={styles.in}>\n {hasReactNode(before) && (\n <span\n className={styles.before}\n role=\"presentation\"\n data-testid={process.env.NODE_ENV === 'test' ? 'before' : undefined}\n >\n {before}\n </span>\n )}\n {hasReactNode(children) && (\n <span\n className={styles.content}\n data-testid={process.env.NODE_ENV === 'test' ? 'children' : undefined}\n >\n {children}\n </span>\n )}\n {hasReactNode(after) && (\n <span\n className={styles.after}\n role=\"presentation\"\n data-testid={process.env.NODE_ENV === 'test' ? 'after' : undefined}\n >\n {after}\n </span>\n )}\n </span>\n </Tappable>\n );\n};\n"],"names":["React","classNames","hasReactNode","useAdaptivity","usePlatform","Spinner","Tappable","styles","stylesSize","s","sizeS","m","sizeM","l","sizeL","stylesMode","primary","modePrimary","secondary","modeSecondary","tertiary","modeTertiary","outline","modeOutline","link","modeLink","stylesAppearance","appearanceAccent","appearancePositive","appearanceNegative","appearanceNeutral","appearanceOverlay","appearanceAccentInvariable","stylesAlign","left","alignLeft","right","alignRight","sizeYClassNames","none","sizeYNone","regular","sizeYRegular","Button","size","mode","appearance","stretched","align","children","before","after","getRootRef","loading","onClick","disableSpinnerAnimation","rounded","disabled","restProps","hasIconOnly","Boolean","sizeY","platform","hoverMode","hover","activeMode","active","Component","href","focusVisibleMode","undefined","baseClassName","host","ios","singleIcon","className","spinner","disableAnimation","noColor","span","in","role","data-testid","process","env","NODE_ENV","content"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/components/Button/Button.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { classNames, hasReactNode } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { usePlatform } from '../../hooks/usePlatform';\nimport type { HasAlign } from '../../types';\nimport { Spinner } from '../Spinner/Spinner';\nimport { Tappable, type TappableOmitProps } from '../Tappable/Tappable';\nimport '../Tappable/Tappable.module.css';\nimport '../Spinner/Spinner.module.css';\nimport styles from './Button.module.css';\n\nconst stylesSize = {\n s: styles.sizeS,\n m: styles.sizeM,\n l: styles.sizeL,\n};\n\nconst stylesMode = {\n primary: styles.modePrimary,\n secondary: styles.modeSecondary,\n tertiary: styles.modeTertiary,\n outline: styles.modeOutline,\n link: styles.modeLink,\n};\n\nconst stylesAppearance = {\n 'accent': styles.appearanceAccent,\n 'positive': styles.appearancePositive,\n 'negative': styles.appearanceNegative,\n 'neutral': styles.appearanceNeutral,\n 'overlay': styles.appearanceOverlay,\n 'accent-invariable': styles.appearanceAccentInvariable,\n};\n\nconst stylesAlign = {\n left: styles.alignLeft,\n right: styles.alignRight,\n};\n\nconst sizeYClassNames = {\n none: styles.sizeYNone,\n regular: styles.sizeYRegular,\n};\n\nexport interface VKUIButtonProps extends HasAlign {\n /**\n * Режим отображения кнопки.\n */\n mode?: 'primary' | 'secondary' | 'tertiary' | 'outline' | 'link';\n /**\n * Цветовая схема кнопки.\n */\n appearance?: 'accent' | 'positive' | 'negative' | 'neutral' | 'overlay' | 'accent-invariable';\n /**\n * Размер кнопки.\n */\n size?: 's' | 'm' | 'l';\n /**\n * Растягивает кнопку на всю ширину контейнера.\n */\n stretched?: boolean;\n /**\n * Контент, отображаемый перед основным содержимым кнопки.\n */\n before?: React.ReactNode;\n /**\n * Контент, отображаемый после основного содержимого кнопки.\n */\n after?: React.ReactNode;\n /**\n * Включает состояние загрузки (отображает спиннер).\n */\n loading?: boolean;\n /**\n * Отключает анимацию спиннера загрузки.\n */\n disableSpinnerAnimation?: boolean;\n /**\n * Добавляет скругленные углы кнопке.\n */\n rounded?: boolean;\n}\n\nexport interface ButtonProps extends Omit<TappableOmitProps, 'size'>, VKUIButtonProps {}\n\n/**\n * @see https://vkcom.github.io/VKUI/#/Button\n */\nexport const Button = ({\n size = 's',\n mode = 'primary',\n appearance = 'accent',\n stretched = false,\n align = 'center',\n children,\n before,\n after,\n getRootRef,\n loading,\n onClick,\n disableSpinnerAnimation,\n rounded,\n disabled,\n ...restProps\n}: ButtonProps): React.ReactNode => {\n const hasIconOnly = !children && Boolean(after) !== Boolean(before);\n const { sizeY = 'none' } = useAdaptivity();\n const platform = usePlatform();\n\n return (\n <Tappable\n hoverMode={styles.hover}\n activeMode={styles.active}\n Component={restProps.href ? 'a' : 'button'}\n focusVisibleMode=\"outside\"\n disabled={loading || disabled}\n {...restProps}\n onClick={loading ? undefined : onClick}\n baseClassName={classNames(\n styles.host,\n stylesSize[size],\n stylesMode[mode],\n stylesAppearance[appearance],\n align !== 'center' && stylesAlign[align],\n sizeY !== 'compact' && sizeYClassNames[sizeY],\n platform === 'ios' && styles.ios,\n stretched && styles.stretched,\n hasIconOnly && !stretched && styles.singleIcon,\n loading && styles.loading,\n rounded && styles.rounded,\n disabled && styles.disabled,\n )}\n getRootRef={getRootRef}\n >\n {loading && (\n <Spinner\n size=\"s\"\n className={styles.spinner}\n disableAnimation={disableSpinnerAnimation}\n noColor\n />\n )}\n <span className={styles.in}>\n {hasReactNode(before) && (\n <span\n className={styles.before}\n role=\"presentation\"\n data-testid={process.env.NODE_ENV === 'test' ? 'before' : undefined}\n >\n {before}\n </span>\n )}\n {hasReactNode(children) && (\n <span\n className={styles.content}\n data-testid={process.env.NODE_ENV === 'test' ? 'children' : undefined}\n >\n {children}\n </span>\n )}\n {hasReactNode(after) && (\n <span\n className={styles.after}\n role=\"presentation\"\n data-testid={process.env.NODE_ENV === 'test' ? 'after' : undefined}\n >\n {after}\n </span>\n )}\n </span>\n </Tappable>\n );\n};\n"],"names":["React","classNames","hasReactNode","useAdaptivity","usePlatform","Spinner","Tappable","styles","stylesSize","s","sizeS","m","sizeM","l","sizeL","stylesMode","primary","modePrimary","secondary","modeSecondary","tertiary","modeTertiary","outline","modeOutline","link","modeLink","stylesAppearance","appearanceAccent","appearancePositive","appearanceNegative","appearanceNeutral","appearanceOverlay","appearanceAccentInvariable","stylesAlign","left","alignLeft","right","alignRight","sizeYClassNames","none","sizeYNone","regular","sizeYRegular","Button","size","mode","appearance","stretched","align","children","before","after","getRootRef","loading","onClick","disableSpinnerAnimation","rounded","disabled","restProps","hasIconOnly","Boolean","sizeY","platform","hoverMode","hover","activeMode","active","Component","href","focusVisibleMode","undefined","baseClassName","host","ios","singleIcon","className","spinner","disableAnimation","noColor","span","in","role","data-testid","process","env","NODE_ENV","content"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
- import { classNames } from "@vkontakte/vkjs";
4
+ import { classNames, isSameDate } from "@vkontakte/vkjs";
5
5
  import { isSameDay, isSameMonth, startOfMonth } from "date-fns";
6
6
  import { useCalendar } from "../../hooks/useCalendar.js";
7
7
  import { useCustomEnsuredControl } from "../../hooks/useEnsuredControl.js";
@@ -35,7 +35,7 @@ const warn = warnOnce('Calendar');
35
35
  timezone,
36
36
  value
37
37
  ]);
38
- const { viewDate, setViewDate, setPrevMonth, setNextMonth, focusedDay, setFocusedDay, focusableDay, setFocusableDay, isDayFocused, isDayDisabled, isMonthDisabled, isYearDisabled } = useCalendar({
38
+ const { viewDate, setViewDate, setPrevMonth, setNextMonth, focusedDay, setFocusedDay, isDayFocused, isDayDisabled, isMonthDisabled, isYearDisabled } = useCalendar({
39
39
  value: timeZonedValue,
40
40
  disableFuture,
41
41
  disablePast,
@@ -46,6 +46,8 @@ const warn = warnOnce('Calendar');
46
46
  minDateTime,
47
47
  maxDateTime
48
48
  });
49
+ // соотвествует дню, на котором можно сфокусироваться с помощью Tab
50
+ const [focusableDay, setFocusableDay] = React.useState();
49
51
  useIsomorphicLayoutEffect(()=>{
50
52
  if (timeZonedValue) {
51
53
  setViewDate(timeZonedValue);
@@ -97,22 +99,22 @@ const warn = warnOnce('Calendar');
97
99
  });
98
100
  }
99
101
  updateValue(actualDate);
100
- setFocusedDay(actualDate);
101
- setFocusableDay(actualDate);
102
102
  }, [
103
103
  timeZonedValue,
104
104
  updateValue,
105
105
  maxDateTime,
106
- minDateTime,
107
- setFocusedDay,
108
- setFocusableDay
106
+ minDateTime
109
107
  ]);
110
108
  const onDayFocus = React.useCallback((date)=>{
111
109
  if (focusedDay && isSameDay(focusedDay, date)) {
112
110
  return;
113
111
  }
114
112
  setFocusedDay(date);
113
+ if (!focusableDay || !isSameDate(date, focusableDay)) {
114
+ setFocusableDay(date);
115
+ }
115
116
  }, [
117
+ focusableDay,
116
118
  focusedDay,
117
119
  setFocusedDay
118
120
  ]);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/Calendar/Calendar.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { classNames } from '@vkontakte/vkjs';\nimport { isSameDay, isSameMonth, startOfMonth } from 'date-fns';\nimport { useCalendar } from '../../hooks/useCalendar';\nimport { useCustomEnsuredControl } from '../../hooks/useEnsuredControl';\nimport { Keys, pressedKey } from '../../lib/accessibility';\nimport {\n clamp,\n isFirstDay,\n isLastDay,\n navigateDate,\n NAVIGATION_KEYS,\n setTimeEqual,\n} from '../../lib/calendar';\nimport { convertDateFromTimeZone, convertDateToTimeZone } from '../../lib/date';\nimport { isHTMLElement } from '../../lib/dom';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport { warnOnce } from '../../lib/warnOnce';\nimport type { HTMLAttributesWithRootRef } from '../../types';\nimport {\n CalendarDays,\n type CalendarDaysProps,\n type CalendarDaysTestsProps,\n} from '../CalendarDays/CalendarDays';\nimport {\n CalendarHeader,\n type CalendarHeaderProps,\n type CalendarHeaderTestsProps,\n} from '../CalendarHeader/CalendarHeader';\nimport {\n type CalendarDoneButtonProps,\n CalendarTime,\n type CalendarTimeProps,\n type CalendarTimeTestsProps,\n} from '../CalendarTime/CalendarTime';\nimport { RootComponent } from '../RootComponent/RootComponent';\nimport styles from './Calendar.module.css';\n\nexport type CalendarTestsProps = CalendarDaysTestsProps &\n CalendarHeaderTestsProps &\n CalendarTimeTestsProps;\n\nexport interface CalendarProps\n extends Omit<HTMLAttributesWithRootRef<HTMLDivElement>, 'onChange' | 'defaultValue'>,\n Pick<CalendarTimeProps, 'changeHoursLabel' | 'changeMinutesLabel'>,\n Pick<\n CalendarHeaderProps,\n | 'prevMonthLabel'\n | 'nextMonthLabel'\n | 'changeMonthLabel'\n | 'changeYearLabel'\n | 'onNextMonth'\n | 'onPrevMonth'\n | 'prevMonthIcon'\n | 'nextMonthIcon'\n | 'prevMonthProps'\n | 'nextMonthProps'\n >,\n Pick<CalendarDaysProps, 'dayProps' | 'listenDayChangesForUpdate' | 'renderDayContent'>,\n CalendarDoneButtonProps,\n CalendarTestsProps {\n /**\n * Текущая выбранная дата.\n */\n value?: Date | null;\n /**\n * Начальная дата при монтировании.\n */\n defaultValue?: Date | null;\n /**\n * Запрещает выбор даты в прошлом.\n * Применяется, если не заданы `shouldDisableDate` и `disableFuture`.\n */\n disablePast?: boolean;\n /**\n * Запрещает выбор даты в будущем.\n * Применяется, если не задано `shouldDisableDate`.\n */\n disableFuture?: boolean;\n /**\n * Включает выбор времени.\n */\n enableTime?: boolean;\n /**\n * Отключает селекторы выбора месяца/года.\n */\n disablePickers?: boolean;\n /**\n * `aria-label` для изменения дня.\n *\n * @deprecated Будет удалeно в **VKUI v8**.\n * Использовалось для задания aria-label для контейнера дней в календаре.\n * Теперь этот контейнер является таблицей (с помощью role=\"grid\") и\n * в aria-label рендерится текущий открытый в календаре месяц и год.\n */\n changeDayLabel?: string;\n /**\n * День недели, с которого начинается неделя.\n */\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n /**\n * Показывать дни соседних месяцев.\n */\n showNeighboringMonth?: boolean;\n /**\n * Размер календаря.\n */\n size?: 's' | 'm';\n /**\n * Обработчик изменения выбранной даты.\n */\n onChange?: (value?: Date) => void; // TODO [>=8]: поменять тип на `(value?: Date | null) => void`\n /**\n * Функция для проверки запрета выбора даты.\n */\n shouldDisableDate?: (value: Date) => boolean;\n /**\n * Дата отображаемого месяца.\n * При использовании обновление даты должно происходить вне компонента.\n */\n viewDate?: Date;\n /**\n * Обработчик изменения даты в шапке календаря.\n */\n onHeaderChange?: (value: Date) => void;\n /**\n * Минимальные дата и время, которые можно выбрать.\n * Применяется, если не заданы `shouldDisableDate` и `disablePast`/`disableFuture`.\n */\n minDateTime?: Date;\n /**\n * Максимальные дата и время, которые можно выбрать.\n * Применяется, если не заданы `shouldDisableDate` и `disablePast`/`disableFuture`.\n */\n maxDateTime?: Date;\n /**\n * Часовой пояс для отображения даты.\n */\n timezone?: string;\n}\n\nconst warn = warnOnce('Calendar');\n\n/**\n * @see https://vkcom.github.io/VKUI/#/Calendar\n */\nexport const Calendar = ({\n getRootRef,\n 'value': valueProp,\n defaultValue,\n onChange,\n disablePast,\n disableFuture,\n shouldDisableDate,\n onDoneButtonClick,\n enableTime = false,\n doneButtonText,\n doneButtonDisabled,\n doneButtonShow,\n DoneButton,\n weekStartsOn = 1,\n disablePickers,\n 'aria-label': ariaLabel = 'Календарь',\n changeHoursLabel = 'Изменить час',\n changeMinutesLabel = 'Изменить минуту',\n prevMonthLabel = 'Предыдущий месяц',\n nextMonthLabel = 'Следующий месяц',\n changeMonthLabel = 'Изменить месяц',\n changeYearLabel = 'Изменить год',\n showNeighboringMonth,\n size = 'm',\n 'viewDate': externalViewDate,\n onHeaderChange,\n onNextMonth,\n onPrevMonth,\n prevMonthIcon,\n nextMonthIcon,\n prevMonthProps,\n nextMonthProps,\n dayProps,\n listenDayChangesForUpdate,\n renderDayContent,\n minDateTime,\n maxDateTime,\n timezone,\n minutesTestId,\n hoursTestId,\n doneButtonTestId,\n prevMonthButtonTestId,\n nextMonthButtonTestId,\n monthDropdownTestId,\n yearDropdownTestId,\n dayTestId,\n ...props\n}: CalendarProps): React.ReactNode => {\n const _onChange = React.useCallback(\n (date: Date | null | undefined) => {\n onChange?.(convertDateFromTimeZone(date, timezone) || undefined);\n },\n [onChange, timezone],\n );\n\n const [value, updateValue] = useCustomEnsuredControl<Date | null | undefined>({\n value: valueProp,\n defaultValue,\n onChange: _onChange,\n });\n\n const timeZonedValue: Date | null | undefined = React.useMemo(\n () => convertDateToTimeZone(value, timezone),\n [timezone, value],\n );\n\n const {\n viewDate,\n setViewDate,\n setPrevMonth,\n setNextMonth,\n focusedDay,\n setFocusedDay,\n focusableDay,\n setFocusableDay,\n isDayFocused,\n isDayDisabled,\n isMonthDisabled,\n isYearDisabled,\n } = useCalendar({\n value: timeZonedValue,\n disableFuture,\n disablePast,\n shouldDisableDate,\n onHeaderChange,\n onNextMonth,\n onPrevMonth,\n minDateTime,\n maxDateTime,\n });\n\n useIsomorphicLayoutEffect(() => {\n if (timeZonedValue) {\n setViewDate(timeZonedValue);\n }\n }, [timeZonedValue]);\n\n if (process.env.NODE_ENV === 'development' && !disablePickers && size === 's') {\n warn(\"Нельзя включить селекты выбора месяца/года, если размер календаря 's'\", 'error');\n }\n\n if (process.env.NODE_ENV === 'development' && enableTime && size === 's') {\n warn(\"Нельзя включить выбор времени, если размер календаря 's'\", 'error');\n }\n\n const handleKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n const key = pressedKey(event);\n if (key && NAVIGATION_KEYS.includes(key)) {\n event.preventDefault();\n\n const newFocusedDay = navigateDate(focusedDay ?? timeZonedValue, key);\n\n if (newFocusedDay && !isSameMonth(newFocusedDay, viewDate)) {\n setViewDate(newFocusedDay);\n }\n setFocusedDay(newFocusedDay);\n setFocusableDay(newFocusedDay);\n\n return;\n }\n\n if (key === Keys.TAB) {\n setFocusedDay(undefined);\n setFocusableDay(focusedDay);\n\n return;\n }\n\n if ((key === Keys.ENTER || key === Keys.SPACE) && isHTMLElement(event.target)) {\n event.preventDefault();\n event.target.click?.();\n }\n },\n [focusedDay, setFocusedDay, setFocusableDay, setViewDate, timeZonedValue, viewDate],\n );\n\n const onDayChange = React.useCallback(\n (date: Date) => {\n let actualDate = setTimeEqual(date, timeZonedValue);\n if (minDateTime || maxDateTime) {\n actualDate = clamp(actualDate, { min: minDateTime, max: maxDateTime });\n }\n updateValue(actualDate);\n setFocusedDay(actualDate);\n setFocusableDay(actualDate);\n },\n [timeZonedValue, updateValue, maxDateTime, minDateTime, setFocusedDay, setFocusableDay],\n );\n\n const onDayFocus = React.useCallback(\n (date: Date) => {\n if (focusedDay && isSameDay(focusedDay, date)) {\n return;\n }\n\n setFocusedDay(date);\n },\n [focusedDay, setFocusedDay],\n );\n\n // activeDay это день в календаре соответствующий значению в инпуте\n const isDayActive = React.useCallback(\n (day: Date) => Boolean(timeZonedValue && isSameDay(day, timeZonedValue)),\n [timeZonedValue],\n );\n\n const isFocusableDayInViewDateMonth = focusableDay && isSameMonth(focusableDay, viewDate);\n const isInputValueDateInViewDateMonth = timeZonedValue && isSameMonth(timeZonedValue, viewDate);\n /**\n * Функция позволяет проверить является ли день в календаре днём на который\n * можно попасть с помощью Tab.\n * Единственный день в таблице календаря у которого есть tabIndex=\"0\"\n * Чтобы на него можно было попасть из заголовка календаря.\n */\n const isDayFocusable = React.useCallback(\n (day: Date) => {\n // если focusableDay день находится среди дней открытого сейчас месяца, то такой день получит tabIndex=\"0\",\n if (isFocusableDayInViewDateMonth) {\n return isSameDay(focusableDay, day);\n }\n\n // при открытии календаря focusableDay не определён,\n // поэтому tabIndex=\"0\" будет у дня, соответствующего дню в инпуте\n if (isInputValueDateInViewDateMonth) {\n return isDayActive(day);\n }\n\n // при переключении месяца любая навигация с помощью Tab начинается\n // с первого дня месяца.\n return isSameDay(startOfMonth(viewDate), day);\n },\n [\n focusableDay,\n viewDate,\n isDayActive,\n isFocusableDayInViewDateMonth,\n isInputValueDateInViewDateMonth,\n ],\n );\n\n return (\n <RootComponent\n aria-label={ariaLabel}\n {...props}\n baseClassName={classNames(styles.host, size === 's' && styles.sizeS)}\n getRootRef={getRootRef}\n >\n <CalendarHeader\n viewDate={externalViewDate || viewDate}\n onChange={setViewDate}\n onNextMonth={setNextMonth}\n onPrevMonth={setPrevMonth}\n disablePickers={disablePickers || size === 's'}\n className={styles.header}\n prevMonthLabel={prevMonthLabel}\n nextMonthLabel={nextMonthLabel}\n changeMonthLabel={changeMonthLabel}\n changeYearLabel={changeYearLabel}\n prevMonthIcon={prevMonthIcon}\n nextMonthIcon={nextMonthIcon}\n prevMonthProps={prevMonthProps}\n nextMonthProps={nextMonthProps}\n isMonthDisabled={isMonthDisabled}\n isYearDisabled={isYearDisabled}\n nextMonthButtonTestId={nextMonthButtonTestId}\n prevMonthButtonTestId={prevMonthButtonTestId}\n monthDropdownTestId={monthDropdownTestId}\n yearDropdownTestId={yearDropdownTestId}\n />\n <CalendarDays\n viewDate={externalViewDate || viewDate}\n value={timeZonedValue}\n weekStartsOn={weekStartsOn}\n onKeyDown={handleKeyDown}\n onDayChange={onDayChange}\n isDayActive={isDayActive}\n onDayFocus={onDayFocus}\n isDayFocused={isDayFocused}\n isDayFocusable={isDayFocusable}\n isDaySelectionStart={isFirstDay}\n isDaySelectionEnd={isLastDay}\n isDayDisabled={isDayDisabled}\n showNeighboringMonth={showNeighboringMonth}\n size={size}\n dayProps={dayProps}\n listenDayChangesForUpdate={listenDayChangesForUpdate}\n renderDayContent={renderDayContent}\n dayTestId={dayTestId}\n />\n {enableTime && timeZonedValue && size !== 's' && (\n <div className={styles.time}>\n <CalendarTime\n value={timeZonedValue}\n onChange={updateValue}\n onDoneButtonClick={onDoneButtonClick}\n doneButtonText={doneButtonText}\n doneButtonDisabled={doneButtonDisabled}\n doneButtonShow={doneButtonShow}\n DoneButton={DoneButton}\n changeHoursLabel={changeHoursLabel}\n changeMinutesLabel={changeMinutesLabel}\n isDayDisabled={minDateTime || maxDateTime ? isDayDisabled : undefined}\n minutesTestId={minutesTestId}\n hoursTestId={hoursTestId}\n doneButtonTestId={doneButtonTestId}\n />\n </div>\n )}\n </RootComponent>\n );\n};\n"],"names":["React","classNames","isSameDay","isSameMonth","startOfMonth","useCalendar","useCustomEnsuredControl","Keys","pressedKey","clamp","isFirstDay","isLastDay","navigateDate","NAVIGATION_KEYS","setTimeEqual","convertDateFromTimeZone","convertDateToTimeZone","isHTMLElement","useIsomorphicLayoutEffect","warnOnce","CalendarDays","CalendarHeader","CalendarTime","RootComponent","styles","warn","Calendar","getRootRef","valueProp","defaultValue","onChange","disablePast","disableFuture","shouldDisableDate","onDoneButtonClick","enableTime","doneButtonText","doneButtonDisabled","doneButtonShow","DoneButton","weekStartsOn","disablePickers","ariaLabel","changeHoursLabel","changeMinutesLabel","prevMonthLabel","nextMonthLabel","changeMonthLabel","changeYearLabel","showNeighboringMonth","size","externalViewDate","onHeaderChange","onNextMonth","onPrevMonth","prevMonthIcon","nextMonthIcon","prevMonthProps","nextMonthProps","dayProps","listenDayChangesForUpdate","renderDayContent","minDateTime","maxDateTime","timezone","minutesTestId","hoursTestId","doneButtonTestId","prevMonthButtonTestId","nextMonthButtonTestId","monthDropdownTestId","yearDropdownTestId","dayTestId","props","_onChange","useCallback","date","undefined","value","updateValue","timeZonedValue","useMemo","viewDate","setViewDate","setPrevMonth","setNextMonth","focusedDay","setFocusedDay","focusableDay","setFocusableDay","isDayFocused","isDayDisabled","isMonthDisabled","isYearDisabled","process","env","NODE_ENV","handleKeyDown","event","key","includes","preventDefault","newFocusedDay","TAB","ENTER","SPACE","target","click","onDayChange","actualDate","min","max","onDayFocus","isDayActive","day","Boolean","isFocusableDayInViewDateMonth","isInputValueDateInViewDateMonth","isDayFocusable","aria-label","baseClassName","host","sizeS","className","header","onKeyDown","isDaySelectionStart","isDaySelectionEnd","div","time"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/components/Calendar/Calendar.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { classNames, isSameDate } from '@vkontakte/vkjs';\nimport { isSameDay, isSameMonth, startOfMonth } from 'date-fns';\nimport { useCalendar } from '../../hooks/useCalendar';\nimport { useCustomEnsuredControl } from '../../hooks/useEnsuredControl';\nimport { Keys, pressedKey } from '../../lib/accessibility';\nimport {\n clamp,\n isFirstDay,\n isLastDay,\n navigateDate,\n NAVIGATION_KEYS,\n setTimeEqual,\n} from '../../lib/calendar';\nimport { convertDateFromTimeZone, convertDateToTimeZone } from '../../lib/date';\nimport { isHTMLElement } from '../../lib/dom';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport { warnOnce } from '../../lib/warnOnce';\nimport type { HTMLAttributesWithRootRef } from '../../types';\nimport {\n CalendarDays,\n type CalendarDaysProps,\n type CalendarDaysTestsProps,\n} from '../CalendarDays/CalendarDays';\nimport {\n CalendarHeader,\n type CalendarHeaderProps,\n type CalendarHeaderTestsProps,\n} from '../CalendarHeader/CalendarHeader';\nimport {\n type CalendarDoneButtonProps,\n CalendarTime,\n type CalendarTimeProps,\n type CalendarTimeTestsProps,\n} from '../CalendarTime/CalendarTime';\nimport { RootComponent } from '../RootComponent/RootComponent';\nimport styles from './Calendar.module.css';\n\nexport type CalendarTestsProps = CalendarDaysTestsProps &\n CalendarHeaderTestsProps &\n CalendarTimeTestsProps;\n\nexport interface CalendarProps\n extends Omit<HTMLAttributesWithRootRef<HTMLDivElement>, 'onChange' | 'defaultValue'>,\n Pick<CalendarTimeProps, 'changeHoursLabel' | 'changeMinutesLabel'>,\n Pick<\n CalendarHeaderProps,\n | 'prevMonthLabel'\n | 'nextMonthLabel'\n | 'changeMonthLabel'\n | 'changeYearLabel'\n | 'onNextMonth'\n | 'onPrevMonth'\n | 'prevMonthIcon'\n | 'nextMonthIcon'\n | 'prevMonthProps'\n | 'nextMonthProps'\n >,\n Pick<CalendarDaysProps, 'dayProps' | 'listenDayChangesForUpdate' | 'renderDayContent'>,\n CalendarDoneButtonProps,\n CalendarTestsProps {\n /**\n * Текущая выбранная дата.\n */\n value?: Date | null;\n /**\n * Начальная дата при монтировании.\n */\n defaultValue?: Date | null;\n /**\n * Запрещает выбор даты в прошлом.\n * Применяется, если не заданы `shouldDisableDate` и `disableFuture`.\n */\n disablePast?: boolean;\n /**\n * Запрещает выбор даты в будущем.\n * Применяется, если не задано `shouldDisableDate`.\n */\n disableFuture?: boolean;\n /**\n * Включает выбор времени.\n */\n enableTime?: boolean;\n /**\n * Отключает селекторы выбора месяца/года.\n */\n disablePickers?: boolean;\n /**\n * `aria-label` для изменения дня.\n *\n * @deprecated Будет удалeно в **VKUI v8**.\n * Использовалось для задания aria-label для контейнера дней в календаре.\n * Теперь этот контейнер является таблицей (с помощью role=\"grid\") и\n * в aria-label рендерится текущий открытый в календаре месяц и год.\n */\n changeDayLabel?: string;\n /**\n * День недели, с которого начинается неделя.\n */\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n /**\n * Показывать дни соседних месяцев.\n */\n showNeighboringMonth?: boolean;\n /**\n * Размер календаря.\n */\n size?: 's' | 'm';\n /**\n * Обработчик изменения выбранной даты.\n */\n onChange?: (value?: Date) => void; // TODO [>=8]: поменять тип на `(value?: Date | null) => void`\n /**\n * Функция для проверки запрета выбора даты.\n */\n shouldDisableDate?: (value: Date) => boolean;\n /**\n * Дата отображаемого месяца.\n * При использовании обновление даты должно происходить вне компонента.\n */\n viewDate?: Date;\n /**\n * Обработчик изменения даты в шапке календаря.\n */\n onHeaderChange?: (value: Date) => void;\n /**\n * Минимальные дата и время, которые можно выбрать.\n * Применяется, если не заданы `shouldDisableDate` и `disablePast`/`disableFuture`.\n */\n minDateTime?: Date;\n /**\n * Максимальные дата и время, которые можно выбрать.\n * Применяется, если не заданы `shouldDisableDate` и `disablePast`/`disableFuture`.\n */\n maxDateTime?: Date;\n /**\n * Часовой пояс для отображения даты.\n */\n timezone?: string;\n}\n\nconst warn = warnOnce('Calendar');\n\n/**\n * @see https://vkcom.github.io/VKUI/#/Calendar\n */\nexport const Calendar = ({\n getRootRef,\n 'value': valueProp,\n defaultValue,\n onChange,\n disablePast,\n disableFuture,\n shouldDisableDate,\n onDoneButtonClick,\n enableTime = false,\n doneButtonText,\n doneButtonDisabled,\n doneButtonShow,\n DoneButton,\n weekStartsOn = 1,\n disablePickers,\n 'aria-label': ariaLabel = 'Календарь',\n changeHoursLabel = 'Изменить час',\n changeMinutesLabel = 'Изменить минуту',\n prevMonthLabel = 'Предыдущий месяц',\n nextMonthLabel = 'Следующий месяц',\n changeMonthLabel = 'Изменить месяц',\n changeYearLabel = 'Изменить год',\n showNeighboringMonth,\n size = 'm',\n 'viewDate': externalViewDate,\n onHeaderChange,\n onNextMonth,\n onPrevMonth,\n prevMonthIcon,\n nextMonthIcon,\n prevMonthProps,\n nextMonthProps,\n dayProps,\n listenDayChangesForUpdate,\n renderDayContent,\n minDateTime,\n maxDateTime,\n timezone,\n minutesTestId,\n hoursTestId,\n doneButtonTestId,\n prevMonthButtonTestId,\n nextMonthButtonTestId,\n monthDropdownTestId,\n yearDropdownTestId,\n dayTestId,\n ...props\n}: CalendarProps): React.ReactNode => {\n const _onChange = React.useCallback(\n (date: Date | null | undefined) => {\n onChange?.(convertDateFromTimeZone(date, timezone) || undefined);\n },\n [onChange, timezone],\n );\n\n const [value, updateValue] = useCustomEnsuredControl<Date | null | undefined>({\n value: valueProp,\n defaultValue,\n onChange: _onChange,\n });\n\n const timeZonedValue: Date | null | undefined = React.useMemo(\n () => convertDateToTimeZone(value, timezone),\n [timezone, value],\n );\n\n const {\n viewDate,\n setViewDate,\n setPrevMonth,\n setNextMonth,\n focusedDay,\n setFocusedDay,\n isDayFocused,\n isDayDisabled,\n isMonthDisabled,\n isYearDisabled,\n } = useCalendar({\n value: timeZonedValue,\n disableFuture,\n disablePast,\n shouldDisableDate,\n onHeaderChange,\n onNextMonth,\n onPrevMonth,\n minDateTime,\n maxDateTime,\n });\n // соотвествует дню, на котором можно сфокусироваться с помощью Tab\n const [focusableDay, setFocusableDay] = React.useState<Date>();\n\n useIsomorphicLayoutEffect(() => {\n if (timeZonedValue) {\n setViewDate(timeZonedValue);\n }\n }, [timeZonedValue]);\n\n if (process.env.NODE_ENV === 'development' && !disablePickers && size === 's') {\n warn(\"Нельзя включить селекты выбора месяца/года, если размер календаря 's'\", 'error');\n }\n\n if (process.env.NODE_ENV === 'development' && enableTime && size === 's') {\n warn(\"Нельзя включить выбор времени, если размер календаря 's'\", 'error');\n }\n\n const handleKeyDown = React.useCallback(\n (event: React.KeyboardEvent) => {\n const key = pressedKey(event);\n if (key && NAVIGATION_KEYS.includes(key)) {\n event.preventDefault();\n\n const newFocusedDay = navigateDate(focusedDay ?? timeZonedValue, key);\n\n if (newFocusedDay && !isSameMonth(newFocusedDay, viewDate)) {\n setViewDate(newFocusedDay);\n }\n setFocusedDay(newFocusedDay);\n setFocusableDay(newFocusedDay);\n\n return;\n }\n\n if (key === Keys.TAB) {\n setFocusedDay(undefined);\n setFocusableDay(focusedDay);\n\n return;\n }\n\n if ((key === Keys.ENTER || key === Keys.SPACE) && isHTMLElement(event.target)) {\n event.preventDefault();\n event.target.click?.();\n }\n },\n [focusedDay, setFocusedDay, setFocusableDay, setViewDate, timeZonedValue, viewDate],\n );\n\n const onDayChange = React.useCallback(\n (date: Date) => {\n let actualDate = setTimeEqual(date, timeZonedValue);\n if (minDateTime || maxDateTime) {\n actualDate = clamp(actualDate, { min: minDateTime, max: maxDateTime });\n }\n updateValue(actualDate);\n },\n [timeZonedValue, updateValue, maxDateTime, minDateTime],\n );\n\n const onDayFocus = React.useCallback(\n (date: Date) => {\n if (focusedDay && isSameDay(focusedDay, date)) {\n return;\n }\n\n setFocusedDay(date);\n if (!focusableDay || !isSameDate(date, focusableDay)) {\n setFocusableDay(date);\n }\n },\n [focusableDay, focusedDay, setFocusedDay],\n );\n\n // activeDay это день в календаре соответствующий значению в инпуте\n const isDayActive = React.useCallback(\n (day: Date) => Boolean(timeZonedValue && isSameDay(day, timeZonedValue)),\n [timeZonedValue],\n );\n\n const isFocusableDayInViewDateMonth = focusableDay && isSameMonth(focusableDay, viewDate);\n const isInputValueDateInViewDateMonth = timeZonedValue && isSameMonth(timeZonedValue, viewDate);\n /**\n * Функция позволяет проверить является ли день в календаре днём на который\n * можно попасть с помощью Tab.\n * Единственный день в таблице календаря у которого есть tabIndex=\"0\"\n * Чтобы на него можно было попасть из заголовка календаря.\n */\n const isDayFocusable = React.useCallback(\n (day: Date) => {\n // если focusableDay день находится среди дней открытого сейчас месяца, то такой день получит tabIndex=\"0\",\n if (isFocusableDayInViewDateMonth) {\n return isSameDay(focusableDay, day);\n }\n\n // при открытии календаря focusableDay не определён,\n // поэтому tabIndex=\"0\" будет у дня, соответствующего дню в инпуте\n if (isInputValueDateInViewDateMonth) {\n return isDayActive(day);\n }\n\n // при переключении месяца любая навигация с помощью Tab начинается\n // с первого дня месяца.\n return isSameDay(startOfMonth(viewDate), day);\n },\n [\n focusableDay,\n viewDate,\n isDayActive,\n isFocusableDayInViewDateMonth,\n isInputValueDateInViewDateMonth,\n ],\n );\n\n return (\n <RootComponent\n aria-label={ariaLabel}\n {...props}\n baseClassName={classNames(styles.host, size === 's' && styles.sizeS)}\n getRootRef={getRootRef}\n >\n <CalendarHeader\n viewDate={externalViewDate || viewDate}\n onChange={setViewDate}\n onNextMonth={setNextMonth}\n onPrevMonth={setPrevMonth}\n disablePickers={disablePickers || size === 's'}\n className={styles.header}\n prevMonthLabel={prevMonthLabel}\n nextMonthLabel={nextMonthLabel}\n changeMonthLabel={changeMonthLabel}\n changeYearLabel={changeYearLabel}\n prevMonthIcon={prevMonthIcon}\n nextMonthIcon={nextMonthIcon}\n prevMonthProps={prevMonthProps}\n nextMonthProps={nextMonthProps}\n isMonthDisabled={isMonthDisabled}\n isYearDisabled={isYearDisabled}\n nextMonthButtonTestId={nextMonthButtonTestId}\n prevMonthButtonTestId={prevMonthButtonTestId}\n monthDropdownTestId={monthDropdownTestId}\n yearDropdownTestId={yearDropdownTestId}\n />\n <CalendarDays\n viewDate={externalViewDate || viewDate}\n value={timeZonedValue}\n weekStartsOn={weekStartsOn}\n onKeyDown={handleKeyDown}\n onDayChange={onDayChange}\n isDayActive={isDayActive}\n onDayFocus={onDayFocus}\n isDayFocused={isDayFocused}\n isDayFocusable={isDayFocusable}\n isDaySelectionStart={isFirstDay}\n isDaySelectionEnd={isLastDay}\n isDayDisabled={isDayDisabled}\n showNeighboringMonth={showNeighboringMonth}\n size={size}\n dayProps={dayProps}\n listenDayChangesForUpdate={listenDayChangesForUpdate}\n renderDayContent={renderDayContent}\n dayTestId={dayTestId}\n />\n {enableTime && timeZonedValue && size !== 's' && (\n <div className={styles.time}>\n <CalendarTime\n value={timeZonedValue}\n onChange={updateValue}\n onDoneButtonClick={onDoneButtonClick}\n doneButtonText={doneButtonText}\n doneButtonDisabled={doneButtonDisabled}\n doneButtonShow={doneButtonShow}\n DoneButton={DoneButton}\n changeHoursLabel={changeHoursLabel}\n changeMinutesLabel={changeMinutesLabel}\n isDayDisabled={minDateTime || maxDateTime ? isDayDisabled : undefined}\n minutesTestId={minutesTestId}\n hoursTestId={hoursTestId}\n doneButtonTestId={doneButtonTestId}\n />\n </div>\n )}\n </RootComponent>\n );\n};\n"],"names":["React","classNames","isSameDate","isSameDay","isSameMonth","startOfMonth","useCalendar","useCustomEnsuredControl","Keys","pressedKey","clamp","isFirstDay","isLastDay","navigateDate","NAVIGATION_KEYS","setTimeEqual","convertDateFromTimeZone","convertDateToTimeZone","isHTMLElement","useIsomorphicLayoutEffect","warnOnce","CalendarDays","CalendarHeader","CalendarTime","RootComponent","styles","warn","Calendar","getRootRef","valueProp","defaultValue","onChange","disablePast","disableFuture","shouldDisableDate","onDoneButtonClick","enableTime","doneButtonText","doneButtonDisabled","doneButtonShow","DoneButton","weekStartsOn","disablePickers","ariaLabel","changeHoursLabel","changeMinutesLabel","prevMonthLabel","nextMonthLabel","changeMonthLabel","changeYearLabel","showNeighboringMonth","size","externalViewDate","onHeaderChange","onNextMonth","onPrevMonth","prevMonthIcon","nextMonthIcon","prevMonthProps","nextMonthProps","dayProps","listenDayChangesForUpdate","renderDayContent","minDateTime","maxDateTime","timezone","minutesTestId","hoursTestId","doneButtonTestId","prevMonthButtonTestId","nextMonthButtonTestId","monthDropdownTestId","yearDropdownTestId","dayTestId","props","_onChange","useCallback","date","undefined","value","updateValue","timeZonedValue","useMemo","viewDate","setViewDate","setPrevMonth","setNextMonth","focusedDay","setFocusedDay","isDayFocused","isDayDisabled","isMonthDisabled","isYearDisabled","focusableDay","setFocusableDay","useState","process","env","NODE_ENV","handleKeyDown","event","key","includes","preventDefault","newFocusedDay","TAB","ENTER","SPACE","target","click","onDayChange","actualDate","min","max","onDayFocus","isDayActive","day","Boolean","isFocusableDayInViewDateMonth","isInputValueDateInViewDateMonth","isDayFocusable","aria-label","baseClassName","host","sizeS","className","header","onKeyDown","isDaySelectionStart","isDaySelectionEnd","div","time"],"mappings":"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"}
@@ -1,15 +1,14 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
- import { addMonths, endOfDay, isAfter, isBefore, isSameDay, isSameMonth, isWithinInterval, startOfDay, subMonths } from "date-fns";
4
+ import { addMonths, endOfDay, isAfter, isBefore, isSameDay, isWithinInterval, startOfDay, subMonths } from "date-fns";
5
5
  import { useCalendar } from "../../hooks/useCalendar.js";
6
6
  import { useCustomEnsuredControl } from "../../hooks/useEnsuredControl.js";
7
- import { Keys, pressedKey } from "../../lib/accessibility.js";
8
- import { isFirstDay, isLastDay, navigateDate, NAVIGATION_KEYS } from "../../lib/calendar.js";
9
- import { isHTMLElement } from "../../lib/dom.js";
7
+ import { isFirstDay, isLastDay } from "../../lib/calendar.js";
10
8
  import { CalendarDays } from "../CalendarDays/CalendarDays.js";
11
9
  import { CalendarHeader } from "../CalendarHeader/CalendarHeader.js";
12
10
  import { RootComponent } from "../RootComponent/RootComponent.js";
11
+ import { useCalendarKeyboardNavigation, useIsDayFocusable } from "./utils.js";
13
12
  import styles from "./CalendarRange.module.css";
14
13
  const getIsDaySelected = (day, value)=>{
15
14
  if (!value?.[0] || !value[1]) {
@@ -22,7 +21,7 @@ const getIsDaySelected = (day, value)=>{
22
21
  };
23
22
  /**
24
23
  * @see https://vkcom.github.io/VKUI/#/CalendarRange
25
- */ export const CalendarRange = ({ value: valueProp, defaultValue, onChange, disablePast, disableFuture, shouldDisableDate, weekStartsOn = 1, disablePickers, prevMonthLabel = 'Предыдущий месяц', nextMonthLabel = 'Следующий месяц', changeMonthLabel = 'Изменить месяц', changeYearLabel = 'Изменить год', changeDayLabel = 'Изменить день', prevMonthIcon, nextMonthIcon, listenDayChangesForUpdate, renderDayContent, dayTestId, leftPartHeaderTestsData, rightPartHeaderTestsData, getRootRef, ...props })=>{
24
+ */ export const CalendarRange = ({ 'value': valueProp, defaultValue, onChange, disablePast, disableFuture, shouldDisableDate, weekStartsOn = 1, disablePickers, prevMonthLabel = 'Предыдущий месяц', nextMonthLabel = 'Следующий месяц', changeMonthLabel = 'Изменить месяц', changeYearLabel = 'Изменить год', 'aria-label': ariaLabel = 'Календарь', prevMonthIcon, nextMonthIcon, listenDayChangesForUpdate, renderDayContent, dayTestId, leftPartHeaderTestsData, rightPartHeaderTestsData, getRootRef, ...props })=>{
26
25
  const _onChange = React.useCallback((newValue)=>onChange?.(newValue || undefined), [
27
26
  onChange
28
27
  ]);
@@ -31,7 +30,7 @@ const getIsDaySelected = (day, value)=>{
31
30
  defaultValue,
32
31
  onChange: _onChange
33
32
  });
34
- const { viewDate, setViewDate, setPrevMonth, setNextMonth, focusedDay, setFocusedDay, isDayFocused, isDayDisabled, resetSelectedDay, isMonthDisabled, isYearDisabled } = useCalendar({
33
+ const { viewDate, setViewDate, setPrevMonth, setNextMonth, focusedDay, setFocusedDay, isDayFocused, isDayDisabled, isMonthDisabled, isYearDisabled } = useCalendar({
35
34
  value,
36
35
  disableFuture,
37
36
  disablePast,
@@ -39,28 +38,16 @@ const getIsDaySelected = (day, value)=>{
39
38
  });
40
39
  const [hintedDate, setHintedDate] = React.useState();
41
40
  const secondViewDate = addMonths(viewDate, 1);
42
- const handleKeyDown = React.useCallback((event)=>{
43
- const key = pressedKey(event);
44
- if (key && NAVIGATION_KEYS.includes(key)) {
45
- event.preventDefault();
46
- const newFocusedDay = navigateDate(focusedDay ?? value?.[1], key);
47
- if (newFocusedDay && !isSameMonth(newFocusedDay, viewDate) && !isSameMonth(newFocusedDay, addMonths(viewDate, 1))) {
48
- setViewDate(newFocusedDay);
49
- }
50
- setFocusedDay(newFocusedDay);
51
- return;
52
- }
53
- if ((key === Keys.ENTER || key === Keys.SPACE) && isHTMLElement(event.target)) {
54
- event.preventDefault();
55
- event.target.click?.();
56
- }
57
- }, [
41
+ const { focusableDayOnFirstCalendar, focusableDayOnSecondCalendar, handleFirstCalendarKeyDown, handleSecondCalendarKeyDown, handleDayFocus } = useCalendarKeyboardNavigation({
58
42
  focusedDay,
59
43
  setFocusedDay,
60
- setViewDate,
61
44
  value,
62
- viewDate
63
- ]);
45
+ viewDates: [
46
+ viewDate,
47
+ secondViewDate
48
+ ],
49
+ setViewDate
50
+ });
64
51
  const getNewValue = React.useCallback((date)=>{
65
52
  const isValueEmpty = !value || value[0] === null && value[1] === null;
66
53
  const isRangeSelected = value && !!value[0] && !!value[1];
@@ -129,7 +116,33 @@ const getIsDaySelected = (day, value)=>{
129
116
  const onRightPartViewDateChange = React.useCallback((newDate)=>setViewDate(subMonths(newDate, 1)), [
130
117
  setViewDate
131
118
  ]);
119
+ const isDayFocusableInFirstCalendar = useIsDayFocusable({
120
+ value,
121
+ focusableDayOnFirstCalendar,
122
+ focusableDayOnSecondCalendar,
123
+ viewDate,
124
+ isDayActive
125
+ });
126
+ const isDayFocusableInSecondCalendar = useIsDayFocusable({
127
+ value,
128
+ focusableDayOnFirstCalendar,
129
+ focusableDayOnSecondCalendar,
130
+ viewDate: secondViewDate,
131
+ isDayActive
132
+ });
133
+ const onDayFocus = React.useCallback((date)=>{
134
+ if (focusedDay && isSameDay(focusedDay, date)) {
135
+ return;
136
+ }
137
+ setFocusedDay(date);
138
+ handleDayFocus(date);
139
+ }, [
140
+ focusedDay,
141
+ handleDayFocus,
142
+ setFocusedDay
143
+ ]);
132
144
  return /*#__PURE__*/ _jsxs(RootComponent, {
145
+ "aria-label": ariaLabel,
133
146
  ...props,
134
147
  baseClassName: styles.host,
135
148
  getRootRef: getRootRef,
@@ -157,8 +170,10 @@ const getIsDaySelected = (day, value)=>{
157
170
  viewDate: viewDate,
158
171
  value: value,
159
172
  weekStartsOn: weekStartsOn,
160
- onKeyDown: handleKeyDown,
173
+ onKeyDown: handleFirstCalendarKeyDown,
174
+ onDayFocus: onDayFocus,
161
175
  isDayFocused: isDayFocused,
176
+ isDayFocusable: isDayFocusableInFirstCalendar,
162
177
  onDayChange: onDayChange,
163
178
  isDaySelected: isDaySelected,
164
179
  isDayActive: isDayActive,
@@ -172,7 +187,6 @@ const getIsDaySelected = (day, value)=>{
172
187
  isDayDisabled: isDayDisabled,
173
188
  listenDayChangesForUpdate: listenDayChangesForUpdate,
174
189
  renderDayContent: renderDayContent,
175
- "aria-label": changeDayLabel,
176
190
  dayTestId: dayTestId
177
191
  })
178
192
  ]
@@ -200,9 +214,10 @@ const getIsDaySelected = (day, value)=>{
200
214
  viewDate: secondViewDate,
201
215
  value: value,
202
216
  weekStartsOn: weekStartsOn,
203
- "aria-label": changeDayLabel,
204
- onKeyDown: handleKeyDown,
217
+ onKeyDown: handleSecondCalendarKeyDown,
218
+ onDayFocus: onDayFocus,
205
219
  isDayFocused: isDayFocused,
220
+ isDayFocusable: isDayFocusableInSecondCalendar,
206
221
  onDayChange: onDayChange,
207
222
  isDaySelected: isDaySelected,
208
223
  isDayActive: isDayActive,
@@ -216,8 +231,6 @@ const getIsDaySelected = (day, value)=>{
216
231
  isDayDisabled: isDayDisabled,
217
232
  listenDayChangesForUpdate: listenDayChangesForUpdate,
218
233
  renderDayContent: renderDayContent,
219
- tabIndex: 0,
220
- onBlur: resetSelectedDay,
221
234
  dayTestId: dayTestId
222
235
  })
223
236
  ]