@openedx/paragon 23.14.8 → 23.15.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/Card/CardBody.d.ts +9 -0
- package/dist/Card/CardBody.js +0 -11
- package/dist/Card/CardBody.js.map +1 -1
- package/dist/Card/CardContext.d.ts +17 -0
- package/dist/Card/CardContext.js +8 -21
- package/dist/Card/CardContext.js.map +1 -1
- package/dist/Card/CardDivider.d.ts +7 -0
- package/dist/Card/CardDivider.js +2 -10
- package/dist/Card/CardDivider.js.map +1 -1
- package/dist/Card/CardFallbackDefaultImage.d.ts +1 -0
- package/dist/Card/CardFallbackDefaultImage.js +1 -0
- package/dist/Card/CardFallbackDefaultImage.js.map +1 -0
- package/dist/Card/CardGrid.d.ts +22 -0
- package/dist/Card/CardGrid.js +6 -31
- package/dist/Card/CardGrid.js.map +1 -1
- package/dist/Chip/constants.js +0 -1
- package/dist/Chip/constants.js.map +1 -1
- package/dist/Container/index.js +0 -1
- package/dist/Container/index.js.map +1 -1
- package/dist/DataTable/CollapsibleButtonGroup.js +0 -1
- package/dist/DataTable/CollapsibleButtonGroup.js.map +1 -1
- package/dist/DataTable/DataTableContext.d.ts +3 -0
- package/dist/DataTable/DataTableContext.js.map +1 -1
- package/dist/DataTable/TableCell.d.ts +14 -0
- package/dist/DataTable/TableCell.js +0 -12
- package/dist/DataTable/TableCell.js.map +1 -1
- package/dist/DataTable/TableHeaderCell.d.ts +26 -0
- package/dist/DataTable/TableHeaderCell.js +4 -32
- package/dist/DataTable/TableHeaderCell.js.map +1 -1
- package/dist/DataTable/filters/CheckboxFilter.js +1 -1
- package/dist/DataTable/filters/CheckboxFilter.js.map +1 -1
- package/dist/DataTable/index.js +7 -2
- package/dist/DataTable/index.js.map +1 -1
- package/dist/Dropdown/index.js +10 -18
- package/dist/Dropdown/index.js.map +1 -1
- package/dist/Menu/MenuItem.d.ts +17 -0
- package/dist/Menu/MenuItem.js +5 -27
- package/dist/Menu/MenuItem.js.map +1 -1
- package/dist/Menu/index.d.ts +16 -0
- package/dist/Menu/index.js +4 -24
- package/dist/Menu/index.js.map +1 -1
- package/dist/Modal/ModalDialogHeader.js +4 -1
- package/dist/Modal/ModalDialogHeader.js.map +1 -1
- package/dist/Modal/ModalLayer.js +7 -12
- package/dist/Modal/ModalLayer.js.map +1 -1
- package/dist/OverflowScroll/data/constants.d.ts +1 -0
- package/dist/OverflowScroll/data/constants.js +1 -2
- package/dist/OverflowScroll/data/constants.js.map +1 -0
- package/dist/PageBanner/index.d.ts +27 -0
- package/dist/PageBanner/index.js +5 -28
- package/dist/PageBanner/index.js.map +1 -1
- package/dist/ProductTour/index.js +5 -7
- package/dist/ProductTour/index.js.map +1 -1
- package/dist/ProgressBar/utils.js +0 -1
- package/dist/SelectableBox/utils.js +1 -1
- package/dist/Sheet/SheetContainer.js +30 -8
- package/dist/Sheet/SheetContainer.js.map +1 -1
- package/dist/Sheet/index.js +15 -5
- package/dist/Sheet/index.js.map +1 -1
- package/dist/Stack/index.d.ts +20 -0
- package/dist/Stack/index.js +3 -28
- package/dist/Stack/index.js.map +1 -1
- package/dist/Sticky/index.js +1 -2
- package/dist/Sticky/index.js.map +1 -1
- package/dist/Tabs/Tab.d.ts +19 -0
- package/dist/Tabs/Tab.js +0 -23
- package/dist/Tabs/Tab.js.map +1 -1
- package/dist/asInput/index.js +7 -14
- package/dist/asInput/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/setupTest.js.map +1 -1
- package/dist/utils/index.js +0 -1
- package/dist/utils/index.js.map +1 -1
- package/lib/version.js +1 -2
- package/package.json +3 -3
- package/src/Card/CardBody.tsx +19 -0
- package/src/Card/CardCarousel/tests/CardCarousel.test.jsx +0 -1
- package/src/Card/{CardContext.jsx → CardContext.tsx} +24 -25
- package/src/Card/CardDivider.tsx +13 -0
- package/src/Card/{CardGrid.jsx → CardGrid.tsx} +28 -35
- package/src/Chip/constants.ts +0 -1
- package/src/ChipCarousel/ChipCarousel.test.jsx +9 -11
- package/src/Container/index.tsx +0 -1
- package/src/DataTable/CollapsibleButtonGroup.jsx +0 -1
- package/src/DataTable/README.md +12 -12
- package/src/DataTable/{TableCell.jsx → TableCell.tsx} +13 -15
- package/src/DataTable/{TableHeaderCell.jsx → TableHeaderCell.tsx} +32 -33
- package/src/DataTable/filters/CheckboxFilter.jsx +1 -1
- package/src/DataTable/filters/tests/CheckboxFilter.test.jsx +31 -0
- package/src/DataTable/index.jsx +6 -2
- package/src/DataTable/selection/tests/utils.js +0 -1
- package/src/DataTable/tablecontrolbar.mdx +4 -4
- package/src/DataTable/tablefilters.mdx +8 -8
- package/src/DataTable/tests/DataTable.test.jsx +6 -4
- package/src/DataTable/tests/TableHeaderCell.test.jsx +0 -1
- package/src/DataTable/utils/tests/getTableArgs.test.js +3 -2
- package/src/DataTable/utils/tests/getVisibleColumns.test.js +0 -2
- package/src/Dropdown/index.jsx +11 -16
- package/src/Form/tests/useCheckboxSetValues.test.jsx +17 -9
- package/src/Menu/MenuItem.tsx +49 -0
- package/src/Menu/{index.jsx → index.tsx} +18 -27
- package/src/Modal/ModalDialogHeader.tsx +5 -1
- package/src/Modal/ModalLayer.tsx +1 -2
- package/src/Modal/tests/ModalLayer.test.tsx +1 -2
- package/src/OverflowScroll/data/{constants.js → constants.ts} +0 -2
- package/src/PageBanner/{index.jsx → index.tsx} +27 -29
- package/src/ProductTour/index.jsx +5 -7
- package/src/ProgressBar/utils.js +0 -1
- package/src/SelectableBox/tests/SelectableBox.test.jsx +0 -1
- package/src/SelectableBox/utils.js +1 -1
- package/src/Sheet/Sheet.test.jsx +63 -3
- package/src/Sheet/SheetContainer.jsx +34 -7
- package/src/Sheet/SheetContainer.test.jsx +34 -1
- package/src/Sheet/__snapshots__/Sheet.test.jsx.snap +15 -6
- package/src/Sheet/index.jsx +12 -2
- package/src/Stack/{index.jsx → index.tsx} +22 -35
- package/src/Sticky/index.jsx +1 -1
- package/src/Tabs/{Tab.jsx → Tab.tsx} +10 -18
- package/src/TransitionReplace/README.md +2 -2
- package/src/TransitionReplace/TransitionReplace.test.jsx +1 -1
- package/src/asInput/index.jsx +0 -3
- package/src/hooks/tests/useToggle.test.tsx +4 -5
- package/src/index.ts +1 -2
- package/src/setupTest.ts +0 -1
- package/src/utils/index.ts +0 -1
- package/src/Card/CardBody.jsx +0 -23
- package/src/Card/CardDivider.jsx +0 -18
- package/src/Menu/MenuItem.jsx +0 -57
- /package/src/Card/{CardFallbackDefaultImage.js → CardFallbackDefaultImage.ts} +0 -0
- /package/src/DataTable/{DataTableContext.jsx → DataTableContext.tsx} +0 -0
|
@@ -1,18 +1,30 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
1
|
+
import React, { ElementType, ReactNode, createElement } from 'react';
|
|
3
2
|
import classNames from 'classnames';
|
|
4
3
|
import useArrowKeyNavigation from '../hooks/useArrowKeyNavigationHook';
|
|
5
4
|
|
|
5
|
+
interface MenuProps {
|
|
6
|
+
/** Specifies class name to append to the base element */
|
|
7
|
+
className?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Specifies the CSS selector string that indicates to which elements
|
|
10
|
+
* the user can navigate using the arrow keys
|
|
11
|
+
*/
|
|
12
|
+
arrowKeyNavigationSelector?: string;
|
|
13
|
+
/** Specifies the base element */
|
|
14
|
+
as?: ElementType;
|
|
15
|
+
/** Specifies the content of the menu */
|
|
16
|
+
children?: ReactNode;
|
|
17
|
+
}
|
|
6
18
|
function Menu({
|
|
7
|
-
as,
|
|
8
|
-
arrowKeyNavigationSelector,
|
|
19
|
+
as = 'div',
|
|
20
|
+
arrowKeyNavigationSelector = 'a:not(:disabled),button:not(:disabled),input:not(:disabled)',
|
|
9
21
|
children,
|
|
10
22
|
...props
|
|
11
|
-
}) {
|
|
23
|
+
}: MenuProps) {
|
|
12
24
|
const parentRef = useArrowKeyNavigation({ selectors: arrowKeyNavigationSelector });
|
|
13
25
|
const className = classNames(props.className, 'pgn__menu');
|
|
14
26
|
|
|
15
|
-
return
|
|
27
|
+
return createElement(
|
|
16
28
|
as,
|
|
17
29
|
{
|
|
18
30
|
...props,
|
|
@@ -28,25 +40,4 @@ function Menu({
|
|
|
28
40
|
);
|
|
29
41
|
}
|
|
30
42
|
|
|
31
|
-
Menu.propTypes = {
|
|
32
|
-
/** Specifies class name to append to the base element */
|
|
33
|
-
className: PropTypes.string,
|
|
34
|
-
/**
|
|
35
|
-
* Specifies the CSS selector string that indicates to which elements
|
|
36
|
-
* the user can navigate using the arrow keys
|
|
37
|
-
*/
|
|
38
|
-
arrowKeyNavigationSelector: PropTypes.string,
|
|
39
|
-
/** Specifies the base element */
|
|
40
|
-
as: PropTypes.elementType,
|
|
41
|
-
/** Specifies the content of the menu */
|
|
42
|
-
children: PropTypes.node,
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
Menu.defaultProps = {
|
|
46
|
-
className: undefined,
|
|
47
|
-
arrowKeyNavigationSelector: 'a:not(:disabled),button:not(:disabled),input:not(:disabled)',
|
|
48
|
-
as: 'div',
|
|
49
|
-
children: null,
|
|
50
|
-
};
|
|
51
|
-
|
|
52
43
|
export default Menu;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable react/require-default-props */
|
|
2
1
|
import React from 'react';
|
|
3
2
|
import PropTypes from 'prop-types';
|
|
4
3
|
import classNames from 'classnames';
|
|
@@ -37,4 +36,9 @@ ModalDialogHeader.propTypes = {
|
|
|
37
36
|
className: PropTypes.string,
|
|
38
37
|
};
|
|
39
38
|
|
|
39
|
+
ModalDialogHeader.defaultProps = {
|
|
40
|
+
as: 'div',
|
|
41
|
+
className: '',
|
|
42
|
+
};
|
|
43
|
+
|
|
40
44
|
export default ModalDialogHeader;
|
package/src/Modal/ModalLayer.tsx
CHANGED
|
@@ -4,15 +4,14 @@ import { FocusOn } from 'react-focus-on';
|
|
|
4
4
|
import Portal from './Portal';
|
|
5
5
|
import { ModalContextProvider } from './ModalContext';
|
|
6
6
|
|
|
7
|
-
// istanbul ignore next
|
|
8
7
|
function ModalBackdrop({ onClick }: { onClick?: () => void }) {
|
|
9
8
|
return (
|
|
10
|
-
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
|
|
11
9
|
<div
|
|
12
10
|
className="pgn__modal-backdrop"
|
|
13
11
|
onClick={onClick}
|
|
14
12
|
onKeyDown={onClick}
|
|
15
13
|
data-testid="modal-backdrop"
|
|
14
|
+
role="presentation"
|
|
16
15
|
/>
|
|
17
16
|
);
|
|
18
17
|
}
|
|
@@ -5,7 +5,6 @@ import userEvent from '@testing-library/user-event';
|
|
|
5
5
|
|
|
6
6
|
import ModalLayer from '../ModalLayer';
|
|
7
7
|
|
|
8
|
-
/* eslint-disable react/prop-types */
|
|
9
8
|
jest.mock('../Portal', () => function PortalMock(props: any) {
|
|
10
9
|
const { children, ...otherProps } = props;
|
|
11
10
|
return (
|
|
@@ -66,7 +65,7 @@ describe('<ModalLayer />', () => {
|
|
|
66
65
|
});
|
|
67
66
|
});
|
|
68
67
|
|
|
69
|
-
|
|
68
|
+
it('when isOpen is false the dialog is not rendered', () => {
|
|
70
69
|
render(
|
|
71
70
|
<ModalLayer isOpen={false} onClose={jest.fn()}>
|
|
72
71
|
<Dialog />
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
3
2
|
import classNames from 'classnames';
|
|
4
3
|
import { Close } from '../../icons';
|
|
5
4
|
import Icon from '../Icon';
|
|
@@ -13,11 +12,34 @@ export const VARIANTS = {
|
|
|
13
12
|
warning: 'warning',
|
|
14
13
|
accentA: 'accentA',
|
|
15
14
|
accentB: 'accentB',
|
|
16
|
-
};
|
|
15
|
+
} as const;
|
|
16
|
+
|
|
17
|
+
interface PageBannerProps {
|
|
18
|
+
/** An element rendered inside the `Page Banner`. */
|
|
19
|
+
children: ReactNode;
|
|
20
|
+
/** Boolean used to control whether `Page Banner` is dismissible. */
|
|
21
|
+
dismissible: boolean;
|
|
22
|
+
/** An element to be set as the dismiss button's alt text (preferably a translated string). */
|
|
23
|
+
dismissAltText: string;
|
|
24
|
+
/** A function to be called on dismiss of the `Page Banner`. */
|
|
25
|
+
onDismiss: () => void;
|
|
26
|
+
/** Boolean used to control whether the Page Banner shows. */
|
|
27
|
+
show: boolean;
|
|
28
|
+
/** A string designating which color variant of the `Page Banner` to display.
|
|
29
|
+
* The full list of variants can be seen [here.](https://github.com/openedx/paragon/blob/release-23.x/src/PageBanner/index.tsx)
|
|
30
|
+
*/
|
|
31
|
+
variant: keyof typeof VARIANTS;
|
|
32
|
+
}
|
|
17
33
|
|
|
18
34
|
function PageBanner({
|
|
19
|
-
children,
|
|
20
|
-
|
|
35
|
+
children,
|
|
36
|
+
dismissible = false,
|
|
37
|
+
dismissAltText = PAGE_BANNER_DISMISS_ALT_TEXT,
|
|
38
|
+
onDismiss = () => {},
|
|
39
|
+
show = true,
|
|
40
|
+
variant = VARIANTS.accentA,
|
|
41
|
+
...rest
|
|
42
|
+
}: PageBannerProps) {
|
|
21
43
|
if (!show) {
|
|
22
44
|
return null;
|
|
23
45
|
}
|
|
@@ -52,28 +74,4 @@ function PageBanner({
|
|
|
52
74
|
);
|
|
53
75
|
}
|
|
54
76
|
|
|
55
|
-
PageBanner.propTypes = {
|
|
56
|
-
/** An element rendered inside the `Page Banner`. */
|
|
57
|
-
children: PropTypes.node,
|
|
58
|
-
/** Boolean used to control whether `Page Banner` is dismissible. */
|
|
59
|
-
dismissible: PropTypes.bool,
|
|
60
|
-
/** An element to be set as the dismiss button's alt text (preferably a translated string). */
|
|
61
|
-
dismissAltText: PropTypes.node,
|
|
62
|
-
/** A function to be called on dismiss of the `Page Banner`. */
|
|
63
|
-
onDismiss: PropTypes.func,
|
|
64
|
-
/** Boolean used to control whether the Page Banner shows. */
|
|
65
|
-
show: PropTypes.bool,
|
|
66
|
-
/** A string designating which color variant of the `Page Banner` to display */
|
|
67
|
-
variant: PropTypes.oneOf([VARIANTS.light, VARIANTS.dark, VARIANTS.warning, VARIANTS.accentA, VARIANTS.accentB]),
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
PageBanner.defaultProps = {
|
|
71
|
-
children: undefined,
|
|
72
|
-
dismissible: false,
|
|
73
|
-
dismissAltText: PAGE_BANNER_DISMISS_ALT_TEXT,
|
|
74
|
-
onDismiss: () => {},
|
|
75
|
-
show: true,
|
|
76
|
-
variant: VARIANTS.accentA,
|
|
77
|
-
};
|
|
78
|
-
|
|
79
77
|
export default PageBanner;
|
|
@@ -111,16 +111,14 @@ const ProductTour = React.forwardRef(({ tours }, ref) => {
|
|
|
111
111
|
}
|
|
112
112
|
setCurrentCheckpointData(null);
|
|
113
113
|
};
|
|
114
|
-
/* eslint-disable */
|
|
115
114
|
/**
|
|
116
115
|
* Takes the final checkpoint array index value and looks for an existing onEnd callback.
|
|
117
|
-
*
|
|
118
|
-
* If an onEnd callback exist on checkpointIndex value and it is the final checkpoint
|
|
119
|
-
* in the array, the onEnd callback will be called for the parent, and individual onEnd object.
|
|
120
|
-
*
|
|
121
|
-
* @param {Integer} checkpointIndex
|
|
116
|
+
*
|
|
117
|
+
* If an onEnd callback exist on checkpointIndex value and it is the final checkpoint
|
|
118
|
+
* in the array, the onEnd callback will be called for the parent, and individual onEnd object.
|
|
119
|
+
*
|
|
120
|
+
* @param {Integer} checkpointIndex
|
|
122
121
|
*/
|
|
123
|
-
/* eslint-enable */
|
|
124
122
|
const handleEnd = (checkpointIndex) => {
|
|
125
123
|
setIndex(0);
|
|
126
124
|
setIsTourEnabled(false);
|
package/src/ProgressBar/utils.js
CHANGED
|
@@ -25,7 +25,6 @@ export const placeInfoAtZero = (
|
|
|
25
25
|
horizontalMargin += annotationOnly ? 0.0 : elementParams.width;
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
-
// eslint-disable-next-line no-param-reassign
|
|
29
28
|
ref.current.style[direction === 'rtl' ? 'marginRight' : 'marginLeft'] = `${-horizontalMargin}px`;
|
|
30
29
|
return true;
|
|
31
30
|
};
|
|
@@ -38,7 +38,6 @@ describe('<SelectableBox />', () => {
|
|
|
38
38
|
it('renders with radio input type if neither checkbox nor radio is passed', () => {
|
|
39
39
|
// Mock the `console.error` is intentional because an invalid `type` prop
|
|
40
40
|
// with `wrongType` specified for `ForwardRef` expects one of the ['radio','flag'] parameters.
|
|
41
|
-
// eslint-disable-next-line no-console
|
|
42
41
|
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
|
43
42
|
render(<SelectableRadio type="wrongType" />);
|
|
44
43
|
const selectableBox = screen.getByRole('button');
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import Form, { CheckboxControl, RadioControl } from '../Form';
|
|
2
2
|
|
|
3
|
-
// eslint-disable-next-line import/prefer-default-export,consistent-return
|
|
4
3
|
export const getInputType = (component, type) => {
|
|
5
4
|
if (component === 'SelectableBox') {
|
|
6
5
|
switch (type) {
|
|
@@ -21,4 +20,5 @@ export const getInputType = (component, type) => {
|
|
|
21
20
|
return Form.RadioSet;
|
|
22
21
|
}
|
|
23
22
|
}
|
|
23
|
+
return null;
|
|
24
24
|
};
|
package/src/Sheet/Sheet.test.jsx
CHANGED
|
@@ -6,11 +6,12 @@ import Sheet, { POSITIONS, VARIANTS } from '.';
|
|
|
6
6
|
|
|
7
7
|
/* eslint-disable react/prop-types */
|
|
8
8
|
jest.mock('./SheetContainer', () => function SheetContainerMock(props) {
|
|
9
|
-
const { children, ...otherProps } = props;
|
|
9
|
+
const { children, className, ...otherProps } = props;
|
|
10
|
+
const allClasses = ['sheet-container', className].filter(Boolean).join(' ');
|
|
10
11
|
return (
|
|
11
|
-
<sheet-container {...otherProps}>
|
|
12
|
+
<div data-testid="sheet-container" className={allClasses} {...otherProps}>
|
|
12
13
|
{children}
|
|
13
|
-
</
|
|
14
|
+
</div>
|
|
14
15
|
);
|
|
15
16
|
});
|
|
16
17
|
|
|
@@ -53,5 +54,64 @@ describe('<Sheet />', () => {
|
|
|
53
54
|
const { container: container2 } = render(<Sheet />);
|
|
54
55
|
expect(container2.firstChild).not.toBeNull();
|
|
55
56
|
});
|
|
57
|
+
|
|
58
|
+
it('renders with custom className', () => {
|
|
59
|
+
const customClassName = 'custom-class';
|
|
60
|
+
const { container } = render(<Sheet className={customClassName} />);
|
|
61
|
+
const sheetElement = container.querySelector('.pgn__sheet-component');
|
|
62
|
+
|
|
63
|
+
expect(sheetElement).toBeInTheDocument();
|
|
64
|
+
expect(sheetElement).toHaveClass('pgn__sheet-component');
|
|
65
|
+
expect(sheetElement).toHaveClass(customClassName);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('handles multiple custom className', () => {
|
|
69
|
+
const customClasses = 'class-one class-two';
|
|
70
|
+
const { container } = render(<Sheet className={customClasses} />);
|
|
71
|
+
const sheetElement = container.querySelector('.pgn__sheet-component');
|
|
72
|
+
|
|
73
|
+
expect(sheetElement).toHaveClass('pgn__sheet-component');
|
|
74
|
+
expect(sheetElement).toHaveClass('class-one');
|
|
75
|
+
expect(sheetElement).toHaveClass('class-two');
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('renders with custom className on SheetContainer', () => {
|
|
79
|
+
const customClassName = 'custom-container-class';
|
|
80
|
+
const { getByTestId } = render(<Sheet containerClassName={customClassName} />);
|
|
81
|
+
const sheetContainer = getByTestId('sheet-container');
|
|
82
|
+
|
|
83
|
+
expect(sheetContainer).toBeInTheDocument();
|
|
84
|
+
expect(sheetContainer).toHaveClass('sheet-container');
|
|
85
|
+
expect(sheetContainer).toHaveClass(customClassName);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('handles multiple custom className values on SheetContainer', () => {
|
|
89
|
+
const customClasses = 'container-one container-two';
|
|
90
|
+
const { getByTestId } = render(<Sheet containerClassName={customClasses} />);
|
|
91
|
+
const sheetContainer = getByTestId('sheet-container');
|
|
92
|
+
|
|
93
|
+
expect(sheetContainer).toBeInTheDocument();
|
|
94
|
+
expect(sheetContainer).toHaveClass('sheet-container');
|
|
95
|
+
expect(sheetContainer).toHaveClass('container-one');
|
|
96
|
+
expect(sheetContainer).toHaveClass('container-two');
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('handles className and containerClassName simultaneously', () => {
|
|
100
|
+
const containerClass = 'container-class';
|
|
101
|
+
const sheetClass = 'sheet-class';
|
|
102
|
+
const { getByTestId, container } = render(
|
|
103
|
+
<Sheet containerClassName={containerClass} className={sheetClass} />,
|
|
104
|
+
);
|
|
105
|
+
const sheetContainer = getByTestId('sheet-container');
|
|
106
|
+
const sheetElement = container.querySelector('.pgn__sheet-component');
|
|
107
|
+
|
|
108
|
+
expect(sheetContainer).toBeInTheDocument();
|
|
109
|
+
expect(sheetContainer).toHaveClass('sheet-container');
|
|
110
|
+
expect(sheetContainer).toHaveClass(containerClass);
|
|
111
|
+
|
|
112
|
+
expect(sheetElement).toBeInTheDocument();
|
|
113
|
+
expect(sheetElement).toHaveClass('pgn__sheet-component');
|
|
114
|
+
expect(sheetElement).toHaveClass(sheetClass);
|
|
115
|
+
});
|
|
56
116
|
});
|
|
57
117
|
});
|
|
@@ -1,23 +1,44 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import ReactDOM from 'react-dom';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
|
+
import classNames from 'classnames';
|
|
4
5
|
|
|
5
6
|
class SheetContainer extends React.Component {
|
|
6
7
|
constructor(props) {
|
|
7
8
|
super(props);
|
|
8
9
|
this.sheetRootName = 'sheet-root';
|
|
10
|
+
this.updateRootElement();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
componentDidUpdate(prevProps) {
|
|
14
|
+
if (prevProps.className !== this.props.className) {
|
|
15
|
+
this.updateRootElement();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
updateRootElement = () => {
|
|
20
|
+
const { className } = this.props;
|
|
21
|
+
|
|
22
|
+
/* istanbul ignore next */
|
|
9
23
|
if (typeof document === 'undefined') {
|
|
10
24
|
this.rootElement = null;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let rootElement = document.getElementById(this.sheetRootName);
|
|
29
|
+
|
|
30
|
+
if (!rootElement) {
|
|
31
|
+
rootElement = document.createElement('div');
|
|
15
32
|
rootElement.setAttribute('id', this.sheetRootName);
|
|
16
|
-
rootElement.setAttribute('class', 'sheet-container');
|
|
17
33
|
rootElement.setAttribute('data-testid', 'sheet-container');
|
|
18
|
-
|
|
34
|
+
document.body.appendChild(rootElement);
|
|
19
35
|
}
|
|
20
|
-
|
|
36
|
+
|
|
37
|
+
const classes = classNames('sheet-container', className);
|
|
38
|
+
rootElement.setAttribute('class', classes);
|
|
39
|
+
|
|
40
|
+
this.rootElement = rootElement;
|
|
41
|
+
};
|
|
21
42
|
|
|
22
43
|
render() {
|
|
23
44
|
if (this.rootElement) {
|
|
@@ -32,6 +53,12 @@ class SheetContainer extends React.Component {
|
|
|
32
53
|
|
|
33
54
|
SheetContainer.propTypes = {
|
|
34
55
|
children: PropTypes.node.isRequired,
|
|
56
|
+
/** Additional CSS classes to apply to the sheet container */
|
|
57
|
+
className: PropTypes.string,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
SheetContainer.defaultProps = {
|
|
61
|
+
className: undefined,
|
|
35
62
|
};
|
|
36
63
|
|
|
37
64
|
export default SheetContainer;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { render, screen, act } from '@testing-library/react';
|
|
3
3
|
import SheetContainer from './SheetContainer';
|
|
4
4
|
|
|
5
5
|
const childId1 = 'sheet-container-TEST-child1';
|
|
@@ -31,4 +31,37 @@ describe('<SheetContainer />', () => {
|
|
|
31
31
|
const childEl2 = screen.getByText(childContent2);
|
|
32
32
|
expect(childEl2).toBeTruthy();
|
|
33
33
|
});
|
|
34
|
+
|
|
35
|
+
it('applies custom className if provided', () => {
|
|
36
|
+
const customClass = 'custom-class';
|
|
37
|
+
render(<SheetContainer className={customClass}>{child1}</SheetContainer>);
|
|
38
|
+
const rootEl = screen.getByTestId('sheet-container');
|
|
39
|
+
expect(rootEl).toBeTruthy();
|
|
40
|
+
expect(rootEl.className).toContain('sheet-container');
|
|
41
|
+
expect(rootEl.className).toContain(customClass);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('calls updateRootElement when className changes (componentDidUpdate)', () => {
|
|
45
|
+
const { rerender } = render(
|
|
46
|
+
<SheetContainer className="first-class">
|
|
47
|
+
<div>Content</div>
|
|
48
|
+
</SheetContainer>,
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const sheetRoot = document.getElementById('sheet-root');
|
|
52
|
+
expect(sheetRoot).toHaveClass('sheet-container');
|
|
53
|
+
expect(sheetRoot).toHaveClass('first-class');
|
|
54
|
+
|
|
55
|
+
act(() => {
|
|
56
|
+
rerender(
|
|
57
|
+
<SheetContainer className="second-class">
|
|
58
|
+
<div>Content</div>
|
|
59
|
+
</SheetContainer>,
|
|
60
|
+
);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
expect(sheetRoot).toHaveClass('sheet-container');
|
|
64
|
+
expect(sheetRoot).toHaveClass('second-class');
|
|
65
|
+
expect(sheetRoot).not.toHaveClass('first-class');
|
|
66
|
+
});
|
|
34
67
|
});
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
3
|
exports[`<Sheet /> snapshots blocking, left snapshot 1`] = `
|
|
4
|
-
<
|
|
4
|
+
<div
|
|
5
|
+
className="sheet-container"
|
|
6
|
+
data-testid="sheet-container"
|
|
7
|
+
>
|
|
5
8
|
<div
|
|
6
9
|
className="pgn__sheet-skrim"
|
|
7
10
|
role="presentation"
|
|
@@ -28,11 +31,14 @@ exports[`<Sheet /> snapshots blocking, left snapshot 1`] = `
|
|
|
28
31
|
/>
|
|
29
32
|
</div>
|
|
30
33
|
</focus-on>
|
|
31
|
-
</
|
|
34
|
+
</div>
|
|
32
35
|
`;
|
|
33
36
|
|
|
34
37
|
exports[`<Sheet /> snapshots dark, right snapshot 1`] = `
|
|
35
|
-
<
|
|
38
|
+
<div
|
|
39
|
+
className="sheet-container"
|
|
40
|
+
data-testid="sheet-container"
|
|
41
|
+
>
|
|
36
42
|
<div
|
|
37
43
|
className="pgn__sheet-skrim hidden"
|
|
38
44
|
role="presentation"
|
|
@@ -59,11 +65,14 @@ exports[`<Sheet /> snapshots dark, right snapshot 1`] = `
|
|
|
59
65
|
/>
|
|
60
66
|
</div>
|
|
61
67
|
</focus-on>
|
|
62
|
-
</
|
|
68
|
+
</div>
|
|
63
69
|
`;
|
|
64
70
|
|
|
65
71
|
exports[`<Sheet /> snapshots default args snapshot: bottom, show, light 1`] = `
|
|
66
|
-
<
|
|
72
|
+
<div
|
|
73
|
+
className="sheet-container"
|
|
74
|
+
data-testid="sheet-container"
|
|
75
|
+
>
|
|
67
76
|
<div
|
|
68
77
|
className="pgn__sheet-skrim hidden"
|
|
69
78
|
role="presentation"
|
|
@@ -96,5 +105,5 @@ exports[`<Sheet /> snapshots default args snapshot: bottom, show, light 1`] = `
|
|
|
96
105
|
</div>
|
|
97
106
|
</div>
|
|
98
107
|
</focus-on>
|
|
99
|
-
</
|
|
108
|
+
</div>
|
|
100
109
|
`;
|
package/src/Sheet/index.jsx
CHANGED
|
@@ -26,13 +26,16 @@ class Sheet extends React.Component {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
renderSheet() {
|
|
29
|
-
const {
|
|
29
|
+
const {
|
|
30
|
+
children, position, variant, className,
|
|
31
|
+
} = this.props;
|
|
30
32
|
return (
|
|
31
33
|
<div
|
|
32
34
|
className={classNames(
|
|
33
35
|
'pgn__sheet-component',
|
|
34
36
|
`pgn__sheet__${variant}`,
|
|
35
37
|
position,
|
|
38
|
+
className,
|
|
36
39
|
)}
|
|
37
40
|
role="alert"
|
|
38
41
|
aria-live="polite"
|
|
@@ -50,12 +53,13 @@ class Sheet extends React.Component {
|
|
|
50
53
|
blocking,
|
|
51
54
|
show,
|
|
52
55
|
onClose,
|
|
56
|
+
containerClassName,
|
|
53
57
|
} = this.props;
|
|
54
58
|
if (!show) {
|
|
55
59
|
return null;
|
|
56
60
|
}
|
|
57
61
|
return (
|
|
58
|
-
<SheetContainer>
|
|
62
|
+
<SheetContainer className={classNames(containerClassName)}>
|
|
59
63
|
<div
|
|
60
64
|
className={classNames(
|
|
61
65
|
'pgn__sheet-skrim',
|
|
@@ -80,6 +84,10 @@ Sheet.propTypes = {
|
|
|
80
84
|
blocking: PropTypes.bool,
|
|
81
85
|
/** an element rendered inside the sheet */
|
|
82
86
|
children: PropTypes.node,
|
|
87
|
+
/** A class that is appended to the sheet container element. */
|
|
88
|
+
containerClassName: PropTypes.string,
|
|
89
|
+
/** A class that is appended to the sheet element. */
|
|
90
|
+
className: PropTypes.string,
|
|
83
91
|
/** a string designating the sheet's position on the window */
|
|
84
92
|
position: PropTypes.oneOf([
|
|
85
93
|
POSITIONS.left,
|
|
@@ -102,6 +110,8 @@ Sheet.defaultProps = {
|
|
|
102
110
|
show: true,
|
|
103
111
|
onClose: () => {},
|
|
104
112
|
variant: VARIANTS.light,
|
|
113
|
+
containerClassName: undefined,
|
|
114
|
+
className: undefined,
|
|
105
115
|
};
|
|
106
116
|
|
|
107
117
|
export default Sheet;
|
|
@@ -1,20 +1,32 @@
|
|
|
1
|
-
import React, { forwardRef } from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
1
|
+
import React, { forwardRef, ForwardedRef } from 'react';
|
|
3
2
|
import classNames from 'classnames';
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
interface StackProps {
|
|
5
|
+
/** Specifies the content of the `Stack`. */
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
/** Specifies direction of the children blocks (column/row). */
|
|
8
|
+
direction?: 'horizontal' | 'vertical';
|
|
9
|
+
/**
|
|
10
|
+
* Specifies inner space between children blocks.
|
|
11
|
+
*
|
|
12
|
+
* Valid values are based on `the spacing classes`:
|
|
13
|
+
* `0, 0.5, ... 6`.
|
|
14
|
+
*/
|
|
15
|
+
gap?: number;
|
|
16
|
+
/** Specifies the order of the children. */
|
|
17
|
+
reversed?: boolean;
|
|
18
|
+
/** Specifies an additional `className` to add to the base element. */
|
|
19
|
+
className?: string;
|
|
20
|
+
}
|
|
9
21
|
|
|
10
22
|
const Stack = forwardRef(({
|
|
11
|
-
direction,
|
|
12
|
-
gap,
|
|
13
|
-
reversed,
|
|
23
|
+
direction = 'vertical',
|
|
24
|
+
gap = 0,
|
|
25
|
+
reversed = false,
|
|
14
26
|
children,
|
|
15
27
|
className,
|
|
16
28
|
...rest
|
|
17
|
-
}, ref) => (
|
|
29
|
+
}: StackProps, ref: ForwardedRef<HTMLDivElement>) => (
|
|
18
30
|
<div
|
|
19
31
|
ref={ref}
|
|
20
32
|
className={classNames(
|
|
@@ -29,29 +41,4 @@ const Stack = forwardRef(({
|
|
|
29
41
|
</div>
|
|
30
42
|
));
|
|
31
43
|
|
|
32
|
-
Stack.propTypes = {
|
|
33
|
-
/** Specifies the content of the `Stack`. */
|
|
34
|
-
children: PropTypes.node.isRequired,
|
|
35
|
-
/** Specifies direction of the children blocks (column/row). */
|
|
36
|
-
direction: PropTypes.oneOf(DIRECTION_VARIANTS),
|
|
37
|
-
/**
|
|
38
|
-
* Specifies inner space between children blocks.
|
|
39
|
-
*
|
|
40
|
-
* Valid values are based on `the spacing classes`:
|
|
41
|
-
* `0, 0.5, ... 6`.
|
|
42
|
-
*/
|
|
43
|
-
gap: PropTypes.number,
|
|
44
|
-
/** Specifies the order of the children. */
|
|
45
|
-
reversed: PropTypes.bool,
|
|
46
|
-
/** Specifies an additional `className` to add to the base element. */
|
|
47
|
-
className: PropTypes.string,
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
Stack.defaultProps = {
|
|
51
|
-
direction: 'vertical',
|
|
52
|
-
gap: 0,
|
|
53
|
-
className: undefined,
|
|
54
|
-
reversed: false,
|
|
55
|
-
};
|
|
56
|
-
|
|
57
44
|
export default Stack;
|
package/src/Sticky/index.jsx
CHANGED
|
@@ -18,7 +18,6 @@ const Sticky = React.forwardRef(({
|
|
|
18
18
|
const defaultRef = React.useRef();
|
|
19
19
|
const resolvedRef = ref || defaultRef;
|
|
20
20
|
|
|
21
|
-
// eslint-disable-next-line consistent-return
|
|
22
21
|
useLayoutEffect(() => {
|
|
23
22
|
if (resolvedRef.current) {
|
|
24
23
|
const stickyElement = resolvedRef.current;
|
|
@@ -45,6 +44,7 @@ const Sticky = React.forwardRef(({
|
|
|
45
44
|
observer.unobserve(stickyElement);
|
|
46
45
|
};
|
|
47
46
|
}
|
|
47
|
+
return undefined;
|
|
48
48
|
}, [position, resolvedRef]);
|
|
49
49
|
|
|
50
50
|
return (
|
|
@@ -1,33 +1,25 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
2
|
import BaseTab from 'react-bootstrap/Tab';
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
return <BaseTab {...props} />;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
Tab.propTypes = {
|
|
4
|
+
interface TabProps {
|
|
10
5
|
/** Specifies the `Tab` navigation title. */
|
|
11
|
-
title:
|
|
6
|
+
title: React.ReactNode;
|
|
12
7
|
/** Specifies notification bubble content. It appears on the top right of the `Tab`. */
|
|
13
|
-
notification
|
|
8
|
+
notification?: React.ReactNode;
|
|
14
9
|
/** Specifies whether `Tab` is disabled. */
|
|
15
|
-
disabled
|
|
10
|
+
disabled?: boolean;
|
|
16
11
|
/**
|
|
17
12
|
* A unique identifier for the Component, the `eventKey` makes it distinguishable
|
|
18
13
|
* from others in a set. Similar to React's `key` prop, in that it only needs to be
|
|
19
14
|
* unique amongst the Components siblings, not globally.
|
|
20
15
|
*/
|
|
21
|
-
eventKey
|
|
16
|
+
eventKey?: string | number;
|
|
22
17
|
/** Specifies class name to append to the base element. */
|
|
23
|
-
tabClassName
|
|
24
|
-
}
|
|
18
|
+
tabClassName?: string;
|
|
19
|
+
}
|
|
25
20
|
|
|
26
|
-
Tab
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
eventKey: undefined,
|
|
30
|
-
tabClassName: undefined,
|
|
31
|
-
};
|
|
21
|
+
function Tab(props: TabProps) {
|
|
22
|
+
return <BaseTab {...props} />;
|
|
23
|
+
}
|
|
32
24
|
|
|
33
25
|
export default Tab;
|