@conduction/components 2.2.55 → 2.2.57
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/README.md +6 -0
- package/lib/components/Pagination/Pagination.js +1 -1
- package/lib/components/card/cardWrapper/CardWrapper.js +13 -1
- package/lib/components/formFields/select/select.js +25 -2
- package/lib/components/logo/Logo.js +7 -1
- package/package.json +1 -1
- package/src/components/Pagination/Pagination.tsx +87 -87
- package/src/components/card/cardWrapper/CardWrapper.tsx +14 -1
- package/src/components/formFields/select/select.tsx +34 -1
- package/src/components/logo/Logo.tsx +10 -1
package/README.md
CHANGED
|
@@ -4,10 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
- **Version 2.2 (breaking changes from 2.1.x)**
|
|
6
6
|
|
|
7
|
+
- 2.2.57:
|
|
8
|
+
- Fixed clear button on SelectSingle not being clickable with keyboard functions.
|
|
9
|
+
- Fixed Logo not being focusable when being clickable.
|
|
10
|
+
- Fixed CardWrapper not being clickable with keyboard functions
|
|
11
|
+
- 2.2.56: Fixed WCAG issue in Pagination by adding aria labels to buttons
|
|
7
12
|
- 2.2.55:
|
|
8
13
|
- Updated Logo to accept aria-label for accessibility.
|
|
9
14
|
- Fixed bug in DisplaySwitch where layoutClassName is added even when empty.
|
|
10
15
|
- Fixed color of the Select dropdown icon to be WCAG-AA compliant.
|
|
16
|
+
- Added more WCAG roles and support to Select box.
|
|
11
17
|
- 2.2.54: Updated CardHeader to allow padding-block-end on title.
|
|
12
18
|
- 2.2.53: Updated Pagination and PrimaryTopNav components to allow text-decorations and border-bottoms.
|
|
13
19
|
- 2.2.52: Added hover filter to Logo component.
|
|
@@ -31,5 +31,5 @@ export const Pagination = ({ totalPages, currentPage, setCurrentPage, ariaLabels
|
|
|
31
31
|
};
|
|
32
32
|
setRoleToPresentation('ul[role*="list"][class*="Pagination"]');
|
|
33
33
|
}, [ariaLabels.pagination]);
|
|
34
|
-
return (_jsx(ReactPaginate, { className: clsx(styles.container, layoutClassName && layoutClassName), disabledClassName: styles.disabled, activeClassName: styles.currentPage, onPageChange: (e) => setCurrentPage(e.selected + 1), forcePage: currentPage - 1, pageRangeDisplayed: 3, pageCount: totalPages, disableInitialCallback: true, marginPagesDisplayed: 2, breakLabel: "...", nextClassName: styles.next, previousClassName: styles.previous, nextAriaLabel: ariaLabels.nextPage, previousAriaLabel: ariaLabels.previousPage, ariaLabelBuilder: (currentPage) => `${ariaLabels.page} ${currentPage}`, nextLabel: _jsx(Button, { tabIndex: -1, className: styles.button, children: _jsx(FontAwesomeIcon, { icon: faChevronRight }) }), previousLabel: _jsx(Button, { tabIndex: -1, className: styles.button, children: _jsx(FontAwesomeIcon, { icon: faChevronLeft }) }) }));
|
|
34
|
+
return (_jsx(ReactPaginate, { className: clsx(styles.container, layoutClassName && layoutClassName), disabledClassName: styles.disabled, activeClassName: styles.currentPage, onPageChange: (e) => setCurrentPage(e.selected + 1), forcePage: currentPage - 1, pageRangeDisplayed: 3, pageCount: totalPages, disableInitialCallback: true, marginPagesDisplayed: 2, breakLabel: "...", nextClassName: styles.next, previousClassName: styles.previous, nextAriaLabel: ariaLabels.nextPage, previousAriaLabel: ariaLabels.previousPage, ariaLabelBuilder: (currentPage) => `${ariaLabels.page} ${currentPage}`, nextLabel: _jsx(Button, { tabIndex: -1, className: styles.button, "aria-label": ariaLabels.nextPage, children: _jsx(FontAwesomeIcon, { icon: faChevronRight }) }), previousLabel: _jsx(Button, { tabIndex: -1, className: styles.button, "aria-label": ariaLabels.previousPage, children: _jsx(FontAwesomeIcon, { icon: faChevronLeft }) }) }));
|
|
35
35
|
};
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import * as styles from "./CardWrapper.module.css";
|
|
3
3
|
export const CardWrapper = (props) => {
|
|
4
|
-
const
|
|
4
|
+
const handleKeyDown = (event) => {
|
|
5
|
+
if (props.onClick && (event.key === "Enter" || event.key === " ")) {
|
|
6
|
+
event.preventDefault();
|
|
7
|
+
props.onClick(event);
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
const _props = {
|
|
11
|
+
...props,
|
|
12
|
+
className: `${props.className} ${styles.container}`,
|
|
13
|
+
role: props.onClick ? "button" : undefined,
|
|
14
|
+
tabIndex: props.onClick ? 0 : undefined,
|
|
15
|
+
...(props.onClick && { onKeyDown: handleKeyDown }),
|
|
16
|
+
};
|
|
5
17
|
return _jsx("div", { ..._props, children: props.children });
|
|
6
18
|
};
|
|
@@ -3,7 +3,7 @@ import * as React from "react";
|
|
|
3
3
|
import * as styles from "./select.module.css";
|
|
4
4
|
import clsx from "clsx";
|
|
5
5
|
import CreatableSelect from "react-select/creatable";
|
|
6
|
-
import ReactSelect from "react-select";
|
|
6
|
+
import ReactSelect, { components } from "react-select";
|
|
7
7
|
import { Controller } from "react-hook-form";
|
|
8
8
|
import { ErrorMessage } from "../errorMessage/ErrorMessage";
|
|
9
9
|
const selectStyles = {
|
|
@@ -95,6 +95,29 @@ const setAttributes = () => {
|
|
|
95
95
|
});
|
|
96
96
|
}, 100);
|
|
97
97
|
};
|
|
98
|
+
// Custom ClearIndicator component that handles keyboard events for accessibility
|
|
99
|
+
const ClearIndicator = (props) => {
|
|
100
|
+
const { clearValue, innerProps, children } = props;
|
|
101
|
+
const handleKeyDown = (event) => {
|
|
102
|
+
if (event.key === " " || event.key === "Enter") {
|
|
103
|
+
event.preventDefault();
|
|
104
|
+
event.stopPropagation();
|
|
105
|
+
if (clearValue) {
|
|
106
|
+
clearValue();
|
|
107
|
+
}
|
|
108
|
+
if (innerProps?.onClick) {
|
|
109
|
+
innerProps.onClick(event);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
else if (innerProps?.onKeyDown) {
|
|
113
|
+
innerProps.onKeyDown(event);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
return (_jsx(components.ClearIndicator, { ...props, innerProps: {
|
|
117
|
+
...innerProps,
|
|
118
|
+
onKeyDown: handleKeyDown,
|
|
119
|
+
}, children: children }));
|
|
120
|
+
};
|
|
98
121
|
export const SelectMultiple = ({ id, name, options, errors, control, validation, defaultValue, disabled, hideErrorMessage, menuPlacement, placeholder, ariaLabel, }) => {
|
|
99
122
|
React.useEffect(() => {
|
|
100
123
|
setAttributes();
|
|
@@ -116,7 +139,7 @@ export const SelectSingle = ({ id, name, options, errors, control, validation, i
|
|
|
116
139
|
setAttributes();
|
|
117
140
|
}, []);
|
|
118
141
|
return (_jsx(Controller, { control, name, defaultValue, rules: validation, render: ({ field: { onChange, value } }) => {
|
|
119
|
-
return (_jsxs(_Fragment, { children: [_jsx(ReactSelect, { "aria-label": ariaLabel, inputId: id, value: value ?? "", className: clsx(styles.select, errors[name] && styles.error), isDisabled: disabled, options, onChange, errors, isClearable, menuPortalTarget: document.body, menuPlacement: menuPlacement, styles: selectStyles, placeholder: disabled ? "Disabled..." : placeholder ?? "Select one or more options...", formatGroupLabel: (group) => _jsx(GroupLabel, { group }) }), errors[name] && !hideErrorMessage && _jsx(ErrorMessage, { message: errors[name]?.message })] }));
|
|
142
|
+
return (_jsxs(_Fragment, { children: [_jsx(ReactSelect, { "aria-label": ariaLabel, inputId: id, value: value ?? "", className: clsx(styles.select, errors[name] && styles.error), isDisabled: disabled, options, onChange, errors, isClearable, menuPortalTarget: document.body, menuPlacement: menuPlacement, styles: selectStyles, placeholder: disabled ? "Disabled..." : placeholder ?? "Select one or more options...", formatGroupLabel: (group) => _jsx(GroupLabel, { group }), components: isClearable ? { ClearIndicator } : undefined }), errors[name] && !hideErrorMessage && _jsx(ErrorMessage, { message: errors[name]?.message })] }));
|
|
120
143
|
} }));
|
|
121
144
|
};
|
|
122
145
|
const GroupLabel = ({ group }) => {
|
|
@@ -2,8 +2,14 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import * as styles from "./Logo.module.css";
|
|
3
3
|
import clsx from "clsx";
|
|
4
4
|
export const Logo = ({ onClick, layoutClassName, variant = "header", ariaLabel = "logo" }) => {
|
|
5
|
+
const handleKeyDown = (event) => {
|
|
6
|
+
if (onClick && (event.key === "Enter" || event.key === " ")) {
|
|
7
|
+
event.preventDefault();
|
|
8
|
+
onClick();
|
|
9
|
+
}
|
|
10
|
+
};
|
|
5
11
|
return (_jsx("div", { className: clsx(styles.container, styles[variant], [
|
|
6
12
|
onClick && styles.clickable,
|
|
7
13
|
layoutClassName && layoutClassName,
|
|
8
|
-
]), role: "img", "aria-label": ariaLabel, onClick }));
|
|
14
|
+
]), role: onClick ? "button" : "img", "aria-label": ariaLabel, tabIndex: onClick ? 0 : undefined, onClick, ...(onClick && { onKeyDown: handleKeyDown }) }));
|
|
9
15
|
};
|
package/package.json
CHANGED
|
@@ -1,87 +1,87 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import * as styles from "./Pagination.module.css";
|
|
3
|
-
import clsx from "clsx";
|
|
4
|
-
|
|
5
|
-
import ReactPaginate from "react-paginate";
|
|
6
|
-
import { Button } from "@utrecht/component-library-react";
|
|
7
|
-
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
8
|
-
import { faChevronRight, faChevronLeft } from "@fortawesome/free-solid-svg-icons";
|
|
9
|
-
|
|
10
|
-
interface PaginationProps {
|
|
11
|
-
totalPages: number;
|
|
12
|
-
currentPage: number;
|
|
13
|
-
setCurrentPage: React.Dispatch<React.SetStateAction<number>>;
|
|
14
|
-
ariaLabels: {
|
|
15
|
-
pagination: string;
|
|
16
|
-
nextPage: string;
|
|
17
|
-
previousPage: string;
|
|
18
|
-
page: string;
|
|
19
|
-
};
|
|
20
|
-
layoutClassName?: string;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export const Pagination: React.FC<PaginationProps> = ({
|
|
24
|
-
totalPages,
|
|
25
|
-
currentPage,
|
|
26
|
-
setCurrentPage,
|
|
27
|
-
ariaLabels,
|
|
28
|
-
layoutClassName,
|
|
29
|
-
}) => {
|
|
30
|
-
if (totalPages < 1) return <></>; // no pages available
|
|
31
|
-
|
|
32
|
-
const setAttributes = (): void => {
|
|
33
|
-
const setRoleToPresentation = (selector: string) => {
|
|
34
|
-
document.querySelectorAll(selector).forEach((element) => {
|
|
35
|
-
if (element.getAttribute("role") !== "list") element.setAttribute("role", "list");
|
|
36
|
-
});
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
setRoleToPresentation('ul[role*="navigation"][class*="Pagination"][aria-label="Pagination"]');
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
React.useEffect(() => {
|
|
43
|
-
setAttributes();
|
|
44
|
-
}, []);
|
|
45
|
-
|
|
46
|
-
React.useEffect(() => {
|
|
47
|
-
const setRoleToPresentation = (selector: string) => {
|
|
48
|
-
document.querySelectorAll(selector).forEach((element) => {
|
|
49
|
-
if (element.getAttribute("aria-label") !== ariaLabels.pagination) {
|
|
50
|
-
element.setAttribute("aria-label", ariaLabels.pagination);
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
setRoleToPresentation('ul[role*="list"][class*="Pagination"]');
|
|
56
|
-
}, [ariaLabels.pagination]);
|
|
57
|
-
|
|
58
|
-
return (
|
|
59
|
-
<ReactPaginate
|
|
60
|
-
className={clsx(styles.container, layoutClassName && layoutClassName)}
|
|
61
|
-
disabledClassName={styles.disabled}
|
|
62
|
-
activeClassName={styles.currentPage}
|
|
63
|
-
onPageChange={(e: any) => setCurrentPage(e.selected + 1)}
|
|
64
|
-
forcePage={currentPage - 1}
|
|
65
|
-
pageRangeDisplayed={3}
|
|
66
|
-
pageCount={totalPages}
|
|
67
|
-
disableInitialCallback
|
|
68
|
-
marginPagesDisplayed={2}
|
|
69
|
-
breakLabel="..."
|
|
70
|
-
nextClassName={styles.next}
|
|
71
|
-
previousClassName={styles.previous}
|
|
72
|
-
nextAriaLabel={ariaLabels.nextPage}
|
|
73
|
-
previousAriaLabel={ariaLabels.previousPage}
|
|
74
|
-
ariaLabelBuilder={(currentPage) => `${ariaLabels.page} ${currentPage}`}
|
|
75
|
-
nextLabel={
|
|
76
|
-
<Button tabIndex={-1} className={styles.button}>
|
|
77
|
-
<FontAwesomeIcon icon={faChevronRight} />
|
|
78
|
-
</Button>
|
|
79
|
-
}
|
|
80
|
-
previousLabel={
|
|
81
|
-
<Button tabIndex={-1} className={styles.button}>
|
|
82
|
-
<FontAwesomeIcon icon={faChevronLeft} />
|
|
83
|
-
</Button>
|
|
84
|
-
}
|
|
85
|
-
/>
|
|
86
|
-
);
|
|
87
|
-
};
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as styles from "./Pagination.module.css";
|
|
3
|
+
import clsx from "clsx";
|
|
4
|
+
|
|
5
|
+
import ReactPaginate from "react-paginate";
|
|
6
|
+
import { Button } from "@utrecht/component-library-react";
|
|
7
|
+
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
8
|
+
import { faChevronRight, faChevronLeft } from "@fortawesome/free-solid-svg-icons";
|
|
9
|
+
|
|
10
|
+
interface PaginationProps {
|
|
11
|
+
totalPages: number;
|
|
12
|
+
currentPage: number;
|
|
13
|
+
setCurrentPage: React.Dispatch<React.SetStateAction<number>>;
|
|
14
|
+
ariaLabels: {
|
|
15
|
+
pagination: string;
|
|
16
|
+
nextPage: string;
|
|
17
|
+
previousPage: string;
|
|
18
|
+
page: string;
|
|
19
|
+
};
|
|
20
|
+
layoutClassName?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const Pagination: React.FC<PaginationProps> = ({
|
|
24
|
+
totalPages,
|
|
25
|
+
currentPage,
|
|
26
|
+
setCurrentPage,
|
|
27
|
+
ariaLabels,
|
|
28
|
+
layoutClassName,
|
|
29
|
+
}) => {
|
|
30
|
+
if (totalPages < 1) return <></>; // no pages available
|
|
31
|
+
|
|
32
|
+
const setAttributes = (): void => {
|
|
33
|
+
const setRoleToPresentation = (selector: string) => {
|
|
34
|
+
document.querySelectorAll(selector).forEach((element) => {
|
|
35
|
+
if (element.getAttribute("role") !== "list") element.setAttribute("role", "list");
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
setRoleToPresentation('ul[role*="navigation"][class*="Pagination"][aria-label="Pagination"]');
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
React.useEffect(() => {
|
|
43
|
+
setAttributes();
|
|
44
|
+
}, []);
|
|
45
|
+
|
|
46
|
+
React.useEffect(() => {
|
|
47
|
+
const setRoleToPresentation = (selector: string) => {
|
|
48
|
+
document.querySelectorAll(selector).forEach((element) => {
|
|
49
|
+
if (element.getAttribute("aria-label") !== ariaLabels.pagination) {
|
|
50
|
+
element.setAttribute("aria-label", ariaLabels.pagination);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
setRoleToPresentation('ul[role*="list"][class*="Pagination"]');
|
|
56
|
+
}, [ariaLabels.pagination]);
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<ReactPaginate
|
|
60
|
+
className={clsx(styles.container, layoutClassName && layoutClassName)}
|
|
61
|
+
disabledClassName={styles.disabled}
|
|
62
|
+
activeClassName={styles.currentPage}
|
|
63
|
+
onPageChange={(e: any) => setCurrentPage(e.selected + 1)}
|
|
64
|
+
forcePage={currentPage - 1}
|
|
65
|
+
pageRangeDisplayed={3}
|
|
66
|
+
pageCount={totalPages}
|
|
67
|
+
disableInitialCallback
|
|
68
|
+
marginPagesDisplayed={2}
|
|
69
|
+
breakLabel="..."
|
|
70
|
+
nextClassName={styles.next}
|
|
71
|
+
previousClassName={styles.previous}
|
|
72
|
+
nextAriaLabel={ariaLabels.nextPage}
|
|
73
|
+
previousAriaLabel={ariaLabels.previousPage}
|
|
74
|
+
ariaLabelBuilder={(currentPage) => `${ariaLabels.page} ${currentPage}`}
|
|
75
|
+
nextLabel={
|
|
76
|
+
<Button tabIndex={-1} className={styles.button} aria-label={ariaLabels.nextPage}>
|
|
77
|
+
<FontAwesomeIcon icon={faChevronRight} />
|
|
78
|
+
</Button>
|
|
79
|
+
}
|
|
80
|
+
previousLabel={
|
|
81
|
+
<Button tabIndex={-1} className={styles.button} aria-label={ariaLabels.previousPage}>
|
|
82
|
+
<FontAwesomeIcon icon={faChevronLeft} />
|
|
83
|
+
</Button>
|
|
84
|
+
}
|
|
85
|
+
/>
|
|
86
|
+
);
|
|
87
|
+
};
|
|
@@ -2,7 +2,20 @@ import * as React from "react";
|
|
|
2
2
|
import * as styles from "./CardWrapper.module.css";
|
|
3
3
|
|
|
4
4
|
export const CardWrapper = (props: React.HTMLAttributes<HTMLDivElement>): JSX.Element => {
|
|
5
|
-
const
|
|
5
|
+
const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {
|
|
6
|
+
if (props.onClick && (event.key === "Enter" || event.key === " ")) {
|
|
7
|
+
event.preventDefault();
|
|
8
|
+
props.onClick(event as any);
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const _props = {
|
|
13
|
+
...props,
|
|
14
|
+
className: `${props.className} ${styles.container}`,
|
|
15
|
+
role: props.onClick ? "button" : undefined,
|
|
16
|
+
tabIndex: props.onClick ? 0 : undefined,
|
|
17
|
+
...(props.onClick && { onKeyDown: handleKeyDown }),
|
|
18
|
+
};
|
|
6
19
|
|
|
7
20
|
return <div {..._props}>{props.children}</div>;
|
|
8
21
|
};
|
|
@@ -2,7 +2,7 @@ import * as React from "react";
|
|
|
2
2
|
import * as styles from "./select.module.css";
|
|
3
3
|
import clsx from "clsx";
|
|
4
4
|
import CreatableSelect from "react-select/creatable";
|
|
5
|
-
import ReactSelect, { MenuPlacement, StylesConfig, GroupBase } from "react-select";
|
|
5
|
+
import ReactSelect, { MenuPlacement, StylesConfig, GroupBase, components } from "react-select";
|
|
6
6
|
import { Control, Controller, FieldValues } from "react-hook-form";
|
|
7
7
|
import { IReactHookFormProps } from "../types";
|
|
8
8
|
import { ErrorMessage } from "../errorMessage/ErrorMessage";
|
|
@@ -122,6 +122,38 @@ const setAttributes = (): void => {
|
|
|
122
122
|
}, 100);
|
|
123
123
|
};
|
|
124
124
|
|
|
125
|
+
// Custom ClearIndicator component that handles keyboard events for accessibility
|
|
126
|
+
const ClearIndicator = (props: any) => {
|
|
127
|
+
const { clearValue, innerProps, children } = props;
|
|
128
|
+
|
|
129
|
+
const handleKeyDown = (event: React.KeyboardEvent) => {
|
|
130
|
+
if (event.key === " " || event.key === "Enter") {
|
|
131
|
+
event.preventDefault();
|
|
132
|
+
event.stopPropagation();
|
|
133
|
+
if (clearValue) {
|
|
134
|
+
clearValue();
|
|
135
|
+
}
|
|
136
|
+
if (innerProps?.onClick) {
|
|
137
|
+
innerProps.onClick(event);
|
|
138
|
+
}
|
|
139
|
+
} else if (innerProps?.onKeyDown) {
|
|
140
|
+
innerProps.onKeyDown(event);
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
return (
|
|
145
|
+
<components.ClearIndicator
|
|
146
|
+
{...props}
|
|
147
|
+
innerProps={{
|
|
148
|
+
...innerProps,
|
|
149
|
+
onKeyDown: handleKeyDown,
|
|
150
|
+
}}
|
|
151
|
+
>
|
|
152
|
+
{children}
|
|
153
|
+
</components.ClearIndicator>
|
|
154
|
+
);
|
|
155
|
+
};
|
|
156
|
+
|
|
125
157
|
export const SelectMultiple = ({
|
|
126
158
|
id,
|
|
127
159
|
name,
|
|
@@ -251,6 +283,7 @@ export const SelectSingle = ({
|
|
|
251
283
|
styles={selectStyles}
|
|
252
284
|
placeholder={disabled ? "Disabled..." : placeholder ?? "Select one or more options..."}
|
|
253
285
|
formatGroupLabel={(group) => <GroupLabel {...{ group }} />}
|
|
286
|
+
components={isClearable ? { ClearIndicator } : undefined}
|
|
254
287
|
/>
|
|
255
288
|
{errors[name] && !hideErrorMessage && <ErrorMessage message={errors[name]?.message as string} />}
|
|
256
289
|
</>
|
|
@@ -10,15 +10,24 @@ interface LogoProps {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export const Logo: React.FC<LogoProps> = ({ onClick, layoutClassName, variant = "header", ariaLabel = "logo" }) => {
|
|
13
|
+
const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {
|
|
14
|
+
if (onClick && (event.key === "Enter" || event.key === " ")) {
|
|
15
|
+
event.preventDefault();
|
|
16
|
+
onClick();
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
13
20
|
return (
|
|
14
21
|
<div
|
|
15
22
|
className={clsx(styles.container, styles[variant], [
|
|
16
23
|
onClick && styles.clickable,
|
|
17
24
|
layoutClassName && layoutClassName,
|
|
18
25
|
])}
|
|
19
|
-
role="img"
|
|
26
|
+
role={onClick ? "button" : "img"}
|
|
20
27
|
aria-label={ariaLabel}
|
|
28
|
+
tabIndex={onClick ? 0 : undefined}
|
|
21
29
|
{...{ onClick }}
|
|
30
|
+
{...(onClick && { onKeyDown: handleKeyDown })}
|
|
22
31
|
/>
|
|
23
32
|
);
|
|
24
33
|
};
|