@vkontakte/vkui 6.3.1 → 6.4.1

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 (243) hide show
  1. package/dist/cjs/components/ChipsInputBase/ChipsInputBase.d.ts +1 -1
  2. package/dist/cjs/components/ChipsInputBase/ChipsInputBase.d.ts.map +1 -1
  3. package/dist/cjs/components/ChipsInputBase/ChipsInputBase.js +4 -2
  4. package/dist/cjs/components/ChipsInputBase/ChipsInputBase.js.map +1 -1
  5. package/dist/cjs/components/ChipsInputBase/types.d.ts +1 -1
  6. package/dist/cjs/components/ChipsInputBase/types.d.ts.map +1 -1
  7. package/dist/cjs/components/ChipsInputBase/types.js.map +1 -1
  8. package/dist/cjs/components/ChipsSelect/ChipsSelect.js +1 -1
  9. package/dist/cjs/components/ChipsSelect/ChipsSelect.js.map +1 -1
  10. package/dist/cjs/components/Clickable/Clickable.d.ts.map +1 -1
  11. package/dist/cjs/components/Clickable/Clickable.js +4 -3
  12. package/dist/cjs/components/Clickable/Clickable.js.map +1 -1
  13. package/dist/cjs/components/CustomSelect/CustomSelect.d.ts.map +1 -1
  14. package/dist/cjs/components/CustomSelect/CustomSelect.js +2 -3
  15. package/dist/cjs/components/CustomSelect/CustomSelect.js.map +1 -1
  16. package/dist/cjs/components/FormField/FormField.d.ts +5 -1
  17. package/dist/cjs/components/FormField/FormField.d.ts.map +1 -1
  18. package/dist/cjs/components/FormField/FormField.js +26 -10
  19. package/dist/cjs/components/FormField/FormField.js.map +1 -1
  20. package/dist/cjs/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.d.ts.map +1 -1
  21. package/dist/cjs/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.js +4 -4
  22. package/dist/cjs/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.js.map +1 -1
  23. package/dist/cjs/components/Input/Input.d.ts +1 -1
  24. package/dist/cjs/components/Input/Input.d.ts.map +1 -1
  25. package/dist/cjs/components/Input/Input.js.map +1 -1
  26. package/dist/cjs/components/ScreenSpinner/ScreenSpinner.d.ts +20 -1
  27. package/dist/cjs/components/ScreenSpinner/ScreenSpinner.d.ts.map +1 -1
  28. package/dist/cjs/components/ScreenSpinner/ScreenSpinner.js +109 -25
  29. package/dist/cjs/components/ScreenSpinner/ScreenSpinner.js.map +1 -1
  30. package/dist/cjs/components/Select/Select.d.ts.map +1 -1
  31. package/dist/cjs/components/Select/Select.js +2 -1
  32. package/dist/cjs/components/Select/Select.js.map +1 -1
  33. package/dist/cjs/components/Snackbar/Snackbar.d.ts +3 -1
  34. package/dist/cjs/components/Snackbar/Snackbar.d.ts.map +1 -1
  35. package/dist/cjs/components/Snackbar/Snackbar.js +4 -3
  36. package/dist/cjs/components/Snackbar/Snackbar.js.map +1 -1
  37. package/dist/cjs/components/Snackbar/types.d.ts +1 -0
  38. package/dist/cjs/components/Snackbar/types.d.ts.map +1 -1
  39. package/dist/cjs/components/Snackbar/utils.d.ts.map +1 -1
  40. package/dist/cjs/components/Snackbar/utils.js +7 -3
  41. package/dist/cjs/components/Snackbar/utils.js.map +1 -1
  42. package/dist/cjs/components/Textarea/Textarea.d.ts +1 -1
  43. package/dist/cjs/components/Textarea/Textarea.d.ts.map +1 -1
  44. package/dist/cjs/components/Textarea/Textarea.js +1 -3
  45. package/dist/cjs/components/Textarea/Textarea.js.map +1 -1
  46. package/dist/cjs/components/Tooltip/Tooltip.d.ts +5 -1
  47. package/dist/cjs/components/Tooltip/Tooltip.d.ts.map +1 -1
  48. package/dist/cjs/components/Tooltip/Tooltip.js +3 -2
  49. package/dist/cjs/components/Tooltip/Tooltip.js.map +1 -1
  50. package/dist/cjs/index.d.ts +2 -2
  51. package/dist/cjs/index.d.ts.map +1 -1
  52. package/dist/cjs/index.js +3 -0
  53. package/dist/cjs/index.js.map +1 -1
  54. package/dist/cjs/lib/animation/useCSSKeyframesAnimationController.d.ts +9 -9
  55. package/dist/cjs/lib/animation/useCSSKeyframesAnimationController.d.ts.map +1 -1
  56. package/dist/cjs/lib/animation/useCSSKeyframesAnimationController.js +31 -52
  57. package/dist/cjs/lib/animation/useCSSKeyframesAnimationController.js.map +1 -1
  58. package/dist/cjs/lib/utils.d.ts +1 -1
  59. package/dist/cjs/lib/utils.d.ts.map +1 -1
  60. package/dist/cjs/lib/utils.js +12 -9
  61. package/dist/cjs/lib/utils.js.map +1 -1
  62. package/dist/components/ChipsInputBase/ChipsInputBase.d.ts +1 -1
  63. package/dist/components/ChipsInputBase/ChipsInputBase.d.ts.map +1 -1
  64. package/dist/components/ChipsInputBase/ChipsInputBase.js +4 -2
  65. package/dist/components/ChipsInputBase/ChipsInputBase.js.map +1 -1
  66. package/dist/components/ChipsInputBase/types.d.ts +1 -1
  67. package/dist/components/ChipsInputBase/types.d.ts.map +1 -1
  68. package/dist/components/ChipsInputBase/types.js.map +1 -1
  69. package/dist/components/ChipsSelect/ChipsSelect.js +1 -1
  70. package/dist/components/ChipsSelect/ChipsSelect.js.map +1 -1
  71. package/dist/components/Clickable/Clickable.d.ts.map +1 -1
  72. package/dist/components/Clickable/Clickable.js +4 -3
  73. package/dist/components/Clickable/Clickable.js.map +1 -1
  74. package/dist/components/CustomSelect/CustomSelect.d.ts.map +1 -1
  75. package/dist/components/CustomSelect/CustomSelect.js +2 -3
  76. package/dist/components/CustomSelect/CustomSelect.js.map +1 -1
  77. package/dist/components/FormField/FormField.d.ts +5 -1
  78. package/dist/components/FormField/FormField.d.ts.map +1 -1
  79. package/dist/components/FormField/FormField.js +26 -10
  80. package/dist/components/FormField/FormField.js.map +1 -1
  81. package/dist/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.d.ts.map +1 -1
  82. package/dist/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.js +4 -4
  83. package/dist/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.js.map +1 -1
  84. package/dist/components/Input/Input.d.ts +1 -1
  85. package/dist/components/Input/Input.d.ts.map +1 -1
  86. package/dist/components/Input/Input.js.map +1 -1
  87. package/dist/components/ScreenSpinner/ScreenSpinner.d.ts +20 -1
  88. package/dist/components/ScreenSpinner/ScreenSpinner.d.ts.map +1 -1
  89. package/dist/components/ScreenSpinner/ScreenSpinner.js +99 -24
  90. package/dist/components/ScreenSpinner/ScreenSpinner.js.map +1 -1
  91. package/dist/components/Select/Select.d.ts.map +1 -1
  92. package/dist/components/Select/Select.js +2 -1
  93. package/dist/components/Select/Select.js.map +1 -1
  94. package/dist/components/Snackbar/Snackbar.d.ts +3 -1
  95. package/dist/components/Snackbar/Snackbar.d.ts.map +1 -1
  96. package/dist/components/Snackbar/Snackbar.js +4 -3
  97. package/dist/components/Snackbar/Snackbar.js.map +1 -1
  98. package/dist/components/Snackbar/types.d.ts +1 -0
  99. package/dist/components/Snackbar/types.d.ts.map +1 -1
  100. package/dist/components/Snackbar/types.js.map +1 -1
  101. package/dist/components/Snackbar/utils.d.ts.map +1 -1
  102. package/dist/components/Snackbar/utils.js +7 -3
  103. package/dist/components/Snackbar/utils.js.map +1 -1
  104. package/dist/components/Textarea/Textarea.d.ts +1 -1
  105. package/dist/components/Textarea/Textarea.d.ts.map +1 -1
  106. package/dist/components/Textarea/Textarea.js +1 -3
  107. package/dist/components/Textarea/Textarea.js.map +1 -1
  108. package/dist/components/Tooltip/Tooltip.d.ts +5 -1
  109. package/dist/components/Tooltip/Tooltip.d.ts.map +1 -1
  110. package/dist/components/Tooltip/Tooltip.js +3 -2
  111. package/dist/components/Tooltip/Tooltip.js.map +1 -1
  112. package/dist/components.css +3 -3
  113. package/dist/components.css.map +1 -1
  114. package/dist/components.js.tmp +885 -755
  115. package/dist/cssm/components/ChipsInputBase/ChipsInputBase.d.ts +1 -1
  116. package/dist/cssm/components/ChipsInputBase/ChipsInputBase.d.ts.map +1 -1
  117. package/dist/cssm/components/ChipsInputBase/ChipsInputBase.js +3 -2
  118. package/dist/cssm/components/ChipsInputBase/ChipsInputBase.js.map +1 -1
  119. package/dist/cssm/components/ChipsInputBase/types.d.ts +1 -1
  120. package/dist/cssm/components/ChipsInputBase/types.d.ts.map +1 -1
  121. package/dist/cssm/components/ChipsInputBase/types.js.map +1 -1
  122. package/dist/cssm/components/ChipsSelect/ChipsSelect.js +1 -1
  123. package/dist/cssm/components/ChipsSelect/ChipsSelect.js.map +1 -1
  124. package/dist/cssm/components/Clickable/Clickable.d.ts.map +1 -1
  125. package/dist/cssm/components/Clickable/Clickable.js +4 -3
  126. package/dist/cssm/components/Clickable/Clickable.js.map +1 -1
  127. package/dist/cssm/components/CustomSelect/CustomSelect.d.ts.map +1 -1
  128. package/dist/cssm/components/CustomSelect/CustomSelect.js +2 -3
  129. package/dist/cssm/components/CustomSelect/CustomSelect.js.map +1 -1
  130. package/dist/cssm/components/DateInput/DateInput.module.css +1 -0
  131. package/dist/cssm/components/DateRangeInput/DateRangeInput.module.css +1 -0
  132. package/dist/cssm/components/FormField/FormField.d.ts +5 -1
  133. package/dist/cssm/components/FormField/FormField.d.ts.map +1 -1
  134. package/dist/cssm/components/FormField/FormField.js +24 -9
  135. package/dist/cssm/components/FormField/FormField.js.map +1 -1
  136. package/dist/cssm/components/FormField/FormField.module.css +27 -4
  137. package/dist/cssm/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.d.ts.map +1 -1
  138. package/dist/cssm/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.js +2 -3
  139. package/dist/cssm/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.js.map +1 -1
  140. package/dist/cssm/components/Input/Input.d.ts +1 -1
  141. package/dist/cssm/components/Input/Input.d.ts.map +1 -1
  142. package/dist/cssm/components/Input/Input.js.map +1 -1
  143. package/dist/cssm/components/List/List.module.css +1 -0
  144. package/dist/cssm/components/ScreenSpinner/ScreenSpinner.d.ts +20 -1
  145. package/dist/cssm/components/ScreenSpinner/ScreenSpinner.d.ts.map +1 -1
  146. package/dist/cssm/components/ScreenSpinner/ScreenSpinner.js +86 -18
  147. package/dist/cssm/components/ScreenSpinner/ScreenSpinner.js.map +1 -1
  148. package/dist/cssm/components/ScreenSpinner/ScreenSpinner.module.css +14 -16
  149. package/dist/cssm/components/Select/Select.d.ts.map +1 -1
  150. package/dist/cssm/components/Select/Select.js +1 -1
  151. package/dist/cssm/components/Select/Select.js.map +1 -1
  152. package/dist/cssm/components/Select/Select.module.css +1 -0
  153. package/dist/cssm/components/Snackbar/Snackbar.d.ts +3 -1
  154. package/dist/cssm/components/Snackbar/Snackbar.d.ts.map +1 -1
  155. package/dist/cssm/components/Snackbar/Snackbar.js +4 -3
  156. package/dist/cssm/components/Snackbar/Snackbar.js.map +1 -1
  157. package/dist/cssm/components/Snackbar/Snackbar.module.css +14 -1
  158. package/dist/cssm/components/Snackbar/types.d.ts +1 -0
  159. package/dist/cssm/components/Snackbar/types.d.ts.map +1 -1
  160. package/dist/cssm/components/Snackbar/types.js.map +1 -1
  161. package/dist/cssm/components/Snackbar/utils.d.ts.map +1 -1
  162. package/dist/cssm/components/Snackbar/utils.js +7 -3
  163. package/dist/cssm/components/Snackbar/utils.js.map +1 -1
  164. package/dist/cssm/components/Textarea/Textarea.d.ts +1 -1
  165. package/dist/cssm/components/Textarea/Textarea.d.ts.map +1 -1
  166. package/dist/cssm/components/Textarea/Textarea.js +1 -3
  167. package/dist/cssm/components/Textarea/Textarea.js.map +1 -1
  168. package/dist/cssm/components/Tooltip/Tooltip.d.ts +5 -1
  169. package/dist/cssm/components/Tooltip/Tooltip.d.ts.map +1 -1
  170. package/dist/cssm/components/Tooltip/Tooltip.js +2 -2
  171. package/dist/cssm/components/Tooltip/Tooltip.js.map +1 -1
  172. package/dist/cssm/index.d.ts +2 -2
  173. package/dist/cssm/index.d.ts.map +1 -1
  174. package/dist/cssm/index.js +1 -1
  175. package/dist/cssm/index.js.map +1 -1
  176. package/dist/cssm/lib/animation/useCSSKeyframesAnimationController.d.ts +9 -9
  177. package/dist/cssm/lib/animation/useCSSKeyframesAnimationController.d.ts.map +1 -1
  178. package/dist/cssm/lib/animation/useCSSKeyframesAnimationController.js +31 -51
  179. package/dist/cssm/lib/animation/useCSSKeyframesAnimationController.js.map +1 -1
  180. package/dist/cssm/lib/utils.d.ts +1 -1
  181. package/dist/cssm/lib/utils.d.ts.map +1 -1
  182. package/dist/cssm/lib/utils.js +15 -7
  183. package/dist/cssm/lib/utils.js.map +1 -1
  184. package/dist/index.d.ts +2 -2
  185. package/dist/index.d.ts.map +1 -1
  186. package/dist/index.js +1 -1
  187. package/dist/index.js.map +1 -1
  188. package/dist/lib/animation/useCSSKeyframesAnimationController.d.ts +9 -9
  189. package/dist/lib/animation/useCSSKeyframesAnimationController.d.ts.map +1 -1
  190. package/dist/lib/animation/useCSSKeyframesAnimationController.js +31 -51
  191. package/dist/lib/animation/useCSSKeyframesAnimationController.js.map +1 -1
  192. package/dist/lib/utils.d.ts +1 -1
  193. package/dist/lib/utils.d.ts.map +1 -1
  194. package/dist/lib/utils.js +16 -7
  195. package/dist/lib/utils.js.map +1 -1
  196. package/dist/vkui.css +3 -3
  197. package/dist/vkui.css.map +1 -1
  198. package/dist/vkui.js.tmp +885 -755
  199. package/package.json +3 -3
  200. package/src/components/ChipsInputBase/ChipsInputBase.tsx +3 -1
  201. package/src/components/ChipsInputBase/types.ts +1 -1
  202. package/src/components/ChipsSelect/ChipsSelect.tsx +1 -1
  203. package/src/components/Clickable/Clickable.tsx +16 -13
  204. package/src/components/CustomSelect/CustomSelect.tsx +2 -3
  205. package/src/components/DateInput/DateInput.module.css +1 -0
  206. package/src/components/DateRangeInput/DateRangeInput.module.css +1 -0
  207. package/src/components/FormField/FormField.module.css +26 -4
  208. package/src/components/FormField/FormField.tsx +31 -16
  209. package/src/components/ImageBase/ImageBaseOverlay/ImageBaseOverlay.tsx +2 -3
  210. package/src/components/Input/Input.tsx +1 -1
  211. package/src/components/List/List.module.css +1 -0
  212. package/src/components/ScreenSpinner/ScreenSpinner.module.css +14 -16
  213. package/src/components/ScreenSpinner/ScreenSpinner.tsx +132 -40
  214. package/src/components/Select/Select.module.css +1 -0
  215. package/src/components/Select/Select.tsx +1 -0
  216. package/src/components/Snackbar/Snackbar.module.css +14 -1
  217. package/src/components/Snackbar/Snackbar.tsx +17 -4
  218. package/src/components/Snackbar/types.ts +1 -0
  219. package/src/components/Snackbar/utils.ts +12 -4
  220. package/src/components/Textarea/Textarea.tsx +1 -2
  221. package/src/components/Tooltip/Tooltip.tsx +6 -1
  222. package/src/index.ts +5 -2
  223. package/src/lib/animation/useCSSKeyframesAnimationController.ts +46 -62
  224. package/src/lib/utils.ts +18 -9
  225. package/dist/cjs/components/Clickable/useKeyboard.d.ts +0 -5
  226. package/dist/cjs/components/Clickable/useKeyboard.d.ts.map +0 -1
  227. package/dist/cjs/components/Clickable/useKeyboard.js +0 -29
  228. package/dist/cjs/components/Clickable/useKeyboard.js.map +0 -1
  229. package/dist/cjs/vkui.js +0 -8
  230. package/dist/cjs/vkui.js.map +0 -1
  231. package/dist/components/Clickable/useKeyboard.d.ts +0 -5
  232. package/dist/components/Clickable/useKeyboard.d.ts.map +0 -1
  233. package/dist/components/Clickable/useKeyboard.js +0 -24
  234. package/dist/components/Clickable/useKeyboard.js.map +0 -1
  235. package/dist/cssm/components/Clickable/useKeyboard.d.ts +0 -5
  236. package/dist/cssm/components/Clickable/useKeyboard.d.ts.map +0 -1
  237. package/dist/cssm/components/Clickable/useKeyboard.js +0 -23
  238. package/dist/cssm/components/Clickable/useKeyboard.js.map +0 -1
  239. package/dist/cssm/vkui.js +0 -3
  240. package/dist/cssm/vkui.js.map +0 -1
  241. package/dist/vkui.js +0 -3
  242. package/dist/vkui.js.map +0 -1
  243. package/src/components/Clickable/useKeyboard.tsx +0 -26
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "6.3.1",
2
+ "version": "6.4.1",
3
3
  "name": "@vkontakte/vkui",
4
4
  "description": "VKUI library",
5
5
  "main": "dist/cjs/index.js",
@@ -68,13 +68,13 @@
68
68
  "dependencies": {
69
69
  "@swc/helpers": "^0.5.12",
70
70
  "@vkontakte/icons": "^2.115.0",
71
- "@vkontakte/vkjs": "^1.2.1",
71
+ "@vkontakte/vkjs": "^1.3.0",
72
72
  "@vkontakte/vkui-floating-ui": "^0.2.1",
73
73
  "dayjs": "^1.11.12",
74
74
  "mitt": "^3.0.1"
75
75
  },
76
76
  "devDependencies": {
77
- "storybook": "8.2.5"
77
+ "storybook": "8.2.6"
78
78
  },
79
79
  "size-limit": [
80
80
  {
@@ -37,6 +37,7 @@ export const ChipsInputBase = <O extends ChipOption>({
37
37
  after,
38
38
  status,
39
39
  mode,
40
+ maxHeight,
40
41
 
41
42
  // option
42
43
  value = DEFAULT_VALUE,
@@ -223,6 +224,7 @@ export const ChipsInputBase = <O extends ChipOption>({
223
224
  status={status}
224
225
  mode={mode}
225
226
  className={className}
227
+ maxHeight={maxHeight}
226
228
  onClick={disabled ? undefined : handleRootClick}
227
229
  >
228
230
  <div
@@ -240,7 +242,7 @@ export const ChipsInputBase = <O extends ChipOption>({
240
242
  onKeyDown={disabled ? undefined : handleListboxKeyDown}
241
243
  >
242
244
  {value.map((option, index) => (
243
- <React.Fragment key={`${typeof option.value}-${option.label}`}>
245
+ <React.Fragment key={`${typeof option.value}-${option.value}`}>
244
246
  {renderChip(
245
247
  {
246
248
  'Component': 'div',
@@ -123,7 +123,7 @@ export interface ChipsInputBaseProps<O extends ChipOption = ChipOption>
123
123
  */
124
124
  export interface ChipsInputBasePrivateProps<O extends ChipOption = ChipOption>
125
125
  extends ChipsInputBaseProps<O>,
126
- Pick<FormFieldProps, 'mode' | 'status' | 'before' | 'after'> {
126
+ Pick<FormFieldProps, 'mode' | 'status' | 'before' | 'after' | 'maxHeight'> {
127
127
  onClear: () => void;
128
128
  onAddChipOption: (value: string) => void;
129
129
  onRemoveChipOption: (value: O | ChipOptionValue) => void;
@@ -522,7 +522,7 @@ export const ChipsSelect = <Option extends ChipOption>({
522
522
  );
523
523
  }
524
524
  return (
525
- <React.Fragment key={`${typeof option.value}-${option.label}`}>
525
+ <React.Fragment key={`${typeof option.value}-${option.value}`}>
526
526
  {renderOption(
527
527
  {
528
528
  id: dropdownItemId,
@@ -5,8 +5,8 @@ import {
5
5
  useFocusVisibleClassName,
6
6
  } from '../../hooks/useFocusVisibleClassName';
7
7
  import { mergeCalls } from '../../lib/mergeCalls';
8
+ import { clickByKeyboardHandler } from '../../lib/utils';
8
9
  import { RootComponent, RootComponentProps } from '../RootComponent/RootComponent';
9
- import { useKeyboard } from './useKeyboard';
10
10
  import {
11
11
  ClickableLockStateContext,
12
12
  DEFAULT_ACTIVE_EFFECT_DELAY,
@@ -74,18 +74,21 @@ const RealClickable = <T,>({
74
74
  activated,
75
75
  });
76
76
 
77
- const keyboardHandlers = useKeyboard();
78
-
79
- const handlers = mergeCalls(focusEvents, stateEvents, keyboardHandlers, {
80
- onPointerEnter,
81
- onPointerLeave,
82
- onPointerDown,
83
- onPointerCancel,
84
- onPointerUp,
85
- onBlur,
86
- onFocus,
87
- onKeyDown,
88
- });
77
+ const handlers = mergeCalls(
78
+ focusEvents,
79
+ stateEvents,
80
+ { onKeyDown: clickByKeyboardHandler },
81
+ {
82
+ onPointerEnter,
83
+ onPointerLeave,
84
+ onPointerDown,
85
+ onPointerCancel,
86
+ onPointerUp,
87
+ onBlur,
88
+ onFocus,
89
+ onKeyDown,
90
+ },
91
+ );
89
92
 
90
93
  return (
91
94
  <RootComponent
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { classNames } from '@vkontakte/vkjs';
2
+ import { classNames, debounce } from '@vkontakte/vkjs';
3
3
  import { useAdaptivity } from '../../hooks/useAdaptivity';
4
4
  import { useExternRef } from '../../hooks/useExternRef';
5
5
  import { useFocusWithin } from '../../hooks/useFocusWithin';
@@ -7,7 +7,6 @@ import { useDOM } from '../../lib/dom';
7
7
  import type { PlacementWithAuto } from '../../lib/floating';
8
8
  import { defaultFilterFn, type FilterFn } from '../../lib/select';
9
9
  import { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';
10
- import { debounce } from '../../lib/utils';
11
10
  import { warnOnce } from '../../lib/warnOnce';
12
11
  import { TrackerOptionsProps } from '../CustomScrollView/useTrackerVisibility';
13
12
  import {
@@ -669,7 +668,7 @@ export function CustomSelect<OptionInterfaceT extends CustomSelectOptionInterfac
669
668
  const selected = index === selectedOptionIndex;
670
669
 
671
670
  return (
672
- <React.Fragment key={`${option.value}`}>
671
+ <React.Fragment key={`${typeof option.value}-${option.value}`}>
673
672
  {renderOptionProp({
674
673
  option,
675
674
  hovered,
@@ -1,6 +1,7 @@
1
1
  .DateInput__input {
2
2
  display: block;
3
3
  flex-grow: 1;
4
+ align-self: center;
4
5
  margin-inline: 10px 14px;
5
6
  z-index: var(--vkui_internal--z_index_form_field_element);
6
7
  cursor: text;
@@ -1,5 +1,6 @@
1
1
  .DateRangeInput__input {
2
2
  flex-grow: 1;
3
+ align-self: center;
3
4
  margin-inline: 10px 14px;
4
5
  z-index: var(--vkui_internal--z_index_form_field_element);
5
6
  cursor: text;
@@ -1,13 +1,29 @@
1
1
  .FormField {
2
2
  position: relative;
3
3
  display: flex;
4
- align-items: center;
5
4
  box-sizing: border-box;
6
5
  min-block-size: var(--vkui--size_field_height--regular);
7
6
  font-family: var(--vkui--font_family_base);
8
7
  -webkit-tap-highlight-color: transparent;
9
8
  isolation: isolate;
10
9
  border-radius: var(--vkui--size_border_radius--regular);
10
+ inline-size: 100%;
11
+ }
12
+
13
+ .FormField_scrollContainer {
14
+ display: flex;
15
+ inline-size: 100%;
16
+ align-items: flex-start;
17
+ justify-content: flex-start;
18
+ overflow-y: auto;
19
+ min-block-size: inherit;
20
+ }
21
+
22
+ .FormField__content {
23
+ min-block-size: inherit;
24
+ display: flex;
25
+ flex-grow: 1;
26
+ min-inline-size: 0;
11
27
  }
12
28
 
13
29
  .FormField--sizeY-compact {
@@ -26,15 +42,21 @@
26
42
  z-index: var(--vkui_internal--z_index_form_field_element);
27
43
  }
28
44
 
45
+ .FormField__iconWrapper {
46
+ flex-shrink: 0;
47
+ block-size: 100%;
48
+ display: flex;
49
+ position: sticky;
50
+ inset-block-start: 0;
51
+ }
52
+
29
53
  .FormField__before,
30
54
  .FormField__after {
31
- position: relative;
32
- z-index: var(--vkui_internal--z_index_form_field_side);
33
55
  display: flex;
34
56
  align-items: center;
35
57
  align-content: center;
36
58
  justify-content: center;
37
- flex-shrink: 0;
59
+ align-self: center;
38
60
  min-inline-size: var(--vkui--size_field_height--regular);
39
61
  block-size: 100%;
40
62
  color: var(--vkui--color_icon_secondary);
@@ -23,6 +23,14 @@ const iconAlignClassNames = {
23
23
  end: styles['FormField__icon--align-end'],
24
24
  };
25
25
 
26
+ const renderIcon = (icon: React.ReactNode, align: FieldIconsAlign, className: string) => {
27
+ return (
28
+ <div className={styles['FormField__iconWrapper']}>
29
+ <span className={classNames(iconAlignClassNames[align], className)}>{icon}</span>
30
+ </div>
31
+ );
32
+ };
33
+
26
34
  export type FieldIconsAlign = 'start' | 'center' | 'end';
27
35
 
28
36
  export interface FormFieldProps {
@@ -60,6 +68,10 @@ export interface FormFieldProps {
60
68
  * - `plain` — показывает только текст-подсказку.
61
69
  */
62
70
  mode?: 'default' | 'plain';
71
+ /**
72
+ * Максимальная высота поля
73
+ */
74
+ maxHeight?: number;
63
75
  }
64
76
 
65
77
  interface FormFieldOwnProps
@@ -85,6 +97,8 @@ export const FormField = ({
85
97
  disabled,
86
98
  mode = 'default',
87
99
  className,
100
+ maxHeight,
101
+ style,
88
102
  ...restProps
89
103
  }: FormFieldOwnProps): React.ReactNode => {
90
104
  const elRef = useExternRef(getRootRef);
@@ -111,6 +125,14 @@ export const FormField = ({
111
125
  <Component
112
126
  {...restProps}
113
127
  ref={elRef}
128
+ style={
129
+ maxHeight !== undefined
130
+ ? {
131
+ ...style,
132
+ maxHeight,
133
+ }
134
+ : style
135
+ }
114
136
  onMouseEnter={handleMouseEnter}
115
137
  onMouseLeave={handleMouseLeave}
116
138
  className={classNames(
@@ -124,23 +146,16 @@ export const FormField = ({
124
146
  className,
125
147
  )}
126
148
  >
127
- {before && (
128
- <span className={classNames(styles['FormField__before'], iconAlignClassNames[beforeAlign])}>
129
- {before}
130
- </span>
131
- )}
132
- {children}
133
- {after && (
134
- <span
135
- className={classNames(
136
- styles['FormField__after'],
137
- iconAlignClassNames[afterAlign],
138
- 'vkuiInternalFormField__after',
149
+ <div className={styles['FormField_scrollContainer']}>
150
+ {before && renderIcon(before, beforeAlign, styles['FormField__before'])}
151
+ <div className={styles['FormField__content']}>{children}</div>
152
+ {after &&
153
+ renderIcon(
154
+ after,
155
+ afterAlign,
156
+ classNames(styles['FormField__after'], 'vkuiInternalFormField__after'),
139
157
  )}
140
- >
141
- {after}
142
- </span>
143
- )}
158
+ </div>
144
159
  <span aria-hidden className={styles['FormField__border']} />
145
160
  </Component>
146
161
  );
@@ -1,11 +1,11 @@
1
1
  import * as React from 'react';
2
2
  import { classNames } from '@vkontakte/vkjs';
3
- import { useKeyboard } from '../../../components/Clickable/useKeyboard';
4
3
  import { useAdaptivityHasPointer } from '../../../hooks/useAdaptivityHasPointer';
5
4
  import { useAppearance } from '../../../hooks/useAppearance';
6
5
  import { useExternRef } from '../../../hooks/useExternRef';
7
6
  import { useFocusVisible } from '../../../hooks/useFocusVisible';
8
7
  import { useFocusVisibleClassName } from '../../../hooks/useFocusVisibleClassName';
8
+ import { clickByKeyboardHandler } from '../../../lib/utils';
9
9
  import { ImageBaseContext } from '../context';
10
10
  import { validateOverlayIcon } from '../validators';
11
11
  import { useNonInteractiveOverlayProps } from './hooks';
@@ -41,7 +41,6 @@ const ImageBaseOverlayInteractive = ({
41
41
  }: ImageBaseOverlayInteractiveProps & { overlayShown?: boolean }) => {
42
42
  const { focusVisible, ...focusEvents } = useFocusVisible();
43
43
  const focusVisibleClassNames = useFocusVisibleClassName({ focusVisible, mode: 'inside' });
44
- const keyboardHandlers = useKeyboard();
45
44
 
46
45
  return (
47
46
  <>
@@ -56,8 +55,8 @@ const ImageBaseOverlayInteractive = ({
56
55
  className,
57
56
  )}
58
57
  ref={getRootRef}
58
+ onKeyDown={clickByKeyboardHandler}
59
59
  {...focusEvents}
60
- {...keyboardHandlers}
61
60
  >
62
61
  {children}
63
62
  </div>
@@ -16,7 +16,7 @@ export interface InputProps
16
16
  HasRef<HTMLInputElement>,
17
17
  HasRootRef<HTMLDivElement>,
18
18
  HasAlign,
19
- FormFieldProps {}
19
+ Omit<FormFieldProps, 'maxHeight'> {}
20
20
 
21
21
  /**
22
22
  * @see https://vkcom.github.io/VKUI/#/Input
@@ -1,5 +1,6 @@
1
1
  .List {
2
2
  display: grid;
3
+ grid-template-columns: minmax(0, 1fr);
3
4
  }
4
5
 
5
6
  .List__placeholder {
@@ -1,30 +1,24 @@
1
1
  .ScreenSpinner {
2
+ position: relative;
3
+ inline-size: 88px;
4
+ block-size: 88px;
5
+ background: var(--vkui--color_background_contrast_themed);
6
+ box-shadow: var(--vkui--elevation4);
7
+ border-radius: var(--vkui--size_border_radius--regular);
8
+ color: var(--vkui--color_icon_medium);
2
9
  animation: screen-spinner-intro 0.3s ease;
3
10
  }
4
11
 
5
- .ScreenSpinner--clickable {
6
- cursor: pointer;
7
- }
8
-
9
12
  .ScreenSpinner__spinner {
10
13
  opacity: 1;
11
14
  transition: opacity 0.1s ease;
12
15
  }
13
16
 
14
- .ScreenSpinner__spinner--hidden {
17
+ .ScreenSpinner--state-done .ScreenSpinner__spinner,
18
+ .ScreenSpinner--state-error .ScreenSpinner__spinner {
15
19
  opacity: 0;
16
20
  }
17
21
 
18
- .ScreenSpinner__container {
19
- position: relative;
20
- inline-size: 88px;
21
- block-size: 88px;
22
- background: var(--vkui--color_background_contrast_themed);
23
- box-shadow: var(--vkui--elevation4);
24
- border-radius: var(--vkui--size_border_radius--regular);
25
- color: var(--vkui--color_icon_medium);
26
- }
27
-
28
22
  .ScreenSpinner__icon {
29
23
  position: absolute;
30
24
  inset-block-start: 0;
@@ -35,13 +29,17 @@
35
29
  justify-content: center;
36
30
  }
37
31
 
32
+ .ScreenSpinner--state-cancelable .ScreenSpinner__icon {
33
+ cursor: pointer;
34
+ }
35
+
38
36
  /* stylelint-disable-next-line selector-pseudo-class-disallowed-list */
39
37
  .ScreenSpinner__icon :global(.vkuiIcon) {
40
38
  animation: screen-spinner-intro 0.2s ease;
41
39
  }
42
40
 
43
41
  /* stylelint-disable-next-line selector-max-type, selector-pseudo-class-disallowed-list */
44
- .ScreenSpinner__icon--state-done :global(.vkuiIcon) path {
42
+ .ScreenSpinner--state-done :global(.vkuiIcon) path {
45
43
  stroke-dasharray: 50;
46
44
  stroke-dashoffset: 50;
47
45
  animation: screen-spinner-icon-done 0.6s 0.3s var(--vkui--animation_easing_platform) forwards;
@@ -1,7 +1,12 @@
1
+ import * as React from 'react';
1
2
  import { Icon24Cancel } from '@vkontakte/icons';
2
3
  import { classNames } from '@vkontakte/vkjs';
4
+ import { mergeCalls } from '../../lib/mergeCalls';
5
+ import { clickByKeyboardHandler } from '../../lib/utils';
6
+ import { HTMLAttributesWithRootRef } from '../../types';
3
7
  import { useScrollLock } from '../AppRoot/ScrollContext';
4
8
  import { PopoutWrapper } from '../PopoutWrapper/PopoutWrapper';
9
+ import { RootComponent } from '../RootComponent/RootComponent';
5
10
  import { Spinner, SpinnerProps } from '../Spinner/Spinner';
6
11
  import { Icon48CancelCircle } from './Icon48CancelCircle';
7
12
  import { Icon48DoneOutline } from './Icon48DoneOutline';
@@ -9,61 +14,148 @@ import styles from './ScreenSpinner.module.css';
9
14
 
10
15
  export interface ScreenSpinnerProps extends SpinnerProps {
11
16
  state?: 'loading' | 'cancelable' | 'done' | 'error';
17
+ cancelLabel?: string;
12
18
  }
13
19
 
14
- /**
15
- * @see https://vkcom.github.io/VKUI/#/ScreenSpinner
16
- */
17
- export const ScreenSpinner = ({
18
- style,
19
- className,
20
- state = 'loading',
20
+ export interface ScreenSpinnerContextProps {
21
+ state: NonNullable<ScreenSpinnerProps['state']>;
22
+ }
23
+
24
+ export const ScreenSpinnerContext: React.Context<ScreenSpinnerContextProps> =
25
+ React.createContext<ScreenSpinnerContextProps>({
26
+ state: 'loading',
27
+ });
28
+
29
+ const stateClassNames = {
30
+ cancelable: styles['ScreenSpinner--state-cancelable'],
31
+ done: styles['ScreenSpinner--state-done'],
32
+ error: styles['ScreenSpinner--state-error'],
33
+ };
34
+
35
+ const ScreenSpinnerLoader: React.FC<SpinnerProps> = ({
21
36
  size = 'large',
22
- onClick,
23
37
  children = 'Пожалуйста, подождите...',
24
38
  ...restProps
25
- }: ScreenSpinnerProps): React.ReactNode => {
26
- const hideSpinner = state === 'done' || state === 'error';
39
+ }: SpinnerProps) => {
40
+ return (
41
+ <Spinner className={styles['ScreenSpinner__spinner']} size={size} {...restProps}>
42
+ {children}
43
+ </Spinner>
44
+ );
45
+ };
46
+
47
+ ScreenSpinnerLoader.displayName = 'ScreenSpinner.Loader';
48
+
49
+ type ScreenSpinnerSwapIconProps = HTMLAttributesWithRootRef<HTMLElement> & {
50
+ cancelLabel?: ScreenSpinnerProps['cancelLabel'];
51
+ };
52
+
53
+ const ScreenSpinnerCancelIcon: React.FC<ScreenSpinnerSwapIconProps> = ({
54
+ onKeyDown,
55
+ 'aria-label': ariaLabel = 'Отменить',
56
+ ...restProps
57
+ }: ScreenSpinnerSwapIconProps) => {
58
+ const handlers = mergeCalls(
59
+ { onKeyDown: clickByKeyboardHandler },
60
+ {
61
+ onKeyDown,
62
+ },
63
+ );
64
+ let clickableProps: React.HTMLAttributes<HTMLSpanElement> = {
65
+ ...handlers,
66
+ 'tabIndex': 0,
67
+ 'role': 'button',
68
+ 'aria-label': ariaLabel,
69
+ };
70
+
71
+ return (
72
+ <RootComponent baseClassName={styles['ScreenSpinner__icon']} {...clickableProps} {...restProps}>
73
+ <Icon24Cancel />
74
+ </RootComponent>
75
+ );
76
+ };
77
+
78
+ const ScreenSpinnerSwapIcon: React.FC<ScreenSpinnerSwapIconProps> = ({
79
+ cancelLabel,
80
+ ...restProps
81
+ }: ScreenSpinnerSwapIconProps) => {
82
+ const { state } = React.useContext(ScreenSpinnerContext);
83
+
84
+ if (state === 'cancelable') {
85
+ return <ScreenSpinnerCancelIcon aria-label={cancelLabel} {...restProps} />;
86
+ }
27
87
 
28
88
  const Icon = {
29
89
  loading: () => null,
30
- cancelable: Icon24Cancel,
31
90
  done: Icon48DoneOutline,
32
91
  error: Icon48CancelCircle,
33
92
  }[state];
34
93
 
94
+ return (
95
+ <RootComponent baseClassName={styles['ScreenSpinner__icon']} {...restProps}>
96
+ <Icon />
97
+ </RootComponent>
98
+ );
99
+ };
100
+
101
+ ScreenSpinnerSwapIcon.displayName = 'ScreenSpinner.SwapIcon';
102
+
103
+ type ScreenSpinnerContainerProps = HTMLAttributesWithRootRef<HTMLSpanElement> &
104
+ Pick<ScreenSpinnerProps, 'state'>;
105
+
106
+ const ScreenSpinnerContainer: React.FC<ScreenSpinnerContainerProps> = ({
107
+ state = 'loading',
108
+ ...restProps
109
+ }: ScreenSpinnerContainerProps) => {
110
+ return (
111
+ <ScreenSpinnerContext.Provider value={{ state }}>
112
+ <RootComponent
113
+ baseClassName={classNames(
114
+ styles['ScreenSpinner'],
115
+ state !== 'loading' && stateClassNames[state],
116
+ )}
117
+ {...restProps}
118
+ />
119
+ </ScreenSpinnerContext.Provider>
120
+ );
121
+ };
122
+
123
+ ScreenSpinnerContainer.displayName = 'ScreenSpinner.Container';
124
+
125
+ /**
126
+ * @see https://vkcom.github.io/VKUI/#/ScreenSpinner
127
+ */
128
+ export const ScreenSpinner: React.FC<ScreenSpinnerProps> & {
129
+ Container: typeof ScreenSpinnerContainer;
130
+ Loader: typeof ScreenSpinnerLoader;
131
+ SwapIcon: typeof ScreenSpinnerSwapIcon;
132
+ } = ({
133
+ style,
134
+ className,
135
+ state = 'loading',
136
+ onClick,
137
+ cancelLabel,
138
+ ...restProps
139
+ }: ScreenSpinnerProps): React.ReactNode => {
35
140
  useScrollLock();
36
141
 
37
142
  return (
38
- <PopoutWrapper
39
- noBackground
40
- className={classNames(
41
- styles['ScreenSpinner'],
42
- state === 'cancelable' && styles['ScreenSpinner--clickable'],
43
- className,
44
- )}
45
- style={style}
46
- >
47
- <div className={styles['ScreenSpinner__container']} onClick={onClick}>
48
- <Spinner
49
- className={classNames(
50
- styles['ScreenSpinner__spinner'],
51
- hideSpinner && styles['ScreenSpinner__spinner--hidden'],
52
- )}
53
- size={size}
54
- {...restProps}
55
- >
56
- {children}
57
- </Spinner>
58
- <div
59
- className={classNames(
60
- styles['ScreenSpinner__icon'],
61
- state === 'done' && styles['ScreenSpinner__icon--state-done'],
62
- )}
63
- >
64
- <Icon />
65
- </div>
66
- </div>
143
+ <PopoutWrapper className={className} style={style} noBackground>
144
+ <ScreenSpinnerContainer state={state}>
145
+ <ScreenSpinnerLoader {...restProps} />
146
+ <ScreenSpinnerSwapIcon onClick={onClick} cancelLabel={cancelLabel} />
147
+ </ScreenSpinnerContainer>
67
148
  </PopoutWrapper>
68
149
  );
69
150
  };
151
+
152
+ ScreenSpinner.displayName = 'ScreenSpinner';
153
+
154
+ ScreenSpinner.Container = ScreenSpinnerContainer;
155
+ ScreenSpinner.Container.displayName = 'ScreenSpinner.Container';
156
+
157
+ ScreenSpinner.Loader = ScreenSpinnerLoader;
158
+ ScreenSpinner.Loader.displayName = 'ScreenSpinner.Loader';
159
+
160
+ ScreenSpinner.SwapIcon = ScreenSpinnerSwapIcon;
161
+ ScreenSpinner.SwapIcon.displayName = 'ScreenSpinner.SwapIcon';
@@ -21,6 +21,7 @@
21
21
  }
22
22
 
23
23
  .Select__container {
24
+ align-self: center;
24
25
  flex-grow: 1;
25
26
  flex-shrink: 1;
26
27
  padding-inline: 12px 0;
@@ -44,6 +44,7 @@ export const Select = <OptionT extends CustomSelectOptionInterface>({
44
44
  nativeSelectTestId,
45
45
  after,
46
46
  mode,
47
+ maxHeight,
47
48
  getSelectInputRef,
48
49
  overscrollBehavior,
49
50
  beforeAlign,
@@ -3,6 +3,7 @@
3
3
  --vkui_internal--snackbar_in_padding: 8px;
4
4
  --vkui_internal--snackbar_shift_x: 0;
5
5
  --vkui_internal--snackbar_shift_y: 0;
6
+ --vkui_internal--snackbar_direction: 0;
6
7
  --vkui_internal--snackbar_animation_from: translate3d(0, 0, 0);
7
8
  --vkui_internal--snackbar_animation_to: translate3d(0, 0, 0);
8
9
  --vkui_internal--snackbar_animation_duration: 340ms;
@@ -27,10 +28,22 @@
27
28
  inset-block-start: var(--vkui_internal--safe_area_inset_top);
28
29
  }
29
30
 
31
+ .Snackbar--placement-bottom-start {
32
+ --vkui_internal--snackbar_direction: -1;
33
+ }
34
+
35
+ .Snackbar--placement-bottom-end {
36
+ --vkui_internal--snackbar_direction: 1;
37
+ }
38
+
30
39
  .Snackbar--placement-bottom-start,
31
40
  .Snackbar--placement-bottom,
32
41
  .Snackbar--placement-bottom-end {
33
- --vkui_internal--snackbar_animation_from: translate3d(-100%, 0, 0);
42
+ --vkui_internal--snackbar_animation_from: translate3d(
43
+ calc(var(--vkui_internal--snackbar_direction) * 100%),
44
+ 0,
45
+ 0
46
+ );
34
47
  --vkui_internal--snackbar_animation_to: translate3d(var(--vkui_internal--snackbar_shift_x), 0, 0);
35
48
 
36
49
  inset-block-end: var(--vkui_internal--snackbar_safe_area_inset_bottom);