@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
@@ -8,6 +8,10 @@
8
8
 
9
9
  В таких случаях передавайте в `PanelHeader` свойство `separator={false}`.
10
10
 
11
+ >**Важно**
12
+ >
13
+ > Правая часть шапки будет скрыта, если в [`ConfigProvider`](#/ConfigProvider) передан `webviewType={WebviewType.VKAPPS}`.
14
+
11
15
  ```jsx
12
16
  class Example extends React.Component {
13
17
  constructor(props) {
@@ -0,0 +1,39 @@
1
+ .PopperPortal {
2
+ position: relative;
3
+ z-index: 1;
4
+ }
5
+
6
+ .Popper__arrow-in {
7
+ content: '';
8
+ display: block;
9
+ width: 20px;
10
+ height: 8px;
11
+ }
12
+
13
+ [data-popper-placement^="bottom"] .Popper__arrow {
14
+ bottom: 100%;
15
+ }
16
+
17
+ [data-popper-placement^="top"] .Popper__arrow {
18
+ top: 100%;
19
+ }
20
+
21
+ [data-popper-placement^="top"] .Popper__arrow-in {
22
+ transform: rotate(180deg);
23
+ }
24
+
25
+ [data-popper-placement^="left"] .Popper__arrow {
26
+ left: calc(100% - 6px);
27
+ }
28
+
29
+ [data-popper-placement^="left"] .Popper__arrow-in {
30
+ transform: rotate(90deg);
31
+ }
32
+
33
+ [data-popper-placement^="right"] .Popper__arrow {
34
+ right: calc(100% - 6px);
35
+ }
36
+
37
+ [data-popper-placement^="right"] .Popper__arrow-in {
38
+ transform: rotate(270deg);
39
+ }
@@ -0,0 +1,147 @@
1
+ import * as React from 'react';
2
+ import { usePopper } from 'react-popper';
3
+ import { AppRootPortal } from '../AppRoot/AppRootPortal';
4
+ import { HasRef } from '../../types';
5
+ import { usePlatform } from '../../hooks/usePlatform';
6
+ import { getClassName } from '../../helpers/getClassName';
7
+ import { useExternRef } from '../../hooks/useExternRef';
8
+ import { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';
9
+ import './Popper.css';
10
+
11
+ export type Placement = 'auto' | 'auto-start' | 'auto-end' | 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' |
12
+ 'right-start' | 'right-end' | 'left-start' | 'left-end' | 'top' | 'bottom' | 'left' | 'right';
13
+
14
+ type Modifier = {
15
+ name: string;
16
+ options?: {
17
+ [index: string]: any;
18
+ };
19
+ };
20
+
21
+ export interface PopperCommonProps extends React.HTMLAttributes<HTMLElement>, HasRef<HTMLElement> {
22
+ /**
23
+ * По умолчанию компонент выберет наилучшее расположение сам. Но его можно задать извне с помощью этого свойства
24
+ */
25
+ placement?: Placement;
26
+ /**
27
+ * Отступ по вспомогательной оси
28
+ */
29
+ offsetSkidding?: number;
30
+ /**
31
+ * Отступ по главной оси
32
+ */
33
+ offsetDistance?: number;
34
+ arrow?: boolean;
35
+ arrowClassName?: string;
36
+ onPlacementChange?: (data: { placement?: Placement }) => void;
37
+ }
38
+
39
+ export interface PopperProps extends PopperCommonProps {
40
+ targetRef?: React.RefObject<HTMLElement>;
41
+ }
42
+
43
+ const ARROW_PADDING = 8;
44
+ const ARROW_WIDTH = 20;
45
+ const ARROW_HEIGHT = 8;
46
+
47
+ export const Popper: React.FC<PopperProps> = ({
48
+ targetRef,
49
+ children,
50
+ getRef,
51
+ placement = 'bottom-start',
52
+ onPlacementChange,
53
+ arrow,
54
+ arrowClassName,
55
+ offsetDistance = 8,
56
+ offsetSkidding = 0,
57
+ style: compStyles,
58
+ ...restProps
59
+ }: PopperProps) => {
60
+ const [popperNode, setPopperNode] = React.useState(null);
61
+ const [smallTargetOffsetSkidding, setSmallTargetOffsetSkidding] = React.useState(0);
62
+ const platform = usePlatform();
63
+
64
+ const setExternalRef = useExternRef(getRef, setPopperNode);
65
+
66
+ const modifiers: Modifier[] = [{
67
+ name: 'preventOverflow',
68
+ }, {
69
+ name: 'offset',
70
+ options: {
71
+ offset: [
72
+ arrow ? offsetSkidding - smallTargetOffsetSkidding : offsetSkidding,
73
+ arrow ? offsetDistance + ARROW_HEIGHT : offsetDistance,
74
+ ],
75
+ },
76
+ }, {
77
+ name: 'flip',
78
+ }];
79
+
80
+ if (arrow) {
81
+ modifiers.push({
82
+ name: 'arrow',
83
+ options: {
84
+ padding: ARROW_PADDING,
85
+ },
86
+ });
87
+ }
88
+
89
+ const { styles, state, attributes } = usePopper(targetRef.current, popperNode, {
90
+ placement,
91
+ modifiers,
92
+ });
93
+
94
+ const resolvedPlacement = state?.placement;
95
+ const isEdgePlacement = !!resolvedPlacement && resolvedPlacement.includes('-'); // true, если поппер отрисован скраю
96
+
97
+ // Если поппер рисуется скраю, то нужно опционально сместить его в тех случаях, когда стрелка не дотягивается до
98
+ // таргета из-за маленьких размеров последнего
99
+ useIsomorphicLayoutEffect(() => {
100
+ if (arrow && isEdgePlacement) {
101
+ const placementDirection = resolvedPlacement.startsWith('bottom') || resolvedPlacement.startsWith('top') ? 'vertical' : 'horizontal';
102
+
103
+ const arrowSize = placementDirection === 'vertical' ? ARROW_WIDTH : ARROW_HEIGHT;
104
+ const targetSize = placementDirection === 'vertical' ? targetRef.current.offsetWidth : targetRef.current.offsetHeight;
105
+
106
+ if (targetSize < arrowSize + 2 * ARROW_PADDING) {
107
+ setSmallTargetOffsetSkidding(ARROW_PADDING + arrowSize / 2);
108
+ }
109
+ } else {
110
+ setSmallTargetOffsetSkidding(0);
111
+ }
112
+ }, [arrow, isEdgePlacement]);
113
+
114
+ React.useEffect(() => {
115
+ if (resolvedPlacement) {
116
+ onPlacementChange && onPlacementChange({ placement: resolvedPlacement });
117
+ }
118
+ }, [resolvedPlacement]);
119
+
120
+ const dropdown = (
121
+ <div
122
+ {...restProps}
123
+ {...attributes.popper}
124
+ vkuiClass={getClassName('Popper', platform)}
125
+ ref={setExternalRef}
126
+ style={{ ...compStyles, ...styles.popper }}
127
+ >
128
+ {arrow && (
129
+ <div
130
+ {...attributes.arrow}
131
+ vkuiClass="Popper__arrow"
132
+ data-popper-arrow={true}
133
+ style={styles.arrow}
134
+ >
135
+ <svg vkuiClass="Popper__arrow-in" className={arrowClassName} width="20" height="8" viewBox="0 0 20 8" fill="none" xmlns="http://www.w3.org/2000/svg">
136
+ <path fillRule="evenodd" clipRule="evenodd" d="M10 0C13 0 15.9999 8 20 8H0C3.9749 8 7 0 10 0Z" fill="currentColor" />
137
+ </svg>
138
+ </div>
139
+ )}
140
+ <div vkuiClass="Popper__content">
141
+ {children}
142
+ </div>
143
+ </div>
144
+ );
145
+
146
+ return <AppRootPortal forcePortal vkuiClass="PopperPortal">{dropdown}</AppRootPortal>;
147
+ };
@@ -0,0 +1,23 @@
1
+ >**Важно**
2
+ >
3
+ >Это нестабильный компонент. Его API может меняться в рамках одной мажорной версии. [Подробнее про нестабильные компоненты](#/Unstable).
4
+
5
+ Низкоуровневый компонент для отрисовки выпадающего блока. Единственная его задача — корректно позициионироваться
6
+ рядом с целевым элементом. На основе этого компонента сделаны [ClickPopper](#/ClickPopper) и [HoverPopper](#/HoverPopper),
7
+ реализующие логику скрытия и показа по клику и по ховеру соответственно.
8
+
9
+ ```jsx { "props": { "layout": false, "iframe": false } }
10
+ const [shown, setShown] = React.useState(false);
11
+ const buttonRef = React.useRef();
12
+
13
+ return (
14
+ <React.Fragment>
15
+ <Button getRootRef={buttonRef} onClick={() => setShown(!shown)} style={{ margin: 50 }}>{shown ? 'Закрыть' : 'Открыть'}</Button>
16
+ {shown &&
17
+ <Popper offsetDistance={8} style={{ padding: '9px 12px' }} targetRef={buttonRef}>
18
+ Привет
19
+ </Popper>
20
+ }
21
+ </React.Fragment>
22
+ )
23
+ ```
@@ -0,0 +1,55 @@
1
+ Тултип, открывающийся при наведеннии мыши на `children`. В отличие от [TextTooltip](#/TextTooltip), имеет меньше ограничений
2
+ по содержимому. Компонент всё ещё предназначен для информирования пользователей, но внутри допускаются кнопки, ссылки, картинки.
3
+
4
+ ```jsx { "props": { "layout": false, "iframe": true } }
5
+ <Checkbox>
6
+ Специальные возможности
7
+ <RichTooltip style={{maxWidth: 320}} content={
8
+ <Subhead weight="regular" style={{padding: '8px 12px', color: 'var(--text_primary)'}}>
9
+ Если включить эту настройку, элементы управления на сайте будут определены и озвучены синтезатором речи.
10
+ <br/><br/>
11
+ Настройка повышает доступность сайта и подходит для пользователей с ограниченными возможностями.
12
+ </Subhead>
13
+ }>
14
+ <Icon16HelpOutline style={{
15
+ display: 'inline-block',
16
+ verticalAlign: 'middle',
17
+ position: 'relative',
18
+ top: -1,
19
+ color: 'var(--icon_secondary)'
20
+ }}/>
21
+ </RichTooltip>
22
+ </Checkbox>
23
+
24
+ <RichTooltip style={{maxWidth: 320}} content={
25
+ <RichCell
26
+ disabled
27
+ after={
28
+ <TextTooltip text="Добавить">
29
+ <Icon28UserAddOutline/>
30
+ </TextTooltip>
31
+ }
32
+ before={<Avatar size={72} src={getAvatarUrl('user_ilyagrshn')}/>}
33
+ caption="Команда ВКонтакте, Санкт-Петербург"
34
+ bottom={
35
+ <UsersStack
36
+ photos={[
37
+ getAvatarUrl('user_ox'),
38
+ getAvatarUrl('user_vitalyavolyn'),
39
+ getAvatarUrl('user_eee'),
40
+ ]}
41
+ >73 общих друга</UsersStack>
42
+ }
43
+ actions={
44
+ <React.Fragment>
45
+ <Button>Добавить</Button>
46
+ <Button mode="secondary">Скрыть</Button>
47
+ </React.Fragment>
48
+ }
49
+ >
50
+ Илья Гришин
51
+ </RichCell>
52
+ }>
53
+ <Link style={{display: 'inline-block', margin: 20}}>Илья Гришин</Link>
54
+ </RichTooltip>
55
+ ```
@@ -0,0 +1,10 @@
1
+ .RichTooltip {
2
+ box-shadow: 0 0 4px rgba(0, 0, 0, .04), 0 4px 32px rgba(0, 0, 0, .16);
3
+ border-radius: 8px;
4
+ background: var(--background_content);
5
+ animation: vkui-popper-fadein .2s ease;
6
+ }
7
+
8
+ .RichTooltip__arrow {
9
+ color: var(--background_content);
10
+ }
@@ -0,0 +1,70 @@
1
+ import * as React from 'react';
2
+ import { HoverPopper } from '../HoverPopper/HoverPopper';
3
+ import { getClassName } from '../../helpers/getClassName';
4
+ import { usePlatform } from '../../hooks/usePlatform';
5
+ import { useAppearance } from '../../hooks/useAppearance';
6
+ import { classNames } from '../../lib/classNames';
7
+ import { prefixClass } from '../../lib/prefixClass';
8
+ import { Placement } from '../Popper/Popper';
9
+ import './RichTooltip.css';
10
+
11
+ // Приходится избегать экстендов от HoverPopperProps и PopperProps, потому что react-docgen не умеет в Omit.
12
+ // Ждём либо фикса react-docgen (что вряд ли), либо переезда на react-docgen-typescript, где такой проблемы нет.
13
+ export interface RichTooltipProps {
14
+ /**
15
+ * Содержимое тултипа
16
+ */
17
+ content?: React.ReactNode;
18
+ /**
19
+ * Если передан, то тултип будет показыван/скрыт в зависимости от значения свойства
20
+ */
21
+ shown?: boolean;
22
+ /**
23
+ * Вызывается при каждом изменении видимости тултипа
24
+ */
25
+ onShownChange?: (shown: boolean) => void;
26
+ /**
27
+ * Количество миллисекунд, после которых произойдет показ дропдауна
28
+ */
29
+ showDelay?: number;
30
+ /**
31
+ * Количество миллисекунд, после которых произойдет скрытие дропдауна
32
+ */
33
+ hideDelay?: number;
34
+ /**
35
+ * Либо jsx-элемент (div, button, etc.), либо компонент со свойством `getRootRef`, которое применяется к корневому элементу компонента
36
+ */
37
+ children?: React.ReactElement;
38
+ /**
39
+ * По умолчанию компонент выберет наилучшее расположение сам. Но его можно задать извне с помощью этого свойства
40
+ */
41
+ placement?: Placement;
42
+ /**
43
+ * Отступ по вспомогательной оси
44
+ */
45
+ offsetSkidding?: number;
46
+ /**
47
+ * Отступ по главной оси
48
+ */
49
+ offsetDistance?: number;
50
+ onPlacementChange?: (data: { placement?: Placement }) => void;
51
+ arrow?: boolean;
52
+ }
53
+
54
+ export const RichTooltip: React.FC<RichTooltipProps> = ({ children, arrow = true, ...popperProps }: RichTooltipProps) => {
55
+ const platform = usePlatform();
56
+ const appearance = useAppearance();
57
+
58
+ return (
59
+ <HoverPopper
60
+ vkuiClass={classNames(getClassName('RichTooltip', platform), {
61
+ [`RichTooltip--${appearance}`]: !!appearance,
62
+ })}
63
+ arrow={arrow}
64
+ arrowClassName={prefixClass('RichTooltip__arrow')}
65
+ {...popperProps}
66
+ >
67
+ {children}
68
+ </HoverPopper>
69
+ );
70
+ };
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import mitt from 'mitt';
3
- import { hasHover as deviceHasHover, noop } from '@vkontakte/vkjs';
3
+ import { noop } from '@vkontakte/vkjs';
4
4
  import { Touch, TouchEvent, TouchProps } from '../Touch/Touch';
5
5
  import TouchRootContext from '../Touch/TouchContext';
6
6
  import { classNames } from '../../lib/classNames';
@@ -128,7 +128,8 @@ const Tappable: React.FC<TappableProps> = ({
128
128
  getRootRef,
129
129
  sizeX,
130
130
  hasMouse,
131
- hasHover: _hasHover = deviceHasHover,
131
+ deviceHasHover,
132
+ hasHover: _hasHover = true,
132
133
  hoverMode = 'background',
133
134
  hasActive: _hasActive = true,
134
135
  activeMode = 'background',
@@ -147,7 +148,7 @@ const Tappable: React.FC<TappableProps> = ({
147
148
 
148
149
  const hovered = _hovered && !props.disabled;
149
150
  const hasActive = _hasActive && !childHover && !props.disabled;
150
- const hasHover = _hasHover && !childHover;
151
+ const hasHover = deviceHasHover && _hasHover && !childHover;
151
152
  const isCustomElement = Component !== 'a' && Component !== 'button' && !props.contentEditable;
152
153
  const isPresetHoverMode = ['opacity', 'background'].includes(hoverMode);
153
154
  const isPresetActiveMode = ['opacity', 'background'].includes(activeMode);
@@ -270,7 +271,7 @@ const Tappable: React.FC<TappableProps> = ({
270
271
  );
271
272
  };
272
273
 
273
- export default withAdaptivity(Tappable, { sizeX: true, hasMouse: true });
274
+ export default withAdaptivity(Tappable, { sizeX: true, hasMouse: true, deviceHasHover: true });
274
275
 
275
276
  function Wave({ x, y, onClear }: Wave & { onClear: VoidFunction }) {
276
277
  const timeout = useTimeout(onClear, 225);
@@ -0,0 +1,7 @@
1
+ Тултип, открывающийся при наведеннии мыши на `children`. В качестве содержимого тултипа рекомендуется использовать только текст.
2
+
3
+ ```jsx { "props": { "layout": false, "iframe": false } }
4
+ <TextTooltip text="Привет">
5
+ <Button style={{ margin: 20 }}>Наведи</Button>
6
+ </TextTooltip>
7
+ ```
@@ -0,0 +1,12 @@
1
+ .TextTooltip {
2
+ border-radius: 8px;
3
+ background: rgba(44, 45, 46, .88); /*TODO узнать у дизайнеров название токена*/
4
+ padding: 8px 12px 9px;
5
+ color: var(--white);
6
+ box-shadow: 0 0 4px rgba(0, 0, 0, .04), 0 4px 32px rgba(0, 0, 0, .16);
7
+ animation: vkui-popper-fadein .2s ease;
8
+ }
9
+
10
+ .TextTooltip__arrow {
11
+ color: rgba(44, 45, 46, .88);
12
+ }
@@ -0,0 +1,76 @@
1
+ import * as React from 'react';
2
+ import { HoverPopper } from '../HoverPopper/HoverPopper';
3
+ import { getClassName } from '../../helpers/getClassName';
4
+ import { usePlatform } from '../../hooks/usePlatform';
5
+ import { hasReactNode } from '../../lib/utils';
6
+ import { Placement } from '../Popper/Popper';
7
+ import Subhead from '../Typography/Subhead/Subhead';
8
+ import { prefixClass } from '../../lib/prefixClass';
9
+ import './TextTooltip.css';
10
+
11
+ // Приходится избегать экстендов от HoverPopperProps и PopperProps, потому что react-docgen не умеет в Omit.
12
+ // Ждём либо фикса react-docgen (что вряд ли), либо переезда на react-docgen-typescript, где такой проблемы нет.
13
+ export interface TextTooltipProps {
14
+ /**
15
+ * Если передан, то тултип будет показыван/скрыт в зависимости от значения свойства
16
+ */
17
+ shown?: boolean;
18
+ /**
19
+ * Вызывается при каждом изменении видимости тултипа
20
+ */
21
+ onShownChange?: (shown: boolean) => void;
22
+ /**
23
+ * Количество миллисекунд, после которых произойдет показ дропдауна
24
+ */
25
+ showDelay?: number;
26
+ /**
27
+ * Количество миллисекунд, после которых произойдет скрытие дропдауна
28
+ */
29
+ hideDelay?: number;
30
+ /**
31
+ * Либо jsx-элемент (div, button, etc.), либо компонент со свойством `getRootRef`, которое применяется к корневому элементу компонента
32
+ */
33
+ children?: React.ReactElement;
34
+ /**
35
+ * По умолчанию компонент выберет наилучшее расположение сам. Но его можно задать извне с помощью этого свойства
36
+ */
37
+ placement?: Placement;
38
+ /**
39
+ * Отступ по вспомогательной оси
40
+ */
41
+ offsetSkidding?: number;
42
+ /**
43
+ * Отступ по главной оси
44
+ */
45
+ offsetDistance?: number;
46
+ onPlacementChange?: (data: { placement?: Placement }) => void;
47
+ /**
48
+ * Текст тултипа
49
+ */
50
+ text?: React.ReactNode;
51
+ /**
52
+ * Заголовок тултипа
53
+ */
54
+ header?: React.ReactNode;
55
+ }
56
+
57
+ export const TextTooltip: React.FC<TextTooltipProps> = ({ children, text, header, ...popperProps }: TextTooltipProps) => {
58
+ const platform = usePlatform();
59
+
60
+ return (
61
+ <HoverPopper
62
+ vkuiClass={getClassName('TextTooltip', platform)}
63
+ arrow
64
+ arrowClassName={prefixClass('TextTooltip__arrow')}
65
+ content={
66
+ <React.Fragment>
67
+ {hasReactNode(header) && <Subhead Component="span" weight="medium" vkuiClass="TextTooltip__header">{header}</Subhead>}
68
+ {hasReactNode(text) && <Subhead Component="span" weight="regular" vkuiClass="TextTooltip__text">{text}</Subhead>}
69
+ </React.Fragment>
70
+ }
71
+ {...popperProps}
72
+ >
73
+ {children}
74
+ </HoverPopper>
75
+ );
76
+ };
@@ -2,6 +2,8 @@
2
2
  хочется представить новый функционал. Это достаточно сложный с точки зрения управления компонент, поэтому он
3
3
  требует подробной документации.
4
4
 
5
+ Для показа тултипа по ховеру, воспользуйтесь [`RichTooltip`](#/RichTooltip) или [`TextTooltip`](#/TextTooltip).
6
+
5
7
  ### Концепция
6
8
  Этот тултип служит для ознакомительных целей. То есть показывать его надо один раз, запоминая факт показа между
7
9
  сессиями. Рекомендуется показывать тултип сразу после того, как нуждающийся в нем элемент появился в зоне видимости.
@@ -16,6 +16,7 @@ interface Config {
16
16
  viewWidth?: boolean;
17
17
  viewHeight?: boolean;
18
18
  hasMouse?: boolean;
19
+ deviceHasHover?: boolean;
19
20
  }
20
21
 
21
22
  export function withAdaptivity<T>(TargetComponent: T, config: Config): T {
@@ -32,6 +33,7 @@ export function withAdaptivity<T>(TargetComponent: T, config: Config): T {
32
33
  const viewWidth = context.viewWidth;
33
34
  const viewHeight = context.viewHeight;
34
35
  const hasMouse = context.hasMouse;
36
+ const deviceHasHover = context.deviceHasHover;
35
37
 
36
38
  const adaptivityProps: {
37
39
  sizeX?: SizeType;
@@ -39,18 +41,20 @@ export function withAdaptivity<T>(TargetComponent: T, config: Config): T {
39
41
  viewWidth?: ViewWidth;
40
42
  viewHeight?: ViewHeight;
41
43
  hasMouse?: boolean;
44
+ deviceHasHover?: boolean;
42
45
  } = {};
43
46
  config.sizeX ? adaptivityProps.sizeX = sizeX : undefined;
44
47
  config.sizeY ? adaptivityProps.sizeY = sizeY : undefined;
45
48
  config.viewWidth ? adaptivityProps.viewWidth = viewWidth : undefined;
46
49
  config.viewHeight ? adaptivityProps.viewHeight = viewHeight : undefined;
47
50
  config.hasMouse ? adaptivityProps.hasMouse = hasMouse : undefined;
51
+ config.deviceHasHover ? adaptivityProps.deviceHasHover = deviceHasHover : undefined;
48
52
 
49
53
  // @ts-ignore
50
54
  const target = <TargetComponent {...props} {...adaptivityProps} />;
51
55
 
52
56
  if (update) {
53
- return <AdaptivityContext.Provider value={{ sizeX, sizeY, viewWidth, viewHeight, hasMouse }}>
57
+ return <AdaptivityContext.Provider value={{ sizeX, sizeY, viewWidth, viewHeight, hasMouse, deviceHasHover }}>
54
58
  {target}
55
59
  </AdaptivityContext.Provider>;
56
60
  }
@@ -0,0 +1,24 @@
1
+ import * as React from 'react';
2
+ import { useExternRef } from './useExternRef';
3
+ import { warnOnce } from '../lib/warnOnce';
4
+
5
+ type ChildrenElement<T> = React.ReactElement<{ getRootRef?: React.Ref<T> }>;
6
+
7
+ const isDOMTypeElement = (element: React.ReactElement): element is React.DOMElement<any, any> => {
8
+ return typeof element.type === 'string';
9
+ };
10
+
11
+ const warn = warnOnce('usePatchChildrenRef');
12
+ export const usePatchChildrenRef = <T = HTMLElement>(children: ChildrenElement<T>): [React.MutableRefObject<T>, ChildrenElement<T>] => {
13
+ const childRef = React.isValidElement(children) && (isDOMTypeElement(children) ? children.ref as React.Ref<T> : children.props.getRootRef);
14
+ const patchedRef = useExternRef<T>(childRef);
15
+ React.useEffect(() => {
16
+ if (!patchedRef.current && process.env.NODE_ENV === 'development') {
17
+ warn('Кажется, в `children` передан компонент, который не поддерживает свойство `getRootRef`. Мы не можем' +
18
+ 'получить ссылку на корневой dom-элемент этого компонента');
19
+ }
20
+ }, [children.type]);
21
+ return [patchedRef, React.isValidElement(children) ? React.cloneElement(children, {
22
+ [isDOMTypeElement(children) ? 'ref' : 'getRootRef']: patchedRef,
23
+ }) : children];
24
+ };
package/src/index.ts CHANGED
@@ -102,7 +102,8 @@ export { default as SimpleCell } from './components/SimpleCell/SimpleCell';
102
102
  export type { SimpleCellProps } from './components/SimpleCell/SimpleCell';
103
103
  export { HorizontalCell } from './components/HorizontalCell/HorizontalCell';
104
104
  export type { HorizontalCellProps } from './components/HorizontalCell/HorizontalCell';
105
- export { default as Footer } from './components/Footer/Footer';
105
+ export { Footer } from './components/Footer/Footer';
106
+ export type { FooterProps } from './components/Footer/Footer';
106
107
  export { default as InfoRow } from './components/InfoRow/InfoRow';
107
108
  export type { InfoRowProps } from './components/InfoRow/InfoRow';
108
109
  export { default as Gallery } from './components/Gallery/Gallery';
@@ -7,3 +7,8 @@
7
7
  transform: rotate(360deg);
8
8
  }
9
9
  }
10
+
11
+ @keyframes vkui-popper-fadein {
12
+ from { opacity: 0; }
13
+ to { opacity: 1; }
14
+ }
@@ -25,10 +25,15 @@
25
25
  .vkui__root input,
26
26
  .vkui__root textarea,
27
27
  .vkui__root select,
28
- .vkui__root button {
28
+ .vkui__root button,
29
+ .vkui__portal-root input,
30
+ .vkui__portal-root textarea,
31
+ .vkui__portal-root select,
32
+ .vkui__portal-root button {
29
33
  font-family: inherit;
30
34
  }
31
35
 
32
- .vkui__root *:focus {
36
+ .vkui__root *:focus,
37
+ .vkui__portal-root *:focus {
33
38
  outline: none;
34
39
  }
@@ -1,3 +1,7 @@
1
1
  /* Forms */
2
2
  @import '../components/ChipsSelect/ChipsSelect.css';
3
3
  @import '../components/SimpleCheckbox/SimpleCheckbox.css';
4
+ @import '../components/Dropdown/Dropdown.css';
5
+ @import '../components/Popper/Popper.css';
6
+ @import '../components/TextTooltip/TextTooltip.css';
7
+ @import '../components/RichTooltip/RichTooltip.css';
@@ -4,6 +4,18 @@
4
4
  export { default as ChipsSelect } from './../components/ChipsSelect/ChipsSelect';
5
5
  export type { ChipsSelectProps } from './../components/ChipsSelect/ChipsSelect';
6
6
 
7
+ export { Dropdown } from '../components/Dropdown/Dropdown';
8
+ export type { DropdownProps } from '../components/Dropdown/Dropdown';
9
+
10
+ export { TextTooltip } from '../components/TextTooltip/TextTooltip';
11
+ export type { TextTooltipProps } from '../components/TextTooltip/TextTooltip';
12
+
13
+ export { RichTooltip } from '../components/RichTooltip/RichTooltip';
14
+ export type { RichTooltipProps } from '../components/RichTooltip/RichTooltip';
15
+
16
+ export { Popper } from '../components/Popper/Popper';
17
+ export type { PopperProps } from '../components/Popper/Popper';
18
+
7
19
  export { default as ViewInfinite } from './../components/View/ViewInfinite';
8
20
  export type { ViewInfiniteProps } from './../components/View/ViewInfinite';
9
21