@navikt/ds-react 6.4.1 → 6.6.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 (349) hide show
  1. package/cjs/date/datepicker/parts/DayButton.js +1 -1
  2. package/cjs/date/datepicker/parts/DayButton.js.map +1 -1
  3. package/cjs/date/hooks/useDatepicker.js +4 -1
  4. package/cjs/date/hooks/useDatepicker.js.map +1 -1
  5. package/cjs/date/hooks/useMonthPicker.js +4 -1
  6. package/cjs/date/hooks/useMonthPicker.js.map +1 -1
  7. package/cjs/date/monthpicker/MonthButton.js +1 -1
  8. package/cjs/date/monthpicker/MonthButton.js.map +1 -1
  9. package/cjs/form/combobox/FilteredOptions/filteredOptionsContext.js +2 -4
  10. package/cjs/form/combobox/FilteredOptions/filteredOptionsContext.js.map +1 -1
  11. package/cjs/form/combobox/Input/Input.js +6 -1
  12. package/cjs/form/combobox/Input/Input.js.map +1 -1
  13. package/cjs/form/form-summary/FormSummary.d.ts +82 -0
  14. package/cjs/form/form-summary/FormSummary.js +81 -0
  15. package/cjs/form/form-summary/FormSummary.js.map +1 -0
  16. package/cjs/form/form-summary/FormSummaryAnswer.d.ts +11 -0
  17. package/cjs/form/form-summary/FormSummaryAnswer.js +25 -0
  18. package/cjs/form/form-summary/FormSummaryAnswer.js.map +1 -0
  19. package/cjs/form/form-summary/FormSummaryAnswers.d.ts +9 -0
  20. package/cjs/{toggle-group/ToggleItem.js → form/form-summary/FormSummaryAnswers.js} +6 -10
  21. package/cjs/form/form-summary/FormSummaryAnswers.js.map +1 -0
  22. package/cjs/form/form-summary/FormSummaryEditLink.d.ts +17 -0
  23. package/cjs/form/form-summary/FormSummaryEditLink.js +49 -0
  24. package/cjs/form/form-summary/FormSummaryEditLink.js.map +1 -0
  25. package/cjs/form/form-summary/FormSummaryHeader.d.ts +9 -0
  26. package/cjs/{tabs/TabPanel.js → form/form-summary/FormSummaryHeader.js} +6 -6
  27. package/cjs/form/form-summary/FormSummaryHeader.js.map +1 -0
  28. package/cjs/form/form-summary/FormSummaryHeading.d.ts +14 -0
  29. package/cjs/form/form-summary/FormSummaryHeading.js +31 -0
  30. package/cjs/form/form-summary/FormSummaryHeading.js.map +1 -0
  31. package/cjs/form/form-summary/FormSummaryLabel.d.ts +6 -0
  32. package/cjs/form/form-summary/FormSummaryLabel.js +45 -0
  33. package/cjs/form/form-summary/FormSummaryLabel.js.map +1 -0
  34. package/cjs/form/form-summary/FormSummaryValue.d.ts +6 -0
  35. package/cjs/form/form-summary/FormSummaryValue.js +49 -0
  36. package/cjs/form/form-summary/FormSummaryValue.js.map +1 -0
  37. package/cjs/form/form-summary/index.d.ts +8 -0
  38. package/cjs/form/form-summary/index.js +24 -0
  39. package/cjs/form/form-summary/index.js.map +1 -0
  40. package/cjs/index.d.ts +3 -2
  41. package/cjs/index.js +5 -3
  42. package/cjs/index.js.map +1 -1
  43. package/cjs/tabs/Tabs.context.d.ts +30 -0
  44. package/cjs/tabs/Tabs.context.js +14 -0
  45. package/cjs/tabs/Tabs.context.js.map +1 -0
  46. package/cjs/tabs/Tabs.d.ts +8 -43
  47. package/cjs/tabs/Tabs.js +19 -12
  48. package/cjs/tabs/Tabs.js.map +1 -1
  49. package/cjs/tabs/Tabs.types.d.ts +41 -0
  50. package/cjs/tabs/Tabs.types.js +3 -0
  51. package/cjs/tabs/Tabs.types.js.map +1 -0
  52. package/cjs/tabs/index.d.ts +5 -4
  53. package/cjs/tabs/index.js +6 -6
  54. package/cjs/tabs/index.js.map +1 -1
  55. package/cjs/tabs/parts/tab/Tab.d.ts +25 -0
  56. package/cjs/tabs/parts/tab/Tab.js +64 -0
  57. package/cjs/tabs/parts/tab/Tab.js.map +1 -0
  58. package/cjs/tabs/parts/tab/useTab.d.ts +20 -0
  59. package/cjs/tabs/parts/tab/useTab.js +29 -0
  60. package/cjs/tabs/parts/tab/useTab.js.map +1 -0
  61. package/cjs/tabs/parts/tablist/ScrollButtons.d.ts +8 -0
  62. package/cjs/tabs/parts/tablist/ScrollButtons.js +15 -0
  63. package/cjs/tabs/parts/tablist/ScrollButtons.js.map +1 -0
  64. package/{esm/tabs → cjs/tabs/parts/tablist}/TabList.d.ts +1 -1
  65. package/cjs/tabs/parts/tablist/TabList.js +61 -0
  66. package/cjs/tabs/parts/tablist/TabList.js.map +1 -0
  67. package/cjs/tabs/parts/tablist/useScrollButtons.d.ts +12 -0
  68. package/cjs/tabs/parts/tablist/useScrollButtons.js +61 -0
  69. package/cjs/tabs/parts/tablist/useScrollButtons.js.map +1 -0
  70. package/cjs/tabs/parts/tablist/useTabList.d.ts +7 -0
  71. package/cjs/tabs/parts/tablist/useTabList.js +66 -0
  72. package/cjs/tabs/parts/tablist/useTabList.js.map +1 -0
  73. package/cjs/tabs/parts/tabpanel/TabPanel.d.ts +25 -0
  74. package/cjs/tabs/{Tab.js → parts/tabpanel/TabPanel.js} +7 -20
  75. package/cjs/tabs/parts/tabpanel/TabPanel.js.map +1 -0
  76. package/cjs/tabs/parts/tabpanel/useTabPanel.d.ts +12 -0
  77. package/cjs/tabs/parts/tabpanel/useTabPanel.js +17 -0
  78. package/cjs/tabs/parts/tabpanel/useTabPanel.js.map +1 -0
  79. package/cjs/tabs/useTabs.d.ts +14 -0
  80. package/cjs/tabs/useTabs.js +43 -0
  81. package/cjs/tabs/useTabs.js.map +1 -0
  82. package/cjs/toggle-group/ToggleGroup.context.d.ts +31 -0
  83. package/cjs/toggle-group/ToggleGroup.context.js +16 -0
  84. package/cjs/toggle-group/ToggleGroup.context.js.map +1 -0
  85. package/cjs/toggle-group/ToggleGroup.d.ts +5 -36
  86. package/cjs/toggle-group/ToggleGroup.js +24 -24
  87. package/cjs/toggle-group/ToggleGroup.js.map +1 -1
  88. package/cjs/toggle-group/ToggleGroup.types.d.ts +38 -0
  89. package/cjs/toggle-group/ToggleGroup.types.js +3 -0
  90. package/cjs/toggle-group/ToggleGroup.types.js.map +1 -0
  91. package/cjs/toggle-group/index.d.ts +3 -2
  92. package/cjs/toggle-group/index.js +1 -1
  93. package/cjs/toggle-group/index.js.map +1 -1
  94. package/cjs/toggle-group/{ToggleItem.d.ts → parts/ToggleItem.d.ts} +2 -2
  95. package/cjs/toggle-group/parts/ToggleItem.js +53 -0
  96. package/cjs/toggle-group/parts/ToggleItem.js.map +1 -0
  97. package/cjs/toggle-group/parts/useToggleItem.d.ts +20 -0
  98. package/cjs/toggle-group/parts/useToggleItem.js +76 -0
  99. package/cjs/toggle-group/parts/useToggleItem.js.map +1 -0
  100. package/cjs/toggle-group/useToggleGroup.d.ts +8 -0
  101. package/cjs/toggle-group/useToggleGroup.js +29 -0
  102. package/cjs/toggle-group/useToggleGroup.js.map +1 -0
  103. package/cjs/util/hooks/descendants/descendant.js +10 -1
  104. package/cjs/util/hooks/descendants/descendant.js.map +1 -1
  105. package/cjs/util/hooks/descendants/useDescendant.js +0 -5
  106. package/cjs/util/hooks/descendants/useDescendant.js.map +1 -1
  107. package/esm/date/datepicker/parts/DayButton.js +1 -1
  108. package/esm/date/datepicker/parts/DayButton.js.map +1 -1
  109. package/esm/date/hooks/useDatepicker.js +4 -1
  110. package/esm/date/hooks/useDatepicker.js.map +1 -1
  111. package/esm/date/hooks/useMonthPicker.js +4 -1
  112. package/esm/date/hooks/useMonthPicker.js.map +1 -1
  113. package/esm/date/monthpicker/MonthButton.js +1 -1
  114. package/esm/date/monthpicker/MonthButton.js.map +1 -1
  115. package/esm/form/combobox/FilteredOptions/filteredOptionsContext.js +2 -4
  116. package/esm/form/combobox/FilteredOptions/filteredOptionsContext.js.map +1 -1
  117. package/esm/form/combobox/Input/Input.js +6 -1
  118. package/esm/form/combobox/Input/Input.js.map +1 -1
  119. package/esm/form/form-summary/FormSummary.d.ts +82 -0
  120. package/esm/form/form-summary/FormSummary.js +52 -0
  121. package/esm/form/form-summary/FormSummary.js.map +1 -0
  122. package/esm/form/form-summary/FormSummaryAnswer.d.ts +11 -0
  123. package/esm/form/form-summary/FormSummaryAnswer.js +19 -0
  124. package/esm/form/form-summary/FormSummaryAnswer.js.map +1 -0
  125. package/esm/form/form-summary/FormSummaryAnswers.d.ts +9 -0
  126. package/esm/{tabs/TabPanel.js → form/form-summary/FormSummaryAnswers.js} +5 -6
  127. package/esm/form/form-summary/FormSummaryAnswers.js.map +1 -0
  128. package/esm/form/form-summary/FormSummaryEditLink.d.ts +17 -0
  129. package/esm/form/form-summary/FormSummaryEditLink.js +20 -0
  130. package/esm/form/form-summary/FormSummaryEditLink.js.map +1 -0
  131. package/esm/form/form-summary/FormSummaryHeader.d.ts +9 -0
  132. package/esm/form/form-summary/FormSummaryHeader.js +19 -0
  133. package/esm/form/form-summary/FormSummaryHeader.js.map +1 -0
  134. package/esm/form/form-summary/FormSummaryHeading.d.ts +14 -0
  135. package/esm/form/form-summary/FormSummaryHeading.js +5 -0
  136. package/esm/form/form-summary/FormSummaryHeading.js.map +1 -0
  137. package/esm/form/form-summary/FormSummaryLabel.d.ts +6 -0
  138. package/esm/form/form-summary/FormSummaryLabel.js +19 -0
  139. package/esm/form/form-summary/FormSummaryLabel.js.map +1 -0
  140. package/esm/form/form-summary/FormSummaryValue.d.ts +6 -0
  141. package/esm/form/form-summary/FormSummaryValue.js +20 -0
  142. package/esm/form/form-summary/FormSummaryValue.js.map +1 -0
  143. package/esm/form/form-summary/index.d.ts +8 -0
  144. package/esm/form/form-summary/index.js +10 -0
  145. package/esm/form/form-summary/index.js.map +1 -0
  146. package/esm/index.d.ts +3 -2
  147. package/esm/index.js +2 -1
  148. package/esm/index.js.map +1 -1
  149. package/esm/tabs/Tabs.context.d.ts +30 -0
  150. package/esm/tabs/Tabs.context.js +10 -0
  151. package/esm/tabs/Tabs.context.js.map +1 -0
  152. package/esm/tabs/Tabs.d.ts +8 -43
  153. package/esm/tabs/Tabs.js +19 -12
  154. package/esm/tabs/Tabs.js.map +1 -1
  155. package/esm/tabs/Tabs.types.d.ts +41 -0
  156. package/esm/tabs/Tabs.types.js +2 -0
  157. package/esm/tabs/Tabs.types.js.map +1 -0
  158. package/esm/tabs/index.d.ts +5 -4
  159. package/esm/tabs/index.js +3 -3
  160. package/esm/tabs/index.js.map +1 -1
  161. package/esm/tabs/parts/tab/Tab.d.ts +25 -0
  162. package/esm/tabs/parts/tab/Tab.js +35 -0
  163. package/esm/tabs/parts/tab/Tab.js.map +1 -0
  164. package/esm/tabs/parts/tab/useTab.d.ts +20 -0
  165. package/esm/tabs/parts/tab/useTab.js +25 -0
  166. package/esm/tabs/parts/tab/useTab.js.map +1 -0
  167. package/esm/tabs/parts/tablist/ScrollButtons.d.ts +8 -0
  168. package/esm/tabs/parts/tablist/ScrollButtons.js +10 -0
  169. package/esm/tabs/parts/tablist/ScrollButtons.js.map +1 -0
  170. package/{cjs/tabs → esm/tabs/parts/tablist}/TabList.d.ts +1 -1
  171. package/esm/tabs/parts/tablist/TabList.js +32 -0
  172. package/esm/tabs/parts/tablist/TabList.js.map +1 -0
  173. package/esm/tabs/parts/tablist/useScrollButtons.d.ts +12 -0
  174. package/esm/tabs/parts/tablist/useScrollButtons.js +57 -0
  175. package/esm/tabs/parts/tablist/useScrollButtons.js.map +1 -0
  176. package/esm/tabs/parts/tablist/useTabList.d.ts +7 -0
  177. package/esm/tabs/parts/tablist/useTabList.js +62 -0
  178. package/esm/tabs/parts/tablist/useTabList.js.map +1 -0
  179. package/esm/tabs/parts/tabpanel/TabPanel.d.ts +25 -0
  180. package/esm/tabs/parts/tabpanel/TabPanel.js +22 -0
  181. package/esm/tabs/parts/tabpanel/TabPanel.js.map +1 -0
  182. package/esm/tabs/parts/tabpanel/useTabPanel.d.ts +12 -0
  183. package/esm/tabs/parts/tabpanel/useTabPanel.js +13 -0
  184. package/esm/tabs/parts/tabpanel/useTabPanel.js.map +1 -0
  185. package/esm/tabs/useTabs.d.ts +14 -0
  186. package/esm/tabs/useTabs.js +39 -0
  187. package/esm/tabs/useTabs.js.map +1 -0
  188. package/esm/toggle-group/ToggleGroup.context.d.ts +31 -0
  189. package/esm/toggle-group/ToggleGroup.context.js +12 -0
  190. package/esm/toggle-group/ToggleGroup.context.js.map +1 -0
  191. package/esm/toggle-group/ToggleGroup.d.ts +5 -36
  192. package/esm/toggle-group/ToggleGroup.js +24 -24
  193. package/esm/toggle-group/ToggleGroup.js.map +1 -1
  194. package/esm/toggle-group/ToggleGroup.types.d.ts +38 -0
  195. package/esm/toggle-group/ToggleGroup.types.js +2 -0
  196. package/esm/toggle-group/ToggleGroup.types.js.map +1 -0
  197. package/esm/toggle-group/index.d.ts +3 -2
  198. package/esm/toggle-group/index.js +1 -1
  199. package/esm/toggle-group/index.js.map +1 -1
  200. package/esm/toggle-group/{ToggleItem.d.ts → parts/ToggleItem.d.ts} +2 -2
  201. package/esm/toggle-group/parts/ToggleItem.js +25 -0
  202. package/esm/toggle-group/parts/ToggleItem.js.map +1 -0
  203. package/esm/toggle-group/parts/useToggleItem.d.ts +20 -0
  204. package/esm/toggle-group/parts/useToggleItem.js +72 -0
  205. package/esm/toggle-group/parts/useToggleItem.js.map +1 -0
  206. package/esm/toggle-group/useToggleGroup.d.ts +8 -0
  207. package/esm/toggle-group/useToggleGroup.js +25 -0
  208. package/esm/toggle-group/useToggleGroup.js.map +1 -0
  209. package/esm/util/hooks/descendants/descendant.js +10 -1
  210. package/esm/util/hooks/descendants/descendant.js.map +1 -1
  211. package/esm/util/hooks/descendants/useDescendant.js +0 -5
  212. package/esm/util/hooks/descendants/useDescendant.js.map +1 -1
  213. package/package.json +15 -6
  214. package/src/date/datepicker/parts/DayButton.tsx +2 -0
  215. package/src/date/hooks/useDatepicker.tsx +5 -1
  216. package/src/date/hooks/useMonthPicker.tsx +5 -1
  217. package/src/date/monthpicker/MonthButton.tsx +1 -0
  218. package/src/form/combobox/FilteredOptions/filteredOptionsContext.tsx +9 -1
  219. package/src/form/combobox/Input/Input.tsx +5 -0
  220. package/src/form/form-summary/FormSummary.tsx +106 -0
  221. package/src/form/form-summary/FormSummaryAnswer.tsx +27 -0
  222. package/src/form/form-summary/FormSummaryAnswers.tsx +25 -0
  223. package/src/form/form-summary/FormSummaryEditLink.tsx +35 -0
  224. package/src/form/form-summary/FormSummaryHeader.tsx +25 -0
  225. package/src/form/form-summary/FormSummaryHeading.tsx +23 -0
  226. package/src/form/form-summary/FormSummaryLabel.tsx +17 -0
  227. package/src/form/form-summary/FormSummaryValue.tsx +24 -0
  228. package/src/form/form-summary/index.ts +30 -0
  229. package/src/index.ts +16 -15
  230. package/src/tabs/Tabs.context.ts +24 -0
  231. package/src/tabs/Tabs.test.tsx +99 -37
  232. package/src/tabs/Tabs.tsx +48 -70
  233. package/src/tabs/Tabs.types.ts +43 -0
  234. package/src/tabs/index.ts +11 -4
  235. package/src/tabs/parts/tab/Tab.tsx +93 -0
  236. package/src/tabs/parts/tab/useTab.ts +52 -0
  237. package/src/tabs/parts/tablist/ScrollButtons.tsx +29 -0
  238. package/src/tabs/parts/tablist/TabList.tsx +56 -0
  239. package/src/tabs/parts/tablist/useScrollButtons.ts +69 -0
  240. package/src/tabs/parts/tablist/useTabList.ts +68 -0
  241. package/src/tabs/parts/tabpanel/TabPanel.tsx +50 -0
  242. package/src/tabs/parts/tabpanel/useTabPanel.ts +18 -0
  243. package/src/tabs/useTabs.ts +51 -0
  244. package/src/toggle-group/ToggleGroup.context.ts +31 -0
  245. package/src/toggle-group/ToggleGroup.test.tsx +57 -16
  246. package/src/toggle-group/ToggleGroup.tsx +63 -90
  247. package/src/toggle-group/ToggleGroup.types.ts +40 -0
  248. package/src/toggle-group/index.ts +3 -2
  249. package/src/toggle-group/parts/ToggleItem.tsx +55 -0
  250. package/src/toggle-group/parts/useToggleItem.ts +104 -0
  251. package/src/toggle-group/useToggleGroup.ts +33 -0
  252. package/src/util/hooks/descendants/descendant.ts +15 -1
  253. package/src/util/hooks/descendants/useDescendant.tsx +0 -5
  254. package/cjs/tabs/Tab.d.ts +0 -18
  255. package/cjs/tabs/Tab.js.map +0 -1
  256. package/cjs/tabs/TabList.js +0 -111
  257. package/cjs/tabs/TabList.js.map +0 -1
  258. package/cjs/tabs/TabPanel.d.ts +0 -13
  259. package/cjs/tabs/TabPanel.js.map +0 -1
  260. package/cjs/tabs/context.d.ts +0 -8
  261. package/cjs/tabs/context.js +0 -6
  262. package/cjs/tabs/context.js.map +0 -1
  263. package/cjs/toggle-group/ToggleItem.js.map +0 -1
  264. package/cjs/toggle-group/context.d.ts +0 -6
  265. package/cjs/toggle-group/context.js +0 -6
  266. package/cjs/toggle-group/context.js.map +0 -1
  267. package/esm/tabs/Tab.d.ts +0 -18
  268. package/esm/tabs/Tab.js +0 -34
  269. package/esm/tabs/Tab.js.map +0 -1
  270. package/esm/tabs/TabList.js +0 -82
  271. package/esm/tabs/TabList.js.map +0 -1
  272. package/esm/tabs/TabPanel.d.ts +0 -13
  273. package/esm/tabs/TabPanel.js.map +0 -1
  274. package/esm/tabs/context.d.ts +0 -8
  275. package/esm/tabs/context.js +0 -3
  276. package/esm/tabs/context.js.map +0 -1
  277. package/esm/toggle-group/ToggleItem.js +0 -24
  278. package/esm/toggle-group/ToggleItem.js.map +0 -1
  279. package/esm/toggle-group/context.d.ts +0 -6
  280. package/esm/toggle-group/context.js +0 -3
  281. package/esm/toggle-group/context.js.map +0 -1
  282. package/src/accordion/accordion.stories.tsx +0 -286
  283. package/src/alert/alert.stories.tsx +0 -306
  284. package/src/button/button.stories.tsx +0 -185
  285. package/src/chat/chat.stories.tsx +0 -341
  286. package/src/chips/chips.stories.tsx +0 -260
  287. package/src/copybutton/copy-button.stories.tsx +0 -261
  288. package/src/date/datepicker/datepicker.stories.tsx +0 -575
  289. package/src/date/monthpicker/monthpicker.stories.tsx +0 -204
  290. package/src/dropdown/dropdown.stories.tsx +0 -124
  291. package/src/expansion-card/expansion-card.stories.tsx +0 -282
  292. package/src/form/checkbox/checkbox.stories.tsx +0 -281
  293. package/src/form/combobox/combobox.stories.tsx +0 -626
  294. package/src/form/confirmation-panel/confirmation-panel.stories.tsx +0 -128
  295. package/src/form/error-summary/error-summary.stories.tsx +0 -81
  296. package/src/form/fieldset/fieldset.stories.tsx +0 -157
  297. package/src/form/file-upload/file-upload-dropzone.stories.tsx +0 -123
  298. package/src/form/file-upload/file-upload-item.stories.tsx +0 -148
  299. package/src/form/file-upload/file-upload.stories.tsx +0 -248
  300. package/src/form/radio/radio.stories.tsx +0 -230
  301. package/src/form/search/search.stories.tsx +0 -238
  302. package/src/form/select/select.stories.tsx +0 -172
  303. package/src/form/switch/switch.stories.tsx +0 -171
  304. package/src/form/textarea/textarea.stories.tsx +0 -254
  305. package/src/form/textfield/text-field.stories.tsx +0 -143
  306. package/src/guide-panel/guidepanel.stories.tsx +0 -90
  307. package/src/help-text/help-text.stories.tsx +0 -91
  308. package/src/internal-header/header.stories.tsx +0 -229
  309. package/src/layout/bleed/Bleed.stories.tsx +0 -395
  310. package/src/layout/box/Box.stories.tsx +0 -380
  311. package/src/layout/grid/h-grid.stories.tsx +0 -122
  312. package/src/layout/page/Page.stories.tsx +0 -271
  313. package/src/layout/responsive/hide.stories.tsx +0 -80
  314. package/src/layout/responsive/show.stories.tsx +0 -80
  315. package/src/layout/sidemal-test/navno-sidemal.stories.tsx +0 -69
  316. package/src/layout/stack/stack.stories.tsx +0 -183
  317. package/src/link/stories/link.stories.tsx +0 -304
  318. package/src/link-panel/link-panel.stories.tsx +0 -59
  319. package/src/list/list.stories.tsx +0 -280
  320. package/src/loader/loader.stories.tsx +0 -82
  321. package/src/modal/modal.stories.tsx +0 -395
  322. package/src/pagination/pagination.stories.tsx +0 -110
  323. package/src/popover/popover.stories.tsx +0 -113
  324. package/src/portal/Portal.stories.tsx +0 -102
  325. package/src/read-more/readmore.stories.tsx +0 -91
  326. package/src/skeleton/skeleton.stories.tsx +0 -130
  327. package/src/stepper/stepper.stories.tsx +0 -200
  328. package/src/table/stories/table-1.stories.tsx +0 -292
  329. package/src/table/stories/table-2-expandable.stories.tsx +0 -298
  330. package/src/table/stories/table-3-async.stories.tsx +0 -179
  331. package/src/table/stories/tests/table.stories.tsx +0 -102
  332. package/src/tabs/Tab.tsx +0 -66
  333. package/src/tabs/TabList.tsx +0 -128
  334. package/src/tabs/TabPanel.tsx +0 -26
  335. package/src/tabs/Tabs.stories.tsx +0 -191
  336. package/src/tabs/context.ts +0 -9
  337. package/src/tag/tag.stories.tsx +0 -126
  338. package/src/timeline/timeline.stories.tsx +0 -445
  339. package/src/toggle-group/ToggleGroup.stories.tsx +0 -137
  340. package/src/toggle-group/ToggleItem.tsx +0 -41
  341. package/src/toggle-group/context.ts +0 -9
  342. package/src/tooltip/tooltip.stories.tsx +0 -101
  343. package/src/typography/stories/bodylong.stories.tsx +0 -209
  344. package/src/typography/stories/bodyshort.stories.tsx +0 -208
  345. package/src/typography/stories/detail.stories.tsx +0 -115
  346. package/src/typography/stories/error-message.stories.tsx +0 -122
  347. package/src/typography/stories/heading.stories.tsx +0 -169
  348. package/src/typography/stories/label.stories.tsx +0 -131
  349. package/src/util/hooks/descendants/descendant.stories.tsx +0 -147
@@ -1,4 +1,5 @@
1
- import { fireEvent, render, screen } from "@testing-library/react";
1
+ import { act, fireEvent, render, screen } from "@testing-library/react";
2
+ import userEvent from "@testing-library/user-event";
2
3
  import React from "react";
3
4
  import { describe, expect, test } from "vitest";
4
5
  import { Tabs } from "./Tabs";
@@ -39,72 +40,133 @@ const TestTabs = ({
39
40
  describe("Tabs", () => {
40
41
  test("sets default value correctly", () => {
41
42
  render(<TestTabs defaultValue="tab2" />);
42
- const tab = screen.getByTestId("tab2");
43
- const panel = screen.getByTestId("tabpanel2");
43
+ const tab2 = screen.getByTestId("tab2");
44
+ const panel2 = screen.getByTestId("tabpanel2");
44
45
 
45
- expect(tab).toHaveAttribute("aria-selected", "true");
46
- expect(panel).toHaveTextContent("Tabpanel 2");
46
+ expect(tab2).toHaveAttribute("aria-selected", "true");
47
+ expect(panel2).toHaveTextContent("Tabpanel 2");
47
48
  });
48
49
 
49
50
  test("label-connection between tab and tabpanel is correct", async () => {
50
51
  render(<TestTabs defaultValue="tab2" />);
51
- const tab = screen.getByTestId("tab2");
52
- const panel = screen.getByTestId("tabpanel2");
52
+ const tab2 = screen.getByTestId("tab2");
53
+ const panel2 = screen.getByTestId("tabpanel2");
53
54
 
54
- const controlsId = tab.getAttribute("aria-controls");
55
- const panelLabelledBy = panel.getAttribute("aria-labelledby");
55
+ const controlsId = tab2.getAttribute("aria-controls");
56
+ const panelLabelledBy = panel2.getAttribute("aria-labelledby");
56
57
 
57
- expect(controlsId).toEqual(panel.id);
58
- expect(tab.id).toEqual(panelLabelledBy);
58
+ expect(controlsId).toEqual(panel2.id);
59
+ expect(tab2.id).toEqual(panelLabelledBy);
59
60
  });
60
61
 
61
62
  test("sets correct attributes on active tab", () => {
62
63
  render(<TestTabs defaultValue="tab2" />);
63
- const tab = screen.getByTestId("tab2");
64
+ const tab2 = screen.getByTestId("tab2");
64
65
 
65
- expect(tab).toHaveAttribute("aria-selected", "true");
66
- expect(tab).toHaveAttribute("role", "tab");
67
- expect(tab).toHaveAttribute("aria-controls");
68
- expect(tab).toHaveAttribute("tabindex", "-1");
66
+ expect(tab2).toHaveAttribute("aria-selected", "true");
67
+ expect(tab2).toHaveAttribute("role", "tab");
68
+ expect(tab2).toHaveAttribute("aria-controls");
69
+ expect(tab2).toHaveAttribute("tabindex", "0");
69
70
  });
70
71
 
71
72
  test("sets correct attributes on idle tab", () => {
72
73
  render(<TestTabs defaultValue="tab2" />);
73
- const tab = screen.getByTestId("tab1");
74
+ const tab1 = screen.getByTestId("tab1");
74
75
 
75
- expect(tab).toHaveAttribute("aria-selected", "false");
76
- expect(tab).toHaveAttribute("role", "tab");
77
- expect(tab).toHaveAttribute("aria-controls");
78
- expect(tab).toHaveAttribute("tabindex", "-1");
76
+ expect(tab1).toHaveAttribute("aria-selected", "false");
77
+ expect(tab1).toHaveAttribute("role", "tab");
78
+ expect(tab1).toHaveAttribute("aria-controls");
79
+ expect(tab1).toHaveAttribute("tabindex", "-1");
79
80
  });
80
81
 
81
82
  test("sets correct attributes on active tabpanel", () => {
82
83
  render(<TestTabs defaultValue="tab2" />);
83
- const panel = screen.getByTestId("tabpanel2");
84
+ const panel2 = screen.getByTestId("tabpanel2");
84
85
 
85
- expect(panel).toHaveAttribute("aria-labelledby");
86
- expect(panel).toHaveAttribute("role", "tabpanel");
87
- expect(panel).toHaveAttribute("tabindex", "0");
88
- expect(panel).toHaveTextContent("Tabpanel 2");
89
- expect(panel).toHaveStyle({ display: "block" });
86
+ expect(panel2).toHaveAttribute("aria-labelledby");
87
+ expect(panel2).toHaveAttribute("role", "tabpanel");
88
+ expect(panel2).toHaveAttribute("tabindex", "0");
89
+ expect(panel2).toHaveTextContent("Tabpanel 2");
90
+ expect(panel2).toHaveStyle({ display: "block" });
90
91
  });
91
92
 
92
93
  test("sets correct attributes on idle tabpanel", () => {
93
94
  render(<TestTabs defaultValue="tab1" />);
94
- const panel = screen.getByTestId("tabpanel2");
95
+ const panel2 = screen.getByTestId("tabpanel2");
95
96
 
96
- expect(panel).toHaveAttribute("aria-labelledby");
97
- expect(panel).toHaveAttribute("role", "tabpanel");
98
- expect(panel).toHaveAttribute("tabindex", "0");
99
- expect(panel).toBeEmptyDOMElement();
100
- expect(panel).toHaveStyle({ display: "none" });
97
+ expect(panel2).toHaveAttribute("aria-labelledby");
98
+ expect(panel2).toHaveAttribute("role", "tabpanel");
99
+ expect(panel2).toHaveAttribute("tabindex", "0");
100
+ expect(panel2).toBeEmptyDOMElement();
101
+ expect(panel2).toHaveStyle({ display: "none" });
101
102
  });
102
103
 
103
104
  test("sets tabindex to 0 when focused", () => {
104
- render(<TestTabs defaultValue="tab2" />);
105
- const tab = screen.getByTestId("tab2");
105
+ render(<TestTabs defaultValue="tab1" />);
106
+ const tab2 = screen.getByTestId("tab2");
107
+
108
+ fireEvent.focus(tab2);
109
+ expect(tab2).toHaveAttribute("tabindex", "0");
110
+ });
111
+
112
+ test("rowing tabindex keydown moves focus", () => {
113
+ render(<TestTabs defaultValue="tab1" />);
114
+ const tab1 = screen.getByTestId("tab1");
115
+
116
+ expect(tab1).toHaveAttribute("tabindex", "0");
117
+ fireEvent.keyDown(tab1, { key: "ArrowRight" });
118
+
119
+ expect(tab1).toHaveAttribute("tabindex", "-1");
120
+ expect(screen.getByTestId("tab2")).toHaveAttribute("tabindex", "0");
121
+ expect(screen.getByTestId("tab2")).toHaveAttribute(
122
+ "aria-selected",
123
+ "false",
124
+ );
125
+ });
126
+
127
+ test("selectionFollowsFocus moves active tabs", () => {
128
+ render(<TestTabs defaultValue="tab1" selectionFollowsFocus />);
129
+ const tab1 = screen.getByTestId("tab1");
106
130
 
107
- fireEvent.focus(tab);
108
- expect(tab).toHaveAttribute("tabindex", "0");
131
+ expect(tab1).toHaveAttribute("tabindex", "0");
132
+ fireEvent.keyDown(tab1, { key: "ArrowRight" });
133
+
134
+ expect(screen.getByTestId("tab2")).toHaveAttribute("aria-selected", "true");
135
+ expect(screen.getByTestId("tab2")).toHaveAttribute("tabindex", "0");
136
+ });
137
+
138
+ test("tabbing from tabs moves focus to tabPanel", async () => {
139
+ render(<TestTabs defaultValue="tab1" />);
140
+ const tab1 = screen.getByTestId("tab1");
141
+
142
+ tab1.focus();
143
+ await userEvent.tab();
144
+
145
+ expect(screen.getByTestId("tabpanel1")).toHaveFocus();
146
+ });
147
+
148
+ test("shift+tab back to tablist should focus selected tab", async () => {
149
+ render(<TestTabs defaultValue="tab1" />);
150
+ const tab1 = screen.getByTestId("tab1");
151
+
152
+ /* Move focus to tab2 */
153
+ fireEvent.keyDown(tab1, { key: "ArrowRight" });
154
+ expect(screen.getByTestId("tab2")).toHaveFocus();
155
+
156
+ /* Move focus to tabPanel */
157
+ // eslint-disable-next-line testing-library/no-unnecessary-act
158
+ await act(async () => {
159
+ /* Tablist handles tabbing with setTimeout, so we need to use act */
160
+ await userEvent.tab();
161
+ });
162
+
163
+ expect(screen.getByTestId("tabpanel1")).toHaveFocus();
164
+ /* Move focus back to tablist, now tab1 should have focus */
165
+
166
+ // eslint-disable-next-line testing-library/no-unnecessary-act
167
+ await act(async () => {
168
+ await userEvent.tab({ shift: true });
169
+ });
170
+ expect(screen.getByTestId("tab1")).toHaveFocus();
109
171
  });
110
172
  });
package/src/tabs/Tabs.tsx CHANGED
@@ -1,48 +1,15 @@
1
- import * as RadixTabs from "@radix-ui/react-tabs";
2
1
  import cl from "clsx";
3
- import React, { HTMLAttributes, forwardRef } from "react";
4
- import { OverridableComponent } from "../util/types";
5
- import Tab, { TabProps } from "./Tab";
6
- import TabList, { TabListProps } from "./TabList";
7
- import TabPanel, { TabPanelProps } from "./TabPanel";
8
- import { TabsContext } from "./context";
9
-
10
- export interface TabsProps
11
- extends Omit<HTMLAttributes<HTMLDivElement>, "onChange" | "dir"> {
12
- children: React.ReactNode;
13
- /**
14
- * Changes padding and font-size.
15
- * @default "medium"
16
- */
17
- size?: "medium" | "small";
18
- /**
19
- * onChange callback for selected Tab.
20
- */
21
- onChange?: (value: string) => void;
22
- /**
23
- * Controlled selected value.
24
- */
25
- value?: string;
26
- /**
27
- * If not controlled, a default-value needs to be set.
28
- */
29
- defaultValue?: string;
30
- /**
31
- * Automatically activates tab on focus/navigation.
32
- * @default false
33
- */
34
- selectionFollowsFocus?: boolean;
35
- /**
36
- * Loops back to start when navigating past last item.
37
- * @default false
38
- */
39
- loop?: boolean;
40
- /**
41
- * Icon position in Tab.
42
- * @default "left"
43
- */
44
- iconPosition?: "left" | "top";
45
- }
2
+ import React, { forwardRef } from "react";
3
+ import {
4
+ TabsDescendantsProvider,
5
+ TabsProvider,
6
+ useTabsDescendants,
7
+ } from "./Tabs.context";
8
+ import { TabsProps } from "./Tabs.types";
9
+ import Tab from "./parts/tab/Tab";
10
+ import TabList from "./parts/tablist/TabList";
11
+ import TabPanel from "./parts/tabpanel/TabPanel";
12
+ import { useTabs } from "./useTabs";
46
13
 
47
14
  interface TabsComponent
48
15
  extends React.ForwardRefExoticComponent<
@@ -52,19 +19,15 @@ interface TabsComponent
52
19
  * @see 🏷️ {@link TabProps}
53
20
  * @see [🤖 OverridableComponent](https://aksel.nav.no/grunnleggende/kode/overridablecomponent) support
54
21
  */
55
- Tab: OverridableComponent<TabProps, HTMLButtonElement>;
22
+ Tab: typeof Tab;
56
23
  /**
57
24
  * @see 🏷️ {@link TabListProps}
58
25
  */
59
- List: React.ForwardRefExoticComponent<
60
- TabListProps & React.RefAttributes<HTMLDivElement>
61
- >;
26
+ List: typeof TabList;
62
27
  /**
63
28
  * @see 🏷️ {@link TabPanelProps}
64
29
  */
65
- Panel: React.ForwardRefExoticComponent<
66
- TabPanelProps & React.RefAttributes<HTMLDivElement>
67
- >;
30
+ Panel: typeof TabPanel;
68
31
  }
69
32
 
70
33
  /**
@@ -98,33 +61,48 @@ export const Tabs = forwardRef<HTMLDivElement, TabsProps>(
98
61
  {
99
62
  className,
100
63
  children,
101
- onChange,
102
64
  size = "medium",
65
+ defaultValue = "",
66
+ value,
67
+ onChange,
68
+ id,
103
69
  selectionFollowsFocus = false,
104
- loop = false,
70
+ loop = true,
105
71
  iconPosition = "left",
72
+ fill = false,
106
73
  ...rest
107
74
  },
108
75
  ref,
109
76
  ) => {
77
+ const descendants = useTabsDescendants();
78
+
79
+ const tabsContext = useTabs({ defaultValue, value, onChange, id });
80
+
81
+ /**
82
+ * TabsProvider handles memoization of context values, so we can safely skip it here.
83
+ */
84
+ const context = {
85
+ ...tabsContext,
86
+ selectionFollowsFocus,
87
+ loop,
88
+ size,
89
+ iconPosition,
90
+ fill,
91
+ };
92
+
110
93
  return (
111
- <RadixTabs.Root
112
- {...rest}
113
- ref={ref}
114
- className={cl("navds-tabs", className, `navds-tabs--${size}`)}
115
- activationMode={selectionFollowsFocus ? "automatic" : "manual"}
116
- onValueChange={onChange}
117
- >
118
- <TabsContext.Provider
119
- value={{
120
- size,
121
- loop,
122
- iconPosition,
123
- }}
124
- >
125
- {children}
126
- </TabsContext.Provider>
127
- </RadixTabs.Root>
94
+ <TabsDescendantsProvider value={descendants}>
95
+ <TabsProvider {...context}>
96
+ <div
97
+ ref={ref}
98
+ {...rest}
99
+ id={id}
100
+ className={cl("navds-tabs", className, `navds-tabs--${size}`)}
101
+ >
102
+ {children}
103
+ </div>
104
+ </TabsProvider>
105
+ </TabsDescendantsProvider>
128
106
  );
129
107
  },
130
108
  ) as TabsComponent;
@@ -0,0 +1,43 @@
1
+ import { HTMLAttributes } from "react";
2
+
3
+ export interface TabsProps
4
+ extends Omit<HTMLAttributes<HTMLDivElement>, "onChange" | "dir"> {
5
+ children: React.ReactNode;
6
+ /**
7
+ * Changes padding and font-size.
8
+ * @default "medium"
9
+ */
10
+ size?: "medium" | "small";
11
+ /**
12
+ * onChange callback for selected Tab.
13
+ */
14
+ onChange?: (value: string) => void;
15
+ /**
16
+ * Controlled selected value.
17
+ */
18
+ value?: string;
19
+ /**
20
+ * If not controlled, a default-value needs to be set.
21
+ */
22
+ defaultValue?: string;
23
+ /**
24
+ * Automatically activates tab on focus/navigation.
25
+ * @default false
26
+ */
27
+ selectionFollowsFocus?: boolean;
28
+ /**
29
+ * Loops back to start when navigating past last item.
30
+ * @default true
31
+ */
32
+ loop?: boolean;
33
+ /**
34
+ * Icon position in Tab.
35
+ * @default "left"
36
+ */
37
+ iconPosition?: "left" | "top";
38
+ /**
39
+ * Stretches each tab to fill avaliable space in container.
40
+ * @default false
41
+ */
42
+ fill?: boolean;
43
+ }
package/src/tabs/index.ts CHANGED
@@ -1,5 +1,12 @@
1
1
  "use client";
2
- export { default as TabsTab, type TabProps } from "./Tab";
3
- export { default as TabsList, type TabListProps } from "./TabList";
4
- export { default as TabsPanel, type TabPanelProps } from "./TabPanel";
5
- export { default as Tabs, type TabsProps } from "./Tabs";
2
+ export { default as Tabs } from "./Tabs";
3
+ export { type TabsProps } from "./Tabs.types";
4
+ export { default as TabsTab, type TabProps } from "./parts/tab/Tab";
5
+ export {
6
+ default as TabsList,
7
+ type TabListProps,
8
+ } from "./parts/tablist/TabList";
9
+ export {
10
+ default as TabsPanel,
11
+ type TabPanelProps,
12
+ } from "./parts/tabpanel/TabPanel";
@@ -0,0 +1,93 @@
1
+ import cl from "clsx";
2
+ import React, { forwardRef } from "react";
3
+ import { BodyShort } from "../../../typography";
4
+ import { OverridableComponent } from "../../../util";
5
+ import { useTabsContext } from "../../Tabs.context";
6
+ import { useTab } from "./useTab";
7
+
8
+ export interface TabProps
9
+ extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "children"> {
10
+ /**
11
+ * Tab label.
12
+ */
13
+ label?: React.ReactNode;
14
+ /**
15
+ * Tab Icon.
16
+ */
17
+ icon?: React.ReactNode;
18
+ /**
19
+ * Value for state-handling.
20
+ */
21
+ value: string;
22
+ /**
23
+ * Overrides auto-generated id.
24
+ *
25
+ * **Warning**: Tab generates an id if not provided. If you need to override it,
26
+ * make sure to also include the correct `aria-controls` id for the TabPanel it controls.
27
+ */
28
+ id?: string;
29
+ }
30
+
31
+ export const Tab: OverridableComponent<TabProps, HTMLButtonElement> =
32
+ forwardRef(
33
+ (
34
+ {
35
+ className,
36
+ as: Component = "button",
37
+ label,
38
+ icon,
39
+ value,
40
+ onClick,
41
+ onFocus,
42
+ disabled,
43
+ id,
44
+ ...rest
45
+ },
46
+ ref: React.ForwardedRef<HTMLButtonElement>,
47
+ ) => {
48
+ const tabCtx = useTab({ value, onClick, onFocus, disabled }, ref);
49
+ const ctx = useTabsContext();
50
+
51
+ if (!label && !icon) {
52
+ console.error("<Tabs.Tab/> needs label and/or icon");
53
+ return null;
54
+ }
55
+
56
+ return (
57
+ <Component
58
+ ref={tabCtx.ref}
59
+ {...rest}
60
+ className={cl(
61
+ "navds-tabs__tab",
62
+ `navds-tabs__tab--${ctx?.size ?? "medium"}`,
63
+ `navds-tabs__tab-icon--${ctx?.iconPosition}`,
64
+ className,
65
+ {
66
+ "navds-tabs__tab--icon-only": icon && !label,
67
+ "navds-tabs__tab--fill": ctx.fill,
68
+ },
69
+ )}
70
+ role="tab"
71
+ type="button"
72
+ aria-selected={tabCtx.isSelected}
73
+ data-state={tabCtx.isSelected ? "active" : "inactive"}
74
+ tabIndex={tabCtx.isFocused ? 0 : -1}
75
+ aria-controls={rest["aria-controls"] ?? tabCtx.controlsId}
76
+ id={id ?? tabCtx.id}
77
+ onFocus={tabCtx.onFocus}
78
+ onClick={tabCtx.onClick}
79
+ >
80
+ <BodyShort
81
+ as="span"
82
+ className="navds-tabs__tab-inner"
83
+ size={ctx?.size}
84
+ >
85
+ <span aria-hidden={!!label}>{icon}</span>
86
+ <span>{label}</span>
87
+ </BodyShort>
88
+ </Component>
89
+ );
90
+ },
91
+ );
92
+
93
+ export default Tab;
@@ -0,0 +1,52 @@
1
+ import { composeEventHandlers } from "../../../util/composeEventHandlers";
2
+ import { mergeRefs } from "../../../util/hooks/useMergeRefs";
3
+ import { useTabsContext, useTabsDescendant } from "../../Tabs.context";
4
+
5
+ export interface UseTabProps {
6
+ /**
7
+ * If `true`, the `Tab` won't be toggleable
8
+ * @default false
9
+ */
10
+ disabled?: boolean;
11
+ onClick?: React.MouseEventHandler;
12
+ onFocus?: React.FocusEventHandler;
13
+ value: string;
14
+ }
15
+
16
+ export function useTab<P extends UseTabProps>(
17
+ { value, disabled = false, onFocus: _onFocus, onClick }: P,
18
+ ref: React.ForwardedRef<HTMLButtonElement>,
19
+ ) {
20
+ const {
21
+ id,
22
+ setSelectedValue,
23
+ selectionFollowsFocus,
24
+ focusedValue,
25
+ setFocusedValue,
26
+ selectedValue,
27
+ makeTabId,
28
+ makeTabPanelId,
29
+ } = useTabsContext();
30
+
31
+ const { register } = useTabsDescendant({
32
+ disabled,
33
+ value,
34
+ });
35
+
36
+ const isSelected = value === selectedValue;
37
+
38
+ const onFocus = () => {
39
+ setFocusedValue(value);
40
+ selectionFollowsFocus && setSelectedValue(value);
41
+ };
42
+
43
+ return {
44
+ ref: mergeRefs([register, ref]),
45
+ isSelected,
46
+ isFocused: focusedValue === value,
47
+ id: makeTabId(id, value),
48
+ controlsId: makeTabPanelId(id, value),
49
+ onClick: composeEventHandlers(onClick, () => setSelectedValue(value)),
50
+ onFocus: disabled ? undefined : composeEventHandlers(_onFocus, onFocus),
51
+ };
52
+ }
@@ -0,0 +1,29 @@
1
+ import cl from "clsx";
2
+ import React from "react";
3
+ import { ChevronLeftIcon, ChevronRightIcon } from "@navikt/aksel-icons";
4
+
5
+ interface ScrollButtonProps {
6
+ hidden: boolean;
7
+ onClick: () => void;
8
+ dir: "left" | "right";
9
+ }
10
+
11
+ function ScrollButton({ hidden, onClick, dir }: ScrollButtonProps) {
12
+ return (
13
+ <div
14
+ className={cl("navds-tabs__scroll-button", {
15
+ "navds-tabs__scroll-button--hidden": hidden,
16
+ })}
17
+ onClick={onClick}
18
+ aria-hidden
19
+ >
20
+ {dir === "left" ? (
21
+ <ChevronLeftIcon title="scroll tilbake" />
22
+ ) : (
23
+ <ChevronRightIcon title="scroll neste" />
24
+ )}
25
+ </div>
26
+ );
27
+ }
28
+
29
+ export default ScrollButton;
@@ -0,0 +1,56 @@
1
+ /* eslint-disable jsx-a11y/interactive-supports-focus */
2
+ import cl from "clsx";
3
+ import React, { forwardRef, useRef } from "react";
4
+ import { composeEventHandlers } from "../../../util/composeEventHandlers";
5
+ import { useMergeRefs } from "../../../util/hooks/useMergeRefs";
6
+ import ScrollButton from "./ScrollButtons";
7
+ import { useScrollButtons } from "./useScrollButtons";
8
+ import { useTabList } from "./useTabList";
9
+
10
+ export interface TabListProps extends React.HTMLAttributes<HTMLDivElement> {
11
+ /**
12
+ * <Tabs.Tab /> elements.
13
+ */
14
+ children: React.ReactNode;
15
+ }
16
+
17
+ export const TabList = forwardRef<HTMLDivElement, TabListProps>(
18
+ ({ className, onKeyDown, ...rest }, ref) => {
19
+ const { onKeyDown: _onKeyDown } = useTabList();
20
+
21
+ const listRef = useRef<HTMLDivElement>(null);
22
+ const mergedRef = useMergeRefs(listRef, ref);
23
+
24
+ const scrollCtx = useScrollButtons(listRef);
25
+
26
+ return (
27
+ <div className="navds-tabs__tablist-wrapper">
28
+ {scrollCtx.show && (
29
+ <ScrollButton
30
+ dir="left"
31
+ hidden={!scrollCtx.start}
32
+ onClick={scrollCtx.scrollLeft}
33
+ />
34
+ )}
35
+ <div
36
+ ref={mergedRef}
37
+ {...rest}
38
+ onScroll={scrollCtx.update}
39
+ className={cl("navds-tabs__tablist", className)}
40
+ role="tablist"
41
+ aria-orientation="horizontal"
42
+ onKeyDown={composeEventHandlers(onKeyDown, _onKeyDown)}
43
+ />
44
+ {scrollCtx.show && (
45
+ <ScrollButton
46
+ dir="right"
47
+ hidden={!scrollCtx.end}
48
+ onClick={scrollCtx.scrollRight}
49
+ />
50
+ )}
51
+ </div>
52
+ );
53
+ },
54
+ );
55
+
56
+ export default TabList;