@arbor-education/design-system.components 0.14.0 → 0.16.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 (320) hide show
  1. package/.gather/skills/write-stories/SKILL.md +207 -271
  2. package/.storybook/preview.ts +5 -0
  3. package/CHANGELOG.md +27 -0
  4. package/README.md +8 -0
  5. package/component-library.md +144 -13
  6. package/dist/components/articleCard/ArticleCard.stories.d.ts +137 -11
  7. package/dist/components/articleCard/ArticleCard.stories.d.ts.map +1 -1
  8. package/dist/components/articleCard/ArticleCard.stories.js +358 -91
  9. package/dist/components/articleCard/ArticleCard.stories.js.map +1 -1
  10. package/dist/components/avatar/Avatar.stories.d.ts +6 -6
  11. package/dist/components/avatar/Avatar.stories.d.ts.map +1 -1
  12. package/dist/components/avatar/Avatar.stories.js +393 -49
  13. package/dist/components/avatar/Avatar.stories.js.map +1 -1
  14. package/dist/components/avatarGroup/AvatarGroup.stories.d.ts +9 -7
  15. package/dist/components/avatarGroup/AvatarGroup.stories.d.ts.map +1 -1
  16. package/dist/components/avatarGroup/AvatarGroup.stories.js +688 -65
  17. package/dist/components/avatarGroup/AvatarGroup.stories.js.map +1 -1
  18. package/dist/components/banner/Banner.stories.d.ts.map +1 -1
  19. package/dist/components/banner/Banner.stories.js +7 -3
  20. package/dist/components/banner/Banner.stories.js.map +1 -1
  21. package/dist/components/card/Card.stories.d.ts +105 -4
  22. package/dist/components/card/Card.stories.d.ts.map +1 -1
  23. package/dist/components/card/Card.stories.js +336 -18
  24. package/dist/components/card/Card.stories.js.map +1 -1
  25. package/dist/components/combobox/Combobox.stories.d.ts +134 -21
  26. package/dist/components/combobox/Combobox.stories.d.ts.map +1 -1
  27. package/dist/components/combobox/Combobox.stories.js +676 -175
  28. package/dist/components/combobox/Combobox.stories.js.map +1 -1
  29. package/dist/components/datePicker/DatePicker.stories.d.ts +119 -27
  30. package/dist/components/datePicker/DatePicker.stories.d.ts.map +1 -1
  31. package/dist/components/datePicker/DatePicker.stories.js +575 -47
  32. package/dist/components/datePicker/DatePicker.stories.js.map +1 -1
  33. package/dist/components/dateTimePicker/DateTimePicker.stories.d.ts +155 -39
  34. package/dist/components/dateTimePicker/DateTimePicker.stories.d.ts.map +1 -1
  35. package/dist/components/dateTimePicker/DateTimePicker.stories.js +674 -103
  36. package/dist/components/dateTimePicker/DateTimePicker.stories.js.map +1 -1
  37. package/dist/components/editableText/EditableText.stories.d.ts +53 -12
  38. package/dist/components/editableText/EditableText.stories.d.ts.map +1 -1
  39. package/dist/components/editableText/EditableText.stories.js +401 -64
  40. package/dist/components/editableText/EditableText.stories.js.map +1 -1
  41. package/dist/components/formField/FormField.d.ts +4 -0
  42. package/dist/components/formField/FormField.d.ts.map +1 -1
  43. package/dist/components/formField/FormField.js +2 -1
  44. package/dist/components/formField/FormField.js.map +1 -1
  45. package/dist/components/formField/FormField.test.js +5 -0
  46. package/dist/components/formField/FormField.test.js.map +1 -1
  47. package/dist/components/formField/fieldset/Fieldset.stories.d.ts +56 -4
  48. package/dist/components/formField/fieldset/Fieldset.stories.d.ts.map +1 -1
  49. package/dist/components/formField/fieldset/Fieldset.stories.js +534 -28
  50. package/dist/components/formField/fieldset/Fieldset.stories.js.map +1 -1
  51. package/dist/components/formField/inputs/checkbox/CheckboxGroup.d.ts +3 -1
  52. package/dist/components/formField/inputs/checkbox/CheckboxGroup.d.ts.map +1 -1
  53. package/dist/components/formField/inputs/checkbox/CheckboxInput.js +1 -1
  54. package/dist/components/formField/inputs/checkbox/CheckboxInput.js.map +1 -1
  55. package/dist/components/formField/inputs/colourPickerDropdown/ColourPickerDropdown.stories.d.ts +95 -1
  56. package/dist/components/formField/inputs/colourPickerDropdown/ColourPickerDropdown.stories.d.ts.map +1 -1
  57. package/dist/components/formField/inputs/colourPickerDropdown/ColourPickerDropdown.stories.js +386 -9
  58. package/dist/components/formField/inputs/colourPickerDropdown/ColourPickerDropdown.stories.js.map +1 -1
  59. package/dist/components/formField/inputs/number/NumberInput.d.ts.map +1 -1
  60. package/dist/components/formField/inputs/number/NumberInput.js +14 -2
  61. package/dist/components/formField/inputs/number/NumberInput.js.map +1 -1
  62. package/dist/components/formField/inputs/number/NumberInput.test.js +21 -0
  63. package/dist/components/formField/inputs/number/NumberInput.test.js.map +1 -1
  64. package/dist/components/formField/inputs/radio/RadioButtonGroup.d.ts +6 -2
  65. package/dist/components/formField/inputs/radio/RadioButtonGroup.d.ts.map +1 -1
  66. package/dist/components/formField/inputs/radio/RadioButtonGroup.js.map +1 -1
  67. package/dist/components/formField/inputs/radio/RadioButtonInput.stories.d.ts.map +1 -1
  68. package/dist/components/formField/inputs/radio/RadioButtonInput.stories.js +61 -49
  69. package/dist/components/formField/inputs/radio/RadioButtonInput.stories.js.map +1 -1
  70. package/dist/components/formField/inputs/selectDropdown/SelectDropdown.stories.d.ts +188 -166
  71. package/dist/components/formField/inputs/selectDropdown/SelectDropdown.stories.d.ts.map +1 -1
  72. package/dist/components/formField/inputs/selectDropdown/SelectDropdown.stories.js +821 -160
  73. package/dist/components/formField/inputs/selectDropdown/SelectDropdown.stories.js.map +1 -1
  74. package/dist/components/formField/inputs/time/TimeInput.stories.d.ts +176 -22
  75. package/dist/components/formField/inputs/time/TimeInput.stories.d.ts.map +1 -1
  76. package/dist/components/formField/inputs/time/TimeInput.stories.js +851 -92
  77. package/dist/components/formField/inputs/time/TimeInput.stories.js.map +1 -1
  78. package/dist/components/formField/label/Label.stories.d.ts +54 -5
  79. package/dist/components/formField/label/Label.stories.d.ts.map +1 -1
  80. package/dist/components/formField/label/Label.stories.js +238 -4
  81. package/dist/components/formField/label/Label.stories.js.map +1 -1
  82. package/dist/components/icoText/IcoText.stories.d.ts +32 -6
  83. package/dist/components/icoText/IcoText.stories.d.ts.map +1 -1
  84. package/dist/components/icoText/IcoText.stories.js +309 -14
  85. package/dist/components/icoText/IcoText.stories.js.map +1 -1
  86. package/dist/components/kpiCard/KPICard.stories.d.ts +100 -2
  87. package/dist/components/kpiCard/KPICard.stories.d.ts.map +1 -1
  88. package/dist/components/kpiCard/KPICard.stories.js +354 -10
  89. package/dist/components/kpiCard/KPICard.stories.js.map +1 -1
  90. package/dist/components/kvpList/KVPList.stories.d.ts +57 -4
  91. package/dist/components/kvpList/KVPList.stories.d.ts.map +1 -1
  92. package/dist/components/kvpList/KVPList.stories.js +403 -10
  93. package/dist/components/kvpList/KVPList.stories.js.map +1 -1
  94. package/dist/components/modal/Modal.stories.d.ts +113 -9
  95. package/dist/components/modal/Modal.stories.d.ts.map +1 -1
  96. package/dist/components/modal/Modal.stories.js +633 -13
  97. package/dist/components/modal/Modal.stories.js.map +1 -1
  98. package/dist/components/modal/modalManager/ModalManager.stories.d.ts +34 -10
  99. package/dist/components/modal/modalManager/ModalManager.stories.d.ts.map +1 -1
  100. package/dist/components/modal/modalManager/ModalManager.stories.js +463 -85
  101. package/dist/components/modal/modalManager/ModalManager.stories.js.map +1 -1
  102. package/dist/components/pill/Pill.d.ts.map +1 -1
  103. package/dist/components/pill/Pill.js +1 -1
  104. package/dist/components/pill/Pill.js.map +1 -1
  105. package/dist/components/pill/Pill.stories.d.ts.map +1 -1
  106. package/dist/components/pill/Pill.stories.js +11 -13
  107. package/dist/components/pill/Pill.stories.js.map +1 -1
  108. package/dist/components/row/Row.stories.d.ts +1 -2
  109. package/dist/components/row/Row.stories.d.ts.map +1 -1
  110. package/dist/components/row/Row.stories.js +360 -50
  111. package/dist/components/row/Row.stories.js.map +1 -1
  112. package/dist/components/searchBar/SearchBar.stories.d.ts +52 -4
  113. package/dist/components/searchBar/SearchBar.stories.d.ts.map +1 -1
  114. package/dist/components/searchBar/SearchBar.stories.js +428 -36
  115. package/dist/components/searchBar/SearchBar.stories.js.map +1 -1
  116. package/dist/components/section/Section.stories.d.ts +11 -41
  117. package/dist/components/section/Section.stories.d.ts.map +1 -1
  118. package/dist/components/section/Section.stories.js +494 -56
  119. package/dist/components/section/Section.stories.js.map +1 -1
  120. package/dist/components/singleUser/SingleUser.stories.d.ts +5 -4
  121. package/dist/components/singleUser/SingleUser.stories.d.ts.map +1 -1
  122. package/dist/components/singleUser/SingleUser.stories.js +303 -31
  123. package/dist/components/singleUser/SingleUser.stories.js.map +1 -1
  124. package/dist/components/slideoverManager/SlideoverManager.stories.d.ts +32 -11
  125. package/dist/components/slideoverManager/SlideoverManager.stories.d.ts.map +1 -1
  126. package/dist/components/slideoverManager/SlideoverManager.stories.js +380 -84
  127. package/dist/components/slideoverManager/SlideoverManager.stories.js.map +1 -1
  128. package/dist/components/table/DSDefaultColDef.d.ts.map +1 -1
  129. package/dist/components/table/DSDefaultColDef.js +4 -3
  130. package/dist/components/table/DSDefaultColDef.js.map +1 -1
  131. package/dist/components/table/Table.d.ts +7 -1
  132. package/dist/components/table/Table.d.ts.map +1 -1
  133. package/dist/components/table/Table.js +12 -5
  134. package/dist/components/table/Table.js.map +1 -1
  135. package/dist/components/table/Table.stories.d.ts +3 -0
  136. package/dist/components/table/Table.stories.d.ts.map +1 -1
  137. package/dist/components/table/Table.stories.js +445 -3
  138. package/dist/components/table/Table.stories.js.map +1 -1
  139. package/dist/components/table/Table.test.js +184 -0
  140. package/dist/components/table/Table.test.js.map +1 -1
  141. package/dist/components/table/TableFooter.stories.d.ts +49 -0
  142. package/dist/components/table/TableFooter.stories.d.ts.map +1 -0
  143. package/dist/components/table/TableFooter.stories.js +137 -0
  144. package/dist/components/table/TableFooter.stories.js.map +1 -0
  145. package/dist/components/table/TableHeader.stories.d.ts +93 -0
  146. package/dist/components/table/TableHeader.stories.d.ts.map +1 -0
  147. package/dist/components/table/TableHeader.stories.js +176 -0
  148. package/dist/components/table/TableHeader.stories.js.map +1 -0
  149. package/dist/components/table/cellEditors/DateCellEditor.stories.d.ts +44 -0
  150. package/dist/components/table/cellEditors/DateCellEditor.stories.d.ts.map +1 -0
  151. package/dist/components/table/cellEditors/DateCellEditor.stories.js +186 -0
  152. package/dist/components/table/cellEditors/DateCellEditor.stories.js.map +1 -0
  153. package/dist/components/table/cellEditors/NumberCellEditor.d.ts +13 -0
  154. package/dist/components/table/cellEditors/NumberCellEditor.d.ts.map +1 -0
  155. package/dist/components/table/cellEditors/NumberCellEditor.js +35 -0
  156. package/dist/components/table/cellEditors/NumberCellEditor.js.map +1 -0
  157. package/dist/components/table/cellRenderers/BooleanCellRenderer.stories.d.ts +40 -0
  158. package/dist/components/table/cellRenderers/BooleanCellRenderer.stories.d.ts.map +1 -0
  159. package/dist/components/table/cellRenderers/BooleanCellRenderer.stories.js +209 -0
  160. package/dist/components/table/cellRenderers/BooleanCellRenderer.stories.js.map +1 -0
  161. package/dist/components/table/cellRenderers/ButtonCellRenderer.stories.d.ts +48 -0
  162. package/dist/components/table/cellRenderers/ButtonCellRenderer.stories.d.ts.map +1 -0
  163. package/dist/components/table/cellRenderers/ButtonCellRenderer.stories.js +244 -0
  164. package/dist/components/table/cellRenderers/ButtonCellRenderer.stories.js.map +1 -0
  165. package/dist/components/table/cellRenderers/CheckboxCellRenderer.d.ts.map +1 -1
  166. package/dist/components/table/cellRenderers/CheckboxCellRenderer.js +3 -1
  167. package/dist/components/table/cellRenderers/CheckboxCellRenderer.js.map +1 -1
  168. package/dist/components/table/cellRenderers/CheckboxCellRenderer.stories.d.ts +64 -0
  169. package/dist/components/table/cellRenderers/CheckboxCellRenderer.stories.d.ts.map +1 -0
  170. package/dist/components/table/cellRenderers/CheckboxCellRenderer.stories.js +241 -0
  171. package/dist/components/table/cellRenderers/CheckboxCellRenderer.stories.js.map +1 -0
  172. package/dist/components/table/cellRenderers/DefaultCellRenderer.stories.d.ts +55 -0
  173. package/dist/components/table/cellRenderers/DefaultCellRenderer.stories.d.ts.map +1 -0
  174. package/dist/components/table/cellRenderers/DefaultCellRenderer.stories.js +245 -0
  175. package/dist/components/table/cellRenderers/DefaultCellRenderer.stories.js.map +1 -0
  176. package/dist/components/table/cellRenderers/InlineTextCellRenderer.stories.d.ts +67 -0
  177. package/dist/components/table/cellRenderers/InlineTextCellRenderer.stories.d.ts.map +1 -0
  178. package/dist/components/table/cellRenderers/InlineTextCellRenderer.stories.js +221 -0
  179. package/dist/components/table/cellRenderers/InlineTextCellRenderer.stories.js.map +1 -0
  180. package/dist/components/table/cellRenderers/SelectDropdownCellRenderer.stories.d.ts +75 -0
  181. package/dist/components/table/cellRenderers/SelectDropdownCellRenderer.stories.d.ts.map +1 -0
  182. package/dist/components/table/cellRenderers/SelectDropdownCellRenderer.stories.js +270 -0
  183. package/dist/components/table/cellRenderers/SelectDropdownCellRenderer.stories.js.map +1 -0
  184. package/dist/components/table/columnFilters/BooleanFilter.stories.d.ts +57 -0
  185. package/dist/components/table/columnFilters/BooleanFilter.stories.d.ts.map +1 -0
  186. package/dist/components/table/columnFilters/BooleanFilter.stories.js +198 -0
  187. package/dist/components/table/columnFilters/BooleanFilter.stories.js.map +1 -0
  188. package/dist/components/table/columnFilters/TimeFilter.stories.d.ts +58 -0
  189. package/dist/components/table/columnFilters/TimeFilter.stories.d.ts.map +1 -0
  190. package/dist/components/table/columnFilters/TimeFilter.stories.js +207 -0
  191. package/dist/components/table/columnFilters/TimeFilter.stories.js.map +1 -0
  192. package/dist/components/table/pagination/PaginationPanel.stories.d.ts +113 -0
  193. package/dist/components/table/pagination/PaginationPanel.stories.d.ts.map +1 -0
  194. package/dist/components/table/pagination/PaginationPanel.stories.js +272 -0
  195. package/dist/components/table/pagination/PaginationPanel.stories.js.map +1 -0
  196. package/dist/components/table/tableControls/TableControls.stories.d.ts +151 -0
  197. package/dist/components/table/tableControls/TableControls.stories.d.ts.map +1 -0
  198. package/dist/components/table/tableControls/TableControls.stories.js +356 -0
  199. package/dist/components/table/tableControls/TableControls.stories.js.map +1 -0
  200. package/dist/components/table/tableControls/TableSettingsDropdown.d.ts +27 -1
  201. package/dist/components/table/tableControls/TableSettingsDropdown.d.ts.map +1 -1
  202. package/dist/components/table/tableControls/TableSettingsDropdown.js +53 -26
  203. package/dist/components/table/tableControls/TableSettingsDropdown.js.map +1 -1
  204. package/dist/components/table/tableControls/TableSettingsDropdown.test.d.ts +2 -0
  205. package/dist/components/table/tableControls/TableSettingsDropdown.test.d.ts.map +1 -0
  206. package/dist/components/table/tableControls/TableSettingsDropdown.test.js +178 -0
  207. package/dist/components/table/tableControls/TableSettingsDropdown.test.js.map +1 -0
  208. package/dist/components/tabs/Tabs.stories.d.ts +22 -4
  209. package/dist/components/tabs/Tabs.stories.d.ts.map +1 -1
  210. package/dist/components/tabs/Tabs.stories.js +398 -22
  211. package/dist/components/tabs/Tabs.stories.js.map +1 -1
  212. package/dist/components/tabs/TabsItem.stories.d.ts +54 -1
  213. package/dist/components/tabs/TabsItem.stories.d.ts.map +1 -1
  214. package/dist/components/tabs/TabsItem.stories.js +61 -9
  215. package/dist/components/tabs/TabsItem.stories.js.map +1 -1
  216. package/dist/components/toast/Toast.stories.d.ts +103 -10
  217. package/dist/components/toast/Toast.stories.d.ts.map +1 -1
  218. package/dist/components/toast/Toast.stories.js +409 -47
  219. package/dist/components/toast/Toast.stories.js.map +1 -1
  220. package/dist/components/toggle/Toggle.stories.d.ts +61 -46
  221. package/dist/components/toggle/Toggle.stories.d.ts.map +1 -1
  222. package/dist/components/toggle/Toggle.stories.js +311 -122
  223. package/dist/components/toggle/Toggle.stories.js.map +1 -1
  224. package/dist/components/tooltip/Tooltip.stories.d.ts +78 -6
  225. package/dist/components/tooltip/Tooltip.stories.d.ts.map +1 -1
  226. package/dist/components/tooltip/Tooltip.stories.js +413 -7
  227. package/dist/components/tooltip/Tooltip.stories.js.map +1 -1
  228. package/dist/components/tooltip/TooltipWrapper.stories.d.ts +71 -7
  229. package/dist/components/tooltip/TooltipWrapper.stories.d.ts.map +1 -1
  230. package/dist/components/tooltip/TooltipWrapper.stories.js +238 -10
  231. package/dist/components/tooltip/TooltipWrapper.stories.js.map +1 -1
  232. package/dist/index.css +27 -0
  233. package/dist/index.css.map +1 -1
  234. package/dist/index.d.ts +3 -2
  235. package/dist/index.d.ts.map +1 -1
  236. package/dist/index.js +3 -2
  237. package/dist/index.js.map +1 -1
  238. package/dist/utils/PopupParentContext.stories.d.ts +17 -0
  239. package/dist/utils/PopupParentContext.stories.d.ts.map +1 -0
  240. package/dist/utils/PopupParentContext.stories.js +266 -0
  241. package/dist/utils/PopupParentContext.stories.js.map +1 -0
  242. package/dist/utils/getDefaultPopupParent.d.ts.map +1 -1
  243. package/dist/utils/getDefaultPopupParent.js +6 -0
  244. package/dist/utils/getDefaultPopupParent.js.map +1 -1
  245. package/package.json +1 -1
  246. package/src/components/articleCard/ArticleCard.stories.tsx +524 -111
  247. package/src/components/avatar/Avatar.stories.tsx +504 -59
  248. package/src/components/avatarGroup/AvatarGroup.stories.tsx +977 -175
  249. package/src/components/banner/Banner.stories.tsx +7 -3
  250. package/src/components/card/Card.stories.tsx +466 -36
  251. package/src/components/combobox/Combobox.stories.tsx +867 -260
  252. package/src/components/datePicker/DatePicker.stories.tsx +777 -60
  253. package/src/components/dateTimePicker/DateTimePicker.stories.tsx +910 -132
  254. package/src/components/editableText/EditableText.stories.tsx +567 -91
  255. package/src/components/formField/FormField.test.tsx +6 -0
  256. package/src/components/formField/FormField.tsx +5 -0
  257. package/src/components/formField/fieldset/Fieldset.stories.tsx +761 -51
  258. package/src/components/formField/inputs/checkbox/CheckboxGroup.tsx +1 -1
  259. package/src/components/formField/inputs/checkbox/CheckboxInput.tsx +1 -1
  260. package/src/components/formField/inputs/colourPickerDropdown/ColourPickerDropdown.stories.tsx +504 -11
  261. package/src/components/formField/inputs/number/NumberInput.test.tsx +28 -0
  262. package/src/components/formField/inputs/number/NumberInput.tsx +15 -0
  263. package/src/components/formField/inputs/radio/RadioButtonGroup.tsx +17 -4
  264. package/src/components/formField/inputs/radio/RadioButtonInput.stories.tsx +71 -59
  265. package/src/components/formField/inputs/selectDropdown/SelectDropdown.stories.tsx +1079 -168
  266. package/src/components/formField/inputs/time/TimeInput.stories.tsx +1140 -104
  267. package/src/components/formField/label/Label.stories.tsx +317 -8
  268. package/src/components/icoText/IcoText.stories.tsx +442 -31
  269. package/src/components/kpiCard/KPICard.stories.tsx +475 -30
  270. package/src/components/kvpList/KVPList.stories.tsx +593 -26
  271. package/src/components/modal/Modal.stories.tsx +963 -26
  272. package/src/components/modal/modalManager/ModalManager.stories.tsx +612 -454
  273. package/src/components/pill/Pill.stories.tsx +11 -13
  274. package/src/components/pill/Pill.tsx +1 -0
  275. package/src/components/row/Row.stories.tsx +474 -58
  276. package/src/components/searchBar/SearchBar.stories.tsx +570 -38
  277. package/src/components/section/Section.stories.tsx +723 -70
  278. package/src/components/singleUser/SingleUser.stories.tsx +393 -34
  279. package/src/components/slideoverManager/SlideoverManager.stories.tsx +572 -342
  280. package/src/components/table/DSDefaultColDef.ts +25 -5
  281. package/src/components/table/Table.stories.tsx +504 -3
  282. package/src/components/table/Table.test.tsx +255 -0
  283. package/src/components/table/Table.tsx +15 -2
  284. package/src/components/table/TableFooter.stories.tsx +196 -0
  285. package/src/components/table/TableHeader.stories.tsx +251 -0
  286. package/src/components/table/cellEditors/DateCellEditor.stories.tsx +245 -0
  287. package/src/components/table/cellEditors/NumberCellEditor.tsx +83 -0
  288. package/src/components/table/cellEditors/numberCellEditor.scss +11 -0
  289. package/src/components/table/cellRenderers/BooleanCellRenderer.stories.tsx +278 -0
  290. package/src/components/table/cellRenderers/ButtonCellRenderer.stories.tsx +333 -0
  291. package/src/components/table/cellRenderers/CheckboxCellRenderer.stories.tsx +337 -0
  292. package/src/components/table/cellRenderers/CheckboxCellRenderer.tsx +5 -1
  293. package/src/components/table/cellRenderers/DefaultCellRenderer.stories.tsx +342 -0
  294. package/src/components/table/cellRenderers/InlineTextCellRenderer.stories.tsx +292 -0
  295. package/src/components/table/cellRenderers/SelectDropdownCellRenderer.stories.tsx +369 -0
  296. package/src/components/table/columnFilters/BooleanFilter.stories.tsx +268 -0
  297. package/src/components/table/columnFilters/TimeFilter.stories.tsx +281 -0
  298. package/src/components/table/pagination/PaginationPanel.stories.tsx +327 -0
  299. package/src/components/table/table.scss +11 -0
  300. package/src/components/table/tableControls/TableControls.stories.tsx +415 -0
  301. package/src/components/table/tableControls/TableSettingsDropdown.test.tsx +207 -0
  302. package/src/components/table/tableControls/TableSettingsDropdown.tsx +103 -39
  303. package/src/components/tabs/Tabs.stories.tsx +540 -60
  304. package/src/components/tabs/TabsItem.stories.tsx +82 -8
  305. package/src/components/toast/Toast.stories.tsx +539 -77
  306. package/src/components/toggle/Toggle.stories.tsx +371 -135
  307. package/src/components/tooltip/Tooltip.stories.tsx +606 -15
  308. package/src/components/tooltip/TooltipWrapper.stories.tsx +348 -12
  309. package/src/docs/Contributing.mdx +241 -0
  310. package/src/docs/UsingComponents.mdx +93 -0
  311. package/src/docs/Welcome.mdx +68 -0
  312. package/src/global.scss +7 -0
  313. package/src/index.scss +1 -0
  314. package/src/index.ts +3 -2
  315. package/src/utils/PopupParentContext.stories.tsx +367 -0
  316. package/src/utils/getDefaultPopupParent.ts +6 -0
  317. package/.ralph/storybook-upgrade/knowledge.md +0 -308
  318. package/.ralph/storybook-upgrade/prd.json +0 -777
  319. package/.ralph/storybook-upgrade/progress.md +0 -342
  320. package/src/components/table/TableWIP.mdx +0 -3
@@ -1,90 +1,743 @@
1
- import type { Meta } from '@storybook/react-vite';
2
- import { Section } from './Section';
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import {
3
+ Controls,
4
+ Heading as DocHeading,
5
+ Markdown,
6
+ Primary as DocPrimary,
7
+ Stories,
8
+ Subtitle,
9
+ Title,
10
+ } from '@storybook/addon-docs/blocks';
11
+ import { fn } from 'storybook/test';
12
+
3
13
  import { Row } from 'Components/row/Row';
14
+ import { Section } from './Section';
15
+
16
+ // ---------------------------------------------------------------------------
17
+ // Content strings for the custom DocsPage
18
+ // ---------------------------------------------------------------------------
19
+
20
+ const DESCRIPTION_INTRO = [
21
+ '`Section` is a structural layout component that wraps a labelled content region.',
22
+ 'It renders a semantic `<section>` element with an optional title heading, an optional action button,',
23
+ 'and optional collapse/expand behaviour.',
24
+ 'Sections can be nested to create hierarchical content structures — nested sections automatically',
25
+ 'lose their horizontal padding to maintain visual rhythm.',
26
+ ].join(' ');
27
+
28
+ const PROPS_INTRO
29
+ = 'The preview below is wired to the **Controls** panel — tweak any prop to see the story update in real time.';
30
+
31
+ const USAGE_GUIDANCE = [
32
+ '### When to use',
33
+ '',
34
+ '- Grouping related content within a page or panel under a descriptive heading (e.g. "Personal Details", "Contact Information").',
35
+ '- Providing a collapsible region where space is at a premium and the content can reasonably be hidden by default.',
36
+ '- Pairing with an action button in the heading to give quick access to a related action (e.g. "Edit", "Add").',
37
+ '- Nesting sections to model a parent/child hierarchy — e.g. a "Student Profile" section containing "Personal Details" and "Academic" sub-sections.',
38
+ '',
39
+ '---',
40
+ '',
41
+ '### When NOT to use',
42
+ '',
43
+ '| Situation | Use instead |',
44
+ '|---|---|',
45
+ '| Full-page layout regions | Native `<main>`, `<aside>`, or `<article>` elements |',
46
+ '| Overlay or modal content | [`Modal`](?path=/docs/components-modals-modal--docs) or [`Slideover`](?path=/docs/components-slideover--docs) |',
47
+ '| Tabbed content panels | A tab component with panel regions |',
48
+ '| Purely decorative grouping with no heading | A plain `<div>` — `Section` always renders a heading element |',
49
+ ].join('\n');
50
+
51
+ const DEVELOPER_NOTES = [
52
+ '### `collapsed` is initial state only',
53
+ '',
54
+ 'The `collapsed` prop sets the **initial** collapsed state — the component becomes self-managed (uncontrolled) after mount.',
55
+ '`Section` owns the expanded/collapsed state internally via `useState(initialCollapsed)`.',
56
+ 'You cannot control the expanded state from outside after the component has mounted.',
57
+ 'If you need fully controlled behaviour, you will need a custom implementation.',
58
+ '',
59
+ '---',
60
+ '',
61
+ '### `headingLevel` defaults to `1` — use with care',
62
+ '',
63
+ '`headingLevel` defaults to `1`, which renders an `<h1>`. Most pages should have only one `<h1>`.',
64
+ 'Always set an explicit `headingLevel` appropriate to the heading hierarchy of the page.',
65
+ 'Use `2` for top-level sections on a page that already has an `<h1>`, and `3` or `4` for nested sub-sections.',
66
+ '',
67
+ '---',
68
+ '',
69
+ '### Button props must all be provided together',
70
+ '',
71
+ 'The action button only renders when `buttonText` is provided.',
72
+ 'When adding a button, always supply all four props together: `buttonText`, `buttonOnClick`, `buttonVariant`, and `buttonSize`.',
73
+ 'If any are omitted, the `Button` component falls back to its own defaults, which may produce unexpected visual results.',
74
+ '',
75
+ '---',
76
+ '',
77
+ '### Accessibility',
78
+ '',
79
+ '- The `<section>` renders with a hardcoded `aria-label="section"` to give it an implicit `role="region"`. This label is not configurable.',
80
+ '- When `collapsible` is `true`, a `<button>` with `aria-expanded` is rendered in the heading — this is the accessible toggle.',
81
+ '- The heading element gains `tabIndex={0}` and responds to **Enter** and **Space** when collapsible.',
82
+ '- Title icons should always include `titleIconScreenReaderText` unless they are purely decorative and the title fully describes the section.',
83
+ '',
84
+ '---',
85
+ '',
86
+ '### TypeScript types',
87
+ '',
88
+ '```ts',
89
+ "import { Section } from '@arbor-education/design-system.components';",
90
+ '',
91
+ 'type SectionProps = Section.Props;',
92
+ '```',
93
+ ].join('\n');
94
+
95
+ const RELATED_COMPONENTS = [
96
+ '## Related components',
97
+ '',
98
+ '[Row](?path=/docs/components-row--docs) · [Card](?path=/docs/components-card--docs) · [Heading](?path=/docs/components-heading--docs)',
99
+ ].join('\n');
100
+
101
+ // ---------------------------------------------------------------------------
102
+ // Custom DocsPage
103
+ // ---------------------------------------------------------------------------
104
+
105
+ function SectionDocsPage() {
106
+ return (
107
+ <>
108
+ <Title />
109
+ <Subtitle />
110
+ <Markdown>{DESCRIPTION_INTRO}</Markdown>
111
+ <DocHeading>Interactive example</DocHeading>
112
+ <Markdown>{PROPS_INTRO}</Markdown>
113
+ <DocPrimary />
114
+ <Controls />
115
+ <DocHeading>Usage guidance</DocHeading>
116
+ <Markdown>{USAGE_GUIDANCE}</Markdown>
117
+ <DocHeading>Developer notes</DocHeading>
118
+ <Markdown>{DEVELOPER_NOTES}</Markdown>
119
+ <DocHeading>Examples</DocHeading>
120
+ <Stories title="" />
121
+ <Markdown>{RELATED_COMPONENTS}</Markdown>
122
+ </>
123
+ );
124
+ }
125
+
126
+ // ---------------------------------------------------------------------------
127
+ // Meta
128
+ // ---------------------------------------------------------------------------
4
129
 
5
130
  const meta: Meta<typeof Section> = {
6
131
  title: 'Components/Section',
7
132
  component: Section,
8
- globals: {
9
- backgrounds: { value: 'dark' },
133
+ tags: ['autodocs'],
134
+ parameters: {
135
+ layout: 'padded',
136
+ docs: {
137
+ page: SectionDocsPage,
138
+ },
139
+ },
140
+ argTypes: {
141
+ title: {
142
+ description: 'Heading text rendered at the top of the section.',
143
+ control: 'text',
144
+ table: {
145
+ type: { summary: 'string' },
146
+ defaultValue: { summary: 'undefined' },
147
+ },
148
+ },
149
+ headingLevel: {
150
+ description: [
151
+ 'The HTML heading level rendered for the section title.',
152
+ 'Defaults to `1` (an `<h1>`) — always set this explicitly to match the page heading hierarchy.',
153
+ 'Use `2` for top-level sections, `3` or `4` for nested sub-sections.',
154
+ ].join(' '),
155
+ control: 'select',
156
+ options: [1, 2, 3, 4],
157
+ table: {
158
+ type: { summary: '1 | 2 | 3 | 4' },
159
+ defaultValue: { summary: '1' },
160
+ },
161
+ },
162
+ titleIconName: {
163
+ description: [
164
+ 'Icon rendered immediately after the title text.',
165
+ 'Pass `titleIconScreenReaderText` if the icon carries semantic meaning.',
166
+ ].join(' '),
167
+ control: 'text',
168
+ table: {
169
+ type: { summary: 'IconName' },
170
+ defaultValue: { summary: 'undefined' },
171
+ },
172
+ },
173
+ titleIconColor: {
174
+ description: 'CSS colour value applied to the title icon (e.g. `var(--color-brand-600)` or a hex string).',
175
+ control: 'color',
176
+ table: {
177
+ type: { summary: 'string' },
178
+ defaultValue: { summary: 'undefined' },
179
+ },
180
+ },
181
+ titleIconScreenReaderText: {
182
+ description: [
183
+ 'Accessible label for the title icon.',
184
+ 'Omit only when the icon is purely decorative and the title already conveys full meaning.',
185
+ ].join(' '),
186
+ control: 'text',
187
+ table: {
188
+ type: { summary: 'string' },
189
+ defaultValue: { summary: 'undefined' },
190
+ },
191
+ },
192
+ collapsible: {
193
+ description: [
194
+ 'When `true`, the section heading becomes a toggle.',
195
+ 'A chevron button with `aria-expanded` is rendered and the section contents can be shown or hidden.',
196
+ 'Keyboard users can toggle with **Enter** or **Space**.',
197
+ ].join(' '),
198
+ control: 'boolean',
199
+ table: {
200
+ type: { summary: 'boolean' },
201
+ defaultValue: { summary: 'false' },
202
+ },
203
+ },
204
+ collapsed: {
205
+ description: [
206
+ '**Initial** collapsed state when `collapsible` is `true`.',
207
+ 'This prop sets the state at mount — the component is uncontrolled after that.',
208
+ 'Changing this prop after mount has no effect.',
209
+ ].join(' '),
210
+ control: 'boolean',
211
+ table: {
212
+ type: { summary: 'boolean' },
213
+ defaultValue: { summary: 'false' },
214
+ },
215
+ },
216
+ buttonText: {
217
+ description: [
218
+ 'Label for the action button rendered in the section heading.',
219
+ 'Must be paired with `buttonOnClick`, `buttonVariant`, and `buttonSize`.',
220
+ ].join(' '),
221
+ control: 'text',
222
+ table: {
223
+ type: { summary: 'string' },
224
+ defaultValue: { summary: 'undefined' },
225
+ },
226
+ },
227
+ buttonOnClick: {
228
+ description: 'Click handler for the heading action button.',
229
+ action: 'buttonOnClick',
230
+ control: false,
231
+ table: {
232
+ type: { summary: 'MouseEventHandler<HTMLButtonElement>' },
233
+ defaultValue: { summary: 'undefined' },
234
+ },
235
+ },
236
+ buttonVariant: {
237
+ description: 'Visual variant for the heading action button. Always supply when `buttonText` is set.',
238
+ control: 'select',
239
+ options: ['primary', 'secondary', 'tertiary', 'primary-destructive', 'secondary-destructive', 'tertiary-destructive', 'ghost'],
240
+ table: {
241
+ type: { summary: "'primary' | 'secondary' | 'tertiary' | 'primary-destructive' | 'secondary-destructive' | 'tertiary-destructive' | 'ghost'" },
242
+ defaultValue: { summary: 'undefined' },
243
+ },
244
+ },
245
+ buttonSize: {
246
+ description: "Size of the heading action button. Always supply when `buttonText` is set. Use `'S'` to keep it visually lightweight alongside the title.",
247
+ control: 'select',
248
+ options: ['S', 'M', 'L'],
249
+ table: {
250
+ type: { summary: "'S' | 'M' | 'L'" },
251
+ defaultValue: { summary: 'undefined' },
252
+ },
253
+ },
254
+ className: {
255
+ description: 'Additional CSS class names applied to the root `<section>` element.',
256
+ control: 'text',
257
+ table: {
258
+ type: { summary: 'string' },
259
+ defaultValue: { summary: 'undefined' },
260
+ },
261
+ },
262
+ children: {
263
+ description: [
264
+ 'Content rendered inside the section body.',
265
+ 'Typically `Row` components, nested `Section` components, or any React node.',
266
+ ].join(' '),
267
+ control: false,
268
+ table: {
269
+ type: { summary: 'ReactNode' },
270
+ defaultValue: { summary: 'undefined' },
271
+ },
272
+ },
10
273
  },
11
274
  };
12
275
 
13
- export const Default = {
14
- args: {
15
- title: 'titleValue',
16
- children: [<p key={1}>Sunt consectetur esse labore dolor consequat tempor dolor incididunt. Ullamco veniam ex enim consequat esse. Qui aute consequat dolore dolore ipsum commodo magna minim consectetur deserunt veniam in ipsum. Aute veniam do mollit cupidatat laboris. Laborum nisi est qui et eiusmod. Enim aliqua quis officia ut eiusmod quis dolore id commodo ipsum cillum sunt adipisicing laboris. Et non est sunt cillum ipsum.</p>],
276
+ export default meta;
277
+ type Story = StoryObj<typeof meta>;
278
+
279
+ // ---------------------------------------------------------------------------
280
+ // Helper
281
+ // ---------------------------------------------------------------------------
282
+
283
+ const withDescription = (story: Story, description: string): Story => ({
284
+ ...story,
285
+ parameters: {
286
+ ...story.parameters,
287
+ docs: { ...story.parameters?.docs, description: { story: description } },
17
288
  },
18
- };
289
+ });
290
+
291
+ // ---------------------------------------------------------------------------
292
+ // Stories
293
+ // ---------------------------------------------------------------------------
19
294
 
20
- export const NestedSections = {
21
- args: {
22
- title: 'Parent Section',
23
- collapsible: true,
24
- children: [
25
- <Section key={1} title="Sub-section 1" collapsible>
26
- <p>Eu nisi dolore qui irure irure nulla aliqua commodo non sint dolor consectetur. Ullamco dolore ut exercitation ad cupidatat ipsum. Nisi proident esse nisi ullamco irure incididunt eiusmod fugiat est culpa Lorem. Dolor esse ut minim magna. In qui fugiat non nulla eu mollit enim excepteur consequat qui consequat occaecat aliquip adipisicing. Eu est nisi irure laboris culpa amet consectetur irure quis duis.</p>
27
- </Section>,
28
- <Section key={2} title="Sub-section 2" collapsible>
29
- <p>Eu nisi dolore qui irure irure nulla aliqua commodo non sint dolor consectetur. Ullamco dolore ut exercitation ad cupidatat ipsum. Nisi proident esse nisi ullamco irure incididunt eiusmod fugiat est culpa Lorem. Dolor esse ut minim magna. In qui fugiat non nulla eu mollit enim excepteur consequat qui consequat occaecat aliquip adipisicing. Eu est nisi irure laboris culpa amet consectetur irure quis duis.</p>
30
- </Section>,
31
- ],
295
+ export const Default: Story = withDescription(
296
+ {
297
+ args: {
298
+ title: 'Student Details',
299
+ headingLevel: 2,
300
+ children: (
301
+ <p>
302
+ Section content goes here. Add
303
+ <code>Row</code>
304
+ {' '}
305
+ components, nested
306
+ <code>Section</code>
307
+ {' '}
308
+ components, or any content relevant to the section topic.
309
+ </p>
310
+ ),
311
+ },
312
+ render: args => <Section {...args} />,
32
313
  },
33
- };
314
+ 'The default story is wired to the Controls panel. Toggle `collapsible` to add expand/collapse behaviour, or add `buttonText` (with the three companion props) to surface an action in the heading.',
315
+ );
316
+
317
+ export const WithHeadingLevel: Story = withDescription(
318
+ {
319
+ parameters: {
320
+ controls: { disable: true },
321
+ docs: {
322
+ source: {
323
+ language: 'tsx',
324
+ code: `
325
+ import { Section } from '@arbor-education/design-system.components';
34
326
 
35
- export const WithRows = {
36
- args: {
37
- title: 'Student Details',
38
- children: [
39
- <Row key={1} label="First Name" value="Jacob" />,
40
- <Row key={2} label="Last Name" value="Black" />,
41
- <Row key={3} label="Year Group" value="Year 10" note="2024/2025" />,
42
- <Row key={4} label="Form Group" value="10A" />,
43
- ],
327
+ function SectionHierarchyExample() {
328
+ return (
329
+ <Section title="Student Profile" headingLevel={2}>
330
+ <p>Top-level section — headingLevel 2.</p>
331
+ <Section title="Personal Details" headingLevel={3}>
332
+ <p>Sub-section headingLevel 3.</p>
333
+ <Section title="Emergency Contacts" headingLevel={4}>
334
+ <p>Deeper sub-section headingLevel 4.</p>
335
+ </Section>
336
+ </Section>
337
+ </Section>
338
+ );
339
+ }
340
+ export default SectionHierarchyExample;
341
+ `.trim(),
342
+ },
343
+ },
344
+ },
345
+ render: () => (
346
+ <Section title="Student Profile" headingLevel={2}>
347
+ <p>
348
+ Top-level section —
349
+ <code>
350
+ headingLevel=
351
+ {2}
352
+ </code>
353
+ .
354
+ </p>
355
+ <Section title="Personal Details" headingLevel={3}>
356
+ <p>
357
+ Sub-section —
358
+ <code>
359
+ headingLevel=
360
+ {3}
361
+ </code>
362
+ .
363
+ </p>
364
+ <Section title="Emergency Contacts" headingLevel={4}>
365
+ <p>
366
+ Deeper sub-section —
367
+ <code>
368
+ headingLevel=
369
+ {4}
370
+ </code>
371
+ .
372
+ </p>
373
+ </Section>
374
+ </Section>
375
+ </Section>
376
+ ),
44
377
  },
45
- };
378
+ 'Set `headingLevel` to match the correct position in the page heading hierarchy. The default is `1` — always override it to avoid multiple `<h1>` elements on the page.',
379
+ );
380
+
381
+ export const WithTitleIcon: Story = withDescription(
382
+ {
383
+ parameters: {
384
+ controls: { disable: true },
385
+ docs: {
386
+ source: {
387
+ language: 'tsx',
388
+ code: `
389
+ import { Section } from '@arbor-education/design-system.components';
46
390
 
47
- export const WithClickableRows = {
48
- args: {
49
- title: 'Quick Links',
50
- buttonText: 'Edit',
51
- children: [
52
- <Row key={1} label="Attendance" value="96%" note="Above target" onClick={() => { console.log('click!'); }} />,
53
- <Row key={2} label="Behaviour" value="3 positive points" onClick={() => { console.log('click!'); }} />,
54
- <Row key={3} label="Assessment" value="On track" note="Last updated 2 days ago" onClick={() => { console.log('click!'); }} />,
55
- ],
391
+ function SENSectionWithIcon() {
392
+ return (
393
+ <Section
394
+ title="SEN Information"
395
+ headingLevel={2}
396
+ titleIconName="circle-alert"
397
+ titleIconColor="var(--color-semantic-warning-600)"
398
+ titleIconScreenReaderText="Special educational needs flag"
399
+ >
400
+ <p>Section content here.</p>
401
+ </Section>
402
+ );
403
+ }
404
+ export default SENSectionWithIcon;
405
+ `.trim(),
406
+ },
407
+ },
408
+ },
409
+ render: () => (
410
+ <Section
411
+ title="SEN Information"
412
+ headingLevel={2}
413
+ titleIconName="circle-alert"
414
+ titleIconColor="var(--color-semantic-warning-600)"
415
+ titleIconScreenReaderText="Special educational needs flag"
416
+ >
417
+ <p>
418
+ An icon after the title provides an at-a-glance visual cue. Pass
419
+ <code>titleIconScreenReaderText</code>
420
+ {' '}
421
+ so the icon is announced to screen readers.
422
+ </p>
423
+ </Section>
424
+ ),
56
425
  },
57
- };
426
+ 'Add `titleIconName` to render an icon after the section title. Pair it with `titleIconColor` for semantic colour and `titleIconScreenReaderText` for accessibility.',
427
+ );
58
428
 
59
- export const CollapsibleWithRows = {
60
- args: {
61
- title: 'Contact Information',
62
- collapsible: true,
63
- children: [
64
- <Row key={1} label="Email" value="jacob.black@forks.edu" />,
65
- <Row key={2} label="Phone" value="01onal 555 0123" />,
66
- <Row key={3} label="Address" value="La Push, Washington" note="Primary" />,
67
- ],
429
+ export const WithActionButton: Story = withDescription(
430
+ {
431
+ parameters: {
432
+ controls: { disable: true },
433
+ docs: {
434
+ source: {
435
+ language: 'tsx',
436
+ code: `
437
+ import { Section } from '@arbor-education/design-system.components';
438
+
439
+ function PersonalDetailsSection() {
440
+ return (
441
+ <Section
442
+ title="Personal Details"
443
+ headingLevel={2}
444
+ buttonText="Edit"
445
+ buttonOnClick={() => openEditModal()}
446
+ buttonVariant="secondary"
447
+ buttonSize="S"
448
+ >
449
+ <p>Section content here.</p>
450
+ </Section>
451
+ );
452
+ }
453
+ export default PersonalDetailsSection;
454
+ `.trim(),
455
+ },
456
+ },
457
+ },
458
+ render: () => (
459
+ <Section
460
+ title="Personal Details"
461
+ headingLevel={2}
462
+ buttonText="Edit"
463
+ buttonOnClick={fn()}
464
+ buttonVariant="secondary"
465
+ buttonSize="S"
466
+ >
467
+ <p>
468
+ The action button appears in the heading row. Always provide all four button props together:
469
+ <code>buttonText</code>
470
+ ,
471
+ <code>buttonOnClick</code>
472
+ ,
473
+ <code>buttonVariant</code>
474
+ , and
475
+ <code>buttonSize</code>
476
+ .
477
+ </p>
478
+ </Section>
479
+ ),
68
480
  },
69
- };
481
+ 'Provide all four button props together to render an action button in the section heading. Use `buttonSize="S"` to keep it visually lightweight alongside the title.',
482
+ );
70
483
 
71
- export const NestedSectionsWithRows = {
72
- args: {
73
- title: 'Student Profile',
74
- collapsible: true,
75
- children: [
76
- <Section key={1} title="Personal Details" collapsible>
77
- <Row label="First Name" value="Jacob" />
78
- <Row label="Last Name" value="Black" />
79
- <Row label="Date of Birth" value="14/01/1990" note="Age 36" />
80
- </Section>,
81
- <Section key={2} title="Academic" collapsible>
82
- <Row label="Year Group" value="Year 10" note="2024/2025" />
83
- <Row label="Form Group" value="10A" />
84
- <Row label="Attendance" value="96%" note="Above target" onClick={() => { console.log('click!'); }} />
85
- </Section>,
86
- ],
484
+ export const Collapsible: Story = withDescription(
485
+ {
486
+ parameters: {
487
+ controls: { disable: true },
488
+ docs: {
489
+ source: {
490
+ language: 'tsx',
491
+ code: `
492
+ import { Section } from '@arbor-education/design-system.components';
493
+
494
+ function CollapsibleSection() {
495
+ return (
496
+ <Section
497
+ title="Additional Notes"
498
+ headingLevel={2}
499
+ collapsible
500
+ >
501
+ <p>This section starts expanded. Click the heading or the chevron to collapse it.</p>
502
+ </Section>
503
+ );
504
+ }
505
+ export default CollapsibleSection;
506
+ `.trim(),
507
+ },
508
+ },
509
+ },
510
+ render: () => (
511
+ <Section
512
+ title="Additional Notes"
513
+ headingLevel={2}
514
+ collapsible
515
+ >
516
+ <p>
517
+ This section starts
518
+ <strong>expanded</strong>
519
+ . Click the heading or the chevron to collapse it. The state is managed internally — no external state management is required.
520
+ </p>
521
+ </Section>
522
+ ),
87
523
  },
88
- };
524
+ 'Set `collapsible` to add expand/collapse behaviour. The section starts expanded by default. Click the heading or the chevron icon to toggle — keyboard users can press **Enter** or **Space**.',
525
+ );
89
526
 
90
- export default meta;
527
+ export const CollapsibleInitiallyCollapsed: Story = withDescription(
528
+ {
529
+ parameters: {
530
+ controls: { disable: true },
531
+ docs: {
532
+ source: {
533
+ language: 'tsx',
534
+ code: `
535
+ import { Section } from '@arbor-education/design-system.components';
536
+
537
+ function CollapsedByDefaultSection() {
538
+ return (
539
+ <Section
540
+ title="Medical Information"
541
+ headingLevel={2}
542
+ collapsible
543
+ collapsed
544
+ >
545
+ <p>Sensitive content that is hidden by default.</p>
546
+ </Section>
547
+ );
548
+ }
549
+ export default CollapsedByDefaultSection;
550
+ `.trim(),
551
+ },
552
+ },
553
+ },
554
+ render: () => (
555
+ <Section
556
+ title="Medical Information"
557
+ headingLevel={2}
558
+ collapsible
559
+ collapsed
560
+ >
561
+ <p>
562
+ This content was hidden when the section mounted. The
563
+ <code>collapsed</code>
564
+ {' '}
565
+ prop only sets the initial state — the section is self-managed after that.
566
+ </p>
567
+ </Section>
568
+ ),
569
+ },
570
+ 'Pass `collapsed` alongside `collapsible` to start in the collapsed state. The `collapsed` prop is **initial state only** — the component owns the toggle state after mount and changing the prop later has no effect.',
571
+ );
572
+
573
+ export const CollapsibleWithActionButton: Story = withDescription(
574
+ {
575
+ parameters: {
576
+ controls: { disable: true },
577
+ docs: {
578
+ source: {
579
+ language: 'tsx',
580
+ code: `
581
+ import { Section } from '@arbor-education/design-system.components';
582
+
583
+ function ContactSection() {
584
+ return (
585
+ <Section
586
+ title="Contact Information"
587
+ headingLevel={2}
588
+ collapsible
589
+ buttonText="Add contact"
590
+ buttonOnClick={() => openAddContactModal()}
591
+ buttonVariant="secondary"
592
+ buttonSize="S"
593
+ >
594
+ <p>Contact details here.</p>
595
+ </Section>
596
+ );
597
+ }
598
+ export default ContactSection;
599
+ `.trim(),
600
+ },
601
+ },
602
+ },
603
+ render: () => (
604
+ <Section
605
+ title="Contact Information"
606
+ headingLevel={2}
607
+ collapsible
608
+ buttonText="Add contact"
609
+ buttonOnClick={fn()}
610
+ buttonVariant="secondary"
611
+ buttonSize="S"
612
+ >
613
+ <p>
614
+ A section can be both collapsible
615
+ <em>and</em>
616
+ {' '}
617
+ have an action button. The chevron and the button both appear in the heading row.
618
+ </p>
619
+ </Section>
620
+ ),
621
+ },
622
+ 'A section can combine `collapsible` with an action button. Both the chevron toggle and the action button appear in the heading row — useful when the content can be hidden but the action remains permanently accessible.',
623
+ );
624
+
625
+ export const WithRows: Story = withDescription(
626
+ {
627
+ parameters: {
628
+ controls: { disable: true },
629
+ docs: {
630
+ source: {
631
+ language: 'tsx',
632
+ code: `
633
+ import { Section, Row } from '@arbor-education/design-system.components';
634
+
635
+ function PupilDetailSection() {
636
+ return (
637
+ <Section
638
+ title="Personal Details"
639
+ headingLevel={2}
640
+ buttonText="Edit"
641
+ buttonOnClick={() => openEditModal()}
642
+ buttonVariant="secondary"
643
+ buttonSize="S"
644
+ >
645
+ <Row label="Full name" value="Amara Osei-Bonsu" />
646
+ <Row label="Date of birth" value="14 March 2009" note="Age 16" />
647
+ <Row label="Year group" value="Year 10" />
648
+ <Row label="Form" value="10JH" />
649
+ <Row label="UPN" value="A823456789012" />
650
+ </Section>
651
+ );
652
+ }
653
+ export default PupilDetailSection;
654
+ `.trim(),
655
+ },
656
+ },
657
+ },
658
+ render: () => (
659
+ <Section
660
+ title="Personal Details"
661
+ headingLevel={2}
662
+ buttonText="Edit"
663
+ buttonOnClick={fn()}
664
+ buttonVariant="secondary"
665
+ buttonSize="S"
666
+ >
667
+ <Row label="Full name" value="Amara Osei-Bonsu" />
668
+ <Row label="Date of birth" value="14 March 2009" note="Age 16" />
669
+ <Row label="Year group" value="Year 10" />
670
+ <Row label="Form" value="10JH" />
671
+ <Row label="UPN" value="A823456789012" />
672
+ </Section>
673
+ ),
674
+ },
675
+ 'The most common real-world usage — `Row` components inside a `Section`. Static and clickable rows can be freely mixed. The section heading can carry an action button for record-level operations like "Edit".',
676
+ );
677
+
678
+ export const NestedCollapsibleSections: Story = withDescription(
679
+ {
680
+ parameters: {
681
+ controls: { disable: true },
682
+ docs: {
683
+ source: {
684
+ language: 'tsx',
685
+ code: `
686
+ import { Section, Row } from '@arbor-education/design-system.components';
687
+
688
+ function PupilProfilePanel() {
689
+ return (
690
+ <Section title="Student Profile" headingLevel={2} collapsible>
691
+ <Section title="Personal Details" headingLevel={3} collapsible>
692
+ <Row label="Full name" value="Amara Osei-Bonsu" />
693
+ <Row label="Date of birth" value="14 March 2009" note="Age 16" />
694
+ <Row label="Admission number" value="001847" />
695
+ </Section>
696
+ <Section title="Academic" headingLevel={3} collapsible>
697
+ <Row label="Year group" value="Year 10" />
698
+ <Row label="Form" value="10JH" />
699
+ <Row
700
+ label="Attendance (YTD)"
701
+ value="88.3%"
702
+ note="Below 90% threshold"
703
+ onClick={() => navigateToAttendance()}
704
+ />
705
+ </Section>
706
+ <Section title="Contact Information" headingLevel={3} collapsible collapsed>
707
+ <Row label="Email" value="guardian@example.com" note="Primary contact" />
708
+ <Row label="Phone" value="07700 900123" />
709
+ </Section>
710
+ </Section>
711
+ );
712
+ }
713
+ export default PupilProfilePanel;
714
+ `.trim(),
715
+ },
716
+ },
717
+ },
718
+ render: () => (
719
+ <Section title="Student Profile" headingLevel={2} collapsible>
720
+ <Section title="Personal Details" headingLevel={3} collapsible>
721
+ <Row label="Full name" value="Amara Osei-Bonsu" />
722
+ <Row label="Date of birth" value="14 March 2009" note="Age 16" />
723
+ <Row label="Admission number" value="001847" />
724
+ </Section>
725
+ <Section title="Academic" headingLevel={3} collapsible>
726
+ <Row label="Year group" value="Year 10" />
727
+ <Row label="Form" value="10JH" />
728
+ <Row
729
+ label="Attendance (YTD)"
730
+ value="88.3%"
731
+ note="Below 90% threshold"
732
+ onClick={fn()}
733
+ />
734
+ </Section>
735
+ <Section title="Contact Information" headingLevel={3} collapsible collapsed>
736
+ <Row label="Email" value="guardian@example.com" note="Primary contact" />
737
+ <Row label="Phone" value="07700 900123" />
738
+ </Section>
739
+ </Section>
740
+ ),
741
+ },
742
+ 'Nested sections are a common pattern for hierarchical detail panels. Nested sections automatically lose their horizontal padding to maintain visual rhythm. Each section manages its own collapsed state independently.',
743
+ );