@openedx/paragon 22.13.0 → 22.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/Alert/_variables.scss +2 -1
- package/dist/Annotation/index.js.map +1 -1
- package/dist/Annotation/index.scss +6 -5
- package/dist/Avatar/index.js.map +1 -1
- package/dist/AvatarButton/index.js.map +1 -1
- package/dist/Breadcrumb/index.js.map +1 -1
- package/dist/Bubble/index.js +1 -0
- package/dist/Bubble/index.js.map +1 -1
- package/dist/Bubble/index.scss +3 -2
- package/dist/Button/deprecated/index.js.map +1 -1
- package/dist/Button/index.scss +19 -18
- package/dist/Card/CardCarousel/CardCarouselHeader.js +2 -2
- package/dist/Card/CardCarousel/CardCarouselHeader.js.map +1 -1
- package/dist/Card/CardFooter.js.map +1 -1
- package/dist/Card/CardHeader.js +1 -1
- package/dist/Card/CardHeader.js.map +1 -1
- package/dist/Card/CardImageCap.js.map +1 -1
- package/dist/Card/CardStatus.js.map +1 -1
- package/dist/Card/_variables.scss +3 -2
- package/dist/Card/index.js.map +1 -1
- package/dist/Card/index.scss +10 -9
- package/dist/Chip/ChipIcon.d.ts +1 -1
- package/dist/Chip/index.js +1 -0
- package/dist/Chip/index.js.map +1 -1
- package/dist/ChipCarousel/index.js.map +1 -1
- package/dist/Collapsible/index.js.map +1 -1
- package/dist/ColorPicker/index.js +1 -1
- package/dist/ColorPicker/index.js.map +1 -1
- package/dist/ColorPicker/index.scss +2 -1
- package/dist/DataTable/CollapsibleButtonGroup.js +2 -2
- package/dist/DataTable/CollapsibleButtonGroup.js.map +1 -1
- package/dist/DataTable/DropdownFilters.js +1 -1
- package/dist/DataTable/DropdownFilters.js.map +1 -1
- package/dist/DataTable/TableRow.js.map +1 -1
- package/dist/DataTable/filters/CheckboxFilter.js.map +1 -1
- package/dist/DataTable/filters/DropdownFilter.js.map +1 -1
- package/dist/DataTable/filters/MultiSelectDropdownFilter.js.map +1 -1
- package/dist/DataTable/filters/TextFilter.js.map +1 -1
- package/dist/DataTable/index.scss +14 -13
- package/dist/DataTable/utils/getVisibleColumns.js +1 -1
- package/dist/DataTable/utils/getVisibleColumns.js.map +1 -1
- package/dist/Dropdown/_variables.scss +2 -1
- package/dist/Dropdown/deprecated/DropdownMenu.js +15 -19
- package/dist/Dropdown/deprecated/DropdownMenu.js.map +1 -1
- package/dist/Dropdown/deprecated/index.js +1 -1
- package/dist/Dropdown/deprecated/index.js.map +1 -1
- package/dist/Dropdown/index.js.map +1 -1
- package/dist/Dropzone/DefaultContent.js.map +1 -1
- package/dist/Dropzone/UploadProgress.js.map +1 -1
- package/dist/Dropzone/index.scss +3 -2
- package/dist/Fieldset/index.js.map +1 -1
- package/dist/Form/FormAutosuggest.js +1 -1
- package/dist/Form/FormAutosuggest.js.map +1 -1
- package/dist/Form/FormControl.js.map +1 -1
- package/dist/Form/FormControlDecorator.js.map +1 -1
- package/dist/Form/FormGroupContext.d.ts +1 -1
- package/dist/Form/FormGroupContext.js.map +1 -1
- package/dist/Form/FormText.js.map +1 -1
- package/dist/Form/_index.scss +9 -7
- package/dist/Form/_variables.scss +4 -2
- package/dist/Form/fieldUtils.js.map +1 -1
- package/dist/Hyperlink/index.d.ts +10 -5
- package/dist/Hyperlink/index.js +57 -25
- package/dist/Hyperlink/index.js.map +1 -1
- package/dist/Hyperlink/index.scss +3 -1
- package/dist/Icon/index.js.map +1 -1
- package/dist/IconButton/index.d.ts +13 -8
- package/dist/IconButton/index.js.map +1 -1
- package/dist/IconButtonToggle/index.js.map +1 -1
- package/dist/IconButtonToggle/index.scss +3 -1
- package/dist/Input/index.js.map +1 -1
- package/dist/InputSelect/index.js.map +1 -1
- package/dist/Layout/index.js.map +1 -1
- package/dist/ListBox/index.js.map +1 -1
- package/dist/ListBoxOption/index.js.map +1 -1
- package/dist/Menu/SelectMenu.js +1 -1
- package/dist/Menu/SelectMenu.js.map +1 -1
- package/dist/Menu/index.js +1 -1
- package/dist/Menu/index.js.map +1 -1
- package/dist/Modal/ModalContext.d.ts +1 -1
- package/dist/Modal/ModalDialog.d.ts +1 -1
- package/dist/Modal/ModalDialog.js.map +1 -1
- package/dist/Modal/ModalDialogBody.js +1 -1
- package/dist/Modal/ModalDialogBody.js.map +1 -1
- package/dist/Modal/ModalDialogHeroBackground.js.map +1 -1
- package/dist/Modal/ModalLayer.d.ts +3 -3
- package/dist/Modal/ModalLayer.js.map +1 -1
- package/dist/Modal/ModalPopup.js.map +1 -1
- package/dist/Modal/_ModalDialog.scss +3 -1
- package/dist/Modal/index.js +3 -1
- package/dist/Modal/index.js.map +1 -1
- package/dist/Modal/index.scss +3 -5
- package/dist/Nav/_mixins.scss +3 -1
- package/dist/Overlay/index.d.ts +2 -2
- package/dist/PageBanner/index.js.map +1 -1
- package/dist/PageBanner/index.scss +2 -1
- package/dist/Pagination/PaginationContext.js.map +1 -1
- package/dist/Pagination/index.js.map +1 -1
- package/dist/Popover/_variables.scss +2 -1
- package/dist/Popover/index.js.map +1 -1
- package/dist/ProductTour/Checkpoint.scss +9 -8
- package/dist/ProductTour/index.js +1 -1
- package/dist/ProductTour/index.js.map +1 -1
- package/dist/ProgressBar/index.js.map +1 -1
- package/dist/Scrollable/index.js +1 -1
- package/dist/Scrollable/index.js.map +1 -1
- package/dist/SearchField/SearchFieldAdvanced.js.map +1 -1
- package/dist/SearchField/index.scss +2 -1
- package/dist/SelectableBox/SelectableBoxSet.js.map +1 -1
- package/dist/Sheet/index.js.map +1 -1
- package/dist/Stack/index.js.map +1 -1
- package/dist/StatefulButton/index.js.map +1 -1
- package/dist/StatusAlert/index.js.map +1 -1
- package/dist/Stepper/StepperHeader.js +1 -1
- package/dist/Stepper/StepperHeader.js.map +1 -1
- package/dist/Stepper/StepperHeaderStep.js.map +1 -1
- package/dist/Sticky/index.js.map +1 -1
- package/dist/Table/_variables.scss +2 -1
- package/dist/Tabs/deprecated/index.js.map +1 -1
- package/dist/Tabs/index.js +1 -1
- package/dist/Tabs/index.js.map +1 -1
- package/dist/Toast/ToastContainer.scss +1 -1
- package/dist/Toast/index.scss +2 -2
- package/dist/Truncate/index.js +1 -1
- package/dist/Truncate/index.js.map +1 -1
- package/dist/ValidationFormGroup/index.js.map +1 -1
- package/dist/asInput/index.js.map +1 -1
- package/dist/hooks/{useArrowKeyNavigation.js → useArrowKeyNavigationHook.js} +5 -1
- package/dist/hooks/useArrowKeyNavigationHook.js.map +1 -0
- package/dist/hooks/{useIndexOfLastVisibleChild.js → useIndexOfLastVisibleChildHook.js} +5 -1
- package/dist/hooks/useIndexOfLastVisibleChildHook.js.map +1 -0
- package/dist/hooks/{useIsVisible.js → useIsVisibleHook.js} +1 -1
- package/dist/hooks/useIsVisibleHook.js.map +1 -0
- package/dist/hooks/{useToggle.js → useToggleHook.js} +5 -1
- package/dist/hooks/useToggleHook.js.map +1 -0
- package/dist/hooks/{useWindowSize.js → useWindowSizeHook.js} +1 -1
- package/dist/hooks/useWindowSizeHook.js.map +1 -0
- package/dist/index.d.ts +6 -6
- package/dist/index.js +6 -6
- package/dist/paragon.css +1 -45
- package/dist/utils/newId.js.map +1 -1
- package/dist/withDeprecatedProps.js.map +1 -1
- package/icons/node_modules/@svgr/babel-plugin-add-jsx-attribute/CHANGELOG.md +50 -0
- package/icons/node_modules/@svgr/babel-plugin-add-jsx-attribute/LICENSE +7 -0
- package/icons/node_modules/@svgr/babel-plugin-add-jsx-attribute/README.md +37 -0
- package/icons/node_modules/@svgr/babel-plugin-add-jsx-attribute/dist/index.d.ts +20 -0
- package/icons/node_modules/@svgr/babel-plugin-add-jsx-attribute/dist/index.js +79 -0
- package/icons/node_modules/@svgr/babel-plugin-add-jsx-attribute/dist/index.js.map +1 -0
- package/icons/node_modules/@svgr/babel-plugin-add-jsx-attribute/package.json +40 -0
- package/icons/node_modules/@svgr/babel-plugin-add-jsx-attribute/tsconfig.json +4 -0
- package/icons/package.json +1 -1
- package/package.json +12 -19
- package/scss/core/_exports.module.scss +7 -6
- package/scss/core/_functions.scss +9 -7
- package/scss/core/_typography.scss +2 -1
- package/scss/core/_utilities.scss +2 -1
- package/scss/core/_variables.scss +98 -95
- package/src/Alert/_variables.scss +2 -1
- package/src/Annotation/index.scss +6 -5
- package/src/Breadcrumb/Breadcrumb.test.jsx +3 -2
- package/src/Bubble/index.scss +3 -2
- package/src/Bubble/index.tsx +1 -0
- package/src/Button/Button.test.tsx +6 -1
- package/src/Button/deprecated/Button.test.jsx +6 -4
- package/src/Button/index.scss +19 -18
- package/src/Card/CardCarousel/tests/CardCarouselControls.test.jsx +6 -4
- package/src/Card/_variables.scss +3 -2
- package/src/Card/index.scss +10 -9
- package/src/Chip/index.tsx +1 -0
- package/src/Collapsible/Collapsible.test.jsx +15 -7
- package/src/ColorPicker/ColorPicker.test.jsx +9 -16
- package/src/ColorPicker/index.jsx +1 -1
- package/src/ColorPicker/index.scss +2 -1
- package/src/DataTable/CollapsibleButtonGroup.jsx +2 -2
- package/src/DataTable/DropdownFilters.jsx +1 -1
- package/src/DataTable/dataviews.mdx +1 -8
- package/src/DataTable/index.scss +14 -13
- package/src/DataTable/selection/tests/ControlledSelectHeader.test.jsx +6 -4
- package/src/DataTable/tests/BulkActions.test.jsx +2 -4
- package/src/DataTable/tests/DataViewToggle.test.jsx +3 -7
- package/src/DataTable/tests/DropdownFilters.test.jsx +1 -1
- package/src/DataTable/tests/TableActions.test.jsx +1 -1
- package/src/Dropdown/_variables.scss +2 -1
- package/src/Dropdown/deprecated/Dropdown.test.jsx +43 -27
- package/src/Dropzone/README.md +3 -3
- package/src/Dropzone/index.scss +3 -2
- package/src/Dropzone/tests/__snapshots__/Dropzone.test.jsx.snap +10 -1
- package/src/Form/FormAutosuggest.jsx +1 -1
- package/src/Form/FormGroupContext.tsx +1 -1
- package/src/Form/_index.scss +9 -7
- package/src/Form/_variables.scss +4 -2
- package/src/Form/tests/FormAutosuggest.test.jsx +76 -57
- package/src/Form/tests/FormCheckboxSet.test.jsx +3 -2
- package/src/Form/tests/FormControl.test.jsx +9 -6
- package/src/Form/tests/FormRadioSet.test.jsx +3 -2
- package/src/Hyperlink/Hyperlink.test.tsx +50 -20
- package/src/Hyperlink/README.md +14 -1
- package/src/Hyperlink/index.scss +3 -1
- package/src/Hyperlink/index.tsx +71 -30
- package/src/IconButtonToggle/IconButtonToggle.test.jsx +3 -2
- package/src/IconButtonToggle/index.scss +3 -1
- package/src/ListBox/ListBox.test.jsx +8 -4
- package/src/MailtoLink/MailtoLink.test.jsx +12 -3
- package/src/Menu/Menu.test.jsx +27 -19
- package/src/Menu/SelectMenu.jsx +1 -1
- package/src/Menu/SelectMenu.test.jsx +35 -16
- package/src/Menu/__snapshots__/Menu.test.jsx.snap +0 -1
- package/src/Menu/index.jsx +1 -1
- package/src/Modal/ModalDialogBody.jsx +1 -1
- package/src/Modal/_ModalDialog.scss +3 -1
- package/src/Modal/index.jsx +2 -0
- package/src/Modal/index.scss +3 -5
- package/src/Modal/tests/ModalLayer.test.tsx +3 -2
- package/src/Nav/_mixins.scss +3 -1
- package/src/OverflowScroll/data/tests/useOverflowScroll.test.jsx +1 -2
- package/src/OverflowScroll/data/tests/useOverflowScrollActions.test.jsx +1 -1
- package/src/OverflowScroll/data/tests/useOverflowScrollElementAttributes.test.jsx +1 -1
- package/src/OverflowScroll/data/tests/useOverflowScrollEventListeners.test.jsx +1 -2
- package/src/PageBanner/index.scss +2 -1
- package/src/Pagination/Pagination.test.jsx +36 -28
- package/src/Popover/_variables.scss +2 -1
- package/src/ProductTour/Checkpoint.scss +9 -8
- package/src/ProductTour/Checkpoint.test.jsx +3 -2
- package/src/ProductTour/ProductTour.test.jsx +11 -24
- package/src/ProductTour/index.jsx +1 -1
- package/src/Scrollable/Scrollable.test.jsx +2 -2
- package/src/Scrollable/index.jsx +1 -1
- package/src/SearchField/index.scss +2 -1
- package/src/SelectableBox/tests/SelectableBox.test.jsx +3 -2
- package/src/StatusAlert/StatusAlert.test.jsx +6 -2
- package/src/Stepper/StepperHeader.jsx +1 -1
- package/src/Stepper/tests/Stepper.test.jsx +1 -1
- package/src/Table/_variables.scss +2 -1
- package/src/Tabs/Tabs.test.jsx +1 -1
- package/src/Tabs/deprecated/Tabs.test.jsx +6 -4
- package/src/Tabs/index.jsx +1 -1
- package/src/Toast/ToastContainer.scss +1 -1
- package/src/Toast/index.scss +2 -2
- package/src/Truncate/index.jsx +1 -1
- package/src/hooks/tests/useToggle.test.tsx +1 -1
- package/src/hooks/{useArrowKeyNavigation.tsx → useArrowKeyNavigationHook.tsx} +4 -0
- package/src/hooks/{useIndexOfLastVisibleChild.tsx → useIndexOfLastVisibleChildHook.tsx} +4 -0
- package/src/hooks/{useToggle.tsx → useToggleHook.tsx} +4 -0
- package/src/index.d.ts +6 -6
- package/src/index.js +6 -6
- package/dist/hooks/useArrowKeyNavigation.js.map +0 -1
- package/dist/hooks/useIndexOfLastVisibleChild.js.map +0 -1
- package/dist/hooks/useIsVisible.js.map +0 -1
- package/dist/hooks/useToggle.js.map +0 -1
- package/dist/hooks/useWindowSize.js.map +0 -1
- package/src/DataTable/tests/utils.js +0 -9
- /package/dist/hooks/{useArrowKeyNavigation.d.ts → useArrowKeyNavigationHook.d.ts} +0 -0
- /package/dist/hooks/{useIndexOfLastVisibleChild.d.ts → useIndexOfLastVisibleChildHook.d.ts} +0 -0
- /package/dist/hooks/{useIsVisible.d.ts → useIsVisibleHook.d.ts} +0 -0
- /package/dist/hooks/{useToggle.d.ts → useToggleHook.d.ts} +0 -0
- /package/dist/hooks/{useWindowSize.d.ts → useWindowSizeHook.d.ts} +0 -0
- /package/src/hooks/{useIsVisible.tsx → useIsVisibleHook.tsx} +0 -0
- /package/src/hooks/{useWindowSize.tsx → useWindowSizeHook.tsx} +0 -0
package/src/Hyperlink/index.tsx
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import classNames from 'classnames';
|
|
4
|
+
import {
|
|
5
|
+
type BsPrefixRefForwardingComponent as ComponentWithAsProp,
|
|
6
|
+
type BsPrefixProps,
|
|
7
|
+
} from 'react-bootstrap/esm/helpers';
|
|
8
|
+
import { defineMessages, useIntl } from 'react-intl';
|
|
4
9
|
import { Launch } from '../../icons';
|
|
5
10
|
import Icon from '../Icon';
|
|
11
|
+
// @ts-ignore
|
|
12
|
+
import { customPropTypeRequirement } from '../utils/propTypes/utils';
|
|
6
13
|
|
|
7
|
-
export
|
|
8
|
-
export const HYPER_LINK_EXTERNAL_LINK_TITLE = 'Opens in a new tab';
|
|
9
|
-
|
|
10
|
-
interface Props extends Omit<React.ComponentPropsWithRef<'a'>, 'href' | 'target'> {
|
|
14
|
+
export interface HyperlinkProps extends BsPrefixProps, Omit<React.ComponentPropsWithRef<'a'>, 'href' | 'target'> {
|
|
11
15
|
/** specifies the URL */
|
|
12
|
-
destination
|
|
16
|
+
destination?: string;
|
|
13
17
|
/** Content of the hyperlink */
|
|
14
18
|
children: React.ReactNode;
|
|
15
19
|
/** Custom class names for the hyperlink */
|
|
@@ -24,22 +28,42 @@ interface Props extends Omit<React.ComponentPropsWithRef<'a'>, 'href' | 'target'
|
|
|
24
28
|
isInline?: boolean;
|
|
25
29
|
/** specify if we need to show launch Icon. By default, it will be visible. */
|
|
26
30
|
showLaunchIcon?: boolean;
|
|
31
|
+
/** specifies where the link should open. The default behavior is `_self`, which means that the URL will be
|
|
32
|
+
* loaded into the same browsing context as the current one.
|
|
33
|
+
* If the target is `_blank` (opening a new window) `rel='noopener'` will be added to the anchor tag to prevent
|
|
34
|
+
* any potential [reverse tabnabbing attack](https://www.owasp.org/index.php/Reverse_Tabnabbing).
|
|
35
|
+
*/
|
|
27
36
|
target?: '_blank' | '_self';
|
|
28
37
|
}
|
|
29
38
|
|
|
30
|
-
|
|
39
|
+
export type HyperlinkType = ComponentWithAsProp<'a', HyperlinkProps>;
|
|
40
|
+
|
|
41
|
+
const messages = defineMessages({
|
|
42
|
+
externalLinkAltText: {
|
|
43
|
+
id: 'Hyperlink.externalLinkAltText',
|
|
44
|
+
defaultMessage: 'in a new tab',
|
|
45
|
+
},
|
|
46
|
+
externalLinkTitle: {
|
|
47
|
+
id: 'Hyperlink.externalLinkTitle',
|
|
48
|
+
defaultMessage: 'Opens in a new tab',
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const Hyperlink = forwardRef<HTMLAnchorElement, HyperlinkProps>(({
|
|
53
|
+
as: Component = 'a',
|
|
31
54
|
className,
|
|
32
55
|
destination,
|
|
33
56
|
children,
|
|
34
|
-
target,
|
|
57
|
+
target = '_self',
|
|
35
58
|
onClick,
|
|
36
59
|
externalLinkAlternativeText,
|
|
37
60
|
externalLinkTitle,
|
|
38
|
-
variant,
|
|
39
|
-
isInline,
|
|
40
|
-
showLaunchIcon,
|
|
61
|
+
variant = 'default',
|
|
62
|
+
isInline = false,
|
|
63
|
+
showLaunchIcon = true,
|
|
41
64
|
...attrs
|
|
42
65
|
}, ref) => {
|
|
66
|
+
const intl = useIntl();
|
|
43
67
|
let externalLinkIcon;
|
|
44
68
|
|
|
45
69
|
if (target === '_blank') {
|
|
@@ -63,11 +87,11 @@ const Hyperlink = React.forwardRef<HTMLAnchorElement, Props>(({
|
|
|
63
87
|
externalLinkIcon = (
|
|
64
88
|
<span
|
|
65
89
|
className="pgn__hyperlink__external-icon"
|
|
66
|
-
title={externalLinkTitle}
|
|
90
|
+
title={externalLinkTitle || intl.formatMessage(messages.externalLinkTitle)}
|
|
67
91
|
>
|
|
68
92
|
<Icon
|
|
69
93
|
src={Launch}
|
|
70
|
-
screenReaderText={externalLinkAlternativeText}
|
|
94
|
+
screenReaderText={externalLinkAlternativeText || intl.formatMessage(messages.externalLinkAltText)}
|
|
71
95
|
style={{ height: '1em', width: '1em' }}
|
|
72
96
|
data-testid="hyperlink-icon"
|
|
73
97
|
/>
|
|
@@ -76,8 +100,13 @@ const Hyperlink = React.forwardRef<HTMLAnchorElement, Props>(({
|
|
|
76
100
|
}
|
|
77
101
|
}
|
|
78
102
|
|
|
103
|
+
const additionalProps: Record<string, any> = { ...attrs };
|
|
104
|
+
if (destination) {
|
|
105
|
+
additionalProps.href = destination;
|
|
106
|
+
}
|
|
107
|
+
|
|
79
108
|
return (
|
|
80
|
-
<
|
|
109
|
+
<Component
|
|
81
110
|
ref={ref}
|
|
82
111
|
className={classNames(
|
|
83
112
|
'pgn__hyperlink',
|
|
@@ -88,32 +117,29 @@ const Hyperlink = React.forwardRef<HTMLAnchorElement, Props>(({
|
|
|
88
117
|
},
|
|
89
118
|
className,
|
|
90
119
|
)}
|
|
91
|
-
href={destination}
|
|
92
120
|
target={target}
|
|
93
121
|
onClick={onClick}
|
|
94
|
-
{...
|
|
122
|
+
{...additionalProps}
|
|
95
123
|
>
|
|
96
124
|
{children}
|
|
97
125
|
{externalLinkIcon}
|
|
98
|
-
</
|
|
126
|
+
</Component>
|
|
99
127
|
);
|
|
100
128
|
});
|
|
101
129
|
|
|
102
|
-
Hyperlink.defaultProps = {
|
|
103
|
-
className: undefined,
|
|
104
|
-
target: '_self',
|
|
105
|
-
onClick: () => {},
|
|
106
|
-
externalLinkAlternativeText: HYPER_LINK_EXTERNAL_LINK_ALT_TEXT,
|
|
107
|
-
externalLinkTitle: HYPER_LINK_EXTERNAL_LINK_TITLE,
|
|
108
|
-
variant: 'default',
|
|
109
|
-
isInline: false,
|
|
110
|
-
showLaunchIcon: true,
|
|
111
|
-
};
|
|
112
|
-
|
|
113
130
|
Hyperlink.propTypes = {
|
|
114
|
-
/** specifies the
|
|
115
|
-
|
|
131
|
+
/** specifies the component element type to render for the hyperlink */
|
|
132
|
+
// @ts-ignore
|
|
133
|
+
as: PropTypes.elementType,
|
|
134
|
+
/** specifies the URL; required iff `as` prop is a standard anchor tag */
|
|
135
|
+
destination: customPropTypeRequirement(
|
|
136
|
+
PropTypes.string,
|
|
137
|
+
({ as }: { as: React.ElementType }) => as && as === 'a',
|
|
138
|
+
// "[`destination` is required when]..."
|
|
139
|
+
'the `as` prop is a standard anchor element (i.e., "a")',
|
|
140
|
+
),
|
|
116
141
|
/** Content of the hyperlink */
|
|
142
|
+
// @ts-ignore
|
|
117
143
|
children: PropTypes.node.isRequired,
|
|
118
144
|
/** Custom class names for the hyperlink */
|
|
119
145
|
className: PropTypes.string,
|
|
@@ -137,4 +163,19 @@ Hyperlink.propTypes = {
|
|
|
137
163
|
showLaunchIcon: PropTypes.bool,
|
|
138
164
|
};
|
|
139
165
|
|
|
166
|
+
Hyperlink.defaultProps = {
|
|
167
|
+
as: 'a',
|
|
168
|
+
className: undefined,
|
|
169
|
+
destination: undefined,
|
|
170
|
+
externalLinkAlternativeText: undefined,
|
|
171
|
+
externalLinkTitle: undefined,
|
|
172
|
+
isInline: false,
|
|
173
|
+
onClick: undefined,
|
|
174
|
+
showLaunchIcon: true,
|
|
175
|
+
target: '_self',
|
|
176
|
+
variant: 'default',
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
Hyperlink.displayName = 'Hyperlink';
|
|
180
|
+
|
|
140
181
|
export default Hyperlink;
|
|
@@ -21,7 +21,8 @@ describe('IconButtonToggle tests', () => {
|
|
|
21
21
|
expect(btnAbc).toHaveClass('btn-icon-primary-active');
|
|
22
22
|
expect(btnAbc).toHaveAttribute('aria-selected', 'true');
|
|
23
23
|
});
|
|
24
|
-
test('switching activeValue works as expected', () => {
|
|
24
|
+
test('switching activeValue works as expected', async () => {
|
|
25
|
+
const user = userEvent.setup();
|
|
25
26
|
const spyChanger = jest.fn();
|
|
26
27
|
render(
|
|
27
28
|
<IconButtonToggle activeValue="abc" onChange={spyChanger}>
|
|
@@ -38,7 +39,7 @@ describe('IconButtonToggle tests', () => {
|
|
|
38
39
|
expect(btnAbc).toHaveClass('btn-icon-primary-active');
|
|
39
40
|
expect(btnAbc).toHaveAttribute('aria-selected', 'true');
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
await user.click(btnDef);
|
|
42
43
|
|
|
43
44
|
waitFor(() => {
|
|
44
45
|
expect(btnDef).toHaveClass('btn-icon-primary-active');
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import { render, screen, waitFor } from '@testing-library/react';
|
|
3
3
|
import userEvent from '@testing-library/user-event';
|
|
4
4
|
|
|
5
5
|
import ListBox from '.';
|
|
@@ -82,15 +82,18 @@ describe('ListBox', () => {
|
|
|
82
82
|
|
|
83
83
|
listBoxElement.focus();
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
await waitFor(() => {
|
|
86
|
+
expect(listBoxElement.getAttribute('aria-activedescendant')).toEqual('list-box-option-0');
|
|
87
|
+
});
|
|
86
88
|
});
|
|
87
89
|
|
|
88
90
|
it('should not select first ListBoxOption on focus if ListBoxOption selected', async () => {
|
|
91
|
+
const user = userEvent.setup();
|
|
89
92
|
const listBoxElement = screen.getByRole('listbox');
|
|
90
93
|
|
|
91
94
|
listBoxElement.focus();
|
|
92
95
|
|
|
93
|
-
await
|
|
96
|
+
await user.keyboard('{arrowdown}');
|
|
94
97
|
|
|
95
98
|
listBoxElement.focus();
|
|
96
99
|
|
|
@@ -98,11 +101,12 @@ describe('ListBox', () => {
|
|
|
98
101
|
});
|
|
99
102
|
|
|
100
103
|
it('should select next ListBoxOption on down arrow key', async () => {
|
|
104
|
+
const user = userEvent.setup();
|
|
101
105
|
const listBoxElement = screen.getByRole('listbox');
|
|
102
106
|
|
|
103
107
|
listBoxElement.focus();
|
|
104
108
|
|
|
105
|
-
await
|
|
109
|
+
await user.keyboard('{arrowdown}');
|
|
106
110
|
|
|
107
111
|
expect(listBoxElement.getAttribute('aria-activedescendant')).toEqual('list-box-option-1');
|
|
108
112
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { render } from '@testing-library/react';
|
|
3
|
+
import { IntlProvider } from 'react-intl';
|
|
3
4
|
|
|
4
5
|
import MailtoLink from '.';
|
|
5
6
|
|
|
@@ -11,10 +12,18 @@ const content = 'content';
|
|
|
11
12
|
|
|
12
13
|
const baseProps = { subject, body, content };
|
|
13
14
|
|
|
15
|
+
function MailtoLinkWrapper(props) {
|
|
16
|
+
return (
|
|
17
|
+
<IntlProvider locale="en">
|
|
18
|
+
<MailtoLink {...props} />
|
|
19
|
+
</IntlProvider>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
14
23
|
describe('correct rendering', () => {
|
|
15
24
|
it('renders MailtoLink with single to, cc, and bcc recipient', () => {
|
|
16
25
|
const singleRecipientLink = (
|
|
17
|
-
<
|
|
26
|
+
<MailtoLinkWrapper
|
|
18
27
|
{...baseProps}
|
|
19
28
|
to={emailAddress}
|
|
20
29
|
cc={emailAddress}
|
|
@@ -31,7 +40,7 @@ describe('correct rendering', () => {
|
|
|
31
40
|
|
|
32
41
|
it('renders mailtoLink with many to, cc, and bcc recipients', () => {
|
|
33
42
|
const multiRecipientLink = (
|
|
34
|
-
<
|
|
43
|
+
<MailtoLinkWrapper
|
|
35
44
|
{...baseProps}
|
|
36
45
|
to={emailAddresses}
|
|
37
46
|
cc={emailAddresses}
|
|
@@ -46,7 +55,7 @@ describe('correct rendering', () => {
|
|
|
46
55
|
});
|
|
47
56
|
|
|
48
57
|
it('renders empty mailtoLink', () => {
|
|
49
|
-
const { getByText } = render(<
|
|
58
|
+
const { getByText } = render(<MailtoLinkWrapper content={content} />);
|
|
50
59
|
const linkElement = getByText('content');
|
|
51
60
|
expect(linkElement.getAttribute('href')).toEqual('mailto:');
|
|
52
61
|
});
|
package/src/Menu/Menu.test.jsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { IntlProvider } from 'react-intl';
|
|
2
3
|
import { render, screen } from '@testing-library/react';
|
|
3
4
|
import renderer from 'react-test-renderer';
|
|
4
5
|
import userEvent from '@testing-library/user-event';
|
|
@@ -20,15 +21,17 @@ describe('Menu Item renders correctly', () => {
|
|
|
20
21
|
|
|
21
22
|
it('renders as expected with menu items', () => {
|
|
22
23
|
const tree = renderer.create((
|
|
23
|
-
<
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
<IntlProvider locale="en">
|
|
25
|
+
<Menu>
|
|
26
|
+
<MenuItem> A Menu Item</MenuItem>
|
|
27
|
+
<MenuItem iconBefore={Add} stoven>A Menu Item With an Icon Before</MenuItem>
|
|
28
|
+
<MenuItem iconAfter={Check}>A Menu Item With an Icon After </MenuItem>
|
|
29
|
+
<MenuItem disabled>A Disabled Menu Item</MenuItem>
|
|
30
|
+
<MenuItem as={Hyperlink} destination="https://en.wikipedia.org/wiki/Hyperlink">A Link Menu Item</MenuItem>
|
|
31
|
+
<MenuItem as={Button} variant="primary" size="inline">A Button Menu Item</MenuItem>
|
|
32
|
+
<MenuItem as={Form.Checkbox}>A Checkbox Menu Item</MenuItem>
|
|
33
|
+
</Menu>
|
|
34
|
+
</IntlProvider>
|
|
32
35
|
)).toJSON();
|
|
33
36
|
expect(tree).toMatchSnapshot();
|
|
34
37
|
});
|
|
@@ -71,48 +74,53 @@ describe('Keyboard Interactions', () => {
|
|
|
71
74
|
expect(defaultItem).toHaveFocus();
|
|
72
75
|
});
|
|
73
76
|
|
|
74
|
-
it('should focus the next item after ArrowDown keyDown', () => {
|
|
77
|
+
it('should focus the next item after ArrowDown keyDown', async () => {
|
|
78
|
+
const user = userEvent.setup();
|
|
75
79
|
const defaultItem = screen.getByText('Default');
|
|
76
80
|
const cantTouchThisItem = screen.getByText(MENU_ITEM_TEXT).parentElement;
|
|
77
81
|
|
|
78
|
-
|
|
82
|
+
await user.type(defaultItem, '{arrowdown}');
|
|
79
83
|
|
|
80
84
|
expect(cantTouchThisItem).toHaveFocus();
|
|
81
85
|
});
|
|
82
86
|
|
|
83
|
-
it('should focus the next item after Tab keyDown', () => {
|
|
87
|
+
it('should focus the next item after Tab keyDown', async () => {
|
|
88
|
+
const user = userEvent.setup();
|
|
84
89
|
const defaultItem = screen.getByText('Default').parentElement;
|
|
85
90
|
const cantTouchThisItem = screen.getByText(MENU_ITEM_TEXT).parentElement;
|
|
86
91
|
defaultItem.focus();
|
|
87
|
-
|
|
92
|
+
await user.tab();
|
|
88
93
|
|
|
89
94
|
expect(cantTouchThisItem).toHaveFocus();
|
|
90
95
|
});
|
|
91
96
|
|
|
92
|
-
it('should loop focus to the first item after Tab keyDown on last item', () => {
|
|
97
|
+
it('should loop focus to the first item after Tab keyDown on last item', async () => {
|
|
98
|
+
const user = userEvent.setup();
|
|
93
99
|
const defaultItem = screen.getByText('Default').parentElement;
|
|
94
100
|
const iconBeforeItem = screen.getByText('Icon Before');
|
|
95
101
|
iconBeforeItem.focus();
|
|
96
|
-
|
|
102
|
+
await user.tab();
|
|
97
103
|
|
|
98
104
|
expect(defaultItem).toHaveFocus();
|
|
99
105
|
});
|
|
100
106
|
|
|
101
|
-
it('should loop focus to the last item after ArrowUp keyDown on first item', () => {
|
|
107
|
+
it('should loop focus to the last item after ArrowUp keyDown on first item', async () => {
|
|
108
|
+
const user = userEvent.setup();
|
|
102
109
|
const defaultItem = screen.getByText('Default').parentElement;
|
|
103
110
|
const iconBeforeItem = screen.getByText('Icon Before').parentElement;
|
|
104
111
|
defaultItem.focus();
|
|
105
|
-
|
|
112
|
+
await user.type(defaultItem, '{arrowup}');
|
|
106
113
|
|
|
107
114
|
expect(iconBeforeItem).toHaveFocus();
|
|
108
115
|
});
|
|
109
116
|
|
|
110
|
-
it('should focus the previous item after Shift + Tab keyDown', () => {
|
|
117
|
+
it('should focus the previous item after Shift + Tab keyDown', async () => {
|
|
118
|
+
const user = userEvent.setup();
|
|
111
119
|
const button1 = screen.getAllByRole('button')[0];
|
|
112
120
|
const button2 = screen.getAllByRole('button')[1];
|
|
113
121
|
|
|
114
122
|
button2.focus();
|
|
115
|
-
|
|
123
|
+
await user.tab({ shift: true });
|
|
116
124
|
|
|
117
125
|
expect(button1).toHaveFocus();
|
|
118
126
|
});
|
package/src/Menu/SelectMenu.jsx
CHANGED
|
@@ -4,7 +4,7 @@ import classNames from 'classnames';
|
|
|
4
4
|
import { ExpandMore } from '../../icons';
|
|
5
5
|
import Button from '../Button';
|
|
6
6
|
import ModalPopup from '../Modal/ModalPopup';
|
|
7
|
-
import useToggle from '../hooks/
|
|
7
|
+
import useToggle from '../hooks/useToggleHook';
|
|
8
8
|
import Menu from '.';
|
|
9
9
|
import withDeprecatedProps, { DeprTypes } from '../withDeprecatedProps';
|
|
10
10
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { IntlProvider } from 'react-intl';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
2
4
|
import { render, screen } from '@testing-library/react';
|
|
3
5
|
import renderer from 'react-test-renderer';
|
|
4
6
|
import userEvent from '@testing-library/user-event';
|
|
@@ -10,27 +12,44 @@ import Hyperlink from '../Hyperlink';
|
|
|
10
12
|
const app = document.createElement('div');
|
|
11
13
|
document.body.appendChild(app);
|
|
12
14
|
|
|
15
|
+
function SelectMenuWrapper({ children }) {
|
|
16
|
+
return (
|
|
17
|
+
<IntlProvider locale="en">
|
|
18
|
+
{children}
|
|
19
|
+
</IntlProvider>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
SelectMenuWrapper.propTypes = {
|
|
23
|
+
children: PropTypes.node.isRequired,
|
|
24
|
+
};
|
|
25
|
+
|
|
13
26
|
function DefaultSelectMenu(props) {
|
|
14
|
-
return
|
|
27
|
+
return (
|
|
28
|
+
<SelectMenuWrapper>
|
|
29
|
+
<SelectMenu {...props}><MenuItem>A Menu Item</MenuItem></SelectMenu>
|
|
30
|
+
</SelectMenuWrapper>
|
|
31
|
+
);
|
|
15
32
|
}
|
|
16
33
|
|
|
17
34
|
function defaultSelectMenu() {
|
|
18
35
|
return (
|
|
19
|
-
<
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
36
|
+
<SelectMenuWrapper>
|
|
37
|
+
<SelectMenu>
|
|
38
|
+
<MenuItem>A Menu Item</MenuItem>
|
|
39
|
+
<MenuItem iconBefore={Add}>A Menu Item With an Icon Before</MenuItem>
|
|
40
|
+
<MenuItem iconAfter={Check}>A Menu Item With an Icon After </MenuItem>
|
|
41
|
+
<MenuItem disabled>A Disabled Menu Item</MenuItem>
|
|
42
|
+
<MenuItem as={Hyperlink} destination="https://en.wikipedia.org/wiki/Hyperlink">A Link Menu Item</MenuItem>
|
|
43
|
+
<MenuItem>Falstaff</MenuItem>
|
|
44
|
+
<MenuItem>Scipio</MenuItem>
|
|
45
|
+
<MenuItem>Faustus</MenuItem>
|
|
46
|
+
<MenuItem>Cordelia</MenuItem>
|
|
47
|
+
<MenuItem>Renfrancine</MenuItem>
|
|
48
|
+
<MenuItem>Stovern</MenuItem>
|
|
49
|
+
<MenuItem>Kainian</MenuItem>
|
|
50
|
+
<MenuItem>M. Hortens</MenuItem>
|
|
51
|
+
</SelectMenu>
|
|
52
|
+
</SelectMenuWrapper>
|
|
34
53
|
);
|
|
35
54
|
}
|
|
36
55
|
|
|
@@ -95,7 +95,6 @@ exports[`Menu Item renders correctly renders as expected with menu items 1`] = `
|
|
|
95
95
|
<a
|
|
96
96
|
className="pgn__hyperlink default-link standalone-link pgn__menu-item"
|
|
97
97
|
href="https://en.wikipedia.org/wiki/Hyperlink"
|
|
98
|
-
onClick={[Function]}
|
|
99
98
|
target="_self"
|
|
100
99
|
>
|
|
101
100
|
<span
|
package/src/Menu/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 useArrowKeyNavigation from '../hooks/
|
|
4
|
+
import useArrowKeyNavigation from '../hooks/useArrowKeyNavigationHook';
|
|
5
5
|
|
|
6
6
|
function Menu({
|
|
7
7
|
as,
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
@use "sass:map";
|
|
2
|
+
|
|
1
3
|
.pgn__modal {
|
|
2
4
|
background: $modal-content-bg;
|
|
3
5
|
border-radius: $modal-content-inner-border-radius;
|
|
@@ -315,7 +317,7 @@
|
|
|
315
317
|
|
|
316
318
|
.pgn__alert-modal__title_icon {
|
|
317
319
|
flex-shrink: 0;
|
|
318
|
-
margin-right: map
|
|
320
|
+
margin-right: map.get($spacers, 2\.5);
|
|
319
321
|
}
|
|
320
322
|
}
|
|
321
323
|
}
|
package/src/Modal/index.jsx
CHANGED
|
@@ -50,6 +50,8 @@ class Modal extends React.Component {
|
|
|
50
50
|
|
|
51
51
|
componentWillUnmount() {
|
|
52
52
|
if (this.parentElement) {
|
|
53
|
+
// TODO: update this to use the new createRoot() compatible APIs.
|
|
54
|
+
// eslint-disable-next-line react/no-deprecated
|
|
53
55
|
ReactDOM.unmountComponentAtNode(this.parentElement);
|
|
54
56
|
}
|
|
55
57
|
}
|
package/src/Modal/index.scss
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
@use "sass:map";
|
|
1
2
|
@import "variables";
|
|
2
3
|
@import "~bootstrap/scss/modal";
|
|
3
4
|
@import "ModalDialog";
|
|
@@ -19,12 +20,9 @@
|
|
|
19
20
|
|
|
20
21
|
.pgn__modal-backdrop {
|
|
21
22
|
background: $modal-backdrop-bg;
|
|
22
|
-
|
|
23
|
-
left: 0;
|
|
23
|
+
inset: 0;
|
|
24
24
|
opacity: $modal-backdrop-opacity;
|
|
25
25
|
position: fixed;
|
|
26
|
-
right: 0;
|
|
27
|
-
top: 0;
|
|
28
26
|
z-index: 0;
|
|
29
27
|
}
|
|
30
28
|
|
|
@@ -88,7 +86,7 @@
|
|
|
88
86
|
margin: auto;
|
|
89
87
|
padding: calc($spacer / 2);
|
|
90
88
|
|
|
91
|
-
@media (min-width: map
|
|
89
|
+
@media (min-width: map.get($grid-breakpoints, "sm")) {
|
|
92
90
|
padding: $spacer;
|
|
93
91
|
}
|
|
94
92
|
}
|
|
@@ -78,7 +78,8 @@ describe('<ModalLayer />', () => {
|
|
|
78
78
|
});
|
|
79
79
|
|
|
80
80
|
describe('Dismiss modal', () => {
|
|
81
|
-
it('closes a non-blocking modal layer when backdrop is clicked', () => {
|
|
81
|
+
it('closes a non-blocking modal layer when backdrop is clicked', async () => {
|
|
82
|
+
const user = userEvent.setup();
|
|
82
83
|
const closeFn = jest.fn();
|
|
83
84
|
render(
|
|
84
85
|
<ModalLayer isOpen onClose={closeFn} isBlocking={false}>
|
|
@@ -86,7 +87,7 @@ describe('<ModalLayer />', () => {
|
|
|
86
87
|
</ModalLayer>,
|
|
87
88
|
);
|
|
88
89
|
const backdrop = screen.getByTestId('modal-backdrop');
|
|
89
|
-
|
|
90
|
+
await user.click(backdrop);
|
|
90
91
|
expect(closeFn).toHaveBeenCalled();
|
|
91
92
|
});
|
|
92
93
|
|
package/src/Nav/_mixins.scss
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
@use "sass:map";
|
|
2
|
+
|
|
1
3
|
@mixin nav-tabs-link-focus(
|
|
2
4
|
$border-color,
|
|
3
5
|
$radius: $nav-tabs-border-radius,
|
|
@@ -5,7 +7,7 @@
|
|
|
5
7
|
) {
|
|
6
8
|
position: relative;
|
|
7
9
|
outline: 0;
|
|
8
|
-
z-index: map
|
|
10
|
+
z-index: map.get($map: $indexes, $key: 1);
|
|
9
11
|
|
|
10
12
|
&::before {
|
|
11
13
|
content: "";
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { renderHook } from '@testing-library/react
|
|
3
|
-
import { act } from '@testing-library/react';
|
|
2
|
+
import { act, renderHook } from '@testing-library/react';
|
|
4
3
|
import useOverflowScroll from '../useOverflowScroll';
|
|
5
4
|
import useOverflowScrollActions from '../useOverflowScrollActions';
|
|
6
5
|
import getChildrenElements from '../getChildrenElements';
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { renderHook } from '@testing-library/react
|
|
2
|
-
import { act } from '@testing-library/react';
|
|
1
|
+
import { act, renderHook } from '@testing-library/react';
|
|
3
2
|
import useOverflowScrollEventListeners from '../useOverflowScrollEventListeners';
|
|
4
3
|
|
|
5
4
|
const divElement = document.createElement('div');
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
@use "sass:map";
|
|
1
2
|
// stylelint-disable-next-line selector-class-pattern
|
|
2
3
|
.pgn__pageBanner-component {
|
|
3
4
|
width: 100%;
|
|
@@ -46,7 +47,7 @@
|
|
|
46
47
|
flex-grow: 1;
|
|
47
48
|
justify-content: center;
|
|
48
49
|
align-items: center;
|
|
49
|
-
padding:
|
|
50
|
+
padding: map.get($spacers, 2) map.get($spacers, 2\.5);
|
|
50
51
|
text-align: center;
|
|
51
52
|
}
|
|
52
53
|
|