@elliemae/ds-utilities 2.4.1 → 2.4.2-rc.11
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/cjs/hooks/index.js +1 -0
- package/cjs/hooks/useFocusTrap.js +59 -3
- package/cjs/index.js +1 -0
- package/esm/hooks/index.js +1 -1
- package/esm/hooks/useFocusTrap.js +60 -5
- package/esm/index.js +1 -1
- package/package.json +1 -1
- package/types/hooks/index.d.ts +1 -1
- package/types/hooks/useFocusTrap.d.ts +7 -2
package/cjs/hooks/index.js
CHANGED
|
@@ -64,4 +64,5 @@ exports.useParentElement = useParentElement.useParentElement;
|
|
|
64
64
|
exports.useOnElementResize = useOnElementResize.useOnElementResize;
|
|
65
65
|
exports.useIsShowingEllipsis = useIsShowingEllipsis.useIsShowingEllipsis;
|
|
66
66
|
exports.useCallbackAfterRender = useCallbackAfterRender.useCallbackAfterRender;
|
|
67
|
+
exports.UseFocusTrapWithSchema = useFocusTrap.UseFocusTrapWithSchema;
|
|
67
68
|
exports.useFocusTrap = useFocusTrap.useFocusTrap;
|
|
@@ -3,13 +3,65 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var React = require('react');
|
|
6
|
+
var dsPropsHelpers = require('@elliemae/ds-props-helpers');
|
|
6
7
|
|
|
7
|
-
const
|
|
8
|
-
|
|
8
|
+
const useFocusTrapProps = {
|
|
9
|
+
firstElementRef: 'object',
|
|
10
|
+
lastElementRef: 'object',
|
|
11
|
+
onKeyDown: 'function'
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const getVariableType = arg => {
|
|
15
|
+
if (Array.isArray(arg)) return 'array';
|
|
16
|
+
if (arg === null) return 'null';
|
|
17
|
+
if (arg === undefined) return 'undefined';
|
|
18
|
+
return typeof arg;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const throwTypeError = (validPropKey, invalidProp) => {
|
|
22
|
+
throw new Error("Warning: You are trying to pass a not valid \"".concat(validPropKey, "\" property to use a useFocusTrap hook, please provide a valid type.\n\n Received: ").concat(getVariableType(invalidProp), "\n Expected: ").concat(useFocusTrapProps[validPropKey], "\n "));
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const throwRequiredError = validPropKey => {
|
|
26
|
+
throw new Error("Warning: Please provide a \"".concat(validPropKey, "\" property to use a useFocusTrap hook, this property is required."));
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const validateProps = componentProps => {
|
|
30
|
+
if (componentProps.firstElementRef === undefined) {
|
|
31
|
+
throwRequiredError('firstElementRef');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (componentProps.lastElementRef === undefined) {
|
|
35
|
+
throwRequiredError('lastElementRef');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (componentProps.firstElementRef && typeof componentProps.firstElementRef !== 'object') {
|
|
39
|
+
throwTypeError('firstElementRef', componentProps.firstElementRef);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (componentProps.lastElementRef && typeof componentProps.lastElementRef !== 'object') {
|
|
43
|
+
throwTypeError('lastElementRef', componentProps.lastElementRef);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (componentProps.onKeyDown && typeof componentProps.onKeyDown !== 'function') {
|
|
47
|
+
throwTypeError('onKeyDown', componentProps.onKeyDown);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const propTypes = {
|
|
52
|
+
firstElementRef: dsPropsHelpers.PropTypes.oneOfType([dsPropsHelpers.PropTypes.oneOf([null]), dsPropsHelpers.PropTypes.node]).description('Reference to the first element in the focus trap.').isRequired,
|
|
53
|
+
lastElementRef: dsPropsHelpers.PropTypes.oneOfType([dsPropsHelpers.PropTypes.oneOf([null]), dsPropsHelpers.PropTypes.node]).description('Reference to the second element in the focus trap.').isRequired,
|
|
54
|
+
onKeyDown: dsPropsHelpers.PropTypes.func.description('Optional onKeyDown callback.')
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const useFocusTrap = props => {
|
|
58
|
+
// We need to investigate how to validate references with useValidateTypescriptPropTypes.
|
|
59
|
+
React.useEffect(() => validateProps(props), [props]);
|
|
60
|
+
const {
|
|
9
61
|
firstElementRef,
|
|
10
62
|
lastElementRef,
|
|
11
63
|
onKeyDown
|
|
12
|
-
} =
|
|
64
|
+
} = props;
|
|
13
65
|
return React.useCallback(e => {
|
|
14
66
|
if (onKeyDown) onKeyDown(e); // we need to check all the condition before preventing default
|
|
15
67
|
// because we want last-element/first-element tab/shift-tab to keep working
|
|
@@ -28,4 +80,8 @@ const useFocusTrap = _ref => {
|
|
|
28
80
|
}, [firstElementRef, lastElementRef, onKeyDown]);
|
|
29
81
|
};
|
|
30
82
|
|
|
83
|
+
const UseFocusTrapWithSchema = dsPropsHelpers.describe(useFocusTrap);
|
|
84
|
+
UseFocusTrapWithSchema.propTypes = propTypes;
|
|
85
|
+
|
|
86
|
+
exports.UseFocusTrapWithSchema = UseFocusTrapWithSchema;
|
|
31
87
|
exports.useFocusTrap = useFocusTrap;
|
package/cjs/index.js
CHANGED
|
@@ -106,6 +106,7 @@ exports.useParentElement = useParentElement.useParentElement;
|
|
|
106
106
|
exports.useOnElementResize = useOnElementResize.useOnElementResize;
|
|
107
107
|
exports.useIsShowingEllipsis = useIsShowingEllipsis.useIsShowingEllipsis;
|
|
108
108
|
exports.useCallbackAfterRender = useCallbackAfterRender.useCallbackAfterRender;
|
|
109
|
+
exports.UseFocusTrapWithSchema = useFocusTrap.UseFocusTrapWithSchema;
|
|
109
110
|
exports.useFocusTrap = useFocusTrap.useFocusTrap;
|
|
110
111
|
exports.addLeadingZeros = timeUtils.addLeadingZeros;
|
|
111
112
|
exports.getVisibleTimeByFormat = timeUtils.getVisibleTimeByFormat;
|
package/esm/hooks/index.js
CHANGED
|
@@ -18,4 +18,4 @@ export { useParentElement } from './useParentElement.js';
|
|
|
18
18
|
export { useOnElementResize } from './useOnElementResize.js';
|
|
19
19
|
export { useIsShowingEllipsis } from './useIsShowingEllipsis.js';
|
|
20
20
|
export { useCallbackAfterRender } from './useCallbackAfterRender.js';
|
|
21
|
-
export { useFocusTrap } from './useFocusTrap.js';
|
|
21
|
+
export { UseFocusTrapWithSchema, useFocusTrap } from './useFocusTrap.js';
|
|
@@ -1,11 +1,63 @@
|
|
|
1
|
-
import { useCallback } from 'react';
|
|
1
|
+
import { useEffect, useCallback } from 'react';
|
|
2
|
+
import { PropTypes, describe } from '@elliemae/ds-props-helpers';
|
|
2
3
|
|
|
3
|
-
const
|
|
4
|
-
|
|
4
|
+
const useFocusTrapProps = {
|
|
5
|
+
firstElementRef: 'object',
|
|
6
|
+
lastElementRef: 'object',
|
|
7
|
+
onKeyDown: 'function'
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const getVariableType = arg => {
|
|
11
|
+
if (Array.isArray(arg)) return 'array';
|
|
12
|
+
if (arg === null) return 'null';
|
|
13
|
+
if (arg === undefined) return 'undefined';
|
|
14
|
+
return typeof arg;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const throwTypeError = (validPropKey, invalidProp) => {
|
|
18
|
+
throw new Error("Warning: You are trying to pass a not valid \"".concat(validPropKey, "\" property to use a useFocusTrap hook, please provide a valid type.\n\n Received: ").concat(getVariableType(invalidProp), "\n Expected: ").concat(useFocusTrapProps[validPropKey], "\n "));
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const throwRequiredError = validPropKey => {
|
|
22
|
+
throw new Error("Warning: Please provide a \"".concat(validPropKey, "\" property to use a useFocusTrap hook, this property is required."));
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const validateProps = componentProps => {
|
|
26
|
+
if (componentProps.firstElementRef === undefined) {
|
|
27
|
+
throwRequiredError('firstElementRef');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (componentProps.lastElementRef === undefined) {
|
|
31
|
+
throwRequiredError('lastElementRef');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (componentProps.firstElementRef && typeof componentProps.firstElementRef !== 'object') {
|
|
35
|
+
throwTypeError('firstElementRef', componentProps.firstElementRef);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (componentProps.lastElementRef && typeof componentProps.lastElementRef !== 'object') {
|
|
39
|
+
throwTypeError('lastElementRef', componentProps.lastElementRef);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (componentProps.onKeyDown && typeof componentProps.onKeyDown !== 'function') {
|
|
43
|
+
throwTypeError('onKeyDown', componentProps.onKeyDown);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const propTypes = {
|
|
48
|
+
firstElementRef: PropTypes.oneOfType([PropTypes.oneOf([null]), PropTypes.node]).description('Reference to the first element in the focus trap.').isRequired,
|
|
49
|
+
lastElementRef: PropTypes.oneOfType([PropTypes.oneOf([null]), PropTypes.node]).description('Reference to the second element in the focus trap.').isRequired,
|
|
50
|
+
onKeyDown: PropTypes.func.description('Optional onKeyDown callback.')
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const useFocusTrap = props => {
|
|
54
|
+
// We need to investigate how to validate references with useValidateTypescriptPropTypes.
|
|
55
|
+
useEffect(() => validateProps(props), [props]);
|
|
56
|
+
const {
|
|
5
57
|
firstElementRef,
|
|
6
58
|
lastElementRef,
|
|
7
59
|
onKeyDown
|
|
8
|
-
} =
|
|
60
|
+
} = props;
|
|
9
61
|
return useCallback(e => {
|
|
10
62
|
if (onKeyDown) onKeyDown(e); // we need to check all the condition before preventing default
|
|
11
63
|
// because we want last-element/first-element tab/shift-tab to keep working
|
|
@@ -24,4 +76,7 @@ const useFocusTrap = _ref => {
|
|
|
24
76
|
}, [firstElementRef, lastElementRef, onKeyDown]);
|
|
25
77
|
};
|
|
26
78
|
|
|
27
|
-
|
|
79
|
+
const UseFocusTrapWithSchema = describe(useFocusTrap);
|
|
80
|
+
UseFocusTrapWithSchema.propTypes = propTypes;
|
|
81
|
+
|
|
82
|
+
export { UseFocusTrapWithSchema, useFocusTrap };
|
package/esm/index.js
CHANGED
|
@@ -24,7 +24,7 @@ export { useParentElement } from './hooks/useParentElement.js';
|
|
|
24
24
|
export { useOnElementResize } from './hooks/useOnElementResize.js';
|
|
25
25
|
export { useIsShowingEllipsis } from './hooks/useIsShowingEllipsis.js';
|
|
26
26
|
export { useCallbackAfterRender } from './hooks/useCallbackAfterRender.js';
|
|
27
|
-
export { useFocusTrap } from './hooks/useFocusTrap.js';
|
|
27
|
+
export { UseFocusTrapWithSchema, useFocusTrap } from './hooks/useFocusTrap.js';
|
|
28
28
|
export { addLeadingZeros, getVisibleTimeByFormat } from './timeUtils.js';
|
|
29
29
|
export { compose } from './compose.js';
|
|
30
30
|
export { DOCUMENT, WINDOW } from './platform.js';
|
package/package.json
CHANGED
package/types/hooks/index.d.ts
CHANGED
|
@@ -18,4 +18,4 @@ export * from './useParentElement';
|
|
|
18
18
|
export * from './useOnElementResize';
|
|
19
19
|
export * from './useIsShowingEllipsis';
|
|
20
20
|
export * from './useCallbackAfterRender';
|
|
21
|
-
export
|
|
21
|
+
export { useFocusTrap, UseFocusTrapWithSchema } from './useFocusTrap';
|
|
@@ -4,5 +4,10 @@ declare type UseFocusTrapT = <T extends HTMLElement = HTMLElement, K extends HTM
|
|
|
4
4
|
lastElementRef: React.MutableRefObject<K | null>;
|
|
5
5
|
onKeyDown?: (e: KeyboardEvent) => void;
|
|
6
6
|
}) => (e: KeyboardEvent) => void;
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
declare const useFocusTrap: UseFocusTrapT;
|
|
8
|
+
declare const UseFocusTrapWithSchema: import("@elliemae/ds-props-helpers/types/propTypes/types").DocumentedReactComponent<{
|
|
9
|
+
firstElementRef: React.MutableRefObject<HTMLElement | null>;
|
|
10
|
+
lastElementRef: React.MutableRefObject<HTMLElement | null>;
|
|
11
|
+
onKeyDown?: ((e: KeyboardEvent) => void) | undefined;
|
|
12
|
+
}>;
|
|
13
|
+
export { useFocusTrap, UseFocusTrapWithSchema };
|