@openedx/paragon 22.8.1 → 22.9.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/Modal/ModalContext.d.ts +15 -0
- package/dist/Modal/ModalContext.js +7 -14
- package/dist/Modal/ModalContext.js.map +1 -1
- package/dist/Modal/ModalDialog.d.ts +105 -0
- package/dist/Modal/ModalDialog.js +23 -22
- package/dist/Modal/ModalDialog.js.map +1 -1
- package/dist/Modal/ModalDialogHeader.d.ts +10 -0
- package/dist/Modal/ModalDialogHeader.js +6 -7
- package/dist/Modal/ModalDialogHeader.js.map +1 -1
- package/dist/Modal/ModalLayer.d.ts +53 -0
- package/dist/Modal/ModalLayer.js +5 -14
- package/dist/Modal/ModalLayer.js.map +1 -1
- package/dist/Modal/Portal.d.ts +11 -0
- package/dist/Modal/Portal.js +5 -6
- package/dist/Modal/Portal.js.map +1 -1
- package/dist/hooks/useArrowKeyNavigation.js +2 -3
- package/dist/hooks/useArrowKeyNavigation.js.map +1 -1
- package/dist/index.d.ts +18 -4
- package/dist/index.js +19 -5
- package/package.json +2 -2
- package/src/DataTable/selection/tests/ControlledSelectHeader.test.jsx +7 -7
- package/src/Modal/{ModalContext.jsx → ModalContext.tsx} +19 -16
- package/src/Modal/{ModalDialog.jsx → ModalDialog.tsx} +50 -24
- package/src/Modal/{ModalDialogHeader.jsx → ModalDialogHeader.tsx} +17 -11
- package/src/Modal/{ModalLayer.jsx → ModalLayer.tsx} +17 -17
- package/src/Modal/{Portal.jsx → Portal.tsx} +10 -7
- package/src/Modal/tests/{ModalDialog.test.jsx → ModalDialog.test.tsx} +16 -10
- package/src/Modal/tests/{ModalLayer.test.jsx → ModalLayer.test.tsx} +5 -5
- package/src/Modal/tests/{Portal.test.jsx → Portal.test.tsx} +3 -3
- package/src/hooks/useArrowKeyNavigation.jsx +1 -2
- package/src/index.d.ts +18 -4
- package/src/index.js +19 -5
- /package/src/Truncate/{Truncate.test.js → utils.test.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useArrowKeyNavigation.js","names":["useRef","useEffect","handleEnter","_ref","event","currentIndex","activeElement","click","preventDefault","handleArrowKey","_ref2","availableElements","focus","nextElement","key","length","_availableElements","_slicedToArray","handleEvents","_ref3","_ref3$ignoredKeys","ignoredKeys","parentNode","_ref3$selectors","selectors","includes","_document","document","contains","querySelectorAll","Array","from","findIndex","availableElement","useArrowKeyNavigation","props","_ref4","eventHandler","current","addEventListener","removeEventListener"],"sources":["../../src/hooks/useArrowKeyNavigation.jsx"],"sourcesContent":["import { useRef, useEffect } from 'react';\n\n/**\n * A React hook to enable arrow key navigation on a component.\n */\n\nfunction handleEnter({ event, currentIndex, activeElement }) {\n if (currentIndex === -1) { return; }\n activeElement.click();\n event.preventDefault();\n}\n\nfunction handleArrowKey({ event, currentIndex, availableElements }) {\n // If the focus isn't in the container, focus on the first thing\n if (currentIndex === -1) { availableElements[0].focus(); }\n\n // Move the focus up or down. Wrap around ends of list.\n let nextElement;\n\n if (event.key === 'ArrowDown' || event.key === 'ArrowRight') {\n nextElement = availableElements[(currentIndex + 1) % availableElements.length];\n }\n if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') {\n nextElement = currentIndex - 1 < 0\n ? availableElements[currentIndex - 1 + availableElements.length]\n : availableElements[currentIndex - 1];\n }\n if (event.key === 'End') {\n nextElement = availableElements[availableElements.length - 1];\n }\n if (event.key === 'Home') {\n [nextElement] = availableElements;\n }\n\n
|
|
1
|
+
{"version":3,"file":"useArrowKeyNavigation.js","names":["useRef","useEffect","handleEnter","_ref","event","currentIndex","activeElement","click","preventDefault","handleArrowKey","_ref2","_nextElement","availableElements","focus","nextElement","key","length","_availableElements","_slicedToArray","handleEvents","_ref3","_ref3$ignoredKeys","ignoredKeys","parentNode","_ref3$selectors","selectors","includes","_document","document","contains","querySelectorAll","Array","from","findIndex","availableElement","useArrowKeyNavigation","props","_ref4","eventHandler","current","addEventListener","removeEventListener"],"sources":["../../src/hooks/useArrowKeyNavigation.jsx"],"sourcesContent":["import { useRef, useEffect } from 'react';\n\n/**\n * A React hook to enable arrow key navigation on a component.\n */\n\nfunction handleEnter({ event, currentIndex, activeElement }) {\n if (currentIndex === -1) { return; }\n activeElement.click();\n event.preventDefault();\n}\n\nfunction handleArrowKey({ event, currentIndex, availableElements }) {\n // If the focus isn't in the container, focus on the first thing\n if (currentIndex === -1) { availableElements[0].focus(); }\n\n // Move the focus up or down. Wrap around ends of list.\n let nextElement;\n\n if (event.key === 'ArrowDown' || event.key === 'ArrowRight') {\n nextElement = availableElements[(currentIndex + 1) % availableElements.length];\n }\n if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') {\n nextElement = currentIndex - 1 < 0\n ? availableElements[currentIndex - 1 + availableElements.length]\n : availableElements[currentIndex - 1];\n }\n if (event.key === 'End') {\n nextElement = availableElements[availableElements.length - 1];\n }\n if (event.key === 'Home') {\n [nextElement] = availableElements;\n }\n\n nextElement?.focus();\n event.preventDefault();\n}\n\n/**\n * Implement arrow key navigation for the given parentNode\n */\nfunction handleEvents({\n event,\n ignoredKeys = [],\n parentNode,\n selectors = 'a,button,input',\n}) {\n if (!parentNode) { return; }\n\n const { key } = event;\n\n if (!['ArrowUp', 'ArrowDown', 'ArrowRight', 'ArrowLeft', 'Enter', 'Home', 'End'].includes(key)\n || ignoredKeys.includes(key)) {\n return;\n }\n\n const { activeElement } = document;\n\n // If we're not inside the container, don't do anything\n if (!parentNode.contains(activeElement)) { return; }\n\n // Get the list of elements we're allowed to scroll through\n const availableElements = parentNode.querySelectorAll(selectors);\n\n // No elements are available to loop through.\n if (!availableElements.length) { return; }\n\n // Which index is currently selected\n const currentIndex = Array.from(availableElements).findIndex(\n (availableElement) => availableElement === activeElement,\n );\n\n if (key === 'Enter') {\n handleEnter({ event, currentIndex, activeElement });\n }\n handleArrowKey({ event, currentIndex, availableElements });\n}\n\nexport default function useArrowKeyNavigation(props) {\n const { selectors, ignoredKeys } = props || {};\n const parentNode = useRef();\n\n useEffect(() => {\n const eventHandler = (event) => {\n handleEvents({\n event, ignoredKeys, parentNode: parentNode.current, selectors,\n });\n };\n\n document.addEventListener('keydown', eventHandler);\n\n return () => document.removeEventListener('keydown', eventHandler);\n }, [ignoredKeys, selectors]);\n\n return parentNode;\n}\n"],"mappings":"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","ignoreList":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -12,7 +12,11 @@ export { default as Container, ContainerSize } from './Container';
|
|
|
12
12
|
export { default as Hyperlink, HYPER_LINK_EXTERNAL_LINK_ALT_TEXT, HYPER_LINK_EXTERNAL_LINK_TITLE } from './Hyperlink';
|
|
13
13
|
export { default as Icon } from './Icon';
|
|
14
14
|
export { default as IconButton, IconButtonWithTooltip } from './IconButton';
|
|
15
|
+
export { default as ModalContext } from './Modal/ModalContext';
|
|
16
|
+
export { default as ModalDialog, MODAL_DIALOG_CLOSE_LABEL } from './Modal/ModalDialog';
|
|
17
|
+
export { default as ModalLayer } from './Modal/ModalLayer';
|
|
15
18
|
export { default as Overlay, OverlayTrigger } from './Overlay';
|
|
19
|
+
export { default as Portal } from './Modal/Portal';
|
|
16
20
|
export { default as Tooltip } from './Tooltip';
|
|
17
21
|
|
|
18
22
|
// // // // // // // // // // // // // // // // // // // // // // // // // // //
|
|
@@ -39,7 +43,9 @@ export const
|
|
|
39
43
|
export const
|
|
40
44
|
Carousel: any, CarouselItem: any, CAROUSEL_NEXT_LABEL_TEXT: any, CAROUSEL_PREV_LABEL_TEXT: any;
|
|
41
45
|
// from './Carousel';
|
|
46
|
+
/** @deprecated Replaced by `Form.Checkbox`. */
|
|
42
47
|
export const CheckBox: any; // from './CheckBox';
|
|
48
|
+
/** @deprecated Replaced by `Form.Checkbox` and `Form.CheckboxSet`. */
|
|
43
49
|
export const CheckBoxGroup: any; // from './CheckBoxGroup';
|
|
44
50
|
export const CloseButton: any; // from './CloseButton';
|
|
45
51
|
export const Layout: any, Col: any, Row: any; // from './Layout';
|
|
@@ -53,6 +59,7 @@ export const
|
|
|
53
59
|
SplitButton: any;
|
|
54
60
|
// from './Dropdown';
|
|
55
61
|
export const Fade: any; // from './Fade';
|
|
62
|
+
/** @deprecated */
|
|
56
63
|
export const Fieldset: any; // from './Fieldset';
|
|
57
64
|
export const
|
|
58
65
|
Form: any,
|
|
@@ -77,28 +84,30 @@ export const
|
|
|
77
84
|
InputGroup: any;
|
|
78
85
|
// from './Form';
|
|
79
86
|
export const IconButtonToggle: any; // from './IconButtonToggle';
|
|
87
|
+
/** @deprecated Replaced by `Form.Control`. */
|
|
80
88
|
export const Input: any; // from './Input';
|
|
89
|
+
/** @deprecated Replaced by `Form.Control`. */
|
|
81
90
|
export const InputSelect: any; // from './InputSelect';
|
|
91
|
+
/** @deprecated Replaced by `Form.Control`. */
|
|
82
92
|
export const InputText: any; // from './InputText';
|
|
83
93
|
export const Image: any, Figure; // from './Image';
|
|
94
|
+
/** @deprecated */
|
|
84
95
|
export const ListBox: any; // from './ListBox';
|
|
96
|
+
/** @deprecated */
|
|
85
97
|
export const ListBoxOption: any; // from './ListBoxOption';
|
|
86
98
|
export const MailtoLink: any, MAIL_TO_LINK_EXTERNAL_LINK_ALTERNATIVE_TEXT: string, MAIL_TO_LINK_EXTERNAL_LINK_TITLE: string; // from './MailtoLink';
|
|
87
99
|
export const Media: any; // from './Media';
|
|
88
100
|
export const Menu: any; // from './Menu';
|
|
89
101
|
export const MenuItem: any; // from './Menu/MenuItem';
|
|
90
102
|
export const SelectMenu: any, SELECT_MENU_DEFAULT_MESSAGE: string; // from './Menu/SelectMenu';
|
|
103
|
+
/** @deprecated Use `ModalDialog` instead. */
|
|
91
104
|
export const Modal: any; // from './Modal';
|
|
92
105
|
export const ModalCloseButton: any; // from './Modal/ModalCloseButton';
|
|
93
106
|
export const FullscreenModal: any, FULLSCREEN_MODAL_CLOSE_LABEL: string; // from './Modal/FullscreenModal';
|
|
94
107
|
export const MarketingModal: any; // from './Modal/MarketingModal';
|
|
95
108
|
export const StandardModal: any, STANDARD_MODAL_CLOSE_LABEL: string; // from './Modal/StandardModal';
|
|
96
109
|
export const AlertModal: any; // from './Modal/AlertModal';
|
|
97
|
-
export const ModalLayer: any; // from './Modal/ModalLayer';
|
|
98
|
-
export const ModalDialog: any, MODAL_DIALOG_CLOSE_LABEL: string; // from './Modal/ModalDialog';
|
|
99
110
|
export const ModalPopup: any; // from './Modal/ModalPopup';
|
|
100
|
-
export const ModalContext: any; // from './Modal/ModalContext';
|
|
101
|
-
export const Portal: any; // from './Modal/Portal';
|
|
102
111
|
export const PopperElement: any; // from './Modal/PopperElement';
|
|
103
112
|
|
|
104
113
|
export const
|
|
@@ -122,6 +131,7 @@ export const
|
|
|
122
131
|
export const Popover: any, PopoverTitle: any, PopoverContent: any; // from './Popover';
|
|
123
132
|
export const ProgressBar: any; // from './ProgressBar';
|
|
124
133
|
export const ProductTour: any; // from './ProductTour';
|
|
134
|
+
/** @deprecated Replaced by `Form.Radio` and `Form.RadioSet`. */
|
|
125
135
|
export const RadioButtonGroup: any, RadioButton: any; // from './RadioButtonGroup';
|
|
126
136
|
export const ResponsiveEmbed: any; // from './ResponsiveEmbed';
|
|
127
137
|
export const
|
|
@@ -135,7 +145,9 @@ export const Sheet: any; // from './Sheet';
|
|
|
135
145
|
export const Spinner: any; // from './Spinner';
|
|
136
146
|
export const Stepper: any; // from './Stepper';
|
|
137
147
|
export const StatefulButton: any; // from './StatefulButton';
|
|
148
|
+
/** @deprecated Replaced by `Alert`. */
|
|
138
149
|
export const StatusAlert: any; // from './StatusAlert';
|
|
150
|
+
/** @deprecated Replaced by `DataTable`. */
|
|
139
151
|
export const Table: any; // from './Table';
|
|
140
152
|
export const
|
|
141
153
|
Tabs: any,
|
|
@@ -144,8 +156,10 @@ export const
|
|
|
144
156
|
TabContent: any,
|
|
145
157
|
TabPane: any;
|
|
146
158
|
// from './Tabs';
|
|
159
|
+
/** @deprecated Replaced by `Form.Control`. */
|
|
147
160
|
export const TextArea: any; // from './TextArea';
|
|
148
161
|
export const Toast: any, TOAST_CLOSE_LABEL_TEXT: string, TOAST_DELAY: number; // from './Toast';
|
|
162
|
+
/** @deprecated Replaced by `Form.Group`. */
|
|
149
163
|
export const ValidationFormGroup: any; // from './ValidationFormGroup';
|
|
150
164
|
export const TransitionReplace: any; // from './TransitionReplace';
|
|
151
165
|
export const ValidationMessage: any; // from './ValidationMessage';
|
package/dist/index.js
CHANGED
|
@@ -8,10 +8,15 @@ export { default as Bubble } from './Bubble';
|
|
|
8
8
|
export { default as Button, ButtonGroup, ButtonToolbar } from './Button';
|
|
9
9
|
export { default as Chip, CHIP_PGN_CLASS } from './Chip';
|
|
10
10
|
export { default as ChipCarousel } from './ChipCarousel';
|
|
11
|
+
export { default as Container } from './Container';
|
|
11
12
|
export { default as Hyperlink, HYPER_LINK_EXTERNAL_LINK_ALT_TEXT, HYPER_LINK_EXTERNAL_LINK_TITLE } from './Hyperlink';
|
|
12
13
|
export { default as Icon } from './Icon';
|
|
13
14
|
export { default as IconButton, IconButtonWithTooltip } from './IconButton';
|
|
15
|
+
export { default as ModalContext } from './Modal/ModalContext';
|
|
16
|
+
export { default as ModalDialog, MODAL_DIALOG_CLOSE_LABEL } from './Modal/ModalDialog';
|
|
17
|
+
export { default as ModalLayer } from './Modal/ModalLayer';
|
|
14
18
|
export { default as Overlay, OverlayTrigger } from './Overlay';
|
|
19
|
+
export { default as Portal } from './Modal/Portal';
|
|
15
20
|
export { default as Tooltip } from './Tooltip';
|
|
16
21
|
|
|
17
22
|
// // // // // // // // // // // // // // // // // // // // // // // // // // //
|
|
@@ -38,10 +43,11 @@ export {
|
|
|
38
43
|
export {
|
|
39
44
|
default as Carousel, CarouselItem, CAROUSEL_NEXT_LABEL_TEXT, CAROUSEL_PREV_LABEL_TEXT,
|
|
40
45
|
} from './Carousel';
|
|
46
|
+
/** @deprecated Replaced by `Form.Checkbox`. */
|
|
41
47
|
export { default as CheckBox } from './CheckBox';
|
|
48
|
+
/** @deprecated Replaced by `Form.Checkbox` and `Form.CheckboxSet`. */
|
|
42
49
|
export { default as CheckBoxGroup } from './CheckBoxGroup';
|
|
43
50
|
export { default as CloseButton } from './CloseButton';
|
|
44
|
-
export { default as Container } from './Container';
|
|
45
51
|
export { default as Layout, Col, Row } from './Layout';
|
|
46
52
|
export { default as Collapse } from './Collapse';
|
|
47
53
|
export { default as Collapsible } from './Collapsible';
|
|
@@ -53,6 +59,7 @@ export {
|
|
|
53
59
|
SplitButton,
|
|
54
60
|
} from './Dropdown';
|
|
55
61
|
export { default as Fade } from './Fade';
|
|
62
|
+
/** @deprecated */
|
|
56
63
|
export { default as Fieldset } from './Fieldset';
|
|
57
64
|
export {
|
|
58
65
|
default as Form,
|
|
@@ -77,28 +84,30 @@ export {
|
|
|
77
84
|
InputGroup,
|
|
78
85
|
} from './Form';
|
|
79
86
|
export { default as IconButtonToggle } from './IconButtonToggle';
|
|
87
|
+
/** @deprecated Replaced by `Form.Control`. */
|
|
80
88
|
export { default as Input } from './Input';
|
|
89
|
+
/** @deprecated Replaced by `Form.Control`. */
|
|
81
90
|
export { default as InputSelect } from './InputSelect';
|
|
91
|
+
/** @deprecated Replaced by `Form.Control`. */
|
|
82
92
|
export { default as InputText } from './InputText';
|
|
83
93
|
export { default as Image, Figure } from './Image';
|
|
94
|
+
/** @deprecated */
|
|
84
95
|
export { default as ListBox } from './ListBox';
|
|
96
|
+
/** @deprecated */
|
|
85
97
|
export { default as ListBoxOption } from './ListBoxOption';
|
|
86
98
|
export { default as MailtoLink, MAIL_TO_LINK_EXTERNAL_LINK_ALTERNATIVE_TEXT, MAIL_TO_LINK_EXTERNAL_LINK_TITLE } from './MailtoLink';
|
|
87
99
|
export { default as Media } from './Media';
|
|
88
100
|
export { default as Menu } from './Menu';
|
|
89
101
|
export { default as MenuItem } from './Menu/MenuItem';
|
|
90
102
|
export { default as SelectMenu, SELECT_MENU_DEFAULT_MESSAGE } from './Menu/SelectMenu';
|
|
103
|
+
/** @deprecated Use `ModalDialog` instead. */
|
|
91
104
|
export { default as Modal } from './Modal';
|
|
92
105
|
export { default as ModalCloseButton } from './Modal/ModalCloseButton';
|
|
93
106
|
export { default as FullscreenModal, FULLSCREEN_MODAL_CLOSE_LABEL } from './Modal/FullscreenModal';
|
|
94
107
|
export { default as MarketingModal } from './Modal/MarketingModal';
|
|
95
108
|
export { default as StandardModal, STANDARD_MODAL_CLOSE_LABEL } from './Modal/StandardModal';
|
|
96
109
|
export { default as AlertModal } from './Modal/AlertModal';
|
|
97
|
-
export { default as ModalLayer } from './Modal/ModalLayer';
|
|
98
|
-
export { default as ModalDialog, MODAL_DIALOG_CLOSE_LABEL } from './Modal/ModalDialog';
|
|
99
110
|
export { default as ModalPopup } from './Modal/ModalPopup';
|
|
100
|
-
export { default as ModalContext } from './Modal/ModalContext';
|
|
101
|
-
export { default as Portal } from './Modal/Portal';
|
|
102
111
|
export { default as PopperElement } from './Modal/PopperElement';
|
|
103
112
|
|
|
104
113
|
export {
|
|
@@ -122,6 +131,7 @@ export {
|
|
|
122
131
|
export { default as Popover, PopoverTitle, PopoverContent } from './Popover';
|
|
123
132
|
export { default as ProgressBar } from './ProgressBar';
|
|
124
133
|
export { default as ProductTour } from './ProductTour';
|
|
134
|
+
/** @deprecated Replaced by `Form.Radio` and `Form.RadioSet`. */
|
|
125
135
|
export { default as RadioButtonGroup, RadioButton } from './RadioButtonGroup';
|
|
126
136
|
export { default as ResponsiveEmbed } from './ResponsiveEmbed';
|
|
127
137
|
export {
|
|
@@ -135,7 +145,9 @@ export { default as Sheet } from './Sheet';
|
|
|
135
145
|
export { default as Spinner } from './Spinner';
|
|
136
146
|
export { default as Stepper } from './Stepper';
|
|
137
147
|
export { default as StatefulButton } from './StatefulButton';
|
|
148
|
+
/** @deprecated Replaced by `Alert`. */
|
|
138
149
|
export { default as StatusAlert } from './StatusAlert';
|
|
150
|
+
/** @deprecated Replaced by `DataTable`. */
|
|
139
151
|
export { default as Table } from './Table';
|
|
140
152
|
export {
|
|
141
153
|
default as Tabs,
|
|
@@ -144,8 +156,10 @@ export {
|
|
|
144
156
|
TabContent,
|
|
145
157
|
TabPane,
|
|
146
158
|
} from './Tabs';
|
|
159
|
+
/** @deprecated Replaced by `Form.Control`. */
|
|
147
160
|
export { default as TextArea } from './TextArea';
|
|
148
161
|
export { default as Toast, TOAST_CLOSE_LABEL_TEXT, TOAST_DELAY } from './Toast';
|
|
162
|
+
/** @deprecated Replaced by `Form.Group`. */
|
|
149
163
|
export { default as ValidationFormGroup } from './ValidationFormGroup';
|
|
150
164
|
export { default as TransitionReplace } from './TransitionReplace';
|
|
151
165
|
export { default as ValidationMessage } from './ValidationMessage';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openedx/paragon",
|
|
3
|
-
"version": "22.
|
|
3
|
+
"version": "22.9.0",
|
|
4
4
|
"description": "Accessible, responsive UI component library based on Bootstrap.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
"@babel/preset-env": "^7.16.8",
|
|
96
96
|
"@babel/preset-react": "^7.16.7",
|
|
97
97
|
"@babel/preset-typescript": "^7.16.7",
|
|
98
|
-
"@edx/eslint-config": "^
|
|
98
|
+
"@edx/eslint-config": "^4.2.0",
|
|
99
99
|
"@edx/stylelint-config-edx": "^2.3.0",
|
|
100
100
|
"@edx/typescript-config": "^1.0.1",
|
|
101
101
|
"@formatjs/cli": "^5.0.2",
|
|
@@ -8,6 +8,13 @@ import DataTableContext from '../../DataTableContext';
|
|
|
8
8
|
import * as selectActions from '../data/actions';
|
|
9
9
|
import { getRowIds } from '../data/helpers';
|
|
10
10
|
|
|
11
|
+
function DataTableContextChild() {
|
|
12
|
+
const contextValue = useContext(DataTableContext);
|
|
13
|
+
return (
|
|
14
|
+
<div className="context-value" data-contextvalue={contextValue} />
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
11
18
|
// eslint-disable-next-line react/prop-types
|
|
12
19
|
function ControlledSelectHeaderWrapper({ tableProps, selectProps, ...rest }) {
|
|
13
20
|
return (
|
|
@@ -18,13 +25,6 @@ function ControlledSelectHeaderWrapper({ tableProps, selectProps, ...rest }) {
|
|
|
18
25
|
);
|
|
19
26
|
}
|
|
20
27
|
|
|
21
|
-
function DataTableContextChild() {
|
|
22
|
-
const contextValue = useContext(DataTableContext);
|
|
23
|
-
return (
|
|
24
|
-
<div className="context-value" data-contextvalue={contextValue} />
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
28
|
const mockToggleAllPageRowsSelectedProps = jest.fn();
|
|
29
29
|
const rows = [{ id: 1 }, { id: 2 }];
|
|
30
30
|
const tableProps = {
|
|
@@ -1,14 +1,29 @@
|
|
|
1
1
|
import React, { useMemo } from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
interface ContextData {
|
|
4
|
+
onClose: () => void;
|
|
5
|
+
isOpen: boolean;
|
|
6
|
+
isBlocking: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const ModalContext = React.createContext<ContextData>({
|
|
5
10
|
onClose: () => {},
|
|
11
|
+
isOpen: false,
|
|
12
|
+
isBlocking: false,
|
|
6
13
|
});
|
|
7
14
|
|
|
8
15
|
function ModalContextProvider({
|
|
9
|
-
onClose,
|
|
16
|
+
onClose,
|
|
17
|
+
isOpen,
|
|
18
|
+
isBlocking = false,
|
|
19
|
+
children = null,
|
|
20
|
+
}: {
|
|
21
|
+
onClose: () => void;
|
|
22
|
+
isOpen: boolean;
|
|
23
|
+
isBlocking?: boolean;
|
|
24
|
+
children?: React.ReactNode;
|
|
10
25
|
}) {
|
|
11
|
-
const modalContextValue = useMemo(
|
|
26
|
+
const modalContextValue = useMemo<ContextData>(
|
|
12
27
|
() => ({ onClose, isOpen, isBlocking }),
|
|
13
28
|
[onClose, isOpen, isBlocking],
|
|
14
29
|
);
|
|
@@ -20,17 +35,5 @@ function ModalContextProvider({
|
|
|
20
35
|
);
|
|
21
36
|
}
|
|
22
37
|
|
|
23
|
-
ModalContextProvider.propTypes = {
|
|
24
|
-
children: PropTypes.node,
|
|
25
|
-
onClose: PropTypes.func.isRequired,
|
|
26
|
-
isBlocking: PropTypes.bool,
|
|
27
|
-
isOpen: PropTypes.bool.isRequired,
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
ModalContextProvider.defaultProps = {
|
|
31
|
-
children: null,
|
|
32
|
-
isBlocking: false,
|
|
33
|
-
};
|
|
34
|
-
|
|
35
38
|
export { ModalContextProvider };
|
|
36
39
|
export default ModalContext;
|
|
@@ -3,11 +3,16 @@ import PropTypes from 'prop-types';
|
|
|
3
3
|
import classNames from 'classnames';
|
|
4
4
|
import { useMediaQuery } from 'react-responsive';
|
|
5
5
|
import ModalLayer from './ModalLayer';
|
|
6
|
+
// @ts-ignore for now - this needs to be converted to TypeScript
|
|
6
7
|
import ModalCloseButton from './ModalCloseButton';
|
|
7
8
|
import ModalDialogHeader from './ModalDialogHeader';
|
|
9
|
+
// @ts-ignore for now - this needs to be converted to TypeScript
|
|
8
10
|
import ModalDialogTitle from './ModalDialogTitle';
|
|
11
|
+
// @ts-ignore for now - this needs to be converted to TypeScript
|
|
9
12
|
import ModalDialogFooter from './ModalDialogFooter';
|
|
13
|
+
// @ts-ignore for now - this needs to be converted to TypeScript
|
|
10
14
|
import ModalDialogBody from './ModalDialogBody';
|
|
15
|
+
// @ts-ignore for now - this needs to be converted to TypeScript
|
|
11
16
|
import ModalDialogHero from './ModalDialogHero';
|
|
12
17
|
|
|
13
18
|
import Icon from '../Icon';
|
|
@@ -16,22 +21,57 @@ import { Close } from '../../icons';
|
|
|
16
21
|
|
|
17
22
|
export const MODAL_DIALOG_CLOSE_LABEL = 'Close';
|
|
18
23
|
|
|
24
|
+
interface Props {
|
|
25
|
+
/** Specifies the content of the dialog */
|
|
26
|
+
children: React.ReactNode;
|
|
27
|
+
/** The aria-label of the dialog */
|
|
28
|
+
title: string;
|
|
29
|
+
/** A callback to close the modal dialog, e.g. when Escape is pressed */
|
|
30
|
+
onClose: () => void;
|
|
31
|
+
/** Is the modal dialog open or closed? */
|
|
32
|
+
isOpen?: boolean;
|
|
33
|
+
/** The close 'x' icon button in the top right of the dialog box */
|
|
34
|
+
hasCloseButton?: boolean;
|
|
35
|
+
/** Size determines the maximum width of the dialog box */
|
|
36
|
+
size?: 'sm' | 'md' | 'lg' | 'xl' | 'fullscreen';
|
|
37
|
+
/** The visual style of the dialog box */
|
|
38
|
+
variant?: 'default' | 'warning' | 'danger' | 'success' | 'dark';
|
|
39
|
+
/** The label supplied to the close icon button if one is rendered */
|
|
40
|
+
closeLabel?: string;
|
|
41
|
+
/** Specifies class name to append to the base element */
|
|
42
|
+
className?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Determines where a scrollbar should appear if a modal is too large for the
|
|
45
|
+
* viewport. When false, the ``ModalDialog``. Body receives a scrollbar, when true
|
|
46
|
+
* the browser window itself receives the scrollbar.
|
|
47
|
+
*/
|
|
48
|
+
isFullscreenScroll?: boolean;
|
|
49
|
+
/** To show full screen view on mobile screens */
|
|
50
|
+
isFullscreenOnMobile?: boolean;
|
|
51
|
+
/** Prevent clicking on the backdrop or pressing Esc to close the modal */
|
|
52
|
+
isBlocking?: boolean;
|
|
53
|
+
/** Specifies the z-index of the modal */
|
|
54
|
+
zIndex?: number;
|
|
55
|
+
/** Specifies whether overflow is visible in the modal */
|
|
56
|
+
isOverflowVisible?: boolean;
|
|
57
|
+
}
|
|
58
|
+
|
|
19
59
|
function ModalDialog({
|
|
20
60
|
children,
|
|
21
61
|
title,
|
|
22
|
-
isOpen,
|
|
62
|
+
isOpen = false,
|
|
23
63
|
onClose,
|
|
24
|
-
size,
|
|
25
|
-
variant,
|
|
26
|
-
hasCloseButton,
|
|
27
|
-
closeLabel,
|
|
28
|
-
isFullscreenScroll,
|
|
64
|
+
size = 'md',
|
|
65
|
+
variant = 'default',
|
|
66
|
+
hasCloseButton = true,
|
|
67
|
+
closeLabel = MODAL_DIALOG_CLOSE_LABEL,
|
|
68
|
+
isFullscreenScroll = false,
|
|
29
69
|
className,
|
|
30
|
-
isFullscreenOnMobile,
|
|
31
|
-
isBlocking,
|
|
70
|
+
isFullscreenOnMobile = false,
|
|
71
|
+
isBlocking = false,
|
|
32
72
|
zIndex,
|
|
33
|
-
isOverflowVisible,
|
|
34
|
-
}) {
|
|
73
|
+
isOverflowVisible = true,
|
|
74
|
+
}: Props) {
|
|
35
75
|
const isMobile = useMediaQuery({ query: '(max-width: 767.98px)' });
|
|
36
76
|
const showFullScreen = (isFullscreenOnMobile && isMobile);
|
|
37
77
|
return (
|
|
@@ -126,20 +166,6 @@ ModalDialog.propTypes = {
|
|
|
126
166
|
isOverflowVisible: PropTypes.bool,
|
|
127
167
|
};
|
|
128
168
|
|
|
129
|
-
ModalDialog.defaultProps = {
|
|
130
|
-
isOpen: false,
|
|
131
|
-
hasCloseButton: true,
|
|
132
|
-
size: 'md',
|
|
133
|
-
variant: 'default',
|
|
134
|
-
closeLabel: MODAL_DIALOG_CLOSE_LABEL,
|
|
135
|
-
className: undefined,
|
|
136
|
-
isFullscreenScroll: false,
|
|
137
|
-
isFullscreenOnMobile: false,
|
|
138
|
-
isBlocking: false,
|
|
139
|
-
zIndex: undefined,
|
|
140
|
-
isOverflowVisible: true,
|
|
141
|
-
};
|
|
142
|
-
|
|
143
169
|
ModalDialog.Header = ModalDialogHeader;
|
|
144
170
|
ModalDialog.Title = ModalDialogTitle;
|
|
145
171
|
ModalDialog.Footer = ModalDialogFooter;
|
|
@@ -1,21 +1,32 @@
|
|
|
1
|
+
/* eslint-disable react/require-default-props */
|
|
1
2
|
import React from 'react';
|
|
2
3
|
import PropTypes from 'prop-types';
|
|
3
4
|
import classNames from 'classnames';
|
|
5
|
+
import type { ComponentWithAsProp } from '../utils/types/bootstrap';
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
as
|
|
7
|
+
export interface Props {
|
|
8
|
+
as?: string;
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type HeaderType = ComponentWithAsProp<'div', Props>;
|
|
14
|
+
|
|
15
|
+
const ModalDialogHeader: HeaderType = React.forwardRef<HTMLDivElement, Props>(({
|
|
16
|
+
as = 'div',
|
|
7
17
|
children,
|
|
8
18
|
...props
|
|
9
|
-
})
|
|
10
|
-
|
|
19
|
+
}, ref) => (
|
|
20
|
+
React.createElement(
|
|
11
21
|
as,
|
|
12
22
|
{
|
|
13
23
|
...props,
|
|
24
|
+
ref,
|
|
14
25
|
className: classNames('pgn__modal-header', props.className),
|
|
15
26
|
},
|
|
16
27
|
children,
|
|
17
|
-
)
|
|
18
|
-
|
|
28
|
+
)
|
|
29
|
+
));
|
|
19
30
|
|
|
20
31
|
ModalDialogHeader.propTypes = {
|
|
21
32
|
/** Specifies the base element */
|
|
@@ -26,9 +37,4 @@ ModalDialogHeader.propTypes = {
|
|
|
26
37
|
className: PropTypes.string,
|
|
27
38
|
};
|
|
28
39
|
|
|
29
|
-
ModalDialogHeader.defaultProps = {
|
|
30
|
-
as: 'div',
|
|
31
|
-
className: undefined,
|
|
32
|
-
};
|
|
33
|
-
|
|
34
40
|
export default ModalDialogHeader;
|
|
@@ -6,7 +6,7 @@ import Portal from './Portal';
|
|
|
6
6
|
import { ModalContextProvider } from './ModalContext';
|
|
7
7
|
|
|
8
8
|
// istanbul ignore next
|
|
9
|
-
function ModalBackdrop({ onClick }) {
|
|
9
|
+
function ModalBackdrop({ onClick }: { onClick?: () => void }) {
|
|
10
10
|
return (
|
|
11
11
|
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
|
|
12
12
|
<div
|
|
@@ -22,12 +22,8 @@ ModalBackdrop.propTypes = {
|
|
|
22
22
|
onClick: PropTypes.func,
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
ModalBackdrop.defaultProps = {
|
|
26
|
-
onClick: undefined,
|
|
27
|
-
};
|
|
28
|
-
|
|
29
25
|
// istanbul ignore next
|
|
30
|
-
function ModalContentContainer({ children }) {
|
|
26
|
+
function ModalContentContainer({ children = null }: { children?: React.ReactNode }) {
|
|
31
27
|
return <div className="pgn__modal-content-container">{children}</div>;
|
|
32
28
|
}
|
|
33
29
|
|
|
@@ -35,9 +31,18 @@ ModalContentContainer.propTypes = {
|
|
|
35
31
|
children: PropTypes.node,
|
|
36
32
|
};
|
|
37
33
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
34
|
+
interface Props {
|
|
35
|
+
/** Specifies the contents of the modal */
|
|
36
|
+
children: React.ReactNode;
|
|
37
|
+
/** A callback function for when the modal is dismissed */
|
|
38
|
+
onClose: () => void;
|
|
39
|
+
/** Is the modal dialog open or closed */
|
|
40
|
+
isOpen: boolean;
|
|
41
|
+
/** Prevent clicking on the backdrop or pressing Esc to close the modal */
|
|
42
|
+
isBlocking?: boolean;
|
|
43
|
+
/** Specifies the z-index of the modal */
|
|
44
|
+
zIndex?: number;
|
|
45
|
+
}
|
|
41
46
|
|
|
42
47
|
/**
|
|
43
48
|
* The ModalLayer should be used for any component that wishes to engage the user
|
|
@@ -46,8 +51,8 @@ ModalContentContainer.defaultProps = {
|
|
|
46
51
|
* component is that if a modal object is visible then it is "enabled"
|
|
47
52
|
*/
|
|
48
53
|
function ModalLayer({
|
|
49
|
-
children, onClose, isOpen, isBlocking, zIndex,
|
|
50
|
-
}) {
|
|
54
|
+
children, onClose, isOpen, isBlocking = false, zIndex,
|
|
55
|
+
}: Props) {
|
|
51
56
|
useEffect(() => {
|
|
52
57
|
if (isOpen) {
|
|
53
58
|
document.body.classList.add('pgn__hidden-scroll-padding-right');
|
|
@@ -63,7 +68,7 @@ function ModalLayer({
|
|
|
63
68
|
return null;
|
|
64
69
|
}
|
|
65
70
|
|
|
66
|
-
const handleClose = isBlocking ?
|
|
71
|
+
const handleClose = isBlocking ? undefined : onClose;
|
|
67
72
|
|
|
68
73
|
return (
|
|
69
74
|
<ModalContextProvider onClose={onClose} isOpen={isOpen} isBlocking={isBlocking}>
|
|
@@ -102,10 +107,5 @@ ModalLayer.propTypes = {
|
|
|
102
107
|
zIndex: PropTypes.number,
|
|
103
108
|
};
|
|
104
109
|
|
|
105
|
-
ModalLayer.defaultProps = {
|
|
106
|
-
isBlocking: false,
|
|
107
|
-
zIndex: undefined,
|
|
108
|
-
};
|
|
109
|
-
|
|
110
110
|
export { ModalBackdrop, ModalContentContainer };
|
|
111
111
|
export default ModalLayer;
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import ReactDOM from 'react-dom';
|
|
3
|
-
import PropTypes from 'prop-types';
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
interface Props {
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
class Portal extends React.Component<Props> {
|
|
9
|
+
private rootName: string;
|
|
10
|
+
|
|
11
|
+
private rootElement: HTMLElement | null;
|
|
12
|
+
|
|
13
|
+
constructor(props: Props) {
|
|
7
14
|
super(props);
|
|
8
15
|
this.rootName = 'paragon-portal-root';
|
|
9
16
|
// istanbul ignore if
|
|
@@ -31,8 +38,4 @@ class Portal extends React.Component {
|
|
|
31
38
|
}
|
|
32
39
|
}
|
|
33
40
|
|
|
34
|
-
Portal.propTypes = {
|
|
35
|
-
children: PropTypes.node.isRequired,
|
|
36
|
-
};
|
|
37
|
-
|
|
38
41
|
export default Portal;
|
|
@@ -3,16 +3,6 @@ import { render, screen } from '@testing-library/react';
|
|
|
3
3
|
|
|
4
4
|
import ModalDialog from '../ModalDialog';
|
|
5
5
|
|
|
6
|
-
jest.mock('../ModalLayer', () => function ModalLayerMock(props) {
|
|
7
|
-
// eslint-disable-next-line react/prop-types
|
|
8
|
-
const { children, ...otherProps } = props;
|
|
9
|
-
return (
|
|
10
|
-
<modal-layer {...otherProps}>
|
|
11
|
-
{children}
|
|
12
|
-
</modal-layer>
|
|
13
|
-
);
|
|
14
|
-
});
|
|
15
|
-
|
|
16
6
|
describe('ModalDialog', () => {
|
|
17
7
|
it('renders a dialog with aria-label and content', () => {
|
|
18
8
|
const onClose = jest.fn();
|
|
@@ -45,6 +35,22 @@ describe('ModalDialog', () => {
|
|
|
45
35
|
expect(dialogNode).toHaveAttribute('aria-label', 'My dialog');
|
|
46
36
|
expect(screen.getByText('The content')).toBeInTheDocument();
|
|
47
37
|
});
|
|
38
|
+
|
|
39
|
+
it('is hidden by default', () => {
|
|
40
|
+
const onClose = jest.fn();
|
|
41
|
+
render(
|
|
42
|
+
<ModalDialog
|
|
43
|
+
title="My dialog"
|
|
44
|
+
onClose={onClose}
|
|
45
|
+
>
|
|
46
|
+
<ModalDialog.Header><ModalDialog.Title>The title</ModalDialog.Title></ModalDialog.Header>
|
|
47
|
+
<ModalDialog.Body><p>The hidden content</p></ModalDialog.Body>
|
|
48
|
+
<ModalDialog.Footer><ModalDialog.CloseButton>Cancel</ModalDialog.CloseButton></ModalDialog.Footer>
|
|
49
|
+
</ModalDialog>,
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
|
53
|
+
});
|
|
48
54
|
});
|
|
49
55
|
|
|
50
56
|
describe('ModalDialog with Hero', () => {
|
|
@@ -6,12 +6,11 @@ import userEvent from '@testing-library/user-event';
|
|
|
6
6
|
import ModalLayer from '../ModalLayer';
|
|
7
7
|
|
|
8
8
|
/* eslint-disable react/prop-types */
|
|
9
|
-
jest.mock('../Portal', () => function PortalMock(props) {
|
|
9
|
+
jest.mock('../Portal', () => function PortalMock(props: any) {
|
|
10
10
|
const { children, ...otherProps } = props;
|
|
11
11
|
return (
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
</paragon-portal>
|
|
12
|
+
// @ts-ignore this fake element. (Property 'paragon-portal' does not exist on type 'JSX.IntrinsicElements')
|
|
13
|
+
<paragon-portal {...otherProps}>{children}</paragon-portal>
|
|
15
14
|
);
|
|
16
15
|
});
|
|
17
16
|
|
|
@@ -19,6 +18,7 @@ jest.mock('react-focus-on', () => ({
|
|
|
19
18
|
FocusOn: jest.fn().mockImplementation((props) => {
|
|
20
19
|
const { children, ...otherProps } = props;
|
|
21
20
|
return (
|
|
21
|
+
// @ts-ignore this fake element. (Property 'focus-on' does not exist on type 'JSX.IntrinsicElements')
|
|
22
22
|
<focus-on data-testid="focus-on" {...otherProps}>{children}</focus-on>
|
|
23
23
|
);
|
|
24
24
|
}),
|
|
@@ -117,7 +117,7 @@ describe('<ModalLayer />', () => {
|
|
|
117
117
|
);
|
|
118
118
|
expect(FocusOn).toHaveBeenCalledWith(
|
|
119
119
|
expect.objectContaining({
|
|
120
|
-
onEscapeKey:
|
|
120
|
+
onEscapeKey: undefined,
|
|
121
121
|
}),
|
|
122
122
|
// note: this 2nd function argument represents the
|
|
123
123
|
// `refOrContext` (in this case, the context value
|