@navikt/ds-react 6.13.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 (341) hide show
  1. package/cjs/accordion/AccordionContext.d.ts +0 -1
  2. package/cjs/collapsible/Collapsible.context.d.ts +0 -1
  3. package/cjs/date/context/useDateInputContext.d.ts +0 -1
  4. package/cjs/date/datepicker/parts/HeadRow.d.ts +0 -1
  5. package/cjs/date/datepicker/parts/HeadRow.js +2 -3
  6. package/cjs/date/datepicker/parts/HeadRow.js.map +1 -1
  7. package/cjs/date/datepicker/parts/Row.d.ts +0 -1
  8. package/cjs/date/datepicker/parts/TableHead.d.ts +0 -1
  9. package/cjs/date/datepicker/parts/WeekNumber.d.ts +0 -1
  10. package/cjs/date/datepicker/types.d.ts +0 -1
  11. package/cjs/date/monthpicker/types.d.ts +0 -1
  12. package/cjs/date/utils/check-dates.js +2 -2
  13. package/cjs/date/utils/check-dates.js.map +1 -1
  14. package/cjs/date/utils/get-initial-year.js +1 -2
  15. package/cjs/date/utils/get-initial-year.js.map +1 -1
  16. package/cjs/date/utils/get-month-weeks.js +2 -3
  17. package/cjs/date/utils/get-month-weeks.js.map +1 -1
  18. package/cjs/date/utils/is-match.js +2 -3
  19. package/cjs/date/utils/is-match.js.map +1 -1
  20. package/cjs/dropdown/Menu/index.d.ts +1 -1
  21. package/cjs/dropdown/context.d.ts +0 -1
  22. package/cjs/expansion-card/context.d.ts +0 -1
  23. package/cjs/form/checkbox/useCheckbox.d.ts +3 -3
  24. package/cjs/form/combobox/Combobox.d.ts +1 -1
  25. package/cjs/form/combobox/Combobox.js.map +1 -1
  26. package/cjs/form/combobox/ComboboxProvider.js +3 -1
  27. package/cjs/form/combobox/ComboboxProvider.js.map +1 -1
  28. package/cjs/form/combobox/FilteredOptions/AddNewOption.d.ts +3 -0
  29. package/cjs/form/combobox/FilteredOptions/AddNewOption.js +41 -0
  30. package/cjs/form/combobox/FilteredOptions/AddNewOption.js.map +1 -0
  31. package/cjs/form/combobox/FilteredOptions/FilteredOptions.js +13 -57
  32. package/cjs/form/combobox/FilteredOptions/FilteredOptions.js.map +1 -1
  33. package/cjs/form/combobox/FilteredOptions/FilteredOptionsItem.d.ts +6 -0
  34. package/cjs/form/combobox/FilteredOptions/FilteredOptionsItem.js +43 -0
  35. package/cjs/form/combobox/FilteredOptions/FilteredOptionsItem.js.map +1 -0
  36. package/cjs/form/combobox/FilteredOptions/LoadingMessage.d.ts +3 -0
  37. package/cjs/form/combobox/FilteredOptions/LoadingMessage.js +16 -0
  38. package/cjs/form/combobox/FilteredOptions/LoadingMessage.js.map +1 -0
  39. package/cjs/form/combobox/FilteredOptions/MaxSelectedMessage.d.ts +3 -0
  40. package/cjs/form/combobox/FilteredOptions/MaxSelectedMessage.js +20 -0
  41. package/cjs/form/combobox/FilteredOptions/MaxSelectedMessage.js.map +1 -0
  42. package/cjs/form/combobox/FilteredOptions/NoSearchHitsMessage.d.ts +3 -0
  43. package/cjs/form/combobox/FilteredOptions/NoSearchHitsMessage.js +14 -0
  44. package/cjs/form/combobox/FilteredOptions/NoSearchHitsMessage.js.map +1 -0
  45. package/cjs/form/combobox/FilteredOptions/filtered-options-util.d.ts +1 -0
  46. package/cjs/form/combobox/FilteredOptions/filtered-options-util.js +6 -1
  47. package/cjs/form/combobox/FilteredOptions/filtered-options-util.js.map +1 -1
  48. package/cjs/form/combobox/FilteredOptions/filteredOptionsContext.js +5 -5
  49. package/cjs/form/combobox/FilteredOptions/filteredOptionsContext.js.map +1 -1
  50. package/cjs/form/combobox/Input/Input.context.d.ts +20 -7
  51. package/cjs/form/combobox/Input/Input.context.js +6 -12
  52. package/cjs/form/combobox/Input/Input.context.js.map +1 -1
  53. package/cjs/form/combobox/Input/Input.d.ts +2 -1
  54. package/cjs/form/combobox/Input/Input.js +45 -20
  55. package/cjs/form/combobox/Input/Input.js.map +1 -1
  56. package/cjs/form/combobox/Input/InputController.d.ts +1 -1
  57. package/cjs/form/combobox/Input/InputController.js +1 -1
  58. package/cjs/form/combobox/Input/InputController.js.map +1 -1
  59. package/cjs/form/combobox/types.d.ts +8 -4
  60. package/cjs/form/fieldset/context.d.ts +0 -1
  61. package/cjs/form/fieldset/useFieldset.d.ts +1 -1
  62. package/cjs/form/file-upload/FileUpload.context.d.ts +0 -1
  63. package/cjs/form/file-upload/parts/dropzone/dropzone.types.d.ts +0 -1
  64. package/cjs/form/file-upload/parts/item/utils/format-file-size.js +1 -2
  65. package/cjs/form/file-upload/parts/item/utils/format-file-size.js.map +1 -1
  66. package/cjs/form/file-upload/useFileUpload.d.ts +1 -2
  67. package/cjs/form/file-upload/utils/is-accepted-file-type.js +1 -2
  68. package/cjs/form/file-upload/utils/is-accepted-file-type.js.map +1 -1
  69. package/cjs/form/file-upload/utils/is-accepted-size.js +1 -2
  70. package/cjs/form/file-upload/utils/is-accepted-size.js.map +1 -1
  71. package/cjs/form/radio/useRadio.d.ts +3 -3
  72. package/cjs/form/search/context.d.ts +0 -1
  73. package/cjs/layout/base/PrimitiveAsChildProps.d.ts +0 -1
  74. package/cjs/layout/grid/HGrid.js +4 -1
  75. package/cjs/layout/grid/HGrid.js.map +1 -1
  76. package/cjs/layout/stack/Stack.js +7 -2
  77. package/cjs/layout/stack/Stack.js.map +1 -1
  78. package/cjs/layout/utilities/css.js +2 -3
  79. package/cjs/layout/utilities/css.js.map +1 -1
  80. package/cjs/list/context.d.ts +0 -1
  81. package/cjs/list/types.d.ts +0 -1
  82. package/cjs/modal/ModalUtils.js +3 -3
  83. package/cjs/modal/ModalUtils.js.map +1 -1
  84. package/cjs/modal/types.d.ts +0 -1
  85. package/cjs/overlays/dismissablelayer/DismissableLayer.d.ts +1 -1
  86. package/cjs/overlays/dismissablelayer/util/dispatchCustomEvent.js +2 -2
  87. package/cjs/overlays/dismissablelayer/util/dispatchCustomEvent.js.map +1 -1
  88. package/cjs/overlays/dismissablelayer/util/useEscapeKeydown.js +1 -2
  89. package/cjs/overlays/dismissablelayer/util/useEscapeKeydown.js.map +1 -1
  90. package/cjs/overlays/dismissablelayer/util/useFocusOutside.js +1 -2
  91. package/cjs/overlays/dismissablelayer/util/useFocusOutside.js.map +1 -1
  92. package/cjs/overlays/dismissablelayer/util/usePointerDownOutside.js +1 -2
  93. package/cjs/overlays/dismissablelayer/util/usePointerDownOutside.js.map +1 -1
  94. package/cjs/overlays/floating/Floating.utils.js +2 -3
  95. package/cjs/overlays/floating/Floating.utils.js.map +1 -1
  96. package/cjs/overlays/floating-menu/Menu.d.ts +106 -0
  97. package/cjs/overlays/floating-menu/Menu.js +593 -0
  98. package/cjs/overlays/floating-menu/Menu.js.map +1 -0
  99. package/cjs/overlays/floating-menu/parts/FocusScope.d.ts +22 -0
  100. package/cjs/overlays/floating-menu/parts/FocusScope.js +89 -0
  101. package/cjs/overlays/floating-menu/parts/FocusScope.js.map +1 -0
  102. package/cjs/overlays/floating-menu/parts/RovingFocus.d.ts +9 -0
  103. package/cjs/overlays/floating-menu/parts/RovingFocus.js +112 -0
  104. package/cjs/overlays/floating-menu/parts/RovingFocus.js.map +1 -0
  105. package/cjs/overlays/floating-menu/parts/SlottedDivElement.d.ts +7 -0
  106. package/cjs/overlays/floating-menu/parts/SlottedDivElement.js +46 -0
  107. package/cjs/overlays/floating-menu/parts/SlottedDivElement.js.map +1 -0
  108. package/cjs/slot/merge-props.js +1 -2
  109. package/cjs/slot/merge-props.js.map +1 -1
  110. package/cjs/stepper/context.d.ts +0 -1
  111. package/cjs/table/context.d.ts +0 -1
  112. package/cjs/tabs/Tabs.context.d.ts +1 -2
  113. package/cjs/tabs/parts/tab/useTab.d.ts +1 -2
  114. package/cjs/tabs/parts/tab/useTab.js +1 -2
  115. package/cjs/tabs/parts/tab/useTab.js.map +1 -1
  116. package/cjs/tabs/parts/tablist/useScrollButtons.d.ts +0 -1
  117. package/cjs/tabs/parts/tablist/useScrollButtons.js +1 -2
  118. package/cjs/tabs/parts/tablist/useScrollButtons.js.map +1 -1
  119. package/cjs/tabs/parts/tablist/useTabList.js +3 -3
  120. package/cjs/tabs/parts/tablist/useTabList.js.map +1 -1
  121. package/cjs/tabs/parts/tabpanel/useTabPanel.js +1 -2
  122. package/cjs/tabs/parts/tabpanel/useTabPanel.js.map +1 -1
  123. package/cjs/tabs/useTabs.d.ts +0 -1
  124. package/cjs/tabs/useTabs.js +1 -2
  125. package/cjs/tabs/useTabs.js.map +1 -1
  126. package/cjs/timeline/hooks/usePeriodContext.d.ts +0 -1
  127. package/cjs/timeline/hooks/useRowContext.d.ts +0 -1
  128. package/cjs/timeline/hooks/useTimelineContext.d.ts +0 -1
  129. package/cjs/timeline/period/types.d.ts +0 -1
  130. package/cjs/timeline/zoom/index.d.ts +1 -1
  131. package/cjs/toggle-group/ToggleGroup.context.d.ts +1 -2
  132. package/cjs/toggle-group/parts/useToggleItem.d.ts +1 -2
  133. package/cjs/toggle-group/parts/useToggleItem.js +3 -3
  134. package/cjs/toggle-group/parts/useToggleItem.js.map +1 -1
  135. package/cjs/toggle-group/useToggleGroup.d.ts +0 -1
  136. package/cjs/toggle-group/useToggleGroup.js +1 -2
  137. package/cjs/toggle-group/useToggleGroup.js.map +1 -1
  138. package/cjs/util/composeEventHandlers.d.ts +1 -2
  139. package/cjs/util/composeEventHandlers.js +1 -2
  140. package/cjs/util/composeEventHandlers.js.map +1 -1
  141. package/cjs/util/copy.js +1 -1
  142. package/cjs/util/copy.js.map +1 -1
  143. package/cjs/util/create-context.js +1 -2
  144. package/cjs/util/create-context.js.map +1 -1
  145. package/cjs/util/debounce.js +1 -1
  146. package/cjs/util/debounce.js.map +1 -1
  147. package/cjs/util/hooks/descendants/useDescendant.d.ts +1 -1
  148. package/cjs/util/hooks/descendants/useDescendant.js +1 -2
  149. package/cjs/util/hooks/descendants/useDescendant.js.map +1 -1
  150. package/cjs/util/hooks/descendants/utils.js +4 -4
  151. package/cjs/util/hooks/descendants/utils.js.map +1 -1
  152. package/cjs/util/hooks/useCallbackRef.d.ts +0 -1
  153. package/cjs/util/hooks/useCallbackRef.js +1 -2
  154. package/cjs/util/hooks/useCallbackRef.js.map +1 -1
  155. package/cjs/util/hooks/useControllableState.js +1 -2
  156. package/cjs/util/hooks/useControllableState.js.map +1 -1
  157. package/cjs/util/hooks/useId.js +1 -2
  158. package/cjs/util/hooks/useId.js.map +1 -1
  159. package/cjs/util/hooks/useMergeRefs.d.ts +1 -1
  160. package/cjs/util/hooks/useMergeRefs.js +2 -3
  161. package/cjs/util/hooks/useMergeRefs.js.map +1 -1
  162. package/cjs/util/i18n/get.js +1 -2
  163. package/cjs/util/i18n/get.js.map +1 -1
  164. package/cjs/util/i18n/i18n.context.d.ts +0 -1
  165. package/cjs/util/i18n/i18n.context.js +2 -2
  166. package/cjs/util/i18n/i18n.context.js.map +1 -1
  167. package/cjs/util/i18n/merge.js +1 -2
  168. package/cjs/util/i18n/merge.js.map +1 -1
  169. package/cjs/util/omit.js +1 -2
  170. package/cjs/util/omit.js.map +1 -1
  171. package/cjs/util/types/AsChild.d.ts +0 -1
  172. package/cjs/util/types/AsChildProps.d.ts +0 -1
  173. package/cjs/util/virtualfocus/Context.d.ts +43 -0
  174. package/cjs/util/virtualfocus/Context.js +9 -0
  175. package/cjs/util/virtualfocus/Context.js.map +1 -0
  176. package/cjs/util/virtualfocus/SlottedDivElement.d.ts +7 -0
  177. package/cjs/util/virtualfocus/SlottedDivElement.js +46 -0
  178. package/cjs/util/virtualfocus/SlottedDivElement.js.map +1 -0
  179. package/cjs/util/virtualfocus/VirtualFocus.d.ts +62 -0
  180. package/cjs/util/virtualfocus/VirtualFocus.js +90 -0
  181. package/cjs/util/virtualfocus/VirtualFocus.js.map +1 -0
  182. package/cjs/util/virtualfocus/parts/VirtualFocusAnchor.d.ts +33 -0
  183. package/cjs/util/virtualfocus/parts/VirtualFocusAnchor.js +80 -0
  184. package/cjs/util/virtualfocus/parts/VirtualFocusAnchor.js.map +1 -0
  185. package/cjs/util/virtualfocus/parts/VirtualFocusContent.d.ts +4 -0
  186. package/cjs/util/virtualfocus/parts/VirtualFocusContent.js +45 -0
  187. package/cjs/util/virtualfocus/parts/VirtualFocusContent.js.map +1 -0
  188. package/cjs/util/virtualfocus/parts/VirtualFocusItem.d.ts +18 -0
  189. package/cjs/util/virtualfocus/parts/VirtualFocusItem.js +64 -0
  190. package/cjs/util/virtualfocus/parts/VirtualFocusItem.js.map +1 -0
  191. package/esm/accordion/AccordionContext.d.ts +0 -1
  192. package/esm/collapsible/Collapsible.context.d.ts +0 -1
  193. package/esm/date/context/useDateInputContext.d.ts +0 -1
  194. package/esm/date/datepicker/parts/HeadRow.d.ts +0 -1
  195. package/esm/date/datepicker/parts/Row.d.ts +0 -1
  196. package/esm/date/datepicker/parts/TableHead.d.ts +0 -1
  197. package/esm/date/datepicker/parts/WeekNumber.d.ts +0 -1
  198. package/esm/date/datepicker/types.d.ts +0 -1
  199. package/esm/date/monthpicker/types.d.ts +0 -1
  200. package/esm/dropdown/Menu/index.d.ts +1 -1
  201. package/esm/dropdown/context.d.ts +0 -1
  202. package/esm/expansion-card/context.d.ts +0 -1
  203. package/esm/form/checkbox/useCheckbox.d.ts +3 -3
  204. package/esm/form/combobox/Combobox.d.ts +1 -1
  205. package/esm/form/combobox/Combobox.js.map +1 -1
  206. package/esm/form/combobox/ComboboxProvider.js +3 -1
  207. package/esm/form/combobox/ComboboxProvider.js.map +1 -1
  208. package/esm/form/combobox/FilteredOptions/AddNewOption.d.ts +3 -0
  209. package/esm/form/combobox/FilteredOptions/AddNewOption.js +36 -0
  210. package/esm/form/combobox/FilteredOptions/AddNewOption.js.map +1 -0
  211. package/esm/form/combobox/FilteredOptions/FilteredOptions.js +13 -57
  212. package/esm/form/combobox/FilteredOptions/FilteredOptions.js.map +1 -1
  213. package/esm/form/combobox/FilteredOptions/FilteredOptionsItem.d.ts +6 -0
  214. package/esm/form/combobox/FilteredOptions/FilteredOptionsItem.js +38 -0
  215. package/esm/form/combobox/FilteredOptions/FilteredOptionsItem.js.map +1 -0
  216. package/esm/form/combobox/FilteredOptions/LoadingMessage.d.ts +3 -0
  217. package/esm/form/combobox/FilteredOptions/LoadingMessage.js +11 -0
  218. package/esm/form/combobox/FilteredOptions/LoadingMessage.js.map +1 -0
  219. package/esm/form/combobox/FilteredOptions/MaxSelectedMessage.d.ts +3 -0
  220. package/esm/form/combobox/FilteredOptions/MaxSelectedMessage.js +15 -0
  221. package/esm/form/combobox/FilteredOptions/MaxSelectedMessage.js.map +1 -0
  222. package/esm/form/combobox/FilteredOptions/NoSearchHitsMessage.d.ts +3 -0
  223. package/esm/form/combobox/FilteredOptions/NoSearchHitsMessage.js +9 -0
  224. package/esm/form/combobox/FilteredOptions/NoSearchHitsMessage.js.map +1 -0
  225. package/esm/form/combobox/FilteredOptions/filtered-options-util.d.ts +1 -0
  226. package/esm/form/combobox/FilteredOptions/filtered-options-util.js +6 -1
  227. package/esm/form/combobox/FilteredOptions/filtered-options-util.js.map +1 -1
  228. package/esm/form/combobox/FilteredOptions/filteredOptionsContext.js +5 -5
  229. package/esm/form/combobox/FilteredOptions/filteredOptionsContext.js.map +1 -1
  230. package/esm/form/combobox/Input/Input.context.d.ts +20 -7
  231. package/esm/form/combobox/Input/Input.context.js +7 -13
  232. package/esm/form/combobox/Input/Input.context.js.map +1 -1
  233. package/esm/form/combobox/Input/Input.d.ts +2 -1
  234. package/esm/form/combobox/Input/Input.js +46 -21
  235. package/esm/form/combobox/Input/Input.js.map +1 -1
  236. package/esm/form/combobox/Input/InputController.d.ts +1 -1
  237. package/esm/form/combobox/Input/InputController.js +1 -1
  238. package/esm/form/combobox/Input/InputController.js.map +1 -1
  239. package/esm/form/combobox/types.d.ts +8 -4
  240. package/esm/form/fieldset/context.d.ts +0 -1
  241. package/esm/form/fieldset/useFieldset.d.ts +1 -1
  242. package/esm/form/file-upload/FileUpload.context.d.ts +0 -1
  243. package/esm/form/file-upload/parts/dropzone/dropzone.types.d.ts +0 -1
  244. package/esm/form/file-upload/useFileUpload.d.ts +1 -2
  245. package/esm/form/radio/useRadio.d.ts +3 -3
  246. package/esm/form/search/context.d.ts +0 -1
  247. package/esm/layout/base/PrimitiveAsChildProps.d.ts +0 -1
  248. package/esm/layout/grid/HGrid.js +4 -1
  249. package/esm/layout/grid/HGrid.js.map +1 -1
  250. package/esm/layout/stack/Stack.js +7 -2
  251. package/esm/layout/stack/Stack.js.map +1 -1
  252. package/esm/list/context.d.ts +0 -1
  253. package/esm/list/types.d.ts +0 -1
  254. package/esm/modal/types.d.ts +0 -1
  255. package/esm/overlays/dismissablelayer/DismissableLayer.d.ts +1 -1
  256. package/esm/overlays/floating-menu/Menu.d.ts +106 -0
  257. package/esm/overlays/floating-menu/Menu.js +551 -0
  258. package/esm/overlays/floating-menu/Menu.js.map +1 -0
  259. package/esm/overlays/floating-menu/parts/FocusScope.d.ts +22 -0
  260. package/esm/overlays/floating-menu/parts/FocusScope.js +63 -0
  261. package/esm/overlays/floating-menu/parts/FocusScope.js.map +1 -0
  262. package/esm/overlays/floating-menu/parts/RovingFocus.d.ts +9 -0
  263. package/esm/overlays/floating-menu/parts/RovingFocus.js +86 -0
  264. package/esm/overlays/floating-menu/parts/RovingFocus.js.map +1 -0
  265. package/esm/overlays/floating-menu/parts/SlottedDivElement.d.ts +7 -0
  266. package/esm/overlays/floating-menu/parts/SlottedDivElement.js +20 -0
  267. package/esm/overlays/floating-menu/parts/SlottedDivElement.js.map +1 -0
  268. package/esm/stepper/context.d.ts +0 -1
  269. package/esm/table/context.d.ts +0 -1
  270. package/esm/tabs/Tabs.context.d.ts +1 -2
  271. package/esm/tabs/parts/tab/useTab.d.ts +1 -2
  272. package/esm/tabs/parts/tablist/useScrollButtons.d.ts +0 -1
  273. package/esm/tabs/parts/tablist/useTabList.js +2 -1
  274. package/esm/tabs/parts/tablist/useTabList.js.map +1 -1
  275. package/esm/tabs/useTabs.d.ts +0 -1
  276. package/esm/timeline/hooks/usePeriodContext.d.ts +0 -1
  277. package/esm/timeline/hooks/useRowContext.d.ts +0 -1
  278. package/esm/timeline/hooks/useTimelineContext.d.ts +0 -1
  279. package/esm/timeline/period/types.d.ts +0 -1
  280. package/esm/timeline/zoom/index.d.ts +1 -1
  281. package/esm/toggle-group/ToggleGroup.context.d.ts +1 -2
  282. package/esm/toggle-group/parts/useToggleItem.d.ts +1 -2
  283. package/esm/toggle-group/parts/useToggleItem.js +2 -1
  284. package/esm/toggle-group/parts/useToggleItem.js.map +1 -1
  285. package/esm/toggle-group/useToggleGroup.d.ts +0 -1
  286. package/esm/util/composeEventHandlers.d.ts +1 -2
  287. package/esm/util/hooks/descendants/useDescendant.d.ts +1 -1
  288. package/esm/util/hooks/useCallbackRef.d.ts +0 -1
  289. package/esm/util/hooks/useMergeRefs.d.ts +1 -1
  290. package/esm/util/i18n/i18n.context.d.ts +0 -1
  291. package/esm/util/types/AsChild.d.ts +0 -1
  292. package/esm/util/types/AsChildProps.d.ts +0 -1
  293. package/esm/util/virtualfocus/Context.d.ts +43 -0
  294. package/esm/util/virtualfocus/Context.js +5 -0
  295. package/esm/util/virtualfocus/Context.js.map +1 -0
  296. package/esm/util/virtualfocus/SlottedDivElement.d.ts +7 -0
  297. package/esm/util/virtualfocus/SlottedDivElement.js +20 -0
  298. package/esm/util/virtualfocus/SlottedDivElement.js.map +1 -0
  299. package/esm/util/virtualfocus/VirtualFocus.d.ts +62 -0
  300. package/esm/util/virtualfocus/VirtualFocus.js +63 -0
  301. package/esm/util/virtualfocus/VirtualFocus.js.map +1 -0
  302. package/esm/util/virtualfocus/parts/VirtualFocusAnchor.d.ts +33 -0
  303. package/esm/util/virtualfocus/parts/VirtualFocusAnchor.js +54 -0
  304. package/esm/util/virtualfocus/parts/VirtualFocusAnchor.js.map +1 -0
  305. package/esm/util/virtualfocus/parts/VirtualFocusContent.d.ts +4 -0
  306. package/esm/util/virtualfocus/parts/VirtualFocusContent.js +19 -0
  307. package/esm/util/virtualfocus/parts/VirtualFocusContent.js.map +1 -0
  308. package/esm/util/virtualfocus/parts/VirtualFocusItem.d.ts +18 -0
  309. package/esm/util/virtualfocus/parts/VirtualFocusItem.js +38 -0
  310. package/esm/util/virtualfocus/parts/VirtualFocusItem.js.map +1 -0
  311. package/package.json +3 -3
  312. package/src/form/combobox/Combobox.tsx +4 -1
  313. package/src/form/combobox/ComboboxProvider.tsx +3 -0
  314. package/src/form/combobox/FilteredOptions/AddNewOption.tsx +63 -0
  315. package/src/form/combobox/FilteredOptions/FilteredOptions.tsx +11 -121
  316. package/src/form/combobox/FilteredOptions/FilteredOptionsItem.tsx +73 -0
  317. package/src/form/combobox/FilteredOptions/LoadingMessage.tsx +20 -0
  318. package/src/form/combobox/FilteredOptions/MaxSelectedMessage.tsx +27 -0
  319. package/src/form/combobox/FilteredOptions/NoSearchHitsMessage.tsx +19 -0
  320. package/src/form/combobox/FilteredOptions/filtered-options-util.ts +9 -1
  321. package/src/form/combobox/FilteredOptions/filteredOptionsContext.tsx +8 -5
  322. package/src/form/combobox/Input/Input.context.tsx +27 -25
  323. package/src/form/combobox/Input/Input.tsx +60 -29
  324. package/src/form/combobox/Input/InputController.tsx +2 -0
  325. package/src/form/combobox/__tests__/combobox.test.tsx +174 -66
  326. package/src/form/combobox/types.ts +11 -7
  327. package/src/layout/grid/HGrid.tsx +4 -1
  328. package/src/layout/stack/Stack.tsx +6 -2
  329. package/src/overlays/floating-menu/Menu.tsx +1177 -0
  330. package/src/overlays/floating-menu/parts/FocusScope.tsx +84 -0
  331. package/src/overlays/floating-menu/parts/RovingFocus.tsx +121 -0
  332. package/src/overlays/floating-menu/parts/SlottedDivElement.tsx +17 -0
  333. package/src/tabs/parts/tablist/useTabList.ts +4 -1
  334. package/src/toggle-group/parts/useToggleItem.ts +4 -1
  335. package/src/util/composeEventHandlers.ts +1 -1
  336. package/src/util/virtualfocus/Context.tsx +27 -0
  337. package/src/util/virtualfocus/SlottedDivElement.tsx +17 -0
  338. package/src/util/virtualfocus/VirtualFocus.tsx +89 -0
  339. package/src/util/virtualfocus/parts/VirtualFocusAnchor.tsx +102 -0
  340. package/src/util/virtualfocus/parts/VirtualFocusContent.tsx +17 -0
  341. package/src/util/virtualfocus/parts/VirtualFocusItem.tsx +60 -0
@@ -0,0 +1,63 @@
1
+ import React, { useState } from "react";
2
+ import { useId } from "../../util/hooks/index.js";
3
+ import { VirtualFocusDescendantsProvider, VirtualFocusInternalContextProvider, useVirtualFocusDescendantInitializer, } from "./Context.js";
4
+ import { VirtualFocusAnchor } from "./parts/VirtualFocusAnchor.js";
5
+ import { VirtualFocusContent } from "./parts/VirtualFocusContent.js";
6
+ import { VirtualFocusItem } from "./parts/VirtualFocusItem.js";
7
+ /**
8
+ * A component that manages a virtual focus using the 'up' and 'down'
9
+ * arrow keys as well as selection with 'Return'.
10
+ *
11
+ * @see [📝 Documentation](https://aksel.nav.no/komponenter/core/virtualfocus)
12
+ * @see 🏷️ {@link AccordionProps}
13
+ *
14
+ * @example
15
+ * ```jsx
16
+ * <VirtualFocus>
17
+ * <VirtualFocus.Anchor
18
+ * role="combobox"
19
+ * onSelect={() => {
20
+ * console.log("you selected the anchor");
21
+ * }}
22
+ * onActive={() => {
23
+ * console.log("the anchor is now virtually focused");
24
+ * }}
25
+ * >
26
+ * <input type="text" />
27
+ * </VirtualFocus.Anchor>
28
+ * <VirtualFocus.Content>
29
+ * <VirtualFocus.Item
30
+ * onSelect={() => {
31
+ * console.log("you selected the item");
32
+ * }}
33
+ * onActive={() => {
34
+ * console.log("the item is now virtually focused");
35
+ * }}
36
+ * >
37
+ * <p>item 1</p>
38
+ * </VirtualFocus.Item>
39
+ * <VirtualFocus.Item
40
+ * onSelect={() => {
41
+ * console.log("you selected the item");
42
+ * }}
43
+ * onActive={() => {
44
+ * console.log("the item is now virtually focused");
45
+ * }}
46
+ * >
47
+ * <p>item 2</p>
48
+ * </VirtualFocus.Item>
49
+ * </VirtualFocus.Content>
50
+ * </VirtualFocus>
51
+ * ```
52
+ */
53
+ export const VirtualFocus = ({ children, loop = false }) => {
54
+ const descendants = useVirtualFocusDescendantInitializer();
55
+ const [virtualFocusIdx, setVirtualFocusIdx] = useState(0);
56
+ return (React.createElement(VirtualFocusInternalContextProvider, { virtualFocusIdx: virtualFocusIdx, setVirtualFocusIdx: setVirtualFocusIdx, loop: loop, uniqueId: useId() },
57
+ React.createElement(VirtualFocusDescendantsProvider, { value: descendants }, children)));
58
+ };
59
+ VirtualFocus.Anchor = VirtualFocusAnchor;
60
+ VirtualFocus.Item = VirtualFocusItem;
61
+ VirtualFocus.Content = VirtualFocusContent;
62
+ export default VirtualFocus;
63
+ //# sourceMappingURL=VirtualFocus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VirtualFocus.js","sourceRoot":"","sources":["../../../src/util/virtualfocus/VirtualFocus.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EACL,+BAA+B,EAC/B,mCAAmC,EACnC,oCAAoC,GACrC,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAW5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAAE,QAAQ,EAAE,IAAI,GAAG,KAAK,EAAqB,EAAE,EAAE;IAC5E,MAAM,WAAW,GAAG,oCAAoC,EAAE,CAAC;IAC3D,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAE1D,OAAO,CACL,oBAAC,mCAAmC,IAClC,eAAe,EAAE,eAAe,EAChC,kBAAkB,EAAE,kBAAkB,EACtC,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,KAAK,EAAE;QAEjB,oBAAC,+BAA+B,IAAC,KAAK,EAAE,WAAW,IAChD,QAAQ,CACuB,CACE,CACvC,CAAC;AACJ,CAAC,CAAC;AAEF,YAAY,CAAC,MAAM,GAAG,kBAAkB,CAAC;AACzC,YAAY,CAAC,IAAI,GAAG,gBAAgB,CAAC;AACrC,YAAY,CAAC,OAAO,GAAG,mBAAmB,CAAC;AAE3C,eAAe,YAAY,CAAC"}
@@ -0,0 +1,33 @@
1
+ import React from "react";
2
+ export interface VirtualFocusAnchorProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "id"> {
3
+ /**
4
+ * The role of the container. This is a limited subset of roles that
5
+ * require manual focus management.
6
+ *
7
+ * Children that are to get focus inside this container element shall be
8
+ * pointed to by `aria-activedescendant`.
9
+ **/
10
+ role: "combobox" | "grid" | "listbox" | "menu" | "menubar" | "radiogroup" | "tree" | "treegrid" | "tablist";
11
+ /**
12
+ * The function that is run when the focused element
13
+ * is to be selected (eg. do an actual search, change route... etc)
14
+ */
15
+ onSelect: () => void;
16
+ /**
17
+ * The function that is run when the element gets
18
+ * virtual focus set to it.
19
+ */
20
+ onActive: () => void;
21
+ children: React.ReactElement;
22
+ /**
23
+ * Set this to `0` if you want the Anchor itself
24
+ * to be focusable. Since this Anchor is hoisted & merged with
25
+ * its first child, you most likely want to keep this as `0`.
26
+ * @default 0
27
+ */
28
+ tabIndex?: number;
29
+ }
30
+ /**
31
+ * Must have a single child that is an input element.
32
+ */
33
+ export declare const VirtualFocusAnchor: React.ForwardRefExoticComponent<VirtualFocusAnchorProps & React.RefAttributes<HTMLInputElement>>;
@@ -0,0 +1,54 @@
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
+ import { composeEventHandlers } from "../../composeEventHandlers.js";
15
+ import { useMergeRefs } from "../../hooks/index.js";
16
+ import { useVirtualFocusDescendant, useVirtualFocusInternalContext, } from "../Context.js";
17
+ /**
18
+ * Must have a single child that is an input element.
19
+ */
20
+ export const VirtualFocusAnchor = forwardRef((_a, ref) => {
21
+ var { onSelect, onActive, children } = _a, rest = __rest(_a, ["onSelect", "onActive", "children"]);
22
+ const { virtualFocusIdx, setVirtualFocusIdx, loop, uniqueId } = useVirtualFocusInternalContext();
23
+ const { register, descendants, index } = useVirtualFocusDescendant({
24
+ handleOnActive: () => {
25
+ setVirtualFocusIdx(0);
26
+ onActive();
27
+ },
28
+ handleOnSelect: onSelect,
29
+ });
30
+ const mergedRefs = useMergeRefs(ref, register);
31
+ return (React.createElement(Slot, Object.assign({ ref: mergedRefs, tabIndex: 0 }, rest, { id: `virtualfocus-${uniqueId}-${index}`, "aria-owns": `virtualfocus-${uniqueId}-content`, "aria-controls": `virtualfocus-${uniqueId}-content`, "aria-activedescendant": `virtualfocus-${uniqueId}-${virtualFocusIdx}`, onKeyDown: composeEventHandlers(rest.onKeyDown, (event) => {
32
+ if (event.key === "ArrowDown") {
33
+ event.preventDefault();
34
+ const to_focus_descendant = descendants.next(virtualFocusIdx, loop);
35
+ if (to_focus_descendant) {
36
+ to_focus_descendant.handleOnActive();
37
+ }
38
+ }
39
+ else if (event.key === "ArrowUp") {
40
+ event.preventDefault();
41
+ const to_focus_descendant = descendants.prev(virtualFocusIdx, loop);
42
+ if (to_focus_descendant) {
43
+ to_focus_descendant.handleOnActive();
44
+ }
45
+ }
46
+ else if (event.key === "Enter") {
47
+ const curr = descendants.item(virtualFocusIdx);
48
+ if (curr === null || curr === void 0 ? void 0 : curr.handleOnSelect) {
49
+ curr.handleOnSelect();
50
+ }
51
+ }
52
+ }) }), children));
53
+ });
54
+ //# sourceMappingURL=VirtualFocusAnchor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VirtualFocusAnchor.js","sourceRoot":"","sources":["../../../../src/util/virtualfocus/parts/VirtualFocusAnchor.tsx"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EACL,yBAAyB,EACzB,8BAA8B,GAC/B,MAAM,YAAY,CAAC;AAyCpB;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAG1C,CAAC,EAAyC,EAAE,GAAG,EAAE,EAAE;QAAlD,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,OAAW,EAAN,IAAI,cAAvC,oCAAyC,CAAF;IACxC,MAAM,EAAE,eAAe,EAAE,kBAAkB,EAAE,IAAI,EAAE,QAAQ,EAAE,GAC3D,8BAA8B,EAAE,CAAC;IAEnC,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,yBAAyB,CAAC;QACjE,cAAc,EAAE,GAAG,EAAE;YACnB,kBAAkB,CAAC,CAAC,CAAC,CAAC;YACtB,QAAQ,EAAE,CAAC;QACb,CAAC;QACD,cAAc,EAAE,QAAQ;KACzB,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAE/C,OAAO,CACL,oBAAC,IAAI,kBACH,GAAG,EAAE,UAAU,EACf,QAAQ,EAAE,CAAC,IACP,IAAI,IACR,EAAE,EAAE,gBAAgB,QAAQ,IAAI,KAAK,EAAE,eAC5B,gBAAgB,QAAQ,UAAU,mBAC9B,gBAAgB,QAAQ,UAAU,2BAC1B,gBAAgB,QAAQ,IAAI,eAAe,EAAE,EACpE,SAAS,EAAE,oBAAoB,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;YACxD,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW,EAAE,CAAC;gBAC9B,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,MAAM,mBAAmB,GAAG,WAAW,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;gBACpE,IAAI,mBAAmB,EAAE,CAAC;oBACxB,mBAAmB,CAAC,cAAc,EAAE,CAAC;gBACvC,CAAC;YACH,CAAC;iBAAM,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;gBACnC,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,MAAM,mBAAmB,GAAG,WAAW,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;gBACpE,IAAI,mBAAmB,EAAE,CAAC;oBACxB,mBAAmB,CAAC,cAAc,EAAE,CAAC;gBACvC,CAAC;YACH,CAAC;iBAAM,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;gBACjC,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;gBAC/C,IAAI,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,cAAc,EAAE,CAAC;oBACzB,IAAI,CAAC,cAAc,EAAE,CAAC;gBACxB,CAAC;YACH,CAAC;QACH,CAAC,CAAC,KAED,QAAQ,CACJ,CACR,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import React from "react";
2
+ export interface VirtualFocusContentProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "id"> {
3
+ }
4
+ export declare const VirtualFocusContent: React.ForwardRefExoticComponent<VirtualFocusContentProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,19 @@
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 { useVirtualFocusInternalContext } from "../Context.js";
14
+ export const VirtualFocusContent = forwardRef((_a, ref) => {
15
+ var { children } = _a, rest = __rest(_a, ["children"]);
16
+ const { uniqueId } = useVirtualFocusInternalContext();
17
+ return (React.createElement("div", Object.assign({ ref: ref }, rest, { id: `virtualfocus-${uniqueId}-content` }), children));
18
+ });
19
+ //# sourceMappingURL=VirtualFocusContent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VirtualFocusContent.js","sourceRoot":"","sources":["../../../../src/util/virtualfocus/parts/VirtualFocusContent.tsx"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,8BAA8B,EAAE,MAAM,YAAY,CAAC;AAK5D,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAG3C,CAAC,EAAqB,EAAE,GAAG,EAAE,EAAE;QAA9B,EAAE,QAAQ,OAAW,EAAN,IAAI,cAAnB,YAAqB,CAAF;IACpB,MAAM,EAAE,QAAQ,EAAE,GAAG,8BAA8B,EAAE,CAAC;IACtD,OAAO,CACL,2CAAK,GAAG,EAAE,GAAG,IAAM,IAAI,IAAE,EAAE,EAAE,gBAAgB,QAAQ,UAAU,KAC5D,QAAQ,CACL,CACP,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -0,0 +1,18 @@
1
+ import React from "react";
2
+ export interface VirtualFocusItemProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "id" | "tabIndex"> {
3
+ /**
4
+ * The function that is run when the element is focused
5
+ * (virtually, not actual focus, eg. set a border around an item)
6
+ */
7
+ onActive: () => void;
8
+ /**
9
+ * The function that is run when the focused element
10
+ * is to be selected (eg. do an actual search, change route... etc)
11
+ */
12
+ onSelect: () => void;
13
+ children: React.ReactNode;
14
+ }
15
+ /**
16
+ * Contains an item you want to be iterable via virtual focus.
17
+ */
18
+ export declare const VirtualFocusItem: React.ForwardRefExoticComponent<VirtualFocusItemProps & React.RefAttributes<HTMLElement>>;
@@ -0,0 +1,38 @@
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
+ import { composeEventHandlers } from "../../composeEventHandlers.js";
15
+ import { useMergeRefs } from "../../hooks/index.js";
16
+ import { useVirtualFocusDescendant, useVirtualFocusInternalContext, } from "../Context.js";
17
+ /**
18
+ * Contains an item you want to be iterable via virtual focus.
19
+ */
20
+ export const VirtualFocusItem = forwardRef((_a, ref) => {
21
+ var { children, onActive, onSelect } = _a, rest = __rest(_a, ["children", "onActive", "onSelect"]);
22
+ const { virtualFocusIdx, setVirtualFocusIdx, uniqueId } = useVirtualFocusInternalContext();
23
+ const { register, index } = useVirtualFocusDescendant({
24
+ handleOnActive: () => {
25
+ setVirtualFocusIdx(index);
26
+ onActive();
27
+ },
28
+ handleOnSelect: onSelect,
29
+ });
30
+ const mergedRefs = useMergeRefs(ref, register);
31
+ return (React.createElement(Slot, Object.assign({ ref: mergedRefs }, rest, { id: `virtualfocus-${uniqueId}-${index}`, "data-aksel-virtualfocus": virtualFocusIdx === index, tabIndex: -1, onClick: composeEventHandlers(rest.onClick, () => {
32
+ onSelect();
33
+ }), onMouseMove: composeEventHandlers(rest.onMouseMove, () => {
34
+ setVirtualFocusIdx(index);
35
+ onActive();
36
+ }) }), children));
37
+ });
38
+ //# sourceMappingURL=VirtualFocusItem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VirtualFocusItem.js","sourceRoot":"","sources":["../../../../src/util/virtualfocus/parts/VirtualFocusItem.tsx"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EACL,yBAAyB,EACzB,8BAA8B,GAC/B,MAAM,YAAY,CAAC;AAiBpB;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,UAAU,CACxC,CAAC,EAAyC,EAAE,GAAG,EAAE,EAAE;QAAlD,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,OAAW,EAAN,IAAI,cAAvC,oCAAyC,CAAF;IACtC,MAAM,EAAE,eAAe,EAAE,kBAAkB,EAAE,QAAQ,EAAE,GACrD,8BAA8B,EAAE,CAAC;IACnC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,yBAAyB,CAAC;QACpD,cAAc,EAAE,GAAG,EAAE;YACnB,kBAAkB,CAAC,KAAK,CAAC,CAAC;YAC1B,QAAQ,EAAE,CAAC;QACb,CAAC;QACD,cAAc,EAAE,QAAQ;KACzB,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC/C,OAAO,CACL,oBAAC,IAAI,kBACH,GAAG,EAAE,UAAU,IACX,IAAI,IACR,EAAE,EAAE,gBAAgB,QAAQ,IAAI,KAAK,EAAE,6BACd,eAAe,KAAK,KAAK,EAClD,QAAQ,EAAE,CAAC,CAAC,EACZ,OAAO,EAAE,oBAAoB,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;YAC/C,QAAQ,EAAE,CAAC;QACb,CAAC,CAAC,EACF,WAAW,EAAE,oBAAoB,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE;YACvD,kBAAkB,CAAC,KAAK,CAAC,CAAC;YAC1B,QAAQ,EAAE,CAAC;QACb,CAAC,CAAC,KAED,QAAQ,CACJ,CACR,CAAC;AACJ,CAAC,CACF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@navikt/ds-react",
3
- "version": "6.13.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.13.0",
598
- "@navikt/ds-tokens": "^6.13.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"
@@ -10,7 +10,10 @@ import { ComboboxProps } from "./types";
10
10
 
11
11
  export const Combobox = forwardRef<
12
12
  HTMLInputElement,
13
- Omit<ComboboxProps, "onChange" | "options" | "size" | "onClear" | "value">
13
+ Omit<
14
+ ComboboxProps,
15
+ "onChange" | "options" | "size" | "onClear" | "value" | "disabled"
16
+ >
14
17
  >((props, ref) => {
15
18
  const { className, hideLabel = false, description, label, ...rest } = props;
16
19
 
@@ -35,6 +35,7 @@ const ComboboxProvider = forwardRef<HTMLInputElement, ComboboxProps>(
35
35
  allowNewValues = false,
36
36
  children,
37
37
  defaultValue,
38
+ disabled,
38
39
  error,
39
40
  errorId,
40
41
  filteredOptions: externalFilteredOptions,
@@ -60,6 +61,8 @@ const ComboboxProvider = forwardRef<HTMLInputElement, ComboboxProps>(
60
61
  <InputContextProvider
61
62
  value={{
62
63
  defaultValue,
64
+ description: rest.description,
65
+ disabled,
63
66
  error,
64
67
  errorId,
65
68
  id,
@@ -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;