@openedx/paragon 23.0.0-alpha.4 → 23.0.0-alpha.6
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/Card/BaseCard.d.ts +18 -0
- package/dist/Card/BaseCard.js +53 -0
- package/dist/Card/BaseCard.js.map +1 -0
- package/dist/Card/index.js +1 -1
- package/dist/Card/index.js.map +1 -1
- package/dist/Card/index.scss +2 -0
- package/dist/Container/index.d.ts +16 -0
- package/dist/Container/index.js +15 -13
- package/dist/Container/index.js.map +1 -1
- package/dist/IconButton/index.js +1 -1
- package/dist/IconButton/index.js.map +1 -1
- package/dist/Menu/SelectMenu.js +9 -4
- package/dist/Menu/SelectMenu.js.map +1 -1
- 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 +110 -0
- package/dist/Modal/ModalDialog.js +23 -21
- 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/core.css +2 -0
- package/dist/core.css.map +1 -1
- package/dist/core.min.css +1 -1
- package/dist/hooks/useArrowKeyNavigation.js +2 -3
- package/dist/hooks/useArrowKeyNavigation.js.map +1 -1
- package/dist/index.d.ts +19 -5
- package/dist/index.js +5 -5
- package/icons/es5/Newsstand.js +15 -0
- package/icons/es5/index.js +1 -0
- package/icons/es5/index.ts +1 -0
- package/icons/jsx/Newsstand.jsx +17 -0
- package/icons/jsx/index.jsx +1 -0
- package/icons/svg/newsstand.svg +1 -0
- package/package.json +2 -2
- package/src/Card/BaseCard.tsx +92 -0
- package/src/Card/README.md +0 -2
- package/src/Card/index.jsx +1 -1
- package/src/Card/index.scss +2 -0
- package/src/Card/tests/BaseCard.test.jsx +82 -0
- package/src/Container/{Container.test.jsx → Container.test.tsx} +14 -8
- package/src/Container/README.md +4 -0
- package/src/Container/index.tsx +64 -0
- package/src/DataTable/selection/tests/ControlledSelectHeader.test.jsx +7 -7
- package/src/IconButton/index.tsx +1 -1
- package/src/Menu/SelectMenu.jsx +5 -0
- package/src/Menu/SelectMenu.test.jsx +6 -0
- package/src/Menu/select-menu.md +8 -0
- package/src/Modal/{ModalContext.jsx → ModalContext.tsx} +19 -16
- package/src/Modal/{ModalDialog.jsx → ModalDialog.tsx} +50 -23
- 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 +19 -5
- package/src/index.js +5 -5
- package/src/Container/index.jsx +0 -49
- /package/src/Truncate/{Truncate.test.js → utils.test.js} +0 -0
package/src/IconButton/index.tsx
CHANGED
|
@@ -2,9 +2,9 @@ import React from 'react';
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import classNames from 'classnames';
|
|
4
4
|
import { type Placement } from 'react-bootstrap/Overlay';
|
|
5
|
-
import Icon from '../Icon';
|
|
6
5
|
import { OverlayTrigger } from '../Overlay';
|
|
7
6
|
import Tooltip from '../Tooltip';
|
|
7
|
+
import Icon from '../Icon';
|
|
8
8
|
|
|
9
9
|
interface Props extends React.HTMLAttributes<HTMLButtonElement> {
|
|
10
10
|
iconAs?: React.ComponentType<any>,
|
package/src/Menu/SelectMenu.jsx
CHANGED
|
@@ -15,6 +15,7 @@ function SelectMenu({
|
|
|
15
15
|
children,
|
|
16
16
|
className,
|
|
17
17
|
variant,
|
|
18
|
+
disabled,
|
|
18
19
|
...props
|
|
19
20
|
}) {
|
|
20
21
|
const [triggerTarget, setTriggerTarget] = useState(null);
|
|
@@ -89,6 +90,7 @@ function SelectMenu({
|
|
|
89
90
|
variant={variant}
|
|
90
91
|
iconAfter={ExpandMore}
|
|
91
92
|
onClick={open}
|
|
93
|
+
disabled={disabled}
|
|
92
94
|
>
|
|
93
95
|
{selected !== undefined && children[selected] ? children[selected].props.children : defaultMessage}
|
|
94
96
|
</Button>
|
|
@@ -131,12 +133,15 @@ SelectMenu.propTypes = {
|
|
|
131
133
|
className: PropTypes.string,
|
|
132
134
|
/** Specifies variant to use. */
|
|
133
135
|
variant: PropTypes.string,
|
|
136
|
+
/** Specifies if the `SelectMenu` is disabled. */
|
|
137
|
+
disabled: PropTypes.bool,
|
|
134
138
|
};
|
|
135
139
|
|
|
136
140
|
SelectMenu.defaultProps = {
|
|
137
141
|
defaultMessage: SELECT_MENU_DEFAULT_MESSAGE,
|
|
138
142
|
className: undefined,
|
|
139
143
|
variant: 'outline-primary',
|
|
144
|
+
disabled: false,
|
|
140
145
|
};
|
|
141
146
|
|
|
142
147
|
const SelectMenuWithDeprecatedProp = withDeprecatedProps(SelectMenu, 'SelectMenu', {
|
|
@@ -58,6 +58,12 @@ describe('correct rendering', () => {
|
|
|
58
58
|
const button = screen.getByRole('button');
|
|
59
59
|
expect(button).toHaveClass('btn-brand');
|
|
60
60
|
});
|
|
61
|
+
|
|
62
|
+
it('renders as disabled', () => {
|
|
63
|
+
render(DefaultSelectMenu({ disabled: true }));
|
|
64
|
+
const button = screen.getByRole('button');
|
|
65
|
+
expect(button).toBeDisabled();
|
|
66
|
+
});
|
|
61
67
|
});
|
|
62
68
|
|
|
63
69
|
describe('mouse behavior & keyboard behavior', () => {
|
package/src/Menu/select-menu.md
CHANGED
|
@@ -56,3 +56,11 @@ The ``Modal`` brings focus to the first menu element upon the click of the trigg
|
|
|
56
56
|
<MenuItem>M. Hortens</MenuItem>
|
|
57
57
|
</SelectMenu>
|
|
58
58
|
```
|
|
59
|
+
|
|
60
|
+
## Disabled
|
|
61
|
+
|
|
62
|
+
```jsx live
|
|
63
|
+
<SelectMenu disabled>
|
|
64
|
+
<MenuItem>A Menu Item</MenuItem>
|
|
65
|
+
</SelectMenu>
|
|
66
|
+
```
|
|
@@ -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 (
|
|
@@ -131,19 +171,6 @@ ModalDialog.propTypes = {
|
|
|
131
171
|
isOverflowVisible: PropTypes.bool.isRequired,
|
|
132
172
|
};
|
|
133
173
|
|
|
134
|
-
ModalDialog.defaultProps = {
|
|
135
|
-
isOpen: false,
|
|
136
|
-
hasCloseButton: true,
|
|
137
|
-
size: 'md',
|
|
138
|
-
variant: 'default',
|
|
139
|
-
closeLabel: MODAL_DIALOG_CLOSE_LABEL,
|
|
140
|
-
className: undefined,
|
|
141
|
-
isFullscreenScroll: false,
|
|
142
|
-
isFullscreenOnMobile: false,
|
|
143
|
-
isBlocking: false,
|
|
144
|
-
zIndex: undefined,
|
|
145
|
-
};
|
|
146
|
-
|
|
147
174
|
ModalDialog.Header = ModalDialogHeader;
|
|
148
175
|
ModalDialog.Title = ModalDialogTitle;
|
|
149
176
|
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();
|
|
@@ -46,6 +36,22 @@ describe('ModalDialog', () => {
|
|
|
46
36
|
expect(dialogNode).toHaveAttribute('aria-label', 'My dialog');
|
|
47
37
|
expect(screen.getByText('The content')).toBeInTheDocument();
|
|
48
38
|
});
|
|
39
|
+
|
|
40
|
+
it('is hidden by default', () => {
|
|
41
|
+
const onClose = jest.fn();
|
|
42
|
+
render(
|
|
43
|
+
<ModalDialog
|
|
44
|
+
title="My dialog"
|
|
45
|
+
onClose={onClose}
|
|
46
|
+
>
|
|
47
|
+
<ModalDialog.Header><ModalDialog.Title>The title</ModalDialog.Title></ModalDialog.Header>
|
|
48
|
+
<ModalDialog.Body><p>The hidden content</p></ModalDialog.Body>
|
|
49
|
+
<ModalDialog.Footer><ModalDialog.CloseButton>Cancel</ModalDialog.CloseButton></ModalDialog.Footer>
|
|
50
|
+
</ModalDialog>,
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
|
54
|
+
});
|
|
49
55
|
});
|
|
50
56
|
|
|
51
57
|
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
|
|
@@ -21,7 +21,7 @@ describe('<Portal />', () => {
|
|
|
21
21
|
|
|
22
22
|
const portalRoot = getPortalRoot();
|
|
23
23
|
expect(portalRoot).not.toBeNull();
|
|
24
|
-
expect(portalRoot
|
|
24
|
+
expect(portalRoot!.children[0].id).toBe('portal-content-a');
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
it('renders both contents in a single #paragon-portal-root div', () => {
|
|
@@ -38,7 +38,7 @@ describe('<Portal />', () => {
|
|
|
38
38
|
|
|
39
39
|
const portalRoot = getPortalRoot();
|
|
40
40
|
expect(portalRoot).not.toBeNull();
|
|
41
|
-
expect(portalRoot
|
|
42
|
-
expect(portalRoot
|
|
41
|
+
expect(portalRoot!.children[0].id).toBe('portal-content-a');
|
|
42
|
+
expect(portalRoot!.children[1].id).toBe('portal-content-b');
|
|
43
43
|
});
|
|
44
44
|
});
|
|
@@ -32,8 +32,7 @@ function handleArrowKey({ event, currentIndex, availableElements }) {
|
|
|
32
32
|
[nextElement] = availableElements;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
nextElement && nextElement.focus();
|
|
35
|
+
nextElement?.focus();
|
|
37
36
|
event.preventDefault();
|
|
38
37
|
}
|
|
39
38
|
|
package/src/index.d.ts
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, ContainerSize } 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 const
|
|
|
38
43
|
export const
|
|
39
44
|
Carousel: any, CarouselItem: any, CAROUSEL_NEXT_LABEL_TEXT: any, CAROUSEL_PREV_LABEL_TEXT: any;
|
|
40
45
|
// from './Carousel';
|
|
46
|
+
/** @deprecated Replaced by `Form.Checkbox`. */
|
|
41
47
|
export const CheckBox: any; // from './CheckBox';
|
|
48
|
+
/** @deprecated Replaced by `Form.Checkbox` and `Form.CheckboxSet`. */
|
|
42
49
|
export const CheckBoxGroup: any; // from './CheckBoxGroup';
|
|
43
50
|
export const CloseButton: any; // from './CloseButton';
|
|
44
|
-
export const Container: any; // from './Container';
|
|
45
51
|
export const Layout: any, Col: any, Row: any; // from './Layout';
|
|
46
52
|
export const Collapse: any; // from './Collapse';
|
|
47
53
|
export const Collapsible: any; // from './Collapsible';
|
|
@@ -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/src/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
|
// // // // // // // // // // // // // // // // // // // // // // // // // // //
|
|
@@ -39,7 +44,6 @@ export {
|
|
|
39
44
|
default as Carousel, CarouselItem, CAROUSEL_NEXT_LABEL_TEXT, CAROUSEL_PREV_LABEL_TEXT,
|
|
40
45
|
} from './Carousel';
|
|
41
46
|
export { default as CloseButton } from './CloseButton';
|
|
42
|
-
export { default as Container } from './Container';
|
|
43
47
|
export { default as Layout, Col, Row } from './Layout';
|
|
44
48
|
export { default as Collapse } from './Collapse';
|
|
45
49
|
export { default as Collapsible } from './Collapsible';
|
|
@@ -85,11 +89,7 @@ export { default as FullscreenModal, FULLSCREEN_MODAL_CLOSE_LABEL } from './Moda
|
|
|
85
89
|
export { default as MarketingModal } from './Modal/MarketingModal';
|
|
86
90
|
export { default as StandardModal, STANDARD_MODAL_CLOSE_LABEL } from './Modal/StandardModal';
|
|
87
91
|
export { default as AlertModal } from './Modal/AlertModal';
|
|
88
|
-
export { default as ModalLayer } from './Modal/ModalLayer';
|
|
89
|
-
export { default as ModalDialog, MODAL_DIALOG_CLOSE_LABEL } from './Modal/ModalDialog';
|
|
90
92
|
export { default as ModalPopup } from './Modal/ModalPopup';
|
|
91
|
-
export { default as ModalContext } from './Modal/ModalContext';
|
|
92
|
-
export { default as Portal } from './Modal/Portal';
|
|
93
93
|
export { default as PopperElement } from './Modal/PopperElement';
|
|
94
94
|
|
|
95
95
|
export {
|
package/src/Container/index.jsx
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import React, { forwardRef } from 'react';
|
|
2
|
-
import classNames from 'classnames';
|
|
3
|
-
import RBContainer from 'react-bootstrap/Container';
|
|
4
|
-
import PropTypes from 'prop-types';
|
|
5
|
-
|
|
6
|
-
const SIZE_CLASS_NAMES = {
|
|
7
|
-
xs: 'container-mw-xs',
|
|
8
|
-
sm: 'container-mw-sm',
|
|
9
|
-
md: 'container-mw-md',
|
|
10
|
-
lg: 'container-mw-lg',
|
|
11
|
-
xl: 'container-mw-xl',
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
const Container = forwardRef(({ size, children, ...props }, ref) => (
|
|
15
|
-
<RBContainer
|
|
16
|
-
{...props}
|
|
17
|
-
ref={ref}
|
|
18
|
-
className={classNames(
|
|
19
|
-
props.className,
|
|
20
|
-
SIZE_CLASS_NAMES[size],
|
|
21
|
-
)}
|
|
22
|
-
>
|
|
23
|
-
{children}
|
|
24
|
-
</RBContainer>
|
|
25
|
-
));
|
|
26
|
-
|
|
27
|
-
Container.propTypes = {
|
|
28
|
-
...RBContainer.propTypes,
|
|
29
|
-
/** Override the base element */
|
|
30
|
-
as: PropTypes.elementType,
|
|
31
|
-
/** Specifies the contents of the container */
|
|
32
|
-
children: PropTypes.node,
|
|
33
|
-
/** Fill all available space at any breakpoint */
|
|
34
|
-
fluid: PropTypes.bool,
|
|
35
|
-
/** Set the maximum width for the container */
|
|
36
|
-
size: PropTypes.oneOf(Object.keys(SIZE_CLASS_NAMES)),
|
|
37
|
-
/** Overrides underlying component base CSS class name */
|
|
38
|
-
bsPrefix: PropTypes.string,
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
Container.defaultProps = {
|
|
42
|
-
as: 'div',
|
|
43
|
-
children: undefined,
|
|
44
|
-
fluid: true,
|
|
45
|
-
size: undefined,
|
|
46
|
-
bsPrefix: 'container',
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
export default Container;
|
|
File without changes
|