@navikt/ds-react 6.0.0-alpha.1 → 6.0.0-alpha.7

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 (658) hide show
  1. package/_docs.json +520 -60
  2. package/cjs/chat/Bubble.d.ts +0 -5
  3. package/cjs/chat/Bubble.js +2 -2
  4. package/cjs/chat/Bubble.js.map +1 -1
  5. package/cjs/chat/Chat.d.ts +0 -10
  6. package/cjs/chat/Chat.js +3 -3
  7. package/cjs/chat/Chat.js.map +1 -1
  8. package/cjs/date/context/useSharedMonthContext.js +2 -6
  9. package/cjs/date/context/useSharedMonthContext.js.map +1 -1
  10. package/cjs/date/datepicker/DatePicker.js +3 -5
  11. package/cjs/date/datepicker/DatePicker.js.map +1 -1
  12. package/cjs/date/datepicker/DatePickerStandalone.js +3 -5
  13. package/cjs/date/datepicker/DatePickerStandalone.js.map +1 -1
  14. package/cjs/date/datepicker/parts/DayButton.js +2 -5
  15. package/cjs/date/datepicker/parts/DayButton.js.map +1 -1
  16. package/cjs/date/datepicker/parts/DropdownCaption.js +3 -6
  17. package/cjs/date/datepicker/parts/DropdownCaption.js.map +1 -1
  18. package/cjs/date/datepicker/parts/Row.js +2 -1
  19. package/cjs/date/datepicker/parts/Row.js.map +1 -1
  20. package/cjs/date/hooks/useDatepicker.d.ts +1 -6
  21. package/cjs/date/hooks/useDatepicker.js +7 -11
  22. package/cjs/date/hooks/useDatepicker.js.map +1 -1
  23. package/cjs/date/hooks/useMonthPicker.d.ts +1 -6
  24. package/cjs/date/hooks/useMonthPicker.js.map +1 -1
  25. package/cjs/date/hooks/useRangeDatepicker.js +20 -25
  26. package/cjs/date/hooks/useRangeDatepicker.js.map +1 -1
  27. package/cjs/date/monthpicker/MonthButton.js +11 -15
  28. package/cjs/date/monthpicker/MonthButton.js.map +1 -1
  29. package/cjs/date/monthpicker/MonthCaption.js +4 -7
  30. package/cjs/date/monthpicker/MonthCaption.js.map +1 -1
  31. package/cjs/date/monthpicker/MonthPicker.js +7 -1
  32. package/cjs/date/monthpicker/MonthPicker.js.map +1 -1
  33. package/cjs/date/monthpicker/MonthPickerStandalone.js +7 -1
  34. package/cjs/date/monthpicker/MonthPickerStandalone.js.map +1 -1
  35. package/cjs/date/monthpicker/MonthSelector.js +8 -11
  36. package/cjs/date/monthpicker/MonthSelector.js.map +1 -1
  37. package/cjs/date/parts/DateInput.d.ts +1 -1
  38. package/cjs/date/utils/check-dates.js +2 -6
  39. package/cjs/date/utils/check-dates.js.map +1 -1
  40. package/cjs/date/utils/dates-disabled.js +3 -6
  41. package/cjs/date/utils/dates-disabled.js.map +1 -1
  42. package/cjs/date/utils/format-date.d.ts +1 -0
  43. package/cjs/date/utils/format-date.js +2 -5
  44. package/cjs/date/utils/format-date.js.map +1 -1
  45. package/cjs/date/utils/get-dates.js +14 -21
  46. package/cjs/date/utils/get-dates.js.map +1 -1
  47. package/cjs/date/utils/get-initial-year.js +2 -5
  48. package/cjs/date/utils/get-initial-year.js.map +1 -1
  49. package/cjs/date/utils/is-match.js +14 -20
  50. package/cjs/date/utils/is-match.js.map +1 -1
  51. package/cjs/date/utils/labels.d.ts +1 -0
  52. package/cjs/date/utils/labels.js.map +1 -1
  53. package/cjs/date/utils/locale.d.ts +1 -1
  54. package/cjs/date/utils/locale.js +4 -9
  55. package/cjs/date/utils/locale.js.map +1 -1
  56. package/cjs/date/utils/navigation.js +21 -24
  57. package/cjs/date/utils/navigation.js.map +1 -1
  58. package/cjs/date/utils/parse-date.d.ts +1 -0
  59. package/cjs/date/utils/parse-date.js +8 -13
  60. package/cjs/date/utils/parse-date.js.map +1 -1
  61. package/cjs/form/Textarea.js +8 -8
  62. package/cjs/form/Textarea.js.map +1 -1
  63. package/cjs/form/combobox/Combobox.js +1 -1
  64. package/cjs/form/combobox/Combobox.js.map +1 -1
  65. package/cjs/form/combobox/ComboboxProvider.js +2 -1
  66. package/cjs/form/combobox/ComboboxProvider.js.map +1 -1
  67. package/cjs/form/combobox/ComboboxWrapper.js +1 -1
  68. package/cjs/form/combobox/ComboboxWrapper.js.map +1 -1
  69. package/cjs/form/combobox/FilteredOptions/FilteredOptions.js +59 -41
  70. package/cjs/form/combobox/FilteredOptions/FilteredOptions.js.map +1 -1
  71. package/cjs/form/combobox/FilteredOptions/filtered-options-util.d.ts +2 -1
  72. package/cjs/form/combobox/FilteredOptions/filtered-options-util.js +3 -1
  73. package/cjs/form/combobox/FilteredOptions/filtered-options-util.js.map +1 -1
  74. package/cjs/form/combobox/FilteredOptions/filteredOptionsContext.js +15 -3
  75. package/cjs/form/combobox/FilteredOptions/filteredOptionsContext.js.map +1 -1
  76. package/cjs/form/combobox/FilteredOptions/useVirtualFocus.d.ts +2 -4
  77. package/cjs/form/combobox/FilteredOptions/useVirtualFocus.js +52 -32
  78. package/cjs/form/combobox/FilteredOptions/useVirtualFocus.js.map +1 -1
  79. package/cjs/form/combobox/Input/Input.js +3 -1
  80. package/cjs/form/combobox/Input/Input.js.map +1 -1
  81. package/cjs/form/combobox/SelectedOptions/selectedOptionsContext.d.ts +5 -2
  82. package/cjs/form/combobox/SelectedOptions/selectedOptionsContext.js +3 -1
  83. package/cjs/form/combobox/SelectedOptions/selectedOptionsContext.js.map +1 -1
  84. package/cjs/form/combobox/types.d.ts +14 -0
  85. package/cjs/form/error-summary/ErrorSummary.d.ts +9 -3
  86. package/cjs/form/error-summary/ErrorSummary.js +4 -9
  87. package/cjs/form/error-summary/ErrorSummary.js.map +1 -1
  88. package/cjs/form/error-summary/ErrorSummaryItem.d.ts +1 -1
  89. package/cjs/form/error-summary/ErrorSummaryItem.js +2 -1
  90. package/cjs/form/error-summary/ErrorSummaryItem.js.map +1 -1
  91. package/cjs/form/search/Search.d.ts +1 -0
  92. package/cjs/form/search/Search.js +2 -2
  93. package/cjs/form/search/Search.js.map +1 -1
  94. package/cjs/index.d.ts +1 -2
  95. package/cjs/index.js +1 -3
  96. package/cjs/index.js.map +1 -1
  97. package/cjs/layout/bleed/Bleed.d.ts +2 -2
  98. package/cjs/layout/utilities/css.js +4 -0
  99. package/cjs/layout/utilities/css.js.map +1 -1
  100. package/cjs/layout/utilities/types.d.ts +1 -1
  101. package/cjs/overlays/index.d.ts +2 -0
  102. package/cjs/overlays/index.js +6 -0
  103. package/cjs/overlays/index.js.map +1 -0
  104. package/cjs/overlays/portal/Portal.d.ts +11 -0
  105. package/cjs/{grid/Grid.js → overlays/portal/Portal.js} +15 -11
  106. package/cjs/overlays/portal/Portal.js.map +1 -0
  107. package/cjs/tabs/TabList.js +2 -2
  108. package/cjs/tabs/TabList.js.map +1 -1
  109. package/cjs/tabs/TabPanel.js +2 -2
  110. package/cjs/tabs/TabPanel.js.map +1 -1
  111. package/cjs/timeline/AxisLabels.js +4 -4
  112. package/cjs/timeline/AxisLabels.js.map +1 -1
  113. package/cjs/tooltip/Tooltip.js +3 -7
  114. package/cjs/tooltip/Tooltip.js.map +1 -1
  115. package/cjs/util/Slot.js +5 -2
  116. package/cjs/util/Slot.js.map +1 -1
  117. package/cjs/util/TextareaAutoSize.js +14 -24
  118. package/cjs/util/TextareaAutoSize.js.map +1 -1
  119. package/cjs/util/types/AsChildProps.d.ts +36 -0
  120. package/cjs/util/types/AsChildProps.js +3 -0
  121. package/cjs/util/types/AsChildProps.js.map +1 -0
  122. package/cjs/util/types/index.d.ts +1 -0
  123. package/esm/accordion/Accordion.d.ts +3 -3
  124. package/esm/accordion/Accordion.js +4 -4
  125. package/esm/accordion/AccordionContent.js +2 -2
  126. package/esm/accordion/AccordionHeader.js +4 -4
  127. package/esm/accordion/AccordionItem.js +3 -3
  128. package/esm/accordion/index.d.ts +1 -1
  129. package/esm/accordion/index.js +1 -1
  130. package/esm/alert/Alert.js +2 -2
  131. package/esm/alert/index.d.ts +2 -2
  132. package/esm/alert/index.js +1 -1
  133. package/esm/button/Button.d.ts +1 -1
  134. package/esm/button/Button.js +6 -6
  135. package/esm/button/index.d.ts +2 -2
  136. package/esm/button/index.js +1 -1
  137. package/esm/chat/Bubble.d.ts +0 -5
  138. package/esm/chat/Bubble.js +3 -3
  139. package/esm/chat/Bubble.js.map +1 -1
  140. package/esm/chat/Chat.d.ts +1 -11
  141. package/esm/chat/Chat.js +5 -5
  142. package/esm/chat/Chat.js.map +1 -1
  143. package/esm/chat/index.d.ts +1 -1
  144. package/esm/chat/index.js +1 -1
  145. package/esm/chips/Chips.d.ts +3 -3
  146. package/esm/chips/Chips.js +2 -2
  147. package/esm/chips/Removable.js +1 -1
  148. package/esm/chips/Toggle.d.ts +1 -1
  149. package/esm/chips/index.d.ts +1 -1
  150. package/esm/chips/index.js +1 -1
  151. package/esm/copybutton/CopyButton.js +3 -3
  152. package/esm/copybutton/index.d.ts +1 -1
  153. package/esm/copybutton/index.js +1 -1
  154. package/esm/date/context/index.d.ts +2 -2
  155. package/esm/date/context/index.js +2 -2
  156. package/esm/date/context/useSharedMonthContext.d.ts +1 -1
  157. package/esm/date/context/useSharedMonthContext.js +2 -3
  158. package/esm/date/context/useSharedMonthContext.js.map +1 -1
  159. package/esm/date/datepicker/DatePicker.d.ts +3 -3
  160. package/esm/date/datepicker/DatePicker.js +15 -17
  161. package/esm/date/datepicker/DatePicker.js.map +1 -1
  162. package/esm/date/datepicker/DatePickerStandalone.d.ts +1 -1
  163. package/esm/date/datepicker/DatePickerStandalone.js +9 -11
  164. package/esm/date/datepicker/DatePickerStandalone.js.map +1 -1
  165. package/esm/date/datepicker/parts/Caption.js +3 -3
  166. package/esm/date/datepicker/parts/DayButton.js +1 -1
  167. package/esm/date/datepicker/parts/DayButton.js.map +1 -1
  168. package/esm/date/datepicker/parts/DropdownCaption.js +6 -9
  169. package/esm/date/datepicker/parts/DropdownCaption.js.map +1 -1
  170. package/esm/date/datepicker/parts/HeadRow.js +1 -1
  171. package/esm/date/datepicker/parts/Row.js +5 -4
  172. package/esm/date/datepicker/parts/Row.js.map +1 -1
  173. package/esm/date/datepicker/parts/WeekNumber.js +1 -1
  174. package/esm/date/datepicker/parts/WeekRow.js +6 -6
  175. package/esm/date/hooks/index.d.ts +6 -6
  176. package/esm/date/hooks/index.js +3 -3
  177. package/esm/date/hooks/useDatepicker.d.ts +3 -8
  178. package/esm/date/hooks/useDatepicker.js +2 -3
  179. package/esm/date/hooks/useDatepicker.js.map +1 -1
  180. package/esm/date/hooks/useMonthPicker.d.ts +3 -8
  181. package/esm/date/hooks/useMonthPicker.js +1 -1
  182. package/esm/date/hooks/useMonthPicker.js.map +1 -1
  183. package/esm/date/hooks/useRangeDatepicker.d.ts +3 -3
  184. package/esm/date/hooks/useRangeDatepicker.js +2 -4
  185. package/esm/date/hooks/useRangeDatepicker.js.map +1 -1
  186. package/esm/date/index.d.ts +7 -7
  187. package/esm/date/index.js +3 -3
  188. package/esm/date/monthpicker/MonthButton.js +3 -7
  189. package/esm/date/monthpicker/MonthButton.js.map +1 -1
  190. package/esm/date/monthpicker/MonthCaption.js +5 -8
  191. package/esm/date/monthpicker/MonthCaption.js.map +1 -1
  192. package/esm/date/monthpicker/MonthPicker.d.ts +3 -3
  193. package/esm/date/monthpicker/MonthPicker.js +17 -11
  194. package/esm/date/monthpicker/MonthPicker.js.map +1 -1
  195. package/esm/date/monthpicker/MonthPickerStandalone.d.ts +1 -1
  196. package/esm/date/monthpicker/MonthPickerStandalone.js +12 -6
  197. package/esm/date/monthpicker/MonthPickerStandalone.js.map +1 -1
  198. package/esm/date/monthpicker/MonthSelector.js +5 -8
  199. package/esm/date/monthpicker/MonthSelector.js.map +1 -1
  200. package/esm/date/monthpicker/types.d.ts +1 -1
  201. package/esm/date/parts/DateInput.d.ts +2 -2
  202. package/esm/date/parts/DateInput.js +5 -5
  203. package/esm/date/parts/DateWrapper.js +6 -6
  204. package/esm/date/utils/check-dates.js +1 -2
  205. package/esm/date/utils/check-dates.js.map +1 -1
  206. package/esm/date/utils/dates-disabled.js +1 -1
  207. package/esm/date/utils/dates-disabled.js.map +1 -1
  208. package/esm/date/utils/format-date.d.ts +1 -0
  209. package/esm/date/utils/format-date.js +2 -2
  210. package/esm/date/utils/format-date.js.map +1 -1
  211. package/esm/date/utils/get-dates.js +1 -5
  212. package/esm/date/utils/get-dates.js.map +1 -1
  213. package/esm/date/utils/get-initial-year.js +1 -1
  214. package/esm/date/utils/get-initial-year.js.map +1 -1
  215. package/esm/date/utils/index.d.ts +10 -10
  216. package/esm/date/utils/index.js +10 -10
  217. package/esm/date/utils/is-match.js +1 -4
  218. package/esm/date/utils/is-match.js.map +1 -1
  219. package/esm/date/utils/labels.d.ts +1 -0
  220. package/esm/date/utils/labels.js.map +1 -1
  221. package/esm/date/utils/locale.d.ts +1 -1
  222. package/esm/date/utils/locale.js +1 -3
  223. package/esm/date/utils/locale.js.map +1 -1
  224. package/esm/date/utils/navigation.d.ts +1 -1
  225. package/esm/date/utils/navigation.js +2 -2
  226. package/esm/date/utils/navigation.js.map +1 -1
  227. package/esm/date/utils/parse-date.d.ts +1 -0
  228. package/esm/date/utils/parse-date.js +2 -4
  229. package/esm/date/utils/parse-date.js.map +1 -1
  230. package/esm/dropdown/Dropdown.d.ts +2 -2
  231. package/esm/dropdown/Dropdown.js +4 -4
  232. package/esm/dropdown/Menu/GroupedList/GroupedItem.d.ts +1 -1
  233. package/esm/dropdown/Menu/GroupedList/GroupedItem.js +2 -2
  234. package/esm/dropdown/Menu/GroupedList/index.d.ts +3 -3
  235. package/esm/dropdown/Menu/GroupedList/index.js +2 -2
  236. package/esm/dropdown/Menu/List/Item.d.ts +1 -1
  237. package/esm/dropdown/Menu/List/Item.js +2 -2
  238. package/esm/dropdown/Menu/List/index.d.ts +2 -2
  239. package/esm/dropdown/Menu/List/index.js +1 -1
  240. package/esm/dropdown/Menu/index.d.ts +2 -2
  241. package/esm/dropdown/Menu/index.js +5 -5
  242. package/esm/dropdown/Toggle.js +2 -2
  243. package/esm/dropdown/index.d.ts +1 -1
  244. package/esm/dropdown/index.js +1 -1
  245. package/esm/expansion-card/ExpansionCard.d.ts +5 -5
  246. package/esm/expansion-card/ExpansionCard.js +5 -5
  247. package/esm/expansion-card/ExpansionCardContent.js +2 -2
  248. package/esm/expansion-card/ExpansionCardDescription.js +2 -2
  249. package/esm/expansion-card/ExpansionCardHeader.js +1 -1
  250. package/esm/expansion-card/ExpansionCardTitle.d.ts +1 -1
  251. package/esm/expansion-card/index.d.ts +1 -1
  252. package/esm/expansion-card/index.js +1 -1
  253. package/esm/form/ConfirmationPanel.d.ts +1 -1
  254. package/esm/form/ConfirmationPanel.js +4 -4
  255. package/esm/form/Fieldset/Fieldset.d.ts +1 -1
  256. package/esm/form/Fieldset/Fieldset.js +5 -5
  257. package/esm/form/Fieldset/index.d.ts +2 -2
  258. package/esm/form/Fieldset/index.js +2 -2
  259. package/esm/form/Fieldset/useFieldset.js +1 -1
  260. package/esm/form/Select.d.ts +1 -1
  261. package/esm/form/Select.js +4 -4
  262. package/esm/form/Switch.d.ts +1 -1
  263. package/esm/form/Switch.js +5 -5
  264. package/esm/form/TextField.d.ts +1 -1
  265. package/esm/form/TextField.js +4 -4
  266. package/esm/form/Textarea.d.ts +1 -1
  267. package/esm/form/Textarea.js +15 -15
  268. package/esm/form/Textarea.js.map +1 -1
  269. package/esm/form/TextareaCounter.d.ts +1 -1
  270. package/esm/form/TextareaCounter.js +2 -2
  271. package/esm/form/checkbox/Checkbox.d.ts +1 -1
  272. package/esm/form/checkbox/Checkbox.js +5 -5
  273. package/esm/form/checkbox/CheckboxGroup.d.ts +1 -1
  274. package/esm/form/checkbox/CheckboxGroup.js +1 -1
  275. package/esm/form/checkbox/index.d.ts +3 -3
  276. package/esm/form/checkbox/index.js +2 -2
  277. package/esm/form/checkbox/types.d.ts +1 -1
  278. package/esm/form/checkbox/useCheckbox.d.ts +1 -1
  279. package/esm/form/checkbox/useCheckbox.js +3 -3
  280. package/esm/form/combobox/Combobox.d.ts +1 -1
  281. package/esm/form/combobox/Combobox.js +12 -12
  282. package/esm/form/combobox/Combobox.js.map +1 -1
  283. package/esm/form/combobox/ComboboxProvider.d.ts +1 -1
  284. package/esm/form/combobox/ComboboxProvider.js +7 -6
  285. package/esm/form/combobox/ComboboxProvider.js.map +1 -1
  286. package/esm/form/combobox/ComboboxWrapper.js +1 -1
  287. package/esm/form/combobox/ComboboxWrapper.js.map +1 -1
  288. package/esm/form/combobox/FilteredOptions/FilteredOptions.js +65 -47
  289. package/esm/form/combobox/FilteredOptions/FilteredOptions.js.map +1 -1
  290. package/esm/form/combobox/FilteredOptions/filtered-options-util.d.ts +2 -1
  291. package/esm/form/combobox/FilteredOptions/filtered-options-util.js +3 -1
  292. package/esm/form/combobox/FilteredOptions/filtered-options-util.js.map +1 -1
  293. package/esm/form/combobox/FilteredOptions/filteredOptionsContext.d.ts +2 -2
  294. package/esm/form/combobox/FilteredOptions/filteredOptionsContext.js +20 -8
  295. package/esm/form/combobox/FilteredOptions/filteredOptionsContext.js.map +1 -1
  296. package/esm/form/combobox/FilteredOptions/useVirtualFocus.d.ts +2 -4
  297. package/esm/form/combobox/FilteredOptions/useVirtualFocus.js +52 -32
  298. package/esm/form/combobox/FilteredOptions/useVirtualFocus.js.map +1 -1
  299. package/esm/form/combobox/Input/Input.js +8 -6
  300. package/esm/form/combobox/Input/Input.js.map +1 -1
  301. package/esm/form/combobox/Input/inputContext.d.ts +1 -1
  302. package/esm/form/combobox/Input/inputContext.js +2 -2
  303. package/esm/form/combobox/SelectedOptions/SelectedOptions.js +3 -3
  304. package/esm/form/combobox/SelectedOptions/selectedOptionsContext.d.ts +5 -2
  305. package/esm/form/combobox/SelectedOptions/selectedOptionsContext.js +6 -4
  306. package/esm/form/combobox/SelectedOptions/selectedOptionsContext.js.map +1 -1
  307. package/esm/form/combobox/ToggleListButton.js +1 -1
  308. package/esm/form/combobox/customOptionsContext.js +1 -1
  309. package/esm/form/combobox/index.d.ts +2 -2
  310. package/esm/form/combobox/index.js +1 -1
  311. package/esm/form/combobox/types.d.ts +15 -1
  312. package/esm/form/error-summary/ErrorSummary.d.ts +9 -3
  313. package/esm/form/error-summary/ErrorSummary.js +8 -13
  314. package/esm/form/error-summary/ErrorSummary.js.map +1 -1
  315. package/esm/form/error-summary/ErrorSummaryItem.d.ts +2 -2
  316. package/esm/form/error-summary/ErrorSummaryItem.js +2 -1
  317. package/esm/form/error-summary/ErrorSummaryItem.js.map +1 -1
  318. package/esm/form/error-summary/index.d.ts +2 -2
  319. package/esm/form/error-summary/index.js +1 -1
  320. package/esm/form/index.d.ts +11 -11
  321. package/esm/form/index.js +11 -11
  322. package/esm/form/radio/Radio.d.ts +1 -1
  323. package/esm/form/radio/Radio.js +4 -4
  324. package/esm/form/radio/RadioGroup.d.ts +1 -1
  325. package/esm/form/radio/RadioGroup.js +2 -2
  326. package/esm/form/radio/index.d.ts +3 -3
  327. package/esm/form/radio/index.js +2 -2
  328. package/esm/form/radio/types.d.ts +1 -1
  329. package/esm/form/radio/useRadio.d.ts +1 -1
  330. package/esm/form/radio/useRadio.js +3 -3
  331. package/esm/form/search/Search.d.ts +3 -2
  332. package/esm/form/search/Search.js +8 -8
  333. package/esm/form/search/Search.js.map +1 -1
  334. package/esm/form/search/SearchButton.d.ts +1 -1
  335. package/esm/form/search/SearchButton.js +3 -3
  336. package/esm/form/search/index.d.ts +1 -1
  337. package/esm/form/search/index.js +1 -1
  338. package/esm/form/useFormField.js +2 -2
  339. package/esm/guide-panel/GuidePanel.js +1 -1
  340. package/esm/guide-panel/Illustration.js +1 -1
  341. package/esm/guide-panel/index.d.ts +2 -2
  342. package/esm/guide-panel/index.js +2 -2
  343. package/esm/help-text/HelpText.d.ts +1 -1
  344. package/esm/help-text/HelpText.js +4 -4
  345. package/esm/help-text/HelpTextIcon.js +1 -1
  346. package/esm/help-text/index.d.ts +2 -2
  347. package/esm/help-text/index.js +1 -1
  348. package/esm/index.d.ts +40 -41
  349. package/esm/index.js +40 -42
  350. package/esm/index.js.map +1 -1
  351. package/esm/internal-header/InternalHeader.d.ts +5 -5
  352. package/esm/internal-header/InternalHeader.js +4 -4
  353. package/esm/internal-header/InternalHeaderButton.d.ts +1 -1
  354. package/esm/internal-header/InternalHeaderTitle.d.ts +1 -1
  355. package/esm/internal-header/InternalHeaderUser.js +1 -1
  356. package/esm/internal-header/InternalHeaderUserButton.d.ts +1 -1
  357. package/esm/internal-header/InternalHeaderUserButton.js +2 -2
  358. package/esm/internal-header/index.d.ts +5 -5
  359. package/esm/internal-header/index.js +1 -1
  360. package/esm/layout/bleed/Bleed.d.ts +3 -3
  361. package/esm/layout/bleed/Bleed.js +2 -2
  362. package/esm/layout/bleed/index.d.ts +1 -1
  363. package/esm/layout/bleed/index.js +1 -1
  364. package/esm/layout/box/Box.d.ts +2 -2
  365. package/esm/layout/box/Box.js +1 -1
  366. package/esm/layout/box/index.d.ts +1 -1
  367. package/esm/layout/box/index.js +1 -1
  368. package/esm/layout/grid/HGrid.d.ts +1 -1
  369. package/esm/layout/grid/HGrid.js +1 -1
  370. package/esm/layout/grid/index.d.ts +1 -1
  371. package/esm/layout/grid/index.js +1 -1
  372. package/esm/layout/page/Page.d.ts +2 -2
  373. package/esm/layout/page/Page.js +1 -1
  374. package/esm/layout/page/index.d.ts +2 -2
  375. package/esm/layout/page/index.js +1 -1
  376. package/esm/layout/page/parts/PageBlock.d.ts +1 -1
  377. package/esm/layout/responsive/Responsive.d.ts +1 -1
  378. package/esm/layout/responsive/Responsive.js +1 -1
  379. package/esm/layout/responsive/index.d.ts +1 -1
  380. package/esm/layout/responsive/index.js +1 -1
  381. package/esm/layout/sidemal-test/AvatarPanel.js +2 -2
  382. package/esm/layout/sidemal-test/Content.js +9 -9
  383. package/esm/layout/sidemal-test/Filter.js +4 -4
  384. package/esm/layout/sidemal-test/Header.js +5 -5
  385. package/esm/layout/sidemal-test/Intro.js +4 -4
  386. package/esm/layout/sidemal-test/Sidebar.js +4 -4
  387. package/esm/layout/sidemal-test/content-box/ContentBox.d.ts +1 -1
  388. package/esm/layout/sidemal-test/content-box/index.d.ts +1 -1
  389. package/esm/layout/sidemal-test/content-box/index.js +1 -1
  390. package/esm/layout/stack/HStack.d.ts +2 -2
  391. package/esm/layout/stack/HStack.js +1 -1
  392. package/esm/layout/stack/Stack.d.ts +2 -2
  393. package/esm/layout/stack/Stack.js +1 -1
  394. package/esm/layout/stack/VStack.d.ts +2 -2
  395. package/esm/layout/stack/VStack.js +1 -1
  396. package/esm/layout/stack/index.d.ts +4 -4
  397. package/esm/layout/stack/index.js +4 -4
  398. package/esm/layout/utilities/css.d.ts +1 -1
  399. package/esm/layout/utilities/css.js +4 -0
  400. package/esm/layout/utilities/css.js.map +1 -1
  401. package/esm/layout/utilities/types.d.ts +1 -1
  402. package/esm/link/Link.d.ts +1 -1
  403. package/esm/link/index.d.ts +2 -2
  404. package/esm/link/index.js +1 -1
  405. package/esm/link-panel/LinkPanel.d.ts +3 -3
  406. package/esm/link-panel/LinkPanel.js +3 -3
  407. package/esm/link-panel/LinkPanelDescription.js +1 -1
  408. package/esm/link-panel/LinkPanelTitle.d.ts +1 -1
  409. package/esm/link-panel/index.d.ts +2 -2
  410. package/esm/link-panel/index.js +1 -1
  411. package/esm/list/List.d.ts +2 -2
  412. package/esm/list/List.js +4 -4
  413. package/esm/list/ListItem.js +2 -2
  414. package/esm/list/context.d.ts +1 -1
  415. package/esm/list/index.d.ts +2 -2
  416. package/esm/list/index.js +1 -1
  417. package/esm/loader/Loader.js +2 -2
  418. package/esm/loader/index.d.ts +2 -2
  419. package/esm/loader/index.js +1 -1
  420. package/esm/modal/Modal.d.ts +4 -4
  421. package/esm/modal/Modal.js +12 -12
  422. package/esm/modal/ModalHeader.js +2 -2
  423. package/esm/modal/ModalUtils.d.ts +1 -1
  424. package/esm/modal/index.d.ts +5 -5
  425. package/esm/modal/index.js +1 -1
  426. package/esm/overlays/index.d.ts +2 -0
  427. package/esm/overlays/index.js +2 -0
  428. package/esm/overlays/index.js.map +1 -0
  429. package/esm/overlays/portal/Portal.d.ts +11 -0
  430. package/esm/overlays/portal/Portal.js +27 -0
  431. package/esm/overlays/portal/Portal.js.map +1 -0
  432. package/esm/package.json +1 -1
  433. package/esm/pagination/Pagination.d.ts +1 -1
  434. package/esm/pagination/Pagination.js +2 -2
  435. package/esm/pagination/PaginationItem.d.ts +2 -2
  436. package/esm/pagination/PaginationItem.js +1 -1
  437. package/esm/pagination/index.d.ts +1 -1
  438. package/esm/pagination/index.js +1 -1
  439. package/esm/panel/Panel.d.ts +1 -1
  440. package/esm/panel/index.d.ts +2 -2
  441. package/esm/panel/index.js +1 -1
  442. package/esm/popover/Popover.d.ts +1 -1
  443. package/esm/popover/Popover.js +5 -5
  444. package/esm/popover/index.d.ts +2 -2
  445. package/esm/popover/index.js +1 -1
  446. package/esm/provider/index.d.ts +1 -1
  447. package/esm/provider/index.js +1 -1
  448. package/esm/read-more/ReadMore.js +3 -3
  449. package/esm/read-more/index.d.ts +2 -2
  450. package/esm/read-more/index.js +1 -1
  451. package/esm/skeleton/index.d.ts +2 -2
  452. package/esm/skeleton/index.js +1 -1
  453. package/esm/stepper/Step.d.ts +1 -1
  454. package/esm/stepper/Step.js +3 -3
  455. package/esm/stepper/Stepper.d.ts +1 -1
  456. package/esm/stepper/Stepper.js +2 -2
  457. package/esm/stepper/index.d.ts +1 -1
  458. package/esm/stepper/index.js +1 -1
  459. package/esm/table/ColumnHeader.d.ts +1 -1
  460. package/esm/table/ColumnHeader.js +2 -2
  461. package/esm/table/DataCell.js +1 -1
  462. package/esm/table/ExpandableRow.d.ts +1 -1
  463. package/esm/table/ExpandableRow.js +6 -6
  464. package/esm/table/Table.d.ts +8 -8
  465. package/esm/table/Table.js +8 -8
  466. package/esm/table/context.d.ts +1 -1
  467. package/esm/table/index.d.ts +9 -9
  468. package/esm/table/index.js +1 -1
  469. package/esm/tabs/Tab.d.ts +1 -1
  470. package/esm/tabs/Tab.js +2 -2
  471. package/esm/tabs/TabList.js +5 -5
  472. package/esm/tabs/TabList.js.map +1 -1
  473. package/esm/tabs/TabPanel.js +2 -2
  474. package/esm/tabs/TabPanel.js.map +1 -1
  475. package/esm/tabs/Tabs.d.ts +4 -4
  476. package/esm/tabs/Tabs.js +4 -4
  477. package/esm/tabs/index.d.ts +4 -4
  478. package/esm/tabs/index.js +1 -1
  479. package/esm/tag/Tag.js +1 -1
  480. package/esm/tag/index.d.ts +1 -1
  481. package/esm/tag/index.js +1 -1
  482. package/esm/timeline/AxisLabels.d.ts +1 -1
  483. package/esm/timeline/AxisLabels.js +5 -5
  484. package/esm/timeline/AxisLabels.js.map +1 -1
  485. package/esm/timeline/Pin.d.ts +1 -1
  486. package/esm/timeline/Pin.js +3 -3
  487. package/esm/timeline/Timeline.d.ts +5 -5
  488. package/esm/timeline/Timeline.js +9 -9
  489. package/esm/timeline/TimelineRow.d.ts +1 -1
  490. package/esm/timeline/TimelineRow.js +5 -5
  491. package/esm/timeline/hooks/useRowContext.d.ts +1 -1
  492. package/esm/timeline/hooks/useTimelineRows.d.ts +1 -1
  493. package/esm/timeline/hooks/useTimelineRows.js +3 -3
  494. package/esm/timeline/index.d.ts +6 -6
  495. package/esm/timeline/index.js +1 -1
  496. package/esm/timeline/period/ClickablePeriod.d.ts +1 -1
  497. package/esm/timeline/period/ClickablePeriod.js +5 -5
  498. package/esm/timeline/period/NonClickablePeriod.d.ts +1 -1
  499. package/esm/timeline/period/NonClickablePeriod.js +1 -1
  500. package/esm/timeline/period/index.d.ts +1 -1
  501. package/esm/timeline/period/index.js +4 -4
  502. package/esm/timeline/utils/filter.d.ts +1 -1
  503. package/esm/timeline/utils/index.d.ts +1 -1
  504. package/esm/timeline/utils/index.js +1 -1
  505. package/esm/timeline/utils/sort.d.ts +1 -1
  506. package/esm/timeline/utils/timeline.d.ts +1 -1
  507. package/esm/timeline/utils/timeline.js +1 -1
  508. package/esm/timeline/zoom/ZoomButton.js +2 -2
  509. package/esm/timeline/zoom/index.d.ts +1 -1
  510. package/esm/timeline/zoom/index.js +1 -1
  511. package/esm/toggle-group/ToggleGroup.d.ts +1 -1
  512. package/esm/toggle-group/ToggleGroup.js +4 -4
  513. package/esm/toggle-group/ToggleItem.js +2 -2
  514. package/esm/toggle-group/index.d.ts +2 -2
  515. package/esm/toggle-group/index.js +1 -1
  516. package/esm/tooltip/Tooltip.js +9 -13
  517. package/esm/tooltip/Tooltip.js.map +1 -1
  518. package/esm/tooltip/index.d.ts +1 -1
  519. package/esm/tooltip/index.js +1 -1
  520. package/esm/typography/BodyLong.d.ts +2 -2
  521. package/esm/typography/BodyLong.js +1 -1
  522. package/esm/typography/BodyShort.d.ts +2 -2
  523. package/esm/typography/BodyShort.js +1 -1
  524. package/esm/typography/Detail.d.ts +2 -2
  525. package/esm/typography/Detail.js +1 -1
  526. package/esm/typography/ErrorMessage.d.ts +2 -2
  527. package/esm/typography/ErrorMessage.js +1 -1
  528. package/esm/typography/Heading.d.ts +2 -2
  529. package/esm/typography/Heading.js +1 -1
  530. package/esm/typography/Ingress.d.ts +1 -1
  531. package/esm/typography/Label.d.ts +2 -2
  532. package/esm/typography/Label.js +1 -1
  533. package/esm/typography/index.d.ts +7 -7
  534. package/esm/typography/index.js +7 -7
  535. package/esm/typography/util.d.ts +1 -1
  536. package/esm/util/Slot.js +6 -3
  537. package/esm/util/Slot.js.map +1 -1
  538. package/esm/util/TextareaAutoSize.js +17 -27
  539. package/esm/util/TextareaAutoSize.js.map +1 -1
  540. package/esm/util/hooks/descendants/descendant.js +1 -1
  541. package/esm/util/hooks/descendants/useDescendant.d.ts +1 -1
  542. package/esm/util/hooks/descendants/useDescendant.js +5 -5
  543. package/esm/util/hooks/index.d.ts +8 -8
  544. package/esm/util/hooks/index.js +8 -8
  545. package/esm/util/hooks/useControllableState.js +1 -1
  546. package/esm/util/index.d.ts +6 -6
  547. package/esm/util/index.js +5 -5
  548. package/esm/util/types/AsChildProps.d.ts +36 -0
  549. package/esm/util/types/AsChildProps.js +2 -0
  550. package/esm/util/types/AsChildProps.js.map +1 -0
  551. package/esm/util/types/index.d.ts +2 -1
  552. package/package.json +13 -12
  553. package/src/alert/alert.stories.tsx +202 -113
  554. package/src/chat/Bubble.tsx +2 -23
  555. package/src/chat/Chat.tsx +1 -18
  556. package/src/chat/chat.stories.tsx +0 -31
  557. package/src/date/context/useSharedMonthContext.tsx +1 -2
  558. package/src/date/datepicker/DatePicker.tsx +1 -3
  559. package/src/date/datepicker/DatePickerStandalone.tsx +1 -3
  560. package/src/date/datepicker/datepicker.stories.tsx +5 -5
  561. package/src/date/datepicker/parts/DayButton.tsx +1 -1
  562. package/src/date/datepicker/parts/DropdownCaption.tsx +1 -4
  563. package/src/date/datepicker/parts/Row.tsx +3 -2
  564. package/src/date/hooks/useDatepicker.tsx +2 -8
  565. package/src/date/hooks/useMonthPicker.tsx +1 -6
  566. package/src/date/hooks/useRangeDatepicker.tsx +5 -3
  567. package/src/date/monthpicker/MonthButton.tsx +7 -5
  568. package/src/date/monthpicker/MonthCaption.tsx +7 -4
  569. package/src/date/monthpicker/MonthPicker.tsx +10 -8
  570. package/src/date/monthpicker/MonthPickerStandalone.tsx +10 -8
  571. package/src/date/monthpicker/MonthSelector.tsx +1 -4
  572. package/src/date/monthpicker/monthpicker.stories.tsx +3 -2
  573. package/src/date/parts/DateInput.tsx +1 -1
  574. package/src/date/utils/__tests__/format-dates.test.ts +1 -1
  575. package/src/date/utils/__tests__/get-initial-year.test.ts +1 -1
  576. package/src/date/utils/__tests__/parse-dates.test.ts +2 -2
  577. package/src/date/utils/check-dates.ts +1 -2
  578. package/src/date/utils/dates-disabled.ts +1 -1
  579. package/src/date/utils/format-date.ts +1 -1
  580. package/src/date/utils/get-dates.ts +7 -5
  581. package/src/date/utils/get-initial-year.ts +1 -1
  582. package/src/date/utils/is-match.ts +6 -4
  583. package/src/date/utils/labels.ts +1 -0
  584. package/src/date/utils/locale.ts +1 -3
  585. package/src/date/utils/navigation.ts +1 -1
  586. package/src/date/utils/parse-date.ts +1 -3
  587. package/src/form/Textarea.tsx +34 -34
  588. package/src/form/combobox/Combobox.tsx +1 -1
  589. package/src/form/combobox/ComboboxProvider.tsx +2 -0
  590. package/src/form/combobox/ComboboxWrapper.tsx +0 -1
  591. package/src/form/combobox/FilteredOptions/FilteredOptions.tsx +131 -92
  592. package/src/form/combobox/FilteredOptions/filtered-options-util.ts +9 -2
  593. package/src/form/combobox/FilteredOptions/filteredOptionsContext.tsx +22 -3
  594. package/src/form/combobox/FilteredOptions/useVirtualFocus.ts +63 -45
  595. package/src/form/combobox/Input/Input.tsx +3 -1
  596. package/src/form/combobox/SelectedOptions/selectedOptionsContext.tsx +11 -1
  597. package/src/form/combobox/combobox.stories.tsx +36 -1
  598. package/src/form/combobox/combobox.test.tsx +1 -3
  599. package/src/form/combobox/types.ts +15 -0
  600. package/src/form/error-summary/ErrorSummary.tsx +15 -11
  601. package/src/form/error-summary/ErrorSummaryItem.tsx +10 -8
  602. package/src/form/error-summary/error-summary.stories.tsx +55 -1
  603. package/src/form/search/Search.tsx +6 -1
  604. package/src/form/stories/textarea.stories.tsx +37 -0
  605. package/src/index.ts +1 -2
  606. package/src/layout/bleed/Bleed.stories.tsx +13 -0
  607. package/src/layout/bleed/Bleed.tsx +2 -2
  608. package/src/layout/box/Box.stories.tsx +1 -1
  609. package/src/layout/sidemal-test/navno-sidemal.stories.tsx +1 -0
  610. package/src/layout/utilities/css.ts +3 -0
  611. package/src/layout/utilities/types.ts +1 -1
  612. package/src/overlays/index.ts +2 -0
  613. package/src/overlays/portal/Portal.stories.tsx +99 -0
  614. package/src/overlays/portal/Portal.tsx +32 -0
  615. package/src/tabs/TabList.tsx +2 -2
  616. package/src/tabs/TabPanel.tsx +2 -2
  617. package/src/timeline/AxisLabels.tsx +1 -1
  618. package/src/tooltip/Tooltip.tsx +4 -8
  619. package/src/util/Slot.tsx +4 -2
  620. package/src/util/TextareaAutoSize.tsx +16 -31
  621. package/src/util/types/AsChildProps.ts +37 -0
  622. package/src/util/types/index.ts +1 -0
  623. package/cjs/grid/Cell.d.ts +0 -30
  624. package/cjs/grid/Cell.js +0 -52
  625. package/cjs/grid/Cell.js.map +0 -1
  626. package/cjs/grid/Grid.d.ts +0 -13
  627. package/cjs/grid/Grid.js.map +0 -1
  628. package/cjs/grid/index.d.ts +0 -2
  629. package/cjs/grid/index.js +0 -11
  630. package/cjs/grid/index.js.map +0 -1
  631. package/cjs/layout/content-container/ContentContainer.d.ts +0 -9
  632. package/cjs/layout/content-container/ContentContainer.js +0 -48
  633. package/cjs/layout/content-container/ContentContainer.js.map +0 -1
  634. package/cjs/layout/content-container/index.d.ts +0 -1
  635. package/cjs/layout/content-container/index.js +0 -9
  636. package/cjs/layout/content-container/index.js.map +0 -1
  637. package/esm/grid/Cell.d.ts +0 -30
  638. package/esm/grid/Cell.js +0 -23
  639. package/esm/grid/Cell.js.map +0 -1
  640. package/esm/grid/Grid.d.ts +0 -13
  641. package/esm/grid/Grid.js +0 -23
  642. package/esm/grid/Grid.js.map +0 -1
  643. package/esm/grid/index.d.ts +0 -2
  644. package/esm/grid/index.js +0 -3
  645. package/esm/grid/index.js.map +0 -1
  646. package/esm/layout/content-container/ContentContainer.d.ts +0 -9
  647. package/esm/layout/content-container/ContentContainer.js +0 -19
  648. package/esm/layout/content-container/ContentContainer.js.map +0 -1
  649. package/esm/layout/content-container/index.d.ts +0 -1
  650. package/esm/layout/content-container/index.js +0 -2
  651. package/esm/layout/content-container/index.js.map +0 -1
  652. package/src/grid/Cell.tsx +0 -53
  653. package/src/grid/Grid.tsx +0 -23
  654. package/src/grid/grid.stories.tsx +0 -67
  655. package/src/grid/index.ts +0 -2
  656. package/src/layout/content-container/ContentContainer.tsx +0 -22
  657. package/src/layout/content-container/index.ts +0 -4
  658. package/src/layout/sidemal-test/navno-sidemal.stories.mdx +0 -29
@@ -27,111 +27,150 @@ const FilteredOptions = () => {
27
27
  activeDecendantId,
28
28
  virtualFocus,
29
29
  } = useFilteredOptionsContext();
30
- const { isMultiSelect, selectedOptions, toggleOption } =
30
+ const { isMultiSelect, selectedOptions, toggleOption, maxSelected } =
31
31
  useSelectedOptionsContext();
32
32
 
33
+ const isDisabled = (option) =>
34
+ maxSelected?.isLimitReached && !selectedOptions.includes(option);
35
+
36
+ const shouldRenderNonSelectables =
37
+ maxSelected?.isLimitReached || // Render maxSelected message
38
+ isLoading || // Render loading message
39
+ (!isLoading && filteredOptions.length === 0); // Render no hits message
40
+
41
+ const shouldRenderFilteredOptionsList =
42
+ (allowNewValues && isValueNew && !maxSelected?.isLimitReached) || // Render add new option
43
+ filteredOptions.length > 0; // Render filtered options
44
+
33
45
  return (
34
- <ul
35
- ref={setFilteredOptionsRef}
46
+ <div
36
47
  className={cl("navds-combobox__list", {
37
48
  "navds-combobox__list--closed": !isListOpen,
38
49
  "navds-combobox__list--with-hover": isMouseLastUsedInputDevice,
39
50
  })}
40
51
  id={filteredOptionsUtil.getFilteredOptionsId(id)}
41
- role="listbox"
42
52
  tabIndex={-1}
43
53
  >
44
- {isLoading && (
45
- <li
46
- className="navds-combobox__list-item--loading"
47
- role="option"
48
- aria-selected={false}
49
- id={filteredOptionsUtil.getIsLoadingId(id)}
50
- data-no-focus="true"
51
- >
52
- <Loader aria-label="Søker..." />
53
- </li>
54
+ {shouldRenderNonSelectables && (
55
+ <div className="navds-combobox__list_non-selectables" role="status">
56
+ {maxSelected?.isLimitReached && (
57
+ <div
58
+ className="navds-combobox__list-item--max-selected"
59
+ id={filteredOptionsUtil.getMaxSelectedOptionsId(id)}
60
+ >
61
+ {maxSelected.message ??
62
+ `${selectedOptions.length} av ${maxSelected.limit} er valgt.`}
63
+ </div>
64
+ )}
65
+ {isLoading && (
66
+ <div
67
+ className="navds-combobox__list-item--loading"
68
+ id={filteredOptionsUtil.getIsLoadingId(id)}
69
+ >
70
+ <Loader title="Søker..." />
71
+ </div>
72
+ )}
73
+ {!isLoading && filteredOptions.length === 0 && (
74
+ <div
75
+ className="navds-combobox__list-item--no-options"
76
+ id={filteredOptionsUtil.getNoHitsId(id)}
77
+ >
78
+ Ingen søketreff
79
+ </div>
80
+ )}
81
+ </div>
54
82
  )}
55
- {isValueNew && allowNewValues && (
56
- <li
57
- tabIndex={-1}
58
- onMouseMove={() => {
59
- if (
60
- activeDecendantId !== filteredOptionsUtil.getAddNewOptionId(id)
61
- ) {
62
- virtualFocus.moveFocusToElement(
63
- filteredOptionsUtil.getAddNewOptionId(id),
64
- );
65
- setIsMouseLastUsedInputDevice(true);
66
- }
67
- }}
68
- onPointerUp={(event) => {
69
- toggleOption(value, event);
70
- if (!isMultiSelect && !selectedOptions.includes(value))
71
- toggleIsListOpen(false);
72
- }}
73
- id={filteredOptionsUtil.getAddNewOptionId(id)}
74
- className={cl("navds-combobox__list-item__new-option", {
75
- "navds-combobox__list-item__new-option--focus":
76
- activeDecendantId === filteredOptionsUtil.getAddNewOptionId(id),
77
- })}
78
- role="option"
79
- aria-selected={false}
80
- >
81
- <PlusIcon aria-hidden />
82
- <BodyShort size={size}>
83
- Legg til{" "}
84
- <Label as="span" size={size}>
85
- &#8220;{value}&#8221;
86
- </Label>
87
- </BodyShort>
88
- </li>
89
- )}
90
- {!isLoading && filteredOptions.length === 0 && (
91
- <li
92
- className="navds-combobox__list-item__no-options"
93
- role="option"
94
- aria-selected={false}
95
- id={filteredOptionsUtil.getNoHitsId(id)}
96
- data-no-focus="true"
83
+
84
+ {shouldRenderFilteredOptionsList && (
85
+ <ul
86
+ ref={setFilteredOptionsRef}
87
+ role="listbox"
88
+ className="navds-combobox__list-options"
97
89
  >
98
- Ingen søketreff
99
- </li>
90
+ {isValueNew && !maxSelected?.isLimitReached && allowNewValues && (
91
+ <li
92
+ tabIndex={-1}
93
+ onMouseMove={() => {
94
+ if (
95
+ activeDecendantId !==
96
+ filteredOptionsUtil.getAddNewOptionId(id)
97
+ ) {
98
+ virtualFocus.moveFocusToElement(
99
+ filteredOptionsUtil.getAddNewOptionId(id),
100
+ );
101
+ setIsMouseLastUsedInputDevice(true);
102
+ }
103
+ }}
104
+ onPointerUp={(event) => {
105
+ toggleOption(value, event);
106
+ if (!isMultiSelect && !selectedOptions.includes(value))
107
+ toggleIsListOpen(false);
108
+ }}
109
+ id={filteredOptionsUtil.getAddNewOptionId(id)}
110
+ className={cl(
111
+ "navds-combobox__list-item navds-combobox__list-item--new-option",
112
+ {
113
+ "navds-combobox__list-item--new-option--focus":
114
+ activeDecendantId ===
115
+ filteredOptionsUtil.getAddNewOptionId(id),
116
+ },
117
+ )}
118
+ role="option"
119
+ aria-selected={false}
120
+ >
121
+ <PlusIcon aria-hidden />
122
+ <BodyShort size={size}>
123
+ Legg til{" "}
124
+ <Label as="span" size={size}>
125
+ &#8220;{value}&#8221;
126
+ </Label>
127
+ </BodyShort>
128
+ </li>
129
+ )}
130
+ {filteredOptions.map((option) => (
131
+ <li
132
+ className={cl("navds-combobox__list-item", {
133
+ "navds-combobox__list-item--focus":
134
+ activeDecendantId ===
135
+ filteredOptionsUtil.getOptionId(id, option),
136
+ "navds-combobox__list-item--selected":
137
+ selectedOptions.includes(option),
138
+ })}
139
+ data-no-focus={isDisabled(option) || undefined}
140
+ id={filteredOptionsUtil.getOptionId(id, option)}
141
+ key={option}
142
+ tabIndex={-1}
143
+ onMouseMove={() => {
144
+ if (
145
+ activeDecendantId !==
146
+ filteredOptionsUtil.getOptionId(id, option)
147
+ ) {
148
+ virtualFocus.moveFocusToElement(
149
+ filteredOptionsUtil.getOptionId(id, option),
150
+ );
151
+ setIsMouseLastUsedInputDevice(true);
152
+ }
153
+ }}
154
+ onPointerUp={(event) => {
155
+ if (isDisabled(option)) {
156
+ return;
157
+ }
158
+ toggleOption(option, event);
159
+ if (!isMultiSelect && !selectedOptions.includes(option)) {
160
+ toggleIsListOpen(false);
161
+ }
162
+ }}
163
+ role="option"
164
+ aria-selected={selectedOptions.includes(option)}
165
+ aria-disabled={isDisabled(option) || undefined}
166
+ >
167
+ <BodyShort size={size}>{option}</BodyShort>
168
+ {selectedOptions.includes(option) && <CheckmarkIcon />}
169
+ </li>
170
+ ))}
171
+ </ul>
100
172
  )}
101
- {filteredOptions.map((option) => (
102
- <li
103
- className={cl("navds-combobox__list-item", {
104
- "navds-combobox__list-item--focus":
105
- activeDecendantId === filteredOptionsUtil.getOptionId(id, option),
106
- "navds-combobox__list-item--selected":
107
- selectedOptions.includes(option),
108
- })}
109
- id={filteredOptionsUtil.getOptionId(id, option)}
110
- key={option}
111
- tabIndex={-1}
112
- onMouseMove={() => {
113
- if (
114
- activeDecendantId !== filteredOptionsUtil.getOptionId(id, option)
115
- ) {
116
- virtualFocus.moveFocusToElement(
117
- filteredOptionsUtil.getOptionId(id, option),
118
- );
119
- setIsMouseLastUsedInputDevice(true);
120
- }
121
- }}
122
- onPointerUp={(event) => {
123
- toggleOption(option, event);
124
- if (!isMultiSelect && !selectedOptions.includes(option))
125
- toggleIsListOpen(false);
126
- }}
127
- role="option"
128
- aria-selected={selectedOptions.includes(option)}
129
- >
130
- <BodyShort size={size}>{option}</BodyShort>
131
- {selectedOptions.includes(option) && <CheckmarkIcon />}
132
- </li>
133
- ))}
134
- </ul>
173
+ </div>
135
174
  );
136
175
  };
137
176
 
@@ -7,8 +7,11 @@ const isPartOfText = (value, text) =>
7
7
  const isValueInList = (value, list) =>
8
8
  list?.find((listItem) => normalizeText(value) === normalizeText(listItem));
9
9
 
10
- const getMatchingValuesFromList = (value, list) =>
11
- list?.filter((listItem) => isPartOfText(value, listItem));
10
+ const getMatchingValuesFromList = (value, list, alwaysIncluded) =>
11
+ list?.filter(
12
+ (listItem) =>
13
+ isPartOfText(value, listItem) || alwaysIncluded.includes(listItem),
14
+ );
12
15
 
13
16
  const getFilteredOptionsId = (comboboxId: string) =>
14
17
  `${comboboxId}-filtered-options`;
@@ -25,6 +28,9 @@ const getIsLoadingId = (comboboxId: string) => `${comboboxId}-is-loading`;
25
28
 
26
29
  const getNoHitsId = (comboboxId: string) => `${comboboxId}-no-hits`;
27
30
 
31
+ const getMaxSelectedOptionsId = (comboboxId: string) =>
32
+ `${comboboxId}-max-selected-options`;
33
+
28
34
  export default {
29
35
  normalizeText,
30
36
  isPartOfText,
@@ -35,4 +41,5 @@ export default {
35
41
  getOptionId,
36
42
  getIsLoadingId,
37
43
  getNoHitsId,
44
+ getMaxSelectedOptionsId,
38
45
  };
@@ -9,6 +9,7 @@ import React, {
9
9
  } from "react";
10
10
  import { useClientLayoutEffect, usePrevious } from "../../../util/hooks";
11
11
  import { useInputContext } from "../Input/inputContext";
12
+ import { useSelectedOptionsContext } from "../SelectedOptions/selectedOptionsContext";
12
13
  import { useCustomOptionsContext } from "../customOptionsContext";
13
14
  import { ComboboxProps } from "../types";
14
15
  import filteredOptionsUtils from "./filtered-options-util";
@@ -70,6 +71,7 @@ export const FilteredOptionsProvider = ({
70
71
  setSearchTerm,
71
72
  shouldAutocomplete,
72
73
  } = useInputContext();
74
+ const { selectedOptions, maxSelected } = useSelectedOptionsContext();
73
75
 
74
76
  const [isInternalListOpen, setInternalListOpen] = useState(false);
75
77
  const { customOptions } = useCustomOptionsContext();
@@ -79,8 +81,18 @@ export const FilteredOptionsProvider = ({
79
81
  return externalFilteredOptions;
80
82
  }
81
83
  const opts = [...customOptions, ...options];
82
- return filteredOptionsUtils.getMatchingValuesFromList(searchTerm, opts);
83
- }, [customOptions, externalFilteredOptions, options, searchTerm]);
84
+ return filteredOptionsUtils.getMatchingValuesFromList(
85
+ searchTerm,
86
+ opts,
87
+ selectedOptions,
88
+ );
89
+ }, [
90
+ customOptions,
91
+ externalFilteredOptions,
92
+ options,
93
+ searchTerm,
94
+ selectedOptions,
95
+ ]);
84
96
 
85
97
  const previousSearchTerm = usePrevious(searchTerm);
86
98
 
@@ -154,10 +166,17 @@ export const FilteredOptionsProvider = ({
154
166
  activeOption = filteredOptionsUtils.getIsLoadingId(id);
155
167
  }
156
168
  }
157
- return cl(activeOption, partialAriaDescribedBy) || undefined;
169
+ const maybeMaxSelectedOptionsId =
170
+ maxSelected?.isLimitReached &&
171
+ filteredOptionsUtils.getMaxSelectedOptionsId(id);
172
+ return (
173
+ cl(activeOption, maybeMaxSelectedOptionsId, partialAriaDescribedBy) ||
174
+ undefined
175
+ );
158
176
  }, [
159
177
  isListOpen,
160
178
  isLoading,
179
+ maxSelected?.isLimitReached,
161
180
  value,
162
181
  partialAriaDescribedBy,
163
182
  shouldAutocomplete,
@@ -1,11 +1,10 @@
1
- import { Dispatch, SetStateAction, useState } from "react";
1
+ import { useState } from "react";
2
2
 
3
3
  export type VirtualFocusType = {
4
4
  activeElement: HTMLElement | undefined;
5
5
  getElementById: (id: string) => HTMLElement | undefined;
6
- isFocusOnTheTop: boolean;
7
- isFocusOnTheBottom: boolean;
8
- setIndex: Dispatch<SetStateAction<number>>;
6
+ isFocusOnTheTop: () => boolean;
7
+ isFocusOnTheBottom: () => boolean;
9
8
  moveFocusUp: () => void;
10
9
  moveFocusDown: () => void;
11
10
  moveFocusToElement: (id: string) => void;
@@ -16,57 +15,77 @@ export type VirtualFocusType = {
16
15
  const useVirtualFocus = (
17
16
  containerRef: HTMLElement | null,
18
17
  ): VirtualFocusType => {
19
- const [index, setIndex] = useState(-1);
20
-
21
- const listOfAllChildren: HTMLElement[] = containerRef?.children
22
- ? Array.prototype.slice.call(containerRef?.children)
23
- : [];
24
- const elementsAbleToReceiveFocus = listOfAllChildren.filter(
25
- (child) => child.getAttribute("data-no-focus") !== "true",
18
+ const [activeElement, setActiveElement] = useState<HTMLElement | undefined>(
19
+ undefined,
26
20
  );
27
21
 
28
- const activeElement = elementsAbleToReceiveFocus[index];
22
+ const getListOfAllChildren = (): HTMLElement[] =>
23
+ Array.from(containerRef?.children ?? []) as HTMLElement[];
24
+ const getElementsAbleToReceiveFocus = () =>
25
+ getListOfAllChildren().filter(
26
+ (child) => child.getAttribute("data-no-focus") !== "true",
27
+ );
28
+
29
29
  const getElementById = (id: string) =>
30
- listOfAllChildren.find((element) => element.id === id);
31
- const isFocusOnTheTop = index === 0;
32
- const isFocusOnTheBottom = index === elementsAbleToReceiveFocus.length - 1;
30
+ getListOfAllChildren().find((element) => element.id === id);
31
+ const isFocusOnTheTop = () =>
32
+ activeElement
33
+ ? getElementsAbleToReceiveFocus().indexOf(activeElement) === 0
34
+ : false;
35
+ const isFocusOnTheBottom = () => {
36
+ const elementsAbleToReceiveFocus = getElementsAbleToReceiveFocus();
37
+ return activeElement
38
+ ? elementsAbleToReceiveFocus.indexOf(activeElement) ===
39
+ elementsAbleToReceiveFocus.length - 1
40
+ : false;
41
+ };
33
42
 
34
- const scrollToOption = (newIndex: number) => {
35
- const indexOfElementToScrollTo = Math.min(
36
- Math.max(newIndex, 0),
37
- containerRef?.children.length || 0,
38
- );
39
- if (containerRef?.children[indexOfElementToScrollTo]) {
40
- const child = containerRef.children[indexOfElementToScrollTo];
41
- const { top, bottom } = child.getBoundingClientRect();
42
- const parentRect = containerRef.getBoundingClientRect();
43
- if (top < parentRect.top || bottom > parentRect.bottom) {
44
- child.scrollIntoView({ block: "nearest" });
45
- }
43
+ const _moveFocusAndScrollTo = (_element?: HTMLElement) => {
44
+ setActiveElement(_element);
45
+ _element?.scrollIntoView?.({ block: "nearest" });
46
+ };
47
+
48
+ const moveFocusUp = () => {
49
+ if (!activeElement) {
50
+ return;
51
+ }
52
+ const elementsAbleToReceiveFocus = getElementsAbleToReceiveFocus();
53
+ const _currentIndex = elementsAbleToReceiveFocus.indexOf(activeElement);
54
+ const elementAbove = elementsAbleToReceiveFocus[_currentIndex - 1];
55
+ if (_currentIndex === 0) {
56
+ setActiveElement(undefined);
57
+ } else {
58
+ _moveFocusAndScrollTo(elementAbove);
46
59
  }
47
60
  };
48
61
 
49
- const _moveFocusAndScrollTo = (_index: number) => {
50
- setIndex(_index);
51
- scrollToOption(_index);
62
+ const moveFocusDown = () => {
63
+ const elementsAbleToReceiveFocus = getElementsAbleToReceiveFocus();
64
+ if (!activeElement) {
65
+ _moveFocusAndScrollTo(elementsAbleToReceiveFocus[0]);
66
+ return;
67
+ }
68
+ const _currentIndex = elementsAbleToReceiveFocus.indexOf(activeElement);
69
+ if (_currentIndex === elementsAbleToReceiveFocus.length - 1) {
70
+ return;
71
+ } else {
72
+ _moveFocusAndScrollTo(elementsAbleToReceiveFocus[_currentIndex + 1]);
73
+ }
52
74
  };
53
- const moveFocusUp = () => _moveFocusAndScrollTo(Math.max(index - 1, -1));
54
- const moveFocusDown = () =>
55
- _moveFocusAndScrollTo(
56
- Math.min(index + 1, elementsAbleToReceiveFocus.length - 1),
75
+
76
+ const moveFocusToTop = () => _moveFocusAndScrollTo(undefined);
77
+ const moveFocusToBottom = () => {
78
+ const elementsAbleToReceiveFocus = getElementsAbleToReceiveFocus();
79
+ return _moveFocusAndScrollTo(
80
+ elementsAbleToReceiveFocus[elementsAbleToReceiveFocus.length - 1],
57
81
  );
58
- const moveFocusToTop = () => _moveFocusAndScrollTo(-1);
59
- const moveFocusToBottom = () =>
60
- _moveFocusAndScrollTo(elementsAbleToReceiveFocus.length - 1);
82
+ };
61
83
  const moveFocusToElement = (id: string) => {
62
- const thisElement = elementsAbleToReceiveFocus.find(
63
- (_element) => _element.getAttribute("id") === id,
84
+ const _element = getElementsAbleToReceiveFocus().find(
85
+ (_focusableElement) => _focusableElement.getAttribute("id") === id,
64
86
  );
65
- const indexOfElement = thisElement
66
- ? elementsAbleToReceiveFocus.indexOf(thisElement)
67
- : -1;
68
- if (indexOfElement >= 0) {
69
- setIndex(indexOfElement);
87
+ if (_element) {
88
+ setActiveElement(_element);
70
89
  }
71
90
  };
72
91
 
@@ -75,7 +94,6 @@ const useVirtualFocus = (
75
94
  getElementById,
76
95
  isFocusOnTheTop,
77
96
  isFocusOnTheBottom,
78
- setIndex,
79
97
  moveFocusUp,
80
98
  moveFocusDown,
81
99
  moveFocusToElement,
@@ -101,9 +101,11 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
101
101
  onEnter(e);
102
102
  break;
103
103
  case "Home":
104
+ toggleIsListOpen(false);
104
105
  virtualFocus.moveFocusToTop();
105
106
  break;
106
107
  case "End":
108
+ toggleIsListOpen(true);
107
109
  virtualFocus.moveFocusToBottom();
108
110
  break;
109
111
  default:
@@ -135,7 +137,7 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
135
137
  // Otherwise ignore keystrokes, so it doesn't interfere with text editing
136
138
  if (isListOpen && activeDecendantId) {
137
139
  e.preventDefault();
138
- if (virtualFocus.isFocusOnTheTop) {
140
+ if (virtualFocus.isFocusOnTheTop()) {
139
141
  toggleIsListOpen(false);
140
142
  }
141
143
  virtualFocus.moveFocusUp();
@@ -8,7 +8,7 @@ import React, {
8
8
  import { usePrevious } from "../../../util/hooks";
9
9
  import { useInputContext } from "../Input/inputContext";
10
10
  import { useCustomOptionsContext } from "../customOptionsContext";
11
- import { ComboboxProps } from "../types";
11
+ import { ComboboxProps, MaxSelected } from "../types";
12
12
 
13
13
  type SelectedOptionsContextType = {
14
14
  addSelectedOption: (option: string) => void;
@@ -16,6 +16,7 @@ type SelectedOptionsContextType = {
16
16
  removeSelectedOption: (option: string) => void;
17
17
  prevSelectedOptions?: string[];
18
18
  selectedOptions: string[];
19
+ maxSelected?: MaxSelected & { isLimitReached: boolean };
19
20
  setSelectedOptions: (any) => void;
20
21
  toggleOption: (
21
22
  option: string,
@@ -39,6 +40,7 @@ export const SelectedOptionsProvider = ({
39
40
  | "options"
40
41
  | "selectedOptions"
41
42
  | "onToggleSelected"
43
+ | "maxSelected"
42
44
  >;
43
45
  }) => {
44
46
  const { clearInput, focusInput } = useInputContext();
@@ -54,6 +56,7 @@ export const SelectedOptionsProvider = ({
54
56
  selectedOptions: externalSelectedOptions,
55
57
  onToggleSelected,
56
58
  options,
59
+ maxSelected,
57
60
  } = value;
58
61
  const [internalSelectedOptions, setSelectedOptions] = useState<string[]>([]);
59
62
  const selectedOptions = useMemo(
@@ -129,6 +132,9 @@ export const SelectedOptionsProvider = ({
129
132
 
130
133
  const prevSelectedOptions = usePrevious<string[]>(selectedOptions);
131
134
 
135
+ const isLimitReached =
136
+ !!maxSelected?.limit && selectedOptions.length >= maxSelected.limit;
137
+
132
138
  const selectedOptionsState = {
133
139
  addSelectedOption,
134
140
  isMultiSelect,
@@ -137,6 +143,10 @@ export const SelectedOptionsProvider = ({
137
143
  selectedOptions,
138
144
  setSelectedOptions,
139
145
  toggleOption,
146
+ maxSelected: maxSelected && {
147
+ ...maxSelected,
148
+ isLimitReached,
149
+ },
140
150
  };
141
151
 
142
152
  return (
@@ -1,6 +1,6 @@
1
1
  import { Meta, StoryFn, StoryObj } from "@storybook/react";
2
2
  import { expect, fn, userEvent, within } from "@storybook/test";
3
- import React, { useId, useMemo, useState } from "react";
3
+ import React, { useId, useMemo, useRef, useState } from "react";
4
4
  import { Chips, ComboboxProps, TextField, UNSAFE_Combobox } from "../../index";
5
5
 
6
6
  export default {
@@ -37,11 +37,16 @@ Default.args = {
37
37
  label: "Hva er dine favorittfrukter?",
38
38
  shouldAutocomplete: true,
39
39
  isLoading: false,
40
+ isMultiSelect: false,
41
+ allowNewValues: false,
40
42
  };
41
43
  Default.argTypes = {
42
44
  isListOpen: {
43
45
  control: { type: "boolean" },
44
46
  },
47
+ maxSelected: {
48
+ control: { type: "number" },
49
+ },
45
50
  size: {
46
51
  options: ["medium", "small"],
47
52
  defaultValue: "medium",
@@ -284,6 +289,36 @@ export const ComboboxSizes = () => (
284
289
  </>
285
290
  );
286
291
 
292
+ export const MaxSelectedOptions: StoryFunction = () => {
293
+ const id = useId();
294
+ const [value, setValue] = useState<string | undefined>("");
295
+ const [selectedOptions, setSelectedOptions] = useState([
296
+ options[0],
297
+ options[1],
298
+ ]);
299
+ const comboboxRef = useRef<HTMLInputElement>(null);
300
+ return (
301
+ <UNSAFE_Combobox
302
+ id={id}
303
+ label="Komboboks med begrenset antall valg"
304
+ options={options}
305
+ maxSelected={{ limit: 2 }}
306
+ selectedOptions={selectedOptions}
307
+ onToggleSelected={(option, isSelected) =>
308
+ isSelected
309
+ ? setSelectedOptions([...selectedOptions, option])
310
+ : setSelectedOptions(selectedOptions.filter((o) => o !== option))
311
+ }
312
+ isMultiSelect
313
+ allowNewValues
314
+ isListOpen={comboboxRef.current ? undefined : true}
315
+ value={value}
316
+ onChange={(event) => setValue(event?.target.value)}
317
+ ref={comboboxRef}
318
+ />
319
+ );
320
+ };
321
+
287
322
  export const WithError: StoryFunction = (props) => {
288
323
  const [hasSelectedValue, setHasSelectedValue] = useState(false);
289
324
  const [isLoading, setIsLoading] = useState(false);
@@ -74,9 +74,7 @@ describe("Render combobox", () => {
74
74
  it("Should show loading icon when loading (used for async search)", async () => {
75
75
  render(<App options={[]} isListOpen isLoading />);
76
76
 
77
- expect(
78
- await screen.findByRole("option", { name: "venter..." }),
79
- ).toBeInTheDocument();
77
+ expect(await screen.findByText("Søker...")).toBeInTheDocument();
80
78
  });
81
79
  });
82
80
 
@@ -1,6 +1,17 @@
1
1
  import React, { ChangeEvent, InputHTMLAttributes } from "react";
2
2
  import { FormFieldProps } from "../useFormField";
3
3
 
4
+ export type MaxSelected = {
5
+ /**
6
+ * The limit for maximum selected options
7
+ */
8
+ limit: number;
9
+ /**
10
+ * Override the message to display when the limit for maximum selected options has been reached
11
+ */
12
+ message?: string;
13
+ };
14
+
4
15
  export interface ComboboxProps
5
16
  extends FormFieldProps,
6
17
  Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "onChange" | "value"> {
@@ -97,6 +108,10 @@ export interface ComboboxProps
97
108
  * e.g. for a filter, where options can be toggled elsewhere/programmatically.
98
109
  */
99
110
  selectedOptions?: string[];
111
+ /**
112
+ * Options for the maximum number of selected options.
113
+ */
114
+ maxSelected?: MaxSelected;
100
115
  /**
101
116
  * Set to "true" to enable inline autocomplete.
102
117
  *