@openedx/paragon 21.11.4 → 21.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Container/index.js +6 -2
- package/dist/Container/index.js.map +1 -1
- package/dist/DataTable/index.js +1 -0
- package/dist/DataTable/index.js.map +1 -1
- package/dist/DataTable/selection/BaseSelectionStatus.js +3 -2
- package/dist/DataTable/selection/BaseSelectionStatus.js.map +1 -1
- package/dist/Dropdown/index.js.map +1 -1
- package/dist/Form/FormSwitch.js +3 -0
- package/dist/Form/FormSwitch.js.map +1 -1
- package/dist/Hyperlink/index.js +7 -6
- package/dist/Hyperlink/index.js.map +1 -1
- package/dist/Icon/index.js +17 -10
- package/dist/Icon/index.js.map +1 -1
- package/dist/IconButton/index.js +1 -1
- package/dist/IconButton/index.js.map +1 -1
- package/dist/Layout/index.js.map +1 -1
- package/dist/Modal/ModalDialog.js +3 -0
- package/dist/Modal/ModalDialog.js.map +1 -1
- package/dist/Modal/index.js +11 -6
- package/dist/Modal/index.js.map +1 -1
- package/dist/Popover/index.js +8 -8
- package/dist/Popover/index.js.map +1 -1
- package/dist/ProductTour/Checkpoint.js +10 -8
- package/dist/ProductTour/Checkpoint.js.map +1 -1
- package/dist/ProductTour/messages.js +16 -0
- package/dist/SearchField/SearchFieldAdvanced.js +12 -7
- package/dist/SearchField/SearchFieldAdvanced.js.map +1 -1
- package/dist/SearchField/SearchFieldLabel.js +3 -3
- package/dist/SearchField/SearchFieldLabel.js.map +1 -1
- package/dist/SearchField/index.js +0 -1
- package/dist/SearchField/index.js.map +1 -1
- package/dist/Tabs/index.js +13 -13
- package/dist/Tabs/index.js.map +1 -1
- package/dist/hooks/useIndexOfLastVisibleChild.js +33 -38
- package/dist/hooks/useIndexOfLastVisibleChild.js.map +1 -1
- package/dist/i18n/messages/ar.json +2 -1
- package/dist/i18n/messages/ca.json +2 -1
- package/dist/i18n/messages/es_419.json +2 -1
- package/dist/i18n/messages/es_AR.json +2 -1
- package/dist/i18n/messages/es_ES.json +2 -1
- package/dist/i18n/messages/fr.json +2 -1
- package/dist/i18n/messages/he.json +2 -1
- package/dist/i18n/messages/id.json +2 -1
- package/dist/i18n/messages/it_IT.json +2 -1
- package/dist/i18n/messages/ko_KR.json +2 -1
- package/dist/i18n/messages/pl.json +2 -1
- package/dist/i18n/messages/pt_BR.json +2 -1
- package/dist/i18n/messages/pt_PT.json +2 -1
- package/dist/i18n/messages/ru.json +2 -1
- package/dist/i18n/messages/th.json +2 -1
- package/dist/i18n/messages/tr_TR.json +2 -1
- package/dist/i18n/messages/uk.json +2 -1
- package/dist/i18n/messages/zh_CN.json +2 -1
- package/icons/es5/RightSidebarFilled.js +15 -0
- package/icons/es5/RightSidebarOutlined.js +15 -0
- package/icons/es5/index.js +2 -0
- package/icons/jsx/RightSidebarFilled.jsx +19 -0
- package/icons/jsx/RightSidebarOutlined.jsx +19 -0
- package/icons/jsx/index.jsx +2 -0
- package/icons/svg/right_sidebar_filled.svg +3 -0
- package/icons/svg/right_sidebar_outlined.svg +3 -0
- package/package.json +1 -1
- package/src/Container/index.jsx +4 -0
- package/src/DataTable/index.jsx +1 -0
- package/src/DataTable/selection/BaseSelectionStatus.jsx +2 -2
- package/src/DataTable/tests/DataTable.test.jsx +31 -0
- package/src/Dropdown/index.jsx +4 -0
- package/src/Form/FormSwitch.jsx +3 -0
- package/src/Hyperlink/index.jsx +7 -6
- package/src/Icon/index.jsx +17 -10
- package/src/IconButton/index.jsx +1 -1
- package/src/Layout/index.jsx +1 -4
- package/src/Modal/ModalDialog.jsx +3 -0
- package/src/Modal/index.jsx +11 -6
- package/src/Popover/README.md +0 -1
- package/src/Popover/index.jsx +11 -11
- package/src/ProductTour/Checkpoint.jsx +9 -6
- package/src/ProductTour/messages.js +16 -0
- package/src/SearchField/SearchFieldAdvanced.jsx +12 -7
- package/src/SearchField/SearchFieldLabel.jsx +3 -3
- package/src/SearchField/index.jsx +0 -1
- package/src/Tabs/index.jsx +19 -13
- package/src/hooks/tests/useIndexOfLastVisibleChild.test.jsx +3 -3
- package/src/hooks/useIndexOfLastVisibleChild.jsx +36 -38
- package/src/hooks/useIndexOfLastVisibleChild.mdx +3 -3
- package/src/i18n/messages/ar.json +2 -1
- package/src/i18n/messages/ca.json +2 -1
- package/src/i18n/messages/es_419.json +2 -1
- package/src/i18n/messages/es_AR.json +2 -1
- package/src/i18n/messages/es_ES.json +2 -1
- package/src/i18n/messages/fr.json +2 -1
- package/src/i18n/messages/he.json +2 -1
- package/src/i18n/messages/id.json +2 -1
- package/src/i18n/messages/it_IT.json +2 -1
- package/src/i18n/messages/ko_KR.json +2 -1
- package/src/i18n/messages/pl.json +2 -1
- package/src/i18n/messages/pt_BR.json +2 -1
- package/src/i18n/messages/pt_PT.json +2 -1
- package/src/i18n/messages/ru.json +2 -1
- package/src/i18n/messages/th.json +2 -1
- package/src/i18n/messages/tr_TR.json +2 -1
- package/src/i18n/messages/uk.json +2 -1
- package/src/i18n/messages/zh_CN.json +2 -1
|
@@ -28,5 +28,6 @@
|
|
|
28
28
|
"pgn.FormAutosuggest.iconButtonClosed": "Close the options menu",
|
|
29
29
|
"pgn.FormAutosuggest.iconButtonOpened": "Open the options menu",
|
|
30
30
|
"pgn.Toast.closeLabel": "Close",
|
|
31
|
-
"pgn.ProductTour.Checkpoint.position-text": "Top of step {step}"
|
|
31
|
+
"pgn.ProductTour.Checkpoint.top-position-text": "Top of step {step}",
|
|
32
|
+
"pgn.ProductTour.Checkpoint.bottom-position-text": "Bottom of step {step}"
|
|
32
33
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
const SvgRightSidebarFilled = props => /*#__PURE__*/React.createElement("svg", _extends({
|
|
4
|
+
width: 24,
|
|
5
|
+
height: 24,
|
|
6
|
+
viewBox: "0 0 24 24",
|
|
7
|
+
fill: "none",
|
|
8
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
9
|
+
}, props), /*#__PURE__*/React.createElement("path", {
|
|
10
|
+
fillRule: "evenodd",
|
|
11
|
+
clipRule: "evenodd",
|
|
12
|
+
d: "M2 22V2h20v20H2ZM14 4H4v16h10V4Z",
|
|
13
|
+
fill: "currentColor"
|
|
14
|
+
}));
|
|
15
|
+
export default SvgRightSidebarFilled;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
const SvgRightSidebarOutlined = props => /*#__PURE__*/React.createElement("svg", _extends({
|
|
4
|
+
width: 24,
|
|
5
|
+
height: 24,
|
|
6
|
+
viewBox: "0 0 24 24",
|
|
7
|
+
fill: "none",
|
|
8
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
9
|
+
}, props), /*#__PURE__*/React.createElement("path", {
|
|
10
|
+
fillRule: "evenodd",
|
|
11
|
+
clipRule: "evenodd",
|
|
12
|
+
d: "M2 2v20h20V2H2Zm18 2h-4v16h4V4ZM4 4h10v16H4V4Z",
|
|
13
|
+
fill: "currentColor"
|
|
14
|
+
}));
|
|
15
|
+
export default SvgRightSidebarOutlined;
|
package/icons/es5/index.js
CHANGED
|
@@ -1694,6 +1694,8 @@ export { default as RestoreFromTrash } from "./RestoreFromTrash";
|
|
|
1694
1694
|
export { default as RestorePage } from "./RestorePage";
|
|
1695
1695
|
export { default as Reviews } from "./Reviews";
|
|
1696
1696
|
export { default as RiceBowl } from "./RiceBowl";
|
|
1697
|
+
export { default as RightSidebarFilled } from "./RightSidebarFilled";
|
|
1698
|
+
export { default as RightSidebarOutlined } from "./RightSidebarOutlined";
|
|
1697
1699
|
export { default as RingVolume } from "./RingVolume";
|
|
1698
1700
|
export { default as Rocket } from "./Rocket";
|
|
1699
1701
|
export { default as RocketLaunch } from "./RocketLaunch";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
const SvgRightSidebarFilled = (props) => (
|
|
3
|
+
<svg
|
|
4
|
+
width={24}
|
|
5
|
+
height={24}
|
|
6
|
+
viewBox="0 0 24 24"
|
|
7
|
+
fill="none"
|
|
8
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
9
|
+
{...props}
|
|
10
|
+
>
|
|
11
|
+
<path
|
|
12
|
+
fillRule="evenodd"
|
|
13
|
+
clipRule="evenodd"
|
|
14
|
+
d="M2 22V2h20v20H2ZM14 4H4v16h10V4Z"
|
|
15
|
+
fill="currentColor"
|
|
16
|
+
/>
|
|
17
|
+
</svg>
|
|
18
|
+
);
|
|
19
|
+
export default SvgRightSidebarFilled;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
const SvgRightSidebarOutlined = (props) => (
|
|
3
|
+
<svg
|
|
4
|
+
width={24}
|
|
5
|
+
height={24}
|
|
6
|
+
viewBox="0 0 24 24"
|
|
7
|
+
fill="none"
|
|
8
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
9
|
+
{...props}
|
|
10
|
+
>
|
|
11
|
+
<path
|
|
12
|
+
fillRule="evenodd"
|
|
13
|
+
clipRule="evenodd"
|
|
14
|
+
d="M2 2v20h20V2H2Zm18 2h-4v16h4V4ZM4 4h10v16H4V4Z"
|
|
15
|
+
fill="currentColor"
|
|
16
|
+
/>
|
|
17
|
+
</svg>
|
|
18
|
+
);
|
|
19
|
+
export default SvgRightSidebarOutlined;
|
package/icons/jsx/index.jsx
CHANGED
|
@@ -1694,6 +1694,8 @@ export { default as RestoreFromTrash } from "./RestoreFromTrash";
|
|
|
1694
1694
|
export { default as RestorePage } from "./RestorePage";
|
|
1695
1695
|
export { default as Reviews } from "./Reviews";
|
|
1696
1696
|
export { default as RiceBowl } from "./RiceBowl";
|
|
1697
|
+
export { default as RightSidebarFilled } from "./RightSidebarFilled";
|
|
1698
|
+
export { default as RightSidebarOutlined } from "./RightSidebarOutlined";
|
|
1697
1699
|
export { default as RingVolume } from "./RingVolume";
|
|
1698
1700
|
export { default as Rocket } from "./Rocket";
|
|
1699
1701
|
export { default as RocketLaunch } from "./RocketLaunch";
|
package/package.json
CHANGED
package/src/Container/index.jsx
CHANGED
|
@@ -28,11 +28,14 @@ Container.propTypes = {
|
|
|
28
28
|
...RBContainer.propTypes,
|
|
29
29
|
/** Override the base element */
|
|
30
30
|
as: PropTypes.elementType,
|
|
31
|
+
/** Specifies the contents of the container */
|
|
31
32
|
children: PropTypes.node,
|
|
32
33
|
/** Fill all available space at any breakpoint */
|
|
33
34
|
fluid: PropTypes.bool,
|
|
34
35
|
/** Set the maximum width for the container */
|
|
35
36
|
size: PropTypes.oneOf(Object.keys(SIZE_CLASS_NAMES)),
|
|
37
|
+
/** Overrides underlying component base CSS class name */
|
|
38
|
+
bsPrefix: PropTypes.string,
|
|
36
39
|
};
|
|
37
40
|
|
|
38
41
|
Container.defaultProps = {
|
|
@@ -40,6 +43,7 @@ Container.defaultProps = {
|
|
|
40
43
|
children: undefined,
|
|
41
44
|
fluid: true,
|
|
42
45
|
size: undefined,
|
|
46
|
+
bsPrefix: 'container',
|
|
43
47
|
};
|
|
44
48
|
|
|
45
49
|
export default Container;
|
package/src/DataTable/index.jsx
CHANGED
|
@@ -22,11 +22,11 @@ function BaseSelectionStatus({
|
|
|
22
22
|
}) {
|
|
23
23
|
const {
|
|
24
24
|
itemCount, filteredRows, isPaginated, state,
|
|
25
|
-
isSelectable, maxSelectedRows,
|
|
25
|
+
isSelectable, maxSelectedRows, manualFilters,
|
|
26
26
|
} = useContext(DataTableContext);
|
|
27
27
|
const hasAppliedFilters = state?.filters?.length > 0;
|
|
28
28
|
const isAllRowsSelected = numSelectedRows === itemCount;
|
|
29
|
-
const filteredItems = filteredRows?.length || itemCount;
|
|
29
|
+
const filteredItems = manualFilters ? itemCount : (filteredRows?.length || itemCount);
|
|
30
30
|
const hasMaxSelectedRows = isSelectable && maxSelectedRows;
|
|
31
31
|
|
|
32
32
|
const intlAllSelectedText = allSelectedText || (
|
|
@@ -6,6 +6,8 @@ import { IntlProvider } from 'react-intl';
|
|
|
6
6
|
|
|
7
7
|
import DataTable from '..';
|
|
8
8
|
import DataTableContext from '../DataTableContext';
|
|
9
|
+
import { TextFilter } from '../..';
|
|
10
|
+
import { SELECT_ALL_TEST_ID } from '../selection/data/constants';
|
|
9
11
|
|
|
10
12
|
const additionalColumns = [
|
|
11
13
|
{
|
|
@@ -198,6 +200,35 @@ describe('<DataTable />', () => {
|
|
|
198
200
|
|
|
199
201
|
expect(spinner).toBeTruthy();
|
|
200
202
|
});
|
|
203
|
+
it('displays the total number of items when applying filter and selecting all items', async () => {
|
|
204
|
+
const propsWithSelection = {
|
|
205
|
+
...props,
|
|
206
|
+
isSelectable: true,
|
|
207
|
+
isFilterable: true,
|
|
208
|
+
manualFilters: true,
|
|
209
|
+
defaultColumnValues: { Filter: TextFilter },
|
|
210
|
+
isPaginated: true,
|
|
211
|
+
initialState: { pageSize: 3, pageIndex: 0 },
|
|
212
|
+
pageCount: 3,
|
|
213
|
+
fetchData: jest.fn(),
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
render(<DataTableWrapper {...propsWithSelection} />);
|
|
217
|
+
const filtersButton = screen.getByRole('button', { name: 'Filters' });
|
|
218
|
+
|
|
219
|
+
await userEvent.click(filtersButton);
|
|
220
|
+
|
|
221
|
+
const searchFormControl = screen.getByPlaceholderText('Search coat color');
|
|
222
|
+
await userEvent.type(searchFormControl, 'brown tabby');
|
|
223
|
+
|
|
224
|
+
const selectAllCheckBox = screen.getByTitle('Toggle All Current Page Rows Selected');
|
|
225
|
+
await userEvent.click(selectAllCheckBox);
|
|
226
|
+
|
|
227
|
+
const selectAllButton = screen.getByTestId(SELECT_ALL_TEST_ID);
|
|
228
|
+
// A filtered array is returned from the backend,
|
|
229
|
+
// and the element counter displays its length.
|
|
230
|
+
expect(selectAllButton).toHaveTextContent('Select all 7');
|
|
231
|
+
});
|
|
201
232
|
|
|
202
233
|
describe('[legacy] controlled table selections', () => {
|
|
203
234
|
it('passes initial controlledTableSelections to context', async () => {
|
package/src/Dropdown/index.jsx
CHANGED
|
@@ -69,6 +69,7 @@ const Dropdown = React.forwardRef(
|
|
|
69
69
|
);
|
|
70
70
|
},
|
|
71
71
|
);
|
|
72
|
+
|
|
72
73
|
Dropdown.propTypes = {
|
|
73
74
|
autoClose: PropTypes.oneOfType([
|
|
74
75
|
PropTypes.string,
|
|
@@ -79,6 +80,7 @@ Dropdown.propTypes = {
|
|
|
79
80
|
show: PropTypes.bool,
|
|
80
81
|
variant: PropTypes.oneOf(['light', 'dark']),
|
|
81
82
|
};
|
|
83
|
+
|
|
82
84
|
Dropdown.defaultProps = {
|
|
83
85
|
autoClose: true,
|
|
84
86
|
className: '',
|
|
@@ -127,9 +129,11 @@ Dropdown.Item = React.forwardRef(
|
|
|
127
129
|
);
|
|
128
130
|
},
|
|
129
131
|
);
|
|
132
|
+
|
|
130
133
|
Dropdown.Item.propTypes = {
|
|
131
134
|
className: PropTypes.string,
|
|
132
135
|
};
|
|
136
|
+
|
|
133
137
|
Dropdown.Item.defaultProps = {
|
|
134
138
|
className: undefined,
|
|
135
139
|
};
|
package/src/Form/FormSwitch.jsx
CHANGED
|
@@ -79,8 +79,11 @@ FormSwitch.propTypes = {
|
|
|
79
79
|
children: PropTypes.node.isRequired,
|
|
80
80
|
/** Specifies class name to append to the base element. */
|
|
81
81
|
className: PropTypes.string,
|
|
82
|
+
/** Specifies class name to append to the label element. */
|
|
82
83
|
labelClassName: PropTypes.string,
|
|
84
|
+
/** Specifies helper text to display below the switch. */
|
|
83
85
|
helperText: PropTypes.node,
|
|
86
|
+
/** Determines whether the label should float to the left when the switch is active. */
|
|
84
87
|
floatLabelLeft: PropTypes.bool,
|
|
85
88
|
};
|
|
86
89
|
|
package/src/Hyperlink/index.jsx
CHANGED
|
@@ -101,18 +101,19 @@ Hyperlink.propTypes = {
|
|
|
101
101
|
children: PropTypes.node.isRequired,
|
|
102
102
|
/** Custom class names for the hyperlink */
|
|
103
103
|
className: PropTypes.string,
|
|
104
|
-
/** specifies where the link should open. The default behavior is `_self`, which means that the URL will be
|
|
105
|
-
|
|
104
|
+
/** specifies where the link should open. The default behavior is `_self`, which means that the URL will be
|
|
105
|
+
* loaded into the same browsing context as the current one.
|
|
106
|
+
* If the target is `_blank` (opening a new window) `rel='noopener'` will be added to the anchor tag to prevent
|
|
107
|
+
* any potential [reverse tabnabbing attack](https://www.owasp.org/index.php/Reverse_Tabnabbing).
|
|
108
|
+
*/
|
|
106
109
|
target: PropTypes.string,
|
|
107
110
|
/** specifies the callback function when the link is clicked */
|
|
108
111
|
onClick: PropTypes.func,
|
|
109
|
-
// eslint-disable-next-line max-len
|
|
110
112
|
/** specifies the text for links with a `_blank` target (which loads the URL in a new browsing context). */
|
|
111
113
|
externalLinkAlternativeText: isRequiredIf(
|
|
112
114
|
PropTypes.string,
|
|
113
115
|
props => props.target === '_blank',
|
|
114
116
|
),
|
|
115
|
-
// eslint-disable-next-line max-len
|
|
116
117
|
/** specifies the title for links with a `_blank` target (which loads the URL in a new browsing context). */
|
|
117
118
|
externalLinkTitle: isRequiredIf(
|
|
118
119
|
PropTypes.string,
|
|
@@ -120,9 +121,9 @@ Hyperlink.propTypes = {
|
|
|
120
121
|
),
|
|
121
122
|
/** type of hyperlink */
|
|
122
123
|
variant: PropTypes.oneOf(['default', 'muted', 'brand']),
|
|
123
|
-
/** specify the link style. By default it will be underlined. */
|
|
124
|
+
/** specify the link style. By default, it will be underlined. */
|
|
124
125
|
isInline: PropTypes.bool,
|
|
125
|
-
/** specify if we need to show launch Icon. By default it will be visible. */
|
|
126
|
+
/** specify if we need to show launch Icon. By default, it will be visible. */
|
|
126
127
|
showLaunchIcon: PropTypes.bool,
|
|
127
128
|
};
|
|
128
129
|
|
package/src/Icon/index.jsx
CHANGED
|
@@ -70,28 +70,35 @@ function Icon({
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
Icon.propTypes = {
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
/**
|
|
74
|
+
* An icon component to render.
|
|
75
|
+
* Example import of a Paragon icon component: `import { Check } from '@edx/paragon/icons';`
|
|
76
|
+
*/
|
|
75
77
|
src: PropTypes.oneOfType([PropTypes.element, PropTypes.func]),
|
|
76
78
|
/** HTML element attributes to pass through to the underlying svg element */
|
|
77
79
|
svgAttrs: PropTypes.shape({
|
|
78
80
|
'aria-label': PropTypes.string,
|
|
79
81
|
'aria-labelledby': PropTypes.string,
|
|
80
82
|
}),
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
/**
|
|
84
|
+
* the `id` property of the Icon element, by default this value is generated
|
|
85
|
+
* with the `newId` function with the `prefix` of `Icon`.
|
|
86
|
+
*/
|
|
83
87
|
id: PropTypes.string,
|
|
84
|
-
// eslint-disable-next-line max-len
|
|
85
88
|
/** The size of the icon. */
|
|
86
89
|
size: PropTypes.oneOf(['xs', 'sm', 'md', 'lg']),
|
|
87
|
-
// eslint-disable-next-line max-len
|
|
88
90
|
/** A class name that will define what the Icon looks like. */
|
|
89
91
|
className: PropTypes.string,
|
|
90
|
-
|
|
91
|
-
|
|
92
|
+
/**
|
|
93
|
+
* a boolean that determines the value of `aria-hidden` attribute on the Icon span,
|
|
94
|
+
* this value is `true` by default.
|
|
95
|
+
*/
|
|
92
96
|
hidden: PropTypes.bool,
|
|
93
|
-
|
|
94
|
-
|
|
97
|
+
/**
|
|
98
|
+
* a string or an element that will be used on a secondary span leveraging the `sr-only` style
|
|
99
|
+
* for screenreader only text, this value is `undefined` by default. This value is recommended for use unless
|
|
100
|
+
* the Icon is being used in a way that is purely decorative or provides no additional context for screen
|
|
101
|
+
* reader users. This field should be thought of the same way an `alt` attribute would be used for `image` tags.
|
|
95
102
|
*/
|
|
96
103
|
screenReaderText: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
|
|
97
104
|
};
|
package/src/IconButton/index.jsx
CHANGED
|
@@ -87,7 +87,7 @@ IconButton.propTypes = {
|
|
|
87
87
|
alt: PropTypes.string.isRequired,
|
|
88
88
|
/** Changes icon styles for dark background */
|
|
89
89
|
invertColors: PropTypes.bool,
|
|
90
|
-
/** Accepts a React fontawesome icon.
|
|
90
|
+
/** Accepts a React fontawesome icon. */
|
|
91
91
|
icon: PropTypes.shape({
|
|
92
92
|
prefix: PropTypes.string,
|
|
93
93
|
iconName: PropTypes.string,
|
package/src/Layout/index.jsx
CHANGED
package/src/Modal/index.jsx
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable max-len */
|
|
2
1
|
import React from 'react';
|
|
3
2
|
import ReactDOM from 'react-dom';
|
|
4
3
|
import classNames from 'classnames';
|
|
@@ -271,21 +270,26 @@ class Modal extends React.Component {
|
|
|
271
270
|
Modal.propTypes = {
|
|
272
271
|
/** specifies whether the modal renders open or closed on the initial render. It defaults to false. */
|
|
273
272
|
open: PropTypes.bool,
|
|
274
|
-
/** is the selector for an element in the dom which the modal should be rendered under.
|
|
275
|
-
|
|
273
|
+
/** is the selector for an element in the dom which the modal should be rendered under.
|
|
274
|
+
* It uses querySelector to find the first element that matches that selector,
|
|
275
|
+
* and then creates a React portal to a div underneath the parent element.
|
|
276
|
+
*/
|
|
276
277
|
parentSelector: PropTypes.string,
|
|
277
278
|
/** a string or an element that is rendered inside of the modal title, above the modal body. */
|
|
278
279
|
title: PropTypes.oneOfType([PropTypes.string, PropTypes.element]).isRequired,
|
|
279
280
|
/** a string or an element that is rendered inside of the modal body, between the title and the footer. */
|
|
280
281
|
body: PropTypes.oneOfType([PropTypes.string, PropTypes.element]).isRequired,
|
|
281
|
-
/** an array of either elements or shapes that take the form of the buttonPropTypes.
|
|
282
|
+
/** an array of either elements or shapes that take the form of the buttonPropTypes.
|
|
283
|
+
* See the [buttonPropTypes](https://github.com/openedx/paragon/blob/master/src/Button/index.jsx#L40)
|
|
284
|
+
* for a list of acceptable props to pass as part of a button. */
|
|
282
285
|
buttons: PropTypes.arrayOf(PropTypes.oneOfType([
|
|
283
286
|
PropTypes.element,
|
|
284
287
|
PropTypes.shape({}), // TODO: Only accept nodes in the future
|
|
285
288
|
])),
|
|
286
289
|
/** specifies the display text of the default Close button. It defaults to "Close". */
|
|
287
290
|
closeText: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
|
|
288
|
-
/** a function that is called on close. It can be used to perform actions upon closing of the modal,
|
|
291
|
+
/** a function that is called on close. It can be used to perform actions upon closing of the modal,
|
|
292
|
+
* such as restoring focus to the previous logical focusable element. */
|
|
289
293
|
onClose: PropTypes.func.isRequired,
|
|
290
294
|
variant: PropTypes.shape({
|
|
291
295
|
status: PropTypes.string,
|
|
@@ -295,7 +299,8 @@ Modal.propTypes = {
|
|
|
295
299
|
/** specifies whether a close button is rendered in the modal header. It defaults to true. */
|
|
296
300
|
renderHeaderCloseButton: PropTypes.bool,
|
|
297
301
|
/**
|
|
298
|
-
* Specifies optional classes to add to the element with the '.modal-dialog' class.
|
|
302
|
+
* Specifies optional classes to add to the element with the '.modal-dialog' class.
|
|
303
|
+
* See Bootstrap documentation for possible classes. Some options: modal-lg, modal-sm, modal-dialog-centered
|
|
299
304
|
*/
|
|
300
305
|
dialogClassName: PropTypes.string,
|
|
301
306
|
};
|
package/src/Popover/README.md
CHANGED
package/src/Popover/index.jsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import classNames from 'classnames';
|
|
4
|
-
import
|
|
4
|
+
import BasePopover from 'react-bootstrap/Popover';
|
|
5
5
|
import BasePopoverTitle from 'react-bootstrap/PopoverTitle';
|
|
6
6
|
import BasePopoverContent from 'react-bootstrap/PopoverContent';
|
|
7
7
|
|
|
@@ -13,18 +13,18 @@ const PLACEMENT_VARIANTS = [
|
|
|
13
13
|
'right',
|
|
14
14
|
];
|
|
15
15
|
|
|
16
|
-
const
|
|
16
|
+
const Popover = React.forwardRef(({
|
|
17
17
|
children,
|
|
18
18
|
variant,
|
|
19
19
|
...props
|
|
20
20
|
}, ref) => (
|
|
21
|
-
<
|
|
21
|
+
<BasePopover
|
|
22
22
|
{...props}
|
|
23
23
|
className={classNames({ [`popover-${variant}`]: !!variant }, props.className)}
|
|
24
24
|
ref={ref}
|
|
25
25
|
>
|
|
26
26
|
{children}
|
|
27
|
-
</
|
|
27
|
+
</BasePopover>
|
|
28
28
|
));
|
|
29
29
|
|
|
30
30
|
function PopoverTitle(props) {
|
|
@@ -44,8 +44,8 @@ const commonPropTypes = {
|
|
|
44
44
|
PopoverTitle.propTypes = commonPropTypes;
|
|
45
45
|
PopoverContent.propTypes = commonPropTypes;
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
...
|
|
47
|
+
Popover.propTypes = {
|
|
48
|
+
...BasePopover.propTypes,
|
|
49
49
|
/** An html id attribute, necessary for accessibility. */
|
|
50
50
|
id: PropTypes.string.isRequired,
|
|
51
51
|
/**
|
|
@@ -88,8 +88,8 @@ WrapperPopover.propTypes = {
|
|
|
88
88
|
variant: PropTypes.string,
|
|
89
89
|
};
|
|
90
90
|
|
|
91
|
-
|
|
92
|
-
...
|
|
91
|
+
Popover.defaultProps = {
|
|
92
|
+
...BasePopover.defaultProps,
|
|
93
93
|
placement: 'right',
|
|
94
94
|
title: undefined,
|
|
95
95
|
arrowProps: undefined,
|
|
@@ -111,8 +111,8 @@ PopoverContent.defaultProps = {
|
|
|
111
111
|
bsPrefix: 'popover-body',
|
|
112
112
|
};
|
|
113
113
|
|
|
114
|
-
|
|
115
|
-
|
|
114
|
+
Popover.Title = PopoverTitle;
|
|
115
|
+
Popover.Content = PopoverContent;
|
|
116
116
|
|
|
117
117
|
export { PopoverTitle, PopoverContent };
|
|
118
|
-
export default
|
|
118
|
+
export default Popover;
|
|
@@ -10,6 +10,7 @@ import CheckpointActionRow from './CheckpointActionRow';
|
|
|
10
10
|
import CheckpointBody from './CheckpointBody';
|
|
11
11
|
import CheckpointBreadcrumbs from './CheckpointBreadcrumbs';
|
|
12
12
|
import CheckpointTitle from './CheckpointTitle';
|
|
13
|
+
import messages from './messages';
|
|
13
14
|
|
|
14
15
|
const Checkpoint = React.forwardRef(({
|
|
15
16
|
body,
|
|
@@ -99,10 +100,8 @@ const Checkpoint = React.forwardRef(({
|
|
|
99
100
|
>
|
|
100
101
|
<span className="sr-only">
|
|
101
102
|
<FormattedMessage
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
value={{ step: index + 1 }}
|
|
105
|
-
description="Screen-reader message to indicate the user's position in a sequence of checkpoints."
|
|
103
|
+
{...messages.topPositionText}
|
|
104
|
+
values={{ step: index + 1 }}
|
|
106
105
|
/>
|
|
107
106
|
</span>
|
|
108
107
|
{(title || !isOnlyCheckpoint) && (
|
|
@@ -118,8 +117,12 @@ const Checkpoint = React.forwardRef(({
|
|
|
118
117
|
{...props}
|
|
119
118
|
/>
|
|
120
119
|
<div id="pgn__checkpoint-arrow" data-popper-arrow />
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
<span className="sr-only">
|
|
121
|
+
<FormattedMessage
|
|
122
|
+
{...messages.bottomPositionText}
|
|
123
|
+
values={{ step: index + 1 }}
|
|
124
|
+
/>
|
|
125
|
+
</span>
|
|
123
126
|
</div>
|
|
124
127
|
);
|
|
125
128
|
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { defineMessages } from 'react-intl';
|
|
2
|
+
|
|
3
|
+
const messages = defineMessages({
|
|
4
|
+
topPositionText: {
|
|
5
|
+
id: 'pgn.ProductTour.Checkpoint.top-position-text',
|
|
6
|
+
defaultMessage: 'Top of step {step}',
|
|
7
|
+
description: 'Screen-reader message to notify user that they are located at the bottom of the product tour step.',
|
|
8
|
+
},
|
|
9
|
+
bottomPositionText: {
|
|
10
|
+
id: 'pgn.ProductTour.Checkpoint.bottom-position-text',
|
|
11
|
+
defaultMessage: 'Bottom of step {step}',
|
|
12
|
+
description: 'Screen-reader message to notify user that they are located at the bottom of the product tour step.',
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export default messages;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable max-len */
|
|
2
1
|
import React, {
|
|
3
2
|
useRef, createContext, useState, useEffect,
|
|
4
3
|
} from 'react';
|
|
@@ -138,27 +137,32 @@ SearchFieldAdvanced.propTypes = {
|
|
|
138
137
|
onSubmit: PropTypes.func.isRequired,
|
|
139
138
|
/** specifies a custom class name. */
|
|
140
139
|
className: PropTypes.string,
|
|
141
|
-
/** specifies a callback function for when the user loses focus in the `SearchField` component.
|
|
140
|
+
/** specifies a callback function for when the user loses focus in the `SearchField` component.
|
|
141
|
+
* The default is an empty function. For example:
|
|
142
142
|
```jsx
|
|
143
143
|
<SearchField onBlur={event => console.log(event)} />
|
|
144
144
|
``` */
|
|
145
145
|
onBlur: PropTypes.func,
|
|
146
|
-
/** specifies a callback function for when the value in `SearchField` is changed by the user.
|
|
146
|
+
/** specifies a callback function for when the value in `SearchField` is changed by the user.
|
|
147
|
+
* The default is an empty function. For example:
|
|
147
148
|
```jsx
|
|
148
149
|
<SearchField onChange={value => console.log(value)} />
|
|
149
150
|
``` */
|
|
150
151
|
onChange: PropTypes.func,
|
|
151
|
-
/** specifies a callback function for when the value in `SearchField` is cleared by the user.
|
|
152
|
+
/** specifies a callback function for when the value in `SearchField` is cleared by the user.
|
|
153
|
+
* The default is an empty function. For example:
|
|
152
154
|
```jsx
|
|
153
155
|
<SearchField onClear={() => console.log('search cleared')} />
|
|
154
156
|
``` */
|
|
155
157
|
onClear: PropTypes.func,
|
|
156
|
-
/** specifies a callback function for when the user focuses in the `SearchField` component.
|
|
158
|
+
/** specifies a callback function for when the user focuses in the `SearchField` component.
|
|
159
|
+
* The default is an empty function. For example:
|
|
157
160
|
```jsx
|
|
158
161
|
<SearchField onFocus={event => console.log(event)} />
|
|
159
162
|
``` */
|
|
160
163
|
onFocus: PropTypes.func,
|
|
161
|
-
/** specifies the screenreader text for both the clear and submit buttons (e.g., for i18n translations).
|
|
164
|
+
/** specifies the screenreader text for both the clear and submit buttons (e.g., for i18n translations).
|
|
165
|
+
* The default is `{ label: 'search', clearButton: 'clear search', searchButton: 'submit search' }`. */
|
|
162
166
|
screenReaderText: PropTypes.shape({
|
|
163
167
|
label: PropTypes.oneOfType([PropTypes.string, PropTypes.element]).isRequired,
|
|
164
168
|
submitButton: PropTypes.oneOfType([PropTypes.string, PropTypes.element]).isRequired,
|
|
@@ -171,7 +175,8 @@ SearchFieldAdvanced.propTypes = {
|
|
|
171
175
|
submit: PropTypes.element.isRequired,
|
|
172
176
|
clear: PropTypes.element,
|
|
173
177
|
}),
|
|
174
|
-
/** specifies the aria-label attribute on the form element. This is useful if you use the `SearchField` component
|
|
178
|
+
/** specifies the aria-label attribute on the form element. This is useful if you use the `SearchField` component
|
|
179
|
+
* more than once on a page. */
|
|
175
180
|
formAriaLabel: PropTypes.string,
|
|
176
181
|
/** Specifies whether the `SearchField` is disabled. */
|
|
177
182
|
disabled: PropTypes.bool,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable max-len */
|
|
2
1
|
import React, { useContext } from 'react';
|
|
3
2
|
import PropTypes from 'prop-types';
|
|
4
3
|
import classNames from 'classnames';
|
|
@@ -21,8 +20,9 @@ function SearchFieldLabel({ children, ...props }) {
|
|
|
21
20
|
|
|
22
21
|
SearchFieldLabel.propTypes = {
|
|
23
22
|
/**
|
|
24
|
-
* specifies the label to use for the input field (e.g., for i18n translations).
|
|
25
|
-
* a screenreader-only label will be used in
|
|
23
|
+
* specifies the label to use for the input field (e.g., for i18n translations).
|
|
24
|
+
* Note: if `children` is not provided, a screenreader-only label will be used in
|
|
25
|
+
* its placed based on the `screenReaderText.label` prop for `SearchField.Advanced`.
|
|
26
26
|
*/
|
|
27
27
|
children: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
|
|
28
28
|
};
|