@inera/ids-react 9.1.0 → 9.1.2
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/components/dialog/dialog.js +1 -1
- package/components/form/datepicker/datepicker.d.ts +1 -1
- package/components/form/datepicker/datepicker.js +8 -7
- package/components/form/input/input-base.js +4 -3
- package/components/form/select-multiple/select-multiple.js +1 -1
- package/components/header-1177/header-1177-avatar.js +1 -1
- package/components/header-1177/header-1177-menu-mobile.js +1 -1
- package/components/header-1177/header-1177-nav-item.js +1 -1
- package/components/header-1177-admin/header-1177-admin-avatar-mobile.js +1 -1
- package/components/header-1177-admin/header-1177-admin-avatar.js +1 -1
- package/components/header-1177-admin/header-1177-admin-menu-mobile.js +1 -1
- package/components/header-1177-admin/header-1177-admin-nav-item.js +1 -1
- package/components/header-1177-pro/header-1177-pro-avatar-mobile.js +1 -1
- package/components/header-1177-pro/header-1177-pro-avatar.js +1 -1
- package/components/header-1177-pro/header-1177-pro-menu-mobile.js +1 -1
- package/components/header-1177-pro/header-1177-pro-nav-item.js +1 -1
- package/components/header-inera/header-inera-menu-mobile.js +1 -1
- package/components/header-inera/header-inera-nav-item.js +1 -1
- package/components/header-inera-admin/header-inera-admin-avatar-mobile.js +1 -1
- package/components/header-inera-admin/header-inera-admin-avatar.js +1 -1
- package/components/header-inera-admin/header-inera-admin-menu-mobile.js +1 -1
- package/components/header-inera-admin/header-inera-admin-nav-item.js +1 -1
- package/components/side-panel/side-panel.js +1 -1
- package/components/utils/hooks/useEsc.d.ts +1 -9
- package/components/utils/hooks/useEsc.js +14 -17
- package/package.json +1 -1
|
@@ -11,7 +11,7 @@ function IDSDialog({ show = false, srClose = "Stäng", headline, width, maxWidth
|
|
|
11
11
|
const dialogRef = useRef(null);
|
|
12
12
|
const scrollAreaRef = useRef(null);
|
|
13
13
|
useFocusTrap(dialogRef.current, isVisible && !noFocusTrap);
|
|
14
|
-
useEsc(() => setIsVisible(false), triggerRef, isVisible && !persistent);
|
|
14
|
+
useEsc(() => setIsVisible(false), triggerRef, dialogRef, isVisible && !persistent);
|
|
15
15
|
// Sync prop show
|
|
16
16
|
useEffect(() => {
|
|
17
17
|
setIsVisible(show);
|
|
@@ -34,4 +34,4 @@ export interface IDSDatePickerProps extends Omit<React.HTMLAttributes<HTMLElemen
|
|
|
34
34
|
onClose?: () => void;
|
|
35
35
|
onDayClick?: (date: Date, modifiers: Modifiers, e: React.MouseEvent) => void;
|
|
36
36
|
}
|
|
37
|
-
export declare function IDSDatePicker({ label, value, light, placeholder, errorMsg, missingDateErrorMsg, invalidDateErrorMsg, calendarHeader, srOpenText, srCloseText, validationOnBlur, defaultMonth, startMonth, endMonth, noValidation, disabled, required, invalid, tooltip, disableNavigation, modifiers, focusedDay, onChange, onFocus, onBlur, onOpen, onClose, onDayClick, className, ...props }: IDSDatePickerProps): import("react/jsx-runtime").JSX.Element;
|
|
37
|
+
export declare function IDSDatePicker({ label, id, value, light, placeholder, errorMsg, missingDateErrorMsg, invalidDateErrorMsg, calendarHeader, srOpenText, srCloseText, validationOnBlur, defaultMonth, startMonth, endMonth, noValidation, disabled, required, invalid, tooltip, disableNavigation, modifiers, focusedDay, onChange, onFocus, onBlur, onOpen, onClose, onDayClick, className, ...props }: IDSDatePickerProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
-
import {
|
|
2
|
+
import { useId, useRef, useState, useEffect } from 'react';
|
|
3
3
|
import { isValid, getWeek, format, subMonths, addMonths } from 'date-fns';
|
|
4
4
|
import { sv } from 'react-day-picker/locale';
|
|
5
5
|
import clsx from 'clsx';
|
|
@@ -24,7 +24,12 @@ const getPrevMonthYear = (date) => {
|
|
|
24
24
|
const getNextMonthYear = (date) => {
|
|
25
25
|
return `${getSweMonth(addMonths(date, 1))} ${getSweYear(addMonths(date, 1))}`;
|
|
26
26
|
};
|
|
27
|
-
function IDSDatePicker({ label, value, light = false, placeholder = "åååå-mm-dd", errorMsg = "", missingDateErrorMsg = "Datum saknas", invalidDateErrorMsg = "Ogiltigt datum", calendarHeader = "Välj datum", srOpenText = "Öppna kalendern", srCloseText = "Stäng kalendern", validationOnBlur = false, defaultMonth, startMonth = new Date(1900, 0, 1), endMonth = new Date(2050, 0, 1), noValidation = false, disabled = false, required = false, invalid = false, tooltip, disableNavigation = false, modifiers, focusedDay, onChange, onFocus, onBlur, onOpen, onClose, onDayClick, className, ...props }) {
|
|
27
|
+
function IDSDatePicker({ label, id, value, light = false, placeholder = "åååå-mm-dd", errorMsg = "", missingDateErrorMsg = "Datum saknas", invalidDateErrorMsg = "Ogiltigt datum", calendarHeader = "Välj datum", srOpenText = "Öppna kalendern", srCloseText = "Stäng kalendern", validationOnBlur = false, defaultMonth, startMonth = new Date(1900, 0, 1), endMonth = new Date(2050, 0, 1), noValidation = false, disabled = false, required = false, invalid = false, tooltip, disableNavigation = false, modifiers, focusedDay, onChange, onFocus, onBlur, onOpen, onClose, onDayClick, className, ...props }) {
|
|
28
|
+
const reactId = useId();
|
|
29
|
+
const dialogId = `datepicker-dialog-${reactId}`;
|
|
30
|
+
const headerId = `datepicker-header-${reactId}`;
|
|
31
|
+
const inputId = id ?? `datepicker-input-${reactId}`;
|
|
32
|
+
const errorMsgId = `datepicker-error-${reactId}`;
|
|
28
33
|
const shortWeek = "v.";
|
|
29
34
|
const inputRef = useRef(null);
|
|
30
35
|
const triggerRef = useRef(null);
|
|
@@ -32,10 +37,6 @@ function IDSDatePicker({ label, value, light = false, placeholder = "åååå-mm
|
|
|
32
37
|
const headerRef = useRef(null);
|
|
33
38
|
const prevMonthButtonRef = useRef(null);
|
|
34
39
|
const nextMonthButtonRef = useRef(null);
|
|
35
|
-
const dialogId = `datepicker-dialog-${useId()}`;
|
|
36
|
-
const headerId = `datepicker-header-${useId()}`;
|
|
37
|
-
const inputId = props.id || `datepicker-input-${useId()}`;
|
|
38
|
-
const errorMsgId = `datepicker-error-${useId()}`;
|
|
39
40
|
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
|
40
41
|
const [inputValue, setInputValue] = useState(value);
|
|
41
42
|
const initialSelectedDate = !!value ? createNewDate(value) : undefined;
|
|
@@ -234,7 +235,7 @@ function IDSDatePicker({ label, value, light = false, placeholder = "åååå-mm
|
|
|
234
235
|
WeekNumberHeader: props => (jsx(WeekNumberHeader, { ...props, className: "ids-datepicker__week-number-header", children: shortWeek })),
|
|
235
236
|
MonthsDropdown: props => (jsx(MonthsDropdown, { ...props, disabled: disableNavigation, className: "ids-datepicker__month-select" })),
|
|
236
237
|
YearsDropdown: props => (jsx(YearsDropdown, { ...props, disabled: disableNavigation, className: "ids-datepicker__year-select" }))
|
|
237
|
-
}, startMonth: startMonth, endMonth: endMonth, month: month, onMonthChange: setMonth, defaultMonth: defaultMonth, selected: selectedDate, onSelect: handleDayPickerSelect, onDayClick: onDayClick })] })] }), (showError || showInvalidError || showMissingError) && (jsxs(IDSErrorMessage, { id: errorMsgId, show: true, children: [showInvalidError && !showMissingError && invalidDateErrorMsg, showMissingError && missingDateErrorMsg, showError && errorMsg] }))] }));
|
|
238
|
+
}, startMonth: startMonth, endMonth: endMonth, month: month, onMonthChange: setMonth, defaultMonth: defaultMonth, selected: selectedDate, onSelect: handleDayPickerSelect, onDayClick: onDayClick })] })] }), (showError || showInvalidError || showMissingError) && (jsxs(IDSErrorMessage, { id: errorMsgId, show: true, children: [showInvalidError && !showMissingError && !showError && invalidDateErrorMsg, showMissingError && !showInvalidError && !showError && missingDateErrorMsg, showError && errorMsg] }))] }));
|
|
238
239
|
}
|
|
239
240
|
|
|
240
241
|
export { IDSDatePicker };
|
|
@@ -19,9 +19,10 @@ function IDSInputBase({ label, type = "text", icon, hint, unit, showSearchLabel
|
|
|
19
19
|
}
|
|
20
20
|
: {};
|
|
21
21
|
ariaHandler["aria-label"] = type === "search" && !showSearchLabel ? label : "";
|
|
22
|
-
return (jsxs(Fragment, { children: [jsxs("div", { className: clsx("ids-input", { "ids-input--search": type === "search", "ids-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
return (jsxs(Fragment, { children: [jsxs("div", { className: clsx("ids-input", { "ids-input--search": type === "search", "ids-input--icon": !!icon }, className), "data-testid": dataTestId, style: style, children: [jsxs("div", { className: "ids-input__wrapper", children: [label && (jsxs("div", { className: clsx("ids-label-wrapper", "ids-label-wrapper--margin-bottom", {
|
|
23
|
+
"ids-hidden": type === "search" && !showSearchLabel
|
|
24
|
+
}), children: [jsx("label", { className: clsx("ids-label", {
|
|
25
|
+
"ids-label--disabled": disabled || readOnly
|
|
25
26
|
}), htmlFor: inputId, children: label }), tooltip && jsx("span", { className: "ids-label__tooltip", children: tooltip })] })), jsxs("div", { className: "ids-input__unit-wrapper", children: [jsxs("div", { className: "ids-input__input-wrapper", children: [type === "search" && jsx("span", { className: "ids-input__search-icon" }), jsx("input", { ref: inputRef, id: inputId, type: type, readOnly: readOnly, className: clsx("ids-input__input", {
|
|
26
27
|
"ids-input--light": light,
|
|
27
28
|
"ids-input--invalid": invalid,
|
|
@@ -14,7 +14,7 @@ function IDSSelectMultiple({ label, id, invalid = false, noValidation = false, e
|
|
|
14
14
|
useClickOutside([componentRef, buttonRef], () => {
|
|
15
15
|
setIsExpanded(false);
|
|
16
16
|
});
|
|
17
|
-
useEsc(() => setIsExpanded(false), buttonRef, isExpanded);
|
|
17
|
+
useEsc(() => setIsExpanded(false), buttonRef, componentRef, isExpanded);
|
|
18
18
|
useEffect(() => {
|
|
19
19
|
if (checkboxListInvalid && !noValidation)
|
|
20
20
|
setIsExpanded(true);
|
|
@@ -20,7 +20,7 @@ function IDSHeader1177Avatar({ expanded = false, persistent = false, children, .
|
|
|
20
20
|
if (!persistent)
|
|
21
21
|
setIsExpanded(false);
|
|
22
22
|
});
|
|
23
|
-
useEsc(() => setIsExpanded(false), buttonRef, isExpanded && !persistent);
|
|
23
|
+
useEsc(() => setIsExpanded(false), buttonRef, componentRef, isExpanded && !persistent);
|
|
24
24
|
const toggleAvatar = () => setIsExpanded(prev => !prev);
|
|
25
25
|
// Clicking a link inside dropdown closes it
|
|
26
26
|
useEffect(() => {
|
|
@@ -16,7 +16,7 @@ function IDSHeader1177MenuMobile({ srLabel = "Meny", persistent = false, expande
|
|
|
16
16
|
if (!persistent)
|
|
17
17
|
setIsExpanded(false);
|
|
18
18
|
});
|
|
19
|
-
useEsc(() => setIsExpanded(false), buttonRef, isExpanded && !persistent);
|
|
19
|
+
useEsc(() => setIsExpanded(false), buttonRef, componentRef, isExpanded && !persistent);
|
|
20
20
|
const handleLinkClick = () => {
|
|
21
21
|
setIsExpanded(false);
|
|
22
22
|
onClosed?.();
|
|
@@ -15,7 +15,7 @@ function IDSHeader1177NavItem({ expanded = false, ...props }) {
|
|
|
15
15
|
useClickOutside([componentRef, buttonRef], () => {
|
|
16
16
|
setIsExpanded(false);
|
|
17
17
|
});
|
|
18
|
-
useEsc(() => setIsExpanded(false), buttonRef);
|
|
18
|
+
useEsc(() => setIsExpanded(false), buttonRef, componentRef);
|
|
19
19
|
useEffect(() => {
|
|
20
20
|
setIsExpanded(expanded);
|
|
21
21
|
}, [expanded]);
|
|
@@ -18,7 +18,7 @@ function IDSHeader1177AdminAvatarMobile({ username = "", unit = "", expanded = f
|
|
|
18
18
|
if (!persistent)
|
|
19
19
|
setIsExpanded(false);
|
|
20
20
|
});
|
|
21
|
-
useEsc(() => setIsExpanded(false), buttonRef, isExpanded && !persistent);
|
|
21
|
+
useEsc(() => setIsExpanded(false), buttonRef, componentRef, isExpanded && !persistent);
|
|
22
22
|
const toggleAvatar = () => setIsExpanded(prev => !prev);
|
|
23
23
|
return (jsx(IDSHeader1177AdminAvatarMobileBase, { ...props, client: true, username: username, unit: unit, unresponsive: headerContext?.unresponsive ?? false, hide: headerContext?.hideAvatar, expanded: isExpanded, onToggleAvatar: toggleAvatar, componentRef: componentRef, buttonRef: buttonRef, children: children }));
|
|
24
24
|
}
|
|
@@ -18,7 +18,7 @@ function IDSHeader1177AdminAvatar({ username, unit, expanded = false, children,
|
|
|
18
18
|
if (!persistent)
|
|
19
19
|
setIsExpanded(false);
|
|
20
20
|
});
|
|
21
|
-
useEsc(() => setIsExpanded(false), buttonRef, isExpanded && !persistent);
|
|
21
|
+
useEsc(() => setIsExpanded(false), buttonRef, componentRef, isExpanded && !persistent);
|
|
22
22
|
const toggleAvatar = () => setIsExpanded(prev => !prev);
|
|
23
23
|
const handleClickOutside = (event) => {
|
|
24
24
|
if (!persistent && componentRef.current && !componentRef.current.contains(event.target)) {
|
|
@@ -15,7 +15,7 @@ function IDSHeader1177AdminMenuMobile({ srLabel = "Meny", persistent = false, ex
|
|
|
15
15
|
if (!persistent)
|
|
16
16
|
setIsExpanded(false);
|
|
17
17
|
});
|
|
18
|
-
useEsc(() => setIsExpanded(false), buttonRef, isExpanded && !persistent);
|
|
18
|
+
useEsc(() => setIsExpanded(false), buttonRef, componentRef, isExpanded && !persistent);
|
|
19
19
|
const handleLinkClick = () => {
|
|
20
20
|
setIsExpanded(false);
|
|
21
21
|
onClosed?.();
|
|
@@ -15,7 +15,7 @@ function IDSHeader1177AdminNavItem({ expanded = false, ...props }) {
|
|
|
15
15
|
useClickOutside([componentRef, buttonRef], () => {
|
|
16
16
|
setIsExpanded(false);
|
|
17
17
|
});
|
|
18
|
-
useEsc(() => setIsExpanded(false), buttonRef);
|
|
18
|
+
useEsc(() => setIsExpanded(false), buttonRef, componentRef);
|
|
19
19
|
useEffect(() => {
|
|
20
20
|
setIsExpanded(expanded);
|
|
21
21
|
}, [expanded]);
|
|
@@ -17,7 +17,7 @@ function IDSHeader1177ProAvatarMobile({ username = "", unit = "", expanded = fal
|
|
|
17
17
|
if (!persistent)
|
|
18
18
|
setIsExpanded(false);
|
|
19
19
|
});
|
|
20
|
-
useEsc(() => setIsExpanded(false), buttonRef, isExpanded && !persistent);
|
|
20
|
+
useEsc(() => setIsExpanded(false), buttonRef, componentRef, isExpanded && !persistent);
|
|
21
21
|
const toggleAvatar = () => setIsExpanded(prev => !prev);
|
|
22
22
|
return (jsx(IDSHeader1177ProAvatarMobileBase, { ...props, client: true, username: username, unit: unit, expanded: isExpanded, componentRef: componentRef, buttonRef: buttonRef, onToggleMenu: username ? toggleAvatar : undefined, hide: headerContext?.hideAvatar ?? false, unresponsive: headerContext?.unresponsive ?? false, children: children }));
|
|
23
23
|
}
|
|
@@ -19,7 +19,7 @@ function IDSHeader1177ProAvatar({ username, unit, expanded = false, children, pe
|
|
|
19
19
|
if (!persistent)
|
|
20
20
|
setIsExpanded(false);
|
|
21
21
|
});
|
|
22
|
-
useEsc(() => setIsExpanded(false), buttonRef, isExpanded && !persistent);
|
|
22
|
+
useEsc(() => setIsExpanded(false), buttonRef, componentRef, isExpanded && !persistent);
|
|
23
23
|
const toggleAvatar = () => setIsExpanded(prev => !prev);
|
|
24
24
|
useEffect(() => {
|
|
25
25
|
const clickOutsideHandler = (e) => {
|
|
@@ -15,7 +15,7 @@ function IDSHeader1177ProMenuMobile({ srLabel = "Meny", persistent = false, expa
|
|
|
15
15
|
if (!persistent)
|
|
16
16
|
setIsExpanded(false);
|
|
17
17
|
});
|
|
18
|
-
useEsc(() => setIsExpanded(false), buttonRef, isExpanded && !persistent);
|
|
18
|
+
useEsc(() => setIsExpanded(false), buttonRef, componentRef, isExpanded && !persistent);
|
|
19
19
|
const handleLinkClick = () => {
|
|
20
20
|
setIsExpanded(false);
|
|
21
21
|
onClosed?.();
|
|
@@ -15,7 +15,7 @@ function IDSHeader1177ProNavItem({ expanded = false, ...props }) {
|
|
|
15
15
|
useClickOutside([componentRef, buttonRef], () => {
|
|
16
16
|
setIsExpanded(false);
|
|
17
17
|
});
|
|
18
|
-
useEsc(() => setIsExpanded(false), buttonRef);
|
|
18
|
+
useEsc(() => setIsExpanded(false), buttonRef, componentRef);
|
|
19
19
|
useEffect(() => {
|
|
20
20
|
setIsExpanded(expanded);
|
|
21
21
|
}, [expanded]);
|
|
@@ -15,7 +15,7 @@ function IDSHeaderIneraMenuMobile({ srLabel = "Meny", expanded = false, persiste
|
|
|
15
15
|
if (!persistent)
|
|
16
16
|
setIsExpanded(false);
|
|
17
17
|
});
|
|
18
|
-
useEsc(() => setIsExpanded(false), buttonRef, isExpanded && !persistent);
|
|
18
|
+
useEsc(() => setIsExpanded(false), buttonRef, componentRef, isExpanded && !persistent);
|
|
19
19
|
const handleLinkClick = () => {
|
|
20
20
|
setIsExpanded(false);
|
|
21
21
|
onClosed?.();
|
|
@@ -15,7 +15,7 @@ function IDSHeaderIneraNavItem({ expanded = false, ...props }) {
|
|
|
15
15
|
useClickOutside([componentRef, buttonRef], () => {
|
|
16
16
|
setIsExpanded(false);
|
|
17
17
|
});
|
|
18
|
-
useEsc(() => setIsExpanded(false), buttonRef);
|
|
18
|
+
useEsc(() => setIsExpanded(false), buttonRef, componentRef);
|
|
19
19
|
useEffect(() => {
|
|
20
20
|
setIsExpanded(expanded);
|
|
21
21
|
}, [expanded]);
|
|
@@ -19,7 +19,7 @@ function IDSHeaderIneraAdminAvatarMobile({ username = "", unit = "", expanded =
|
|
|
19
19
|
if (!persistent)
|
|
20
20
|
setIsExpanded(false);
|
|
21
21
|
});
|
|
22
|
-
useEsc(() => setIsExpanded(false), buttonRef, isExpanded && !persistent);
|
|
22
|
+
useEsc(() => setIsExpanded(false), buttonRef, componentRef, isExpanded && !persistent);
|
|
23
23
|
const toggleAvatar = () => setIsExpanded(prev => !prev);
|
|
24
24
|
return (jsx(IDSHeaderIneraAdminAvatarMobileBase, { ...props, client: true, username: username, unit: unit, expanded: isExpanded, componentRef: componentRef, buttonRef: buttonRef, onToggleMenu: username ? toggleAvatar : undefined, unresponsive: headerContext?.unresponsive ?? false, children: children }));
|
|
25
25
|
}
|
|
@@ -20,7 +20,7 @@ function IDSHeaderIneraAdminAvatar({ username, unit, expanded = false, children,
|
|
|
20
20
|
if (!persistent)
|
|
21
21
|
setIsExpanded(false);
|
|
22
22
|
});
|
|
23
|
-
useEsc(() => setIsExpanded(false), buttonRef, isExpanded && !persistent);
|
|
23
|
+
useEsc(() => setIsExpanded(false), buttonRef, componentRef, isExpanded && !persistent);
|
|
24
24
|
const toggleAvatar = () => setIsExpanded(prev => !prev);
|
|
25
25
|
useEffect(() => {
|
|
26
26
|
const clickOutsideHandler = (e) => {
|
|
@@ -15,7 +15,7 @@ function IDSHeaderIneraAdminMenuMobile({ srLabel = "Meny", expanded = false, per
|
|
|
15
15
|
if (!persistent)
|
|
16
16
|
setIsExpanded(false);
|
|
17
17
|
});
|
|
18
|
-
useEsc(() => setIsExpanded(false), buttonRef, isExpanded && !persistent);
|
|
18
|
+
useEsc(() => setIsExpanded(false), buttonRef, componentRef, isExpanded && !persistent);
|
|
19
19
|
const handleLinkClick = () => {
|
|
20
20
|
setIsExpanded(false);
|
|
21
21
|
onClosed?.();
|
|
@@ -15,7 +15,7 @@ function IDSHeaderIneraAdminNavItem({ expanded = false, ...props }) {
|
|
|
15
15
|
useClickOutside([componentRef, buttonRef], () => {
|
|
16
16
|
setIsExpanded(false);
|
|
17
17
|
});
|
|
18
|
-
useEsc(() => setIsExpanded(false), buttonRef);
|
|
18
|
+
useEsc(() => setIsExpanded(false), buttonRef, componentRef);
|
|
19
19
|
useEffect(() => {
|
|
20
20
|
setIsExpanded(expanded);
|
|
21
21
|
}, [expanded]);
|
|
@@ -10,7 +10,7 @@ function IDSSidePanel({ show, menu = false, noScrollAreaFocus = false, srLabel =
|
|
|
10
10
|
const isControlled = show !== undefined;
|
|
11
11
|
const [internalShow, setInternalShow] = useState(false);
|
|
12
12
|
const visible = isControlled ? show : internalShow;
|
|
13
|
-
useEsc(() => setVisible(false), hamburgerRef, internalShow);
|
|
13
|
+
useEsc(() => setVisible(false), hamburgerRef, internalRef, internalShow);
|
|
14
14
|
const setVisible = (value) => {
|
|
15
15
|
if (!isControlled) {
|
|
16
16
|
setInternalShow(value);
|
|
@@ -1,10 +1,2 @@
|
|
|
1
1
|
import { RefObject } from "react";
|
|
2
|
-
|
|
3
|
-
* useEsc
|
|
4
|
-
* Calls the provided callback when Escape is pressed and optionally focuses a ref
|
|
5
|
-
*
|
|
6
|
-
* @param callback - function to call when Escape is pressed
|
|
7
|
-
* @param focusRef - optional ref to focus when Escape is pressed
|
|
8
|
-
* @param enabled - optional, defaults to true; disables listener when false
|
|
9
|
-
*/
|
|
10
|
-
export declare function useEsc(callback: () => void, focusRef?: RefObject<HTMLElement>, enabled?: boolean): void;
|
|
2
|
+
export declare function useEsc(callback: (event: KeyboardEvent) => void, focusRef?: RefObject<HTMLElement>, containerRef?: RefObject<HTMLElement>, enabled?: boolean): void;
|
|
@@ -1,27 +1,24 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
* useEsc
|
|
5
|
-
* Calls the provided callback when Escape is pressed and optionally focuses a ref
|
|
6
|
-
*
|
|
7
|
-
* @param callback - function to call when Escape is pressed
|
|
8
|
-
* @param focusRef - optional ref to focus when Escape is pressed
|
|
9
|
-
* @param enabled - optional, defaults to true; disables listener when false
|
|
10
|
-
*/
|
|
11
|
-
function useEsc(callback, focusRef, enabled = true) {
|
|
3
|
+
function useEsc(callback, focusRef, containerRef, enabled = true) {
|
|
12
4
|
useEffect(() => {
|
|
13
5
|
if (!enabled)
|
|
14
6
|
return;
|
|
15
|
-
const
|
|
16
|
-
if (event.key
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
7
|
+
const handler = (event) => {
|
|
8
|
+
if (event.key !== "Escape")
|
|
9
|
+
return;
|
|
10
|
+
if (containerRef?.current) {
|
|
11
|
+
const active = document.activeElement;
|
|
12
|
+
if (!containerRef.current.contains(active))
|
|
13
|
+
return;
|
|
20
14
|
}
|
|
15
|
+
event.preventDefault();
|
|
16
|
+
callback(event);
|
|
17
|
+
focusRef?.current?.focus();
|
|
21
18
|
};
|
|
22
|
-
document.addEventListener("keydown",
|
|
23
|
-
return () => document.removeEventListener("keydown",
|
|
24
|
-
}, [callback, focusRef, enabled]);
|
|
19
|
+
document.addEventListener("keydown", handler);
|
|
20
|
+
return () => document.removeEventListener("keydown", handler);
|
|
21
|
+
}, [callback, focusRef, enabled, containerRef]);
|
|
25
22
|
}
|
|
26
23
|
|
|
27
24
|
export { useEsc };
|