@navikt/ds-react 7.32.1 → 7.32.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/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/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/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/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/useEventCallback.js.map +1 -0
- package/cjs/{overlays/overlay → util}/hooks/useLatestRef.js +2 -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/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/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/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/useEventCallback.js.map +1 -0
- package/esm/{overlays/overlay → util}/hooks/useLatestRef.js +1 -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/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/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/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/{overlays/overlay → util}/hooks/useLatestRef.ts +1 -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
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect } from "react";
|
|
3
|
+
import { useRefWithInit } from "./useRefWithInit.js";
|
|
4
|
+
const EMPTY = 0;
|
|
5
|
+
class Timeout {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.currentId = EMPTY;
|
|
8
|
+
this.clear = () => {
|
|
9
|
+
if (this.currentId !== EMPTY) {
|
|
10
|
+
clearTimeout(this.currentId);
|
|
11
|
+
this.currentId = EMPTY;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
this.disposeEffect = () => {
|
|
15
|
+
return this.clear;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
static create() {
|
|
19
|
+
return new Timeout();
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Executes `fn` after `delay`, clearing any previously scheduled call.
|
|
23
|
+
*/
|
|
24
|
+
start(delay, fn) {
|
|
25
|
+
this.clear();
|
|
26
|
+
this.currentId = setTimeout(() => {
|
|
27
|
+
this.currentId = EMPTY;
|
|
28
|
+
fn();
|
|
29
|
+
}, delay); /* Node.js types are enabled in development */
|
|
30
|
+
}
|
|
31
|
+
isStarted() {
|
|
32
|
+
return this.currentId !== EMPTY;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* A `setTimeout` with automatic cleanup and guard.
|
|
37
|
+
*/
|
|
38
|
+
function useTimeout() {
|
|
39
|
+
const timeout = useRefWithInit(Timeout.create).current;
|
|
40
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
41
|
+
useEffect(timeout.disposeEffect, []);
|
|
42
|
+
return timeout;
|
|
43
|
+
}
|
|
44
|
+
export { Timeout, useTimeout };
|
|
45
|
+
//# sourceMappingURL=useTimeout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTimeout.js","sourceRoot":"","sources":["../../../src/util/hooks/useTimeout.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,KAAK,GAAG,CAAC,CAAC;AAEhB,MAAM,OAAO;IAAb;QAKE,cAAS,GAAW,KAAK,CAAC;QAiB1B,UAAK,GAAG,GAAG,EAAE;YACX,IAAI,IAAI,CAAC,SAAS,KAAK,KAAK,EAAE,CAAC;gBAC7B,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC7B,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACzB,CAAC;QACH,CAAC,CAAC;QAEF,kBAAa,GAAG,GAAG,EAAE;YACnB,OAAO,IAAI,CAAC,KAAK,CAAC;QACpB,CAAC,CAAC;IACJ,CAAC;IA/BC,MAAM,CAAC,MAAM;QACX,OAAO,IAAI,OAAO,EAAE,CAAC;IACvB,CAAC;IAID;;OAEG;IACH,KAAK,CAAC,KAAa,EAAE,EAAc;QACjC,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAC/B,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,EAAE,EAAE,CAAC;QACP,CAAC,EAAE,KAAK,CAAsB,CAAC,CAAC,8CAA8C;IAChF,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC;IAClC,CAAC;CAYF;AAED;;GAEG;AACH,SAAS,UAAU;IACjB,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAQ,CAAC;IAExD,uDAAuD;IACvD,SAAS,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IAErC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC"}
|
|
@@ -16,6 +16,7 @@ import { useRenameCSS } from "../../theme/Theme.js";
|
|
|
16
16
|
import { composeEventHandlers } from "../composeEventHandlers.js";
|
|
17
17
|
import { createContext } from "../create-context.js";
|
|
18
18
|
import { useMergeRefs } from "../hooks/useMergeRefs.js";
|
|
19
|
+
import { ownerWindow } from "../owner.js";
|
|
19
20
|
const [LinkAnchorContextProvider, useLinkAnchorContext] = createContext({
|
|
20
21
|
name: "LinkAnchorOverlayContext",
|
|
21
22
|
});
|
|
@@ -27,7 +28,8 @@ const LinkAnchorOverlay = forwardRef((_a, forwardedRef) => {
|
|
|
27
28
|
return (React.createElement(LinkAnchorContextProvider, { anchorRef: anchorRef },
|
|
28
29
|
React.createElement(Component, Object.assign({ ref: forwardedRef }, restProps, { className: cn("navds-link-anchor__overlay", className), onClick: composeEventHandlers(onClick, (e) => {
|
|
29
30
|
var _a;
|
|
30
|
-
if (e.target === anchorRef.current ||
|
|
31
|
+
if (e.target === anchorRef.current ||
|
|
32
|
+
isTextSelected(anchorRef.current)) {
|
|
31
33
|
return;
|
|
32
34
|
}
|
|
33
35
|
const event = new MouseEvent("click", {
|
|
@@ -61,12 +63,9 @@ const LinkAnchorArrow = forwardRef((_a, forwardedRef) => {
|
|
|
61
63
|
return (React.createElement(ArrowRightIcon, Object.assign({ ref: forwardedRef, "aria-hidden": true, className: cn("navds-link-anchor__arrow", className) }, restProps)));
|
|
62
64
|
});
|
|
63
65
|
/* -------------------------- LinkAnchor Utilities -------------------------- */
|
|
64
|
-
function isTextSelected() {
|
|
65
|
-
var _a;
|
|
66
|
-
|
|
67
|
-
return false;
|
|
68
|
-
}
|
|
69
|
-
return !!((_a = window.getSelection()) === null || _a === void 0 ? void 0 : _a.toString());
|
|
66
|
+
function isTextSelected(refElement) {
|
|
67
|
+
var _a, _b;
|
|
68
|
+
return !!((_b = (_a = ownerWindow(refElement)) === null || _a === void 0 ? void 0 : _a.getSelection()) === null || _b === void 0 ? void 0 : _b.toString());
|
|
70
69
|
}
|
|
71
70
|
export { LinkAnchor, LinkAnchorArrow, LinkAnchorOverlay };
|
|
72
71
|
//# sourceMappingURL=LinkAnchor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinkAnchor.js","sourceRoot":"","sources":["../../../src/util/link-anchor/LinkAnchor.tsx"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,KAAK,EAAE,EAIZ,UAAU,EACV,MAAM,GACP,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"LinkAnchor.js","sourceRoot":"","sources":["../../../src/util/link-anchor/LinkAnchor.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the owner document of a given element.
|
|
3
|
+
*
|
|
4
|
+
* Use this when the node might live in a different browsing context than the code
|
|
5
|
+
* invoking the utility (portals, iframes, custom documents).
|
|
6
|
+
*
|
|
7
|
+
* Examples:
|
|
8
|
+
* - Focus guards for portaled menus: pass the menu root so guards are created in the portal document.
|
|
9
|
+
* - Components rendered inside an iframe preview: scope listeners to the iframe-document.
|
|
10
|
+
* - Element opened with `window.open`: scope listeners to the new window-document.
|
|
11
|
+
*
|
|
12
|
+
* Scenarios:
|
|
13
|
+
* - Modal content rendered to parent `document.body` via a portal while running inside an iframe.
|
|
14
|
+
* - Tooltips or popovers that live outside the component't immediate DOM tree.
|
|
15
|
+
*
|
|
16
|
+
* https://github.com/radix-ui/primitives/issues/1676
|
|
17
|
+
* https://github.com/radix-ui/primitives/issues/1721
|
|
18
|
+
* https://github.com/radix-ui/primitives/discussions/1715
|
|
19
|
+
*/
|
|
20
|
+
declare function ownerDocument(node: Element | null): Document;
|
|
21
|
+
/**
|
|
22
|
+
* Returns the owner window of a given element.
|
|
23
|
+
*
|
|
24
|
+
* Examples:
|
|
25
|
+
* - Keyboard listeners for portaled overlays.
|
|
26
|
+
* - Resize/scroll observers applied to iframe widgets.
|
|
27
|
+
*/
|
|
28
|
+
declare function ownerWindow(node: Document | Element | null): typeof window;
|
|
29
|
+
export { ownerDocument, ownerWindow };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the owner document of a given element.
|
|
3
|
+
*
|
|
4
|
+
* Use this when the node might live in a different browsing context than the code
|
|
5
|
+
* invoking the utility (portals, iframes, custom documents).
|
|
6
|
+
*
|
|
7
|
+
* Examples:
|
|
8
|
+
* - Focus guards for portaled menus: pass the menu root so guards are created in the portal document.
|
|
9
|
+
* - Components rendered inside an iframe preview: scope listeners to the iframe-document.
|
|
10
|
+
* - Element opened with `window.open`: scope listeners to the new window-document.
|
|
11
|
+
*
|
|
12
|
+
* Scenarios:
|
|
13
|
+
* - Modal content rendered to parent `document.body` via a portal while running inside an iframe.
|
|
14
|
+
* - Tooltips or popovers that live outside the component't immediate DOM tree.
|
|
15
|
+
*
|
|
16
|
+
* https://github.com/radix-ui/primitives/issues/1676
|
|
17
|
+
* https://github.com/radix-ui/primitives/issues/1721
|
|
18
|
+
* https://github.com/radix-ui/primitives/discussions/1715
|
|
19
|
+
*/
|
|
20
|
+
function ownerDocument(node) {
|
|
21
|
+
return (node === null || node === void 0 ? void 0 : node.ownerDocument) || (globalThis === null || globalThis === void 0 ? void 0 : globalThis.document);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Returns the owner window of a given element.
|
|
25
|
+
*
|
|
26
|
+
* Examples:
|
|
27
|
+
* - Keyboard listeners for portaled overlays.
|
|
28
|
+
* - Resize/scroll observers applied to iframe widgets.
|
|
29
|
+
*/
|
|
30
|
+
function ownerWindow(node) {
|
|
31
|
+
var _a;
|
|
32
|
+
return ((_a = node === null || node === void 0 ? void 0 : node.ownerDocument) === null || _a === void 0 ? void 0 : _a.defaultView) || window;
|
|
33
|
+
}
|
|
34
|
+
export { ownerDocument, ownerWindow };
|
|
35
|
+
//# sourceMappingURL=owner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"owner.js","sourceRoot":"","sources":["../../src/util/owner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,SAAS,aAAa,CAAC,IAAoB;IACzC,OAAO,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,aAAa,MAAI,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,QAAQ,CAAA,CAAC;AACrD,CAAC;AAED;;;;;;GAMG;AACH,SAAS,WAAW,CAAC,IAA+B;;IAClD,OAAO,CAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,aAAa,0CAAE,WAAW,KAAI,MAAM,CAAC;AACpD,CAAC;AAED,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@navikt/ds-react",
|
|
3
|
-
"version": "7.32.
|
|
3
|
+
"version": "7.32.2",
|
|
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.2",
|
|
654
|
+
"@navikt/ds-tokens": "^7.32.2",
|
|
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
|
|
|
@@ -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" });
|
|
@@ -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
|
}
|