@navikt/ds-react 6.14.0 → 6.15.0

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 (84) hide show
  1. package/cjs/form/combobox/FilteredOptions/AddNewOption.d.ts +3 -0
  2. package/cjs/form/combobox/FilteredOptions/AddNewOption.js +41 -0
  3. package/cjs/form/combobox/FilteredOptions/AddNewOption.js.map +1 -0
  4. package/cjs/form/combobox/FilteredOptions/FilteredOptions.js +13 -57
  5. package/cjs/form/combobox/FilteredOptions/FilteredOptions.js.map +1 -1
  6. package/cjs/form/combobox/FilteredOptions/FilteredOptionsItem.d.ts +6 -0
  7. package/cjs/form/combobox/FilteredOptions/FilteredOptionsItem.js +43 -0
  8. package/cjs/form/combobox/FilteredOptions/FilteredOptionsItem.js.map +1 -0
  9. package/cjs/form/combobox/FilteredOptions/LoadingMessage.d.ts +3 -0
  10. package/cjs/form/combobox/FilteredOptions/LoadingMessage.js +16 -0
  11. package/cjs/form/combobox/FilteredOptions/LoadingMessage.js.map +1 -0
  12. package/cjs/form/combobox/FilteredOptions/MaxSelectedMessage.d.ts +3 -0
  13. package/cjs/form/combobox/FilteredOptions/MaxSelectedMessage.js +20 -0
  14. package/cjs/form/combobox/FilteredOptions/MaxSelectedMessage.js.map +1 -0
  15. package/cjs/form/combobox/FilteredOptions/NoSearchHitsMessage.d.ts +3 -0
  16. package/cjs/form/combobox/FilteredOptions/NoSearchHitsMessage.js +14 -0
  17. package/cjs/form/combobox/FilteredOptions/NoSearchHitsMessage.js.map +1 -0
  18. package/cjs/form/combobox/Input/Input.d.ts +1 -0
  19. package/cjs/form/combobox/Input/Input.js +3 -2
  20. package/cjs/form/combobox/Input/Input.js.map +1 -1
  21. package/cjs/form/combobox/Input/InputController.js +1 -1
  22. package/cjs/form/combobox/Input/InputController.js.map +1 -1
  23. package/cjs/overlays/floating-menu/Menu.d.ts +106 -0
  24. package/cjs/overlays/floating-menu/Menu.js +593 -0
  25. package/cjs/overlays/floating-menu/Menu.js.map +1 -0
  26. package/cjs/overlays/floating-menu/parts/FocusScope.d.ts +22 -0
  27. package/cjs/overlays/floating-menu/parts/FocusScope.js +89 -0
  28. package/cjs/overlays/floating-menu/parts/FocusScope.js.map +1 -0
  29. package/cjs/overlays/floating-menu/parts/RovingFocus.d.ts +9 -0
  30. package/cjs/overlays/floating-menu/parts/RovingFocus.js +112 -0
  31. package/cjs/overlays/floating-menu/parts/RovingFocus.js.map +1 -0
  32. package/cjs/overlays/floating-menu/parts/SlottedDivElement.d.ts +7 -0
  33. package/cjs/overlays/floating-menu/parts/SlottedDivElement.js +46 -0
  34. package/cjs/overlays/floating-menu/parts/SlottedDivElement.js.map +1 -0
  35. package/cjs/util/composeEventHandlers.d.ts +1 -1
  36. package/esm/form/combobox/FilteredOptions/AddNewOption.d.ts +3 -0
  37. package/esm/form/combobox/FilteredOptions/AddNewOption.js +36 -0
  38. package/esm/form/combobox/FilteredOptions/AddNewOption.js.map +1 -0
  39. package/esm/form/combobox/FilteredOptions/FilteredOptions.js +13 -57
  40. package/esm/form/combobox/FilteredOptions/FilteredOptions.js.map +1 -1
  41. package/esm/form/combobox/FilteredOptions/FilteredOptionsItem.d.ts +6 -0
  42. package/esm/form/combobox/FilteredOptions/FilteredOptionsItem.js +38 -0
  43. package/esm/form/combobox/FilteredOptions/FilteredOptionsItem.js.map +1 -0
  44. package/esm/form/combobox/FilteredOptions/LoadingMessage.d.ts +3 -0
  45. package/esm/form/combobox/FilteredOptions/LoadingMessage.js +11 -0
  46. package/esm/form/combobox/FilteredOptions/LoadingMessage.js.map +1 -0
  47. package/esm/form/combobox/FilteredOptions/MaxSelectedMessage.d.ts +3 -0
  48. package/esm/form/combobox/FilteredOptions/MaxSelectedMessage.js +15 -0
  49. package/esm/form/combobox/FilteredOptions/MaxSelectedMessage.js.map +1 -0
  50. package/esm/form/combobox/FilteredOptions/NoSearchHitsMessage.d.ts +3 -0
  51. package/esm/form/combobox/FilteredOptions/NoSearchHitsMessage.js +9 -0
  52. package/esm/form/combobox/FilteredOptions/NoSearchHitsMessage.js.map +1 -0
  53. package/esm/form/combobox/Input/Input.d.ts +1 -0
  54. package/esm/form/combobox/Input/Input.js +3 -2
  55. package/esm/form/combobox/Input/Input.js.map +1 -1
  56. package/esm/form/combobox/Input/InputController.js +1 -1
  57. package/esm/form/combobox/Input/InputController.js.map +1 -1
  58. package/esm/overlays/floating-menu/Menu.d.ts +106 -0
  59. package/esm/overlays/floating-menu/Menu.js +551 -0
  60. package/esm/overlays/floating-menu/Menu.js.map +1 -0
  61. package/esm/overlays/floating-menu/parts/FocusScope.d.ts +22 -0
  62. package/esm/overlays/floating-menu/parts/FocusScope.js +63 -0
  63. package/esm/overlays/floating-menu/parts/FocusScope.js.map +1 -0
  64. package/esm/overlays/floating-menu/parts/RovingFocus.d.ts +9 -0
  65. package/esm/overlays/floating-menu/parts/RovingFocus.js +86 -0
  66. package/esm/overlays/floating-menu/parts/RovingFocus.js.map +1 -0
  67. package/esm/overlays/floating-menu/parts/SlottedDivElement.d.ts +7 -0
  68. package/esm/overlays/floating-menu/parts/SlottedDivElement.js +20 -0
  69. package/esm/overlays/floating-menu/parts/SlottedDivElement.js.map +1 -0
  70. package/esm/util/composeEventHandlers.d.ts +1 -1
  71. package/package.json +3 -3
  72. package/src/form/combobox/FilteredOptions/AddNewOption.tsx +63 -0
  73. package/src/form/combobox/FilteredOptions/FilteredOptions.tsx +11 -121
  74. package/src/form/combobox/FilteredOptions/FilteredOptionsItem.tsx +73 -0
  75. package/src/form/combobox/FilteredOptions/LoadingMessage.tsx +20 -0
  76. package/src/form/combobox/FilteredOptions/MaxSelectedMessage.tsx +27 -0
  77. package/src/form/combobox/FilteredOptions/NoSearchHitsMessage.tsx +19 -0
  78. package/src/form/combobox/Input/Input.tsx +4 -2
  79. package/src/form/combobox/Input/InputController.tsx +1 -0
  80. package/src/overlays/floating-menu/Menu.tsx +1177 -0
  81. package/src/overlays/floating-menu/parts/FocusScope.tsx +84 -0
  82. package/src/overlays/floating-menu/parts/RovingFocus.tsx +121 -0
  83. package/src/overlays/floating-menu/parts/SlottedDivElement.tsx +17 -0
  84. package/src/util/composeEventHandlers.ts +1 -1
@@ -0,0 +1,63 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import * as React from "react";
13
+ import { forwardRef, useEffect, useState } from "react";
14
+ import { Slot } from "../../../slot/Slot.js";
15
+ import { useCallbackRef, useMergeRefs } from "../../../util/hooks/index.js";
16
+ const AUTOFOCUS_ON_MOUNT = "focusScope.autoFocusOnMount";
17
+ const AUTOFOCUS_ON_UNMOUNT = "focusScope.autoFocusOnUnmount";
18
+ const EVENT_OPTIONS = { bubbles: false, cancelable: true };
19
+ /**
20
+ * FocusScope manages focus on mount and unmount of container.
21
+ * This is used to better handle autofocus of elements when mounted and unmounted.
22
+ * Example usage:
23
+ * - Focus first item in a list when mounted
24
+ * - Focus a button when unmounted
25
+ */
26
+ const FocusScope = forwardRef((_a, ref) => {
27
+ var { onMountHandler: onMountHandlerCallback, onUnmountHandler: onUnmountHandlerCallback } = _a, rest = __rest(_a, ["onMountHandler", "onUnmountHandler"]);
28
+ const [container, setContainer] = useState(null);
29
+ const onMountHandler = useCallbackRef(onMountHandlerCallback);
30
+ const onUnmountHandler = useCallbackRef(onUnmountHandlerCallback);
31
+ const composedRefs = useMergeRefs(ref, setContainer);
32
+ useEffect(() => {
33
+ var _a;
34
+ if (!container)
35
+ return;
36
+ const ownerDocument = (_a = container.ownerDocument) !== null && _a !== void 0 ? _a : globalThis === null || globalThis === void 0 ? void 0 : globalThis.document;
37
+ const hasFocus = container.contains(ownerDocument.activeElement);
38
+ if (!hasFocus) {
39
+ const mountEvent = new CustomEvent(AUTOFOCUS_ON_MOUNT, EVENT_OPTIONS);
40
+ container.addEventListener(AUTOFOCUS_ON_MOUNT, onMountHandler);
41
+ container.dispatchEvent(mountEvent);
42
+ }
43
+ return () => {
44
+ container.removeEventListener(AUTOFOCUS_ON_MOUNT, onMountHandler);
45
+ /**
46
+ * https://github.com/facebook/react/issues/17894
47
+ * As usual when dealing with focus and useEffect,
48
+ * we need to defer the focus to the next event-loop
49
+ * setTimeout makes sure the code is ran after the next render-cycle
50
+ */
51
+ setTimeout(() => {
52
+ const unmountEvent = new CustomEvent(AUTOFOCUS_ON_UNMOUNT, EVENT_OPTIONS);
53
+ container.addEventListener(AUTOFOCUS_ON_UNMOUNT, onUnmountHandler);
54
+ container.dispatchEvent(unmountEvent);
55
+ // we need to remove the listener after we `dispatchEvent`
56
+ container.removeEventListener(AUTOFOCUS_ON_UNMOUNT, onUnmountHandler);
57
+ }, 0);
58
+ };
59
+ }, [container, onMountHandler, onUnmountHandler]);
60
+ return React.createElement(Slot, Object.assign({ tabIndex: -1 }, rest, { ref: composedRefs }));
61
+ });
62
+ export { FocusScope };
63
+ //# sourceMappingURL=FocusScope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FocusScope.js","sourceRoot":"","sources":["../../../../src/overlays/floating-menu/parts/FocusScope.tsx"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnE,MAAM,kBAAkB,GAAG,6BAA6B,CAAC;AACzD,MAAM,oBAAoB,GAAG,+BAA+B,CAAC;AAC7D,MAAM,aAAa,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;AAe3D;;;;;;GAMG;AACH,MAAM,UAAU,GAAG,UAAU,CAC3B,CACE,EAIC,EACD,GAAG,EACH,EAAE;QANF,EACE,cAAc,EAAE,sBAAsB,EACtC,gBAAgB,EAAE,wBAAwB,OAE3C,EADI,IAAI,cAHT,sCAIC,CADQ;IAIT,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAqB,IAAI,CAAC,CAAC;IACrE,MAAM,cAAc,GAAG,cAAc,CAAC,sBAAsB,CAAC,CAAC;IAC9D,MAAM,gBAAgB,GAAG,cAAc,CAAC,wBAAwB,CAAC,CAAC;IAElE,MAAM,YAAY,GAAG,YAAY,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAErD,SAAS,CAAC,GAAG,EAAE;;QACb,IAAI,CAAC,SAAS;YAAE,OAAO;QAEvB,MAAM,aAAa,GAAG,MAAA,SAAS,CAAC,aAAa,mCAAI,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,QAAQ,CAAC;QACtE,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;QAEjE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,UAAU,GAAG,IAAI,WAAW,CAAC,kBAAkB,EAAE,aAAa,CAAC,CAAC;YACtE,SAAS,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAC;YAC/D,SAAS,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QACtC,CAAC;QAED,OAAO,GAAG,EAAE;YACV,SAAS,CAAC,mBAAmB,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAC;YAElE;;;;;eAKG;YACH,UAAU,CAAC,GAAG,EAAE;gBACd,MAAM,YAAY,GAAG,IAAI,WAAW,CAClC,oBAAoB,EACpB,aAAa,CACd,CAAC;gBACF,SAAS,CAAC,gBAAgB,CAAC,oBAAoB,EAAE,gBAAgB,CAAC,CAAC;gBACnE,SAAS,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;gBAEtC,0DAA0D;gBAC1D,SAAS,CAAC,mBAAmB,CAAC,oBAAoB,EAAE,gBAAgB,CAAC,CAAC;YACxE,CAAC,EAAE,CAAC,CAAC,CAAC;QACR,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,SAAS,EAAE,cAAc,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAElD,OAAO,oBAAC,IAAI,kBAAC,QAAQ,EAAE,CAAC,CAAC,IAAM,IAAI,IAAE,GAAG,EAAE,YAAY,IAAI,CAAC;AAC7D,CAAC,CACF,CAAC;AAEF,OAAO,EAAE,UAAU,EAAwB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { DescendantsManager } from "../../../util/hooks/descendants/descendant.js";
3
+ interface RovingFocusProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "tabIndex"> {
4
+ asChild?: boolean;
5
+ descendants: DescendantsManager<HTMLDivElement, object>;
6
+ onEntryFocus?: (event: Event) => void;
7
+ }
8
+ declare const RovingFocus: React.ForwardRefExoticComponent<RovingFocusProps & React.RefAttributes<HTMLDivElement>>;
9
+ export { RovingFocus, type RovingFocusProps };
@@ -0,0 +1,86 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import React, { forwardRef, useCallback, useEffect, useRef } from "react";
13
+ import { Slot } from "../../../slot/Slot.js";
14
+ import { composeEventHandlers } from "../../../util/composeEventHandlers.js";
15
+ import { useCallbackRef, useMergeRefs } from "../../../util/hooks/index.js";
16
+ const ENTRY_FOCUS = "rovingFocusGroup.onEntryFocus";
17
+ const EVENT_OPTIONS = { bubbles: false, cancelable: true };
18
+ const RovingFocus = forwardRef((_a, ref) => {
19
+ var { children, asChild, descendants, onKeyDown, onEntryFocus, onMouseDown, onFocus } = _a, rest = __rest(_a, ["children", "asChild", "descendants", "onKeyDown", "onEntryFocus", "onMouseDown", "onFocus"]);
20
+ const _ref = React.useRef(null);
21
+ const composedRefs = useMergeRefs(ref, _ref);
22
+ const handleEntryFocus = useCallbackRef(onEntryFocus);
23
+ const isMouseFocusRef = useRef(false);
24
+ useEffect(() => {
25
+ const node = _ref.current;
26
+ if (node) {
27
+ node.addEventListener(ENTRY_FOCUS, handleEntryFocus);
28
+ return () => node.removeEventListener(ENTRY_FOCUS, handleEntryFocus);
29
+ }
30
+ }, [handleEntryFocus]);
31
+ const handleKeyDown = useCallback((event) => {
32
+ var _a, _b;
33
+ const loop = false;
34
+ const ownerDocument = (_b = (_a = _ref === null || _ref === void 0 ? void 0 : _ref.current) === null || _a === void 0 ? void 0 : _a.ownerDocument) !== null && _b !== void 0 ? _b : globalThis === null || globalThis === void 0 ? void 0 : globalThis.document;
35
+ const idx = descendants
36
+ .values()
37
+ .findIndex((x) => x.node.isSameNode(ownerDocument.activeElement));
38
+ const nextItem = () => {
39
+ var _a;
40
+ const next = descendants.nextEnabled(idx, loop);
41
+ next && ((_a = next.node) === null || _a === void 0 ? void 0 : _a.focus());
42
+ };
43
+ const prevItem = () => {
44
+ var _a;
45
+ const prev = descendants.prevEnabled(idx, loop);
46
+ prev && ((_a = prev.node) === null || _a === void 0 ? void 0 : _a.focus());
47
+ };
48
+ const firstItem = () => {
49
+ var _a;
50
+ const first = descendants.firstEnabled();
51
+ first && ((_a = first.node) === null || _a === void 0 ? void 0 : _a.focus());
52
+ };
53
+ const lastItem = () => {
54
+ var _a;
55
+ const last = descendants.lastEnabled();
56
+ last && ((_a = last.node) === null || _a === void 0 ? void 0 : _a.focus());
57
+ };
58
+ const keyMap = {
59
+ ArrowUp: prevItem,
60
+ ArrowDown: nextItem,
61
+ Home: firstItem,
62
+ End: lastItem,
63
+ };
64
+ const action = keyMap[event.key];
65
+ if (action) {
66
+ event.preventDefault();
67
+ action(event);
68
+ }
69
+ }, [descendants]);
70
+ const Comp = asChild ? Slot : "div";
71
+ return (React.createElement(Comp, Object.assign({ ref: composedRefs }, rest, { tabIndex: descendants.enabledCount() === 0 ? -1 : 0, style: Object.assign({ outline: "none" }, rest.style), onKeyDown: composeEventHandlers(onKeyDown, handleKeyDown), onMouseDown: composeEventHandlers(onMouseDown, () => {
72
+ isMouseFocusRef.current = true;
73
+ }), onFocus: composeEventHandlers(onFocus, (event) => {
74
+ var _a;
75
+ if (event.target === event.currentTarget) {
76
+ const entryFocusEvent = new CustomEvent(ENTRY_FOCUS, EVENT_OPTIONS);
77
+ event.currentTarget.dispatchEvent(entryFocusEvent);
78
+ if (!entryFocusEvent.defaultPrevented) {
79
+ (_a = descendants.firstEnabled()) === null || _a === void 0 ? void 0 : _a.node.focus({ preventScroll: true });
80
+ }
81
+ }
82
+ isMouseFocusRef.current = false;
83
+ }) }), children));
84
+ });
85
+ export { RovingFocus };
86
+ //# sourceMappingURL=RovingFocus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RovingFocus.js","sourceRoot":"","sources":["../../../../src/overlays/floating-menu/parts/RovingFocus.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ interface SlottedDivProps extends React.HTMLAttributes<HTMLDivElement> {
3
+ asChild?: boolean;
4
+ }
5
+ declare const SlottedDivElement: React.ForwardRefExoticComponent<SlottedDivProps & React.RefAttributes<HTMLDivElement>>;
6
+ type SlottedDivElementRef = React.ElementRef<typeof SlottedDivElement>;
7
+ export { SlottedDivElement, type SlottedDivElementRef, type SlottedDivProps };
@@ -0,0 +1,20 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import React, { forwardRef } from "react";
13
+ import { Slot } from "../../../slot/Slot.js";
14
+ const SlottedDivElement = forwardRef((_a, forwardedRef) => {
15
+ var { asChild } = _a, rest = __rest(_a, ["asChild"]);
16
+ const Comp = asChild ? Slot : "div";
17
+ return React.createElement(Comp, Object.assign({}, rest, { ref: forwardedRef }));
18
+ });
19
+ export { SlottedDivElement };
20
+ //# sourceMappingURL=SlottedDivElement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SlottedDivElement.js","sourceRoot":"","sources":["../../../../src/overlays/floating-menu/parts/SlottedDivElement.tsx"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAM1C,MAAM,iBAAiB,GAAG,UAAU,CAClC,CAAC,EAAoB,EAAE,YAAY,EAAE,EAAE;QAAtC,EAAE,OAAO,OAAW,EAAN,IAAI,cAAlB,WAAoB,CAAF;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IACpC,OAAO,oBAAC,IAAI,oBAAK,IAAI,IAAE,GAAG,EAAE,YAAY,IAAI,CAAC;AAC/C,CAAC,CACF,CAAC;AAIF,OAAO,EAAE,iBAAiB,EAAmD,CAAC"}
@@ -2,6 +2,6 @@
2
2
  * Utility to consistently call original eventhandler, often from props and internal eventhandler
3
3
  * @internal
4
4
  */
5
- export declare function composeEventHandlers<T extends React.SyntheticEvent>(originalEventHandler?: (event: T) => void, ourEventHandler?: (event: T) => void, { checkForDefaultPrevented }?: {
5
+ export declare function composeEventHandlers<T extends React.SyntheticEvent | Event>(originalEventHandler?: (event: T) => void, ourEventHandler?: (event: T) => void, { checkForDefaultPrevented }?: {
6
6
  checkForDefaultPrevented?: boolean | undefined;
7
7
  }): (event: T) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@navikt/ds-react",
3
- "version": "6.14.0",
3
+ "version": "6.15.0",
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",
@@ -594,8 +594,8 @@
594
594
  "dependencies": {
595
595
  "@floating-ui/react": "0.25.4",
596
596
  "@floating-ui/react-dom": "^2.0.9",
597
- "@navikt/aksel-icons": "^6.14.0",
598
- "@navikt/ds-tokens": "^6.14.0",
597
+ "@navikt/aksel-icons": "^6.15.0",
598
+ "@navikt/ds-tokens": "^6.15.0",
599
599
  "clsx": "^2.1.0",
600
600
  "date-fns": "^3.0.0",
601
601
  "react-day-picker": "8.10.0"
@@ -0,0 +1,63 @@
1
+ import cl from "clsx";
2
+ import React from "react";
3
+ import { PlusIcon } from "@navikt/aksel-icons";
4
+ import { BodyShort, Label } from "../../../typography";
5
+ import { useInputContext } from "../Input/Input.context";
6
+ import { useSelectedOptionsContext } from "../SelectedOptions/selectedOptionsContext";
7
+ import { isInList, toComboboxOption } from "../combobox-utils";
8
+ import filteredOptionsUtil from "./filtered-options-util";
9
+ import { useFilteredOptionsContext } from "./filteredOptionsContext";
10
+
11
+ const AddNewOption = () => {
12
+ const {
13
+ inputProps: { id },
14
+ size,
15
+ value,
16
+ } = useInputContext();
17
+ const {
18
+ setIsMouseLastUsedInputDevice,
19
+ toggleIsListOpen,
20
+ activeDecendantId,
21
+ virtualFocus,
22
+ } = useFilteredOptionsContext();
23
+ const { isMultiSelect, selectedOptions, toggleOption } =
24
+ useSelectedOptionsContext();
25
+ return (
26
+ <li
27
+ tabIndex={-1}
28
+ onMouseMove={() => {
29
+ if (activeDecendantId !== filteredOptionsUtil.getAddNewOptionId(id)) {
30
+ virtualFocus.moveFocusToElement(
31
+ filteredOptionsUtil.getAddNewOptionId(id),
32
+ );
33
+ setIsMouseLastUsedInputDevice(true);
34
+ }
35
+ }}
36
+ onPointerUp={(event) => {
37
+ toggleOption(toComboboxOption(value), event);
38
+ if (!isMultiSelect && !isInList(value, selectedOptions))
39
+ toggleIsListOpen(false);
40
+ }}
41
+ id={filteredOptionsUtil.getAddNewOptionId(id)}
42
+ className={cl(
43
+ "navds-combobox__list-item navds-combobox__list-item--new-option",
44
+ {
45
+ "navds-combobox__list-item--new-option--focus":
46
+ activeDecendantId === filteredOptionsUtil.getAddNewOptionId(id),
47
+ },
48
+ )}
49
+ role="option"
50
+ aria-selected={false}
51
+ >
52
+ <PlusIcon aria-hidden />
53
+ <BodyShort size={size}>
54
+ Legg til{" "}
55
+ <Label as="span" size={size}>
56
+ &#8220;{value}&#8221;
57
+ </Label>
58
+ </BodyShort>
59
+ </li>
60
+ );
61
+ };
62
+
63
+ export default AddNewOption;
@@ -1,20 +1,18 @@
1
1
  import cl from "clsx";
2
2
  import React from "react";
3
- import { CheckmarkIcon, PlusIcon } from "@navikt/aksel-icons";
4
- import { Loader } from "../../../loader";
5
- import { BodyShort, Label } from "../../../typography";
6
3
  import { useInputContext } from "../Input/Input.context";
7
4
  import { useSelectedOptionsContext } from "../SelectedOptions/selectedOptionsContext";
8
- import { isInList, toComboboxOption } from "../combobox-utils";
9
- import { ComboboxOption } from "../types";
5
+ import AddNewOption from "./AddNewOption";
6
+ import FilteredOptionsItem from "./FilteredOptionsItem";
7
+ import LoadingMessage from "./LoadingMessage";
8
+ import MaxSelectedMessage from "./MaxSelectedMessage";
9
+ import NoSearchHitsMessage from "./NoSearchHitsMessage";
10
10
  import filteredOptionsUtil from "./filtered-options-util";
11
11
  import { useFilteredOptionsContext } from "./filteredOptionsContext";
12
12
 
13
13
  const FilteredOptions = () => {
14
14
  const {
15
15
  inputProps: { id },
16
- size,
17
- value,
18
16
  } = useInputContext();
19
17
  const {
20
18
  allowNewValues,
@@ -23,17 +21,9 @@ const FilteredOptions = () => {
23
21
  filteredOptions,
24
22
  setFilteredOptionsRef,
25
23
  isMouseLastUsedInputDevice,
26
- setIsMouseLastUsedInputDevice,
27
24
  isValueNew,
28
- toggleIsListOpen,
29
- activeDecendantId,
30
- virtualFocus,
31
25
  } = useFilteredOptionsContext();
32
- const { isMultiSelect, selectedOptions, toggleOption, maxSelected } =
33
- useSelectedOptionsContext();
34
-
35
- const isDisabled = (option: ComboboxOption) =>
36
- maxSelected?.isLimitReached && !isInList(option.value, selectedOptions);
26
+ const { maxSelected } = useSelectedOptionsContext();
37
27
 
38
28
  const shouldRenderNonSelectables =
39
29
  maxSelected?.isLimitReached || // Render maxSelected message
@@ -55,30 +45,10 @@ const FilteredOptions = () => {
55
45
  >
56
46
  {shouldRenderNonSelectables && (
57
47
  <div className="navds-combobox__list_non-selectables" role="status">
58
- {maxSelected?.isLimitReached && (
59
- <div
60
- className="navds-combobox__list-item--max-selected"
61
- id={filteredOptionsUtil.getMaxSelectedOptionsId(id)}
62
- >
63
- {maxSelected.message ??
64
- `${selectedOptions.length} av ${maxSelected.limit} er valgt.`}
65
- </div>
66
- )}
67
- {isLoading && (
68
- <div
69
- className="navds-combobox__list-item--loading"
70
- id={filteredOptionsUtil.getIsLoadingId(id)}
71
- >
72
- <Loader title="Søker..." />
73
- </div>
74
- )}
48
+ {maxSelected?.isLimitReached && <MaxSelectedMessage />}
49
+ {isLoading && <LoadingMessage />}
75
50
  {!isLoading && filteredOptions.length === 0 && !allowNewValues && (
76
- <div
77
- className="navds-combobox__list-item--no-options"
78
- id={filteredOptionsUtil.getNoHitsId(id)}
79
- >
80
- Ingen søketreff
81
- </div>
51
+ <NoSearchHitsMessage />
82
52
  )}
83
53
  </div>
84
54
  )}
@@ -90,90 +60,10 @@ const FilteredOptions = () => {
90
60
  className="navds-combobox__list-options"
91
61
  >
92
62
  {isValueNew && !maxSelected?.isLimitReached && allowNewValues && (
93
- <li
94
- tabIndex={-1}
95
- onMouseMove={() => {
96
- if (
97
- activeDecendantId !==
98
- filteredOptionsUtil.getAddNewOptionId(id)
99
- ) {
100
- virtualFocus.moveFocusToElement(
101
- filteredOptionsUtil.getAddNewOptionId(id),
102
- );
103
- setIsMouseLastUsedInputDevice(true);
104
- }
105
- }}
106
- onPointerUp={(event) => {
107
- toggleOption(toComboboxOption(value), event);
108
- if (!isMultiSelect && !isInList(value, selectedOptions))
109
- toggleIsListOpen(false);
110
- }}
111
- id={filteredOptionsUtil.getAddNewOptionId(id)}
112
- className={cl(
113
- "navds-combobox__list-item navds-combobox__list-item--new-option",
114
- {
115
- "navds-combobox__list-item--new-option--focus":
116
- activeDecendantId ===
117
- filteredOptionsUtil.getAddNewOptionId(id),
118
- },
119
- )}
120
- role="option"
121
- aria-selected={false}
122
- >
123
- <PlusIcon aria-hidden />
124
- <BodyShort size={size}>
125
- Legg til{" "}
126
- <Label as="span" size={size}>
127
- &#8220;{value}&#8221;
128
- </Label>
129
- </BodyShort>
130
- </li>
63
+ <AddNewOption />
131
64
  )}
132
65
  {filteredOptions.map((option) => (
133
- <li
134
- className={cl("navds-combobox__list-item", {
135
- "navds-combobox__list-item--focus":
136
- activeDecendantId ===
137
- filteredOptionsUtil.getOptionId(id, option.label),
138
- "navds-combobox__list-item--selected": isInList(
139
- option.value,
140
- selectedOptions,
141
- ),
142
- })}
143
- data-no-focus={isDisabled(option) || undefined}
144
- id={filteredOptionsUtil.getOptionId(id, option.label)}
145
- key={option.label}
146
- tabIndex={-1}
147
- onMouseMove={() => {
148
- if (
149
- activeDecendantId !==
150
- filteredOptionsUtil.getOptionId(id, option.label)
151
- ) {
152
- virtualFocus.moveFocusToElement(
153
- filteredOptionsUtil.getOptionId(id, option.label),
154
- );
155
- setIsMouseLastUsedInputDevice(true);
156
- }
157
- }}
158
- onPointerUp={(event) => {
159
- if (isDisabled(option)) {
160
- return;
161
- }
162
- toggleOption(option, event);
163
- if (
164
- !isMultiSelect &&
165
- !isInList(option.value, selectedOptions)
166
- ) {
167
- toggleIsListOpen(false);
168
- }
169
- }}
170
- role="option"
171
- aria-selected={isInList(option.value, selectedOptions)}
172
- aria-disabled={isDisabled(option) || undefined}
173
- >
174
- <BodyShort size={size}>{option.label}</BodyShort>
175
- {isInList(option.value, selectedOptions) && <CheckmarkIcon />}
176
- </li>
66
+ <FilteredOptionsItem key={option.value} option={option} />
177
67
  ))}
178
68
  </ul>
179
69
  )}
@@ -0,0 +1,73 @@
1
+ import cl from "clsx";
2
+ import React from "react";
3
+ import { CheckmarkIcon } from "@navikt/aksel-icons";
4
+ import { BodyShort } from "../../../typography";
5
+ import { useInputContext } from "../Input/Input.context";
6
+ import { useSelectedOptionsContext } from "../SelectedOptions/selectedOptionsContext";
7
+ import { isInList } from "../combobox-utils";
8
+ import { ComboboxOption } from "../types";
9
+ import filteredOptionsUtil from "./filtered-options-util";
10
+ import { useFilteredOptionsContext } from "./filteredOptionsContext";
11
+
12
+ const FilteredOptionsItem = ({ option }: { option: ComboboxOption }) => {
13
+ const {
14
+ inputProps: { id },
15
+ size,
16
+ } = useInputContext();
17
+ const {
18
+ setIsMouseLastUsedInputDevice,
19
+ toggleIsListOpen,
20
+ activeDecendantId,
21
+ virtualFocus,
22
+ } = useFilteredOptionsContext();
23
+ const { isMultiSelect, maxSelected, selectedOptions, toggleOption } =
24
+ useSelectedOptionsContext();
25
+
26
+ const isDisabled = (_option: ComboboxOption) =>
27
+ maxSelected?.isLimitReached && !isInList(_option.value, selectedOptions);
28
+ return (
29
+ <li
30
+ className={cl("navds-combobox__list-item", {
31
+ "navds-combobox__list-item--focus":
32
+ activeDecendantId ===
33
+ filteredOptionsUtil.getOptionId(id, option.label),
34
+ "navds-combobox__list-item--selected": isInList(
35
+ option.value,
36
+ selectedOptions,
37
+ ),
38
+ })}
39
+ data-no-focus={isDisabled(option) || undefined}
40
+ id={filteredOptionsUtil.getOptionId(id, option.label)}
41
+ key={option.label}
42
+ tabIndex={-1}
43
+ onMouseMove={() => {
44
+ if (
45
+ activeDecendantId !==
46
+ filteredOptionsUtil.getOptionId(id, option.label)
47
+ ) {
48
+ virtualFocus.moveFocusToElement(
49
+ filteredOptionsUtil.getOptionId(id, option.label),
50
+ );
51
+ setIsMouseLastUsedInputDevice(true);
52
+ }
53
+ }}
54
+ onPointerUp={(event) => {
55
+ if (isDisabled(option)) {
56
+ return;
57
+ }
58
+ toggleOption(option, event);
59
+ if (!isMultiSelect && !isInList(option.value, selectedOptions)) {
60
+ toggleIsListOpen(false);
61
+ }
62
+ }}
63
+ role="option"
64
+ aria-selected={isInList(option.value, selectedOptions)}
65
+ aria-disabled={isDisabled(option) || undefined}
66
+ >
67
+ <BodyShort size={size}>{option.label}</BodyShort>
68
+ {isInList(option.value, selectedOptions) && <CheckmarkIcon />}
69
+ </li>
70
+ );
71
+ };
72
+
73
+ export default FilteredOptionsItem;
@@ -0,0 +1,20 @@
1
+ import React from "react";
2
+ import { Loader } from "../../../loader";
3
+ import { useInputContext } from "../Input/Input.context";
4
+ import filteredOptionsUtil from "./filtered-options-util";
5
+
6
+ const LoadingMessage = () => {
7
+ const {
8
+ inputProps: { id },
9
+ } = useInputContext();
10
+ return (
11
+ <div
12
+ className="navds-combobox__list-item--loading"
13
+ id={filteredOptionsUtil.getIsLoadingId(id)}
14
+ >
15
+ <Loader title="Søker..." />
16
+ </div>
17
+ );
18
+ };
19
+
20
+ export default LoadingMessage;
@@ -0,0 +1,27 @@
1
+ import React from "react";
2
+ import { useInputContext } from "../Input/Input.context";
3
+ import { useSelectedOptionsContext } from "../SelectedOptions/selectedOptionsContext";
4
+ import filteredOptionsUtil from "./filtered-options-util";
5
+
6
+ const MaxSelectedMessage = () => {
7
+ const {
8
+ inputProps: { id },
9
+ } = useInputContext();
10
+ const { maxSelected, selectedOptions } = useSelectedOptionsContext();
11
+
12
+ if (!maxSelected) {
13
+ return null;
14
+ }
15
+
16
+ return (
17
+ <div
18
+ className="navds-combobox__list-item--max-selected"
19
+ id={filteredOptionsUtil.getMaxSelectedOptionsId(id)}
20
+ >
21
+ {maxSelected.message ??
22
+ `${selectedOptions.length} av ${maxSelected.limit} er valgt.`}
23
+ </div>
24
+ );
25
+ };
26
+
27
+ export default MaxSelectedMessage;
@@ -0,0 +1,19 @@
1
+ import React from "react";
2
+ import { useInputContext } from "../Input/Input.context";
3
+ import filteredOptionsUtil from "./filtered-options-util";
4
+
5
+ const NoSearchHitsMessage = () => {
6
+ const {
7
+ inputProps: { id },
8
+ } = useInputContext();
9
+ return (
10
+ <div
11
+ className="navds-combobox__list-item--no-options"
12
+ id={filteredOptionsUtil.getNoHitsId(id)}
13
+ >
14
+ Ingen søketreff
15
+ </div>
16
+ );
17
+ };
18
+
19
+ export default NoSearchHitsMessage;
@@ -16,11 +16,12 @@ interface InputProps
16
16
  extends Omit<InputHTMLAttributes<HTMLInputElement>, "value" | "disabled"> {
17
17
  ref: React.Ref<HTMLInputElement>;
18
18
  inputClassName?: string;
19
+ shouldShowSelectedOptions?: boolean;
19
20
  value?: string;
20
21
  }
21
22
 
22
23
  const Input = forwardRef<HTMLInputElement, InputProps>(
23
- ({ inputClassName, ...rest }, ref) => {
24
+ ({ inputClassName, shouldShowSelectedOptions, ...rest }, ref) => {
24
25
  const internalRef = useRef<HTMLInputElement>(null);
25
26
  const mergedRefs = useMergeRefs(ref, internalRef);
26
27
  const {
@@ -128,7 +129,7 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
128
129
  (e: React.KeyboardEvent<HTMLInputElement>) => {
129
130
  setIsMouseLastUsedInputDevice(false);
130
131
  if (e.key === "Backspace") {
131
- if (value === "") {
132
+ if (value === "" && shouldShowSelectedOptions) {
132
133
  const lastSelectedOption =
133
134
  selectedOptions[selectedOptions.length - 1];
134
135
  if (lastSelectedOption) {
@@ -191,6 +192,7 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
191
192
  virtualFocus,
192
193
  setValue,
193
194
  searchTerm,
195
+ shouldShowSelectedOptions,
194
196
  ],
195
197
  );
196
198
 
@@ -73,6 +73,7 @@ export const InputController = forwardRef<
73
73
  id={inputProps.id}
74
74
  ref={mergedInputRef}
75
75
  inputClassName={inputClassName}
76
+ shouldShowSelectedOptions={shouldShowSelectedOptions}
76
77
  {...rest}
77
78
  />
78
79
  </SelectedOptions>