@navikt/ds-react 7.32.1 → 7.32.3
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/cjs/copybutton/CopyButton.js +4 -9
- package/cjs/copybutton/CopyButton.js.map +1 -1
- package/cjs/form/combobox/Combobox.js +1 -3
- package/cjs/form/combobox/Combobox.js.map +1 -1
- package/cjs/form/combobox/ComboboxWrapper.d.ts +1 -2
- package/cjs/form/combobox/ComboboxWrapper.js +1 -2
- package/cjs/form/combobox/ComboboxWrapper.js.map +1 -1
- package/cjs/form/combobox/FilteredOptions/FilteredOptions.js +28 -19
- package/cjs/form/combobox/FilteredOptions/FilteredOptions.js.map +1 -1
- package/cjs/form/combobox/FilteredOptions/FilteredOptionsItem.js +4 -0
- package/cjs/form/combobox/FilteredOptions/FilteredOptionsItem.js.map +1 -1
- package/cjs/form/combobox/FilteredOptions/useVirtualFocus.js.map +1 -1
- package/cjs/form/combobox/Input/Input.context.d.ts +2 -0
- package/cjs/form/combobox/Input/Input.context.js +4 -1
- package/cjs/form/combobox/Input/Input.context.js.map +1 -1
- package/cjs/form/combobox/Input/InputController.js +2 -2
- package/cjs/form/combobox/Input/InputController.js.map +1 -1
- package/cjs/form/switch/Switch.js +3 -3
- package/cjs/form/switch/Switch.js.map +1 -1
- package/cjs/help-text/HelpText.js +3 -3
- package/cjs/help-text/HelpText.js.map +1 -1
- package/cjs/help-text/HelpTextIcon.d.ts +1 -2
- package/cjs/help-text/HelpTextIcon.js +3 -7
- package/cjs/help-text/HelpTextIcon.js.map +1 -1
- package/cjs/layout/page/parts/PageBlock.d.ts +9 -6
- package/cjs/layout/page/parts/PageBlock.js.map +1 -1
- package/cjs/modal/ModalUtils.js +6 -4
- package/cjs/modal/ModalUtils.js.map +1 -1
- package/cjs/overlays/dismissablelayer/DismissableLayer.js +9 -19
- package/cjs/overlays/dismissablelayer/DismissableLayer.js.map +1 -1
- package/cjs/overlays/dismissablelayer/util/usePointerDownOutside.js +5 -4
- package/cjs/overlays/dismissablelayer/util/usePointerDownOutside.js.map +1 -1
- package/cjs/overlays/floating-menu/Menu.d.ts +4 -4
- package/cjs/overlays/floating-menu/Menu.js +7 -4
- package/cjs/overlays/floating-menu/Menu.js.map +1 -1
- package/cjs/overlays/floating-menu/parts/RovingFocus.js +3 -3
- package/cjs/overlays/floating-menu/parts/RovingFocus.js.map +1 -1
- package/cjs/overlays/overlay/hooks/useAnimationsFinished.js +1 -1
- package/cjs/overlays/overlay/hooks/useAnimationsFinished.js.map +1 -1
- package/cjs/overlays/overlay/hooks/useOpenChangeAnimationComplete.js +2 -2
- package/cjs/overlays/overlay/hooks/useOpenChangeAnimationComplete.js.map +1 -1
- package/cjs/popover/Popover.js +1 -1
- package/cjs/popover/Popover.js.map +1 -1
- package/cjs/progress-bar/ProgressBar.js +9 -6
- package/cjs/progress-bar/ProgressBar.js.map +1 -1
- package/cjs/table/AnimateHeight.js +12 -13
- package/cjs/table/AnimateHeight.js.map +1 -1
- package/cjs/tabs/parts/tablist/useScrollButtons.d.ts +1 -1
- package/cjs/tabs/parts/tablist/useScrollButtons.js +4 -4
- package/cjs/tabs/parts/tablist/useScrollButtons.js.map +1 -1
- package/cjs/util/TextareaAutoSize.js +3 -10
- package/cjs/util/TextareaAutoSize.js.map +1 -1
- package/cjs/util/create-context.d.ts +0 -1
- package/cjs/util/create-context.js.map +1 -1
- package/cjs/util/debounce.d.ts +1 -1
- package/cjs/util/debounce.js +5 -8
- package/cjs/util/debounce.js.map +1 -1
- package/cjs/util/detectBrowser.d.ts +2 -0
- package/cjs/util/detectBrowser.js +7 -0
- package/cjs/util/detectBrowser.js.map +1 -0
- package/cjs/util/focus-boundary/FocusBoundary.d.ts +44 -0
- package/cjs/util/focus-boundary/FocusBoundary.js +365 -0
- package/cjs/util/focus-boundary/FocusBoundary.js.map +1 -0
- package/cjs/util/focus-guards/FocusGuards.d.ts +8 -0
- package/cjs/util/focus-guards/FocusGuards.js +36 -0
- package/cjs/util/focus-guards/FocusGuards.js.map +1 -0
- package/cjs/util/hooks/descendants/useDescendant.js +3 -0
- package/cjs/util/hooks/descendants/useDescendant.js.map +1 -1
- package/cjs/util/hooks/useEventCallback.js.map +1 -0
- package/cjs/{overlays/overlay → util}/hooks/useLatestRef.js +3 -2
- package/cjs/util/hooks/useLatestRef.js.map +1 -0
- package/cjs/util/hooks/useRefWithInit.js.map +1 -0
- package/cjs/util/hooks/useTimeout.d.ts +16 -0
- package/cjs/util/hooks/useTimeout.js +49 -0
- package/cjs/util/hooks/useTimeout.js.map +1 -0
- package/cjs/util/link-anchor/LinkAnchor.js +6 -7
- package/cjs/util/link-anchor/LinkAnchor.js.map +1 -1
- package/cjs/util/owner.d.ts +29 -0
- package/cjs/util/owner.js +38 -0
- package/cjs/util/owner.js.map +1 -0
- package/esm/copybutton/CopyButton.js +5 -10
- package/esm/copybutton/CopyButton.js.map +1 -1
- package/esm/form/combobox/Combobox.js +1 -3
- package/esm/form/combobox/Combobox.js.map +1 -1
- package/esm/form/combobox/ComboboxWrapper.d.ts +1 -2
- package/esm/form/combobox/ComboboxWrapper.js +1 -2
- package/esm/form/combobox/ComboboxWrapper.js.map +1 -1
- package/esm/form/combobox/FilteredOptions/FilteredOptions.js +29 -20
- package/esm/form/combobox/FilteredOptions/FilteredOptions.js.map +1 -1
- package/esm/form/combobox/FilteredOptions/FilteredOptionsItem.js +4 -0
- package/esm/form/combobox/FilteredOptions/FilteredOptionsItem.js.map +1 -1
- package/esm/form/combobox/FilteredOptions/useVirtualFocus.js.map +1 -1
- package/esm/form/combobox/Input/Input.context.d.ts +2 -0
- package/esm/form/combobox/Input/Input.context.js +4 -1
- package/esm/form/combobox/Input/Input.context.js.map +1 -1
- package/esm/form/combobox/Input/InputController.js +2 -2
- package/esm/form/combobox/Input/InputController.js.map +1 -1
- package/esm/form/switch/Switch.js +3 -3
- package/esm/form/switch/Switch.js.map +1 -1
- package/esm/help-text/HelpText.js +3 -3
- package/esm/help-text/HelpText.js.map +1 -1
- package/esm/help-text/HelpTextIcon.d.ts +1 -2
- package/esm/help-text/HelpTextIcon.js +3 -7
- package/esm/help-text/HelpTextIcon.js.map +1 -1
- package/esm/layout/page/parts/PageBlock.d.ts +9 -6
- package/esm/layout/page/parts/PageBlock.js.map +1 -1
- package/esm/modal/ModalUtils.js +6 -4
- package/esm/modal/ModalUtils.js.map +1 -1
- package/esm/overlays/dismissablelayer/DismissableLayer.js +9 -19
- package/esm/overlays/dismissablelayer/DismissableLayer.js.map +1 -1
- package/esm/overlays/dismissablelayer/util/usePointerDownOutside.js +5 -4
- package/esm/overlays/dismissablelayer/util/usePointerDownOutside.js.map +1 -1
- package/esm/overlays/floating-menu/Menu.d.ts +4 -4
- package/esm/overlays/floating-menu/Menu.js +7 -4
- package/esm/overlays/floating-menu/Menu.js.map +1 -1
- package/esm/overlays/floating-menu/parts/RovingFocus.js +3 -3
- package/esm/overlays/floating-menu/parts/RovingFocus.js.map +1 -1
- package/esm/overlays/overlay/hooks/useAnimationsFinished.js +1 -1
- package/esm/overlays/overlay/hooks/useAnimationsFinished.js.map +1 -1
- package/esm/overlays/overlay/hooks/useOpenChangeAnimationComplete.js +2 -2
- package/esm/overlays/overlay/hooks/useOpenChangeAnimationComplete.js.map +1 -1
- package/esm/popover/Popover.js +1 -1
- package/esm/popover/Popover.js.map +1 -1
- package/esm/progress-bar/ProgressBar.js +10 -7
- package/esm/progress-bar/ProgressBar.js.map +1 -1
- package/esm/table/AnimateHeight.js +12 -13
- package/esm/table/AnimateHeight.js.map +1 -1
- package/esm/tabs/parts/tablist/useScrollButtons.d.ts +1 -1
- package/esm/tabs/parts/tablist/useScrollButtons.js +4 -4
- package/esm/tabs/parts/tablist/useScrollButtons.js.map +1 -1
- package/esm/util/TextareaAutoSize.js +1 -8
- package/esm/util/TextareaAutoSize.js.map +1 -1
- package/esm/util/create-context.d.ts +0 -1
- package/esm/util/create-context.js.map +1 -1
- package/esm/util/debounce.d.ts +1 -1
- package/esm/util/debounce.js +5 -8
- package/esm/util/debounce.js.map +1 -1
- package/esm/util/detectBrowser.d.ts +2 -0
- package/esm/util/detectBrowser.js +4 -0
- package/esm/util/detectBrowser.js.map +1 -0
- package/esm/util/focus-boundary/FocusBoundary.d.ts +44 -0
- package/esm/util/focus-boundary/FocusBoundary.js +329 -0
- package/esm/util/focus-boundary/FocusBoundary.js.map +1 -0
- package/esm/util/focus-guards/FocusGuards.d.ts +8 -0
- package/esm/util/focus-guards/FocusGuards.js +31 -0
- package/esm/util/focus-guards/FocusGuards.js.map +1 -0
- package/esm/util/hooks/descendants/useDescendant.js +3 -0
- package/esm/util/hooks/descendants/useDescendant.js.map +1 -1
- package/esm/util/hooks/useEventCallback.js.map +1 -0
- package/esm/{overlays/overlay → util}/hooks/useLatestRef.js +2 -1
- package/esm/util/hooks/useLatestRef.js.map +1 -0
- package/esm/util/hooks/useRefWithInit.js.map +1 -0
- package/esm/util/hooks/useTimeout.d.ts +16 -0
- package/esm/util/hooks/useTimeout.js +45 -0
- package/esm/util/hooks/useTimeout.js.map +1 -0
- package/esm/util/link-anchor/LinkAnchor.js +6 -7
- package/esm/util/link-anchor/LinkAnchor.js.map +1 -1
- package/esm/util/owner.d.ts +29 -0
- package/esm/util/owner.js +35 -0
- package/esm/util/owner.js.map +1 -0
- package/package.json +8 -8
- package/src/copybutton/CopyButton.tsx +5 -17
- package/src/form/combobox/Combobox.tsx +0 -4
- package/src/form/combobox/ComboboxWrapper.tsx +0 -3
- package/src/form/combobox/FilteredOptions/FilteredOptions.tsx +65 -45
- package/src/form/combobox/FilteredOptions/FilteredOptionsItem.tsx +4 -0
- package/src/form/combobox/FilteredOptions/useVirtualFocus.ts +1 -0
- package/src/form/combobox/Input/Input.context.tsx +5 -0
- package/src/form/combobox/Input/InputController.tsx +2 -1
- package/src/form/file-upload/parts/item/utils/format-file-size.test.ts +2 -2
- package/src/form/switch/Switch.tsx +4 -4
- package/src/help-text/HelpText.tsx +3 -2
- package/src/help-text/HelpTextIcon.tsx +2 -12
- package/src/layout/page/parts/PageBlock.tsx +9 -6
- package/src/modal/ModalUtils.ts +7 -4
- package/src/overlays/dismissablelayer/DismissableLayer.tsx +9 -18
- package/src/overlays/dismissablelayer/util/usePointerDownOutside.ts +5 -4
- package/src/overlays/floating-menu/Menu.tsx +13 -9
- package/src/overlays/floating-menu/parts/RovingFocus.tsx +3 -3
- package/src/overlays/overlay/hooks/useAnimationsFinished.ts +1 -1
- package/src/overlays/overlay/hooks/useOpenChangeAnimationComplete.ts +2 -2
- package/src/popover/Popover.tsx +1 -1
- package/src/progress-bar/ProgressBar.tsx +12 -10
- package/src/table/AnimateHeight.tsx +12 -15
- package/src/tabs/parts/tablist/useScrollButtons.ts +4 -3
- package/src/util/TextareaAutoSize.tsx +1 -9
- package/src/util/create-context.tsx +0 -1
- package/src/util/debounce.ts +7 -8
- package/src/util/detectBrowser.ts +5 -0
- package/src/util/focus-boundary/FocusBoundary.tsx +453 -0
- package/src/util/focus-guards/FocusGuards.tsx +56 -0
- package/src/util/hooks/descendants/useDescendant.tsx +3 -0
- package/src/{overlays/overlay → util}/hooks/useLatestRef.ts +2 -1
- package/src/util/hooks/useTimeout.ts +54 -0
- package/src/util/link-anchor/LinkAnchor.tsx +7 -6
- package/src/util/owner.ts +35 -0
- package/cjs/overlays/floating-menu/parts/FocusScope.d.ts +0 -22
- package/cjs/overlays/floating-menu/parts/FocusScope.js +0 -98
- package/cjs/overlays/floating-menu/parts/FocusScope.js.map +0 -1
- package/cjs/overlays/overlay/hooks/useEventCallback.js.map +0 -1
- package/cjs/overlays/overlay/hooks/useLatestRef.js.map +0 -1
- package/cjs/overlays/overlay/hooks/useRefWithInit.js.map +0 -1
- package/esm/overlays/floating-menu/parts/FocusScope.d.ts +0 -22
- package/esm/overlays/floating-menu/parts/FocusScope.js +0 -62
- package/esm/overlays/floating-menu/parts/FocusScope.js.map +0 -1
- package/esm/overlays/overlay/hooks/useEventCallback.js.map +0 -1
- package/esm/overlays/overlay/hooks/useLatestRef.js.map +0 -1
- package/esm/overlays/overlay/hooks/useRefWithInit.js.map +0 -1
- package/src/overlays/floating-menu/parts/FocusScope.tsx +0 -83
- /package/cjs/{overlays/overlay → util}/hooks/useEventCallback.d.ts +0 -0
- /package/cjs/{overlays/overlay → util}/hooks/useEventCallback.js +0 -0
- /package/cjs/{overlays/overlay → util}/hooks/useLatestRef.d.ts +0 -0
- /package/cjs/{overlays/overlay → util}/hooks/useRefWithInit.d.ts +0 -0
- /package/cjs/{overlays/overlay → util}/hooks/useRefWithInit.js +0 -0
- /package/esm/{overlays/overlay → util}/hooks/useEventCallback.d.ts +0 -0
- /package/esm/{overlays/overlay → util}/hooks/useEventCallback.js +0 -0
- /package/esm/{overlays/overlay → util}/hooks/useLatestRef.d.ts +0 -0
- /package/esm/{overlays/overlay → util}/hooks/useRefWithInit.d.ts +0 -0
- /package/esm/{overlays/overlay → util}/hooks/useRefWithInit.js +0 -0
- /package/src/{overlays/overlay → util}/hooks/useEventCallback.ts +0 -0
- /package/src/{overlays/overlay → util}/hooks/useRefWithInit.ts +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@navikt/ds-react",
|
|
3
|
-
"version": "7.32.
|
|
3
|
+
"version": "7.32.3",
|
|
4
4
|
"description": "React components from the Norwegian Labour and Welfare Administration.",
|
|
5
5
|
"author": "Aksel, a team part of the Norwegian Labour and Welfare Administration.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -643,21 +643,21 @@
|
|
|
643
643
|
"clean": "rimraf cjs esm",
|
|
644
644
|
"build": "yarn i18n-jsdoc && concurrently \"tsc -p tsconfig.build.json\" \"tsc -p tsconfig.esm.json && tsc-alias -p tsconfig.esm.json && yarn write-packagejson\" && yarn i18n-jsdoc --cleanup && yarn copy-types",
|
|
645
645
|
"watch": "tsc --watch -p tsconfig.esm.json",
|
|
646
|
-
"test": "TZ=UTC vitest run -c tests/vitest.config.ts",
|
|
646
|
+
"test": "TZ=UTC vitest run -c tests/vitest.config.ts --silent",
|
|
647
647
|
"test:watch": "TZ=UTC vitest watch -c tests/vitest.config.ts",
|
|
648
648
|
"copy-types": "copyfiles -f ./src/types/theme.d.ts ./esm/types"
|
|
649
649
|
},
|
|
650
650
|
"dependencies": {
|
|
651
651
|
"@floating-ui/react": "0.27.8",
|
|
652
|
-
"@floating-ui/react-dom": "^2.
|
|
653
|
-
"@navikt/aksel-icons": "^7.32.
|
|
654
|
-
"@navikt/ds-tokens": "^7.32.
|
|
652
|
+
"@floating-ui/react-dom": "^2.1.6",
|
|
653
|
+
"@navikt/aksel-icons": "^7.32.3",
|
|
654
|
+
"@navikt/ds-tokens": "^7.32.3",
|
|
655
655
|
"clsx": "^2.1.0",
|
|
656
656
|
"date-fns": "^4.0.0",
|
|
657
657
|
"react-day-picker": "9.7.0"
|
|
658
658
|
},
|
|
659
659
|
"devDependencies": {
|
|
660
|
-
"@testing-library/dom": "10.4.
|
|
660
|
+
"@testing-library/dom": "10.4.1",
|
|
661
661
|
"@testing-library/jest-dom": "^6.6.3",
|
|
662
662
|
"@testing-library/react": "^16.3.0",
|
|
663
663
|
"@testing-library/user-event": "^14.5.2",
|
|
@@ -674,8 +674,8 @@
|
|
|
674
674
|
"swr": "^2.3.6",
|
|
675
675
|
"tsc-alias": "1.8.16",
|
|
676
676
|
"tsx": "^4.20.6",
|
|
677
|
-
"typescript": "5.
|
|
678
|
-
"vitest": "^2.
|
|
677
|
+
"typescript": "5.9.3",
|
|
678
|
+
"vitest": "^3.2.4"
|
|
679
679
|
},
|
|
680
680
|
"peerDependencies": {
|
|
681
681
|
"@types/react": ">=17.0.30",
|
|
@@ -1,16 +1,11 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
ButtonHTMLAttributes,
|
|
3
|
-
forwardRef,
|
|
4
|
-
useEffect,
|
|
5
|
-
useRef,
|
|
6
|
-
useState,
|
|
7
|
-
} from "react";
|
|
1
|
+
import React, { ButtonHTMLAttributes, forwardRef, useState } from "react";
|
|
8
2
|
import { CheckmarkIcon, FilesIcon } from "@navikt/aksel-icons";
|
|
9
3
|
import { Button, ButtonProps } from "../button";
|
|
10
4
|
import { useRenameCSS, useThemeInternal } from "../theme/Theme";
|
|
11
5
|
import { Label } from "../typography";
|
|
12
6
|
import { composeEventHandlers } from "../util/composeEventHandlers";
|
|
13
7
|
import copy from "../util/copy";
|
|
8
|
+
import { useTimeout } from "../util/hooks/useTimeout";
|
|
14
9
|
import { useI18n } from "../util/i18n/i18n.hooks";
|
|
15
10
|
|
|
16
11
|
export interface CopyButtonProps
|
|
@@ -94,29 +89,22 @@ export const CopyButton = forwardRef<HTMLButtonElement, CopyButtonProps>(
|
|
|
94
89
|
ref,
|
|
95
90
|
) => {
|
|
96
91
|
const [active, setActive] = useState(false);
|
|
97
|
-
const timeoutRef = useRef<number>(undefined);
|
|
98
92
|
const translate = useI18n("CopyButton");
|
|
93
|
+
const timeout = useTimeout();
|
|
99
94
|
|
|
100
95
|
const { cn } = useRenameCSS();
|
|
101
96
|
|
|
102
97
|
const themeContext = useThemeInternal(false);
|
|
103
98
|
|
|
104
|
-
useEffect(() => {
|
|
105
|
-
return () => {
|
|
106
|
-
timeoutRef.current && clearTimeout(timeoutRef.current);
|
|
107
|
-
};
|
|
108
|
-
}, []);
|
|
109
|
-
|
|
110
99
|
const handleClick = () => {
|
|
111
|
-
timeoutRef.current && clearTimeout(timeoutRef.current);
|
|
112
100
|
copy(copyText);
|
|
113
101
|
setActive(true);
|
|
114
102
|
onActiveChange?.(true);
|
|
115
103
|
|
|
116
|
-
|
|
104
|
+
timeout.start(activeDuration, () => {
|
|
117
105
|
setActive(false);
|
|
118
106
|
onActiveChange?.(false);
|
|
119
|
-
}
|
|
107
|
+
});
|
|
120
108
|
};
|
|
121
109
|
|
|
122
110
|
const activeString = activeText || translate("activeText");
|
|
@@ -5,7 +5,6 @@ import { BodyShort, ErrorMessage, Label } from "../../typography";
|
|
|
5
5
|
import { ReadOnlyIconWithTitle } from "../ReadOnlyIcon";
|
|
6
6
|
import ComboboxWrapper from "./ComboboxWrapper";
|
|
7
7
|
import FilteredOptions from "./FilteredOptions/FilteredOptions";
|
|
8
|
-
import { useFilteredOptionsContext } from "./FilteredOptions/filteredOptionsContext";
|
|
9
8
|
import { useInputContext } from "./Input/Input.context";
|
|
10
9
|
import { InputController } from "./Input/InputController";
|
|
11
10
|
import { ComboboxProps } from "./types";
|
|
@@ -21,8 +20,6 @@ export const Combobox = forwardRef<
|
|
|
21
20
|
|
|
22
21
|
const { cn } = useRenameCSS();
|
|
23
22
|
|
|
24
|
-
const { toggleIsListOpen } = useFilteredOptionsContext();
|
|
25
|
-
|
|
26
23
|
const {
|
|
27
24
|
error,
|
|
28
25
|
errorId,
|
|
@@ -41,7 +38,6 @@ export const Combobox = forwardRef<
|
|
|
41
38
|
hasError={hasError}
|
|
42
39
|
inputProps={inputProps}
|
|
43
40
|
inputSize={size}
|
|
44
|
-
toggleIsListOpen={toggleIsListOpen}
|
|
45
41
|
>
|
|
46
42
|
<Label
|
|
47
43
|
htmlFor={inputProps.id}
|
|
@@ -11,7 +11,6 @@ type ComboboxWrapperProps = {
|
|
|
11
11
|
};
|
|
12
12
|
readOnly?: boolean;
|
|
13
13
|
inputSize: string;
|
|
14
|
-
toggleIsListOpen: (isListOpen: boolean) => void;
|
|
15
14
|
};
|
|
16
15
|
|
|
17
16
|
const ComboboxWrapper = ({
|
|
@@ -20,7 +19,6 @@ const ComboboxWrapper = ({
|
|
|
20
19
|
hasError,
|
|
21
20
|
inputProps,
|
|
22
21
|
inputSize,
|
|
23
|
-
toggleIsListOpen,
|
|
24
22
|
}: ComboboxWrapperProps) => {
|
|
25
23
|
const { cn } = useRenameCSS();
|
|
26
24
|
const { toggleOpenButtonRef, clearInput, readOnly } = useInputContext();
|
|
@@ -39,7 +37,6 @@ const ComboboxWrapper = ({
|
|
|
39
37
|
|
|
40
38
|
function onBlurWrapper(event: React.FocusEvent<HTMLDivElement>) {
|
|
41
39
|
if (!wrapperRef.current?.contains(event.relatedTarget)) {
|
|
42
|
-
toggleIsListOpen(false);
|
|
43
40
|
setHasFocusWithin(false);
|
|
44
41
|
clearInput(event);
|
|
45
42
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import React, { useState } from "react";
|
|
1
|
+
import React, { useRef, useState } from "react";
|
|
2
|
+
import { DismissableLayer } from "../../../overlays/dismissablelayer/DismissableLayer";
|
|
2
3
|
import { Floating } from "../../../overlays/floating/Floating";
|
|
3
4
|
import { useRenameCSS, useThemeInternal } from "../../../theme/Theme";
|
|
4
5
|
import { useClientLayoutEffect } from "../../../util";
|
|
@@ -17,6 +18,7 @@ const FilteredOptions = () => {
|
|
|
17
18
|
const themeContext = useThemeInternal(false);
|
|
18
19
|
const {
|
|
19
20
|
inputProps: { id },
|
|
21
|
+
anchorRef,
|
|
20
22
|
} = useInputContext();
|
|
21
23
|
|
|
22
24
|
const {
|
|
@@ -27,9 +29,12 @@ const FilteredOptions = () => {
|
|
|
27
29
|
setFilteredOptionsRef,
|
|
28
30
|
isMouseLastUsedInputDevice,
|
|
29
31
|
isValueNew,
|
|
32
|
+
toggleIsListOpen,
|
|
30
33
|
} = useFilteredOptionsContext();
|
|
31
34
|
const [localOpen, setLocalOpen] = useState(isListOpen);
|
|
32
35
|
|
|
36
|
+
const floatingRef = useRef<HTMLDivElement | null>(null);
|
|
37
|
+
|
|
33
38
|
/**
|
|
34
39
|
* This is a dirty hack to make the positioning-logic in Floating base the "flip" on the static 290px max-height,
|
|
35
40
|
* instead of the dynamic one based on available space. Without this, the list won't flip to top when there's
|
|
@@ -53,53 +58,68 @@ const FilteredOptions = () => {
|
|
|
53
58
|
const height = themeContext?.isDarkside ? "316px" : "290px";
|
|
54
59
|
|
|
55
60
|
return (
|
|
56
|
-
<
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
enabled={isListOpen}
|
|
67
|
-
style={{
|
|
68
|
-
maxHeight: localOpen
|
|
69
|
-
? `min(${height}, var(--ac-floating-available-height))`
|
|
70
|
-
: `${height}`,
|
|
61
|
+
<DismissableLayer
|
|
62
|
+
asChild
|
|
63
|
+
safeZone={{
|
|
64
|
+
anchor: anchorRef,
|
|
65
|
+
dismissable: floatingRef.current,
|
|
66
|
+
}}
|
|
67
|
+
onDismiss={() => localOpen && toggleIsListOpen(false)}
|
|
68
|
+
onEscapeKeyDown={(event) => {
|
|
69
|
+
/* We handle this manually in Input */
|
|
70
|
+
event.preventDefault();
|
|
71
71
|
}}
|
|
72
|
-
|
|
72
|
+
enabled={localOpen}
|
|
73
73
|
>
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
74
|
+
<Floating.Content
|
|
75
|
+
ref={floatingRef}
|
|
76
|
+
className={cn("navds-combobox__list", {
|
|
77
|
+
"navds-combobox__list--closed": !isListOpen,
|
|
78
|
+
"navds-combobox__list--with-hover": isMouseLastUsedInputDevice,
|
|
79
|
+
})}
|
|
80
|
+
id={filteredOptionsUtil.getFilteredOptionsId(id)}
|
|
81
|
+
tabIndex={-1}
|
|
82
|
+
sideOffset={8}
|
|
83
|
+
side="bottom"
|
|
84
|
+
fallbackPlacements={["top"]}
|
|
85
|
+
enabled={isListOpen}
|
|
86
|
+
style={{
|
|
87
|
+
maxHeight: localOpen
|
|
88
|
+
? `min(${height}, var(--ac-floating-available-height))`
|
|
89
|
+
: `${height}`,
|
|
90
|
+
}}
|
|
91
|
+
autoUpdateWhileMounted={false}
|
|
92
|
+
>
|
|
93
|
+
{shouldRenderNonSelectables && (
|
|
94
|
+
<div
|
|
95
|
+
className={cn("navds-combobox__list_non-selectables")}
|
|
96
|
+
role="status"
|
|
97
|
+
>
|
|
98
|
+
{isMultiSelect && maxSelected.limit && <MaxSelectedMessage />}
|
|
99
|
+
{isLoading && <LoadingMessage />}
|
|
100
|
+
{!isLoading && filteredOptions.length === 0 && !allowNewValues && (
|
|
101
|
+
<NoSearchHitsMessage />
|
|
102
|
+
)}
|
|
103
|
+
</div>
|
|
104
|
+
)}
|
|
86
105
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
106
|
+
{shouldRenderFilteredOptionsList && (
|
|
107
|
+
/* biome-ignore lint/a11y/useFocusableInteractive: Interaction is not handeled by listbox itself. */
|
|
108
|
+
<ul
|
|
109
|
+
ref={setFilteredOptionsRef}
|
|
110
|
+
role="listbox"
|
|
111
|
+
className={cn("navds-combobox__list-options")}
|
|
112
|
+
>
|
|
113
|
+
{isValueNew && !maxSelected.isLimitReached && allowNewValues && (
|
|
114
|
+
<AddNewOption />
|
|
115
|
+
)}
|
|
116
|
+
{filteredOptions.map((option) => (
|
|
117
|
+
<FilteredOptionsItem key={option.value} option={option} />
|
|
118
|
+
))}
|
|
119
|
+
</ul>
|
|
120
|
+
)}
|
|
121
|
+
</Floating.Content>
|
|
122
|
+
</DismissableLayer>
|
|
103
123
|
);
|
|
104
124
|
};
|
|
105
125
|
|
|
@@ -13,6 +13,10 @@ const useTextHighlight = (text: string, searchTerm: string) => {
|
|
|
13
13
|
const indexOfHighlightedText = text
|
|
14
14
|
.toLowerCase()
|
|
15
15
|
.indexOf(searchTerm.toLowerCase());
|
|
16
|
+
if (indexOfHighlightedText === -1) {
|
|
17
|
+
// This can happen if the consumer has implemented their own filtering logic
|
|
18
|
+
return [text, "", ""];
|
|
19
|
+
}
|
|
16
20
|
const start = text.substring(0, indexOfHighlightedText);
|
|
17
21
|
const highlight = text.substring(
|
|
18
22
|
indexOfHighlightedText,
|
|
@@ -18,6 +18,8 @@ interface InputContextValue extends FormFieldType {
|
|
|
18
18
|
toggleOpenButtonRef: React.MutableRefObject<HTMLDivElement | null>;
|
|
19
19
|
hideCaret: boolean;
|
|
20
20
|
setHideCaret: React.Dispatch<React.SetStateAction<boolean>>;
|
|
21
|
+
anchorRef: HTMLDivElement | null;
|
|
22
|
+
setAnchorRef: React.Dispatch<React.SetStateAction<HTMLDivElement | null>>;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
const [InputContextProvider, useInputContext] =
|
|
@@ -75,6 +77,7 @@ const InputProvider = ({ children, value: props }: Props) => {
|
|
|
75
77
|
const toggleOpenButtonRef = useRef<HTMLDivElement>(null);
|
|
76
78
|
const [internalValue, setInternalValue] = useState<string>(defaultValue);
|
|
77
79
|
const [hideCaret, setHideCaret] = useState(false);
|
|
80
|
+
const [anchorRef, setAnchorRef] = useState<HTMLDivElement | null>(null);
|
|
78
81
|
|
|
79
82
|
const value = useMemo(
|
|
80
83
|
() => String(externalValue ?? internalValue),
|
|
@@ -127,6 +130,8 @@ const InputProvider = ({ children, value: props }: Props) => {
|
|
|
127
130
|
toggleOpenButtonRef,
|
|
128
131
|
hideCaret,
|
|
129
132
|
setHideCaret,
|
|
133
|
+
anchorRef,
|
|
134
|
+
setAnchorRef,
|
|
130
135
|
};
|
|
131
136
|
|
|
132
137
|
return (
|
|
@@ -49,6 +49,7 @@ export const InputController = forwardRef<
|
|
|
49
49
|
inputRef,
|
|
50
50
|
toggleOpenButtonRef,
|
|
51
51
|
readOnly,
|
|
52
|
+
setAnchorRef,
|
|
52
53
|
} = useInputContext();
|
|
53
54
|
|
|
54
55
|
const { activeDecendantId, toggleIsListOpen } = useFilteredOptionsContext();
|
|
@@ -57,7 +58,7 @@ export const InputController = forwardRef<
|
|
|
57
58
|
const mergedInputRef = useMergeRefs(inputRef, ref);
|
|
58
59
|
|
|
59
60
|
return (
|
|
60
|
-
<Floating.Anchor asChild>
|
|
61
|
+
<Floating.Anchor asChild ref={setAnchorRef}>
|
|
61
62
|
<div
|
|
62
63
|
className={cn("navds-combobox__wrapper-inner navds-text-field__input", {
|
|
63
64
|
"navds-combobox__wrapper-inner--virtually-unfocused":
|
|
@@ -60,13 +60,13 @@ describe("format-file-size", () => {
|
|
|
60
60
|
|
|
61
61
|
function createLargeMockFile(sizeInBytes: number): File {
|
|
62
62
|
const chunkSize = 1024 * 1024; // 1MB chunk size
|
|
63
|
-
const chunks:
|
|
63
|
+
const chunks: ArrayBuffer[] = [];
|
|
64
64
|
|
|
65
65
|
for (let i = 0; i < sizeInBytes; i += chunkSize) {
|
|
66
66
|
const size = Math.min(chunkSize, sizeInBytes - i);
|
|
67
67
|
const chunk = new Uint8Array(size);
|
|
68
68
|
chunk.fill("a".charCodeAt(0));
|
|
69
|
-
chunks.push(chunk);
|
|
69
|
+
chunks.push(chunk.buffer);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
const blob = new Blob(chunks, { type: "text/plain" });
|
|
@@ -124,14 +124,14 @@ export const Switch = forwardRef<HTMLInputElement, SwitchProps>(
|
|
|
124
124
|
htmlFor={inputProps.id}
|
|
125
125
|
className={cn("navds-switch__label-wrapper")}
|
|
126
126
|
>
|
|
127
|
-
<
|
|
127
|
+
<span
|
|
128
128
|
className={cn("navds-switch__content", {
|
|
129
129
|
"navds-sr-only": hideLabel,
|
|
130
130
|
"navds-switch--with-description": description && !hideLabel,
|
|
131
131
|
})}
|
|
132
132
|
>
|
|
133
133
|
<BodyShort
|
|
134
|
-
as="
|
|
134
|
+
as="span"
|
|
135
135
|
size={size}
|
|
136
136
|
className={cn("navds-switch__label")}
|
|
137
137
|
>
|
|
@@ -141,7 +141,7 @@ export const Switch = forwardRef<HTMLInputElement, SwitchProps>(
|
|
|
141
141
|
{description && (
|
|
142
142
|
<BodyShort
|
|
143
143
|
size={size}
|
|
144
|
-
as="
|
|
144
|
+
as="span"
|
|
145
145
|
className={cn(
|
|
146
146
|
"navds-form-field__subdescription navds-switch__description",
|
|
147
147
|
)}
|
|
@@ -149,7 +149,7 @@ export const Switch = forwardRef<HTMLInputElement, SwitchProps>(
|
|
|
149
149
|
{description}
|
|
150
150
|
</BodyShort>
|
|
151
151
|
)}
|
|
152
|
-
</
|
|
152
|
+
</span>
|
|
153
153
|
</label>
|
|
154
154
|
</div>
|
|
155
155
|
);
|
|
@@ -70,9 +70,10 @@ export const HelpText = forwardRef<HTMLButtonElement, HelpTextProps>(
|
|
|
70
70
|
className={cn(className, "navds-help-text__button")}
|
|
71
71
|
type="button"
|
|
72
72
|
aria-expanded={open}
|
|
73
|
+
aria-label={titleWithFallback}
|
|
73
74
|
>
|
|
74
|
-
<HelpTextIcon
|
|
75
|
-
<HelpTextIcon filled
|
|
75
|
+
<HelpTextIcon />
|
|
76
|
+
<HelpTextIcon filled />
|
|
76
77
|
</button>
|
|
77
78
|
<Popover
|
|
78
79
|
onClose={() => setOpen(false)}
|
|
@@ -1,18 +1,9 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { useRenameCSS } from "../theme/Theme";
|
|
3
|
-
import { useId } from "../util/hooks";
|
|
4
3
|
|
|
5
|
-
export const HelpTextIcon = ({
|
|
6
|
-
title,
|
|
7
|
-
filled = false,
|
|
8
|
-
}: {
|
|
9
|
-
title: string;
|
|
10
|
-
filled?: boolean;
|
|
11
|
-
}) => {
|
|
4
|
+
export const HelpTextIcon = ({ filled = false }: { filled?: boolean }) => {
|
|
12
5
|
const { cn } = useRenameCSS();
|
|
13
6
|
|
|
14
|
-
let titleId: string | undefined = useId();
|
|
15
|
-
titleId = title ? `title-${titleId}` : undefined;
|
|
16
7
|
return (
|
|
17
8
|
<svg
|
|
18
9
|
width="1em"
|
|
@@ -22,12 +13,11 @@ export const HelpTextIcon = ({
|
|
|
22
13
|
xmlns="http://www.w3.org/2000/svg"
|
|
23
14
|
focusable={false}
|
|
24
15
|
role="img"
|
|
25
|
-
aria-labelledby={titleId}
|
|
26
16
|
className={cn("navds-help-text__icon", {
|
|
27
17
|
"navds-help-text__icon--filled": filled,
|
|
28
18
|
})}
|
|
19
|
+
aria-hidden
|
|
29
20
|
>
|
|
30
|
-
{title ? <title id={titleId}>{title}</title> : null}
|
|
31
21
|
<circle
|
|
32
22
|
cx="12"
|
|
33
23
|
cy="12"
|
|
@@ -7,24 +7,27 @@ export const widths = ["text", "md", "lg", "xl", "2xl"] as const;
|
|
|
7
7
|
export interface PageBlockProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
8
8
|
/**
|
|
9
9
|
* Predefined max-width
|
|
10
|
-
*
|
|
11
|
-
* ```
|
|
10
|
+
*
|
|
12
11
|
* text: 576px + dynamic gutters
|
|
12
|
+
*
|
|
13
13
|
* md: 768px
|
|
14
|
+
*
|
|
14
15
|
* lg: 1024px
|
|
16
|
+
*
|
|
15
17
|
* xl: 1280px
|
|
18
|
+
*
|
|
16
19
|
* 2xl: 1440px
|
|
17
|
-
*
|
|
20
|
+
*
|
|
18
21
|
* @default max-width: 100%;
|
|
19
22
|
*/
|
|
20
23
|
width?: (typeof widths)[number];
|
|
21
24
|
/**
|
|
22
25
|
* Adds a standardised responsive padding-inline
|
|
23
|
-
*
|
|
24
|
-
* ```
|
|
26
|
+
*
|
|
25
27
|
* 3rem on > md
|
|
28
|
+
*
|
|
26
29
|
* 1rem on < md
|
|
27
|
-
*
|
|
30
|
+
*
|
|
28
31
|
* @default false
|
|
29
32
|
*/
|
|
30
33
|
gutters?: boolean;
|
package/src/modal/ModalUtils.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import { ownerDocument } from "../util/owner";
|
|
2
3
|
import type { ModalProps } from "./types";
|
|
3
4
|
|
|
4
5
|
export interface MouseCoordinates {
|
|
@@ -45,16 +46,18 @@ export function useBodyScrollLock(
|
|
|
45
46
|
return;
|
|
46
47
|
}
|
|
47
48
|
|
|
49
|
+
const ownerDoc = ownerDocument(modalRef.current);
|
|
50
|
+
|
|
48
51
|
// In case `open` is true initially
|
|
49
52
|
if (modalRef.current.open) {
|
|
50
|
-
|
|
53
|
+
ownerDoc.body.classList.add(BODY_CLASS, BODY_CLASS_LEGACY);
|
|
51
54
|
}
|
|
52
55
|
|
|
53
56
|
const observer = new MutationObserver(() => {
|
|
54
57
|
if (modalRef.current?.open) {
|
|
55
|
-
|
|
58
|
+
ownerDoc.body.classList.add(BODY_CLASS, BODY_CLASS_LEGACY);
|
|
56
59
|
} else {
|
|
57
|
-
|
|
60
|
+
ownerDoc.body.classList.remove(BODY_CLASS, BODY_CLASS_LEGACY);
|
|
58
61
|
}
|
|
59
62
|
});
|
|
60
63
|
|
|
@@ -66,7 +69,7 @@ export function useBodyScrollLock(
|
|
|
66
69
|
return () => {
|
|
67
70
|
observer.disconnect();
|
|
68
71
|
// In case modal is unmounted before it's closed
|
|
69
|
-
|
|
72
|
+
ownerDoc.body.classList.remove(BODY_CLASS, BODY_CLASS_LEGACY);
|
|
70
73
|
};
|
|
71
74
|
}, [modalRef, portalNode, isNested]);
|
|
72
75
|
}
|
|
@@ -8,6 +8,7 @@ import React, {
|
|
|
8
8
|
import { Slot } from "../../slot/Slot";
|
|
9
9
|
import { useMergeRefs } from "../../util/hooks";
|
|
10
10
|
import { createDescendantContext } from "../../util/hooks/descendants/useDescendant";
|
|
11
|
+
import { ownerDocument } from "../../util/owner";
|
|
11
12
|
import { AsChild } from "../../util/types/AsChild";
|
|
12
13
|
import {
|
|
13
14
|
CustomFocusEvent,
|
|
@@ -158,11 +159,7 @@ const DismissableLayerNode = forwardRef<HTMLDivElement, DismissableLayerProps>(
|
|
|
158
159
|
|
|
159
160
|
const mergedRefs = useMergeRefs(setNode, register, ref);
|
|
160
161
|
|
|
161
|
-
|
|
162
|
-
* In some cases the `node.ownerDocument` can differ from global document.
|
|
163
|
-
* This can happend when portaling elements or using web-components
|
|
164
|
-
*/
|
|
165
|
-
const ownerDocument = node?.ownerDocument ?? globalThis?.document;
|
|
162
|
+
const ownerDoc = ownerDocument(node);
|
|
166
163
|
|
|
167
164
|
const hasInteractedOutsideRef = useRef(false);
|
|
168
165
|
const hasPointerDownOutsideRef = useRef(false);
|
|
@@ -278,7 +275,7 @@ const DismissableLayerNode = forwardRef<HTMLDivElement, DismissableLayerProps>(
|
|
|
278
275
|
if (!event.defaultPrevented && onDismiss) {
|
|
279
276
|
onDismiss();
|
|
280
277
|
}
|
|
281
|
-
},
|
|
278
|
+
}, ownerDoc);
|
|
282
279
|
|
|
283
280
|
const focusOutside = useFocusOutside((event) => {
|
|
284
281
|
if (!enabled) {
|
|
@@ -302,7 +299,7 @@ const DismissableLayerNode = forwardRef<HTMLDivElement, DismissableLayerProps>(
|
|
|
302
299
|
if (!event.defaultPrevented && onDismiss) {
|
|
303
300
|
onDismiss();
|
|
304
301
|
}
|
|
305
|
-
},
|
|
302
|
+
}, ownerDoc);
|
|
306
303
|
|
|
307
304
|
useEscapeKeydown((event) => {
|
|
308
305
|
if (!enabled) {
|
|
@@ -331,7 +328,7 @@ const DismissableLayerNode = forwardRef<HTMLDivElement, DismissableLayerProps>(
|
|
|
331
328
|
event.preventDefault();
|
|
332
329
|
onDismiss();
|
|
333
330
|
}
|
|
334
|
-
},
|
|
331
|
+
}, ownerDoc);
|
|
335
332
|
|
|
336
333
|
/**
|
|
337
334
|
* If `disableOutsidePointerEvents` is true,
|
|
@@ -343,23 +340,17 @@ const DismissableLayerNode = forwardRef<HTMLDivElement, DismissableLayerProps>(
|
|
|
343
340
|
if (!node || !enabled || !disableOutsidePointerEvents) return;
|
|
344
341
|
|
|
345
342
|
if (bodyLockCount === 0) {
|
|
346
|
-
originalBodyPointerEvents =
|
|
347
|
-
|
|
343
|
+
originalBodyPointerEvents = ownerDoc.body.style.pointerEvents;
|
|
344
|
+
ownerDoc.body.style.pointerEvents = "none";
|
|
348
345
|
}
|
|
349
346
|
bodyLockCount++;
|
|
350
347
|
return () => {
|
|
351
348
|
if (bodyLockCount === 1) {
|
|
352
|
-
|
|
349
|
+
ownerDoc.body.style.pointerEvents = originalBodyPointerEvents;
|
|
353
350
|
}
|
|
354
351
|
bodyLockCount--;
|
|
355
352
|
};
|
|
356
|
-
}, [
|
|
357
|
-
node,
|
|
358
|
-
ownerDocument,
|
|
359
|
-
disableOutsidePointerEvents,
|
|
360
|
-
descendants,
|
|
361
|
-
enabled,
|
|
362
|
-
]);
|
|
353
|
+
}, [node, ownerDoc, disableOutsidePointerEvents, descendants, enabled]);
|
|
363
354
|
|
|
364
355
|
/**
|
|
365
356
|
* To make sure pointerEvents are enabled for all parents and siblings when the layer is removed from the DOM
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useEffect, useRef } from "react";
|
|
2
2
|
import { useCallbackRef } from "../../../util/hooks";
|
|
3
|
+
import { useTimeout } from "../../../util/hooks/useTimeout";
|
|
3
4
|
import {
|
|
4
5
|
CUSTOM_EVENTS,
|
|
5
6
|
CustomPointerDownEvent,
|
|
@@ -19,6 +20,7 @@ export function usePointerDownOutside(
|
|
|
19
20
|
const handlePointerDownOutside = useCallbackRef(callback) as EventListener;
|
|
20
21
|
const isPointerInsideReactTreeRef = useRef(false);
|
|
21
22
|
const handleClickRef = useRef<typeof handlePointerDownOutside>(() => {});
|
|
23
|
+
const timeout = useTimeout();
|
|
22
24
|
|
|
23
25
|
useEffect(() => {
|
|
24
26
|
const handlePointerDown = (event: PointerEvent) => {
|
|
@@ -77,16 +79,15 @@ export function usePointerDownOutside(
|
|
|
77
79
|
* })
|
|
78
80
|
* });
|
|
79
81
|
*/
|
|
80
|
-
|
|
82
|
+
timeout.start(0, () => {
|
|
81
83
|
ownerDocument.addEventListener("pointerdown", handlePointerDown);
|
|
82
|
-
}
|
|
84
|
+
});
|
|
83
85
|
|
|
84
86
|
return () => {
|
|
85
|
-
window.clearTimeout(timerId);
|
|
86
87
|
ownerDocument.removeEventListener("pointerdown", handlePointerDown);
|
|
87
88
|
ownerDocument.removeEventListener("click", handleClickRef.current);
|
|
88
89
|
};
|
|
89
|
-
}, [ownerDocument, handlePointerDownOutside]);
|
|
90
|
+
}, [ownerDocument, handlePointerDownOutside, timeout]);
|
|
90
91
|
|
|
91
92
|
return {
|
|
92
93
|
// ensures we check React component tree (not just DOM tree)
|