@vkontakte/vkui 6.1.1 → 6.1.2
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.
- package/dist/cjs/components/Clickable/useState.d.ts.map +1 -1
- package/dist/cjs/components/Clickable/useState.js +7 -6
- package/dist/cjs/components/Clickable/useState.js.map +1 -1
- package/dist/cjs/components/CustomScrollView/CustomScrollView.d.ts.map +1 -1
- package/dist/cjs/components/CustomScrollView/CustomScrollView.js +8 -1
- package/dist/cjs/components/CustomScrollView/CustomScrollView.js.map +1 -1
- package/dist/cjs/components/FocusTrap/FocusTrap.d.ts +2 -2
- package/dist/cjs/components/FocusTrap/FocusTrap.d.ts.map +1 -1
- package/dist/cjs/components/FocusTrap/FocusTrap.js +36 -11
- package/dist/cjs/components/FocusTrap/FocusTrap.js.map +1 -1
- package/dist/cjs/components/Select/Select.d.ts +1 -1
- package/dist/cjs/components/Select/Select.d.ts.map +1 -1
- package/dist/cjs/components/Select/Select.js +12 -6
- package/dist/cjs/components/Select/Select.js.map +1 -1
- package/dist/cjs/components/Spacing/Spacing.d.ts +16 -5
- package/dist/cjs/components/Spacing/Spacing.d.ts.map +1 -1
- package/dist/cjs/components/Spacing/Spacing.js +38 -31
- package/dist/cjs/components/Spacing/Spacing.js.map +1 -1
- package/dist/cjs/components/ToolButton/ToolButton.d.ts +5 -0
- package/dist/cjs/components/ToolButton/ToolButton.d.ts.map +1 -1
- package/dist/cjs/components/ToolButton/ToolButton.js +2 -1
- package/dist/cjs/components/ToolButton/ToolButton.js.map +1 -1
- package/dist/cjs/hooks/useResizeObserver.d.ts +6 -0
- package/dist/cjs/hooks/useResizeObserver.d.ts.map +1 -0
- package/dist/cjs/hooks/useResizeObserver.js +32 -0
- package/dist/cjs/hooks/useResizeObserver.js.map +1 -0
- package/dist/cjs/lib/floating/customResizeObserver.d.ts.map +1 -1
- package/dist/cjs/lib/floating/customResizeObserver.js +2 -1
- package/dist/cjs/lib/floating/customResizeObserver.js.map +1 -1
- package/dist/cjs/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.d.ts.map +1 -1
- package/dist/cjs/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.js +11 -1
- package/dist/cjs/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.js.map +1 -1
- package/dist/components/Clickable/useState.d.ts.map +1 -1
- package/dist/components/Clickable/useState.js +7 -6
- package/dist/components/Clickable/useState.js.map +1 -1
- package/dist/components/CustomScrollView/CustomScrollView.d.ts.map +1 -1
- package/dist/components/CustomScrollView/CustomScrollView.js +8 -1
- package/dist/components/CustomScrollView/CustomScrollView.js.map +1 -1
- package/dist/components/FocusTrap/FocusTrap.d.ts +2 -2
- package/dist/components/FocusTrap/FocusTrap.d.ts.map +1 -1
- package/dist/components/FocusTrap/FocusTrap.js +37 -11
- package/dist/components/FocusTrap/FocusTrap.js.map +1 -1
- package/dist/components/Select/Select.d.ts +1 -1
- package/dist/components/Select/Select.d.ts.map +1 -1
- package/dist/components/Select/Select.js +12 -6
- package/dist/components/Select/Select.js.map +1 -1
- package/dist/components/Spacing/Spacing.d.ts +16 -5
- package/dist/components/Spacing/Spacing.d.ts.map +1 -1
- package/dist/components/Spacing/Spacing.js +33 -28
- package/dist/components/Spacing/Spacing.js.map +1 -1
- package/dist/components/ToolButton/ToolButton.d.ts +5 -0
- package/dist/components/ToolButton/ToolButton.d.ts.map +1 -1
- package/dist/components/ToolButton/ToolButton.js +2 -1
- package/dist/components/ToolButton/ToolButton.js.map +1 -1
- package/dist/components.css +4 -4
- package/dist/components.css.map +1 -1
- package/dist/components.js.tmp +461 -330
- package/dist/cssm/components/Clickable/useState.d.ts.map +1 -1
- package/dist/cssm/components/Clickable/useState.js +7 -6
- package/dist/cssm/components/Clickable/useState.js.map +1 -1
- package/dist/cssm/components/CustomScrollView/CustomScrollView.d.ts.map +1 -1
- package/dist/cssm/components/CustomScrollView/CustomScrollView.js +8 -1
- package/dist/cssm/components/CustomScrollView/CustomScrollView.js.map +1 -1
- package/dist/cssm/components/CustomScrollView/CustomScrollView.module.css +4 -0
- package/dist/cssm/components/FocusTrap/FocusTrap.d.ts +2 -2
- package/dist/cssm/components/FocusTrap/FocusTrap.d.ts.map +1 -1
- package/dist/cssm/components/FocusTrap/FocusTrap.js +37 -11
- package/dist/cssm/components/FocusTrap/FocusTrap.js.map +1 -1
- package/dist/cssm/components/Select/Select.d.ts +1 -1
- package/dist/cssm/components/Select/Select.d.ts.map +1 -1
- package/dist/cssm/components/Select/Select.js +8 -5
- package/dist/cssm/components/Select/Select.js.map +1 -1
- package/dist/cssm/components/Spacing/Spacing.d.ts +16 -5
- package/dist/cssm/components/Spacing/Spacing.d.ts.map +1 -1
- package/dist/cssm/components/Spacing/Spacing.js +31 -30
- package/dist/cssm/components/Spacing/Spacing.js.map +1 -1
- package/dist/cssm/components/Spacing/Spacing.module.css +44 -0
- package/dist/cssm/components/ToolButton/ToolButton.d.ts +5 -0
- package/dist/cssm/components/ToolButton/ToolButton.d.ts.map +1 -1
- package/dist/cssm/components/ToolButton/ToolButton.js +2 -1
- package/dist/cssm/components/ToolButton/ToolButton.js.map +1 -1
- package/dist/cssm/components/ToolButton/ToolButton.module.css +6 -20
- package/dist/cssm/hooks/useResizeObserver.d.ts +6 -0
- package/dist/cssm/hooks/useResizeObserver.d.ts.map +1 -0
- package/dist/cssm/hooks/useResizeObserver.js +23 -0
- package/dist/cssm/hooks/useResizeObserver.js.map +1 -0
- package/dist/cssm/lib/floating/customResizeObserver.d.ts.map +1 -1
- package/dist/cssm/lib/floating/customResizeObserver.js +2 -1
- package/dist/cssm/lib/floating/customResizeObserver.js.map +1 -1
- package/dist/cssm/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.d.ts.map +1 -1
- package/dist/cssm/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.js +11 -1
- package/dist/cssm/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.js.map +1 -1
- package/dist/cssm/styles/adaptivity.module.css +1 -2
- package/dist/hooks/useResizeObserver.d.ts +6 -0
- package/dist/hooks/useResizeObserver.d.ts.map +1 -0
- package/dist/hooks/useResizeObserver.js +23 -0
- package/dist/hooks/useResizeObserver.js.map +1 -0
- package/dist/lib/floating/customResizeObserver.d.ts.map +1 -1
- package/dist/lib/floating/customResizeObserver.js +2 -1
- package/dist/lib/floating/customResizeObserver.js.map +1 -1
- package/dist/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.d.ts.map +1 -1
- package/dist/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.js +11 -1
- package/dist/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.js.map +1 -1
- package/dist/vkui.css +4 -4
- package/dist/vkui.css.map +1 -1
- package/dist/vkui.js.tmp +461 -330
- package/package.json +1 -1
- package/src/components/Clickable/useState.tsx +16 -6
- package/src/components/CustomScrollView/CustomScrollView.module.css +4 -0
- package/src/components/CustomScrollView/CustomScrollView.tsx +7 -1
- package/src/components/FocusTrap/FocusTrap.tsx +54 -20
- package/src/components/Select/Select.tsx +12 -5
- package/src/components/Spacing/Spacing.module.css +44 -0
- package/src/components/Spacing/Spacing.tsx +38 -34
- package/src/components/ToolButton/ToolButton.module.css +4 -14
- package/src/components/ToolButton/ToolButton.tsx +7 -2
- package/src/hooks/useResizeObserver.ts +30 -0
- package/src/lib/floating/customResizeObserver.ts +10 -1
- package/src/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.ts +11 -1
- package/src/styles/adaptivity.module.css +1 -2
|
@@ -32,7 +32,7 @@ const stylesDirection = {
|
|
|
32
32
|
};
|
|
33
33
|
const sizeYClassNames = {
|
|
34
34
|
none: "vkuiToolButton--sizeY-none",
|
|
35
|
-
|
|
35
|
+
regular: "vkuiToolButton--sizeY-regular"
|
|
36
36
|
};
|
|
37
37
|
const ToolButton = (_param)=>{
|
|
38
38
|
var { mode = 'primary', appearance = 'accent', direction = 'row', onClick = _vkjs.noop, className, children, IconCompact, IconRegular, rounded } = _param, restProps = _object_without_properties._(_param, [
|
|
@@ -62,6 +62,7 @@ const ToolButton = (_param)=>{
|
|
|
62
62
|
IconRegular: IconRegular
|
|
63
63
|
}),
|
|
64
64
|
hasChildren && /*#__PURE__*/ (0, _jsxruntime.jsx)("span", {
|
|
65
|
+
className: "vkuiToolButton__text",
|
|
65
66
|
children: children
|
|
66
67
|
})
|
|
67
68
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/ToolButton/ToolButton.tsx"],"sourcesContent":["import { classNames, hasReactNode, noop } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport {\n AdaptiveIconRenderer,\n AdaptiveIconRendererProps,\n} from '../AdaptiveIconRenderer/AdaptiveIconRenderer';\nimport { Tappable, TappableProps } from '../Tappable/Tappable';\nimport styles from './ToolButton.module.css';\n\nconst stylesMode = {\n primary: styles['ToolButton--mode-primary'],\n secondary: styles['ToolButton--mode-secondary'],\n tertiary: styles['ToolButton--mode-tertiary'],\n outline: styles['ToolButton--mode-outline'],\n};\n\nconst stylesAppearance = {\n accent: styles['ToolButton--appearance-accent'],\n neutral: styles['ToolButton--appearance-neutral'],\n};\n\nconst stylesDirection = {\n row: styles['ToolButton--direction-row'],\n column: styles['ToolButton--direction-column'],\n};\n\nconst sizeYClassNames = {\n none: styles['ToolButton--sizeY-none'],\n
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/ToolButton/ToolButton.tsx"],"sourcesContent":["import { classNames, hasReactNode, noop } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport {\n AdaptiveIconRenderer,\n AdaptiveIconRendererProps,\n} from '../AdaptiveIconRenderer/AdaptiveIconRenderer';\nimport { Tappable, TappableProps } from '../Tappable/Tappable';\nimport styles from './ToolButton.module.css';\n\nconst stylesMode = {\n primary: styles['ToolButton--mode-primary'],\n secondary: styles['ToolButton--mode-secondary'],\n tertiary: styles['ToolButton--mode-tertiary'],\n outline: styles['ToolButton--mode-outline'],\n};\n\nconst stylesAppearance = {\n accent: styles['ToolButton--appearance-accent'],\n neutral: styles['ToolButton--appearance-neutral'],\n};\n\nconst stylesDirection = {\n row: styles['ToolButton--direction-row'],\n column: styles['ToolButton--direction-column'],\n};\n\nconst sizeYClassNames = {\n none: styles['ToolButton--sizeY-none'],\n regular: styles['ToolButton--sizeY-regular'],\n};\n\nexport interface ToolButtonProps extends TappableProps, AdaptiveIconRendererProps {\n mode?: 'primary' | 'secondary' | 'tertiary' | 'outline';\n appearance?: 'accent' | 'neutral';\n direction?: 'row' | 'column';\n /**\n * Задаёт `50%` закругления для контейнера.\n *\n * > Note: игнорируется при передаче `children`.\n */\n rounded?: boolean;\n}\n\n/**\n * Кнопки, которые используются для вызова инструмента, вставки аттачей или\n * для форматирования. Их можно использовать как кнопки для разового действия\n * или для включения/выключения режима.\n *\n * @see https://vkcom.github.io/VKUI/#/ToolButton\n */\nexport const ToolButton = ({\n mode = 'primary',\n appearance = 'accent',\n direction = 'row',\n onClick = noop,\n className,\n children,\n IconCompact,\n IconRegular,\n rounded,\n ...restProps\n}: ToolButtonProps) => {\n const { sizeY = 'none' } = useAdaptivity();\n const hasChildren = hasReactNode(children);\n\n return (\n <Tappable\n hoverMode={styles['ToolButton--hover']}\n activeMode={styles['ToolButton--active']}\n Component={restProps.href ? 'a' : 'button'}\n focusVisibleMode=\"outside\"\n onClick={onClick}\n className={classNames(\n className,\n styles['ToolButton'],\n rounded && !hasChildren && styles['ToolButton--rounded'],\n stylesMode[mode],\n stylesAppearance[appearance],\n stylesDirection[direction],\n sizeY !== 'compact' && sizeYClassNames[sizeY],\n )}\n {...restProps}\n >\n <AdaptiveIconRenderer IconCompact={IconCompact} IconRegular={IconRegular} />\n {hasChildren && <span className={styles['ToolButton__text']}>{children}</span>}\n </Tappable>\n );\n};\n"],"names":["ToolButton","stylesMode","primary","secondary","tertiary","outline","stylesAppearance","accent","neutral","stylesDirection","row","column","sizeYClassNames","none","regular","mode","appearance","direction","onClick","noop","className","children","IconCompact","IconRegular","rounded","restProps","sizeY","useAdaptivity","hasChildren","hasReactNode","Tappable","hoverMode","activeMode","Component","href","focusVisibleMode","classNames","AdaptiveIconRenderer","span"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BAkDaA;;;eAAAA;;;;;;;sBAlDkC;+BACjB;sCAIvB;0BACiC;AAGxC,MAAMC,aAAa;IACjBC,OAAO;IACPC,SAAS;IACTC,QAAQ;IACRC,OAAO;AACT;AAEA,MAAMC,mBAAmB;IACvBC,MAAM;IACNC,OAAO;AACT;AAEA,MAAMC,kBAAkB;IACtBC,GAAG;IACHC,MAAM;AACR;AAEA,MAAMC,kBAAkB;IACtBC,IAAI;IACJC,OAAO;AACT;AAqBO,MAAMd,aAAa;QAAC,EACzBe,OAAO,SAAS,EAChBC,aAAa,QAAQ,EACrBC,YAAY,KAAK,EACjBC,UAAUC,UAAI,EACdC,SAAS,EACTC,QAAQ,EACRC,WAAW,EACXC,WAAW,EACXC,OAAO,EAES,WADbC;QATHV;QACAC;QACAC;QACAC;QACAE;QACAC;QACAC;QACAC;QACAC;;IAGA,MAAM,EAAEE,QAAQ,MAAM,EAAE,GAAGC,IAAAA,4BAAa;IACxC,MAAMC,cAAcC,IAAAA,kBAAY,EAACR;IAEjC,qBACE,sBAACS,kBAAQ;QACPC,SAAS;QACTC,UAAU;QACVC,WAAWR,UAAUS,IAAI,GAAG,MAAM;QAClCC,kBAAiB;QACjBjB,SAASA;QACTE,WAAWgB,IAAAA,gBAAU,EACnBhB,6BAEAI,WAAW,CAACI,0CACZ3B,UAAU,CAACc,KAAK,EAChBT,gBAAgB,CAACU,WAAW,EAC5BP,eAAe,CAACQ,UAAU,EAC1BS,UAAU,aAAad,eAAe,CAACc,MAAM;OAE3CD;;0BAEJ,qBAACY,0CAAoB;gBAACf,aAAaA;gBAAaC,aAAaA;;YAC5DK,6BAAe,qBAACU;gBAAKlB,SAAS;0BAA+BC;;;;AAGpE"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Хук вызывает переданный коллбэк при изменении размеров элемента.
|
|
4
|
+
*/
|
|
5
|
+
export declare function useResizeObserver(ref: React.MutableRefObject<HTMLElement | null>, callback: (element: HTMLElement) => void): void;
|
|
6
|
+
//# sourceMappingURL=useResizeObserver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useResizeObserver.d.ts","sourceRoot":"","sources":["../../../src/hooks/useResizeObserver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,KAAK,CAAC,gBAAgB,CAAC,WAAW,GAAG,IAAI,CAAC,EAC/C,QAAQ,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,QAmBzC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "useResizeObserver", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return useResizeObserver;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
|
|
12
|
+
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
|
|
13
|
+
const _customResizeObserver = require("../lib/floating/customResizeObserver");
|
|
14
|
+
const _useIsomorphicLayoutEffect = require("../lib/useIsomorphicLayoutEffect");
|
|
15
|
+
const _useStableCallback = require("./useStableCallback");
|
|
16
|
+
function useResizeObserver(ref, callback) {
|
|
17
|
+
const stableCallback = (0, _useStableCallback.useStableCallback)(callback);
|
|
18
|
+
(0, _useIsomorphicLayoutEffect.useIsomorphicLayoutEffect)(function addResizeObserverHandler() {
|
|
19
|
+
/* istanbul ignore if: невозможный кейс (в SSR вызова этой функции не будет) */ if (!ref.current) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const element = ref.current;
|
|
23
|
+
const observer = new _customResizeObserver.CustomResizeObserver(()=>stableCallback(element));
|
|
24
|
+
observer.observe(element);
|
|
25
|
+
observer.appendToTheDOM();
|
|
26
|
+
return ()=>observer.disconnect();
|
|
27
|
+
}, [
|
|
28
|
+
ref
|
|
29
|
+
]);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=useResizeObserver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/hooks/useResizeObserver.ts"],"sourcesContent":["import * as React from 'react';\nimport { CustomResizeObserver } from '../lib/floating/customResizeObserver';\nimport { useIsomorphicLayoutEffect } from '../lib/useIsomorphicLayoutEffect';\nimport { useStableCallback } from './useStableCallback';\n\n/**\n * Хук вызывает переданный коллбэк при изменении размеров элемента.\n */\nexport function useResizeObserver(\n ref: React.MutableRefObject<HTMLElement | null>,\n callback: (element: HTMLElement) => void,\n) {\n const stableCallback = useStableCallback(callback);\n\n useIsomorphicLayoutEffect(\n function addResizeObserverHandler() {\n /* istanbul ignore if: невозможный кейс (в SSR вызова этой функции не будет) */\n if (!ref.current) {\n return;\n }\n const element = ref.current;\n const observer = new CustomResizeObserver(() => stableCallback(element));\n observer.observe(element);\n observer.appendToTheDOM();\n\n return () => observer.disconnect();\n },\n [ref],\n );\n}\n"],"names":["useResizeObserver","ref","callback","stableCallback","useStableCallback","useIsomorphicLayoutEffect","addResizeObserverHandler","current","element","observer","CustomResizeObserver","observe","appendToTheDOM","disconnect"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BAQgBA;;;eAAAA;;;;iEARO;sCACc;2CACK;mCACR;AAK3B,SAASA,kBACdC,GAA+C,EAC/CC,QAAwC;IAExC,MAAMC,iBAAiBC,IAAAA,oCAAiB,EAACF;IAEzCG,IAAAA,oDAAyB,EACvB,SAASC;QACP,6EAA6E,GAC7E,IAAI,CAACL,IAAIM,OAAO,EAAE;YAChB;QACF;QACA,MAAMC,UAAUP,IAAIM,OAAO;QAC3B,MAAME,WAAW,IAAIC,0CAAoB,CAAC,IAAMP,eAAeK;QAC/DC,SAASE,OAAO,CAACH;QACjBC,SAASG,cAAc;QAEvB,OAAO,IAAMH,SAASI,UAAU;IAClC,GACA;QAACZ;KAAI;AAET"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"customResizeObserver.d.ts","sourceRoot":"","sources":["../../../../src/lib/floating/customResizeObserver.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"customResizeObserver.d.ts","sourceRoot":"","sources":["../../../../src/lib/floating/customResizeObserver.ts"],"names":[],"mappings":"AAsCA,qBAAa,oBAAoB;IAOnB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAN3C,OAAO,EAAE,KAAK,CAAC;QACb,MAAM,EAAE,WAAW,CAAC;QACpB,MAAM,EAAE,iBAAiB,CAAC;KAC3B,CAAC,CAAM;IACR,wBAAwB,EAAE,gBAAgB,GAAG,IAAI,CAAQ;gBAE5B,cAAc,EAAE,MAAM,IAAI;IAIvD,OAAO,CAAC,OAAO,EAAE,WAAW;IAO5B,cAAc;IAYd,kBAAkB,CAAC,OAAO,EAAE,WAAW;IAUvC,4BAA4B,CAAC,OAAO,EAAE,WAAW;IAWjD,UAAU;CAeX"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/floating/customResizeObserver.ts"],"sourcesContent":["const defaultIframeStyles: Pick<\n CSSStyleDeclaration,\n 'position'
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/floating/customResizeObserver.ts"],"sourcesContent":["const defaultIframeStyles: Pick<\n CSSStyleDeclaration,\n | 'position'\n | 'left'\n | 'top'\n | 'zIndex'\n | 'width'\n | 'height'\n | 'pointerEvents'\n | 'opacity'\n | 'border'\n> = {\n position: 'absolute',\n left: '0',\n top: '0',\n zIndex: '-1',\n width: '100%',\n height: '100%',\n pointerEvents: 'none',\n opacity: '0',\n border: '0',\n};\n\n/*\n * Специальный CustomResizeObserver как fallback для ResizeObserver\n * Используется для вызова update() функции (перерисовка плавающего окна) floating-ui\n * при изменении размера reference или floating элементов.\n *\n * По умолчанию пытаемся нарисовать скрытый, абсолютно позиционированный относительно\n * наблюдаемого элемента iframe.\n * В случае же, если наблюдаемый элемент имеет position: static, то правильно спозиционировать\n * iframe у нас не получится, поэтому в такой ситуации мы используем MutationObserver.\n *\n * Использовать только MutationObserver мы не можем, потому что с помощью него нельзя отследить\n * изменение размера вызванное переполнением текста.\n *\n * Применяется только если нету поддержики или полифила ResizeObserver.\n * */\nexport class CustomResizeObserver {\n records: Array<{\n target: HTMLElement;\n iframe: HTMLIFrameElement;\n }> = [];\n mutationObserverFallback: MutationObserver | null = null;\n\n constructor(private readonly updateFunction: () => void) {\n this.updateFunction = updateFunction;\n }\n\n observe(element: HTMLElement) {\n if (isPositioned(element)) {\n return this.observeUsingIframe(element);\n }\n return this.observeUsingMutationObserver(element);\n }\n\n appendToTheDOM() {\n for (let record of this.records) {\n record.target.appendChild(record.iframe);\n }\n\n for (let record of this.records) {\n if (record.iframe.contentWindow) {\n record.iframe.contentWindow.addEventListener('resize', this.updateFunction);\n }\n }\n }\n\n observeUsingIframe(element: HTMLElement) {\n const iframe = element.ownerDocument.createElement('iframe');\n iframe.src = 'javascript:void(0)';\n iframe.ariaHidden = 'true';\n iframe.tabIndex = -1;\n Object.assign(iframe.style, defaultIframeStyles);\n\n this.records.push({ target: element, iframe });\n }\n\n observeUsingMutationObserver(element: HTMLElement) {\n if (!this.mutationObserverFallback) {\n this.mutationObserverFallback = new MutationObserver(this.updateFunction);\n }\n\n this.mutationObserverFallback.observe(element, {\n childList: true,\n subtree: true,\n });\n }\n\n disconnect() {\n this.records.map(({ target, iframe }) => {\n if (iframe.contentWindow) {\n iframe.contentWindow.removeEventListener('resize', this.updateFunction);\n }\n\n target.removeChild(iframe);\n });\n this.records = [];\n\n if (this.mutationObserverFallback) {\n this.mutationObserverFallback.disconnect();\n }\n this.mutationObserverFallback = null;\n }\n}\n\nfunction isPositioned(element: HTMLElement): boolean {\n return getComputedStyle(element).position !== 'static';\n}\n"],"names":["CustomResizeObserver","defaultIframeStyles","position","left","top","zIndex","width","height","pointerEvents","opacity","border","observe","element","isPositioned","observeUsingIframe","observeUsingMutationObserver","appendToTheDOM","record","records","target","appendChild","iframe","contentWindow","addEventListener","updateFunction","ownerDocument","createElement","src","ariaHidden","tabIndex","Object","assign","style","push","mutationObserverFallback","MutationObserver","childList","subtree","disconnect","map","removeEventListener","removeChild","constructor","getComputedStyle"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;+BAsCaA;;;eAAAA;;;;AAtCb,MAAMC,sBAWF;IACFC,UAAU;IACVC,MAAM;IACNC,KAAK;IACLC,QAAQ;IACRC,OAAO;IACPC,QAAQ;IACRC,eAAe;IACfC,SAAS;IACTC,QAAQ;AACV;AAiBO,MAAMV;IAWXW,QAAQC,OAAoB,EAAE;QAC5B,IAAIC,aAAaD,UAAU;YACzB,OAAO,IAAI,CAACE,kBAAkB,CAACF;QACjC;QACA,OAAO,IAAI,CAACG,4BAA4B,CAACH;IAC3C;IAEAI,iBAAiB;QACf,KAAK,IAAIC,UAAU,IAAI,CAACC,OAAO,CAAE;YAC/BD,OAAOE,MAAM,CAACC,WAAW,CAACH,OAAOI,MAAM;QACzC;QAEA,KAAK,IAAIJ,UAAU,IAAI,CAACC,OAAO,CAAE;YAC/B,IAAID,OAAOI,MAAM,CAACC,aAAa,EAAE;gBAC/BL,OAAOI,MAAM,CAACC,aAAa,CAACC,gBAAgB,CAAC,UAAU,IAAI,CAACC,cAAc;YAC5E;QACF;IACF;IAEAV,mBAAmBF,OAAoB,EAAE;QACvC,MAAMS,SAAST,QAAQa,aAAa,CAACC,aAAa,CAAC;QACnDL,OAAOM,GAAG,GAAG;QACbN,OAAOO,UAAU,GAAG;QACpBP,OAAOQ,QAAQ,GAAG,CAAC;QACnBC,OAAOC,MAAM,CAACV,OAAOW,KAAK,EAAE/B;QAE5B,IAAI,CAACiB,OAAO,CAACe,IAAI,CAAC;YAAEd,QAAQP;YAASS;QAAO;IAC9C;IAEAN,6BAA6BH,OAAoB,EAAE;QACjD,IAAI,CAAC,IAAI,CAACsB,wBAAwB,EAAE;YAClC,IAAI,CAACA,wBAAwB,GAAG,IAAIC,iBAAiB,IAAI,CAACX,cAAc;QAC1E;QAEA,IAAI,CAACU,wBAAwB,CAACvB,OAAO,CAACC,SAAS;YAC7CwB,WAAW;YACXC,SAAS;QACX;IACF;IAEAC,aAAa;QACX,IAAI,CAACpB,OAAO,CAACqB,GAAG,CAAC,CAAC,EAAEpB,MAAM,EAAEE,MAAM,EAAE;YAClC,IAAIA,OAAOC,aAAa,EAAE;gBACxBD,OAAOC,aAAa,CAACkB,mBAAmB,CAAC,UAAU,IAAI,CAAChB,cAAc;YACxE;YAEAL,OAAOsB,WAAW,CAACpB;QACrB;QACA,IAAI,CAACH,OAAO,GAAG,EAAE;QAEjB,IAAI,IAAI,CAACgB,wBAAwB,EAAE;YACjC,IAAI,CAACA,wBAAwB,CAACI,UAAU;QAC1C;QACA,IAAI,CAACJ,wBAAwB,GAAG;IAClC;IA1DAQ,YAAY,AAAiBlB,cAA0B,CAAE;;QANzDN,yBAAAA,WAAAA,KAAAA;QAIAgB,yBAAAA,4BAAAA,KAAAA;aAE6BV,iBAAAA;aAN7BN,UAGK,EAAE;aACPgB,2BAAoD;QAGlD,IAAI,CAACV,cAAc,GAAGA;IACxB;AAyDF;AAEA,SAASX,aAAaD,OAAoB;IACxC,OAAO+B,iBAAiB/B,SAASV,QAAQ,KAAK;AAChD"}
|
package/dist/cjs/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFloatingWithInteractions.d.ts","sourceRoot":"","sources":["../../../../../src/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAIV,gCAAgC,EAChC,iCAAiC,EAClC,MAAM,SAAS,CAAC;AASjB;;GAEG;AACH,eAAO,MAAM,2BAA2B,4QAqBrC,gCAAgC,KAAG,kCAAkC,CAAC,
|
|
1
|
+
{"version":3,"file":"useFloatingWithInteractions.d.ts","sourceRoot":"","sources":["../../../../../src/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAIV,gCAAgC,EAChC,iCAAiC,EAClC,MAAM,SAAS,CAAC;AASjB;;GAEG;AACH,eAAO,MAAM,2BAA2B,4QAqBrC,gCAAgC,KAAG,kCAAkC,CAAC,CA2TxE,CAAC"}
|
|
@@ -64,7 +64,7 @@ shown: shownProp, onShownChange: onShownChangeProp })=>{
|
|
|
64
64
|
});
|
|
65
65
|
const commitShownLocalState = _react.useCallback((nextShown, reason)=>{
|
|
66
66
|
setShownLocalState((prevState)=>{
|
|
67
|
-
if (prevState.shown !== nextShown) {
|
|
67
|
+
if (prevState.shown !== nextShown || prevState.reason !== reason) {
|
|
68
68
|
return {
|
|
69
69
|
shown: nextShown,
|
|
70
70
|
reason
|
|
@@ -88,6 +88,11 @@ shown: shownProp, onShownChange: onShownChangeProp })=>{
|
|
|
88
88
|
commitShownLocalState
|
|
89
89
|
]);
|
|
90
90
|
const handleFocusOnReference = (0, _useStableCallback.useStableCallback)(()=>{
|
|
91
|
+
// Повторный вызов события фокуса - следствие клика на reference-элемент
|
|
92
|
+
if (shownLocalState.shown) {
|
|
93
|
+
commitShownLocalState(false, 'focus');
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
91
96
|
if (blockFocusRef.current) {
|
|
92
97
|
/* istanbul ignore next: в Jest не воспроизводится баг на вебе (cм. onRestoreFocus) */ blockFocusRef.current = false;
|
|
93
98
|
return;
|
|
@@ -118,6 +123,11 @@ shown: shownProp, onShownChange: onShownChangeProp })=>{
|
|
|
118
123
|
});
|
|
119
124
|
});
|
|
120
125
|
const handleClickOnReference = (0, _useStableCallback.useStableCallback)(()=>{
|
|
126
|
+
// Предыдущий триггер (фокус) уже вызвал открытие/закрытие всплывающего окна, игнорируем вызов
|
|
127
|
+
if (shownLocalState.reason === 'focus') {
|
|
128
|
+
commitShownLocalState(shownLocalState.shown, 'click');
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
121
131
|
commitShownLocalState(!shownLocalState.shown, 'click');
|
|
122
132
|
});
|
|
123
133
|
const handleClickOnReferenceForOnlyClose = (0, _useStableCallback.useStableCallback)(()=>{
|
package/dist/cjs/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.ts"],"sourcesContent":["import * as React from 'react';\nimport { debounce } from '@vkontakte/vkjs';\nimport { getWindow, isHTMLElement } from '@vkontakte/vkui-floating-ui/utils/dom';\nimport { useCustomEnsuredControl } from '../../../hooks/useEnsuredControl';\nimport { useGlobalOnClickOutside } from '../../../hooks/useGlobalOnClickOutside';\nimport { useStableCallback } from '../../../hooks/useStableCallback';\nimport { contains, getActiveElementByAnotherElement } from '../../dom';\nimport { useIsomorphicLayoutEffect } from '../../useIsomorphicLayoutEffect';\nimport { autoUpdateFloatingElement, useFloating } from '../adapters';\nimport { convertFloatingDataToReactCSSProperties } from '../functions';\nimport { type UseFloatingOptions } from '../types/common';\nimport { DEFAULT_TRIGGER } from './constants';\nimport type {\n FloatingProps,\n ReferenceProps,\n ShownChangeReason,\n UseFloatingWithInteractionsProps,\n UseFloatingWithInteractionsReturn,\n} from './types';\nimport { useResolveTriggerType } from './useResolveTriggerType';\n\ntype LocalState = { shown: boolean; reason?: ShownChangeReason };\n\nconst whileElementsMounted: UseFloatingOptions['whileElementsMounted'] = (...args) =>\n /* istanbul ignore next: не знаю как проверить */\n autoUpdateFloatingElement(...args, { elementResize: true });\n\n/**\n * @private\n */\nexport const useFloatingWithInteractions = <T extends HTMLElement = HTMLElement>({\n trigger = DEFAULT_TRIGGER,\n\n // UseFloating\n placement: placementProp = 'bottom',\n middlewares,\n hoverDelay = 0,\n closeAfterClick = false,\n\n // disables\n disabled = false,\n disableInteractive = false,\n disableCloseOnClickOutside = false,\n disableCloseOnEscKey = false,\n\n // uncontrolled\n defaultShown = false,\n\n // controlled\n shown: shownProp,\n onShownChange: onShownChangeProp,\n}: UseFloatingWithInteractionsProps): UseFloatingWithInteractionsReturn<T> => {\n const memoizedValue = React.useMemo(\n () => (shownProp !== undefined ? { shown: shownProp } : undefined),\n [shownProp],\n );\n const [shownLocalState, setShownLocalState] = useCustomEnsuredControl<LocalState>({\n value: memoizedValue,\n disabled,\n defaultValue: { shown: defaultShown },\n onChange: useStableCallback(({ shown, reason }) => {\n if (onShownChangeProp) {\n onShownChangeProp(shown, reason);\n }\n }),\n });\n const [shownFinalState, setShownFinalState] = React.useState(() => shownLocalState.shown);\n const [willBeHide, setWillBeHide] = React.useState(false);\n\n const hasCSSAnimation = React.useRef(false);\n\n const blockMouseEnterRef = React.useRef(false);\n const blockFocusRef = React.useRef(false);\n const blurTimeoutRef = React.useRef<ReturnType<typeof setTimeout>>();\n\n const handleCloseOnReferenceClickOutsideDisabled =\n disabled || disableCloseOnClickOutside || willBeHide || !shownLocalState.shown;\n const handleCloseOnFloatingClickOutsideDisabled =\n disableInteractive || handleCloseOnReferenceClickOutsideDisabled;\n\n const { triggerOnFocus, triggerOnClick, triggerOnHover } = useResolveTriggerType(trigger);\n\n // Библиотека `floating-ui`\n const { placement, x, y, strategy, refs, middlewareData } = useFloating<T>({\n strategy: 'fixed',\n placement: placementProp,\n middleware: middlewares,\n whileElementsMounted,\n });\n\n const commitShownLocalState = React.useCallback(\n (nextShown: boolean, reason: ShownChangeReason) => {\n setShownLocalState((prevState) => {\n if (prevState.shown !== nextShown) {\n return {\n shown: nextShown,\n reason,\n };\n }\n /* istanbul ignore next: страховка, если вдруг на момент вызова обновления состояния, оно уже будет актуальным */\n return prevState;\n });\n },\n [setShownLocalState],\n );\n\n const [mouseEnterDelay, mouseLeaveDelay] =\n typeof hoverDelay === 'number' ? [hoverDelay, hoverDelay] : hoverDelay;\n\n const showWithDelay = React.useMemo(\n () => debounce(() => commitShownLocalState(true, 'hover'), mouseEnterDelay),\n [mouseEnterDelay, commitShownLocalState],\n );\n\n const hideWithDelay = React.useMemo(\n () => debounce(() => commitShownLocalState(false, 'hover'), mouseLeaveDelay),\n [mouseLeaveDelay, commitShownLocalState],\n );\n\n const handleFocusOnReference = useStableCallback(() => {\n if (blockFocusRef.current) {\n /* istanbul ignore next: в Jest не воспроизводится баг на вебе (cм. onRestoreFocus) */\n blockFocusRef.current = false;\n return;\n }\n\n commitShownLocalState(true, 'focus');\n });\n\n const handleBlurOnReference = useStableCallback((event: React.FocusEvent) => {\n blockFocusRef.current = false;\n blockMouseEnterRef.current = false;\n\n if (!shownLocalState.shown) {\n clearTimeout(blurTimeoutRef.current);\n return;\n }\n\n const relatedTarget = event.relatedTarget;\n blurTimeoutRef.current = setTimeout(function waitWindowBlurFire() {\n const reference = refs.reference.current;\n // Если пользователь покинул текущее окно в открытом состоянии, то\n // не закрываем всплывающий элемент.\n /* istanbul ignore if: не умеем симулировать уход из текущего окна */\n if (!relatedTarget && getActiveElementByAnotherElement(reference) === reference) {\n /* istanbul ignore next */\n return;\n }\n\n // Если пользователь нажал на всплывающий элемент, то не закрываем всплывающий элемент.\n // Note: для этого элемент должен быть фокусируемый (например, за счёт `tabindex=\"-1\"`).\n if (contains(refs.floating.current, relatedTarget) || contains(reference, relatedTarget)) {\n return;\n }\n\n commitShownLocalState(false, 'focus');\n });\n });\n\n const handleClickOnReference = useStableCallback(() => {\n commitShownLocalState(!shownLocalState.shown, 'click');\n });\n\n const handleClickOnReferenceForOnlyClose = useStableCallback(() => {\n blockMouseEnterRef.current = true;\n commitShownLocalState(false, 'click');\n });\n\n const handleMouseEnterOnBoth = useStableCallback(() => {\n showWithDelay.cancel();\n hideWithDelay.cancel();\n\n if (!blockMouseEnterRef.current && !shownLocalState.shown) {\n showWithDelay();\n }\n });\n\n const handleMouseLeaveOnBothForHoverAndFocusStates = useStableCallback(() => {\n blockFocusRef.current = false;\n blockMouseEnterRef.current = false;\n\n if (triggerOnHover) {\n showWithDelay.cancel();\n hideWithDelay.cancel();\n\n if (shownLocalState.reason !== 'focus' && shownLocalState.reason !== 'click') {\n hideWithDelay();\n }\n }\n });\n\n const handleFloatingAnimationStart = () => {\n hasCSSAnimation.current = true;\n };\n\n const handleFloatingAnimationEnd = () => {\n if (willBeHide) {\n setShownFinalState(false);\n setWillBeHide(false);\n }\n };\n\n const handleOnClose = React.useCallback(() => {\n blockFocusRef.current = true;\n commitShownLocalState(false, 'callback');\n }, [commitShownLocalState]);\n\n const handleRestoreFocus = React.useCallback(\n () => (triggerOnFocus ? blockFocusRef.current : true),\n [triggerOnFocus],\n );\n\n const handleEscapeKeyDown = React.useCallback(() => {\n blockFocusRef.current = true;\n commitShownLocalState(false, 'escape-key');\n }, [commitShownLocalState]);\n\n const handleClickOutside = React.useCallback(() => {\n blockFocusRef.current = true;\n commitShownLocalState(false, 'click-outside');\n }, [commitShownLocalState]);\n\n useGlobalOnClickOutside(\n handleClickOutside,\n handleCloseOnReferenceClickOutsideDisabled ? null : refs.reference,\n handleCloseOnFloatingClickOutsideDisabled ? null : refs.floating,\n );\n\n useIsomorphicLayoutEffect(\n /**\n * Если пользователь покинул активное окно и:\n * 1. целевой элемент был в состоянии фокуса;\n * 2. всплывающий элемент был закрытом состоянии;\n * то фокус должен быть заблокирован, когда пользователь вернётся обратно. Иначе покажется\n * всплывающий элемент.\n */\n function setGlobalBlurForTriggerOnFocus() {\n if (!triggerOnFocus || !refs.reference.current) {\n return;\n }\n\n const handleGlobalBlur = () => {\n /* istanbul ignore next */\n const reference = refs.reference.current;\n /* istanbul ignore if: не умеем симулировать уход из текущего окна */\n if (\n !shownLocalState.shown &&\n isHTMLElement(reference) &&\n reference === getActiveElementByAnotherElement(reference)\n ) {\n /* istanbul ignore next */\n blockFocusRef.current = true;\n }\n };\n\n const win = getWindow(refs.reference.current);\n win.addEventListener('blur', handleGlobalBlur);\n return () => {\n win.removeEventListener('blur', handleGlobalBlur);\n };\n },\n [triggerOnFocus, refs.reference, shownLocalState],\n );\n\n useIsomorphicLayoutEffect(\n function resolveShownStates() {\n if (willBeHide || shownLocalState.shown === shownFinalState) {\n return;\n }\n\n if (shownLocalState.shown) {\n setShownFinalState(true);\n } else if (hasCSSAnimation.current && !willBeHide) {\n setWillBeHide(true);\n } else {\n setShownFinalState(false);\n }\n\n return () => {\n clearTimeout(blurTimeoutRef.current);\n };\n },\n [shownLocalState, shownFinalState, willBeHide],\n );\n\n const referencePropsRef = React.useRef<ReferenceProps>({});\n const floatingPropsRef = React.useRef<FloatingProps>({ style: {} });\n\n if (shownFinalState) {\n floatingPropsRef.current.style = convertFloatingDataToReactCSSProperties(\n strategy,\n x,\n y,\n undefined,\n middlewareData,\n );\n\n if (disableInteractive) {\n floatingPropsRef.current.style.pointerEvents = 'none';\n }\n }\n\n if (triggerOnFocus) {\n referencePropsRef.current.onFocus = handleFocusOnReference;\n referencePropsRef.current.onBlur = handleBlurOnReference;\n }\n\n if (triggerOnClick) {\n referencePropsRef.current.onClick = handleClickOnReference;\n }\n\n if (triggerOnHover) {\n referencePropsRef.current.onMouseOver = handleMouseEnterOnBoth;\n\n if (closeAfterClick && !triggerOnClick) {\n referencePropsRef.current.onClick = handleClickOnReferenceForOnlyClose;\n }\n\n if (!disableInteractive) {\n floatingPropsRef.current.onMouseOver = handleMouseEnterOnBoth;\n }\n }\n\n if (triggerOnHover || triggerOnFocus) {\n referencePropsRef.current.onMouseLeave = handleMouseLeaveOnBothForHoverAndFocusStates;\n\n if (!disableInteractive) {\n floatingPropsRef.current.onMouseLeave = handleMouseLeaveOnBothForHoverAndFocusStates;\n }\n }\n\n if (shownFinalState) {\n floatingPropsRef.current.onAnimationStart = handleFloatingAnimationStart;\n floatingPropsRef.current.onAnimationEnd = handleFloatingAnimationEnd;\n }\n\n return {\n placement,\n shown: shownFinalState,\n willBeHide,\n refs,\n referenceProps: referencePropsRef.current,\n floatingProps: floatingPropsRef.current,\n middlewareData,\n onClose: handleOnClose,\n // FocusTrap уже определяет нажатие на ESC, поэтому название события содержит конкретный код\n // кнопки вместо просто onKeyDown.\n onEscapeKeyDown: !shownFinalState || disableCloseOnEscKey ? undefined : handleEscapeKeyDown,\n // [Обход баги с FocusTrap]\n //\n // Если сфокусироваться на целевой элемент через нажатие, а потом нажать в область за пределами\n // целевого и всплывающего элемента, то появляется моргание из-за того, что FocusTrap\n // восстанавливает фокус, из-за чего всплывающий элемент снова показывается за счёт\n // `handleFocusOnReference`, а потом скрывается за счёт `handleBlurOnReference`.\n onRestoreFocus: handleRestoreFocus,\n };\n};\n"],"names":["useFloatingWithInteractions","whileElementsMounted","args","autoUpdateFloatingElement","elementResize","trigger","DEFAULT_TRIGGER","placement","placementProp","middlewares","hoverDelay","closeAfterClick","disabled","disableInteractive","disableCloseOnClickOutside","disableCloseOnEscKey","defaultShown","shown","shownProp","onShownChange","onShownChangeProp","memoizedValue","React","useMemo","undefined","shownLocalState","setShownLocalState","useCustomEnsuredControl","value","defaultValue","onChange","useStableCallback","reason","shownFinalState","setShownFinalState","useState","willBeHide","setWillBeHide","hasCSSAnimation","useRef","blockMouseEnterRef","blockFocusRef","blurTimeoutRef","handleCloseOnReferenceClickOutsideDisabled","handleCloseOnFloatingClickOutsideDisabled","triggerOnFocus","triggerOnClick","triggerOnHover","useResolveTriggerType","x","y","strategy","refs","middlewareData","useFloating","middleware","commitShownLocalState","useCallback","nextShown","prevState","mouseEnterDelay","mouseLeaveDelay","showWithDelay","debounce","hideWithDelay","handleFocusOnReference","current","handleBlurOnReference","event","clearTimeout","relatedTarget","setTimeout","waitWindowBlurFire","reference","getActiveElementByAnotherElement","contains","floating","handleClickOnReference","handleClickOnReferenceForOnlyClose","handleMouseEnterOnBoth","cancel","handleMouseLeaveOnBothForHoverAndFocusStates","handleFloatingAnimationStart","handleFloatingAnimationEnd","handleOnClose","handleRestoreFocus","handleEscapeKeyDown","handleClickOutside","useGlobalOnClickOutside","useIsomorphicLayoutEffect","setGlobalBlurForTriggerOnFocus","handleGlobalBlur","isHTMLElement","win","getWindow","addEventListener","removeEventListener","resolveShownStates","referencePropsRef","floatingPropsRef","style","convertFloatingDataToReactCSSProperties","pointerEvents","onFocus","onBlur","onClick","onMouseOver","onMouseLeave","onAnimationStart","onAnimationEnd","referenceProps","floatingProps","onClose","onEscapeKeyDown","onRestoreFocus"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../src/lib/floating/useFloatingWithInteractions/useFloatingWithInteractions.ts"],"sourcesContent":["import * as React from 'react';\nimport { debounce } from '@vkontakte/vkjs';\nimport { getWindow, isHTMLElement } from '@vkontakte/vkui-floating-ui/utils/dom';\nimport { useCustomEnsuredControl } from '../../../hooks/useEnsuredControl';\nimport { useGlobalOnClickOutside } from '../../../hooks/useGlobalOnClickOutside';\nimport { useStableCallback } from '../../../hooks/useStableCallback';\nimport { contains, getActiveElementByAnotherElement } from '../../dom';\nimport { useIsomorphicLayoutEffect } from '../../useIsomorphicLayoutEffect';\nimport { autoUpdateFloatingElement, useFloating } from '../adapters';\nimport { convertFloatingDataToReactCSSProperties } from '../functions';\nimport { type UseFloatingOptions } from '../types/common';\nimport { DEFAULT_TRIGGER } from './constants';\nimport type {\n FloatingProps,\n ReferenceProps,\n ShownChangeReason,\n UseFloatingWithInteractionsProps,\n UseFloatingWithInteractionsReturn,\n} from './types';\nimport { useResolveTriggerType } from './useResolveTriggerType';\n\ntype LocalState = { shown: boolean; reason?: ShownChangeReason };\n\nconst whileElementsMounted: UseFloatingOptions['whileElementsMounted'] = (...args) =>\n /* istanbul ignore next: не знаю как проверить */\n autoUpdateFloatingElement(...args, { elementResize: true });\n\n/**\n * @private\n */\nexport const useFloatingWithInteractions = <T extends HTMLElement = HTMLElement>({\n trigger = DEFAULT_TRIGGER,\n\n // UseFloating\n placement: placementProp = 'bottom',\n middlewares,\n hoverDelay = 0,\n closeAfterClick = false,\n\n // disables\n disabled = false,\n disableInteractive = false,\n disableCloseOnClickOutside = false,\n disableCloseOnEscKey = false,\n\n // uncontrolled\n defaultShown = false,\n\n // controlled\n shown: shownProp,\n onShownChange: onShownChangeProp,\n}: UseFloatingWithInteractionsProps): UseFloatingWithInteractionsReturn<T> => {\n const memoizedValue = React.useMemo(\n () => (shownProp !== undefined ? { shown: shownProp } : undefined),\n [shownProp],\n );\n const [shownLocalState, setShownLocalState] = useCustomEnsuredControl<LocalState>({\n value: memoizedValue,\n disabled,\n defaultValue: { shown: defaultShown },\n onChange: useStableCallback(({ shown, reason }) => {\n if (onShownChangeProp) {\n onShownChangeProp(shown, reason);\n }\n }),\n });\n const [shownFinalState, setShownFinalState] = React.useState(() => shownLocalState.shown);\n const [willBeHide, setWillBeHide] = React.useState(false);\n\n const hasCSSAnimation = React.useRef(false);\n\n const blockMouseEnterRef = React.useRef(false);\n const blockFocusRef = React.useRef(false);\n const blurTimeoutRef = React.useRef<ReturnType<typeof setTimeout>>();\n\n const handleCloseOnReferenceClickOutsideDisabled =\n disabled || disableCloseOnClickOutside || willBeHide || !shownLocalState.shown;\n const handleCloseOnFloatingClickOutsideDisabled =\n disableInteractive || handleCloseOnReferenceClickOutsideDisabled;\n\n const { triggerOnFocus, triggerOnClick, triggerOnHover } = useResolveTriggerType(trigger);\n\n // Библиотека `floating-ui`\n const { placement, x, y, strategy, refs, middlewareData } = useFloating<T>({\n strategy: 'fixed',\n placement: placementProp,\n middleware: middlewares,\n whileElementsMounted,\n });\n\n const commitShownLocalState = React.useCallback(\n (nextShown: boolean, reason: ShownChangeReason) => {\n setShownLocalState((prevState) => {\n if (prevState.shown !== nextShown || prevState.reason !== reason) {\n return {\n shown: nextShown,\n reason,\n };\n }\n /* istanbul ignore next: страховка, если вдруг на момент вызова обновления состояния, оно уже будет актуальным */\n return prevState;\n });\n },\n [setShownLocalState],\n );\n\n const [mouseEnterDelay, mouseLeaveDelay] =\n typeof hoverDelay === 'number' ? [hoverDelay, hoverDelay] : hoverDelay;\n\n const showWithDelay = React.useMemo(\n () => debounce(() => commitShownLocalState(true, 'hover'), mouseEnterDelay),\n [mouseEnterDelay, commitShownLocalState],\n );\n\n const hideWithDelay = React.useMemo(\n () => debounce(() => commitShownLocalState(false, 'hover'), mouseLeaveDelay),\n [mouseLeaveDelay, commitShownLocalState],\n );\n\n const handleFocusOnReference = useStableCallback(() => {\n // Повторный вызов события фокуса - следствие клика на reference-элемент\n if (shownLocalState.shown) {\n commitShownLocalState(false, 'focus');\n return;\n }\n if (blockFocusRef.current) {\n /* istanbul ignore next: в Jest не воспроизводится баг на вебе (cм. onRestoreFocus) */\n blockFocusRef.current = false;\n return;\n }\n\n commitShownLocalState(true, 'focus');\n });\n\n const handleBlurOnReference = useStableCallback((event: React.FocusEvent) => {\n blockFocusRef.current = false;\n blockMouseEnterRef.current = false;\n\n if (!shownLocalState.shown) {\n clearTimeout(blurTimeoutRef.current);\n return;\n }\n\n const relatedTarget = event.relatedTarget;\n blurTimeoutRef.current = setTimeout(function waitWindowBlurFire() {\n const reference = refs.reference.current;\n // Если пользователь покинул текущее окно в открытом состоянии, то\n // не закрываем всплывающий элемент.\n /* istanbul ignore if: не умеем симулировать уход из текущего окна */\n if (!relatedTarget && getActiveElementByAnotherElement(reference) === reference) {\n /* istanbul ignore next */\n return;\n }\n\n // Если пользователь нажал на всплывающий элемент, то не закрываем всплывающий элемент.\n // Note: для этого элемент должен быть фокусируемый (например, за счёт `tabindex=\"-1\"`).\n if (contains(refs.floating.current, relatedTarget) || contains(reference, relatedTarget)) {\n return;\n }\n\n commitShownLocalState(false, 'focus');\n });\n });\n\n const handleClickOnReference = useStableCallback(() => {\n // Предыдущий триггер (фокус) уже вызвал открытие/закрытие всплывающего окна, игнорируем вызов\n if (shownLocalState.reason === 'focus') {\n commitShownLocalState(shownLocalState.shown, 'click');\n return;\n }\n commitShownLocalState(!shownLocalState.shown, 'click');\n });\n\n const handleClickOnReferenceForOnlyClose = useStableCallback(() => {\n blockMouseEnterRef.current = true;\n commitShownLocalState(false, 'click');\n });\n\n const handleMouseEnterOnBoth = useStableCallback(() => {\n showWithDelay.cancel();\n hideWithDelay.cancel();\n\n if (!blockMouseEnterRef.current && !shownLocalState.shown) {\n showWithDelay();\n }\n });\n\n const handleMouseLeaveOnBothForHoverAndFocusStates = useStableCallback(() => {\n blockFocusRef.current = false;\n blockMouseEnterRef.current = false;\n\n if (triggerOnHover) {\n showWithDelay.cancel();\n hideWithDelay.cancel();\n\n if (shownLocalState.reason !== 'focus' && shownLocalState.reason !== 'click') {\n hideWithDelay();\n }\n }\n });\n\n const handleFloatingAnimationStart = () => {\n hasCSSAnimation.current = true;\n };\n\n const handleFloatingAnimationEnd = () => {\n if (willBeHide) {\n setShownFinalState(false);\n setWillBeHide(false);\n }\n };\n\n const handleOnClose = React.useCallback(() => {\n blockFocusRef.current = true;\n commitShownLocalState(false, 'callback');\n }, [commitShownLocalState]);\n\n const handleRestoreFocus = React.useCallback(\n () => (triggerOnFocus ? blockFocusRef.current : true),\n [triggerOnFocus],\n );\n\n const handleEscapeKeyDown = React.useCallback(() => {\n blockFocusRef.current = true;\n commitShownLocalState(false, 'escape-key');\n }, [commitShownLocalState]);\n\n const handleClickOutside = React.useCallback(() => {\n blockFocusRef.current = true;\n commitShownLocalState(false, 'click-outside');\n }, [commitShownLocalState]);\n\n useGlobalOnClickOutside(\n handleClickOutside,\n handleCloseOnReferenceClickOutsideDisabled ? null : refs.reference,\n handleCloseOnFloatingClickOutsideDisabled ? null : refs.floating,\n );\n\n useIsomorphicLayoutEffect(\n /**\n * Если пользователь покинул активное окно и:\n * 1. целевой элемент был в состоянии фокуса;\n * 2. всплывающий элемент был закрытом состоянии;\n * то фокус должен быть заблокирован, когда пользователь вернётся обратно. Иначе покажется\n * всплывающий элемент.\n */\n function setGlobalBlurForTriggerOnFocus() {\n if (!triggerOnFocus || !refs.reference.current) {\n return;\n }\n\n const handleGlobalBlur = () => {\n /* istanbul ignore next */\n const reference = refs.reference.current;\n /* istanbul ignore if: не умеем симулировать уход из текущего окна */\n if (\n !shownLocalState.shown &&\n isHTMLElement(reference) &&\n reference === getActiveElementByAnotherElement(reference)\n ) {\n /* istanbul ignore next */\n blockFocusRef.current = true;\n }\n };\n\n const win = getWindow(refs.reference.current);\n win.addEventListener('blur', handleGlobalBlur);\n return () => {\n win.removeEventListener('blur', handleGlobalBlur);\n };\n },\n [triggerOnFocus, refs.reference, shownLocalState],\n );\n\n useIsomorphicLayoutEffect(\n function resolveShownStates() {\n if (willBeHide || shownLocalState.shown === shownFinalState) {\n return;\n }\n\n if (shownLocalState.shown) {\n setShownFinalState(true);\n } else if (hasCSSAnimation.current && !willBeHide) {\n setWillBeHide(true);\n } else {\n setShownFinalState(false);\n }\n\n return () => {\n clearTimeout(blurTimeoutRef.current);\n };\n },\n [shownLocalState, shownFinalState, willBeHide],\n );\n\n const referencePropsRef = React.useRef<ReferenceProps>({});\n const floatingPropsRef = React.useRef<FloatingProps>({ style: {} });\n\n if (shownFinalState) {\n floatingPropsRef.current.style = convertFloatingDataToReactCSSProperties(\n strategy,\n x,\n y,\n undefined,\n middlewareData,\n );\n\n if (disableInteractive) {\n floatingPropsRef.current.style.pointerEvents = 'none';\n }\n }\n\n if (triggerOnFocus) {\n referencePropsRef.current.onFocus = handleFocusOnReference;\n referencePropsRef.current.onBlur = handleBlurOnReference;\n }\n\n if (triggerOnClick) {\n referencePropsRef.current.onClick = handleClickOnReference;\n }\n\n if (triggerOnHover) {\n referencePropsRef.current.onMouseOver = handleMouseEnterOnBoth;\n\n if (closeAfterClick && !triggerOnClick) {\n referencePropsRef.current.onClick = handleClickOnReferenceForOnlyClose;\n }\n\n if (!disableInteractive) {\n floatingPropsRef.current.onMouseOver = handleMouseEnterOnBoth;\n }\n }\n\n if (triggerOnHover || triggerOnFocus) {\n referencePropsRef.current.onMouseLeave = handleMouseLeaveOnBothForHoverAndFocusStates;\n\n if (!disableInteractive) {\n floatingPropsRef.current.onMouseLeave = handleMouseLeaveOnBothForHoverAndFocusStates;\n }\n }\n\n if (shownFinalState) {\n floatingPropsRef.current.onAnimationStart = handleFloatingAnimationStart;\n floatingPropsRef.current.onAnimationEnd = handleFloatingAnimationEnd;\n }\n\n return {\n placement,\n shown: shownFinalState,\n willBeHide,\n refs,\n referenceProps: referencePropsRef.current,\n floatingProps: floatingPropsRef.current,\n middlewareData,\n onClose: handleOnClose,\n // FocusTrap уже определяет нажатие на ESC, поэтому название события содержит конкретный код\n // кнопки вместо просто onKeyDown.\n onEscapeKeyDown: !shownFinalState || disableCloseOnEscKey ? undefined : handleEscapeKeyDown,\n // [Обход баги с FocusTrap]\n //\n // Если сфокусироваться на целевой элемент через нажатие, а потом нажать в область за пределами\n // целевого и всплывающего элемента, то появляется моргание из-за того, что FocusTrap\n // восстанавливает фокус, из-за чего всплывающий элемент снова показывается за счёт\n // `handleFocusOnReference`, а потом скрывается за счёт `handleBlurOnReference`.\n onRestoreFocus: handleRestoreFocus,\n };\n};\n"],"names":["useFloatingWithInteractions","whileElementsMounted","args","autoUpdateFloatingElement","elementResize","trigger","DEFAULT_TRIGGER","placement","placementProp","middlewares","hoverDelay","closeAfterClick","disabled","disableInteractive","disableCloseOnClickOutside","disableCloseOnEscKey","defaultShown","shown","shownProp","onShownChange","onShownChangeProp","memoizedValue","React","useMemo","undefined","shownLocalState","setShownLocalState","useCustomEnsuredControl","value","defaultValue","onChange","useStableCallback","reason","shownFinalState","setShownFinalState","useState","willBeHide","setWillBeHide","hasCSSAnimation","useRef","blockMouseEnterRef","blockFocusRef","blurTimeoutRef","handleCloseOnReferenceClickOutsideDisabled","handleCloseOnFloatingClickOutsideDisabled","triggerOnFocus","triggerOnClick","triggerOnHover","useResolveTriggerType","x","y","strategy","refs","middlewareData","useFloating","middleware","commitShownLocalState","useCallback","nextShown","prevState","mouseEnterDelay","mouseLeaveDelay","showWithDelay","debounce","hideWithDelay","handleFocusOnReference","current","handleBlurOnReference","event","clearTimeout","relatedTarget","setTimeout","waitWindowBlurFire","reference","getActiveElementByAnotherElement","contains","floating","handleClickOnReference","handleClickOnReferenceForOnlyClose","handleMouseEnterOnBoth","cancel","handleMouseLeaveOnBothForHoverAndFocusStates","handleFloatingAnimationStart","handleFloatingAnimationEnd","handleOnClose","handleRestoreFocus","handleEscapeKeyDown","handleClickOutside","useGlobalOnClickOutside","useIsomorphicLayoutEffect","setGlobalBlurForTriggerOnFocus","handleGlobalBlur","isHTMLElement","win","getWindow","addEventListener","removeEventListener","resolveShownStates","referencePropsRef","floatingPropsRef","style","convertFloatingDataToReactCSSProperties","pointerEvents","onFocus","onBlur","onClick","onMouseOver","onMouseLeave","onAnimationStart","onAnimationEnd","referenceProps","floatingProps","onClose","onEscapeKeyDown","onRestoreFocus"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useState.d.ts","sourceRoot":"","sources":["../../../src/components/Clickable/useState.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;
|
|
1
|
+
{"version":3,"file":"useState.d.ts","sourceRoot":"","sources":["../../../src/components/Clickable/useState.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AASD,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAE/C,eAAO,MAAM,YAAY,KAAK,CAAC;AAwE/B,eAAO,MAAM,yBAAyB,qBAAwC,OAAO,KAAK,IAAI,cAE7F,CAAC;AAEF;;GAEG;AACH,wBAAgB,YAAY,uEAO3B;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,SAAS,EAAE,EAAE,UAAU;;;EAyBzE"}
|
|
@@ -9,9 +9,9 @@ export const DEFAULT_ACTIVE_EFFECT_DELAY = 600;
|
|
|
9
9
|
export const ACTIVE_DELAY = 70;
|
|
10
10
|
/**
|
|
11
11
|
* Управляет наведением на компонент, игнорирует тач события
|
|
12
|
-
*/ function useHover({ hovered, hoverClassName, hasHover = true }) {
|
|
12
|
+
*/ function useHover({ hovered, hoverClassName, hasHover = true, lockState }) {
|
|
13
13
|
const [hoveredState, setHover] = React.useState(false);
|
|
14
|
-
const hover = hasHover && (hovered || hoveredState) ? hoverClassName : undefined;
|
|
14
|
+
const hover = hasHover && !lockState && (hovered || hoveredState) ? hoverClassName : undefined;
|
|
15
15
|
const onPointerEnter = (e)=>{
|
|
16
16
|
if (e.pointerType === 'touch') {
|
|
17
17
|
return;
|
|
@@ -29,11 +29,11 @@ export const ACTIVE_DELAY = 70;
|
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
31
|
* Управляет активацией компонента
|
|
32
|
-
*/ function useActive({ activated, activeClassName, activeEffectDelay, hasActive = true }) {
|
|
32
|
+
*/ function useActive({ activated, activeClassName, activeEffectDelay, hasActive = true, lockState }) {
|
|
33
33
|
const [activatedState, setActivated] = useStateWithDelay(false);
|
|
34
34
|
// Список нажатий которые не требуется отменять
|
|
35
35
|
const pointersUp = React.useMemo(()=>new Set(), []);
|
|
36
|
-
const active = hasActive && (activated || activatedState) ? activeClassName : undefined;
|
|
36
|
+
const active = hasActive && !lockState && (activated || activatedState) ? activeClassName : undefined;
|
|
37
37
|
const onPointerDown = ()=>setActivated(true, ACTIVE_DELAY);
|
|
38
38
|
const onPointerCancel = (e)=>{
|
|
39
39
|
if (pointersUp.has(e.pointerId)) {
|
|
@@ -77,8 +77,9 @@ export const ClickableLockStateContext = /*#__PURE__*/ React.createContext(undef
|
|
|
77
77
|
]);
|
|
78
78
|
const [lockState, setLockBubbling, setLockBubblingImmediate] = useLockState();
|
|
79
79
|
const props = _object_spread({
|
|
80
|
-
hasHover
|
|
81
|
-
hasActive
|
|
80
|
+
hasHover,
|
|
81
|
+
hasActive,
|
|
82
|
+
lockState
|
|
82
83
|
}, restProps);
|
|
83
84
|
const _useHover = useHover(_object_spread({}, props)), { hover } = _useHover, hoverEvent = _object_without_properties(_useHover, [
|
|
84
85
|
"hover"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/Clickable/useState.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames, noop } from '@vkontakte/vkjs';\nimport { callMultiple } from '../../lib/callMultiple';\nimport { mergeCalls } from '../../lib/mergeCalls';\nimport { useStateWithDelay } from './useStateWithDelay';\n\nexport interface StateProps {\n /**\n * Указывает, должен ли компонент реагировать на hover-состояние\n */\n hasHover?: boolean;\n /**\n * Позволяет управлять hovered-состоянием извне\n */\n hovered?: boolean;\n /**\n * Позволяет управлять activated-состоянием извне\n */\n activated?: boolean;\n /**\n * Указывает, должен ли компонент реагировать на active-состояние\n */\n hasActive?: boolean;\n\n /**\n * Длительность показа `activated`-состояния\n */\n activeEffectDelay?: number;\n\n /**\n * Стиль подсветки active-состояния\n */\n activeClassName?: string;\n\n /**\n * Стиль подсветки hover-состояния\n */\n hoverClassName?: string;\n}\n\nexport const DEFAULT_ACTIVE_EFFECT_DELAY = 600;\n\nexport const ACTIVE_DELAY = 70;\n\n/**\n * Управляет наведением на компонент, игнорирует тач события\n */\nfunction useHover({ hovered, hoverClassName, hasHover = true }:
|
|
1
|
+
{"version":3,"sources":["../../../src/components/Clickable/useState.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames, noop } from '@vkontakte/vkjs';\nimport { callMultiple } from '../../lib/callMultiple';\nimport { mergeCalls } from '../../lib/mergeCalls';\nimport { useStateWithDelay } from './useStateWithDelay';\n\nexport interface StateProps {\n /**\n * Указывает, должен ли компонент реагировать на hover-состояние\n */\n hasHover?: boolean;\n /**\n * Позволяет управлять hovered-состоянием извне\n */\n hovered?: boolean;\n /**\n * Позволяет управлять activated-состоянием извне\n */\n activated?: boolean;\n /**\n * Указывает, должен ли компонент реагировать на active-состояние\n */\n hasActive?: boolean;\n\n /**\n * Длительность показа `activated`-состояния\n */\n activeEffectDelay?: number;\n\n /**\n * Стиль подсветки active-состояния\n */\n activeClassName?: string;\n\n /**\n * Стиль подсветки hover-состояния\n */\n hoverClassName?: string;\n}\n\ninterface StateHookProps extends StateProps {\n /**\n * Блокирование активации состояний\n */\n lockState: boolean;\n}\n\nexport const DEFAULT_ACTIVE_EFFECT_DELAY = 600;\n\nexport const ACTIVE_DELAY = 70;\n\n/**\n * Управляет наведением на компонент, игнорирует тач события\n */\nfunction useHover({ hovered, hoverClassName, hasHover = true, lockState }: StateHookProps) {\n const [hoveredState, setHover] = React.useState(false);\n\n const hover = hasHover && !lockState && (hovered || hoveredState) ? hoverClassName : undefined;\n\n const onPointerEnter: React.PointerEventHandler<any> = (e) => {\n if (e.pointerType === 'touch') {\n return;\n }\n\n setHover(true);\n };\n\n const onPointerLeave = () => {\n setHover(false);\n };\n\n return {\n hover,\n onPointerEnter: hasHover ? onPointerEnter : noop,\n onPointerLeave: hasHover ? onPointerLeave : noop,\n };\n}\n\n/**\n * Управляет активацией компонента\n */\nfunction useActive({\n activated,\n activeClassName,\n activeEffectDelay,\n hasActive = true,\n lockState,\n}: StateHookProps) {\n const [activatedState, setActivated] = useStateWithDelay(false);\n\n // Список нажатий которые не требуется отменять\n const pointersUp = React.useMemo(() => new Set<number>(), []);\n\n const active =\n hasActive && !lockState && (activated || activatedState) ? activeClassName : undefined;\n\n const onPointerDown = () => setActivated(true, ACTIVE_DELAY);\n const onPointerCancel: React.PointerEventHandler = (e) => {\n if (pointersUp.has(e.pointerId)) {\n pointersUp.delete(e.pointerId);\n return;\n }\n\n setActivated(false);\n };\n\n const onPointerUp: React.PointerEventHandler = (e) => {\n pointersUp.add(e.pointerId);\n setActivated(true);\n setActivated(false, activeEffectDelay);\n };\n\n return {\n active,\n onPointerLeave: hasActive ? onPointerCancel : noop,\n onPointerDown: hasActive ? onPointerDown : noop,\n onPointerCancel: hasActive ? onPointerCancel : noop,\n onPointerUp: hasActive ? onPointerUp : noop,\n };\n}\n\nexport const ClickableLockStateContext = React.createContext<undefined | ((v: boolean) => void)>(\n undefined,\n);\n\n/**\n * Блокирует стейт на всплытие\n */\nexport function useLockState() {\n const setLockBubbling = React.useContext(ClickableLockStateContext) || noop;\n const [lockState, setLockState] = React.useState(false);\n\n const setLockBubblingImmediate = callMultiple(setLockState, setLockBubbling);\n\n return [lockState, setLockBubbling, setLockBubblingImmediate] as const;\n}\n\n/**\n * Управляет состоянием компонента\n */\nexport function useState({ hasHover, hasActive, ...restProps }: StateProps) {\n const [lockState, setLockBubbling, setLockBubblingImmediate] = useLockState();\n\n const props = {\n hasHover,\n hasActive,\n lockState,\n ...restProps,\n };\n\n const { hover, ...hoverEvent } = useHover({ ...props });\n const { active, ...activeEvent } = useActive(props);\n\n const stateClassName = classNames(hover, active);\n const handlers = mergeCalls(hoverEvent, activeEvent);\n\n React.useEffect(() => {\n setLockBubbling(!!stateClassName);\n }, [setLockBubbling, stateClassName]);\n\n return {\n stateClassName,\n setLockBubblingImmediate,\n ...handlers,\n };\n}\n"],"names":["React","classNames","noop","callMultiple","mergeCalls","useStateWithDelay","DEFAULT_ACTIVE_EFFECT_DELAY","ACTIVE_DELAY","useHover","hovered","hoverClassName","hasHover","lockState","hoveredState","setHover","useState","hover","undefined","onPointerEnter","e","pointerType","onPointerLeave","useActive","activated","activeClassName","activeEffectDelay","hasActive","activatedState","setActivated","pointersUp","useMemo","Set","active","onPointerDown","onPointerCancel","has","pointerId","delete","onPointerUp","add","ClickableLockStateContext","createContext","useLockState","setLockBubbling","useContext","setLockState","setLockBubblingImmediate","restProps","props","hoverEvent","activeEvent","stateClassName","handlers","useEffect"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CustomScrollView.d.ts","sourceRoot":"","sources":["../../../src/components/CustomScrollView/CustomScrollView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"CustomScrollView.d.ts","sourceRoot":"","sources":["../../../src/components/CustomScrollView/CustomScrollView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAwB,MAAM,wBAAwB,CAAC;AAenF,MAAM,WAAW,qBACf,SAAQ,KAAK,CAAC,iBAAiB,CAAC,cAAc,CAAC,EAC7C,UAAU,CAAC,cAAc,CAAC,EAC1B,mBAAmB;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,cAAc,CAAC,WAAW,CAAC,CAAC;IACxC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;IAC1D,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,eAAO,MAAM,gBAAgB,iJAU1B,qBAAqB,4CAmLvB,CAAC"}
|
|
@@ -7,6 +7,7 @@ import { classNames } from '@vkontakte/vkjs';
|
|
|
7
7
|
import { useAdaptivity } from '../../hooks/useAdaptivity';
|
|
8
8
|
import { useEventListener } from '../../hooks/useEventListener';
|
|
9
9
|
import { useExternRef } from '../../hooks/useExternRef';
|
|
10
|
+
import { useResizeObserver } from '../../hooks/useResizeObserver';
|
|
10
11
|
import { useDOM } from '../../lib/dom';
|
|
11
12
|
import { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';
|
|
12
13
|
import { stopPropagation } from '../../lib/utils';
|
|
@@ -44,6 +45,7 @@ export const CustomScrollView = (_param)=>{
|
|
|
44
45
|
const startY = React.useRef(0);
|
|
45
46
|
const trackerTop = React.useRef(0);
|
|
46
47
|
const boxRef = useExternRef(externalBoxRef);
|
|
48
|
+
const boxContentRef = React.useRef(null);
|
|
47
49
|
const barY = React.useRef(null);
|
|
48
50
|
const trackerY = React.useRef(null);
|
|
49
51
|
const setTrackerPosition = (scrollTop)=>{
|
|
@@ -85,6 +87,7 @@ export const CustomScrollView = (_param)=>{
|
|
|
85
87
|
windowResize,
|
|
86
88
|
window
|
|
87
89
|
]);
|
|
90
|
+
useResizeObserver(boxContentRef, resize);
|
|
88
91
|
useIsomorphicLayoutEffect(()=>{
|
|
89
92
|
var _trackerY_current;
|
|
90
93
|
let style = (_trackerY_current = trackerY.current) === null || _trackerY_current === void 0 ? void 0 : _trackerY_current.style;
|
|
@@ -160,7 +163,11 @@ export const CustomScrollView = (_param)=>{
|
|
|
160
163
|
tabIndex: -1,
|
|
161
164
|
ref: boxRef,
|
|
162
165
|
onScroll: scroll,
|
|
163
|
-
children:
|
|
166
|
+
children: /*#__PURE__*/ _jsx("div", {
|
|
167
|
+
ref: boxContentRef,
|
|
168
|
+
className: "vkuiCustomScrollView__box-content",
|
|
169
|
+
children: children
|
|
170
|
+
})
|
|
164
171
|
}),
|
|
165
172
|
/*#__PURE__*/ _jsx("div", {
|
|
166
173
|
className: "vkuiCustomScrollView__barY",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/CustomScrollView/CustomScrollView.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { useEventListener } from '../../hooks/useEventListener';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useDOM } from '../../lib/dom';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport { stopPropagation } from '../../lib/utils';\nimport type { HasRootRef } from '../../types';\nimport { TrackerOptionsProps, useTrackerVisibility } from './useTrackerVisibility';\nimport styles from './CustomScrollView.module.css';\n\nfunction hasPointerClassName(hasPointer: boolean | undefined) {\n switch (hasPointer) {\n case true:\n return styles['CustomScrollView--hasPointer-true'];\n case false:\n return styles['CustomScrollView--hasPointer-false'];\n case undefined:\n default:\n return styles['CustomScrollView--hasPointer-none'];\n }\n}\n\nexport interface CustomScrollViewProps\n extends React.AllHTMLAttributes<HTMLDivElement>,\n HasRootRef<HTMLDivElement>,\n TrackerOptionsProps {\n windowResize?: boolean;\n boxRef?: React.Ref<HTMLDivElement>;\n className?: HTMLDivElement['className'];\n onScroll?: (event: React.UIEvent<HTMLDivElement>) => void;\n children: React.ReactNode;\n}\n\nexport const CustomScrollView = ({\n className,\n children,\n boxRef: externalBoxRef,\n windowResize,\n autoHideScrollbar = false,\n autoHideScrollbarDelay,\n onScroll,\n getRootRef,\n ...restProps\n}: CustomScrollViewProps) => {\n const { document, window } = useDOM();\n const { hasPointer } = useAdaptivity();\n\n const ratio = React.useRef(NaN);\n const lastTrackerTop = React.useRef(0);\n const clientHeight = React.useRef(0);\n const trackerHeight = React.useRef(0);\n const scrollHeight = React.useRef(0);\n const transformProp = React.useRef('');\n const startY = React.useRef(0);\n const trackerTop = React.useRef(0);\n\n const boxRef = useExternRef(externalBoxRef);\n\n const barY = React.useRef<HTMLDivElement>(null);\n const trackerY = React.useRef<HTMLDivElement>(null);\n\n const setTrackerPosition = (scrollTop: number) => {\n lastTrackerTop.current = scrollTop;\n if (trackerY.current !== null) {\n (trackerY.current.style as any)[transformProp.current] = `translate(0, ${scrollTop}px)`;\n }\n };\n\n const setTrackerPositionFromScroll = (scrollTop: number) => {\n const progress = scrollTop / (scrollHeight.current - clientHeight.current);\n setTrackerPosition((clientHeight.current - trackerHeight.current) * progress);\n };\n\n const resize = () => {\n if (!boxRef.current || !barY.current || !trackerY.current) {\n return;\n }\n const localClientHeight = boxRef.current.clientHeight;\n const localScrollHeight = boxRef.current.scrollHeight;\n const localRatio = localClientHeight / localScrollHeight;\n const localTrackerHeight = Math.max(localClientHeight * localRatio, 40);\n\n ratio.current = localRatio;\n clientHeight.current = localClientHeight;\n scrollHeight.current = localScrollHeight;\n trackerHeight.current = localTrackerHeight;\n\n if (localRatio >= 1) {\n barY.current.style.display = 'none';\n } else {\n barY.current.style.display = '';\n trackerY.current.style.height = `${localTrackerHeight}px`;\n setTrackerPositionFromScroll(boxRef.current.scrollTop);\n }\n };\n\n const resizeHandler = useEventListener('resize', resize);\n\n useIsomorphicLayoutEffect(() => {\n if (windowResize && window) {\n resizeHandler.add(window);\n }\n }, [windowResize, window]);\n\n useIsomorphicLayoutEffect(() => {\n let style = trackerY.current?.style;\n let prop = '';\n if (style !== undefined) {\n if ('transform' in style) {\n prop = 'transform';\n } else if ('webkitTransform' in style) {\n prop = 'webkitTransform';\n }\n }\n transformProp.current = prop;\n }, []);\n\n useIsomorphicLayoutEffect(resize);\n\n const setScrollPositionFromTracker = (trackerTop: number) => {\n const progress = trackerTop / (clientHeight.current - trackerHeight.current);\n if (boxRef.current !== null) {\n boxRef.current.scrollTop = (scrollHeight.current - clientHeight.current) * progress;\n }\n };\n\n const onMove = (e: MouseEvent) => {\n e.preventDefault();\n const diff = e.clientY - startY.current;\n const position = Math.min(\n Math.max(trackerTop.current + diff, 0),\n clientHeight.current - trackerHeight.current,\n );\n\n setScrollPositionFromTracker(position);\n };\n\n const {\n trackerVisible,\n onTargetScroll,\n onTrackerDragStart,\n onTrackerDragStop,\n onTrackerMouseEnter,\n onTrackerMouseLeave,\n } = useTrackerVisibility(autoHideScrollbar, autoHideScrollbarDelay);\n\n const onUp = (e: MouseEvent) => {\n e.preventDefault();\n\n if (autoHideScrollbar) {\n onTrackerDragStop();\n }\n\n unsubscribe();\n };\n\n const scroll = (event: React.UIEvent<HTMLDivElement>) => {\n if (ratio.current >= 1 || !boxRef.current) {\n return;\n }\n\n if (autoHideScrollbar) {\n onTargetScroll();\n }\n\n setTrackerPositionFromScroll(boxRef.current.scrollTop);\n onScroll?.(event);\n };\n\n const listeners = [useEventListener('mousemove', onMove), useEventListener('mouseup', onUp)];\n\n function subscribe(el: Document | undefined) {\n if (el) {\n listeners.forEach((l) => l.add(el));\n }\n }\n\n function unsubscribe() {\n listeners.forEach((l) => l.remove());\n }\n\n const onDragStart = (e: React.MouseEvent) => {\n e.preventDefault();\n startY.current = e.clientY;\n trackerTop.current = lastTrackerTop.current;\n\n if (autoHideScrollbar) {\n onTrackerDragStart();\n }\n\n subscribe(document);\n };\n\n return (\n <div\n className={classNames(className, styles['CustomScrollView'], hasPointerClassName(hasPointer))}\n ref={getRootRef}\n {...restProps}\n >\n <div className={styles['CustomScrollView__box']} tabIndex={-1} ref={boxRef} onScroll={scroll}>\n {children}\n </div>\n\n <div className={styles['CustomScrollView__barY']} ref={barY} onClick={stopPropagation}>\n <div\n className={classNames(\n styles['CustomScrollView__trackerY'],\n !trackerVisible && styles['CustomScrollView__trackerY--hidden'],\n )}\n onMouseEnter={autoHideScrollbar ? onTrackerMouseEnter : undefined}\n onMouseLeave={autoHideScrollbar ? onTrackerMouseLeave : undefined}\n ref={trackerY}\n onMouseDown={onDragStart}\n />\n </div>\n </div>\n );\n};\n"],"names":["React","classNames","useAdaptivity","useEventListener","useExternRef","useDOM","useIsomorphicLayoutEffect","stopPropagation","useTrackerVisibility","hasPointerClassName","hasPointer","undefined","CustomScrollView","className","children","boxRef","externalBoxRef","windowResize","autoHideScrollbar","autoHideScrollbarDelay","onScroll","getRootRef","restProps","document","window","ratio","useRef","NaN","lastTrackerTop","clientHeight","trackerHeight","scrollHeight","transformProp","startY","trackerTop","barY","trackerY","setTrackerPosition","scrollTop","current","style","setTrackerPositionFromScroll","progress","resize","localClientHeight","localScrollHeight","localRatio","localTrackerHeight","Math","max","display","height","resizeHandler","add","prop","setScrollPositionFromTracker","onMove","e","preventDefault","diff","clientY","position","min","trackerVisible","onTargetScroll","onTrackerDragStart","onTrackerDragStop","onTrackerMouseEnter","onTrackerMouseLeave","onUp","unsubscribe","scroll","event","listeners","subscribe","el","forEach","l","remove","onDragStart","div","ref","tabIndex","onClick","onMouseEnter","onMouseLeave","onMouseDown"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";;;;AAAA,YAAYA,WAAW,QAAQ;AAC/B,SAASC,UAAU,QAAQ,kBAAkB;AAC7C,SAASC,aAAa,QAAQ,4BAA4B;AAC1D,SAASC,gBAAgB,QAAQ,+BAA+B;AAChE,SAASC,YAAY,QAAQ,2BAA2B;AACxD,SAASC,MAAM,QAAQ,gBAAgB;AACvC,SAASC,yBAAyB,QAAQ,sCAAsC;AAChF,SAASC,eAAe,QAAQ,kBAAkB;AAElD,SAA8BC,oBAAoB,QAAQ,yBAAyB;AAGnF,SAASC,oBAAoBC,UAA+B;IAC1D,OAAQA;QACN,KAAK;YACH;QACF,KAAK;YACH;QACF,KAAKC;QACL;YACE;IACJ;AACF;AAaA,OAAO,MAAMC,mBAAmB;QAAC,EAC/BC,SAAS,EACTC,QAAQ,EACRC,QAAQC,cAAc,EACtBC,YAAY,EACZC,oBAAoB,KAAK,EACzBC,sBAAsB,EACtBC,QAAQ,EACRC,UAAU,EAEY,WADnBC;QARHT;QACAC;QACAC;QACAE;QACAC;QACAC;QACAC;QACAC;;IAGA,MAAM,EAAEE,QAAQ,EAAEC,MAAM,EAAE,GAAGnB;IAC7B,MAAM,EAAEK,UAAU,EAAE,GAAGR;IAEvB,MAAMuB,QAAQzB,MAAM0B,MAAM,CAACC;IAC3B,MAAMC,iBAAiB5B,MAAM0B,MAAM,CAAC;IACpC,MAAMG,eAAe7B,MAAM0B,MAAM,CAAC;IAClC,MAAMI,gBAAgB9B,MAAM0B,MAAM,CAAC;IACnC,MAAMK,eAAe/B,MAAM0B,MAAM,CAAC;IAClC,MAAMM,gBAAgBhC,MAAM0B,MAAM,CAAC;IACnC,MAAMO,SAASjC,MAAM0B,MAAM,CAAC;IAC5B,MAAMQ,aAAalC,MAAM0B,MAAM,CAAC;IAEhC,MAAMX,SAASX,aAAaY;IAE5B,MAAMmB,OAAOnC,MAAM0B,MAAM,CAAiB;IAC1C,MAAMU,WAAWpC,MAAM0B,MAAM,CAAiB;IAE9C,MAAMW,qBAAqB,CAACC;QAC1BV,eAAeW,OAAO,GAAGD;QACzB,IAAIF,SAASG,OAAO,KAAK,MAAM;YAC5BH,SAASG,OAAO,CAACC,KAAK,AAAQ,CAACR,cAAcO,OAAO,CAAC,GAAG,CAAC,aAAa,EAAED,UAAU,GAAG,CAAC;QACzF;IACF;IAEA,MAAMG,+BAA+B,CAACH;QACpC,MAAMI,WAAWJ,YAAaP,CAAAA,aAAaQ,OAAO,GAAGV,aAAaU,OAAO,AAAD;QACxEF,mBAAmB,AAACR,CAAAA,aAAaU,OAAO,GAAGT,cAAcS,OAAO,AAAD,IAAKG;IACtE;IAEA,MAAMC,SAAS;QACb,IAAI,CAAC5B,OAAOwB,OAAO,IAAI,CAACJ,KAAKI,OAAO,IAAI,CAACH,SAASG,OAAO,EAAE;YACzD;QACF;QACA,MAAMK,oBAAoB7B,OAAOwB,OAAO,CAACV,YAAY;QACrD,MAAMgB,oBAAoB9B,OAAOwB,OAAO,CAACR,YAAY;QACrD,MAAMe,aAAaF,oBAAoBC;QACvC,MAAME,qBAAqBC,KAAKC,GAAG,CAACL,oBAAoBE,YAAY;QAEpErB,MAAMc,OAAO,GAAGO;QAChBjB,aAAaU,OAAO,GAAGK;QACvBb,aAAaQ,OAAO,GAAGM;QACvBf,cAAcS,OAAO,GAAGQ;QAExB,IAAID,cAAc,GAAG;YACnBX,KAAKI,OAAO,CAACC,KAAK,CAACU,OAAO,GAAG;QAC/B,OAAO;YACLf,KAAKI,OAAO,CAACC,KAAK,CAACU,OAAO,GAAG;YAC7Bd,SAASG,OAAO,CAACC,KAAK,CAACW,MAAM,GAAG,CAAC,EAAEJ,mBAAmB,EAAE,CAAC;YACzDN,6BAA6B1B,OAAOwB,OAAO,CAACD,SAAS;QACvD;IACF;IAEA,MAAMc,gBAAgBjD,iBAAiB,UAAUwC;IAEjDrC,0BAA0B;QACxB,IAAIW,gBAAgBO,QAAQ;YAC1B4B,cAAcC,GAAG,CAAC7B;QACpB;IACF,GAAG;QAACP;QAAcO;KAAO;IAEzBlB,0BAA0B;YACZ8B;QAAZ,IAAII,SAAQJ,oBAAAA,SAASG,OAAO,cAAhBH,wCAAAA,kBAAkBI,KAAK;QACnC,IAAIc,OAAO;QACX,IAAId,UAAU7B,WAAW;YACvB,IAAI,eAAe6B,OAAO;gBACxBc,OAAO;YACT,OAAO,IAAI,qBAAqBd,OAAO;gBACrCc,OAAO;YACT;QACF;QACAtB,cAAcO,OAAO,GAAGe;IAC1B,GAAG,EAAE;IAELhD,0BAA0BqC;IAE1B,MAAMY,+BAA+B,CAACrB;QACpC,MAAMQ,WAAWR,aAAcL,CAAAA,aAAaU,OAAO,GAAGT,cAAcS,OAAO,AAAD;QAC1E,IAAIxB,OAAOwB,OAAO,KAAK,MAAM;YAC3BxB,OAAOwB,OAAO,CAACD,SAAS,GAAG,AAACP,CAAAA,aAAaQ,OAAO,GAAGV,aAAaU,OAAO,AAAD,IAAKG;QAC7E;IACF;IAEA,MAAMc,SAAS,CAACC;QACdA,EAAEC,cAAc;QAChB,MAAMC,OAAOF,EAAEG,OAAO,GAAG3B,OAAOM,OAAO;QACvC,MAAMsB,WAAWb,KAAKc,GAAG,CACvBd,KAAKC,GAAG,CAACf,WAAWK,OAAO,GAAGoB,MAAM,IACpC9B,aAAaU,OAAO,GAAGT,cAAcS,OAAO;QAG9CgB,6BAA6BM;IAC/B;IAEA,MAAM,EACJE,cAAc,EACdC,cAAc,EACdC,kBAAkB,EAClBC,iBAAiB,EACjBC,mBAAmB,EACnBC,mBAAmB,EACpB,GAAG5D,qBAAqBU,mBAAmBC;IAE5C,MAAMkD,OAAO,CAACZ;QACZA,EAAEC,cAAc;QAEhB,IAAIxC,mBAAmB;YACrBgD;QACF;QAEAI;IACF;IAEA,MAAMC,SAAS,CAACC;QACd,IAAI/C,MAAMc,OAAO,IAAI,KAAK,CAACxB,OAAOwB,OAAO,EAAE;YACzC;QACF;QAEA,IAAIrB,mBAAmB;YACrB8C;QACF;QAEAvB,6BAA6B1B,OAAOwB,OAAO,CAACD,SAAS;QACrDlB,qBAAAA,+BAAAA,SAAWoD;IACb;IAEA,MAAMC,YAAY;QAACtE,iBAAiB,aAAaqD;QAASrD,iBAAiB,WAAWkE;KAAM;IAE5F,SAASK,UAAUC,EAAwB;QACzC,IAAIA,IAAI;YACNF,UAAUG,OAAO,CAAC,CAACC,IAAMA,EAAExB,GAAG,CAACsB;QACjC;IACF;IAEA,SAASL;QACPG,UAAUG,OAAO,CAAC,CAACC,IAAMA,EAAEC,MAAM;IACnC;IAEA,MAAMC,cAAc,CAACtB;QACnBA,EAAEC,cAAc;QAChBzB,OAAOM,OAAO,GAAGkB,EAAEG,OAAO;QAC1B1B,WAAWK,OAAO,GAAGX,eAAeW,OAAO;QAE3C,IAAIrB,mBAAmB;YACrB+C;QACF;QAEAS,UAAUnD;IACZ;IAEA,qBACE,MAACyD;QACCnE,WAAWZ,WAAWY,mCAAuCJ,oBAAoBC;QACjFuE,KAAK5D;OACDC;;0BAEJ,KAAC0D;gBAAInE,SAAS;gBAAmCqE,UAAU,CAAC;gBAAGD,KAAKlE;gBAAQK,UAAUmD;0BACnFzD;;0BAGH,KAACkE;gBAAInE,SAAS;gBAAoCoE,KAAK9C;gBAAMgD,SAAS5E;0BACpE,cAAA,KAACyE;oBACCnE,WAAWZ,6CAET,CAAC8D;oBAEHqB,cAAclE,oBAAoBiD,sBAAsBxD;oBACxD0E,cAAcnE,oBAAoBkD,sBAAsBzD;oBACxDsE,KAAK7C;oBACLkD,aAAaP;;;;;AAKvB,EAAE"}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/CustomScrollView/CustomScrollView.tsx"],"sourcesContent":["import * as React from 'react';\nimport { classNames } from '@vkontakte/vkjs';\nimport { useAdaptivity } from '../../hooks/useAdaptivity';\nimport { useEventListener } from '../../hooks/useEventListener';\nimport { useExternRef } from '../../hooks/useExternRef';\nimport { useResizeObserver } from '../../hooks/useResizeObserver';\nimport { useDOM } from '../../lib/dom';\nimport { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';\nimport { stopPropagation } from '../../lib/utils';\nimport type { HasRootRef } from '../../types';\nimport { TrackerOptionsProps, useTrackerVisibility } from './useTrackerVisibility';\nimport styles from './CustomScrollView.module.css';\n\nfunction hasPointerClassName(hasPointer: boolean | undefined) {\n switch (hasPointer) {\n case true:\n return styles['CustomScrollView--hasPointer-true'];\n case false:\n return styles['CustomScrollView--hasPointer-false'];\n case undefined:\n default:\n return styles['CustomScrollView--hasPointer-none'];\n }\n}\n\nexport interface CustomScrollViewProps\n extends React.AllHTMLAttributes<HTMLDivElement>,\n HasRootRef<HTMLDivElement>,\n TrackerOptionsProps {\n windowResize?: boolean;\n boxRef?: React.Ref<HTMLDivElement>;\n className?: HTMLDivElement['className'];\n onScroll?: (event: React.UIEvent<HTMLDivElement>) => void;\n children: React.ReactNode;\n}\n\nexport const CustomScrollView = ({\n className,\n children,\n boxRef: externalBoxRef,\n windowResize,\n autoHideScrollbar = false,\n autoHideScrollbarDelay,\n onScroll,\n getRootRef,\n ...restProps\n}: CustomScrollViewProps) => {\n const { document, window } = useDOM();\n const { hasPointer } = useAdaptivity();\n\n const ratio = React.useRef(NaN);\n const lastTrackerTop = React.useRef(0);\n const clientHeight = React.useRef(0);\n const trackerHeight = React.useRef(0);\n const scrollHeight = React.useRef(0);\n const transformProp = React.useRef('');\n const startY = React.useRef(0);\n const trackerTop = React.useRef(0);\n\n const boxRef = useExternRef(externalBoxRef);\n const boxContentRef = React.useRef<HTMLDivElement>(null);\n\n const barY = React.useRef<HTMLDivElement>(null);\n const trackerY = React.useRef<HTMLDivElement>(null);\n\n const setTrackerPosition = (scrollTop: number) => {\n lastTrackerTop.current = scrollTop;\n if (trackerY.current !== null) {\n (trackerY.current.style as any)[transformProp.current] = `translate(0, ${scrollTop}px)`;\n }\n };\n\n const setTrackerPositionFromScroll = (scrollTop: number) => {\n const progress = scrollTop / (scrollHeight.current - clientHeight.current);\n setTrackerPosition((clientHeight.current - trackerHeight.current) * progress);\n };\n\n const resize = () => {\n if (!boxRef.current || !barY.current || !trackerY.current) {\n return;\n }\n const localClientHeight = boxRef.current.clientHeight;\n const localScrollHeight = boxRef.current.scrollHeight;\n const localRatio = localClientHeight / localScrollHeight;\n const localTrackerHeight = Math.max(localClientHeight * localRatio, 40);\n\n ratio.current = localRatio;\n clientHeight.current = localClientHeight;\n scrollHeight.current = localScrollHeight;\n trackerHeight.current = localTrackerHeight;\n\n if (localRatio >= 1) {\n barY.current.style.display = 'none';\n } else {\n barY.current.style.display = '';\n trackerY.current.style.height = `${localTrackerHeight}px`;\n setTrackerPositionFromScroll(boxRef.current.scrollTop);\n }\n };\n\n const resizeHandler = useEventListener('resize', resize);\n\n useIsomorphicLayoutEffect(() => {\n if (windowResize && window) {\n resizeHandler.add(window);\n }\n }, [windowResize, window]);\n\n useResizeObserver(boxContentRef, resize);\n\n useIsomorphicLayoutEffect(() => {\n let style = trackerY.current?.style;\n let prop = '';\n if (style !== undefined) {\n if ('transform' in style) {\n prop = 'transform';\n } else if ('webkitTransform' in style) {\n prop = 'webkitTransform';\n }\n }\n transformProp.current = prop;\n }, []);\n\n useIsomorphicLayoutEffect(resize);\n\n const setScrollPositionFromTracker = (trackerTop: number) => {\n const progress = trackerTop / (clientHeight.current - trackerHeight.current);\n if (boxRef.current !== null) {\n boxRef.current.scrollTop = (scrollHeight.current - clientHeight.current) * progress;\n }\n };\n\n const onMove = (e: MouseEvent) => {\n e.preventDefault();\n const diff = e.clientY - startY.current;\n const position = Math.min(\n Math.max(trackerTop.current + diff, 0),\n clientHeight.current - trackerHeight.current,\n );\n\n setScrollPositionFromTracker(position);\n };\n\n const {\n trackerVisible,\n onTargetScroll,\n onTrackerDragStart,\n onTrackerDragStop,\n onTrackerMouseEnter,\n onTrackerMouseLeave,\n } = useTrackerVisibility(autoHideScrollbar, autoHideScrollbarDelay);\n\n const onUp = (e: MouseEvent) => {\n e.preventDefault();\n\n if (autoHideScrollbar) {\n onTrackerDragStop();\n }\n\n unsubscribe();\n };\n\n const scroll = (event: React.UIEvent<HTMLDivElement>) => {\n if (ratio.current >= 1 || !boxRef.current) {\n return;\n }\n\n if (autoHideScrollbar) {\n onTargetScroll();\n }\n\n setTrackerPositionFromScroll(boxRef.current.scrollTop);\n onScroll?.(event);\n };\n\n const listeners = [useEventListener('mousemove', onMove), useEventListener('mouseup', onUp)];\n\n function subscribe(el: Document | undefined) {\n if (el) {\n listeners.forEach((l) => l.add(el));\n }\n }\n\n function unsubscribe() {\n listeners.forEach((l) => l.remove());\n }\n\n const onDragStart = (e: React.MouseEvent) => {\n e.preventDefault();\n startY.current = e.clientY;\n trackerTop.current = lastTrackerTop.current;\n\n if (autoHideScrollbar) {\n onTrackerDragStart();\n }\n\n subscribe(document);\n };\n\n return (\n <div\n className={classNames(className, styles['CustomScrollView'], hasPointerClassName(hasPointer))}\n ref={getRootRef}\n {...restProps}\n >\n <div className={styles['CustomScrollView__box']} tabIndex={-1} ref={boxRef} onScroll={scroll}>\n <div ref={boxContentRef} className={styles['CustomScrollView__box-content']}>\n {children}\n </div>\n </div>\n\n <div className={styles['CustomScrollView__barY']} ref={barY} onClick={stopPropagation}>\n <div\n className={classNames(\n styles['CustomScrollView__trackerY'],\n !trackerVisible && styles['CustomScrollView__trackerY--hidden'],\n )}\n onMouseEnter={autoHideScrollbar ? onTrackerMouseEnter : undefined}\n onMouseLeave={autoHideScrollbar ? onTrackerMouseLeave : undefined}\n ref={trackerY}\n onMouseDown={onDragStart}\n />\n </div>\n </div>\n );\n};\n"],"names":["React","classNames","useAdaptivity","useEventListener","useExternRef","useResizeObserver","useDOM","useIsomorphicLayoutEffect","stopPropagation","useTrackerVisibility","hasPointerClassName","hasPointer","undefined","CustomScrollView","className","children","boxRef","externalBoxRef","windowResize","autoHideScrollbar","autoHideScrollbarDelay","onScroll","getRootRef","restProps","document","window","ratio","useRef","NaN","lastTrackerTop","clientHeight","trackerHeight","scrollHeight","transformProp","startY","trackerTop","boxContentRef","barY","trackerY","setTrackerPosition","scrollTop","current","style","setTrackerPositionFromScroll","progress","resize","localClientHeight","localScrollHeight","localRatio","localTrackerHeight","Math","max","display","height","resizeHandler","add","prop","setScrollPositionFromTracker","onMove","e","preventDefault","diff","clientY","position","min","trackerVisible","onTargetScroll","onTrackerDragStart","onTrackerDragStop","onTrackerMouseEnter","onTrackerMouseLeave","onUp","unsubscribe","scroll","event","listeners","subscribe","el","forEach","l","remove","onDragStart","div","ref","tabIndex","onClick","onMouseEnter","onMouseLeave","onMouseDown"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { AllHTMLAttributes } from 'react';
|
|
2
2
|
import { HasComponent, HasRootRef } from '../../types';
|
|
3
|
-
export interface FocusTrapProps<T extends HTMLElement = HTMLElement> extends
|
|
3
|
+
export interface FocusTrapProps<T extends HTMLElement = HTMLElement> extends AllHTMLAttributes<T>, HasRootRef<T>, HasComponent {
|
|
4
4
|
autoFocus?: boolean;
|
|
5
5
|
restoreFocus?: boolean | (() => boolean);
|
|
6
6
|
timeout?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FocusTrap.d.ts","sourceRoot":"","sources":["../../../src/components/FocusTrap/FocusTrap.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"FocusTrap.d.ts","sourceRoot":"","sources":["../../../src/components/FocusTrap/FocusTrap.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAsB,MAAM,OAAO,CAAC;AAW9D,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAIvD,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,CACjE,SAAQ,iBAAiB,CAAC,CAAC,CAAC,EAC1B,UAAU,CAAC,CAAC,CAAC,EACb,YAAY;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,sIASnB,eAAe,CAAC,CAAC,4CA2KnB,CAAC"}
|
|
@@ -2,10 +2,10 @@ import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
|
|
|
2
2
|
import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
|
|
3
3
|
import { _ as _object_without_properties } from "@swc/helpers/_/_object_without_properties";
|
|
4
4
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
5
|
-
import
|
|
5
|
+
import { useContext, useRef } from 'react';
|
|
6
6
|
import { useExternRef } from '../../hooks/useExternRef';
|
|
7
7
|
import { FOCUSABLE_ELEMENTS_LIST, Keys, pressedKey } from '../../lib/accessibility';
|
|
8
|
-
import { contains, getActiveElementByAnotherElement, getWindow, isHTMLElement } from '../../lib/dom';
|
|
8
|
+
import { contains, getActiveElementByAnotherElement, getWindow, isHTMLElement, useDOM } from '../../lib/dom';
|
|
9
9
|
import { useIsomorphicLayoutEffect } from '../../lib/useIsomorphicLayoutEffect';
|
|
10
10
|
import { AppRootContext } from '../AppRoot/AppRootContext';
|
|
11
11
|
const FOCUSABLE_ELEMENTS = FOCUSABLE_ELEMENTS_LIST.join();
|
|
@@ -22,15 +22,20 @@ const FOCUSABLE_ELEMENTS = FOCUSABLE_ELEMENTS_LIST.join();
|
|
|
22
22
|
"children"
|
|
23
23
|
]);
|
|
24
24
|
const ref = useExternRef(getRootRef);
|
|
25
|
-
const {
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
const { document } = useDOM();
|
|
26
|
+
const { keyboardInput } = useContext(AppRootContext);
|
|
27
|
+
const focusableNodesRef = useRef([]);
|
|
28
|
+
const focusNodeByIndex = (nodeIndex)=>{
|
|
29
|
+
const element = focusableNodesRef.current[nodeIndex];
|
|
30
|
+
if (element) {
|
|
31
|
+
element.focus();
|
|
30
32
|
}
|
|
31
|
-
|
|
33
|
+
};
|
|
34
|
+
const recalculateFocusableNodesRef = (parentNode)=>{
|
|
32
35
|
// eslint-disable-next-line no-restricted-properties
|
|
33
|
-
|
|
36
|
+
const newFocusableElements = parentNode.querySelectorAll(FOCUSABLE_ELEMENTS);
|
|
37
|
+
const nodes = [];
|
|
38
|
+
newFocusableElements.forEach((focusableEl)=>{
|
|
34
39
|
const { display, visibility } = getComputedStyle(focusableEl);
|
|
35
40
|
if (display !== 'none' && visibility !== 'hidden') {
|
|
36
41
|
nodes.push(focusableEl);
|
|
@@ -38,11 +43,32 @@ const FOCUSABLE_ELEMENTS = FOCUSABLE_ELEMENTS_LIST.join();
|
|
|
38
43
|
});
|
|
39
44
|
if (nodes.length === 0) {
|
|
40
45
|
// Чтобы фокус был хотя бы на родителе
|
|
41
|
-
nodes.push(
|
|
46
|
+
nodes.push(parentNode);
|
|
42
47
|
}
|
|
43
48
|
focusableNodesRef.current = nodes;
|
|
49
|
+
};
|
|
50
|
+
const onMutateParentHandler = (parentNode)=>{
|
|
51
|
+
recalculateFocusableNodesRef(parentNode);
|
|
52
|
+
if (document) {
|
|
53
|
+
const activeElement = document.activeElement;
|
|
54
|
+
const currentElementIndex = Math.max(document.activeElement ? focusableNodesRef.current.indexOf(activeElement) : -1, 0);
|
|
55
|
+
focusNodeByIndex(currentElementIndex);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
useIsomorphicLayoutEffect(function collectFocusableNodesRef() {
|
|
59
|
+
if (!ref.current) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const parentNode = ref.current;
|
|
63
|
+
const observer = new MutationObserver(()=>onMutateParentHandler(parentNode));
|
|
64
|
+
observer.observe(ref.current, {
|
|
65
|
+
subtree: true,
|
|
66
|
+
childList: true
|
|
67
|
+
});
|
|
68
|
+
recalculateFocusableNodesRef(parentNode);
|
|
69
|
+
return ()=>observer.disconnect();
|
|
44
70
|
}, [
|
|
45
|
-
|
|
71
|
+
ref
|
|
46
72
|
]);
|
|
47
73
|
useIsomorphicLayoutEffect(function tryToAutoFocusToFirstNode() {
|
|
48
74
|
if (!ref.current || !autoFocus || !keyboardInput) {
|