@toptal/picasso-utils 4.0.1 → 4.0.2-alpha-pf-fix-alpha-release-4de9263c3.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.
- package/dist-package/src/utils/ClickAwayListener/ClickAwayListener.d.ts +21 -0
- package/dist-package/src/utils/ClickAwayListener/ClickAwayListener.d.ts.map +1 -0
- package/dist-package/src/utils/ClickAwayListener/ClickAwayListener.js +111 -0
- package/dist-package/src/utils/ClickAwayListener/ClickAwayListener.js.map +1 -0
- package/dist-package/src/utils/ClickAwayListener/index.d.ts +5 -0
- package/dist-package/src/utils/ClickAwayListener/index.d.ts.map +1 -0
- package/dist-package/src/utils/ClickAwayListener/index.js +3 -0
- package/dist-package/src/utils/ClickAwayListener/index.js.map +1 -0
- package/dist-package/src/utils/Transitions/Rotate180/Rotate180.d.ts.map +1 -1
- package/dist-package/src/utils/Transitions/Rotate180/Rotate180.js +3 -9
- package/dist-package/src/utils/Transitions/Rotate180/Rotate180.js.map +1 -1
- package/dist-package/src/utils/Transitions/Rotate180/styles.d.ts +1 -2
- package/dist-package/src/utils/Transitions/Rotate180/styles.d.ts.map +1 -1
- package/dist-package/src/utils/Transitions/Rotate180/styles.js +6 -9
- package/dist-package/src/utils/Transitions/Rotate180/styles.js.map +1 -1
- package/dist-package/src/utils/capitalize.d.ts +1 -1
- package/dist-package/src/utils/capitalize.d.ts.map +1 -1
- package/dist-package/src/utils/capitalize.js +8 -1
- package/dist-package/src/utils/capitalize.js.map +1 -1
- package/dist-package/src/utils/index.d.ts +2 -1
- package/dist-package/src/utils/index.d.ts.map +1 -1
- package/dist-package/src/utils/index.js +1 -1
- package/dist-package/src/utils/index.js.map +1 -1
- package/package.json +7 -7
- package/src/utils/ClickAwayListener/ClickAwayListener.tsx +191 -0
- package/src/utils/ClickAwayListener/index.ts +5 -0
- package/src/utils/ClickAwayListener/test.tsx +99 -0
- package/src/utils/Modal/__snapshots__/test.tsx.snap +186 -58
- package/src/utils/Modal/test.tsx +2 -6
- package/src/utils/Transitions/Rotate180/Rotate180.tsx +3 -11
- package/src/utils/Transitions/Rotate180/__snapshots__/test.tsx.snap +2 -2
- package/src/utils/Transitions/Rotate180/styles.ts +6 -11
- package/src/utils/capitalize.ts +9 -1
- package/src/utils/index.ts +2 -1
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { MouseEvent as ReactMouseEvent, ReactElement } from 'react';
|
|
2
|
+
type ClickAwayMouseEventHandler = 'onClick' | 'onMouseDown' | 'onMouseUp';
|
|
3
|
+
type ClickAwayTouchEventHandler = 'onTouchStart' | 'onTouchEnd';
|
|
4
|
+
export interface Props {
|
|
5
|
+
/** The wrapped element. */
|
|
6
|
+
children: ReactElement;
|
|
7
|
+
/** If `true`, the React tree is ignored and only the DOM tree is considered. Changes how portaled elements are handled. */
|
|
8
|
+
disableReactTree?: boolean;
|
|
9
|
+
/** The mouse event to listen to. Pass `false` to disable the mouse listener. */
|
|
10
|
+
mouseEvent?: ClickAwayMouseEventHandler | false;
|
|
11
|
+
/** Callback fired when a click-away event is detected. */
|
|
12
|
+
onClickAway: (event: ReactMouseEvent) => void;
|
|
13
|
+
/** The touch event to listen to. Pass `false` to disable the touch listener. */
|
|
14
|
+
touchEvent?: ClickAwayTouchEventHandler | false;
|
|
15
|
+
}
|
|
16
|
+
export declare const ClickAwayListener: {
|
|
17
|
+
(props: Props): JSX.Element;
|
|
18
|
+
displayName: string;
|
|
19
|
+
};
|
|
20
|
+
export default ClickAwayListener;
|
|
21
|
+
//# sourceMappingURL=ClickAwayListener.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClickAwayListener.d.ts","sourceRoot":"","sources":["../../../../src/utils/ClickAwayListener/ClickAwayListener.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,IAAI,eAAe,EAC7B,YAAY,EAGb,MAAM,OAAO,CAAA;AAId,KAAK,0BAA0B,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,CAAA;AACzE,KAAK,0BAA0B,GAAG,cAAc,GAAG,YAAY,CAAA;AAE/D,MAAM,WAAW,KAAK;IACpB,2BAA2B;IAC3B,QAAQ,EAAE,YAAY,CAAA;IACtB,2HAA2H;IAC3H,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,gFAAgF;IAChF,UAAU,CAAC,EAAE,0BAA0B,GAAG,KAAK,CAAA;IAC/C,0DAA0D;IAC1D,WAAW,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAA;IAC7C,gFAAgF;IAChF,UAAU,CAAC,EAAE,0BAA0B,GAAG,KAAK,CAAA;CAChD;AAsCD,eAAO,MAAM,iBAAiB;YAAW,KAAK;;CA6H7C,CAAA;AAID,eAAe,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useRef } from 'react';
|
|
2
|
+
import { toReactEvent } from '@toptal/picasso-shared';
|
|
3
|
+
const mapEventPropToEvent = (eventProp) => eventProp.substring(2).toLowerCase();
|
|
4
|
+
const clickedRootScrollbar = (event, doc) => {
|
|
5
|
+
const { clientX, clientY } = event;
|
|
6
|
+
return (doc.documentElement.clientWidth < clientX ||
|
|
7
|
+
doc.documentElement.clientHeight < clientY);
|
|
8
|
+
};
|
|
9
|
+
const isEventInsideNode = (event, node, doc) => {
|
|
10
|
+
if (event.composedPath) {
|
|
11
|
+
return event.composedPath().indexOf(node) > -1;
|
|
12
|
+
}
|
|
13
|
+
return (!doc.documentElement.contains(event.target) ||
|
|
14
|
+
node.contains(event.target));
|
|
15
|
+
};
|
|
16
|
+
const setRef = (ref, value) => {
|
|
17
|
+
if (typeof ref === 'function') {
|
|
18
|
+
ref(value);
|
|
19
|
+
}
|
|
20
|
+
else if (ref) {
|
|
21
|
+
;
|
|
22
|
+
ref.current = value;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
export const ClickAwayListener = (props) => {
|
|
26
|
+
const { children, disableReactTree = false, mouseEvent = 'onClick', onClickAway, touchEvent = 'onTouchEnd', } = props;
|
|
27
|
+
const movedRef = useRef(false);
|
|
28
|
+
const nodeRef = useRef(null);
|
|
29
|
+
const activatedRef = useRef(false);
|
|
30
|
+
const syntheticEventRef = useRef(false);
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
// Avoid activating synchronously so the interaction that mounts the
|
|
33
|
+
// component does not immediately count as a click-away.
|
|
34
|
+
const timeout = setTimeout(() => {
|
|
35
|
+
activatedRef.current = true;
|
|
36
|
+
}, 0);
|
|
37
|
+
return () => {
|
|
38
|
+
activatedRef.current = false;
|
|
39
|
+
clearTimeout(timeout);
|
|
40
|
+
};
|
|
41
|
+
}, []);
|
|
42
|
+
const childRef = children.ref;
|
|
43
|
+
const handleRef = useCallback((instance) => {
|
|
44
|
+
nodeRef.current = instance;
|
|
45
|
+
setRef(childRef, instance);
|
|
46
|
+
}, [childRef]);
|
|
47
|
+
const handleClickAway = useCallback((event) => {
|
|
48
|
+
var _a;
|
|
49
|
+
const insideReactTree = syntheticEventRef.current;
|
|
50
|
+
syntheticEventRef.current = false;
|
|
51
|
+
const node = nodeRef.current;
|
|
52
|
+
const doc = (_a = node === null || node === void 0 ? void 0 : node.ownerDocument) !== null && _a !== void 0 ? _a : document;
|
|
53
|
+
if (!activatedRef.current || !node || clickedRootScrollbar(event, doc)) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (movedRef.current) {
|
|
57
|
+
movedRef.current = false;
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const insideDOM = isEventInsideNode(event, node, doc);
|
|
61
|
+
if (!insideDOM && (disableReactTree || !insideReactTree)) {
|
|
62
|
+
onClickAway(toReactEvent(event));
|
|
63
|
+
}
|
|
64
|
+
}, [disableReactTree, onClickAway]);
|
|
65
|
+
const createHandleSynthetic = (handlerName) => (event) => {
|
|
66
|
+
var _a;
|
|
67
|
+
syntheticEventRef.current = true;
|
|
68
|
+
const childrenPropsHandlers = children.props;
|
|
69
|
+
(_a = childrenPropsHandlers[handlerName]) === null || _a === void 0 ? void 0 : _a.call(childrenPropsHandlers, event);
|
|
70
|
+
};
|
|
71
|
+
const childrenProps = { ref: handleRef };
|
|
72
|
+
if (touchEvent !== false) {
|
|
73
|
+
childrenProps[touchEvent] = createHandleSynthetic(touchEvent);
|
|
74
|
+
}
|
|
75
|
+
if (mouseEvent !== false) {
|
|
76
|
+
childrenProps[mouseEvent] = createHandleSynthetic(mouseEvent);
|
|
77
|
+
}
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
var _a, _b;
|
|
80
|
+
if (touchEvent === false) {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
const mappedTouchEvent = mapEventPropToEvent(touchEvent);
|
|
84
|
+
const doc = (_b = (_a = nodeRef.current) === null || _a === void 0 ? void 0 : _a.ownerDocument) !== null && _b !== void 0 ? _b : document;
|
|
85
|
+
const handleTouchMove = () => {
|
|
86
|
+
movedRef.current = true;
|
|
87
|
+
};
|
|
88
|
+
doc.addEventListener(mappedTouchEvent, handleClickAway);
|
|
89
|
+
doc.addEventListener('touchmove', handleTouchMove);
|
|
90
|
+
return () => {
|
|
91
|
+
doc.removeEventListener(mappedTouchEvent, handleClickAway);
|
|
92
|
+
doc.removeEventListener('touchmove', handleTouchMove);
|
|
93
|
+
};
|
|
94
|
+
}, [handleClickAway, touchEvent]);
|
|
95
|
+
useEffect(() => {
|
|
96
|
+
var _a, _b;
|
|
97
|
+
if (mouseEvent === false) {
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
const mappedMouseEvent = mapEventPropToEvent(mouseEvent);
|
|
101
|
+
const doc = (_b = (_a = nodeRef.current) === null || _a === void 0 ? void 0 : _a.ownerDocument) !== null && _b !== void 0 ? _b : document;
|
|
102
|
+
doc.addEventListener(mappedMouseEvent, handleClickAway);
|
|
103
|
+
return () => {
|
|
104
|
+
doc.removeEventListener(mappedMouseEvent, handleClickAway);
|
|
105
|
+
};
|
|
106
|
+
}, [handleClickAway, mouseEvent]);
|
|
107
|
+
return React.createElement(React.Fragment, null, React.cloneElement(children, childrenProps));
|
|
108
|
+
};
|
|
109
|
+
ClickAwayListener.displayName = 'ClickAwayListener';
|
|
110
|
+
export default ClickAwayListener;
|
|
111
|
+
//# sourceMappingURL=ClickAwayListener.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClickAwayListener.js","sourceRoot":"","sources":["../../../../src/utils/ClickAwayListener/ClickAwayListener.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/ClickAwayListener/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAEhD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,MAAM,MAAM,sBAAsB,GAAG,KAAK,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/utils/ClickAwayListener/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Rotate180.d.ts","sourceRoot":"","sources":["../../../../../src/utils/Transitions/Rotate180/Rotate180.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,SAAS,EAAE,MAAM,OAAO,CAAA;AAGpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"Rotate180.d.ts","sourceRoot":"","sources":["../../../../../src/utils/Transitions/Rotate180/Rotate180.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,SAAS,EAAE,MAAM,OAAO,CAAA;AAGpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAKvD,MAAM,WAAW,KAAM,SAAQ,SAAS;IACtC,qCAAqC;IACrC,EAAE,EAAE,OAAO,CAAA;IACX,oCAAoC;IACpC,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,eAAO,MAAM,SAAS;YAAW,KAAK;;CAgBrC,CAAA;AAID,eAAe,SAAS,CAAA"}
|
|
@@ -11,17 +11,11 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
11
11
|
};
|
|
12
12
|
import React from 'react';
|
|
13
13
|
import cx from 'classnames';
|
|
14
|
-
import {
|
|
15
|
-
import
|
|
16
|
-
const useStyles = makeStyles(styles, {
|
|
17
|
-
name: 'Rotate180',
|
|
18
|
-
});
|
|
14
|
+
import { twMerge } from '@toptal/picasso-tailwind-merge';
|
|
15
|
+
import { createRotate180ClassNames } from './styles';
|
|
19
16
|
export const Rotate180 = (props) => {
|
|
20
17
|
const { children, style, className, on } = props, rest = __rest(props, ["children", "style", "className", "on"]);
|
|
21
|
-
const
|
|
22
|
-
const childProps = Object.assign({ className: cx(className, classes.transition, {
|
|
23
|
-
[classes.rotate180]: on,
|
|
24
|
-
}), style }, rest);
|
|
18
|
+
const childProps = Object.assign({ className: twMerge(cx(createRotate180ClassNames(on)), className), style }, rest);
|
|
25
19
|
return (React.createElement(React.Fragment, null, React.Children.map(children, child => React.cloneElement(child, childProps))));
|
|
26
20
|
};
|
|
27
21
|
Rotate180.displayName = 'Rotate180';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Rotate180.js","sourceRoot":"","sources":["../../../../../src/utils/Transitions/Rotate180/Rotate180.tsx"],"names":[],"mappings":";;;;;;;;;;;AACA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"Rotate180.js","sourceRoot":"","sources":["../../../../../src/utils/Transitions/Rotate180/Rotate180.tsx"],"names":[],"mappings":";;;;;;;;;;;AACA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,MAAM,YAAY,CAAA;AAE3B,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAExD,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAA;AASpD,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,KAAY,EAAE,EAAE;IACxC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,KAAc,KAAK,EAAd,IAAI,UAAK,KAAK,EAAnD,wCAA2C,CAAQ,CAAA;IAEzD,MAAM,UAAU,mBACd,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC,yBAAyB,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,CAAC,EAChE,KAAK,IACF,IAAI,CACR,CAAA;IAED,OAAO,CACL,0CACG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,CACpC,KAAK,CAAC,YAAY,CAAC,KAAqB,EAAE,UAAU,CAAC,CACtD,CACA,CACJ,CAAA;AACH,CAAC,CAAA;AAED,SAAS,CAAC,WAAW,GAAG,WAAW,CAAA;AAEnC,eAAe,SAAS,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../../../src/utils/Transitions/Rotate180/styles.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../../../src/utils/Transitions/Rotate180/styles.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,yBAAyB,OAAQ,OAAO,KAAG,MAAM,EAK7D,CAAA"}
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
transform: 'rotate(180deg)',
|
|
8
|
-
},
|
|
9
|
-
});
|
|
1
|
+
export const createRotate180ClassNames = (on) => [
|
|
2
|
+
'transition-transform',
|
|
3
|
+
'duration-150',
|
|
4
|
+
'ease-in-out',
|
|
5
|
+
...(on ? ['rotate-180'] : []),
|
|
6
|
+
];
|
|
10
7
|
//# sourceMappingURL=styles.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../../../src/utils/Transitions/Rotate180/styles.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../../../src/utils/Transitions/Rotate180/styles.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,EAAW,EAAY,EAAE,CAAC;IAClE,sBAAsB;IACtB,cAAc;IACd,aAAa;IACb,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;CAC9B,CAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export
|
|
1
|
+
export declare const capitalize: (string: string) => string;
|
|
2
2
|
//# sourceMappingURL=capitalize.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capitalize.d.ts","sourceRoot":"","sources":["../../../src/utils/capitalize.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"capitalize.d.ts","sourceRoot":"","sources":["../../../src/utils/capitalize.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,UAAU,WAAY,MAAM,KAAG,MAM3C,CAAA"}
|
|
@@ -1,2 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
// Not equivalent to `text-transform: capitalize` — only the first letter of
|
|
2
|
+
// the whole string is uppercased, not the first letter of each word.
|
|
3
|
+
export const capitalize = (string) => {
|
|
4
|
+
if (typeof string !== 'string') {
|
|
5
|
+
throw new Error('Picasso: capitalize(string) expects a string argument.');
|
|
6
|
+
}
|
|
7
|
+
return string.charAt(0).toUpperCase() + string.slice(1);
|
|
8
|
+
};
|
|
2
9
|
//# sourceMappingURL=capitalize.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capitalize.js","sourceRoot":"","sources":["../../../src/utils/capitalize.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"capitalize.js","sourceRoot":"","sources":["../../../src/utils/capitalize.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,qEAAqE;AACrE,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,MAAc,EAAU,EAAE;IACnD,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAA;IAC3E,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AACzD,CAAC,CAAA"}
|
|
@@ -8,7 +8,8 @@ export { colorUtils };
|
|
|
8
8
|
export { breakpointsList as breakpoints, screens, isScreenSize, useBreakpoint, useScreens, shadows, colors as palette, gradients, generateRandomString, generateRandomStringOrGetEmptyInTest, sizes, } from '@toptal/picasso-provider';
|
|
9
9
|
export type { BreakpointKeys } from '@toptal/picasso-provider';
|
|
10
10
|
export { useIsomorphicLayoutEffect, isBrowser, type OverridableComponent, } from '@toptal/picasso-shared';
|
|
11
|
-
export { default as ClickAwayListener } from '
|
|
11
|
+
export { default as ClickAwayListener } from './ClickAwayListener';
|
|
12
|
+
export type { ClickAwayListenerProps } from './ClickAwayListener';
|
|
12
13
|
export { capitalize } from './capitalize';
|
|
13
14
|
export { default as disableUnsupportedProps } from './disable-unsupported-props';
|
|
14
15
|
export { type FeatureOptions } from './disable-unsupported-props';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,eAAe,MAAM,eAAe,CAAA;AAEhD,QAAA,MAAM,UAAU;;;;CAIf,CAAA;AAED,OAAO,EAAE,UAAU,EAAE,CAAA;AAErB,OAAO,EACL,eAAe,IAAI,WAAW,EAC9B,OAAO,EACP,YAAY,EACZ,aAAa,EACb,UAAU,EACV,OAAO,EACP,MAAM,IAAI,OAAO,EACjB,SAAS,EACT,oBAAoB,EACpB,oCAAoC,EACpC,KAAK,GACN,MAAM,0BAA0B,CAAA;AACjC,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EACL,yBAAyB,EACzB,SAAS,EACT,KAAK,oBAAoB,GAC1B,MAAM,wBAAwB,CAAA;AAE/B,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@ const colorUtils = {
|
|
|
8
8
|
export { colorUtils };
|
|
9
9
|
export { breakpointsList as breakpoints, screens, isScreenSize, useBreakpoint, useScreens, shadows, colors as palette, gradients, generateRandomString, generateRandomStringOrGetEmptyInTest, sizes, } from '@toptal/picasso-provider';
|
|
10
10
|
export { useIsomorphicLayoutEffect, isBrowser, } from '@toptal/picasso-shared';
|
|
11
|
-
export { default as ClickAwayListener } from '
|
|
11
|
+
export { default as ClickAwayListener } from './ClickAwayListener';
|
|
12
12
|
export { capitalize } from './capitalize';
|
|
13
13
|
export { default as disableUnsupportedProps } from './disable-unsupported-props';
|
|
14
14
|
export { forwardRef, documentable } from './forward-ref';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAE/D,OAAO,KAAK,eAAe,MAAM,eAAe,CAAA;AAEhD,MAAM,UAAU,GAAG;IACjB,KAAK;IACL,OAAO;IACP,MAAM;CACP,CAAA;AAED,OAAO,EAAE,UAAU,EAAE,CAAA;AAErB,OAAO,EACL,eAAe,IAAI,WAAW,EAC9B,OAAO,EACP,YAAY,EACZ,aAAa,EACb,UAAU,EACV,OAAO,EACP,MAAM,IAAI,OAAO,EACjB,SAAS,EACT,oBAAoB,EACpB,oCAAoC,EACpC,KAAK,GACN,MAAM,0BAA0B,CAAA;AAEjC,OAAO,EACL,yBAAyB,EACzB,SAAS,GAEV,MAAM,wBAAwB,CAAA;AAE/B,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toptal/picasso-utils",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.2-alpha-pf-fix-alpha-release-4de9263c3.0",
|
|
4
4
|
"description": "Toptal UI components library - Utils",
|
|
5
5
|
"homepage": "https://github.com/toptal/picasso/tree/master/packages/picasso#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -24,18 +24,18 @@
|
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"ap-style-title-case": "^1.1.2",
|
|
26
26
|
"classnames": "^2.5.1",
|
|
27
|
-
"@toptal/picasso-shared": "16.0.0"
|
|
27
|
+
"@toptal/picasso-shared": "16.0.1-alpha-pf-fix-alpha-release-4de9263c3.0",
|
|
28
|
+
"@toptal/picasso-tailwind-merge": "2.0.6-alpha-pf-fix-alpha-release-4de9263c3.0"
|
|
28
29
|
},
|
|
29
30
|
"devDependencies": {
|
|
30
31
|
"styled-components": "^6.1.1",
|
|
31
|
-
"@toptal/picasso-
|
|
32
|
-
"@toptal/picasso-
|
|
32
|
+
"@toptal/picasso-test-utils": "2.0.2-alpha-pf-fix-alpha-release-4de9263c3.0",
|
|
33
|
+
"@toptal/picasso-provider": "6.0.1-alpha-pf-fix-alpha-release-4de9263c3.0"
|
|
33
34
|
},
|
|
34
35
|
"peerDependencies": {
|
|
35
|
-
"@
|
|
36
|
-
"@toptal/picasso-provider": "*",
|
|
36
|
+
"@toptal/picasso-provider": "6.0.1-alpha-pf-fix-alpha-release-4de9263c3.0",
|
|
37
37
|
"notistack": "1.0.10",
|
|
38
|
-
"react": ">=16.12.0
|
|
38
|
+
"react": ">=16.12.0"
|
|
39
39
|
},
|
|
40
40
|
"publishConfig": {
|
|
41
41
|
"access": "public"
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
MouseEvent as ReactMouseEvent,
|
|
3
|
+
ReactElement,
|
|
4
|
+
Ref,
|
|
5
|
+
SyntheticEvent,
|
|
6
|
+
} from 'react'
|
|
7
|
+
import React, { useCallback, useEffect, useRef } from 'react'
|
|
8
|
+
import { toReactEvent } from '@toptal/picasso-shared'
|
|
9
|
+
|
|
10
|
+
type ClickAwayMouseEventHandler = 'onClick' | 'onMouseDown' | 'onMouseUp'
|
|
11
|
+
type ClickAwayTouchEventHandler = 'onTouchStart' | 'onTouchEnd'
|
|
12
|
+
|
|
13
|
+
export interface Props {
|
|
14
|
+
/** The wrapped element. */
|
|
15
|
+
children: ReactElement
|
|
16
|
+
/** If `true`, the React tree is ignored and only the DOM tree is considered. Changes how portaled elements are handled. */
|
|
17
|
+
disableReactTree?: boolean
|
|
18
|
+
/** The mouse event to listen to. Pass `false` to disable the mouse listener. */
|
|
19
|
+
mouseEvent?: ClickAwayMouseEventHandler | false
|
|
20
|
+
/** Callback fired when a click-away event is detected. */
|
|
21
|
+
onClickAway: (event: ReactMouseEvent) => void
|
|
22
|
+
/** The touch event to listen to. Pass `false` to disable the touch listener. */
|
|
23
|
+
touchEvent?: ClickAwayTouchEventHandler | false
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const mapEventPropToEvent = (
|
|
27
|
+
eventProp: ClickAwayMouseEventHandler | ClickAwayTouchEventHandler
|
|
28
|
+
): string => eventProp.substring(2).toLowerCase()
|
|
29
|
+
|
|
30
|
+
const clickedRootScrollbar = (event: Event, doc: Document): boolean => {
|
|
31
|
+
const { clientX, clientY } = event as MouseEvent
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
doc.documentElement.clientWidth < clientX ||
|
|
35
|
+
doc.documentElement.clientHeight < clientY
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const isEventInsideNode = (
|
|
40
|
+
event: Event,
|
|
41
|
+
node: Element,
|
|
42
|
+
doc: Document
|
|
43
|
+
): boolean => {
|
|
44
|
+
if (event.composedPath) {
|
|
45
|
+
return event.composedPath().indexOf(node) > -1
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
!doc.documentElement.contains(event.target as Node) ||
|
|
50
|
+
node.contains(event.target as Node)
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const setRef = <T,>(ref: Ref<T> | undefined, value: T | null): void => {
|
|
55
|
+
if (typeof ref === 'function') {
|
|
56
|
+
ref(value)
|
|
57
|
+
} else if (ref) {
|
|
58
|
+
;(ref as React.MutableRefObject<T | null>).current = value
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export const ClickAwayListener = (props: Props) => {
|
|
63
|
+
const {
|
|
64
|
+
children,
|
|
65
|
+
disableReactTree = false,
|
|
66
|
+
mouseEvent = 'onClick',
|
|
67
|
+
onClickAway,
|
|
68
|
+
touchEvent = 'onTouchEnd',
|
|
69
|
+
} = props
|
|
70
|
+
|
|
71
|
+
const movedRef = useRef(false)
|
|
72
|
+
const nodeRef = useRef<Element | null>(null)
|
|
73
|
+
const activatedRef = useRef(false)
|
|
74
|
+
const syntheticEventRef = useRef(false)
|
|
75
|
+
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
// Avoid activating synchronously so the interaction that mounts the
|
|
78
|
+
// component does not immediately count as a click-away.
|
|
79
|
+
const timeout = setTimeout(() => {
|
|
80
|
+
activatedRef.current = true
|
|
81
|
+
}, 0)
|
|
82
|
+
|
|
83
|
+
return () => {
|
|
84
|
+
activatedRef.current = false
|
|
85
|
+
clearTimeout(timeout)
|
|
86
|
+
}
|
|
87
|
+
}, [])
|
|
88
|
+
|
|
89
|
+
const childRef = (children as { ref?: Ref<Element> }).ref
|
|
90
|
+
|
|
91
|
+
const handleRef = useCallback(
|
|
92
|
+
(instance: Element | null) => {
|
|
93
|
+
nodeRef.current = instance
|
|
94
|
+
setRef(childRef, instance)
|
|
95
|
+
},
|
|
96
|
+
[childRef]
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
const handleClickAway = useCallback(
|
|
100
|
+
(event: Event) => {
|
|
101
|
+
const insideReactTree = syntheticEventRef.current
|
|
102
|
+
|
|
103
|
+
syntheticEventRef.current = false
|
|
104
|
+
|
|
105
|
+
const node = nodeRef.current
|
|
106
|
+
const doc = node?.ownerDocument ?? document
|
|
107
|
+
|
|
108
|
+
if (!activatedRef.current || !node || clickedRootScrollbar(event, doc)) {
|
|
109
|
+
return
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (movedRef.current) {
|
|
113
|
+
movedRef.current = false
|
|
114
|
+
|
|
115
|
+
return
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const insideDOM = isEventInsideNode(event, node, doc)
|
|
119
|
+
|
|
120
|
+
if (!insideDOM && (disableReactTree || !insideReactTree)) {
|
|
121
|
+
onClickAway(toReactEvent<ReactMouseEvent>(event))
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
[disableReactTree, onClickAway]
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
const createHandleSynthetic =
|
|
128
|
+
(handlerName: ClickAwayMouseEventHandler | ClickAwayTouchEventHandler) =>
|
|
129
|
+
(event: SyntheticEvent) => {
|
|
130
|
+
syntheticEventRef.current = true
|
|
131
|
+
|
|
132
|
+
const childrenPropsHandlers = children.props as Record<
|
|
133
|
+
string,
|
|
134
|
+
((event: SyntheticEvent) => void) | undefined
|
|
135
|
+
>
|
|
136
|
+
|
|
137
|
+
childrenPropsHandlers[handlerName]?.(event)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const childrenProps: Record<string, unknown> = { ref: handleRef }
|
|
141
|
+
|
|
142
|
+
if (touchEvent !== false) {
|
|
143
|
+
childrenProps[touchEvent] = createHandleSynthetic(touchEvent)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (mouseEvent !== false) {
|
|
147
|
+
childrenProps[mouseEvent] = createHandleSynthetic(mouseEvent)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
useEffect(() => {
|
|
151
|
+
if (touchEvent === false) {
|
|
152
|
+
return undefined
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const mappedTouchEvent = mapEventPropToEvent(touchEvent)
|
|
156
|
+
const doc = nodeRef.current?.ownerDocument ?? document
|
|
157
|
+
|
|
158
|
+
const handleTouchMove = () => {
|
|
159
|
+
movedRef.current = true
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
doc.addEventListener(mappedTouchEvent, handleClickAway)
|
|
163
|
+
doc.addEventListener('touchmove', handleTouchMove)
|
|
164
|
+
|
|
165
|
+
return () => {
|
|
166
|
+
doc.removeEventListener(mappedTouchEvent, handleClickAway)
|
|
167
|
+
doc.removeEventListener('touchmove', handleTouchMove)
|
|
168
|
+
}
|
|
169
|
+
}, [handleClickAway, touchEvent])
|
|
170
|
+
|
|
171
|
+
useEffect(() => {
|
|
172
|
+
if (mouseEvent === false) {
|
|
173
|
+
return undefined
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const mappedMouseEvent = mapEventPropToEvent(mouseEvent)
|
|
177
|
+
const doc = nodeRef.current?.ownerDocument ?? document
|
|
178
|
+
|
|
179
|
+
doc.addEventListener(mappedMouseEvent, handleClickAway)
|
|
180
|
+
|
|
181
|
+
return () => {
|
|
182
|
+
doc.removeEventListener(mappedMouseEvent, handleClickAway)
|
|
183
|
+
}
|
|
184
|
+
}, [handleClickAway, mouseEvent])
|
|
185
|
+
|
|
186
|
+
return <>{React.cloneElement(children, childrenProps)}</>
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
ClickAwayListener.displayName = 'ClickAwayListener'
|
|
190
|
+
|
|
191
|
+
export default ClickAwayListener
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render, fireEvent, act } from '@toptal/picasso-test-utils'
|
|
3
|
+
|
|
4
|
+
import { ClickAwayListener } from './ClickAwayListener'
|
|
5
|
+
|
|
6
|
+
const renderClickAwayListener = (
|
|
7
|
+
props: Partial<React.ComponentProps<typeof ClickAwayListener>> = {}
|
|
8
|
+
) => {
|
|
9
|
+
const onClickAway = props.onClickAway ?? jest.fn()
|
|
10
|
+
|
|
11
|
+
const api = render(
|
|
12
|
+
<div>
|
|
13
|
+
<ClickAwayListener onClickAway={onClickAway} {...props}>
|
|
14
|
+
<button type='button'>inside</button>
|
|
15
|
+
</ClickAwayListener>
|
|
16
|
+
<span data-testid='outside'>outside</span>
|
|
17
|
+
</div>
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
// Listeners are activated asynchronously to ignore the mounting interaction.
|
|
21
|
+
act(() => {
|
|
22
|
+
jest.advanceTimersByTime(0)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
return { ...api, onClickAway }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
describe('ClickAwayListener', () => {
|
|
29
|
+
beforeEach(() => {
|
|
30
|
+
jest.useFakeTimers()
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
afterEach(() => {
|
|
34
|
+
jest.useRealTimers()
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
it('fires onClickAway when clicking outside the wrapped element', () => {
|
|
38
|
+
const { getByTestId, onClickAway } = renderClickAwayListener()
|
|
39
|
+
|
|
40
|
+
fireEvent.click(getByTestId('outside'))
|
|
41
|
+
|
|
42
|
+
expect(onClickAway).toHaveBeenCalledTimes(1)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it('does not fire onClickAway when clicking inside the wrapped element', () => {
|
|
46
|
+
const { getByText, onClickAway } = renderClickAwayListener()
|
|
47
|
+
|
|
48
|
+
fireEvent.click(getByText('inside'))
|
|
49
|
+
|
|
50
|
+
expect(onClickAway).not.toHaveBeenCalled()
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('does not fire before the listener is activated', () => {
|
|
54
|
+
const onClickAway = jest.fn()
|
|
55
|
+
|
|
56
|
+
const { getByTestId } = render(
|
|
57
|
+
<div>
|
|
58
|
+
<ClickAwayListener onClickAway={onClickAway}>
|
|
59
|
+
<button type='button'>inside</button>
|
|
60
|
+
</ClickAwayListener>
|
|
61
|
+
<span data-testid='outside'>outside</span>
|
|
62
|
+
</div>
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
fireEvent.click(getByTestId('outside'))
|
|
66
|
+
|
|
67
|
+
expect(onClickAway).not.toHaveBeenCalled()
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it('respects a disabled mouse listener', () => {
|
|
71
|
+
const { getByTestId, onClickAway } = renderClickAwayListener({
|
|
72
|
+
mouseEvent: false,
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
fireEvent.click(getByTestId('outside'))
|
|
76
|
+
|
|
77
|
+
expect(onClickAway).not.toHaveBeenCalled()
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('preserves the child existing event handler', () => {
|
|
81
|
+
const onClick = jest.fn()
|
|
82
|
+
|
|
83
|
+
const { getByText } = render(
|
|
84
|
+
<ClickAwayListener onClickAway={jest.fn()}>
|
|
85
|
+
<button type='button' onClick={onClick}>
|
|
86
|
+
inside
|
|
87
|
+
</button>
|
|
88
|
+
</ClickAwayListener>
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
act(() => {
|
|
92
|
+
jest.advanceTimersByTime(0)
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
fireEvent.click(getByText('inside'))
|
|
96
|
+
|
|
97
|
+
expect(onClick).toHaveBeenCalledTimes(1)
|
|
98
|
+
})
|
|
99
|
+
})
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
exports[`Modal useModal opens and closes modal 1`] = `
|
|
4
4
|
<body>
|
|
5
5
|
<div
|
|
6
|
+
data-base-ui-inert=""
|
|
6
7
|
id="modal-root"
|
|
7
8
|
/>
|
|
8
9
|
<div>
|
|
@@ -11,8 +12,8 @@ exports[`Modal useModal opens and closes modal 1`] = `
|
|
|
11
12
|
>
|
|
12
13
|
<button
|
|
13
14
|
aria-disabled="false"
|
|
14
|
-
aria-hidden="true"
|
|
15
15
|
class="base-Button text-lg inline-flex items-center justify-center select-none appearance-none m-0 relative normal-case align-middle transition-colors duration-350 ease-out shrink-0 outline-hidden [[data-component-type="button"]+&]:ml cursor-pointer no-underline hover:no-underline rounded-sm shadow-none focus-visible:shadow-[0_0_0_3px_rgba(32,78,207,0.48)] focus-within:shadow-[0_0_0_3px_rgba(32,78,207,0.48)] border-none text-white visited:text-white hover:bg-[#4269D6] active:bg-[#1A41AB] bg-blue min-w h-8 py-0 px-4"
|
|
16
|
+
data-base-ui-inert=""
|
|
16
17
|
data-component-type="button"
|
|
17
18
|
role="button"
|
|
18
19
|
tabindex="0"
|
|
@@ -25,47 +26,89 @@ exports[`Modal useModal opens and closes modal 1`] = `
|
|
|
25
26
|
</span>
|
|
26
27
|
</button>
|
|
27
28
|
<div
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
data-base-ui-portal=""
|
|
30
|
+
id=":r2:"
|
|
30
31
|
>
|
|
31
32
|
<div
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
class="fixed z-modal inset-0 bg-black/50 transition-opacity data-starting-style:opacity data-ending-style:opacity"
|
|
34
|
+
data-base-ui-inert=""
|
|
35
|
+
data-open=""
|
|
36
|
+
data-starting-style=""
|
|
37
|
+
role="presentation"
|
|
38
|
+
style="user-select: none; transition-duration: 300ms;"
|
|
35
39
|
/>
|
|
36
|
-
<
|
|
37
|
-
data-
|
|
40
|
+
<span
|
|
41
|
+
data-base-ui-focus-guard=""
|
|
42
|
+
data-base-ui-inert=""
|
|
43
|
+
data-type="inside"
|
|
44
|
+
role="button"
|
|
45
|
+
style="clip-path: inset(50%); overflow: hidden; white-space: nowrap; border: 0px; padding: 0px; width: 1px; height: 1px; margin: -1px; position: fixed; top: 0px; left: 0px;"
|
|
38
46
|
tabindex="0"
|
|
39
47
|
/>
|
|
40
48
|
<div
|
|
41
|
-
class="
|
|
49
|
+
class="fixed z-modal inset-0 flex flex-col text-lg leading-[normal] justify-center items-center transition-opacity data-starting-style:opacity data-ending-style:opacity"
|
|
50
|
+
data-base-ui-focusable=""
|
|
51
|
+
data-open=""
|
|
52
|
+
data-starting-style=""
|
|
53
|
+
id=":r0:"
|
|
42
54
|
role="dialog"
|
|
43
|
-
style="
|
|
55
|
+
style="--nested-dialogs: 0; transition-duration: 300ms;"
|
|
44
56
|
tabindex="-1"
|
|
45
57
|
>
|
|
46
|
-
<
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
aria-disabled="false"
|
|
51
|
-
class="base-Button text-lg inline-flex items-center justify-center select-none appearance-none m-0 relative normal-case align-middle transition-colors duration-350 ease-out shrink-0 outline-hidden [[data-component-type="button"]+&]:ml cursor-pointer no-underline hover:no-underline rounded-sm shadow-none focus-visible:shadow-[0_0_0_3px_rgba(32,78,207,0.48)] focus-within:shadow-[0_0_0_3px_rgba(32,78,207,0.48)] border-none text-white visited:text-white hover:bg-[#4269D6] active:bg-[#1A41AB] bg-blue min-w h-8 py-0 px-4"
|
|
52
|
-
data-component-type="button"
|
|
53
|
-
role="button"
|
|
54
|
-
tabindex="0"
|
|
55
|
-
type="button"
|
|
58
|
+
<div
|
|
59
|
+
class="bg-white shadow-2 transition-shadow duration-300 delay-0 outline-hidden overflow-y flex flex-col m-4 sm:h-auto sm:m-8 max-w-[calc(100%_ sm:max-w-[calc(100%_ rounded-md w-[40.625rem] relative max-h-[calc(100%_ sm:max-h-[calc(100%_"
|
|
60
|
+
role="dialog"
|
|
61
|
+
tabindex="-1"
|
|
56
62
|
>
|
|
57
|
-
<
|
|
58
|
-
|
|
63
|
+
<p>
|
|
64
|
+
Modal content
|
|
65
|
+
</p>
|
|
66
|
+
<button
|
|
67
|
+
aria-disabled="false"
|
|
68
|
+
class="base-Button text-lg inline-flex items-center justify-center select-none appearance-none m-0 relative normal-case align-middle transition-colors duration-350 ease-out shrink-0 outline-hidden [[data-component-type="button"]+&]:ml cursor-pointer no-underline hover:no-underline rounded-sm shadow-none focus-visible:shadow-[0_0_0_3px_rgba(32,78,207,0.48)] focus-within:shadow-[0_0_0_3px_rgba(32,78,207,0.48)] border-none text-white visited:text-white hover:bg-[#4269D6] active:bg-[#1A41AB] bg-blue min-w h-8 py-0 px-4"
|
|
69
|
+
data-component-type="button"
|
|
70
|
+
role="button"
|
|
71
|
+
tabindex="0"
|
|
72
|
+
type="button"
|
|
59
73
|
>
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
74
|
+
<span
|
|
75
|
+
class="items-center inline-flex font-semibold whitespace-nowrap text-button"
|
|
76
|
+
>
|
|
77
|
+
Hide
|
|
78
|
+
</span>
|
|
79
|
+
</button>
|
|
80
|
+
</div>
|
|
63
81
|
</div>
|
|
64
|
-
<
|
|
65
|
-
data-
|
|
82
|
+
<span
|
|
83
|
+
data-base-ui-focus-guard=""
|
|
84
|
+
data-base-ui-inert=""
|
|
85
|
+
data-type="inside"
|
|
86
|
+
role="button"
|
|
87
|
+
style="clip-path: inset(50%); overflow: hidden; white-space: nowrap; border: 0px; padding: 0px; width: 1px; height: 1px; margin: -1px; position: fixed; top: 0px; left: 0px;"
|
|
66
88
|
tabindex="0"
|
|
67
89
|
/>
|
|
68
90
|
</div>
|
|
91
|
+
<span
|
|
92
|
+
data-base-ui-focus-guard=""
|
|
93
|
+
data-base-ui-inert=""
|
|
94
|
+
data-type="outside"
|
|
95
|
+
role="button"
|
|
96
|
+
style="clip-path: inset(50%); overflow: hidden; white-space: nowrap; border: 0px; padding: 0px; width: 1px; height: 1px; margin: -1px; position: fixed; top: 0px; left: 0px;"
|
|
97
|
+
tabindex="0"
|
|
98
|
+
/>
|
|
99
|
+
<span
|
|
100
|
+
aria-owns=":r2:"
|
|
101
|
+
data-base-ui-inert=""
|
|
102
|
+
style="clip-path: inset(50%); position: fixed; top: 0px; left: 0px;"
|
|
103
|
+
/>
|
|
104
|
+
<span
|
|
105
|
+
data-base-ui-focus-guard=""
|
|
106
|
+
data-base-ui-inert=""
|
|
107
|
+
data-type="outside"
|
|
108
|
+
role="button"
|
|
109
|
+
style="clip-path: inset(50%); overflow: hidden; white-space: nowrap; border: 0px; padding: 0px; width: 1px; height: 1px; margin: -1px; position: fixed; top: 0px; left: 0px;"
|
|
110
|
+
tabindex="0"
|
|
111
|
+
/>
|
|
69
112
|
</div>
|
|
70
113
|
</div>
|
|
71
114
|
</body>
|
|
@@ -102,6 +145,7 @@ exports[`Modal useModal opens and closes modal 2`] = `
|
|
|
102
145
|
exports[`Modal useModal shows multiple modals at the same time 1`] = `
|
|
103
146
|
<body>
|
|
104
147
|
<div
|
|
148
|
+
data-base-ui-inert=""
|
|
105
149
|
id="modal-root"
|
|
106
150
|
/>
|
|
107
151
|
<div>
|
|
@@ -110,8 +154,8 @@ exports[`Modal useModal shows multiple modals at the same time 1`] = `
|
|
|
110
154
|
>
|
|
111
155
|
<button
|
|
112
156
|
aria-disabled="false"
|
|
113
|
-
aria-hidden="true"
|
|
114
157
|
class="base-Button text-lg inline-flex items-center justify-center select-none appearance-none m-0 relative normal-case align-middle transition-colors duration-350 ease-out shrink-0 outline-hidden [[data-component-type="button"]+&]:ml cursor-pointer no-underline hover:no-underline rounded-sm shadow-none focus-visible:shadow-[0_0_0_3px_rgba(32,78,207,0.48)] focus-within:shadow-[0_0_0_3px_rgba(32,78,207,0.48)] border-none text-white visited:text-white hover:bg-[#4269D6] active:bg-[#1A41AB] bg-blue min-w h-8 py-0 px-4"
|
|
158
|
+
data-base-ui-inert=""
|
|
115
159
|
data-component-type="button"
|
|
116
160
|
role="button"
|
|
117
161
|
tabindex="0"
|
|
@@ -123,10 +167,31 @@ exports[`Modal useModal shows multiple modals at the same time 1`] = `
|
|
|
123
167
|
Show first
|
|
124
168
|
</span>
|
|
125
169
|
</button>
|
|
170
|
+
<span
|
|
171
|
+
data-base-ui-focus-guard=""
|
|
172
|
+
data-base-ui-inert=""
|
|
173
|
+
data-type="outside"
|
|
174
|
+
role="button"
|
|
175
|
+
style="clip-path: inset(50%); overflow: hidden; white-space: nowrap; border: 0px; padding: 0px; width: 1px; height: 1px; margin: -1px; position: fixed; top: 0px; left: 0px;"
|
|
176
|
+
tabindex="0"
|
|
177
|
+
/>
|
|
178
|
+
<span
|
|
179
|
+
aria-owns=":r7:"
|
|
180
|
+
data-base-ui-inert=""
|
|
181
|
+
style="clip-path: inset(50%); position: fixed; top: 0px; left: 0px;"
|
|
182
|
+
/>
|
|
183
|
+
<span
|
|
184
|
+
data-base-ui-focus-guard=""
|
|
185
|
+
data-base-ui-inert=""
|
|
186
|
+
data-type="outside"
|
|
187
|
+
role="button"
|
|
188
|
+
style="clip-path: inset(50%); overflow: hidden; white-space: nowrap; border: 0px; padding: 0px; width: 1px; height: 1px; margin: -1px; position: fixed; top: 0px; left: 0px;"
|
|
189
|
+
tabindex="0"
|
|
190
|
+
/>
|
|
126
191
|
<button
|
|
127
192
|
aria-disabled="false"
|
|
128
|
-
aria-hidden="true"
|
|
129
193
|
class="base-Button text-lg inline-flex items-center justify-center select-none appearance-none m-0 relative normal-case align-middle transition-colors duration-350 ease-out shrink-0 outline-hidden [[data-component-type="button"]+&]:ml cursor-pointer no-underline hover:no-underline rounded-sm shadow-none focus-visible:shadow-[0_0_0_3px_rgba(32,78,207,0.48)] focus-within:shadow-[0_0_0_3px_rgba(32,78,207,0.48)] border-none text-white visited:text-white hover:bg-[#4269D6] active:bg-[#1A41AB] bg-blue min-w h-8 py-0 px-4"
|
|
194
|
+
data-base-ui-inert=""
|
|
130
195
|
data-component-type="button"
|
|
131
196
|
role="button"
|
|
132
197
|
tabindex="0"
|
|
@@ -139,62 +204,125 @@ exports[`Modal useModal shows multiple modals at the same time 1`] = `
|
|
|
139
204
|
</span>
|
|
140
205
|
</button>
|
|
141
206
|
<div
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
207
|
+
data-base-ui-inert=""
|
|
208
|
+
data-base-ui-portal=""
|
|
209
|
+
id=":r7:"
|
|
145
210
|
>
|
|
146
211
|
<div
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
212
|
+
class="fixed z-modal inset-0 bg-black/50 transition-opacity data-starting-style:opacity data-ending-style:opacity"
|
|
213
|
+
data-base-ui-inert=""
|
|
214
|
+
data-open=""
|
|
215
|
+
data-starting-style=""
|
|
216
|
+
role="presentation"
|
|
217
|
+
style="user-select: none; transition-duration: 300ms;"
|
|
150
218
|
/>
|
|
151
|
-
<
|
|
152
|
-
data-
|
|
219
|
+
<span
|
|
220
|
+
data-base-ui-focus-guard=""
|
|
221
|
+
data-base-ui-inert=""
|
|
222
|
+
data-type="inside"
|
|
223
|
+
role="button"
|
|
224
|
+
style="clip-path: inset(50%); overflow: hidden; white-space: nowrap; border: 0px; padding: 0px; width: 1px; height: 1px; margin: -1px; position: fixed; top: 0px; left: 0px;"
|
|
153
225
|
tabindex="0"
|
|
154
226
|
/>
|
|
155
227
|
<div
|
|
156
|
-
class="
|
|
228
|
+
class="fixed z-modal inset-0 flex flex-col text-lg leading-[normal] justify-center items-center transition-opacity data-starting-style:opacity data-ending-style:opacity"
|
|
229
|
+
data-base-ui-focusable=""
|
|
230
|
+
data-open=""
|
|
231
|
+
data-starting-style=""
|
|
232
|
+
id=":r3:"
|
|
157
233
|
role="dialog"
|
|
158
|
-
style="
|
|
234
|
+
style="--nested-dialogs: 0; transition-duration: 300ms;"
|
|
159
235
|
tabindex="-1"
|
|
160
236
|
>
|
|
161
|
-
<
|
|
162
|
-
|
|
163
|
-
|
|
237
|
+
<div
|
|
238
|
+
class="bg-white shadow-2 transition-shadow duration-300 delay-0 outline-hidden overflow-y flex flex-col m-4 sm:h-auto sm:m-8 max-w-[calc(100%_ sm:max-w-[calc(100%_ rounded-md w-[40.625rem] relative max-h-[calc(100%_ sm:max-h-[calc(100%_"
|
|
239
|
+
role="dialog"
|
|
240
|
+
tabindex="-1"
|
|
241
|
+
>
|
|
242
|
+
<p>
|
|
243
|
+
First modal content
|
|
244
|
+
</p>
|
|
245
|
+
</div>
|
|
164
246
|
</div>
|
|
165
|
-
<
|
|
166
|
-
data-
|
|
247
|
+
<span
|
|
248
|
+
data-base-ui-focus-guard=""
|
|
249
|
+
data-base-ui-inert=""
|
|
250
|
+
data-type="inside"
|
|
251
|
+
role="button"
|
|
252
|
+
style="clip-path: inset(50%); overflow: hidden; white-space: nowrap; border: 0px; padding: 0px; width: 1px; height: 1px; margin: -1px; position: fixed; top: 0px; left: 0px;"
|
|
167
253
|
tabindex="0"
|
|
168
254
|
/>
|
|
169
255
|
</div>
|
|
170
256
|
<div
|
|
171
|
-
|
|
172
|
-
|
|
257
|
+
data-base-ui-portal=""
|
|
258
|
+
id=":r8:"
|
|
173
259
|
>
|
|
174
260
|
<div
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
261
|
+
class="fixed z-modal inset-0 bg-black/50 transition-opacity data-starting-style:opacity data-ending-style:opacity"
|
|
262
|
+
data-base-ui-inert=""
|
|
263
|
+
data-open=""
|
|
264
|
+
data-starting-style=""
|
|
265
|
+
role="presentation"
|
|
266
|
+
style="user-select: none; transition-duration: 300ms;"
|
|
178
267
|
/>
|
|
179
|
-
<
|
|
180
|
-
data-
|
|
268
|
+
<span
|
|
269
|
+
data-base-ui-focus-guard=""
|
|
270
|
+
data-base-ui-inert=""
|
|
271
|
+
data-type="inside"
|
|
272
|
+
role="button"
|
|
273
|
+
style="clip-path: inset(50%); overflow: hidden; white-space: nowrap; border: 0px; padding: 0px; width: 1px; height: 1px; margin: -1px; position: fixed; top: 0px; left: 0px;"
|
|
181
274
|
tabindex="0"
|
|
182
275
|
/>
|
|
183
276
|
<div
|
|
184
|
-
class="
|
|
277
|
+
class="fixed z-modal inset-0 flex flex-col text-lg leading-[normal] justify-center items-center transition-opacity data-starting-style:opacity data-ending-style:opacity"
|
|
278
|
+
data-base-ui-focusable=""
|
|
279
|
+
data-open=""
|
|
280
|
+
data-starting-style=""
|
|
281
|
+
id=":r5:"
|
|
185
282
|
role="dialog"
|
|
186
|
-
style="
|
|
283
|
+
style="--nested-dialogs: 0; transition-duration: 300ms;"
|
|
187
284
|
tabindex="-1"
|
|
188
285
|
>
|
|
189
|
-
<
|
|
190
|
-
|
|
191
|
-
|
|
286
|
+
<div
|
|
287
|
+
class="bg-white shadow-2 transition-shadow duration-300 delay-0 outline-hidden overflow-y flex flex-col m-4 sm:h-auto sm:m-8 max-w-[calc(100%_ sm:max-w-[calc(100%_ rounded-md w-[40.625rem] relative max-h-[calc(100%_ sm:max-h-[calc(100%_"
|
|
288
|
+
role="dialog"
|
|
289
|
+
tabindex="-1"
|
|
290
|
+
>
|
|
291
|
+
<p>
|
|
292
|
+
Second modal content
|
|
293
|
+
</p>
|
|
294
|
+
</div>
|
|
192
295
|
</div>
|
|
193
|
-
<
|
|
194
|
-
data-
|
|
296
|
+
<span
|
|
297
|
+
data-base-ui-focus-guard=""
|
|
298
|
+
data-base-ui-inert=""
|
|
299
|
+
data-type="inside"
|
|
300
|
+
role="button"
|
|
301
|
+
style="clip-path: inset(50%); overflow: hidden; white-space: nowrap; border: 0px; padding: 0px; width: 1px; height: 1px; margin: -1px; position: fixed; top: 0px; left: 0px;"
|
|
195
302
|
tabindex="0"
|
|
196
303
|
/>
|
|
197
304
|
</div>
|
|
305
|
+
<span
|
|
306
|
+
data-base-ui-focus-guard=""
|
|
307
|
+
data-base-ui-inert=""
|
|
308
|
+
data-type="outside"
|
|
309
|
+
role="button"
|
|
310
|
+
style="clip-path: inset(50%); overflow: hidden; white-space: nowrap; border: 0px; padding: 0px; width: 1px; height: 1px; margin: -1px; position: fixed; top: 0px; left: 0px;"
|
|
311
|
+
tabindex="0"
|
|
312
|
+
/>
|
|
313
|
+
<span
|
|
314
|
+
aria-owns=":r8:"
|
|
315
|
+
data-base-ui-inert=""
|
|
316
|
+
style="clip-path: inset(50%); position: fixed; top: 0px; left: 0px;"
|
|
317
|
+
/>
|
|
318
|
+
<span
|
|
319
|
+
data-base-ui-focus-guard=""
|
|
320
|
+
data-base-ui-inert=""
|
|
321
|
+
data-type="outside"
|
|
322
|
+
role="button"
|
|
323
|
+
style="clip-path: inset(50%); overflow: hidden; white-space: nowrap; border: 0px; padding: 0px; width: 1px; height: 1px; margin: -1px; position: fixed; top: 0px; left: 0px;"
|
|
324
|
+
tabindex="0"
|
|
325
|
+
/>
|
|
198
326
|
</div>
|
|
199
327
|
</div>
|
|
200
328
|
</body>
|
package/src/utils/Modal/test.tsx
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import {
|
|
3
|
-
render,
|
|
4
|
-
fireEvent,
|
|
5
|
-
waitForElementToBeRemoved,
|
|
6
|
-
} from '@toptal/picasso-test-utils'
|
|
2
|
+
import { render, fireEvent, waitFor } from '@toptal/picasso-test-utils'
|
|
7
3
|
import { Button } from '@toptal/picasso-button'
|
|
8
4
|
import { Modal } from '@toptal/picasso-modal'
|
|
9
5
|
|
|
@@ -47,7 +43,7 @@ describe('Modal', () => {
|
|
|
47
43
|
const hideModalButton = getByText('Hide')
|
|
48
44
|
|
|
49
45
|
fireEvent.click(hideModalButton)
|
|
50
|
-
await
|
|
46
|
+
await waitFor(() => expect(queryByText('Hide')).toBeFalsy())
|
|
51
47
|
|
|
52
48
|
expect(queryByText('Modal content')).toBeFalsy()
|
|
53
49
|
expect(baseElement).toMatchSnapshot()
|
|
@@ -2,10 +2,9 @@ import type { ReactElement, ReactNode } from 'react'
|
|
|
2
2
|
import React from 'react'
|
|
3
3
|
import cx from 'classnames'
|
|
4
4
|
import type { BaseProps } from '@toptal/picasso-shared'
|
|
5
|
-
import
|
|
6
|
-
import { makeStyles } from '@material-ui/core/styles'
|
|
5
|
+
import { twMerge } from '@toptal/picasso-tailwind-merge'
|
|
7
6
|
|
|
8
|
-
import
|
|
7
|
+
import { createRotate180ClassNames } from './styles'
|
|
9
8
|
|
|
10
9
|
export interface Props extends BaseProps {
|
|
11
10
|
/** Flag for transition execution. */
|
|
@@ -14,18 +13,11 @@ export interface Props extends BaseProps {
|
|
|
14
13
|
children: ReactNode
|
|
15
14
|
}
|
|
16
15
|
|
|
17
|
-
const useStyles = makeStyles<Theme>(styles, {
|
|
18
|
-
name: 'Rotate180',
|
|
19
|
-
})
|
|
20
|
-
|
|
21
16
|
export const Rotate180 = (props: Props) => {
|
|
22
17
|
const { children, style, className, on, ...rest } = props
|
|
23
|
-
const classes = useStyles()
|
|
24
18
|
|
|
25
19
|
const childProps = {
|
|
26
|
-
className: cx(
|
|
27
|
-
[classes.rotate180]: on,
|
|
28
|
-
}),
|
|
20
|
+
className: twMerge(cx(createRotate180ClassNames(on)), className),
|
|
29
21
|
style,
|
|
30
22
|
...rest,
|
|
31
23
|
}
|
|
@@ -6,7 +6,7 @@ exports[`Rotate180 render with transformation 1`] = `
|
|
|
6
6
|
class="Picasso-root"
|
|
7
7
|
>
|
|
8
8
|
<div
|
|
9
|
-
class="
|
|
9
|
+
class="transition-transform duration-150 ease-in rotate-180"
|
|
10
10
|
>
|
|
11
11
|
Rotating component
|
|
12
12
|
</div>
|
|
@@ -20,7 +20,7 @@ exports[`Rotate180 render without transformation 1`] = `
|
|
|
20
20
|
class="Picasso-root"
|
|
21
21
|
>
|
|
22
22
|
<div
|
|
23
|
-
class="
|
|
23
|
+
class="transition-transform duration-150 ease-in"
|
|
24
24
|
>
|
|
25
25
|
Rotating component
|
|
26
26
|
</div>
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
},
|
|
8
|
-
rotate180: {
|
|
9
|
-
transform: 'rotate(180deg)',
|
|
10
|
-
},
|
|
11
|
-
})
|
|
1
|
+
export const createRotate180ClassNames = (on: boolean): string[] => [
|
|
2
|
+
'transition-transform',
|
|
3
|
+
'duration-150',
|
|
4
|
+
'ease-in-out',
|
|
5
|
+
...(on ? ['rotate-180'] : []),
|
|
6
|
+
]
|
package/src/utils/capitalize.ts
CHANGED
|
@@ -1 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
// Not equivalent to `text-transform: capitalize` — only the first letter of
|
|
2
|
+
// the whole string is uppercased, not the first letter of each word.
|
|
3
|
+
export const capitalize = (string: string): string => {
|
|
4
|
+
if (typeof string !== 'string') {
|
|
5
|
+
throw new Error('Picasso: capitalize(string) expects a string argument.')
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
return string.charAt(0).toUpperCase() + string.slice(1)
|
|
9
|
+
}
|
package/src/utils/index.ts
CHANGED
|
@@ -30,7 +30,8 @@ export {
|
|
|
30
30
|
type OverridableComponent,
|
|
31
31
|
} from '@toptal/picasso-shared'
|
|
32
32
|
|
|
33
|
-
export { default as ClickAwayListener } from '
|
|
33
|
+
export { default as ClickAwayListener } from './ClickAwayListener'
|
|
34
|
+
export type { ClickAwayListenerProps } from './ClickAwayListener'
|
|
34
35
|
|
|
35
36
|
export { capitalize } from './capitalize'
|
|
36
37
|
export { default as disableUnsupportedProps } from './disable-unsupported-props'
|