@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.
Files changed (201) hide show
  1. package/cjs/copybutton/CopyButton.js +4 -9
  2. package/cjs/copybutton/CopyButton.js.map +1 -1
  3. package/cjs/form/combobox/Combobox.js +1 -3
  4. package/cjs/form/combobox/Combobox.js.map +1 -1
  5. package/cjs/form/combobox/ComboboxWrapper.d.ts +1 -2
  6. package/cjs/form/combobox/ComboboxWrapper.js +1 -2
  7. package/cjs/form/combobox/ComboboxWrapper.js.map +1 -1
  8. package/cjs/form/combobox/FilteredOptions/FilteredOptions.js +28 -19
  9. package/cjs/form/combobox/FilteredOptions/FilteredOptions.js.map +1 -1
  10. package/cjs/form/combobox/FilteredOptions/useVirtualFocus.js.map +1 -1
  11. package/cjs/form/combobox/Input/Input.context.d.ts +2 -0
  12. package/cjs/form/combobox/Input/Input.context.js +4 -1
  13. package/cjs/form/combobox/Input/Input.context.js.map +1 -1
  14. package/cjs/form/combobox/Input/InputController.js +2 -2
  15. package/cjs/form/combobox/Input/InputController.js.map +1 -1
  16. package/cjs/help-text/HelpText.js +3 -3
  17. package/cjs/help-text/HelpText.js.map +1 -1
  18. package/cjs/help-text/HelpTextIcon.d.ts +1 -2
  19. package/cjs/help-text/HelpTextIcon.js +3 -7
  20. package/cjs/help-text/HelpTextIcon.js.map +1 -1
  21. package/cjs/layout/page/parts/PageBlock.d.ts +9 -6
  22. package/cjs/layout/page/parts/PageBlock.js.map +1 -1
  23. package/cjs/modal/ModalUtils.js +6 -4
  24. package/cjs/modal/ModalUtils.js.map +1 -1
  25. package/cjs/overlays/dismissablelayer/DismissableLayer.js +9 -19
  26. package/cjs/overlays/dismissablelayer/DismissableLayer.js.map +1 -1
  27. package/cjs/overlays/dismissablelayer/util/usePointerDownOutside.js +5 -4
  28. package/cjs/overlays/dismissablelayer/util/usePointerDownOutside.js.map +1 -1
  29. package/cjs/overlays/floating-menu/Menu.d.ts +4 -4
  30. package/cjs/overlays/floating-menu/Menu.js +7 -4
  31. package/cjs/overlays/floating-menu/Menu.js.map +1 -1
  32. package/cjs/overlays/floating-menu/parts/RovingFocus.js +3 -3
  33. package/cjs/overlays/floating-menu/parts/RovingFocus.js.map +1 -1
  34. package/cjs/overlays/overlay/hooks/useAnimationsFinished.js +1 -1
  35. package/cjs/overlays/overlay/hooks/useAnimationsFinished.js.map +1 -1
  36. package/cjs/overlays/overlay/hooks/useOpenChangeAnimationComplete.js +2 -2
  37. package/cjs/overlays/overlay/hooks/useOpenChangeAnimationComplete.js.map +1 -1
  38. package/cjs/progress-bar/ProgressBar.js +9 -6
  39. package/cjs/progress-bar/ProgressBar.js.map +1 -1
  40. package/cjs/table/AnimateHeight.js +12 -13
  41. package/cjs/table/AnimateHeight.js.map +1 -1
  42. package/cjs/tabs/parts/tablist/useScrollButtons.d.ts +1 -1
  43. package/cjs/tabs/parts/tablist/useScrollButtons.js +4 -4
  44. package/cjs/tabs/parts/tablist/useScrollButtons.js.map +1 -1
  45. package/cjs/util/TextareaAutoSize.js +3 -10
  46. package/cjs/util/TextareaAutoSize.js.map +1 -1
  47. package/cjs/util/create-context.d.ts +0 -1
  48. package/cjs/util/create-context.js.map +1 -1
  49. package/cjs/util/debounce.d.ts +1 -1
  50. package/cjs/util/debounce.js +5 -8
  51. package/cjs/util/debounce.js.map +1 -1
  52. package/cjs/util/detectBrowser.d.ts +2 -0
  53. package/cjs/util/detectBrowser.js +7 -0
  54. package/cjs/util/detectBrowser.js.map +1 -0
  55. package/cjs/util/focus-boundary/FocusBoundary.d.ts +44 -0
  56. package/cjs/util/focus-boundary/FocusBoundary.js +365 -0
  57. package/cjs/util/focus-boundary/FocusBoundary.js.map +1 -0
  58. package/cjs/util/focus-guards/FocusGuards.d.ts +8 -0
  59. package/cjs/util/focus-guards/FocusGuards.js +36 -0
  60. package/cjs/util/focus-guards/FocusGuards.js.map +1 -0
  61. package/cjs/util/hooks/useEventCallback.js.map +1 -0
  62. package/cjs/{overlays/overlay → util}/hooks/useLatestRef.js +2 -2
  63. package/cjs/util/hooks/useLatestRef.js.map +1 -0
  64. package/cjs/util/hooks/useRefWithInit.js.map +1 -0
  65. package/cjs/util/hooks/useTimeout.d.ts +16 -0
  66. package/cjs/util/hooks/useTimeout.js +49 -0
  67. package/cjs/util/hooks/useTimeout.js.map +1 -0
  68. package/cjs/util/link-anchor/LinkAnchor.js +6 -7
  69. package/cjs/util/link-anchor/LinkAnchor.js.map +1 -1
  70. package/cjs/util/owner.d.ts +29 -0
  71. package/cjs/util/owner.js +38 -0
  72. package/cjs/util/owner.js.map +1 -0
  73. package/esm/copybutton/CopyButton.js +5 -10
  74. package/esm/copybutton/CopyButton.js.map +1 -1
  75. package/esm/form/combobox/Combobox.js +1 -3
  76. package/esm/form/combobox/Combobox.js.map +1 -1
  77. package/esm/form/combobox/ComboboxWrapper.d.ts +1 -2
  78. package/esm/form/combobox/ComboboxWrapper.js +1 -2
  79. package/esm/form/combobox/ComboboxWrapper.js.map +1 -1
  80. package/esm/form/combobox/FilteredOptions/FilteredOptions.js +29 -20
  81. package/esm/form/combobox/FilteredOptions/FilteredOptions.js.map +1 -1
  82. package/esm/form/combobox/FilteredOptions/useVirtualFocus.js.map +1 -1
  83. package/esm/form/combobox/Input/Input.context.d.ts +2 -0
  84. package/esm/form/combobox/Input/Input.context.js +4 -1
  85. package/esm/form/combobox/Input/Input.context.js.map +1 -1
  86. package/esm/form/combobox/Input/InputController.js +2 -2
  87. package/esm/form/combobox/Input/InputController.js.map +1 -1
  88. package/esm/help-text/HelpText.js +3 -3
  89. package/esm/help-text/HelpText.js.map +1 -1
  90. package/esm/help-text/HelpTextIcon.d.ts +1 -2
  91. package/esm/help-text/HelpTextIcon.js +3 -7
  92. package/esm/help-text/HelpTextIcon.js.map +1 -1
  93. package/esm/layout/page/parts/PageBlock.d.ts +9 -6
  94. package/esm/layout/page/parts/PageBlock.js.map +1 -1
  95. package/esm/modal/ModalUtils.js +6 -4
  96. package/esm/modal/ModalUtils.js.map +1 -1
  97. package/esm/overlays/dismissablelayer/DismissableLayer.js +9 -19
  98. package/esm/overlays/dismissablelayer/DismissableLayer.js.map +1 -1
  99. package/esm/overlays/dismissablelayer/util/usePointerDownOutside.js +5 -4
  100. package/esm/overlays/dismissablelayer/util/usePointerDownOutside.js.map +1 -1
  101. package/esm/overlays/floating-menu/Menu.d.ts +4 -4
  102. package/esm/overlays/floating-menu/Menu.js +7 -4
  103. package/esm/overlays/floating-menu/Menu.js.map +1 -1
  104. package/esm/overlays/floating-menu/parts/RovingFocus.js +3 -3
  105. package/esm/overlays/floating-menu/parts/RovingFocus.js.map +1 -1
  106. package/esm/overlays/overlay/hooks/useAnimationsFinished.js +1 -1
  107. package/esm/overlays/overlay/hooks/useAnimationsFinished.js.map +1 -1
  108. package/esm/overlays/overlay/hooks/useOpenChangeAnimationComplete.js +2 -2
  109. package/esm/overlays/overlay/hooks/useOpenChangeAnimationComplete.js.map +1 -1
  110. package/esm/progress-bar/ProgressBar.js +10 -7
  111. package/esm/progress-bar/ProgressBar.js.map +1 -1
  112. package/esm/table/AnimateHeight.js +12 -13
  113. package/esm/table/AnimateHeight.js.map +1 -1
  114. package/esm/tabs/parts/tablist/useScrollButtons.d.ts +1 -1
  115. package/esm/tabs/parts/tablist/useScrollButtons.js +4 -4
  116. package/esm/tabs/parts/tablist/useScrollButtons.js.map +1 -1
  117. package/esm/util/TextareaAutoSize.js +1 -8
  118. package/esm/util/TextareaAutoSize.js.map +1 -1
  119. package/esm/util/create-context.d.ts +0 -1
  120. package/esm/util/create-context.js.map +1 -1
  121. package/esm/util/debounce.d.ts +1 -1
  122. package/esm/util/debounce.js +5 -8
  123. package/esm/util/debounce.js.map +1 -1
  124. package/esm/util/detectBrowser.d.ts +2 -0
  125. package/esm/util/detectBrowser.js +4 -0
  126. package/esm/util/detectBrowser.js.map +1 -0
  127. package/esm/util/focus-boundary/FocusBoundary.d.ts +44 -0
  128. package/esm/util/focus-boundary/FocusBoundary.js +329 -0
  129. package/esm/util/focus-boundary/FocusBoundary.js.map +1 -0
  130. package/esm/util/focus-guards/FocusGuards.d.ts +8 -0
  131. package/esm/util/focus-guards/FocusGuards.js +31 -0
  132. package/esm/util/focus-guards/FocusGuards.js.map +1 -0
  133. package/esm/util/hooks/useEventCallback.js.map +1 -0
  134. package/esm/{overlays/overlay → util}/hooks/useLatestRef.js +1 -1
  135. package/esm/util/hooks/useLatestRef.js.map +1 -0
  136. package/esm/util/hooks/useRefWithInit.js.map +1 -0
  137. package/esm/util/hooks/useTimeout.d.ts +16 -0
  138. package/esm/util/hooks/useTimeout.js +45 -0
  139. package/esm/util/hooks/useTimeout.js.map +1 -0
  140. package/esm/util/link-anchor/LinkAnchor.js +6 -7
  141. package/esm/util/link-anchor/LinkAnchor.js.map +1 -1
  142. package/esm/util/owner.d.ts +29 -0
  143. package/esm/util/owner.js +35 -0
  144. package/esm/util/owner.js.map +1 -0
  145. package/package.json +8 -8
  146. package/src/copybutton/CopyButton.tsx +5 -17
  147. package/src/form/combobox/Combobox.tsx +0 -4
  148. package/src/form/combobox/ComboboxWrapper.tsx +0 -3
  149. package/src/form/combobox/FilteredOptions/FilteredOptions.tsx +65 -45
  150. package/src/form/combobox/FilteredOptions/useVirtualFocus.ts +1 -0
  151. package/src/form/combobox/Input/Input.context.tsx +5 -0
  152. package/src/form/combobox/Input/InputController.tsx +2 -1
  153. package/src/form/file-upload/parts/item/utils/format-file-size.test.ts +2 -2
  154. package/src/help-text/HelpText.tsx +3 -2
  155. package/src/help-text/HelpTextIcon.tsx +2 -12
  156. package/src/layout/page/parts/PageBlock.tsx +9 -6
  157. package/src/modal/ModalUtils.ts +7 -4
  158. package/src/overlays/dismissablelayer/DismissableLayer.tsx +9 -18
  159. package/src/overlays/dismissablelayer/util/usePointerDownOutside.ts +5 -4
  160. package/src/overlays/floating-menu/Menu.tsx +13 -9
  161. package/src/overlays/floating-menu/parts/RovingFocus.tsx +3 -3
  162. package/src/overlays/overlay/hooks/useAnimationsFinished.ts +1 -1
  163. package/src/overlays/overlay/hooks/useOpenChangeAnimationComplete.ts +2 -2
  164. package/src/progress-bar/ProgressBar.tsx +12 -10
  165. package/src/table/AnimateHeight.tsx +12 -15
  166. package/src/tabs/parts/tablist/useScrollButtons.ts +4 -3
  167. package/src/util/TextareaAutoSize.tsx +1 -9
  168. package/src/util/create-context.tsx +0 -1
  169. package/src/util/debounce.ts +7 -8
  170. package/src/util/detectBrowser.ts +5 -0
  171. package/src/util/focus-boundary/FocusBoundary.tsx +453 -0
  172. package/src/util/focus-guards/FocusGuards.tsx +56 -0
  173. package/src/{overlays/overlay → util}/hooks/useLatestRef.ts +1 -1
  174. package/src/util/hooks/useTimeout.ts +54 -0
  175. package/src/util/link-anchor/LinkAnchor.tsx +7 -6
  176. package/src/util/owner.ts +35 -0
  177. package/cjs/overlays/floating-menu/parts/FocusScope.d.ts +0 -22
  178. package/cjs/overlays/floating-menu/parts/FocusScope.js +0 -98
  179. package/cjs/overlays/floating-menu/parts/FocusScope.js.map +0 -1
  180. package/cjs/overlays/overlay/hooks/useEventCallback.js.map +0 -1
  181. package/cjs/overlays/overlay/hooks/useLatestRef.js.map +0 -1
  182. package/cjs/overlays/overlay/hooks/useRefWithInit.js.map +0 -1
  183. package/esm/overlays/floating-menu/parts/FocusScope.d.ts +0 -22
  184. package/esm/overlays/floating-menu/parts/FocusScope.js +0 -62
  185. package/esm/overlays/floating-menu/parts/FocusScope.js.map +0 -1
  186. package/esm/overlays/overlay/hooks/useEventCallback.js.map +0 -1
  187. package/esm/overlays/overlay/hooks/useLatestRef.js.map +0 -1
  188. package/esm/overlays/overlay/hooks/useRefWithInit.js.map +0 -1
  189. package/src/overlays/floating-menu/parts/FocusScope.tsx +0 -83
  190. /package/cjs/{overlays/overlay → util}/hooks/useEventCallback.d.ts +0 -0
  191. /package/cjs/{overlays/overlay → util}/hooks/useEventCallback.js +0 -0
  192. /package/cjs/{overlays/overlay → util}/hooks/useLatestRef.d.ts +0 -0
  193. /package/cjs/{overlays/overlay → util}/hooks/useRefWithInit.d.ts +0 -0
  194. /package/cjs/{overlays/overlay → util}/hooks/useRefWithInit.js +0 -0
  195. /package/esm/{overlays/overlay → util}/hooks/useEventCallback.d.ts +0 -0
  196. /package/esm/{overlays/overlay → util}/hooks/useEventCallback.js +0 -0
  197. /package/esm/{overlays/overlay → util}/hooks/useLatestRef.d.ts +0 -0
  198. /package/esm/{overlays/overlay → util}/hooks/useRefWithInit.d.ts +0 -0
  199. /package/esm/{overlays/overlay → util}/hooks/useRefWithInit.js +0 -0
  200. /package/src/{overlays/overlay → util}/hooks/useEventCallback.ts +0 -0
  201. /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 || isTextSelected()) {
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
- if (typeof window === "undefined") {
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":"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"}
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.1",
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.0.9",
653
- "@navikt/aksel-icons": "^7.32.1",
654
- "@navikt/ds-tokens": "^7.32.1",
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.0",
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.8.3",
678
- "vitest": "^2.1.9"
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
- timeoutRef.current = window.setTimeout(() => {
104
+ timeout.start(activeDuration, () => {
117
105
  setActive(false);
118
106
  onActiveChange?.(false);
119
- }, activeDuration);
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
- <Floating.Content
57
- className={cn("navds-combobox__list", {
58
- "navds-combobox__list--closed": !isListOpen,
59
- "navds-combobox__list--with-hover": isMouseLastUsedInputDevice,
60
- })}
61
- id={filteredOptionsUtil.getFilteredOptionsId(id)}
62
- tabIndex={-1}
63
- sideOffset={8}
64
- side="bottom"
65
- fallbackPlacements={["top"]}
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
- autoUpdateWhileMounted={false}
72
+ enabled={localOpen}
73
73
  >
74
- {shouldRenderNonSelectables && (
75
- <div
76
- className={cn("navds-combobox__list_non-selectables")}
77
- role="status"
78
- >
79
- {isMultiSelect && maxSelected.limit && <MaxSelectedMessage />}
80
- {isLoading && <LoadingMessage />}
81
- {!isLoading && filteredOptions.length === 0 && !allowNewValues && (
82
- <NoSearchHitsMessage />
83
- )}
84
- </div>
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
- {shouldRenderFilteredOptionsList && (
88
- /* biome-ignore lint/a11y/useFocusableInteractive: Interaction is not handeled by listbox itself. */
89
- <ul
90
- ref={setFilteredOptionsRef}
91
- role="listbox"
92
- className={cn("navds-combobox__list-options")}
93
- >
94
- {isValueNew && !maxSelected.isLimitReached && allowNewValues && (
95
- <AddNewOption />
96
- )}
97
- {filteredOptions.map((option) => (
98
- <FilteredOptionsItem key={option.value} option={option} />
99
- ))}
100
- </ul>
101
- )}
102
- </Floating.Content>
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
 
@@ -67,6 +67,7 @@ const useVirtualFocus = (
67
67
 
68
68
  if (!activeElement) {
69
69
  setActiveAndScrollToElement(elementsAbleToReceiveFocus[0]);
70
+
70
71
  return;
71
72
  }
72
73
  const _currentIndex = elementsAbleToReceiveFocus.indexOf(activeElement);
@@ -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: Uint8Array[] = [];
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 title={titleWithFallback} />
75
- <HelpTextIcon filled title={titleWithFallback} />
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
- * @example
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
- * @example
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;
@@ -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
- document.body.classList.add(BODY_CLASS, BODY_CLASS_LEGACY);
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
- document.body.classList.add(BODY_CLASS, BODY_CLASS_LEGACY);
58
+ ownerDoc.body.classList.add(BODY_CLASS, BODY_CLASS_LEGACY);
56
59
  } else {
57
- document.body.classList.remove(BODY_CLASS, BODY_CLASS_LEGACY);
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
- document.body.classList.remove(BODY_CLASS, BODY_CLASS_LEGACY);
72
+ ownerDoc.body.classList.remove(BODY_CLASS, BODY_CLASS_LEGACY);
70
73
  };
71
74
  }, [modalRef, portalNode, isNested]);
72
75
  }