@digdir/designsystemet-react 0.59.0 → 0.59.1-alpha.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 (91) hide show
  1. package/dist/cjs/components/DropdownMenu/DropdownMenuContent.js +4 -4
  2. package/dist/cjs/components/DropdownMenu/DropdownMenuTrigger.js +1 -1
  3. package/dist/cjs/components/Modal/ModalDialog.js +1 -1
  4. package/dist/cjs/components/Popover/PopoverContent.js +6 -6
  5. package/dist/cjs/components/Popover/PopoverTrigger.js +1 -1
  6. package/dist/cjs/components/Tooltip/Tooltip.js +6 -6
  7. package/dist/cjs/components/form/Checkbox/Checkbox.js +1 -1
  8. package/dist/cjs/components/form/Combobox/Combobox.js +60 -177
  9. package/dist/cjs/components/form/Combobox/ComboboxContext.js +8 -0
  10. package/dist/cjs/components/form/Combobox/ComboboxIdContext.js +42 -0
  11. package/dist/cjs/components/form/Combobox/Custom/Custom.js +14 -9
  12. package/dist/cjs/components/form/Combobox/Empty/Empty.js +4 -4
  13. package/dist/cjs/components/form/Combobox/Option/Option.js +15 -33
  14. package/dist/cjs/components/form/Combobox/Option/useComboboxOption.js +47 -0
  15. package/dist/cjs/components/form/Combobox/internal/ComboboxChips.js +14 -6
  16. package/dist/cjs/components/form/Combobox/internal/ComboboxClearButton.js +4 -4
  17. package/dist/cjs/components/form/Combobox/internal/ComboboxInput.js +40 -35
  18. package/dist/cjs/components/form/Combobox/internal/ComboboxNative.js +2 -2
  19. package/dist/cjs/components/form/Combobox/useCombobox.js +46 -32
  20. package/dist/cjs/components/form/Combobox/useComboboxKeyboard.js +79 -0
  21. package/dist/cjs/components/form/Combobox/useFloatingCombobox.js +78 -0
  22. package/dist/cjs/components/form/Search/Search.js +1 -1
  23. package/dist/cjs/node_modules/@floating-ui/utils/{dom/dist → dist}/floating-ui.utils.dom.js +7 -4
  24. package/dist/cjs/node_modules/@floating-ui/utils/dist/floating-ui.utils.js +5 -0
  25. package/dist/cjs/{node_modules → packages/react/node_modules}/@floating-ui/core/dist/floating-ui.core.js +40 -16
  26. package/dist/cjs/{node_modules → packages/react/node_modules}/@floating-ui/dom/dist/floating-ui.dom.js +83 -31
  27. package/dist/cjs/{node_modules → packages/react/node_modules}/@floating-ui/react/dist/floating-ui.react.js +307 -157
  28. package/dist/cjs/{node_modules/@floating-ui/react/utils → packages/react/node_modules/@floating-ui/react}/dist/floating-ui.react.utils.js +9 -4
  29. package/dist/cjs/{node_modules → packages/react/node_modules}/@floating-ui/react-dom/dist/floating-ui.react-dom.js +22 -18
  30. package/dist/{esm → cjs/packages/react}/node_modules/tabbable/dist/index.esm.js +59 -13
  31. package/dist/cjs/utilities/RovingTabIndex/RovingTabindexItem.js +1 -1
  32. package/dist/cjs/utilities/RovingTabIndex/RovingTabindexRoot.js +1 -1
  33. package/dist/esm/components/DropdownMenu/DropdownMenuContent.js +3 -3
  34. package/dist/esm/components/DropdownMenu/DropdownMenuTrigger.js +1 -1
  35. package/dist/esm/components/Modal/ModalDialog.js +1 -1
  36. package/dist/esm/components/Popover/PopoverContent.js +4 -4
  37. package/dist/esm/components/Popover/PopoverTrigger.js +1 -1
  38. package/dist/esm/components/Tooltip/Tooltip.js +4 -4
  39. package/dist/esm/components/form/Checkbox/Checkbox.js +1 -1
  40. package/dist/esm/components/form/Combobox/Combobox.js +65 -182
  41. package/dist/esm/components/form/Combobox/ComboboxContext.js +6 -0
  42. package/dist/esm/components/form/Combobox/ComboboxIdContext.js +35 -0
  43. package/dist/esm/components/form/Combobox/Custom/Custom.js +13 -8
  44. package/dist/esm/components/form/Combobox/Empty/Empty.js +3 -3
  45. package/dist/esm/components/form/Combobox/Option/Option.js +15 -33
  46. package/dist/esm/components/form/Combobox/Option/useComboboxOption.js +45 -0
  47. package/dist/esm/components/form/Combobox/internal/ComboboxChips.js +13 -5
  48. package/dist/esm/components/form/Combobox/internal/ComboboxClearButton.js +3 -3
  49. package/dist/esm/components/form/Combobox/internal/ComboboxInput.js +39 -34
  50. package/dist/esm/components/form/Combobox/internal/ComboboxNative.js +2 -2
  51. package/dist/esm/components/form/Combobox/useCombobox.js +46 -32
  52. package/dist/esm/components/form/Combobox/useComboboxKeyboard.js +77 -0
  53. package/dist/esm/components/form/Combobox/useFloatingCombobox.js +76 -0
  54. package/dist/esm/components/form/Search/Search.js +1 -1
  55. package/dist/esm/node_modules/@floating-ui/utils/{dom/dist → dist}/floating-ui.utils.dom.js +7 -4
  56. package/dist/esm/node_modules/@floating-ui/utils/dist/floating-ui.utils.js +5 -0
  57. package/dist/esm/{node_modules → packages/react/node_modules}/@floating-ui/core/dist/floating-ui.core.js +40 -16
  58. package/dist/esm/{node_modules → packages/react/node_modules}/@floating-ui/dom/dist/floating-ui.dom.js +82 -30
  59. package/dist/esm/{node_modules → packages/react/node_modules}/@floating-ui/react/dist/floating-ui.react.js +282 -135
  60. package/dist/esm/{node_modules/@floating-ui/react/utils → packages/react/node_modules/@floating-ui/react}/dist/floating-ui.react.utils.js +9 -5
  61. package/dist/esm/{node_modules → packages/react/node_modules}/@floating-ui/react-dom/dist/floating-ui.react-dom.js +19 -14
  62. package/dist/{cjs → esm/packages/react}/node_modules/tabbable/dist/index.esm.js +55 -15
  63. package/dist/esm/utilities/RovingTabIndex/RovingTabindexItem.js +1 -1
  64. package/dist/esm/utilities/RovingTabIndex/RovingTabindexRoot.js +1 -1
  65. package/dist/types/components/form/Combobox/Combobox.d.ts +104 -39
  66. package/dist/types/components/form/Combobox/Combobox.d.ts.map +1 -1
  67. package/dist/types/components/form/Combobox/ComboboxContext.d.ts +48 -0
  68. package/dist/types/components/form/Combobox/ComboboxContext.d.ts.map +1 -0
  69. package/dist/types/components/form/Combobox/ComboboxIdContext.d.ts +19 -0
  70. package/dist/types/components/form/Combobox/ComboboxIdContext.d.ts.map +1 -0
  71. package/dist/types/components/form/Combobox/Custom/Custom.d.ts.map +1 -1
  72. package/dist/types/components/form/Combobox/Option/Option.d.ts +2 -2
  73. package/dist/types/components/form/Combobox/Option/Option.d.ts.map +1 -1
  74. package/dist/types/components/form/Combobox/Option/useComboboxOption.d.ts +14 -0
  75. package/dist/types/components/form/Combobox/Option/useComboboxOption.d.ts.map +1 -0
  76. package/dist/types/components/form/Combobox/internal/ComboboxChips.d.ts.map +1 -1
  77. package/dist/types/components/form/Combobox/internal/ComboboxInput.d.ts +0 -1
  78. package/dist/types/components/form/Combobox/internal/ComboboxInput.d.ts.map +1 -1
  79. package/dist/types/components/form/Combobox/internal/ComboboxNative.d.ts +3 -1
  80. package/dist/types/components/form/Combobox/internal/ComboboxNative.d.ts.map +1 -1
  81. package/dist/types/components/form/Combobox/useCombobox.d.ts +13 -5
  82. package/dist/types/components/form/Combobox/useCombobox.d.ts.map +1 -1
  83. package/dist/types/components/form/Combobox/useComboboxKeyboard.d.ts +20 -0
  84. package/dist/types/components/form/Combobox/useComboboxKeyboard.d.ts.map +1 -0
  85. package/dist/types/components/form/Combobox/useFloatingCombobox.d.ts +41 -0
  86. package/dist/types/components/form/Combobox/useFloatingCombobox.d.ts.map +1 -0
  87. package/package.json +3 -3
  88. package/dist/cjs/node_modules/@floating-ui/react/node_modules/@floating-ui/utils/dist/floating-ui.utils.js +0 -6
  89. package/dist/cjs/node_modules/@floating-ui/react/node_modules/@floating-ui/utils/dom/dist/floating-ui.utils.dom.js +0 -68
  90. package/dist/esm/node_modules/@floating-ui/react/node_modules/@floating-ui/utils/dist/floating-ui.utils.js +0 -4
  91. package/dist/esm/node_modules/@floating-ui/react/node_modules/@floating-ui/utils/dom/dist/floating-ui.utils.dom.js +0 -57
@@ -3,12 +3,12 @@
3
3
 
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
  var React = require('react');
6
- var floatingUi_react = require('../../node_modules/@floating-ui/react/dist/floating-ui.react.js');
6
+ var floatingUi_react = require('../../packages/react/node_modules/@floating-ui/react/dist/floating-ui.react.js');
7
7
  var clsx = require('../../node_modules/clsx/dist/clsx.js');
8
8
  var DropdownMenu_module = require('./DropdownMenu.module.css.js');
9
9
  var DropdownMenu = require('./DropdownMenu.js');
10
- var floatingUi_dom = require('../../node_modules/@floating-ui/dom/dist/floating-ui.dom.js');
11
- var floatingUi_core = require('../../node_modules/@floating-ui/core/dist/floating-ui.core.js');
10
+ var floatingUi_dom = require('../../packages/react/node_modules/@floating-ui/dom/dist/floating-ui.dom.js');
11
+ var floatingUi_core = require('../../packages/react/node_modules/@floating-ui/core/dist/floating-ui.core.js');
12
12
  var useIsomorphicLayoutEffect = require('../../hooks/useIsomorphicLayoutEffect.js');
13
13
 
14
14
  function _interopNamespaceDefault(e) {
@@ -49,7 +49,7 @@ const DropdownMenuContent = React.forwardRef(({ className, children, ...rest },
49
49
  floating: floatingEl.current,
50
50
  },
51
51
  whileElementsMounted: floatingUi_dom.autoUpdate,
52
- middleware: [floatingUi_core.offset(GAP), floatingUi_core.shift()],
52
+ middleware: [floatingUi_core.offset(GAP), floatingUi_dom.shift()],
53
53
  });
54
54
  const { getFloatingProps } = floatingUi_react.useInteractions([
55
55
  floatingUi_react.useFocus(context),
@@ -3,7 +3,7 @@
3
3
 
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
  var React = require('react');
6
- var floatingUi_react = require('../../node_modules/@floating-ui/react/dist/floating-ui.react.js');
6
+ var floatingUi_react = require('../../packages/react/node_modules/@floating-ui/react/dist/floating-ui.react.js');
7
7
  var index = require('../../node_modules/@radix-ui/react-slot/dist/index.js');
8
8
  var DropdownMenu = require('./DropdownMenu.js');
9
9
  var Button = require('../Button/Button.js');
@@ -2,7 +2,7 @@
2
2
  'use strict';
3
3
 
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
- var floatingUi_react = require('../../node_modules/@floating-ui/react/dist/floating-ui.react.js');
5
+ var floatingUi_react = require('../../packages/react/node_modules/@floating-ui/react/dist/floating-ui.react.js');
6
6
  var React = require('react');
7
7
  var index = require('../../node_modules/@radix-ui/react-slot/dist/index.js');
8
8
  var clsx = require('../../node_modules/clsx/dist/clsx.js');
@@ -3,13 +3,13 @@
3
3
 
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
  var React = require('react');
6
- var floatingUi_react = require('../../node_modules/@floating-ui/react/dist/floating-ui.react.js');
6
+ var floatingUi_react = require('../../packages/react/node_modules/@floating-ui/react/dist/floating-ui.react.js');
7
7
  var clsx = require('../../node_modules/clsx/dist/clsx.js');
8
8
  var Popover = require('./Popover.js');
9
9
  var Popover_module = require('./Popover.module.css.js');
10
- var floatingUi_dom = require('../../node_modules/@floating-ui/dom/dist/floating-ui.dom.js');
11
- var floatingUi_core = require('../../node_modules/@floating-ui/core/dist/floating-ui.core.js');
12
- var floatingUi_reactDom = require('../../node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.js');
10
+ var floatingUi_dom = require('../../packages/react/node_modules/@floating-ui/dom/dist/floating-ui.dom.js');
11
+ var floatingUi_core = require('../../packages/react/node_modules/@floating-ui/core/dist/floating-ui.core.js');
12
+ var floatingUi_reactDom = require('../../packages/react/node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.js');
13
13
  var useIsomorphicLayoutEffect = require('../../hooks/useIsomorphicLayoutEffect.js');
14
14
  var Paragraph = require('../Typography/Paragraph/Paragraph.js');
15
15
 
@@ -65,10 +65,10 @@ const PopoverContent = React.forwardRef(({ className, children, style, id, ...re
65
65
  },
66
66
  middleware: [
67
67
  floatingUi_core.offset(ARROW_HEIGHT + ARROW_GAP),
68
- floatingUi_core.flip({
68
+ floatingUi_dom.flip({
69
69
  fallbackAxisSideDirection: 'start',
70
70
  }),
71
- floatingUi_core.shift(),
71
+ floatingUi_dom.shift(),
72
72
  floatingUi_reactDom.arrow({
73
73
  element: arrowRef,
74
74
  }),
@@ -3,7 +3,7 @@
3
3
 
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
  var React = require('react');
6
- var floatingUi_react = require('../../node_modules/@floating-ui/react/dist/floating-ui.react.js');
6
+ var floatingUi_react = require('../../packages/react/node_modules/@floating-ui/react/dist/floating-ui.react.js');
7
7
  var index = require('../../node_modules/@radix-ui/react-slot/dist/index.js');
8
8
  var Popover = require('./Popover.js');
9
9
  var Button = require('../Button/Button.js');
@@ -4,11 +4,11 @@
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
  var React = require('react');
6
6
  var clsx = require('../../node_modules/clsx/dist/clsx.js');
7
- var floatingUi_react = require('../../node_modules/@floating-ui/react/dist/floating-ui.react.js');
7
+ var floatingUi_react = require('../../packages/react/node_modules/@floating-ui/react/dist/floating-ui.react.js');
8
8
  var Tooltip_module = require('./Tooltip.module.css.js');
9
- var floatingUi_dom = require('../../node_modules/@floating-ui/dom/dist/floating-ui.dom.js');
10
- var floatingUi_core = require('../../node_modules/@floating-ui/core/dist/floating-ui.core.js');
11
- var floatingUi_reactDom = require('../../node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.js');
9
+ var floatingUi_dom = require('../../packages/react/node_modules/@floating-ui/dom/dist/floating-ui.dom.js');
10
+ var floatingUi_core = require('../../packages/react/node_modules/@floating-ui/core/dist/floating-ui.core.js');
11
+ var floatingUi_reactDom = require('../../packages/react/node_modules/@floating-ui/react-dom/dist/floating-ui.react-dom.js');
12
12
 
13
13
  function _interopNamespaceDefault(e) {
14
14
  var n = Object.create(null);
@@ -43,10 +43,10 @@ const Tooltip = React.forwardRef(({ children, content, placement = 'top', delay
43
43
  whileElementsMounted: floatingUi_dom.autoUpdate,
44
44
  middleware: [
45
45
  floatingUi_core.offset(ARROW_HEIGHT + ARROW_GAP),
46
- floatingUi_core.flip({
46
+ floatingUi_dom.flip({
47
47
  fallbackAxisSideDirection: 'start',
48
48
  }),
49
- floatingUi_core.shift(),
49
+ floatingUi_dom.shift(),
50
50
  floatingUi_reactDom.arrow({
51
51
  element: arrowRef,
52
52
  }),
@@ -4,7 +4,7 @@
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
  var React = require('react');
6
6
  var clsx = require('../../../node_modules/clsx/dist/clsx.js');
7
- var floatingUi_react = require('../../../node_modules/@floating-ui/react/dist/floating-ui.react.js');
7
+ var floatingUi_react = require('../../../packages/react/node_modules/@floating-ui/react/dist/floating-ui.react.js');
8
8
  var Checkbox_module = require('./Checkbox.module.css.js');
9
9
  var useCheckbox = require('./useCheckbox.js');
10
10
  var Paragraph = require('../../Typography/Paragraph/Paragraph.js');
@@ -3,10 +3,9 @@
3
3
 
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
  var React = require('react');
6
- var floatingUi_react = require('../../../node_modules/@floating-ui/react/dist/floating-ui.react.js');
6
+ var floatingUi_react = require('../../../packages/react/node_modules/@floating-ui/react/dist/floating-ui.react.js');
7
7
  var clsx = require('../../../node_modules/clsx/dist/clsx.js');
8
8
  var index = require('../../../node_modules/@tanstack/react-virtual/dist/esm/index.js');
9
- var ReactDOM = require('react-dom');
10
9
  var useFormField = require('../useFormField.js');
11
10
  var useDebounce = require('../../../utilities/useDebounce.js');
12
11
  var useCombobox = require('./useCombobox.js');
@@ -16,34 +15,31 @@ var ComboboxLabel = require('./internal/ComboboxLabel.js');
16
15
  var ComboboxError = require('./internal/ComboboxError.js');
17
16
  var ComboboxNative = require('./internal/ComboboxNative.js');
18
17
  var Custom = require('./Custom/Custom.js');
18
+ var useFloatingCombobox = require('./useFloatingCombobox.js');
19
+ var useComboboxKeyboard = require('./useComboboxKeyboard.js');
20
+ var ComboboxIdContext = require('./ComboboxIdContext.js');
21
+ var ComboboxContext = require('./ComboboxContext.js');
19
22
  var Box = require('../../Box/Box.js');
20
23
  var Spinner = require('../../Spinner/Spinner.js');
21
- var floatingUi_dom = require('../../../node_modules/@floating-ui/dom/dist/floating-ui.dom.js');
22
- var floatingUi_core = require('../../../node_modules/@floating-ui/core/dist/floating-ui.core.js');
23
24
  var objectUtils = require('../../../utilities/objectUtils.js');
24
25
 
25
- const Combobox = React.forwardRef(({ value, initialValue = [], onValueChange, label, hideLabel = false, description, multiple = false, size = 'medium', disabled = false, readOnly = false, hideChips = false, cleanButtonLabel = 'Fjern alt', clearButtonLabel = 'Fjern alt', hideClearButton = false, error, errorId, id, name, portal = true, htmlSize = 0, virtual = false, children, style, loading, loadingLabel = 'Laster...', filter = (inputValue, option) => {
26
- return option.label.toLowerCase().startsWith(inputValue.toLowerCase());
27
- }, chipSrLabel = (option) => 'Slett ' + option.label, className, ...rest }, forwareddRef) => {
26
+ const ComboboxComponent = React.forwardRef(({ value, initialValue = [], onValueChange, label, hideLabel = false, description, multiple = false, size = 'medium', disabled = false, readOnly = false, hideChips = false, cleanButtonLabel = 'Fjern alt', clearButtonLabel = 'Fjern alt', hideClearButton = false, error, errorId, id, name, portal = true, htmlSize = 0, virtual = false, children, style, loading, loadingLabel = 'Laster...', filter, chipSrLabel = (option) => 'Slett ' + option.label, className, ...rest }, forwareddRef) => {
28
27
  const inputRef = React.useRef(null);
29
28
  const portalRef = React.useRef(null);
29
+ const listRef = React.useRef([]);
30
30
  const listId = React.useId();
31
- const [open, setOpen] = React.useState(false);
32
31
  const [inputValue, setInputValue] = React.useState(rest.inputValue || '');
33
- const [activeIndex, setActiveIndex] = React.useState(null);
34
- const { selectedOptions, setSelectedOptions, options, optionsChildren, restChildren, optionValues, customIds, prevSelectedHash, setPrevSelectedHash, } = useCombobox.default({
32
+ /* const idDispatch = useComboboxIdDispatch(); */
33
+ const { selectedOptions, options, restChildren, interactiveChildren, optionValues, customIds, filteredOptionsChildren, filteredOptions, prevSelectedHash, setSelectedOptions, setPrevSelectedHash, } = useCombobox.default({
35
34
  children,
36
35
  inputValue,
37
36
  filter,
38
37
  multiple,
39
38
  initialValue,
40
39
  });
41
- const [activeDescendant, setActiveDescendant] = React.useState(undefined);
42
- React.useEffect(() => {
43
- if (rest.inputValue !== undefined) {
44
- setInputValue(rest.inputValue);
45
- }
46
- }, [rest.inputValue]);
40
+ const { open, setOpen, refs, floatingStyles, context, getReferenceProps, getFloatingProps, getItemProps, } = useFloatingCombobox.useFloatingCombobox({
41
+ listRef,
42
+ });
47
43
  const formFieldProps = useFormField.useFormField({
48
44
  disabled,
49
45
  readOnly,
@@ -53,100 +49,59 @@ const Combobox = React.forwardRef(({ value, initialValue = [], onValueChange, la
53
49
  description,
54
50
  id,
55
51
  }, 'combobox');
56
- const listRef = React.useRef([]);
57
52
  // if value is set, set input value to the label of the value
58
53
  React.useEffect(() => {
59
- if (value && value.length > 0 && !multiple) {
60
- const option = options.find((option) => option.value === value[0]);
54
+ if (value && value.length >= 0 && !multiple) {
55
+ const option = options[value[0]];
61
56
  setInputValue(option?.label || '');
62
57
  }
63
58
  }, [multiple, value, options]);
64
- // floating UI
65
- const { refs, floatingStyles, context } = floatingUi_react.useFloating({
66
- open,
67
- onOpenChange: (newOpen) => {
68
- ReactDOM.flushSync(() => {
69
- if (refs.floating.current && !newOpen) {
70
- refs.floating.current.scrollTop = 0;
71
- }
72
- setTimeout(() => {
73
- setOpen(newOpen);
74
- }, 1);
75
- });
76
- },
77
- whileElementsMounted: (reference, floating, update) => {
78
- floatingUi_dom.autoUpdate(reference, floating, update);
79
- return () => {
80
- floating.scrollTop = 0;
81
- };
82
- },
83
- middleware: [
84
- floatingUi_core.flip({ padding: 10 }),
85
- floatingUi_core.size({
86
- apply({ rects, elements }) {
87
- requestAnimationFrame(() => {
88
- Object.assign(elements.floating.style, {
89
- width: `calc(${rects.reference.width}px - calc(var(--fds-spacing-2) * 2))`,
90
- maxHeight: `200px`,
91
- });
92
- });
93
- },
94
- }),
95
- floatingUi_core.offset(10),
96
- ],
97
- });
98
- const role = floatingUi_react.useRole(context, { role: 'listbox' });
99
- const dismiss = floatingUi_react.useDismiss(context);
100
- const listNav = floatingUi_react.useListNavigation(context, {
101
- listRef,
102
- activeIndex,
103
- virtual: true,
104
- scrollItemIntoView: true,
105
- enabled: open,
106
- });
107
- const { getReferenceProps, getFloatingProps } = floatingUi_react.useInteractions([
108
- role,
109
- dismiss,
110
- listNav,
111
- ]);
112
- // remove active index if combobox is closed
113
- React.useEffect(() => {
114
- if (!open) {
115
- setActiveIndex(null);
116
- }
117
- }, [open]);
118
59
  // Send new value if option was clicked
119
60
  React.useEffect(() => {
120
61
  const selectedHash = JSON.stringify(selectedOptions);
121
62
  if (prevSelectedHash === selectedHash)
122
63
  return;
123
- const values = selectedOptions.map((option) => option.value);
64
+ const values = Object.keys(selectedOptions);
124
65
  onValueChange?.(values);
125
66
  setPrevSelectedHash(selectedHash);
126
67
  }, [onValueChange, selectedOptions, prevSelectedHash, setPrevSelectedHash]);
127
68
  React.useEffect(() => {
128
- if (value && options.length > 0) {
69
+ if (value && Object.keys(options).length >= 0) {
129
70
  const updatedSelectedOptions = value.map((option) => {
130
- const value = options.find((value) => value.value === option);
71
+ const value = options[option];
131
72
  return value;
132
73
  });
133
- setSelectedOptions(updatedSelectedOptions);
74
+ setSelectedOptions(updatedSelectedOptions.reduce((acc, value) => {
75
+ acc[value.value] = value;
76
+ return acc;
77
+ }, {}));
134
78
  }
135
79
  }, [multiple, prevSelectedHash, value, options, setSelectedOptions]);
136
80
  // handle click on option, either select or deselect - Handles single or multiple
137
81
  const handleSelectOption = (option) => {
138
82
  // if option is already selected, remove it
139
83
  if (value && value.includes(option.value)) {
140
- setSelectedOptions((prev) => prev.filter((i) => i.value !== option.value));
84
+ setSelectedOptions((prev) => {
85
+ const updated = { ...prev };
86
+ delete updated[option.value];
87
+ return updated;
88
+ });
141
89
  return;
142
90
  }
143
91
  if (multiple) {
144
- setSelectedOptions([...selectedOptions, option]);
92
+ /* setSelectedOptions([...selectedOptions, option]); */
93
+ setSelectedOptions((prev) => {
94
+ const updated = { ...prev };
95
+ updated[option.value] = option;
96
+ return updated;
97
+ });
145
98
  setInputValue('');
146
99
  inputRef.current?.focus();
147
100
  }
148
101
  else {
149
- setSelectedOptions([option]);
102
+ setSelectedOptions({
103
+ [option.value]: option,
104
+ });
150
105
  setInputValue(option?.label || '');
151
106
  // move cursor to the end of the input
152
107
  setTimeout(() => {
@@ -157,106 +112,41 @@ const Combobox = React.forwardRef(({ value, initialValue = [], onValueChange, la
157
112
  refs.domReference.current?.focus();
158
113
  };
159
114
  const debouncedHandleSelectOption = useDebounce(handleSelectOption, 50);
160
- // handle keyboard navigation in the list
161
- const handleKeyDownFunc = (event) => {
162
- const navigateable = customIds.length + optionsChildren.length;
163
- if (formFieldProps.readOnly || disabled)
164
- return;
165
- if (!event)
166
- return;
167
- switch (event.key) {
168
- case 'ArrowDown':
169
- event.preventDefault();
170
- if (!open)
171
- setOpen(true);
172
- setActiveIndex((prevActiveIndex) => {
173
- if (prevActiveIndex === null) {
174
- return 0;
175
- }
176
- return Math.min(prevActiveIndex + 1, navigateable - 1);
177
- });
178
- break;
179
- case 'ArrowUp':
180
- event.preventDefault();
181
- /* If we are on the first item, close */
182
- setActiveIndex((prevActiveIndex) => {
183
- if (prevActiveIndex === 0) {
184
- setOpen(false);
185
- return null;
186
- }
187
- if (prevActiveIndex === null) {
188
- return null;
189
- }
190
- return Math.max(prevActiveIndex - 1, 0);
191
- });
192
- break;
193
- case 'Enter':
194
- event.preventDefault();
195
- if (activeIndex !== null &&
196
- (optionsChildren[activeIndex] || customIds.length > 0)) {
197
- // check if we are in the custom components
198
- if (activeIndex <= customIds.length) {
199
- // send `onSelect` event to the custom component
200
- const selectedId = customIds[activeIndex];
201
- const selectedComponent = restChildren.find((component) => useCombobox.isInteractiveComboboxCustom(component) &&
202
- component.props?.id === selectedId);
203
- if (useCombobox.isInteractiveComboboxCustom(selectedComponent) &&
204
- selectedComponent.props.onSelect) {
205
- selectedComponent.props.onSelect();
206
- }
207
- }
208
- // if we are in the options, find the actual index
209
- const valueIndex = activeIndex - customIds.length;
210
- const child = optionsChildren[valueIndex];
211
- if (useCombobox.isComboboxOption(child)) {
212
- const props = child.props;
213
- const option = options.find((option) => option.value === props.value);
214
- if (!multiple) {
215
- // check if option is already selected, if so, deselect it
216
- if (selectedOptions.find((i) => i.value === option?.value)) {
217
- setSelectedOptions([]);
218
- setInputValue('');
219
- return;
220
- }
221
- }
222
- debouncedHandleSelectOption(option);
223
- }
224
- }
225
- break;
226
- case 'Backspace':
227
- if (inputValue === '' && multiple && selectedOptions.length > 0) {
228
- setSelectedOptions((prev) => prev.slice(0, prev.length - 1));
229
- }
230
- // if we are in single mode, we need to set activeValue to null
231
- if (!multiple) {
232
- setSelectedOptions([]);
233
- }
234
- break;
235
- }
236
- };
237
- const handleKeyDown = useDebounce(handleKeyDownFunc, 20);
115
+ const handleKeyDown = useComboboxKeyboard.useComboboxKeyboard({
116
+ filteredOptions,
117
+ selectedOptions,
118
+ readOnly: formFieldProps.readOnly || false,
119
+ disabled: disabled,
120
+ multiple,
121
+ inputValue,
122
+ options,
123
+ open,
124
+ interactiveChildren,
125
+ setOpen,
126
+ setInputValue,
127
+ setSelectedOptions,
128
+ handleSelectOption: debouncedHandleSelectOption,
129
+ });
238
130
  const rowVirtualizer = index.useVirtualizer({
239
- count: optionsChildren.length,
240
- getScrollElement: () => refs.floating.current,
131
+ count: Object.keys(filteredOptionsChildren).length,
132
+ getScrollElement: () => (virtual ? refs.floating.current : null),
241
133
  estimateSize: () => 70,
242
134
  measureElement: (elem) => {
243
135
  return elem.getBoundingClientRect().height;
244
136
  },
245
137
  overscan: 1,
246
138
  });
247
- return (jsxRuntime.jsxs(ComboboxContext.Provider, { value: {
139
+ return (jsxRuntime.jsxs(ComboboxContext.ComboboxContext.Provider, { value: {
248
140
  size,
249
141
  options,
250
142
  selectedOptions,
251
143
  multiple,
252
- activeIndex,
253
144
  disabled,
254
145
  readOnly,
255
146
  open,
256
147
  inputRef,
257
148
  refs,
258
149
  inputValue,
259
- activeDescendant,
260
150
  error,
261
151
  formFieldProps,
262
152
  name,
@@ -266,28 +156,21 @@ const Combobox = React.forwardRef(({ value, initialValue = [], onValueChange, la
266
156
  clearButtonLabel: cleanButtonLabel || clearButtonLabel,
267
157
  hideClearButton,
268
158
  listId,
159
+ customIds,
160
+ filteredOptions,
269
161
  setInputValue,
270
- setActiveIndex,
271
162
  handleKeyDown,
272
163
  setOpen,
273
164
  getReferenceProps,
165
+ getItemProps,
274
166
  setSelectedOptions,
275
- /* Recieves index of option, and the ID of the button element */
276
- setActiveOption: (index, id) => {
277
- if (readOnly)
278
- return;
279
- if (disabled)
280
- return;
281
- setActiveIndex(index);
282
- setActiveDescendant(id);
283
- },
284
167
  /* Recieves the value of the option, and searches for it in our values lookup */
285
168
  onOptionClick: (value) => {
286
169
  if (readOnly)
287
170
  return;
288
171
  if (disabled)
289
172
  return;
290
- const option = options.find((option) => option.value === value);
173
+ const option = options[value];
291
174
  debouncedHandleSelectOption(option);
292
175
  },
293
176
  handleSelectOption: debouncedHandleSelectOption,
@@ -309,10 +192,10 @@ const Combobox = React.forwardRef(({ value, initialValue = [], onValueChange, la
309
192
  left: 0,
310
193
  width: '100%',
311
194
  transform: `translateY(${virtualRow.start}px)`,
312
- }, children: optionsChildren[virtualRow.index] }, virtualRow.index))) })), loading ? (jsxRuntime.jsxs(Custom.default, { className: Combobox_module.loading, children: [jsxRuntime.jsx(Spinner.Spinner, { title: 'Laster', size: 'small' }), loadingLabel] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [restChildren, !virtual && optionsChildren] }))] }) }) }))] }));
195
+ }, children: filteredOptionsChildren[virtualRow.index] }, virtualRow.index))) })), loading ? (jsxRuntime.jsxs(Custom.default, { className: Combobox_module.loading, children: [jsxRuntime.jsx(Spinner.Spinner, { title: 'Laster', size: 'small' }), loadingLabel] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [restChildren, !virtual && filteredOptionsChildren] }))] }) }) }))] }));
313
196
  });
314
- const ComboboxContext = React.createContext(undefined);
197
+ const Combobox = React.forwardRef((props, ref) => (jsxRuntime.jsx(ComboboxIdContext.ComboboxIdProvider, { children: jsxRuntime.jsx(ComboboxComponent, { ...props, ref: ref }) })));
315
198
  Combobox.displayName = 'Combobox';
316
199
 
317
200
  exports.Combobox = Combobox;
318
- exports.ComboboxContext = ComboboxContext;
201
+ exports.ComboboxComponent = ComboboxComponent;
@@ -0,0 +1,8 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ var React = require('react');
5
+
6
+ const ComboboxContext = React.createContext(undefined);
7
+
8
+ exports.ComboboxContext = ComboboxContext;
@@ -0,0 +1,42 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var React = require('react');
6
+
7
+ const ComboboxIdContext = React.createContext({
8
+ activeIndex: 0,
9
+ });
10
+ const ComboboxIdReducer = (state, action) => {
11
+ switch (action.type) {
12
+ case 'SET_ACTIVE_INDEX':
13
+ return {
14
+ ...state,
15
+ activeIndex: action.payload,
16
+ };
17
+ default:
18
+ return state;
19
+ }
20
+ };
21
+ const ComboboxIdDispatch = React.createContext(() => {
22
+ throw new Error('ComboboxIdDispatch must be used within a provider');
23
+ });
24
+ const ComboboxIdProvider = ({ children, }) => {
25
+ const [state, dispatch] = React.useReducer(ComboboxIdReducer, {
26
+ activeIndex: 0,
27
+ });
28
+ return (jsxRuntime.jsx(ComboboxIdContext.Provider, { value: state, children: jsxRuntime.jsx(ComboboxIdDispatch.Provider, { value: dispatch, children: children }) }));
29
+ };
30
+ function useComboboxIdDispatch() {
31
+ return React.useContext(ComboboxIdDispatch);
32
+ }
33
+ function useComboboxId() {
34
+ return React.useContext(ComboboxIdContext);
35
+ }
36
+
37
+ exports.ComboboxIdContext = ComboboxIdContext;
38
+ exports.ComboboxIdDispatch = ComboboxIdDispatch;
39
+ exports.ComboboxIdProvider = ComboboxIdProvider;
40
+ exports.ComboboxIdReducer = ComboboxIdReducer;
41
+ exports.useComboboxId = useComboboxId;
42
+ exports.useComboboxIdDispatch = useComboboxIdDispatch;
@@ -7,7 +7,9 @@ var jsxRuntime = require('react/jsx-runtime');
7
7
  var React = require('react');
8
8
  var clsx = require('../../../../node_modules/clsx/dist/clsx.js');
9
9
  var index = require('../../../../node_modules/@radix-ui/react-slot/dist/index.js');
10
- var Combobox = require('../Combobox.js');
10
+ var floatingUi_react = require('../../../../packages/react/node_modules/@floating-ui/react/dist/floating-ui.react.js');
11
+ var ComboboxContext = require('../ComboboxContext.js');
12
+ var ComboboxIdContext = require('../ComboboxIdContext.js');
11
13
  var Custom_module = require('./Custom.module.css.js');
12
14
  var objectUtils = require('../../../../utilities/objectUtils.js');
13
15
 
@@ -17,17 +19,20 @@ const ComboboxCustom = React.forwardRef(({ asChild, interactive, id, className,
17
19
  }
18
20
  const Component = asChild ? index.Slot : 'div';
19
21
  const randomId = React.useId();
20
- const context = React.useContext(Combobox.ComboboxContext);
22
+ const { activeIndex } = ComboboxIdContext.useComboboxId();
23
+ const context = React.useContext(ComboboxContext.ComboboxContext);
21
24
  if (!context) {
22
25
  throw new Error('ComboboxCustom must be used within a Combobox');
23
26
  }
24
- const { size, activeIndex, optionValues, setActiveIndex } = context;
25
- const index$1 = React.useMemo(() => id && optionValues.indexOf(id), [optionValues, id]);
26
- return (jsxRuntime.jsx(Component, { ref: ref, tabIndex: -1, className: clsx.clsx(Custom_module.custom, Custom_module[size], className), id: id || randomId, role: 'option', "aria-selected": activeIndex === index$1, "data-active": activeIndex === index$1, onMouseEnter: () => {
27
- typeof index$1 === 'number' && setActiveIndex(index$1);
28
- }, onFocus: () => {
29
- typeof index$1 === 'number' && setActiveIndex(index$1);
30
- }, ...objectUtils.omit(['interactive'], rest) }));
27
+ const { size, customIds, listRef, getItemProps } = context;
28
+ const index$1 = React.useMemo(() => (id && customIds.indexOf(id)) || 0, [id, customIds]);
29
+ const combinedRef = floatingUi_react.useMergeRefs([
30
+ (node) => {
31
+ listRef.current[index$1] = node;
32
+ },
33
+ ref,
34
+ ]);
35
+ return (jsxRuntime.jsx(Component, { ref: combinedRef, tabIndex: -1, className: clsx.clsx(Custom_module.custom, Custom_module[size], className), id: id || randomId, role: 'option', "aria-selected": activeIndex === index$1, "data-active": activeIndex === index$1, ...objectUtils.omit(['interactive'], rest), ...objectUtils.omit(['onClick', 'onPointerLeave'], getItemProps()) }));
31
36
  });
32
37
  var ComboboxCustom$1 = ComboboxCustom;
33
38
 
@@ -6,16 +6,16 @@ Object.defineProperty(exports, '__esModule', { value: true });
6
6
  var jsxRuntime = require('react/jsx-runtime');
7
7
  var React = require('react');
8
8
  var clsx = require('../../../../node_modules/clsx/dist/clsx.js');
9
- var Combobox = require('../Combobox.js');
9
+ var ComboboxContext = require('../ComboboxContext.js');
10
10
  var Empty_module = require('./Empty.module.css.js');
11
11
 
12
12
  const ComboboxEmpty = React.forwardRef(({ children, className, ...rest }, ref) => {
13
- const context = React.useContext(Combobox.ComboboxContext);
13
+ const context = React.useContext(ComboboxContext.ComboboxContext);
14
14
  if (!context) {
15
15
  throw new Error('ComboboxEmpty must be used within a Combobox');
16
16
  }
17
- const { optionValues, size } = context;
18
- return (optionValues.length === 0 && (jsxRuntime.jsx("div", { ref: ref, className: clsx.clsx(Empty_module.empty, Empty_module[size], className), ...rest, children: children })));
17
+ const { filteredOptions, size } = context;
18
+ return (filteredOptions.length === 0 && (jsxRuntime.jsx("div", { ref: ref, className: clsx.clsx(Empty_module.empty, Empty_module[size], className), ...rest, children: children })));
19
19
  });
20
20
  ComboboxEmpty.displayName = 'ComboboxEmpty';
21
21