@vkontakte/vkui 4.22.2 → 4.23.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 (236) hide show
  1. package/.cache/.eslintcache +1 -1
  2. package/.cache/.stylelintcache +1 -1
  3. package/.cache/.tsbuildinfo +193 -30
  4. package/.cache/ts/src/components/ActionSheet/ActionSheetContext.d.ts +1 -1
  5. package/.cache/ts/src/components/ActionSheetItem/ActionSheetItem.d.ts +7 -0
  6. package/.cache/ts/src/components/AdaptivityProvider/AdaptivityContext.d.ts +5 -0
  7. package/.cache/ts/src/components/AppRoot/AppRootContext.d.ts +1 -0
  8. package/.cache/ts/src/components/AppRoot/AppRootPortal.d.ts +1 -0
  9. package/.cache/ts/src/components/ClickPopper/ClickPopper.d.ts +21 -0
  10. package/.cache/ts/src/components/ConfigProvider/ConfigProviderContext.d.ts +8 -0
  11. package/.cache/ts/src/components/Dropdown/Dropdown.d.ts +49 -0
  12. package/.cache/ts/src/components/Footer/Footer.d.ts +3 -3
  13. package/.cache/ts/src/components/HoverPopper/HoverPopper.d.ts +29 -0
  14. package/.cache/ts/src/components/Popper/Popper.d.ts +27 -0
  15. package/.cache/ts/src/components/RichTooltip/RichTooltip.d.ts +46 -0
  16. package/.cache/ts/src/components/TextTooltip/TextTooltip.d.ts +49 -0
  17. package/.cache/ts/src/hoc/withAdaptivity.d.ts +1 -0
  18. package/.cache/ts/src/hooks/usePatchChildrenRef.d.ts +6 -0
  19. package/.cache/ts/src/index.d.ts +2 -1
  20. package/.cache/ts/src/unstable/index.d.ts +8 -0
  21. package/dist/cjs/components/ActionSheet/ActionSheet.js +21 -7
  22. package/dist/cjs/components/ActionSheet/ActionSheet.js.map +1 -1
  23. package/dist/cjs/components/ActionSheet/ActionSheetContext.d.ts +1 -1
  24. package/dist/cjs/components/ActionSheet/ActionSheetContext.js.map +1 -1
  25. package/dist/cjs/components/ActionSheet/ActionSheetDropdownDesktop.js +1 -3
  26. package/dist/cjs/components/ActionSheet/ActionSheetDropdownDesktop.js.map +1 -1
  27. package/dist/cjs/components/ActionSheetItem/ActionSheetItem.d.ts +7 -0
  28. package/dist/cjs/components/ActionSheetItem/ActionSheetItem.js +4 -3
  29. package/dist/cjs/components/ActionSheetItem/ActionSheetItem.js.map +1 -1
  30. package/dist/cjs/components/AdaptivityProvider/AdaptivityContext.d.ts +5 -0
  31. package/dist/cjs/components/AdaptivityProvider/AdaptivityContext.js +5 -1
  32. package/dist/cjs/components/AdaptivityProvider/AdaptivityContext.js.map +1 -1
  33. package/dist/cjs/components/AdaptivityProvider/AdaptivityProvider.js +10 -5
  34. package/dist/cjs/components/AdaptivityProvider/AdaptivityProvider.js.map +1 -1
  35. package/dist/cjs/components/AppRoot/AppRoot.js +3 -6
  36. package/dist/cjs/components/AppRoot/AppRoot.js.map +1 -1
  37. package/dist/cjs/components/AppRoot/AppRootContext.d.ts +1 -0
  38. package/dist/cjs/components/AppRoot/AppRootContext.js.map +1 -1
  39. package/dist/cjs/components/AppRoot/AppRootPortal.d.ts +1 -0
  40. package/dist/cjs/components/AppRoot/AppRootPortal.js +7 -3
  41. package/dist/cjs/components/AppRoot/AppRootPortal.js.map +1 -1
  42. package/dist/cjs/components/Cell/Cell.js +3 -1
  43. package/dist/cjs/components/Cell/Cell.js.map +1 -1
  44. package/dist/cjs/components/ClickPopper/ClickPopper.d.ts +21 -0
  45. package/dist/cjs/components/ClickPopper/ClickPopper.js +92 -0
  46. package/dist/cjs/components/ClickPopper/ClickPopper.js.map +1 -0
  47. package/dist/cjs/components/ConfigProvider/ConfigProviderContext.d.ts +8 -0
  48. package/dist/cjs/components/ConfigProvider/ConfigProviderContext.js.map +1 -1
  49. package/dist/cjs/components/Dropdown/Dropdown.d.ts +49 -0
  50. package/dist/cjs/components/Dropdown/Dropdown.js +56 -0
  51. package/dist/cjs/components/Dropdown/Dropdown.js.map +1 -0
  52. package/dist/cjs/components/Footer/Footer.d.ts +3 -3
  53. package/dist/cjs/components/Footer/Footer.js +2 -3
  54. package/dist/cjs/components/Footer/Footer.js.map +1 -1
  55. package/dist/cjs/components/HoverPopper/HoverPopper.d.ts +29 -0
  56. package/dist/cjs/components/HoverPopper/HoverPopper.js +97 -0
  57. package/dist/cjs/components/HoverPopper/HoverPopper.js.map +1 -0
  58. package/dist/cjs/components/Popper/Popper.d.ts +27 -0
  59. package/dist/cjs/components/Popper/Popper.js +153 -0
  60. package/dist/cjs/components/Popper/Popper.js.map +1 -0
  61. package/dist/cjs/components/RichTooltip/RichTooltip.d.ts +46 -0
  62. package/dist/cjs/components/RichTooltip/RichTooltip.js +47 -0
  63. package/dist/cjs/components/RichTooltip/RichTooltip.js.map +1 -0
  64. package/dist/cjs/components/Tappable/Tappable.js +6 -4
  65. package/dist/cjs/components/Tappable/Tappable.js.map +1 -1
  66. package/dist/cjs/components/TextTooltip/TextTooltip.d.ts +49 -0
  67. package/dist/cjs/components/TextTooltip/TextTooltip.js +57 -0
  68. package/dist/cjs/components/TextTooltip/TextTooltip.js.map +1 -0
  69. package/dist/cjs/hoc/withAdaptivity.d.ts +1 -0
  70. package/dist/cjs/hoc/withAdaptivity.js +5 -2
  71. package/dist/cjs/hoc/withAdaptivity.js.map +1 -1
  72. package/dist/cjs/hooks/usePatchChildrenRef.d.ts +6 -0
  73. package/dist/cjs/hooks/usePatchChildrenRef.js +38 -0
  74. package/dist/cjs/hooks/usePatchChildrenRef.js.map +1 -0
  75. package/dist/cjs/index.d.ts +2 -1
  76. package/dist/cjs/index.js +2 -2
  77. package/dist/cjs/index.js.map +1 -1
  78. package/dist/cjs/unstable/index.d.ts +8 -0
  79. package/dist/cjs/unstable/index.js +32 -0
  80. package/dist/cjs/unstable/index.js.map +1 -1
  81. package/dist/components/ActionSheet/ActionSheet.js +22 -8
  82. package/dist/components/ActionSheet/ActionSheet.js.map +1 -1
  83. package/dist/components/ActionSheet/ActionSheetContext.d.ts +1 -1
  84. package/dist/components/ActionSheet/ActionSheetContext.js.map +1 -1
  85. package/dist/components/ActionSheet/ActionSheetDropdownDesktop.js +1 -3
  86. package/dist/components/ActionSheet/ActionSheetDropdownDesktop.js.map +1 -1
  87. package/dist/components/ActionSheetItem/ActionSheetItem.d.ts +7 -0
  88. package/dist/components/ActionSheetItem/ActionSheetItem.js +4 -3
  89. package/dist/components/ActionSheetItem/ActionSheetItem.js.map +1 -1
  90. package/dist/components/AdaptivityProvider/AdaptivityContext.d.ts +5 -0
  91. package/dist/components/AdaptivityProvider/AdaptivityContext.js +4 -1
  92. package/dist/components/AdaptivityProvider/AdaptivityContext.js.map +1 -1
  93. package/dist/components/AdaptivityProvider/AdaptivityProvider.js +11 -6
  94. package/dist/components/AdaptivityProvider/AdaptivityProvider.js.map +1 -1
  95. package/dist/components/AppRoot/AppRoot.js +3 -6
  96. package/dist/components/AppRoot/AppRoot.js.map +1 -1
  97. package/dist/components/AppRoot/AppRootContext.d.ts +1 -0
  98. package/dist/components/AppRoot/AppRootContext.js.map +1 -1
  99. package/dist/components/AppRoot/AppRootPortal.d.ts +1 -0
  100. package/dist/components/AppRoot/AppRootPortal.js +7 -3
  101. package/dist/components/AppRoot/AppRootPortal.js.map +1 -1
  102. package/dist/components/Cell/Cell.js +3 -1
  103. package/dist/components/Cell/Cell.js.map +1 -1
  104. package/dist/components/ClickPopper/ClickPopper.d.ts +21 -0
  105. package/dist/components/ClickPopper/ClickPopper.js +67 -0
  106. package/dist/components/ClickPopper/ClickPopper.js.map +1 -0
  107. package/dist/components/ConfigProvider/ConfigProviderContext.d.ts +8 -0
  108. package/dist/components/ConfigProvider/ConfigProviderContext.js.map +1 -1
  109. package/dist/components/Dropdown/Dropdown.d.ts +49 -0
  110. package/dist/components/Dropdown/Dropdown.js +38 -0
  111. package/dist/components/Dropdown/Dropdown.js.map +1 -0
  112. package/dist/components/Footer/Footer.d.ts +3 -3
  113. package/dist/components/Footer/Footer.js +1 -4
  114. package/dist/components/Footer/Footer.js.map +1 -1
  115. package/dist/components/HoverPopper/HoverPopper.d.ts +29 -0
  116. package/dist/components/HoverPopper/HoverPopper.js +73 -0
  117. package/dist/components/HoverPopper/HoverPopper.js.map +1 -0
  118. package/dist/components/Popper/Popper.d.ts +27 -0
  119. package/dist/components/Popper/Popper.js +127 -0
  120. package/dist/components/Popper/Popper.js.map +1 -0
  121. package/dist/components/RichTooltip/RichTooltip.d.ts +46 -0
  122. package/dist/components/RichTooltip/RichTooltip.js +26 -0
  123. package/dist/components/RichTooltip/RichTooltip.js.map +1 -0
  124. package/dist/components/Tappable/Tappable.js +7 -5
  125. package/dist/components/Tappable/Tappable.js.map +1 -1
  126. package/dist/components/TextTooltip/TextTooltip.d.ts +49 -0
  127. package/dist/components/TextTooltip/TextTooltip.js +34 -0
  128. package/dist/components/TextTooltip/TextTooltip.js.map +1 -0
  129. package/dist/components.css +1 -1
  130. package/dist/components.css.map +1 -1
  131. package/dist/cssm/components/ActionSheet/ActionSheet.js +22 -8
  132. package/dist/cssm/components/ActionSheet/ActionSheet.js.map +1 -1
  133. package/dist/cssm/components/ActionSheet/ActionSheetContext.js.map +1 -1
  134. package/dist/cssm/components/ActionSheet/ActionSheetDropdownDesktop.js +1 -3
  135. package/dist/cssm/components/ActionSheet/ActionSheetDropdownDesktop.js.map +1 -1
  136. package/dist/cssm/components/ActionSheetItem/ActionSheetItem.js +4 -3
  137. package/dist/cssm/components/ActionSheetItem/ActionSheetItem.js.map +1 -1
  138. package/dist/cssm/components/AdaptivityProvider/AdaptivityContext.js +4 -1
  139. package/dist/cssm/components/AdaptivityProvider/AdaptivityContext.js.map +1 -1
  140. package/dist/cssm/components/AdaptivityProvider/AdaptivityProvider.js +11 -6
  141. package/dist/cssm/components/AdaptivityProvider/AdaptivityProvider.js.map +1 -1
  142. package/dist/cssm/components/AppRoot/AppRoot.js +3 -6
  143. package/dist/cssm/components/AppRoot/AppRoot.js.map +1 -1
  144. package/dist/cssm/components/AppRoot/AppRootContext.js.map +1 -1
  145. package/dist/cssm/components/AppRoot/AppRootPortal.js +7 -3
  146. package/dist/cssm/components/AppRoot/AppRootPortal.js.map +1 -1
  147. package/dist/cssm/components/Cell/Cell.js +3 -1
  148. package/dist/cssm/components/Cell/Cell.js.map +1 -1
  149. package/dist/cssm/components/ClickPopper/ClickPopper.js +67 -0
  150. package/dist/cssm/components/ClickPopper/ClickPopper.js.map +1 -0
  151. package/dist/cssm/components/ConfigProvider/ConfigProviderContext.js.map +1 -1
  152. package/dist/cssm/components/Dropdown/Dropdown.css +1 -0
  153. package/dist/cssm/components/Dropdown/Dropdown.js +41 -0
  154. package/dist/cssm/components/Dropdown/Dropdown.js.map +1 -0
  155. package/dist/cssm/components/Footer/Footer.js +1 -4
  156. package/dist/cssm/components/Footer/Footer.js.map +1 -1
  157. package/dist/cssm/components/HoverPopper/HoverPopper.js +73 -0
  158. package/dist/cssm/components/HoverPopper/HoverPopper.js.map +1 -0
  159. package/dist/cssm/components/Popper/Popper.css +1 -0
  160. package/dist/cssm/components/Popper/Popper.js +128 -0
  161. package/dist/cssm/components/Popper/Popper.js.map +1 -0
  162. package/dist/cssm/components/RichTooltip/RichTooltip.css +1 -0
  163. package/dist/cssm/components/RichTooltip/RichTooltip.js +29 -0
  164. package/dist/cssm/components/RichTooltip/RichTooltip.js.map +1 -0
  165. package/dist/cssm/components/Tappable/Tappable.js +7 -5
  166. package/dist/cssm/components/Tappable/Tappable.js.map +1 -1
  167. package/dist/cssm/components/TextTooltip/TextTooltip.css +1 -0
  168. package/dist/cssm/components/TextTooltip/TextTooltip.js +37 -0
  169. package/dist/cssm/components/TextTooltip/TextTooltip.js.map +1 -0
  170. package/dist/cssm/hoc/withAdaptivity.js +5 -2
  171. package/dist/cssm/hoc/withAdaptivity.js.map +1 -1
  172. package/dist/cssm/hooks/usePatchChildrenRef.js +21 -0
  173. package/dist/cssm/hooks/usePatchChildrenRef.js.map +1 -0
  174. package/dist/cssm/index.js +1 -1
  175. package/dist/cssm/index.js.map +1 -1
  176. package/dist/cssm/styles/animations.css +1 -1
  177. package/dist/cssm/styles/common.css +1 -1
  178. package/dist/cssm/styles/components.css +1 -1
  179. package/dist/cssm/styles/unstable.css +1 -1
  180. package/dist/cssm/unstable/index.js +4 -0
  181. package/dist/cssm/unstable/index.js.map +1 -1
  182. package/dist/hoc/withAdaptivity.d.ts +1 -0
  183. package/dist/hoc/withAdaptivity.js +5 -2
  184. package/dist/hoc/withAdaptivity.js.map +1 -1
  185. package/dist/hooks/usePatchChildrenRef.d.ts +6 -0
  186. package/dist/hooks/usePatchChildrenRef.js +21 -0
  187. package/dist/hooks/usePatchChildrenRef.js.map +1 -0
  188. package/dist/index.d.ts +2 -1
  189. package/dist/index.js +1 -1
  190. package/dist/index.js.map +1 -1
  191. package/dist/unstable/index.d.ts +8 -0
  192. package/dist/unstable/index.js +4 -0
  193. package/dist/unstable/index.js.map +1 -1
  194. package/dist/unstable.css +1 -1
  195. package/dist/unstable.css.map +1 -1
  196. package/dist/vkui.css +1 -1
  197. package/dist/vkui.css.map +1 -1
  198. package/package.json +2 -2
  199. package/src/components/ActionSheet/ActionSheet.tsx +16 -9
  200. package/src/components/ActionSheet/ActionSheetContext.ts +1 -1
  201. package/src/components/ActionSheet/ActionSheetDropdownDesktop.tsx +1 -3
  202. package/src/components/ActionSheetItem/ActionSheetItem.tsx +10 -2
  203. package/src/components/AdaptivityProvider/AdaptivityContext.tsx +8 -0
  204. package/src/components/AdaptivityProvider/AdaptivityProvider.tsx +8 -6
  205. package/src/components/AdaptivityProvider/Readme.md +3 -3
  206. package/src/components/AppRoot/AppRoot.tsx +4 -5
  207. package/src/components/AppRoot/AppRootContext.ts +1 -0
  208. package/src/components/AppRoot/AppRootPortal.tsx +5 -3
  209. package/src/components/Cell/Cell.tsx +2 -1
  210. package/src/components/ChipsSelect/Readme.md +1 -1
  211. package/src/components/ClickPopper/ClickPopper.tsx +82 -0
  212. package/src/components/ConfigProvider/ConfigProviderContext.tsx +8 -0
  213. package/src/components/Dropdown/Dropdown.css +19 -0
  214. package/src/components/Dropdown/Dropdown.tsx +74 -0
  215. package/src/components/Dropdown/Readme.md +39 -0
  216. package/src/components/Footer/Footer.tsx +6 -4
  217. package/src/components/HoverPopper/HoverPopper.tsx +100 -0
  218. package/src/components/PanelHeader/Readme.md +4 -0
  219. package/src/components/Popper/Popper.css +39 -0
  220. package/src/components/Popper/Popper.tsx +147 -0
  221. package/src/components/Popper/Readme.md +23 -0
  222. package/src/components/RichTooltip/Readme.md +55 -0
  223. package/src/components/RichTooltip/RichTooltip.css +10 -0
  224. package/src/components/RichTooltip/RichTooltip.tsx +70 -0
  225. package/src/components/Tappable/Tappable.tsx +5 -4
  226. package/src/components/TextTooltip/Readme.md +7 -0
  227. package/src/components/TextTooltip/TextTooltip.css +12 -0
  228. package/src/components/TextTooltip/TextTooltip.tsx +76 -0
  229. package/src/components/Tooltip/Readme.md +2 -0
  230. package/src/hoc/withAdaptivity.tsx +5 -1
  231. package/src/hooks/usePatchChildrenRef.ts +24 -0
  232. package/src/index.ts +2 -1
  233. package/src/styles/animations.css +5 -0
  234. package/src/styles/common.css +7 -2
  235. package/src/styles/unstable.css +4 -0
  236. package/src/unstable/index.ts +12 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vkontakte/vkui",
3
- "version": "4.22.2",
3
+ "version": "4.23.0",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -83,7 +83,7 @@
83
83
  "pre-commit": "^1.2.2",
84
84
  "prop-types": "^15.6.2",
85
85
  "react": "^16.8.6",
86
- "react-docgen": "^5.4.0-alpha.0",
86
+ "react-docgen-typescript": "^2.1.1",
87
87
  "react-dom": "^16.8.6",
88
88
  "react-frame-component": "^3.0.0",
89
89
  "react-styleguidist": "^11.1.5",
@@ -4,7 +4,7 @@ import { ViewWidth, ViewHeight } from '../../hoc/withAdaptivity';
4
4
  import { IOS } from '../../lib/platform';
5
5
  import { ActionSheetDropdownDesktop } from './ActionSheetDropdownDesktop';
6
6
  import { ActionSheetDropdown } from './ActionSheetDropdown';
7
- import { hasReactNode } from '../../lib/utils';
7
+ import { hasReactNode, noop } from '../../lib/utils';
8
8
  import { ActionSheetContext, ItemClickHandler } from './ActionSheetContext';
9
9
  import Caption from '../Typography/Caption/Caption';
10
10
  import { usePlatform } from '../../hooks/usePlatform';
@@ -52,9 +52,12 @@ export const ActionSheet: React.FC<ActionSheetProps> = ({
52
52
  const platform = usePlatform();
53
53
  const [closing, setClosing] = React.useState(false);
54
54
  const onClose = () => setClosing(true);
55
+ const _action = React.useRef(noop);
55
56
 
56
57
  const afterClose = () => {
57
58
  restProps.onClose();
59
+ _action.current();
60
+ _action.current = noop;
58
61
  };
59
62
 
60
63
  if (process.env.NODE_ENV === 'development' && !restProps.onClose) {
@@ -64,25 +67,29 @@ export const ActionSheet: React.FC<ActionSheetProps> = ({
64
67
  const { viewWidth, viewHeight, hasMouse } = useAdaptivity();
65
68
  const isDesktop = viewWidth >= ViewWidth.SMALL_TABLET && (hasMouse || viewHeight >= ViewHeight.MEDIUM);
66
69
 
67
- const timeout = platform === IOS ? 300 : 200;
70
+ let timeout = platform === IOS ? 300 : 200;
71
+
72
+ if (isDesktop) {
73
+ timeout = 0;
74
+ }
68
75
 
69
76
  const fallbackTransitionFinish = useTimeout(afterClose, timeout);
70
77
  React.useEffect(() => {
71
78
  if (closing) {
72
- if (isDesktop) {
73
- afterClose();
74
- } else {
75
- fallbackTransitionFinish.set();
76
- }
79
+ fallbackTransitionFinish.set();
77
80
  } else {
78
81
  fallbackTransitionFinish.clear();
79
82
  }
80
83
  }, [closing]);
81
84
 
82
- const onItemClick = React.useCallback<ItemClickHandler>((action, autoclose) => (event) => {
83
- action && action(event);
85
+ const onItemClick = React.useCallback<ItemClickHandler>((action, immediateAction, autoclose) => (event) => {
86
+ event.persist();
87
+ immediateAction && immediateAction(event);
84
88
  if (autoclose) {
89
+ _action.current = () => action && action(event);
85
90
  setClosing(true);
91
+ } else {
92
+ action && action(event);
86
93
  }
87
94
  }, []);
88
95
  const contextValue = useObjectMemo({ onItemClick, isDesktop });
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
 
3
3
  export type ActionType = (event: React.MouseEvent) => void;
4
4
 
5
- export type ItemClickHandler = (action: ActionType, autoclose: boolean) => (event: React.MouseEvent) => void;
5
+ export type ItemClickHandler = (action: ActionType, immediateAction: ActionType, autoclose: boolean) => (event: React.MouseEvent) => void;
6
6
 
7
7
  export const ActionSheetContext = React.createContext<{
8
8
  onItemClick?: ItemClickHandler;
@@ -76,9 +76,7 @@ export const ActionSheetDropdownDesktop: React.FC<SharedDropdownProps> = ({
76
76
  getRootRef={elementRef}
77
77
  onClick={onClick}
78
78
  style={dropdownStyles}
79
- vkuiClass={classNames(getClassName('ActionSheet', platform), 'ActionSheet--desktop', {
80
- 'ActionSheet--closing': closing,
81
- }, `ActionSheet--sizeY-${sizeY}`)}
79
+ vkuiClass={classNames(getClassName('ActionSheet', platform), 'ActionSheet--desktop', `ActionSheet--sizeY-${sizeY}`)}
82
80
  >
83
81
  {children}
84
82
  </FocusTrap>
@@ -26,6 +26,13 @@ export interface ActionSheetItemProps extends
26
26
  autoclose?: boolean;
27
27
  selectable?: boolean;
28
28
  disabled?: boolean;
29
+ /**
30
+ * Если autoclose === true, onClick будет вызван после завершения анимации скрытия и после вызова onClose.
31
+ * Из этого следует, что в объекте события значения полей типа `currentTarget` будут не определены.
32
+ * Если вам нужен объект события именно на момент клика, используйте `onImmediateClick`.
33
+ */
34
+ onClick?: React.MouseEventHandler<HTMLElement>;
35
+ onImmediateClick?: React.MouseEventHandler<HTMLElement>;
29
36
  }
30
37
 
31
38
  const ActionSheetItem: React.FC<ActionSheetItemProps> = ({
@@ -43,6 +50,7 @@ const ActionSheetItem: React.FC<ActionSheetItemProps> = ({
43
50
  onChange,
44
51
  onClick,
45
52
  sizeY,
53
+ onImmediateClick,
46
54
  ...restProps
47
55
  }: ActionSheetItemProps) => {
48
56
  const platform = usePlatform();
@@ -59,7 +67,7 @@ const ActionSheetItem: React.FC<ActionSheetItemProps> = ({
59
67
  return (
60
68
  <Tappable
61
69
  {...restProps}
62
- onClick={selectable ? onClick : onItemClick(onClick, autoclose)}
70
+ onClick={selectable ? onClick : onItemClick(onClick, onImmediateClick, autoclose)}
63
71
  activeMode="ActionSheetItem--active"
64
72
  vkuiClass={
65
73
  classNames(
@@ -130,7 +138,7 @@ const ActionSheetItem: React.FC<ActionSheetItemProps> = ({
130
138
  name={name}
131
139
  value={value}
132
140
  onChange={onChange}
133
- onClick={onItemClick(noop, autoclose)}
141
+ onClick={onItemClick(noop, noop, autoclose)}
134
142
  defaultChecked={defaultChecked}
135
143
  checked={checked}
136
144
  disabled={restProps.disabled}
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import { hasHover, hasMouse } from '@vkontakte/vkjs';
2
3
 
3
4
  export enum SizeType {
4
5
  COMPACT = 'compact',
@@ -37,15 +38,22 @@ export interface AdaptivityProps extends SizeProps {
37
38
  * @ignore
38
39
  */
39
40
  hasMouse?: boolean;
41
+ /**
42
+ * @ignore
43
+ */
44
+ deviceHasHover?: boolean;
40
45
  }
41
46
 
42
47
  export interface AdaptivityContextInterface extends SizeProps {
43
48
  viewWidth?: ViewWidth;
44
49
  viewHeight?: ViewHeight;
45
50
  hasMouse?: boolean;
51
+ deviceHasHover?: boolean;
46
52
  }
47
53
 
48
54
  export const AdaptivityContext = React.createContext<AdaptivityContextInterface>({
49
55
  sizeX: SizeType.COMPACT,
50
56
  sizeY: SizeType.REGULAR,
57
+ hasMouse,
58
+ deviceHasHover: hasHover,
51
59
  });
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { hasMouse as _hasMouse } from '@vkontakte/vkjs';
2
+ import { hasMouse as _hasMouse, hasHover as _hasHover } from '@vkontakte/vkjs';
3
3
  import { AdaptivityContext, AdaptivityContextInterface, SizeType, ViewHeight, ViewWidth } from './AdaptivityContext';
4
4
  import { useDOM } from '../../lib/dom';
5
5
 
@@ -32,14 +32,15 @@ export default function AdaptivityProvider(props: AdaptivityProviderProps) {
32
32
  React.useEffect(() => {
33
33
  function onResize() {
34
34
  const calculated = calculateAdaptivity(window.innerWidth, window.innerHeight, props);
35
- const { viewWidth, viewHeight, sizeX, sizeY, hasMouse } = adaptivityRef.current;
35
+ const { viewWidth, viewHeight, sizeX, sizeY, hasMouse, deviceHasHover } = adaptivityRef.current;
36
36
 
37
37
  if (
38
38
  viewWidth !== calculated.viewWidth ||
39
39
  viewHeight !== calculated.viewHeight ||
40
40
  sizeX !== calculated.sizeX ||
41
41
  sizeY !== calculated.sizeY ||
42
- hasMouse !== calculated.hasMouse
42
+ hasMouse !== calculated.hasMouse ||
43
+ deviceHasHover !== calculated.deviceHasHover
43
44
  ) {
44
45
  adaptivityRef.current = calculated;
45
46
  updateAdaptivity({});
@@ -52,7 +53,7 @@ export default function AdaptivityProvider(props: AdaptivityProviderProps) {
52
53
  return () => {
53
54
  window.removeEventListener('resize', onResize, false);
54
55
  };
55
- }, [props.viewWidth, props.viewHeight, props.sizeX, props.sizeY, props.hasMouse]);
56
+ }, [props.viewWidth, props.viewHeight, props.sizeX, props.sizeY, props.hasMouse, props.deviceHasHover]);
56
57
 
57
58
  return (
58
59
  <AdaptivityContext.Provider value={adaptivityRef.current}>
@@ -66,7 +67,8 @@ function calculateAdaptivity(windowWidth: number, windowHeight: number, props: A
66
67
  let viewHeight = ViewHeight.SMALL;
67
68
  let sizeY = SizeType.REGULAR;
68
69
  let sizeX = SizeType.REGULAR;
69
- let hasMouse = typeof props.hasMouse === 'boolean' ? props.hasMouse : _hasMouse;
70
+ let hasMouse = props.hasMouse ?? _hasMouse;
71
+ let deviceHasHover = props.deviceHasHover ?? _hasHover;
70
72
 
71
73
  if (windowWidth >= DESKTOP_SIZE) {
72
74
  viewWidth = ViewWidth.DESKTOP;
@@ -102,5 +104,5 @@ function calculateAdaptivity(windowWidth: number, windowHeight: number, props: A
102
104
  props.sizeX && (sizeX = props.sizeX);
103
105
  props.sizeY && (sizeY = props.sizeY);
104
106
 
105
- return { viewWidth, viewHeight, sizeX, sizeY, hasMouse };
107
+ return { viewWidth, viewHeight, sizeX, sizeY, hasMouse, deviceHasHover };
106
108
  }
@@ -1,3 +1,3 @@
1
- Компонент, прокидывающий вниз данные об [адаптивности](#!/Adaptivity). Изначально, рассчитывает `sizeX`, `sizeY`,
2
- `viewWidth` и `viewHeight` самостоятельно, основываясь на `window`. Все эти 4 сущности можно переопределить, передав их в
3
- качестве свойств.
1
+ Компонент, прокидывающий вниз данные об [адаптивности](#!/Adaptivity). Все параметры, которые можно прокинуть через
2
+ props, компонент по умолчанию вычисляет самостоятельно. Передавать их с помощью props стоит в тех случаях, когда
3
+ вы точно уверены, что ваш сайт, например, будет открываться только на мобильных устройствах.
@@ -61,15 +61,13 @@ export const AppRoot: React.FC<AppRootProps> = withAdaptivity(({
61
61
 
62
62
  // setup portal
63
63
  useIsomorphicLayoutEffect(() => {
64
- if (mode === 'full') {
65
- return noop;
66
- }
67
-
68
64
  const portal = document.createElement('div');
69
65
  portal.classList.add('vkui__portal-root');
70
66
  document.body.appendChild(portal);
71
67
  setPortalRoot(portal);
72
- return () => portal.parentElement.removeChild(portal);
68
+ return () => {
69
+ portal.parentElement.removeChild(portal);
70
+ };
73
71
  }, []);
74
72
 
75
73
  // setup root classes
@@ -136,6 +134,7 @@ export const AppRoot: React.FC<AppRootProps> = withAdaptivity(({
136
134
  portalRoot: portalRoot,
137
135
  embedded: mode === 'embedded',
138
136
  keyboardInput: isKeyboardInputActive,
137
+ mode,
139
138
  }}>
140
139
  <ScrollContext.Provider value={scrollController}>
141
140
  <IconSettingsProvider classPrefix="vkui" globalClasses={!noLegacyClasses}>
@@ -4,6 +4,7 @@ export interface AppRootContextInterface {
4
4
  appRoot?: React.RefObject<HTMLDivElement>;
5
5
  portalRoot?: HTMLDivElement;
6
6
  embedded?: boolean;
7
+ mode?: 'partial' | 'embedded' | 'full';
7
8
  keyboardInput?: boolean;
8
9
  }
9
10
 
@@ -2,9 +2,11 @@ import * as React from 'react';
2
2
  import { createPortal } from 'react-dom';
3
3
  import { AppRootContext } from './AppRootContext';
4
4
 
5
- export const AppRootPortal: React.FC<React.PropsWithChildren<{ className?: string }>> = ({ children, className }) => {
6
- const { portalRoot, embedded } = React.useContext(AppRootContext);
7
- return embedded && portalRoot
5
+ export const AppRootPortal: React.FC<React.PropsWithChildren<{ className?: string; forcePortal?: boolean }>> = ({ children, className, forcePortal }) => {
6
+ const { portalRoot, mode } = React.useContext(AppRootContext);
7
+
8
+ forcePortal = forcePortal ?? mode !== 'full';
9
+ return portalRoot && forcePortal
8
10
  ? createPortal((<div className={className}>{children}</div>), portalRoot)
9
11
  : <React.Fragment>{children}</React.Fragment>;
10
12
  };
@@ -67,6 +67,7 @@ export const Cell: React.FC<CellProps> = ({
67
67
  Component,
68
68
  onChange,
69
69
  name,
70
+ value,
70
71
  checked,
71
72
  defaultChecked,
72
73
  getRootRef,
@@ -113,7 +114,7 @@ export const Cell: React.FC<CellProps> = ({
113
114
 
114
115
  let checkbox;
115
116
  if (selectable) {
116
- const checkboxProps: CellCheckboxProps = { name, onChange, defaultChecked, checked, disabled };
117
+ const checkboxProps: CellCheckboxProps = { name, value, onChange, defaultChecked, checked, disabled };
117
118
  checkbox = <CellCheckbox vkuiClass="Cell__checkbox" {...checkboxProps} />;
118
119
  }
119
120
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  >**Важно**
8
8
  >
9
- >Это нестабильный компонент. Его API может меняться в рамках одной мажорной версии. [Подробнее про нестабильный компоненты](#/Unstable).
9
+ >Это нестабильный компонент. Его API может меняться в рамках одной мажорной версии. [Подробнее про нестабильные компоненты](#/Unstable).
10
10
 
11
11
  ```jsx
12
12
  const colors = [{value: 'red', label: 'Красный'}, {value: 'blue', label: 'Синий'}, {value: 'navarin', label: 'Наваринского пламени с дымом',}];
@@ -0,0 +1,82 @@
1
+ import * as React from 'react';
2
+ import { useDOM } from '../../lib/dom';
3
+ import { Popper, PopperCommonProps } from '../Popper/Popper';
4
+ import { useExternRef } from '../../hooks/useExternRef';
5
+ import { useEventListener } from '../../hooks/useEventListener';
6
+ import { useGlobalEventListener } from '../../hooks/useGlobalEventListener';
7
+ import { usePatchChildrenRef } from '../../hooks/usePatchChildrenRef';
8
+
9
+ export interface ClickPopperProps extends PopperCommonProps {
10
+ /**
11
+ * Содержимое `ClickPopper`
12
+ */
13
+ content?: React.ReactNode;
14
+ /**
15
+ * Если передан, то тултип будет показыван/скрыт в зависимости от значения свойства
16
+ */
17
+ shown?: boolean;
18
+ /**
19
+ * Вызывается при каждом изменении видимости тултипа
20
+ */
21
+ onShownChange?: (shown: boolean) => void;
22
+ /**
23
+ * Либо jsx-элемент (div, button, etc.), либо компонент со свойством `getRootRef`, которое применяется к корневому элемнету компонента
24
+ */
25
+ children?: React.ReactElement;
26
+ }
27
+
28
+ export const ClickPopper: React.FC<ClickPopperProps> = ({
29
+ getRef,
30
+ content,
31
+ children,
32
+ onShownChange,
33
+ shown: _shown,
34
+ ...restProps
35
+ }: ClickPopperProps) => {
36
+ const [computedShown, setComputedShown] = React.useState(_shown || false);
37
+ const [dropdownNode, setPopperNode] = React.useState(null);
38
+
39
+ const shown = typeof _shown === 'boolean' ? _shown : computedShown;
40
+
41
+ const { document } = useDOM();
42
+
43
+ const patchedPopperRef = useExternRef(setPopperNode, getRef);
44
+
45
+ const [childRef, child] = usePatchChildrenRef(children);
46
+
47
+ const setShown = (value: boolean) => {
48
+ if (typeof _shown !== 'boolean') {
49
+ setComputedShown(value);
50
+ }
51
+ typeof onShownChange === 'function' && onShownChange(value);
52
+ };
53
+
54
+ useGlobalEventListener(document, 'click', (e: MouseEvent) => {
55
+ if (dropdownNode && !childRef.current.contains(e.target as Node) && !dropdownNode.contains(e.target)) {
56
+ setShown(false);
57
+ }
58
+ });
59
+
60
+ const targetClickEvent = useEventListener('click', () => {
61
+ setShown(!shown);
62
+ });
63
+
64
+ React.useEffect(() => {
65
+ targetClickEvent.add(childRef.current);
66
+ }, []);
67
+
68
+ return (
69
+ <React.Fragment>
70
+ {child}
71
+ {shown &&
72
+ <Popper
73
+ {...restProps}
74
+ targetRef={childRef}
75
+ getRef={patchedPopperRef}
76
+ >
77
+ {content}
78
+ </Popper>
79
+ }
80
+ </React.Fragment>
81
+ );
82
+ };
@@ -8,7 +8,15 @@ export enum Appearance {
8
8
  }
9
9
 
10
10
  export enum Scheme {
11
+ /**
12
+ * @deprecated будет удалено в 5.0.0
13
+ * версия оставлена для совместимости со старыми версиями клиентов
14
+ */
11
15
  DEPRECATED_CLIENT_LIGHT = 'client_light',
16
+ /**
17
+ * @deprecated будет удалено в 5.0.0
18
+ * версия оставлена для совместимости со старыми версиями клиентов
19
+ */
12
20
  DEPRECATED_CLIENT_DARK = 'client_dark',
13
21
  /**
14
22
  * @deprecated будет удалено в 5.0.0
@@ -0,0 +1,19 @@
1
+ .Dropdown {
2
+ animation: vkui-popper-fadein .2s ease;
3
+ background: var(--background_content);
4
+ }
5
+
6
+ .Dropdown--ios {
7
+ box-shadow: 0 0 96px rgba(0, 0, 0, .16), 0 0 2px rgba(0, 0, 0, .12);
8
+ border-radius: 14px;
9
+ }
10
+
11
+ .Dropdown--android {
12
+ box-shadow: 0 0 4px rgba(0, 0, 0, .08), 0 8px 8px rgba(0, 0, 0, .16);
13
+ border-radius: 12px;
14
+ }
15
+
16
+ .Dropdown--vkcom {
17
+ box-shadow: 0 0 2px rgba(0, 0, 0, .08), 0 8px 24px rgba(0, 0, 0, .08);
18
+ border-radius: 12px;
19
+ }
@@ -0,0 +1,74 @@
1
+ import * as React from 'react';
2
+ import { HoverPopper, HoverPopperProps } from '../HoverPopper/HoverPopper';
3
+ import { ClickPopper } from '../ClickPopper/ClickPopper';
4
+ import { getClassName } from '../../helpers/getClassName';
5
+ import { usePlatform } from '../../hooks/usePlatform';
6
+ import { Placement } from '../Popper/Popper';
7
+ import './Dropdown.css';
8
+
9
+ // Приходится избегать экстендов от HoverPopperProps, ClickPopperProps и PopperProps, потому что react-docgen не умеет в Omit.
10
+ // Ждём либо фикса react-docgen (что вряд ли), либо переезда на react-docgen-typescript, где такой проблемы нет.
11
+ export interface DropdownProps {
12
+ /**
13
+ * По умолчанию компонент выберет наилучшее расположение сам. Но его можно задать извне с помощью этого свойства
14
+ */
15
+ placement?: Placement;
16
+ /**
17
+ * Отступ по вспомогательной оси
18
+ */
19
+ offsetSkidding?: number;
20
+ /**
21
+ * Отступ по главной оси
22
+ */
23
+ offsetDistance?: number;
24
+ onPlacementChange?: (data: { placement?: Placement }) => void;
25
+ /**
26
+ * Содержимое тултипа
27
+ */
28
+ content?: React.ReactNode;
29
+ /**
30
+ * Если передан, то тултип будет показыван/скрыт в зависимости от значения свойства
31
+ */
32
+ shown?: boolean;
33
+ /**
34
+ * Вызывается при каждом изменении видимости тултипа
35
+ */
36
+ onShownChange?: (shown: boolean) => void;
37
+ /**
38
+ * Либо jsx-элемент (div, button, etc.), либо компонент со свойством `getRootRef`, которое применяется к корневому элементу компонента
39
+ */
40
+ children?: React.ReactElement;
41
+
42
+ action?: 'click' | 'hover';
43
+ /**
44
+ * Актуально только для action="hover"
45
+ * Количество миллисекунд, после которых произойдет показ дропдауна
46
+ */
47
+ showDelay?: HoverPopperProps['showDelay'];
48
+ /**
49
+ * Актуально только для action="hover"
50
+ * Количество миллисекунд, после которых произойдет скрытие дропдауна
51
+ */
52
+ hideDelay?: HoverPopperProps['hideDelay'];
53
+ }
54
+
55
+ export const Dropdown: React.FC<DropdownProps> = ({ action = 'click', hideDelay, showDelay, ...popperProps }: DropdownProps) => {
56
+ const platform = usePlatform();
57
+
58
+ let Component;
59
+ let actionSpecificProps: Partial<DropdownProps> = {};
60
+
61
+ switch (action) {
62
+ case 'click':
63
+ Component = ClickPopper;
64
+ break;
65
+ case 'hover':
66
+ actionSpecificProps = { hideDelay, showDelay };
67
+ Component = HoverPopper;
68
+ break;
69
+ }
70
+
71
+ return (
72
+ <Component vkuiClass={getClassName('Dropdown', platform)} {...actionSpecificProps} {...popperProps} />
73
+ );
74
+ };
@@ -0,0 +1,39 @@
1
+ Может открываться при клике или наведении мыши на `children`. Ограничений по содержимому нет. Предназначен для
2
+ отрисовки части интерфейса в выпадающем окне.
3
+
4
+ ```jsx { "props": { "layout": false, "iframe": true } }
5
+ const [shown, setShown] = React.useState(true);
6
+
7
+ return (
8
+ <React.Fragment>
9
+ <Dropdown action="hover" placement="right" content={<Div><Text>Привет</Text></Div>}>
10
+ <Button style={{ margin: 20 }}>Наведи</Button>
11
+ </Dropdown>
12
+
13
+ <Dropdown
14
+ shown={shown}
15
+ onShownChange={setShown}
16
+ content={
17
+ <FormLayout>
18
+ <FormItem top="Имя">
19
+ <Input />
20
+ </FormItem>
21
+ <FormItem top="Фамилия">
22
+ <Input />
23
+ </FormItem>
24
+ <FormItem top="Соглашение">
25
+ <Checkbox name="agreement">Согласен</Checkbox>
26
+ </FormItem>
27
+ <FormItem>
28
+ <Button onClick={() => setShown(false)}>Отправить</Button>
29
+ </FormItem>
30
+ </FormLayout>
31
+ }
32
+ >
33
+ <Button style={{ margin: '20px 0 0 0' }}>
34
+ Кликни
35
+ </Button>
36
+ </Dropdown>
37
+ </React.Fragment>
38
+ )
39
+ ```
@@ -1,15 +1,17 @@
1
1
  import * as React from 'react';
2
+ import { HasComponent } from '../../types';
2
3
  import Caption from '../Typography/Caption/Caption';
3
4
  import './Footer.css';
4
5
 
5
- type FooterProps = React.AllHTMLAttributes<HTMLElement>;
6
+ export type FooterProps = React.AllHTMLAttributes<HTMLElement> & HasComponent;
6
7
 
7
- const Footer: React.FC<FooterProps> = ({ children, ...restProps }: FooterProps) => {
8
+ export const Footer: React.FC<FooterProps> = ({
9
+ children,
10
+ ...restProps
11
+ }: FooterProps) => {
8
12
  return (
9
13
  <Caption Component="footer" {...restProps} level="1" weight="regular" vkuiClass="Footer">
10
14
  {children}
11
15
  </Caption>
12
16
  );
13
17
  };
14
-
15
- export default Footer;
@@ -0,0 +1,100 @@
1
+ import * as React from 'react';
2
+ import { Popper, PopperCommonProps } from '../Popper/Popper';
3
+ import { useEventListener } from '../../hooks/useEventListener';
4
+ import { useTimeout } from '../../hooks/useTimeout';
5
+ import { usePatchChildrenRef } from '../../hooks/usePatchChildrenRef';
6
+ import { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';
7
+
8
+ export interface HoverPopperProps extends PopperCommonProps {
9
+ /**
10
+ * Содержимое тултипа
11
+ */
12
+ content?: React.ReactNode;
13
+ /**
14
+ * Если передан, то тултип будет показыван/скрыт в зависимости от значения свойства
15
+ */
16
+ shown?: boolean;
17
+ /**
18
+ * Вызывается при каждом изменении видимости тултипа
19
+ */
20
+ onShownChange?: (shown: boolean) => void;
21
+ /**
22
+ * Количество миллисекунд, после которых произойдет показ дропдауна
23
+ */
24
+ showDelay?: number;
25
+ /**
26
+ * Количество миллисекунд, после которых произойдет скрытие дропдауна
27
+ */
28
+ hideDelay?: number;
29
+ /**
30
+ * Либо jsx-элемент (div, button, etc.), либо компонент со свойством `getRootRef`, которое применяется к корневому элементу компонента
31
+ */
32
+ children?: React.ReactElement;
33
+ }
34
+
35
+ export const HoverPopper: React.FC<HoverPopperProps> = ({
36
+ getRef,
37
+ content,
38
+ children,
39
+ onShownChange,
40
+ shown: _shown,
41
+ showDelay,
42
+ hideDelay = 150,
43
+ ...restProps
44
+ }: HoverPopperProps) => {
45
+ const [computedShown, setComputedShown] = React.useState(_shown || false);
46
+
47
+ const shown = typeof _shown === 'boolean' ? _shown : computedShown;
48
+
49
+ const setShown = (value: boolean) => {
50
+ if (typeof _shown !== 'boolean') {
51
+ setComputedShown(value);
52
+ }
53
+ typeof onShownChange === 'function' && onShownChange(value);
54
+ };
55
+
56
+ const showTimeout = useTimeout(() => {
57
+ setShown(true);
58
+ }, showDelay);
59
+
60
+ const hideTimeout = useTimeout(() => {
61
+ setShown(false);
62
+ }, hideDelay);
63
+
64
+ const [childRef, child] = usePatchChildrenRef(children);
65
+
66
+ const onTargetEnter = () => {
67
+ hideTimeout.clear();
68
+ showTimeout.set();
69
+ };
70
+
71
+ const onTargetLeave = () => {
72
+ showTimeout.clear();
73
+ hideTimeout.set();
74
+ };
75
+
76
+ const targetEnterListener = useEventListener('pointerenter', onTargetEnter);
77
+ const targetLeaveListener = useEventListener('pointerleave', onTargetLeave);
78
+
79
+ useIsomorphicLayoutEffect(() => {
80
+ targetEnterListener.add(childRef.current);
81
+ targetLeaveListener.add(childRef.current);
82
+ }, []);
83
+
84
+ return (
85
+ <React.Fragment>
86
+ {child}
87
+ {shown &&
88
+ <Popper
89
+ {...restProps}
90
+ onMouseOver={hideTimeout.clear}
91
+ onMouseOut={onTargetLeave}
92
+ getRef={getRef}
93
+ targetRef={childRef}
94
+ >
95
+ {content}
96
+ </Popper>
97
+ }
98
+ </React.Fragment>
99
+ );
100
+ };