carbon-react 109.2.3 → 109.3.1
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/esm/__internal__/field-help/field-help.component.d.ts +10 -0
- package/esm/__internal__/field-help/field-help.component.js +12 -16
- package/esm/__internal__/field-help/field-help.style.d.ts +8 -0
- package/esm/__internal__/field-help/field-help.style.js +2 -10
- package/esm/__internal__/field-help/index.d.ts +2 -1
- package/esm/__internal__/focus-trap/focus-trap-utils.d.ts +1 -2
- package/esm/__internal__/focus-trap/focus-trap-utils.js +57 -8
- package/esm/__internal__/focus-trap/focus-trap.component.js +35 -25
- package/esm/__internal__/validations/validation-icon.component.js +1 -1
- package/esm/__spec_helper__/index.d.ts +1 -0
- package/esm/__spec_helper__/index.js +4 -10
- package/esm/__spec_helper__/mock-match-media.d.ts +2 -2
- package/esm/__spec_helper__/mock-match-media.js +2 -2
- package/esm/__spec_helper__/mock-resize-observer.d.ts +2 -0
- package/esm/components/accordion/accordion-group/accordion-group.component.js +1 -1
- package/esm/components/action-popover/action-popover-item/action-popover-item.component.js +2 -2
- package/esm/components/action-popover/action-popover-menu/action-popover-menu.component.js +3 -3
- package/esm/components/action-popover/action-popover.component.js +1 -1
- package/esm/components/alert/alert.component.js +9 -0
- package/esm/components/anchor-navigation/anchor-navigation.component.js +2 -2
- package/esm/components/button/button.component.js +2 -2
- package/esm/components/button-bar/button-bar.component.js +1 -1
- package/esm/components/decimal/decimal.component.js +3 -3
- package/esm/components/dialog/dialog.component.js +9 -2
- package/esm/components/dialog/dialog.d.ts +2 -0
- package/esm/components/dialog-full-screen/dialog-full-screen.component.js +9 -2
- package/esm/components/dialog-full-screen/dialog-full-screen.d.ts +2 -0
- package/esm/components/drawer/drawer.component.js +1 -1
- package/esm/components/grid/grid-container/grid-container.component.d.ts +8 -0
- package/esm/components/grid/grid-container/grid-container.component.js +1821 -21
- package/esm/components/grid/grid-container/grid-container.style.d.ts +3 -0
- package/esm/components/grid/grid-container/grid-container.style.js +2 -2
- package/esm/components/grid/grid-container/index.d.ts +2 -1
- package/esm/components/grid/grid-item/grid-item.component.d.ts +11 -0
- package/esm/components/grid/grid-item/grid-item.component.js +1221 -45
- package/esm/components/grid/grid-item/grid-item.style.d.ts +17 -0
- package/esm/components/grid/grid-item/grid-item.style.js +38 -62
- package/esm/components/grid/grid-item/index.d.ts +2 -1
- package/esm/components/grid/index.d.ts +2 -0
- package/esm/components/grid/index.js +2 -3
- package/esm/components/icon/icon.component.js +1 -1
- package/esm/components/multi-action-button/multi-action-button.component.js +14 -84
- package/esm/components/note/note.component.js +6 -6
- package/esm/components/numeral-date/numeral-date.component.js +1 -1
- package/esm/components/search/search.component.js +1 -1
- package/esm/components/select/filterable-select/filterable-select.component.js +3 -3
- package/esm/components/select/multi-select/multi-select.component.js +2 -2
- package/esm/components/select/simple-select/simple-select.component.js +2 -2
- package/esm/components/sidebar/sidebar.component.js +9 -2
- package/esm/components/sidebar/sidebar.d.ts +2 -0
- package/esm/components/split-button/split-button.component.js +15 -82
- package/esm/components/toast/toast.component.js +35 -9
- package/esm/components/toast/toast.d.ts +5 -1
- package/esm/components/tooltip/tooltip.component.js +1 -1
- package/esm/hooks/__internal__/useMenuKeyboardNavigation/index.d.ts +1 -0
- package/esm/hooks/__internal__/useMenuKeyboardNavigation/index.js +1 -0
- package/esm/hooks/__internal__/useMenuKeyboardNavigation/useMenuKeyboardNavigation.d.ts +2 -0
- package/esm/hooks/__internal__/useMenuKeyboardNavigation/useMenuKeyboardNavigation.js +70 -0
- package/esm/hooks/__internal__/useScrollBlock/useScrollBlock.js +39 -37
- package/lib/__internal__/field-help/field-help.component.d.ts +10 -0
- package/lib/__internal__/field-help/field-help.component.js +12 -16
- package/lib/__internal__/field-help/field-help.style.d.ts +8 -0
- package/lib/__internal__/field-help/field-help.style.js +2 -13
- package/lib/__internal__/field-help/index.d.ts +2 -1
- package/lib/__internal__/focus-trap/focus-trap-utils.d.ts +1 -2
- package/lib/__internal__/focus-trap/focus-trap-utils.js +57 -10
- package/lib/__internal__/focus-trap/focus-trap.component.js +34 -24
- package/lib/__internal__/validations/validation-icon.component.js +1 -1
- package/lib/__spec_helper__/index.d.ts +1 -0
- package/lib/__spec_helper__/index.js +3 -10
- package/lib/__spec_helper__/mock-match-media.d.ts +2 -2
- package/lib/__spec_helper__/mock-match-media.js +4 -4
- package/lib/__spec_helper__/mock-resize-observer.d.ts +2 -0
- package/lib/components/accordion/accordion-group/accordion-group.component.js +1 -1
- package/lib/components/action-popover/action-popover-item/action-popover-item.component.js +2 -2
- package/lib/components/action-popover/action-popover-menu/action-popover-menu.component.js +3 -3
- package/lib/components/action-popover/action-popover.component.js +1 -1
- package/lib/components/alert/alert.component.js +9 -0
- package/lib/components/anchor-navigation/anchor-navigation.component.js +2 -2
- package/lib/components/button/button.component.js +2 -2
- package/lib/components/button-bar/button-bar.component.js +1 -1
- package/lib/components/decimal/decimal.component.js +3 -3
- package/lib/components/dialog/dialog.component.js +9 -2
- package/lib/components/dialog/dialog.d.ts +2 -0
- package/lib/components/dialog-full-screen/dialog-full-screen.component.js +9 -2
- package/lib/components/dialog-full-screen/dialog-full-screen.d.ts +2 -0
- package/lib/components/drawer/drawer.component.js +1 -1
- package/lib/components/grid/grid-container/grid-container.component.d.ts +8 -0
- package/lib/components/grid/grid-container/grid-container.component.js +1826 -22
- package/lib/components/grid/grid-container/grid-container.style.d.ts +3 -0
- package/lib/components/grid/grid-container/grid-container.style.js +2 -2
- package/lib/components/grid/grid-container/index.d.ts +2 -1
- package/lib/components/grid/grid-item/grid-item.component.d.ts +11 -0
- package/lib/components/grid/grid-item/grid-item.component.js +1221 -46
- package/lib/components/grid/grid-item/grid-item.style.d.ts +17 -0
- package/lib/components/grid/grid-item/grid-item.style.js +37 -67
- package/lib/components/grid/grid-item/index.d.ts +2 -1
- package/lib/components/grid/index.d.ts +2 -0
- package/lib/components/icon/icon.component.js +1 -1
- package/lib/components/multi-action-button/multi-action-button.component.js +13 -83
- package/lib/components/note/note.component.js +6 -6
- package/lib/components/numeral-date/numeral-date.component.js +1 -1
- package/lib/components/search/search.component.js +1 -1
- package/lib/components/select/filterable-select/filterable-select.component.js +3 -3
- package/lib/components/select/multi-select/multi-select.component.js +2 -2
- package/lib/components/select/simple-select/simple-select.component.js +2 -2
- package/lib/components/sidebar/sidebar.component.js +9 -2
- package/lib/components/sidebar/sidebar.d.ts +2 -0
- package/lib/components/split-button/split-button.component.js +14 -83
- package/lib/components/toast/toast.component.js +35 -7
- package/lib/components/toast/toast.d.ts +5 -1
- package/lib/components/tooltip/tooltip.component.js +1 -1
- package/lib/hooks/__internal__/useMenuKeyboardNavigation/index.d.ts +1 -0
- package/lib/hooks/__internal__/useMenuKeyboardNavigation/index.js +15 -0
- package/lib/hooks/__internal__/useMenuKeyboardNavigation/package.json +6 -0
- package/lib/hooks/__internal__/useMenuKeyboardNavigation/useMenuKeyboardNavigation.d.ts +2 -0
- package/lib/hooks/__internal__/useMenuKeyboardNavigation/useMenuKeyboardNavigation.js +85 -0
- package/lib/hooks/__internal__/useScrollBlock/useScrollBlock.js +38 -36
- package/package.json +9 -7
- package/scripts/{check_carbon_version.js → check_carbon_version/check_carbon_version.js} +10 -2
- package/scripts/{check_rfcs.js → check_rfcs/check_rfcs.js} +8 -1
- package/esm/__internal__/field-help/field-help.d.ts +0 -14
- package/esm/components/grid/grid-container/grid-container.d.ts +0 -18
- package/esm/components/grid/grid-item/grid-item.d.ts +0 -42
- package/lib/__internal__/field-help/field-help.d.ts +0 -14
- package/lib/components/grid/grid-container/grid-container.d.ts +0 -18
- package/lib/components/grid/grid-item/grid-item.d.ts +0 -42
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { StyledFieldHelpProps } from "./field-help.style";
|
|
3
|
+
export interface FieldHelpProps extends StyledFieldHelpProps {
|
|
4
|
+
/** Child elements */
|
|
5
|
+
children?: React.ReactNode;
|
|
6
|
+
/** The unique id of the FieldHelp component */
|
|
7
|
+
id?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const FieldHelp: ({ children, labelInline, labelWidth, id, }: FieldHelpProps) => JSX.Element;
|
|
10
|
+
export default FieldHelp;
|
|
@@ -1,28 +1,24 @@
|
|
|
1
|
-
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
2
|
-
|
|
3
1
|
import React from "react";
|
|
4
2
|
import PropTypes from "prop-types";
|
|
5
|
-
import
|
|
3
|
+
import StyledFieldHelp from "./field-help.style";
|
|
6
4
|
|
|
7
5
|
const FieldHelp = ({
|
|
8
6
|
children,
|
|
9
7
|
labelInline,
|
|
10
|
-
labelWidth,
|
|
11
|
-
|
|
12
|
-
}) => /*#__PURE__*/React.createElement(
|
|
8
|
+
labelWidth = 30,
|
|
9
|
+
id
|
|
10
|
+
}) => /*#__PURE__*/React.createElement(StyledFieldHelp, {
|
|
13
11
|
"data-element": "help",
|
|
14
12
|
labelInline: labelInline,
|
|
15
|
-
labelWidth: labelWidth
|
|
16
|
-
|
|
13
|
+
labelWidth: labelWidth,
|
|
14
|
+
id: id
|
|
15
|
+
}, children);
|
|
17
16
|
|
|
18
17
|
FieldHelp.propTypes = {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
labelInline: PropTypes.bool,
|
|
24
|
-
|
|
25
|
-
/** Width of a label in percentage. Works only when labelInline is true */
|
|
26
|
-
labelWidth: PropTypes.number
|
|
18
|
+
"children": PropTypes.node,
|
|
19
|
+
"id": PropTypes.string,
|
|
20
|
+
"labelInline": PropTypes.bool,
|
|
21
|
+
"labelWidth": PropTypes.number
|
|
27
22
|
};
|
|
23
|
+
export { FieldHelp };
|
|
28
24
|
export default FieldHelp;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface StyledFieldHelpProps {
|
|
2
|
+
/** When true, label is placed in line an input */
|
|
3
|
+
labelInline?: boolean;
|
|
4
|
+
/** Width of a label in percentage. Works only when labelInline is true */
|
|
5
|
+
labelWidth?: number;
|
|
6
|
+
}
|
|
7
|
+
declare const StyledFieldHelp: import("styled-components").StyledComponent<"span", any, StyledFieldHelpProps, never>;
|
|
8
|
+
export default StyledFieldHelp;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import styled, { css } from "styled-components";
|
|
2
|
-
|
|
3
|
-
const FieldHelpStyle = styled.span`
|
|
2
|
+
const StyledFieldHelp = styled.span`
|
|
4
3
|
display: block;
|
|
5
4
|
flex: 1;
|
|
6
5
|
margin-top: 8px;
|
|
@@ -14,11 +13,4 @@ const FieldHelpStyle = styled.span`
|
|
|
14
13
|
padding-left: 0;
|
|
15
14
|
`}
|
|
16
15
|
`;
|
|
17
|
-
|
|
18
|
-
labelWidth: 30
|
|
19
|
-
};
|
|
20
|
-
FieldHelpStyle.propTypes = {
|
|
21
|
-
labelWidth: PropTypes.number,
|
|
22
|
-
labelInline: PropTypes.bool
|
|
23
|
-
};
|
|
24
|
-
export default FieldHelpStyle;
|
|
16
|
+
export default StyledFieldHelp;
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { default } from "./field-help";
|
|
1
|
+
export { default } from "./field-help.component";
|
|
2
|
+
export type { FieldHelpProps } from "./field-help.component";
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
export const defaultFocusableSelectors: "button:not([disabled]), [href], input:not([type=\"hidden\"]):not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]";
|
|
2
|
-
export function
|
|
3
|
-
export function isRadio(element: any): any;
|
|
2
|
+
export function getNextElement(element: any, focusableElements: any, shiftKey: any): any;
|
|
4
3
|
export function setElementFocus(element: any): void;
|
|
@@ -37,17 +37,66 @@ const isRadio = element => {
|
|
|
37
37
|
return element.hasAttribute("type") && element.getAttribute("type") === "radio";
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
-
const
|
|
40
|
+
const getRadioElementToFocus = (groupName, shiftKey) => {
|
|
41
|
+
const buttonsInGroup = document.querySelectorAll(`input[type="radio"][name="${groupName}"]`);
|
|
42
|
+
const selectedButton = [...buttonsInGroup].find(button => button.checked);
|
|
43
|
+
|
|
44
|
+
if (selectedButton) {
|
|
45
|
+
return selectedButton;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return buttonsInGroup[shiftKey ? buttonsInGroup.length - 1 : 0];
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const getNextElement = (element, focusableElements, shiftKey) => {
|
|
41
52
|
const currentIndex = focusableElements.indexOf(element);
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
53
|
+
const increment = shiftKey ? -1 : 1;
|
|
54
|
+
let nextIndex = currentIndex;
|
|
55
|
+
let foundElement;
|
|
56
|
+
|
|
57
|
+
while (!foundElement) {
|
|
58
|
+
nextIndex += increment;
|
|
59
|
+
|
|
60
|
+
if (nextIndex < 0) {
|
|
61
|
+
nextIndex += focusableElements.length;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (nextIndex >= focusableElements.length) {
|
|
65
|
+
nextIndex -= focusableElements.length;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const nextElement = focusableElements[nextIndex];
|
|
69
|
+
|
|
70
|
+
if (nextElement === element) {
|
|
71
|
+
// guard in case there is only one focusable element (or only a single radio group) in the trap.
|
|
72
|
+
// If this happens we don't want to freeze the browser by looping forever, and it's OK to just focus
|
|
73
|
+
// the same element we're already on
|
|
74
|
+
return element;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (isRadio(nextElement)) {
|
|
78
|
+
// if we've reached a radio element we need to ensure we focus the correct button in its group
|
|
79
|
+
const nextElementGroupName = nextElement.getAttribute("name");
|
|
80
|
+
|
|
81
|
+
if (isRadio(element)) {
|
|
82
|
+
const groupName = element.getAttribute("name"); // if the name is different we're in a new group so can focus the appropriate button in it*/
|
|
83
|
+
|
|
84
|
+
if (nextElementGroupName !== groupName) {
|
|
85
|
+
foundElement = getRadioElementToFocus(nextElementGroupName, shiftKey);
|
|
86
|
+
} // otherwise we're still in the same radio group so need to continue the loop
|
|
45
87
|
|
|
46
|
-
|
|
47
|
-
|
|
88
|
+
} else {
|
|
89
|
+
// if we've moved into a radio group from a non-radio starting point, we still have to ensure we focus
|
|
90
|
+
// the correct button in the group
|
|
91
|
+
foundElement = getRadioElementToFocus(nextElementGroupName, shiftKey);
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
// if we've reached a non-radio element, we can focus it with no issues
|
|
95
|
+
foundElement = nextElement;
|
|
96
|
+
}
|
|
48
97
|
}
|
|
49
98
|
|
|
50
|
-
return
|
|
99
|
+
return foundElement;
|
|
51
100
|
};
|
|
52
101
|
|
|
53
|
-
export { defaultFocusableSelectors,
|
|
102
|
+
export { defaultFocusableSelectors, getNextElement, setElementFocus };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useCallback, useContext, useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
2
2
|
import PropTypes from "prop-types";
|
|
3
|
-
import { defaultFocusableSelectors,
|
|
3
|
+
import { defaultFocusableSelectors, getNextElement, setElementFocus } from "./focus-trap-utils";
|
|
4
4
|
import { ModalContext } from "../../components/modal/modal.component";
|
|
5
5
|
import usePrevious from "../../hooks/__internal__/usePrevious";
|
|
6
6
|
|
|
@@ -10,7 +10,8 @@ const FocusTrap = ({
|
|
|
10
10
|
focusFirstElement,
|
|
11
11
|
bespokeTrap,
|
|
12
12
|
wrapperRef,
|
|
13
|
-
isOpen
|
|
13
|
+
isOpen,
|
|
14
|
+
additionalWrapperRefs
|
|
14
15
|
}) => {
|
|
15
16
|
const trapRef = useRef(null);
|
|
16
17
|
const [focusableElements, setFocusableElements] = useState();
|
|
@@ -28,19 +29,21 @@ const FocusTrap = ({
|
|
|
28
29
|
|
|
29
30
|
return Array.from(candidate).some((el, i) => el !== focusableElements[i]);
|
|
30
31
|
}, [focusableElements]);
|
|
32
|
+
const allRefs = [wrapperRef, ...additionalWrapperRefs].map(ref => ref === null || ref === void 0 ? void 0 : ref.current);
|
|
31
33
|
const updateFocusableElements = useCallback(() => {
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (hasNewInputs(elements)) {
|
|
38
|
-
setFocusableElements(Array.from(elements));
|
|
39
|
-
setFirstElement(elements[0]);
|
|
40
|
-
setLastElement(elements[elements.length - 1]);
|
|
34
|
+
const elements = [];
|
|
35
|
+
allRefs.forEach(ref => {
|
|
36
|
+
if (ref) {
|
|
37
|
+
elements.push(...Array.from(ref.querySelectorAll(defaultFocusableSelectors)).filter(el => Number(el.tabIndex) !== -1));
|
|
41
38
|
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
if (hasNewInputs(elements)) {
|
|
42
|
+
setFocusableElements(Array.from(elements));
|
|
43
|
+
setFirstElement(elements[0]);
|
|
44
|
+
setLastElement(elements[elements.length - 1]);
|
|
42
45
|
}
|
|
43
|
-
}, [hasNewInputs,
|
|
46
|
+
}, [hasNewInputs, allRefs]);
|
|
44
47
|
useEffect(() => {
|
|
45
48
|
const observer = new MutationObserver(updateFocusableElements);
|
|
46
49
|
observer.observe(trapRef.current, {
|
|
@@ -78,20 +81,19 @@ const FocusTrap = ({
|
|
|
78
81
|
ev.preventDefault();
|
|
79
82
|
} else if (ev.shiftKey) {
|
|
80
83
|
/* shift + tab */
|
|
81
|
-
|
|
82
|
-
lastElement.focus();
|
|
83
|
-
ev.preventDefault();
|
|
84
|
-
} // If current element is radio button -
|
|
85
|
-
// find next non radio button element
|
|
86
|
-
|
|
84
|
+
let elementToFocus;
|
|
87
85
|
|
|
88
|
-
if (
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
ev.
|
|
86
|
+
if (activeElement === wrapperRef.current) {
|
|
87
|
+
elementToFocus = getNextElement(firstElement, focusableElements, ev.shiftKey);
|
|
88
|
+
} else {
|
|
89
|
+
elementToFocus = getNextElement(activeElement, focusableElements, ev.shiftKey);
|
|
92
90
|
}
|
|
93
|
-
|
|
94
|
-
|
|
91
|
+
|
|
92
|
+
setElementFocus(elementToFocus);
|
|
93
|
+
ev.preventDefault();
|
|
94
|
+
} else {
|
|
95
|
+
const elementToFocus = getNextElement(activeElement, focusableElements, ev.shiftKey);
|
|
96
|
+
setElementFocus(elementToFocus);
|
|
95
97
|
ev.preventDefault();
|
|
96
98
|
}
|
|
97
99
|
}
|
|
@@ -178,6 +180,14 @@ FocusTrap.propTypes = {
|
|
|
178
180
|
}),
|
|
179
181
|
|
|
180
182
|
/* whether the modal (etc.) component that the focus trap is inside is open or not */
|
|
181
|
-
isOpen: PropTypes.bool
|
|
183
|
+
isOpen: PropTypes.bool,
|
|
184
|
+
|
|
185
|
+
/** an optional array of refs to containers whose content should also be reachable from the FocusTrap */
|
|
186
|
+
additionalWrapperRefs: PropTypes.arrayOf(PropTypes.shape({
|
|
187
|
+
current: PropTypes.any
|
|
188
|
+
}))
|
|
189
|
+
};
|
|
190
|
+
FocusTrap.defaultProps = {
|
|
191
|
+
additionalWrapperRefs: []
|
|
182
192
|
};
|
|
183
193
|
export default FocusTrap;
|
|
@@ -38,7 +38,7 @@ const ValidationIcon = ({
|
|
|
38
38
|
const flipBehaviourCheck = Array.isArray(tooltipFlipOverrides) && tooltipFlipOverrides.every(override => ["bottom", "left", "right", "top"].includes(override));
|
|
39
39
|
|
|
40
40
|
if (tooltipFlipOverrides) {
|
|
41
|
-
invariant(
|
|
41
|
+
!flipBehaviourCheck ? process.env.NODE_ENV !== "production" ? invariant(false, `The tooltipFlipOverrides prop supplied to ValidationIcon must be an array containing some or all of ["top", "bottom", "left", "right"].`) : invariant(false) : void 0;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
const {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import { setup } from "./mock-match-media";
|
|
1
|
+
import { enableFetchMocks } from "jest-fetch-mock";
|
|
2
|
+
import { setupMatchMediaMock } from "./mock-match-media";
|
|
4
3
|
import setupResizeObserverMock from "./mock-resize-observer";
|
|
5
|
-
|
|
6
|
-
require("jest-fetch-mock").enableMocks();
|
|
7
|
-
|
|
4
|
+
enableFetchMocks();
|
|
8
5
|
setupResizeObserverMock();
|
|
9
|
-
|
|
10
|
-
Enzyme.configure({
|
|
11
|
-
adapter: new Adapter()
|
|
12
|
-
});
|
|
6
|
+
setupMatchMediaMock();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
let mocked = false;
|
|
2
2
|
let _matches = false;
|
|
3
3
|
const removeListener = jest.fn();
|
|
4
|
-
export const
|
|
4
|
+
export const setupMatchMediaMock = () => {
|
|
5
5
|
if (!global.window) {
|
|
6
6
|
return;
|
|
7
7
|
}
|
|
@@ -23,7 +23,7 @@ export const setup = () => {
|
|
|
23
23
|
};
|
|
24
24
|
export const mockMatchMedia = matches => {
|
|
25
25
|
if (!mocked) {
|
|
26
|
-
throw new Error("window.matchMedia has not been mocked. Did you call
|
|
26
|
+
throw new Error("window.matchMedia has not been mocked. Did you call setupMatchMediaMock()?");
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
_matches = matches;
|
|
@@ -18,7 +18,7 @@ const AccordionGroup = ({
|
|
|
18
18
|
});
|
|
19
19
|
return hasAccordionChildren;
|
|
20
20
|
}, [children]);
|
|
21
|
-
invariant(
|
|
21
|
+
!hasProperChildren ? process.env.NODE_ENV !== "production" ? invariant(false, `AccordionGroup accepts only children of type \`${Accordion.displayName}\`.`) : invariant(false) : void 0;
|
|
22
22
|
const filteredChildren = useMemo(() => React.Children.toArray(children).filter(child => {
|
|
23
23
|
return /*#__PURE__*/React.isValidElement(child);
|
|
24
24
|
}), [children]);
|
|
@@ -60,8 +60,8 @@ const ActionPopoverItem = ({
|
|
|
60
60
|
}) => {
|
|
61
61
|
const l = useLocale();
|
|
62
62
|
const context = useContext(ActionPopoverContext);
|
|
63
|
-
invariant(
|
|
64
|
-
|
|
63
|
+
!context ? process.env.NODE_ENV !== "production" ? invariant(false, "ActionPopoverItem must be used within an ActionPopover component") : invariant(false) : void 0;
|
|
64
|
+
!( /*#__PURE__*/React.isValidElement(submenu) ? submenu.type === ActionPopoverMenu : true) ? process.env.NODE_ENV !== "production" ? invariant(false, "ActionPopoverItem only accepts submenu of type `ActionPopoverMenu`") : invariant(false) : void 0;
|
|
65
65
|
const {
|
|
66
66
|
setOpenPopover,
|
|
67
67
|
isOpenPopover,
|
|
@@ -21,11 +21,11 @@ const ActionPopoverMenu = /*#__PURE__*/React.forwardRef(({
|
|
|
21
21
|
...rest
|
|
22
22
|
}, ref) => {
|
|
23
23
|
const context = useContext(ActionPopoverContext);
|
|
24
|
-
invariant(
|
|
24
|
+
!context ? process.env.NODE_ENV !== "production" ? invariant(false, "ActionPopoverMenu must be used within an ActionPopover component") : invariant(false) : void 0;
|
|
25
25
|
const {
|
|
26
26
|
focusButton
|
|
27
27
|
} = context;
|
|
28
|
-
|
|
28
|
+
!(setOpen && setFocusIndex && typeof focusIndex !== "undefined") ? process.env.NODE_ENV !== "production" ? invariant(false, "ActionPopoverMenu must be used within an ActionPopover or ActionPopoverItem component") : invariant(false) : void 0;
|
|
29
29
|
const hasProperChildren = useMemo(() => {
|
|
30
30
|
const incorrectChild = React.Children.toArray(children).find(child => {
|
|
31
31
|
if (! /*#__PURE__*/React.isValidElement(child)) {
|
|
@@ -36,7 +36,7 @@ const ActionPopoverMenu = /*#__PURE__*/React.forwardRef(({
|
|
|
36
36
|
});
|
|
37
37
|
return !incorrectChild;
|
|
38
38
|
}, [children]);
|
|
39
|
-
invariant(
|
|
39
|
+
!hasProperChildren ? process.env.NODE_ENV !== "production" ? invariant(false, `ActionPopoverMenu only accepts children of type \`${ActionPopoverItem.displayName}\`` + ` and \`${ActionPopoverDivider.displayName}\`.`) : invariant(false) : void 0;
|
|
40
40
|
const items = useMemo(() => {
|
|
41
41
|
return React.Children.toArray(children).filter(child => {
|
|
42
42
|
return /*#__PURE__*/React.isValidElement(child) && child.type === ActionPopoverItem;
|
|
@@ -49,7 +49,7 @@ const ActionPopover = ({
|
|
|
49
49
|
});
|
|
50
50
|
return !incorrectChild;
|
|
51
51
|
}, [children]);
|
|
52
|
-
invariant(
|
|
52
|
+
!hasProperChildren ? process.env.NODE_ENV !== "production" ? invariant(false, `ActionPopover only accepts children of type \`${ActionPopoverItem.displayName}\`` + ` and \`${ActionPopoverDivider.displayName}\`.`) : invariant(false) : void 0;
|
|
53
53
|
const mappedPlacement = useMemo(() => {
|
|
54
54
|
if (placement === "top" && !rightAlignMenu) {
|
|
55
55
|
return "top-end";
|
|
@@ -30,6 +30,15 @@ Alert.propTypes = {
|
|
|
30
30
|
"disableEscKey": PropTypes.bool,
|
|
31
31
|
"disableFocusTrap": PropTypes.bool,
|
|
32
32
|
"enableBackgroundUI": PropTypes.bool,
|
|
33
|
+
"focusableContainers": PropTypes.arrayOf(PropTypes.shape({
|
|
34
|
+
"current": function (props, propName) {
|
|
35
|
+
if (props[propName] == null) {
|
|
36
|
+
return new Error("Prop '" + propName + "' is required but wasn't specified");
|
|
37
|
+
} else if (typeof props[propName] !== 'object' || props[propName].nodeType !== 1) {
|
|
38
|
+
return new Error("Expected prop '" + propName + "' to be of type Element");
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
})),
|
|
33
42
|
"focusFirstElement": PropTypes.shape({
|
|
34
43
|
"current": function (props, propName) {
|
|
35
44
|
if (props[propName] == null) {
|
|
@@ -13,14 +13,14 @@ const AnchorNavigation = ({
|
|
|
13
13
|
children,
|
|
14
14
|
stickyNavigation
|
|
15
15
|
}) => {
|
|
16
|
-
|
|
16
|
+
!isFragment(stickyNavigation) ? process.env.NODE_ENV !== "production" ? invariant(false, "`stickyNavigation` prop in `AnchorNavigation` should be a React Fragment.") : invariant(false) : void 0;
|
|
17
17
|
const hasCorrectItemStructure = useMemo(() => {
|
|
18
18
|
const incorrectChild = React.Children.toArray(stickyNavigation.props.children).find(child => {
|
|
19
19
|
return ! /*#__PURE__*/React.isValidElement(child) || child.type.displayName !== AnchorNavigationItem.displayName;
|
|
20
20
|
});
|
|
21
21
|
return !incorrectChild;
|
|
22
22
|
}, [stickyNavigation]);
|
|
23
|
-
invariant(
|
|
23
|
+
!hasCorrectItemStructure ? process.env.NODE_ENV !== "production" ? invariant(false, `\`stickyNavigation\` prop in \`AnchorNavigation\` should be a React Fragment that only contains children of type \`${AnchorNavigationItem.displayName}\``) : invariant(false) : void 0;
|
|
24
24
|
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
25
25
|
const sectionRefs = useRef(React.Children.map(stickyNavigation.props.children, child => child.props.target));
|
|
26
26
|
const anchorRefs = useRef(Array.from({
|
|
@@ -97,10 +97,10 @@ const Button = /*#__PURE__*/React.forwardRef(({
|
|
|
97
97
|
fullWidth = false,
|
|
98
98
|
...rest
|
|
99
99
|
}, ref) => {
|
|
100
|
-
|
|
100
|
+
!!!(children || iconType) ? process.env.NODE_ENV !== "production" ? invariant(false, "Either prop `iconType` must be defined or this node must have children.") : invariant(false) : void 0;
|
|
101
101
|
|
|
102
102
|
if (subtext) {
|
|
103
|
-
|
|
103
|
+
!(size === "large") ? process.env.NODE_ENV !== "production" ? invariant(false, "subtext prop has no effect unless the button is large.") : invariant(false) : void 0;
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
if (!deprecatedForwardRefWarnTriggered && forwardRef) {
|
|
@@ -24,7 +24,7 @@ const ButtonBar = ({
|
|
|
24
24
|
});
|
|
25
25
|
return !incorrectChild;
|
|
26
26
|
}, [children]);
|
|
27
|
-
invariant(
|
|
27
|
+
!hasProperChildren ? process.env.NODE_ENV !== "production" ? invariant(false, "ButtonBar accepts only `Button` or `IconButton` elements.") : invariant(false) : void 0;
|
|
28
28
|
|
|
29
29
|
const getBtnProps = child => {
|
|
30
30
|
var _child$props, _child$props2, _child$props2$childre, _child$props2$childre2;
|
|
@@ -31,10 +31,10 @@ const Decimal = ({
|
|
|
31
31
|
const emptyValue = allowEmptyValue ? "" : "0.00";
|
|
32
32
|
const getSafeValueProp = useCallback(initialValue => {
|
|
33
33
|
// We're intentionally preventing the use of number values to help prevent any unintentional rounding issues
|
|
34
|
-
|
|
34
|
+
!(typeof initialValue === "string") ? process.env.NODE_ENV !== "production" ? invariant(false, "Decimal `value` prop must be a string") : invariant(false) : void 0;
|
|
35
35
|
|
|
36
36
|
if (initialValue && !allowEmptyValue) {
|
|
37
|
-
|
|
37
|
+
!(initialValue !== "") ? process.env.NODE_ENV !== "production" ? invariant(false, "Decimal `value` must not be an empty string. Please use `allowEmptyValue` or `0.00`") : invariant(false) : void 0;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
return initialValue;
|
|
@@ -164,7 +164,7 @@ const Decimal = ({
|
|
|
164
164
|
const prevControlledRef = useRef();
|
|
165
165
|
useEffect(() => {
|
|
166
166
|
const message = "Input elements should not switch from uncontrolled to controlled (or vice versa). " + "Decide between using a controlled or uncontrolled input element for the lifetime of the component";
|
|
167
|
-
|
|
167
|
+
!(prevControlledRef.current !== isControlled) ? process.env.NODE_ENV !== "production" ? invariant(false, message) : invariant(false) : void 0;
|
|
168
168
|
prevControlledRef.current = isControlled;
|
|
169
169
|
}, [isControlled]);
|
|
170
170
|
const prevValue = usePrevious(value);
|
|
@@ -31,6 +31,7 @@ const Dialog = ({
|
|
|
31
31
|
help,
|
|
32
32
|
role = "dialog",
|
|
33
33
|
contentPadding = {},
|
|
34
|
+
focusableContainers,
|
|
34
35
|
...rest
|
|
35
36
|
}) => {
|
|
36
37
|
const locale = useLocale();
|
|
@@ -156,7 +157,8 @@ const Dialog = ({
|
|
|
156
157
|
focusFirstElement: focusFirstElement,
|
|
157
158
|
bespokeTrap: bespokeFocusTrap,
|
|
158
159
|
wrapperRef: dialogRef,
|
|
159
|
-
isOpen: open
|
|
160
|
+
isOpen: open,
|
|
161
|
+
additionalWrapperRefs: focusableContainers
|
|
160
162
|
}, /*#__PURE__*/React.createElement(DialogStyle, _extends({
|
|
161
163
|
"aria-modal": true,
|
|
162
164
|
ref: dialogRef,
|
|
@@ -247,7 +249,12 @@ Dialog.propTypes = {
|
|
|
247
249
|
p: PropTypes.oneOf([0, 1, 2, 3, 4, 5, 6, 7, 8]),
|
|
248
250
|
px: PropTypes.oneOf([0, 1, 2, 3, 4, 5, 6, 7, 8]),
|
|
249
251
|
py: PropTypes.oneOf([0, 1, 2, 3, 4, 5, 6, 7, 8])
|
|
250
|
-
})
|
|
252
|
+
}),
|
|
253
|
+
|
|
254
|
+
/** an optional array of refs to containers whose content should also be reachable by tabbing from the dialog */
|
|
255
|
+
focusableContainers: PropTypes.arrayOf(PropTypes.shape({
|
|
256
|
+
current: PropTypes.any
|
|
257
|
+
}))
|
|
251
258
|
};
|
|
252
259
|
Dialog.defaultProps = {
|
|
253
260
|
size: "medium",
|
|
@@ -59,6 +59,8 @@ export interface DialogProps extends ModalProps {
|
|
|
59
59
|
role?: string;
|
|
60
60
|
/** Padding to be set on the Dialog content */
|
|
61
61
|
contentPadding?: ContentPaddingInterface;
|
|
62
|
+
/** an optional array of refs to containers whose content should also be reachable by tabbing from the dialog */
|
|
63
|
+
focusableContainers?: React.MutableRefObject<HTMLElement>[];
|
|
62
64
|
}
|
|
63
65
|
|
|
64
66
|
declare function Dialog(props: DialogProps): JSX.Element;
|
|
@@ -32,6 +32,7 @@ const DialogFullScreen = ({
|
|
|
32
32
|
contentRef,
|
|
33
33
|
help,
|
|
34
34
|
role = "dialog",
|
|
35
|
+
focusableContainers,
|
|
35
36
|
...rest
|
|
36
37
|
}) => {
|
|
37
38
|
const locale = useLocale();
|
|
@@ -86,7 +87,8 @@ const DialogFullScreen = ({
|
|
|
86
87
|
autoFocus: !disableAutoFocus,
|
|
87
88
|
focusFirstElement: focusFirstElement,
|
|
88
89
|
wrapperRef: dialogRef,
|
|
89
|
-
isOpen: open
|
|
90
|
+
isOpen: open,
|
|
91
|
+
additionalWrapperRefs: focusableContainers
|
|
90
92
|
}, /*#__PURE__*/React.createElement(StyledDialogFullScreen, _extends({
|
|
91
93
|
"aria-modal": role === "dialog" ? true : undefined
|
|
92
94
|
}, ariaProps, {
|
|
@@ -170,6 +172,11 @@ DialogFullScreen.propTypes = {
|
|
|
170
172
|
})]),
|
|
171
173
|
|
|
172
174
|
/** The ARIA role to be applied to the DialogFullscreen container */
|
|
173
|
-
role: PropTypes.string
|
|
175
|
+
role: PropTypes.string,
|
|
176
|
+
|
|
177
|
+
/** an optional array of refs to containers whose content should also be reachable by tabbing from the dialog */
|
|
178
|
+
focusableContainers: PropTypes.arrayOf(PropTypes.shape({
|
|
179
|
+
current: PropTypes.any
|
|
180
|
+
}))
|
|
174
181
|
};
|
|
175
182
|
export default DialogFullScreen;
|
|
@@ -41,6 +41,8 @@ export interface DialogFullScreenProps extends ModalProps {
|
|
|
41
41
|
title?: React.ReactNode;
|
|
42
42
|
/** The ARIA role to be applied to the DialogFullscreen container */
|
|
43
43
|
role?: string;
|
|
44
|
+
/** an optional array of refs to containers whose content should also be reachable by tabbing from the dialog */
|
|
45
|
+
focusableContainers?: React.MutableRefObject<HTMLElement>[];
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
declare function DialogFullScreen(props: DialogFullScreenProps): JSX.Element;
|
|
@@ -69,7 +69,7 @@ const Drawer = ({
|
|
|
69
69
|
const previousValue = usePrevious(expanded);
|
|
70
70
|
useEffect(() => {
|
|
71
71
|
const message = "Drawer should not switch from uncontrolled to controlled" + " (or vice versa). Decide between using a controlled or uncontrolled Drawer element" + " for the lifetime of the component";
|
|
72
|
-
|
|
72
|
+
!(isControlled.current === (expanded !== undefined)) ? process.env.NODE_ENV !== "production" ? invariant(false, message) : invariant(false) : void 0;
|
|
73
73
|
|
|
74
74
|
if (isControlled.current && previousValue !== expanded) {
|
|
75
75
|
setIsExpanded(expanded);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { SpaceProps, GridProps } from "styled-system";
|
|
3
|
+
export interface GridContainerProps extends SpaceProps, GridProps, React.HTMLAttributes<HTMLDivElement> {
|
|
4
|
+
/** Defines the Components to be rendered within the GridContainer. Requires GridItemProps */
|
|
5
|
+
children?: React.ReactNode;
|
|
6
|
+
}
|
|
7
|
+
export declare const GridContainer: (props: GridContainerProps) => JSX.Element;
|
|
8
|
+
export default GridContainer;
|