@arbor-education/design-system.components 0.15.0 → 0.16.1

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 (304) hide show
  1. package/.gather/skills/write-stories/SKILL.md +207 -271
  2. package/.storybook/preview.ts +5 -0
  3. package/CHANGELOG.md +23 -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/radio/RadioButtonGroup.d.ts +6 -2
  60. package/dist/components/formField/inputs/radio/RadioButtonGroup.d.ts.map +1 -1
  61. package/dist/components/formField/inputs/radio/RadioButtonGroup.js.map +1 -1
  62. package/dist/components/formField/inputs/radio/RadioButtonInput.stories.d.ts.map +1 -1
  63. package/dist/components/formField/inputs/radio/RadioButtonInput.stories.js +61 -49
  64. package/dist/components/formField/inputs/radio/RadioButtonInput.stories.js.map +1 -1
  65. package/dist/components/formField/inputs/selectDropdown/SelectDropdown.stories.d.ts +188 -166
  66. package/dist/components/formField/inputs/selectDropdown/SelectDropdown.stories.d.ts.map +1 -1
  67. package/dist/components/formField/inputs/selectDropdown/SelectDropdown.stories.js +821 -160
  68. package/dist/components/formField/inputs/selectDropdown/SelectDropdown.stories.js.map +1 -1
  69. package/dist/components/formField/inputs/time/TimeInput.stories.d.ts +176 -22
  70. package/dist/components/formField/inputs/time/TimeInput.stories.d.ts.map +1 -1
  71. package/dist/components/formField/inputs/time/TimeInput.stories.js +851 -92
  72. package/dist/components/formField/inputs/time/TimeInput.stories.js.map +1 -1
  73. package/dist/components/formField/label/Label.stories.d.ts +54 -5
  74. package/dist/components/formField/label/Label.stories.d.ts.map +1 -1
  75. package/dist/components/formField/label/Label.stories.js +238 -4
  76. package/dist/components/formField/label/Label.stories.js.map +1 -1
  77. package/dist/components/icoText/IcoText.stories.d.ts +32 -6
  78. package/dist/components/icoText/IcoText.stories.d.ts.map +1 -1
  79. package/dist/components/icoText/IcoText.stories.js +309 -14
  80. package/dist/components/icoText/IcoText.stories.js.map +1 -1
  81. package/dist/components/kpiCard/KPICard.stories.d.ts +100 -2
  82. package/dist/components/kpiCard/KPICard.stories.d.ts.map +1 -1
  83. package/dist/components/kpiCard/KPICard.stories.js +354 -10
  84. package/dist/components/kpiCard/KPICard.stories.js.map +1 -1
  85. package/dist/components/kvpList/KVPList.stories.d.ts +57 -4
  86. package/dist/components/kvpList/KVPList.stories.d.ts.map +1 -1
  87. package/dist/components/kvpList/KVPList.stories.js +403 -10
  88. package/dist/components/kvpList/KVPList.stories.js.map +1 -1
  89. package/dist/components/modal/Modal.stories.d.ts +113 -9
  90. package/dist/components/modal/Modal.stories.d.ts.map +1 -1
  91. package/dist/components/modal/Modal.stories.js +633 -13
  92. package/dist/components/modal/Modal.stories.js.map +1 -1
  93. package/dist/components/modal/modalManager/ModalManager.stories.d.ts +34 -10
  94. package/dist/components/modal/modalManager/ModalManager.stories.d.ts.map +1 -1
  95. package/dist/components/modal/modalManager/ModalManager.stories.js +463 -85
  96. package/dist/components/modal/modalManager/ModalManager.stories.js.map +1 -1
  97. package/dist/components/pill/Pill.d.ts.map +1 -1
  98. package/dist/components/pill/Pill.js +1 -1
  99. package/dist/components/pill/Pill.js.map +1 -1
  100. package/dist/components/pill/Pill.stories.d.ts.map +1 -1
  101. package/dist/components/pill/Pill.stories.js +11 -13
  102. package/dist/components/pill/Pill.stories.js.map +1 -1
  103. package/dist/components/row/Row.stories.d.ts +1 -2
  104. package/dist/components/row/Row.stories.d.ts.map +1 -1
  105. package/dist/components/row/Row.stories.js +360 -50
  106. package/dist/components/row/Row.stories.js.map +1 -1
  107. package/dist/components/searchBar/SearchBar.stories.d.ts +52 -4
  108. package/dist/components/searchBar/SearchBar.stories.d.ts.map +1 -1
  109. package/dist/components/searchBar/SearchBar.stories.js +428 -36
  110. package/dist/components/searchBar/SearchBar.stories.js.map +1 -1
  111. package/dist/components/section/Section.stories.d.ts +11 -41
  112. package/dist/components/section/Section.stories.d.ts.map +1 -1
  113. package/dist/components/section/Section.stories.js +494 -56
  114. package/dist/components/section/Section.stories.js.map +1 -1
  115. package/dist/components/singleUser/SingleUser.stories.d.ts +5 -4
  116. package/dist/components/singleUser/SingleUser.stories.d.ts.map +1 -1
  117. package/dist/components/singleUser/SingleUser.stories.js +303 -31
  118. package/dist/components/singleUser/SingleUser.stories.js.map +1 -1
  119. package/dist/components/slideoverManager/SlideoverManager.stories.d.ts +32 -11
  120. package/dist/components/slideoverManager/SlideoverManager.stories.d.ts.map +1 -1
  121. package/dist/components/slideoverManager/SlideoverManager.stories.js +380 -84
  122. package/dist/components/slideoverManager/SlideoverManager.stories.js.map +1 -1
  123. package/dist/components/table/DSDefaultColDef.d.ts.map +1 -1
  124. package/dist/components/table/DSDefaultColDef.js +4 -3
  125. package/dist/components/table/DSDefaultColDef.js.map +1 -1
  126. package/dist/components/table/Table.d.ts +6 -1
  127. package/dist/components/table/Table.d.ts.map +1 -1
  128. package/dist/components/table/Table.js +8 -3
  129. package/dist/components/table/Table.js.map +1 -1
  130. package/dist/components/table/Table.stories.d.ts +3 -0
  131. package/dist/components/table/Table.stories.d.ts.map +1 -1
  132. package/dist/components/table/Table.stories.js +384 -5
  133. package/dist/components/table/Table.stories.js.map +1 -1
  134. package/dist/components/table/Table.test.js +30 -0
  135. package/dist/components/table/Table.test.js.map +1 -1
  136. package/dist/components/table/TableFooter.stories.d.ts +49 -0
  137. package/dist/components/table/TableFooter.stories.d.ts.map +1 -0
  138. package/dist/components/table/TableFooter.stories.js +137 -0
  139. package/dist/components/table/TableFooter.stories.js.map +1 -0
  140. package/dist/components/table/TableHeader.stories.d.ts +93 -0
  141. package/dist/components/table/TableHeader.stories.d.ts.map +1 -0
  142. package/dist/components/table/TableHeader.stories.js +176 -0
  143. package/dist/components/table/TableHeader.stories.js.map +1 -0
  144. package/dist/components/table/cellEditors/DateCellEditor.stories.d.ts +44 -0
  145. package/dist/components/table/cellEditors/DateCellEditor.stories.d.ts.map +1 -0
  146. package/dist/components/table/cellEditors/DateCellEditor.stories.js +186 -0
  147. package/dist/components/table/cellEditors/DateCellEditor.stories.js.map +1 -0
  148. package/dist/components/table/cellRenderers/BooleanCellRenderer.stories.d.ts +40 -0
  149. package/dist/components/table/cellRenderers/BooleanCellRenderer.stories.d.ts.map +1 -0
  150. package/dist/components/table/cellRenderers/BooleanCellRenderer.stories.js +209 -0
  151. package/dist/components/table/cellRenderers/BooleanCellRenderer.stories.js.map +1 -0
  152. package/dist/components/table/cellRenderers/ButtonCellRenderer.stories.d.ts +48 -0
  153. package/dist/components/table/cellRenderers/ButtonCellRenderer.stories.d.ts.map +1 -0
  154. package/dist/components/table/cellRenderers/ButtonCellRenderer.stories.js +244 -0
  155. package/dist/components/table/cellRenderers/ButtonCellRenderer.stories.js.map +1 -0
  156. package/dist/components/table/cellRenderers/CheckboxCellRenderer.d.ts.map +1 -1
  157. package/dist/components/table/cellRenderers/CheckboxCellRenderer.js +3 -1
  158. package/dist/components/table/cellRenderers/CheckboxCellRenderer.js.map +1 -1
  159. package/dist/components/table/cellRenderers/CheckboxCellRenderer.stories.d.ts +64 -0
  160. package/dist/components/table/cellRenderers/CheckboxCellRenderer.stories.d.ts.map +1 -0
  161. package/dist/components/table/cellRenderers/CheckboxCellRenderer.stories.js +241 -0
  162. package/dist/components/table/cellRenderers/CheckboxCellRenderer.stories.js.map +1 -0
  163. package/dist/components/table/cellRenderers/DefaultCellRenderer.stories.d.ts +55 -0
  164. package/dist/components/table/cellRenderers/DefaultCellRenderer.stories.d.ts.map +1 -0
  165. package/dist/components/table/cellRenderers/DefaultCellRenderer.stories.js +245 -0
  166. package/dist/components/table/cellRenderers/DefaultCellRenderer.stories.js.map +1 -0
  167. package/dist/components/table/cellRenderers/InlineTextCellRenderer.stories.d.ts +67 -0
  168. package/dist/components/table/cellRenderers/InlineTextCellRenderer.stories.d.ts.map +1 -0
  169. package/dist/components/table/cellRenderers/InlineTextCellRenderer.stories.js +221 -0
  170. package/dist/components/table/cellRenderers/InlineTextCellRenderer.stories.js.map +1 -0
  171. package/dist/components/table/cellRenderers/SelectDropdownCellRenderer.stories.d.ts +75 -0
  172. package/dist/components/table/cellRenderers/SelectDropdownCellRenderer.stories.d.ts.map +1 -0
  173. package/dist/components/table/cellRenderers/SelectDropdownCellRenderer.stories.js +270 -0
  174. package/dist/components/table/cellRenderers/SelectDropdownCellRenderer.stories.js.map +1 -0
  175. package/dist/components/table/columnFilters/BooleanFilter.stories.d.ts +57 -0
  176. package/dist/components/table/columnFilters/BooleanFilter.stories.d.ts.map +1 -0
  177. package/dist/components/table/columnFilters/BooleanFilter.stories.js +198 -0
  178. package/dist/components/table/columnFilters/BooleanFilter.stories.js.map +1 -0
  179. package/dist/components/table/columnFilters/TimeFilter.stories.d.ts +58 -0
  180. package/dist/components/table/columnFilters/TimeFilter.stories.d.ts.map +1 -0
  181. package/dist/components/table/columnFilters/TimeFilter.stories.js +207 -0
  182. package/dist/components/table/columnFilters/TimeFilter.stories.js.map +1 -0
  183. package/dist/components/table/pagination/PaginationPanel.stories.d.ts +113 -0
  184. package/dist/components/table/pagination/PaginationPanel.stories.d.ts.map +1 -0
  185. package/dist/components/table/pagination/PaginationPanel.stories.js +272 -0
  186. package/dist/components/table/pagination/PaginationPanel.stories.js.map +1 -0
  187. package/dist/components/table/tableControls/HideColumnsDropdown.d.ts.map +1 -1
  188. package/dist/components/table/tableControls/HideColumnsDropdown.js +9 -3
  189. package/dist/components/table/tableControls/HideColumnsDropdown.js.map +1 -1
  190. package/dist/components/table/tableControls/TableControls.stories.d.ts +151 -0
  191. package/dist/components/table/tableControls/TableControls.stories.d.ts.map +1 -0
  192. package/dist/components/table/tableControls/TableControls.stories.js +356 -0
  193. package/dist/components/table/tableControls/TableControls.stories.js.map +1 -0
  194. package/dist/components/table/tableControls/TableSettingsDropdown.d.ts +27 -1
  195. package/dist/components/table/tableControls/TableSettingsDropdown.d.ts.map +1 -1
  196. package/dist/components/table/tableControls/TableSettingsDropdown.js +53 -26
  197. package/dist/components/table/tableControls/TableSettingsDropdown.js.map +1 -1
  198. package/dist/components/table/tableControls/TableSettingsDropdown.test.d.ts +2 -0
  199. package/dist/components/table/tableControls/TableSettingsDropdown.test.d.ts.map +1 -0
  200. package/dist/components/table/tableControls/TableSettingsDropdown.test.js +178 -0
  201. package/dist/components/table/tableControls/TableSettingsDropdown.test.js.map +1 -0
  202. package/dist/components/tabs/Tabs.stories.d.ts +22 -4
  203. package/dist/components/tabs/Tabs.stories.d.ts.map +1 -1
  204. package/dist/components/tabs/Tabs.stories.js +398 -22
  205. package/dist/components/tabs/Tabs.stories.js.map +1 -1
  206. package/dist/components/tabs/TabsItem.stories.d.ts +54 -1
  207. package/dist/components/tabs/TabsItem.stories.d.ts.map +1 -1
  208. package/dist/components/tabs/TabsItem.stories.js +61 -9
  209. package/dist/components/tabs/TabsItem.stories.js.map +1 -1
  210. package/dist/components/toast/Toast.stories.d.ts +103 -10
  211. package/dist/components/toast/Toast.stories.d.ts.map +1 -1
  212. package/dist/components/toast/Toast.stories.js +409 -47
  213. package/dist/components/toast/Toast.stories.js.map +1 -1
  214. package/dist/components/toggle/Toggle.stories.d.ts +61 -46
  215. package/dist/components/toggle/Toggle.stories.d.ts.map +1 -1
  216. package/dist/components/toggle/Toggle.stories.js +311 -122
  217. package/dist/components/toggle/Toggle.stories.js.map +1 -1
  218. package/dist/components/tooltip/Tooltip.stories.d.ts +78 -6
  219. package/dist/components/tooltip/Tooltip.stories.d.ts.map +1 -1
  220. package/dist/components/tooltip/Tooltip.stories.js +413 -7
  221. package/dist/components/tooltip/Tooltip.stories.js.map +1 -1
  222. package/dist/components/tooltip/TooltipWrapper.stories.d.ts +71 -7
  223. package/dist/components/tooltip/TooltipWrapper.stories.d.ts.map +1 -1
  224. package/dist/components/tooltip/TooltipWrapper.stories.js +238 -10
  225. package/dist/components/tooltip/TooltipWrapper.stories.js.map +1 -1
  226. package/dist/index.css +8 -0
  227. package/dist/index.css.map +1 -1
  228. package/dist/utils/PopupParentContext.stories.d.ts +17 -0
  229. package/dist/utils/PopupParentContext.stories.d.ts.map +1 -0
  230. package/dist/utils/PopupParentContext.stories.js +266 -0
  231. package/dist/utils/PopupParentContext.stories.js.map +1 -0
  232. package/dist/utils/getDefaultPopupParent.d.ts.map +1 -1
  233. package/dist/utils/getDefaultPopupParent.js +6 -0
  234. package/dist/utils/getDefaultPopupParent.js.map +1 -1
  235. package/package.json +1 -1
  236. package/src/components/articleCard/ArticleCard.stories.tsx +524 -111
  237. package/src/components/avatar/Avatar.stories.tsx +504 -59
  238. package/src/components/avatarGroup/AvatarGroup.stories.tsx +977 -175
  239. package/src/components/banner/Banner.stories.tsx +7 -3
  240. package/src/components/card/Card.stories.tsx +466 -36
  241. package/src/components/combobox/Combobox.stories.tsx +867 -260
  242. package/src/components/datePicker/DatePicker.stories.tsx +777 -60
  243. package/src/components/dateTimePicker/DateTimePicker.stories.tsx +910 -132
  244. package/src/components/editableText/EditableText.stories.tsx +567 -91
  245. package/src/components/formField/FormField.test.tsx +6 -0
  246. package/src/components/formField/FormField.tsx +5 -0
  247. package/src/components/formField/fieldset/Fieldset.stories.tsx +761 -51
  248. package/src/components/formField/inputs/checkbox/CheckboxGroup.tsx +1 -1
  249. package/src/components/formField/inputs/checkbox/CheckboxInput.tsx +1 -1
  250. package/src/components/formField/inputs/colourPickerDropdown/ColourPickerDropdown.stories.tsx +504 -11
  251. package/src/components/formField/inputs/radio/RadioButtonGroup.tsx +17 -4
  252. package/src/components/formField/inputs/radio/RadioButtonInput.stories.tsx +71 -59
  253. package/src/components/formField/inputs/selectDropdown/SelectDropdown.stories.tsx +1079 -168
  254. package/src/components/formField/inputs/time/TimeInput.stories.tsx +1140 -104
  255. package/src/components/formField/label/Label.stories.tsx +317 -8
  256. package/src/components/icoText/IcoText.stories.tsx +442 -31
  257. package/src/components/kpiCard/KPICard.stories.tsx +475 -30
  258. package/src/components/kvpList/KVPList.stories.tsx +593 -26
  259. package/src/components/modal/Modal.stories.tsx +963 -26
  260. package/src/components/modal/modalManager/ModalManager.stories.tsx +612 -454
  261. package/src/components/pill/Pill.stories.tsx +11 -13
  262. package/src/components/pill/Pill.tsx +1 -0
  263. package/src/components/row/Row.stories.tsx +474 -58
  264. package/src/components/searchBar/SearchBar.stories.tsx +570 -38
  265. package/src/components/section/Section.stories.tsx +723 -70
  266. package/src/components/singleUser/SingleUser.stories.tsx +393 -34
  267. package/src/components/slideoverManager/SlideoverManager.stories.tsx +572 -342
  268. package/src/components/table/DSDefaultColDef.ts +25 -5
  269. package/src/components/table/Table.stories.tsx +460 -5
  270. package/src/components/table/Table.test.tsx +53 -0
  271. package/src/components/table/Table.tsx +9 -2
  272. package/src/components/table/TableFooter.stories.tsx +196 -0
  273. package/src/components/table/TableHeader.stories.tsx +251 -0
  274. package/src/components/table/cellEditors/DateCellEditor.stories.tsx +245 -0
  275. package/src/components/table/cellRenderers/BooleanCellRenderer.stories.tsx +278 -0
  276. package/src/components/table/cellRenderers/ButtonCellRenderer.stories.tsx +333 -0
  277. package/src/components/table/cellRenderers/CheckboxCellRenderer.stories.tsx +337 -0
  278. package/src/components/table/cellRenderers/CheckboxCellRenderer.tsx +5 -1
  279. package/src/components/table/cellRenderers/DefaultCellRenderer.stories.tsx +342 -0
  280. package/src/components/table/cellRenderers/InlineTextCellRenderer.stories.tsx +292 -0
  281. package/src/components/table/cellRenderers/SelectDropdownCellRenderer.stories.tsx +369 -0
  282. package/src/components/table/columnFilters/BooleanFilter.stories.tsx +268 -0
  283. package/src/components/table/columnFilters/TimeFilter.stories.tsx +281 -0
  284. package/src/components/table/pagination/PaginationPanel.stories.tsx +327 -0
  285. package/src/components/table/tableControls/HideColumnsDropdown.tsx +11 -2
  286. package/src/components/table/tableControls/TableControls.stories.tsx +415 -0
  287. package/src/components/table/tableControls/TableSettingsDropdown.test.tsx +207 -0
  288. package/src/components/table/tableControls/TableSettingsDropdown.tsx +103 -39
  289. package/src/components/tabs/Tabs.stories.tsx +540 -60
  290. package/src/components/tabs/TabsItem.stories.tsx +82 -8
  291. package/src/components/toast/Toast.stories.tsx +539 -77
  292. package/src/components/toggle/Toggle.stories.tsx +371 -135
  293. package/src/components/tooltip/Tooltip.stories.tsx +606 -15
  294. package/src/components/tooltip/TooltipWrapper.stories.tsx +348 -12
  295. package/src/docs/Contributing.mdx +241 -0
  296. package/src/docs/UsingComponents.mdx +93 -0
  297. package/src/docs/Welcome.mdx +68 -0
  298. package/src/global.scss +7 -0
  299. package/src/utils/PopupParentContext.stories.tsx +367 -0
  300. package/src/utils/getDefaultPopupParent.ts +6 -0
  301. package/.ralph/storybook-upgrade/knowledge.md +0 -308
  302. package/.ralph/storybook-upgrade/prd.json +0 -777
  303. package/.ralph/storybook-upgrade/progress.md +0 -342
  304. package/src/components/table/TableWIP.mdx +0 -3
@@ -1,374 +1,604 @@
1
- import type { Meta, StoryObj } from '@storybook/react';
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import {
3
+ Heading as DocHeading,
4
+ Markdown,
5
+ Stories,
6
+ Subtitle,
7
+ Title,
8
+ } from '@storybook/addon-docs/blocks';
2
9
  import { SlideoverManager } from './SlideoverManager';
3
- import { SlideoverUtils } from '../../utils/SlideoverUtils';
4
- import { Button } from '../button/Button';
5
- import { Section } from '../section/Section';
6
- import { FormField } from '../formField/FormField';
7
- import { generateUuid } from '../../utils/generateUuid';
8
- import { allowedIcons, type IconName } from '../icon/allowedIcons';
10
+ import { SlideoverUtils } from 'Utils/SlideoverUtils';
11
+ import { Button } from 'Components/button/Button';
12
+ import { FormField } from 'Components/formField/FormField';
13
+ import { Section } from 'Components/section/Section';
9
14
 
10
- type SlideoverStoryArgs = {
11
- headerIcon?: IconName;
12
- centerHeaderText?: boolean;
13
- };
15
+ // ---------------------------------------------------------------------------
16
+ // Docs page content
17
+ // ---------------------------------------------------------------------------
14
18
 
15
- const meta: Meta<SlideoverStoryArgs> = {
19
+ const DESCRIPTION_INTRO = [
20
+ '`SlideoverManager` is a container that manages a **stack** of slideover panels.',
21
+ 'Mount it once near the root of your application and push slideovers onto the stack via `SlideoverUtils.addSlideover()`.',
22
+ 'The built-in **Back** button pops the top panel, enabling drill-down navigation patterns.',
23
+ ].join(' ');
24
+
25
+ const USAGE_GUIDANCE = [
26
+ '### When to use',
27
+ '',
28
+ '- **Editing a record** while keeping the parent list visible in context',
29
+ '- **Detail panels** — viewing supplementary information without a full-page navigation',
30
+ '- **Drill-down flows** — e.g. Pupil → Assessments → Edit Assessment (stacked panels)',
31
+ '',
32
+ '---',
33
+ '',
34
+ '### When NOT to use',
35
+ '',
36
+ '| Situation | Use instead |',
37
+ '|---|---|',
38
+ '| A short confirmation or irreversible action | [`Modal`](?path=/docs/components-modals-modal--docs) — modals are better for blocking decisions |',
39
+ '| Navigation to a distinct page/route | Standard page navigation |',
40
+ '| A floating menu or dropdown | [`Dropdown`](?path=/docs/components-dropdown--docs) |',
41
+ '',
42
+ '---',
43
+ '',
44
+ '### `SlideoverProps` — what goes inside each panel',
45
+ '',
46
+ '| Prop | Type | Default | Description |',
47
+ '|---|---|---|---|',
48
+ '| `title` | `string` | — | Header title text |',
49
+ '| `children` | `ReactNode` | — | Main scrollable content |',
50
+ '| `footerContents` | `ReactNode` | — | Sticky footer — use for primary actions (Save / Cancel) |',
51
+ '| `headerIcon` | `IconName` | — | Icon rendered next to the title |',
52
+ '| `centerHeaderText` | `boolean` | `true` | Whether the header text is centred |',
53
+ '| `hideBackButton` | `boolean` | — | Hides the Back chevron button in the header |',
54
+ '',
55
+ '---',
56
+ '',
57
+ '### `SlideoverManager` props',
58
+ '',
59
+ '| Prop | Type | Default | Description |',
60
+ '|---|---|---|---|',
61
+ '| `slideovers` | `SlideoverProps[]` | — | Initial stack of slideovers to mount pre-opened |',
62
+ ].join('\n');
63
+
64
+ const DEVELOPER_NOTES = [
65
+ '### Setup — mount once at the app root',
66
+ '',
67
+ '`SlideoverManager` must be mounted **once** near the root of your application.',
68
+ 'It subscribes to global PubSub events — mounting multiple instances means all receive the same events,',
69
+ 'causing duplicate slideovers.',
70
+ '',
71
+ '```tsx',
72
+ '// App root',
73
+ 'function App() {',
74
+ ' return (',
75
+ ' <div>',
76
+ ' <SlideoverManager slideovers={[]} />',
77
+ ' <YourRouter />',
78
+ ' </div>',
79
+ ' );',
80
+ '}',
81
+ '```',
82
+ '',
83
+ '---',
84
+ '',
85
+ '### Pushing and popping slideovers',
86
+ '',
87
+ '```ts',
88
+ "import { SlideoverUtils } from '@arbor-education/design-system.components';",
89
+ '',
90
+ '// Push a new panel onto the stack',
91
+ 'SlideoverUtils.addSlideover({',
92
+ " title: 'Edit Pupil',",
93
+ ' children: <EditPupilForm />,',
94
+ ' footerContents: (',
95
+ ' <>',
96
+ ' <Button variant="secondary" onClick={SlideoverUtils.removeSlideover}>Cancel</Button>',
97
+ ' <Button onClick={handleSave}>Save</Button>',
98
+ ' </>',
99
+ ' ),',
100
+ '});',
101
+ '',
102
+ '// Pop the top panel',
103
+ 'SlideoverUtils.removeSlideover();',
104
+ '',
105
+ '// Clear the entire stack',
106
+ 'SlideoverUtils.removeAllSlideovers();',
107
+ '```',
108
+ '',
109
+ '---',
110
+ '',
111
+ '### Stacking behaviour',
112
+ '',
113
+ 'Each `SlideoverUtils.addSlideover()` call pushes a new panel on top of the current one.',
114
+ 'The **Back** button (rendered automatically in each header) calls `SlideoverUtils.removeSlideover()` to pop the top panel.',
115
+ 'Set `hideBackButton={true}` on panels that should not allow the user to go back — use your own close action instead.',
116
+ '',
117
+ '---',
118
+ '',
119
+ '### Accessibility',
120
+ '',
121
+ '- The overlay dims the background and traps focus inside the active slideover panel.',
122
+ '- The Back button is keyboard accessible and labelled.',
123
+ '- Ensure the `title` prop is always set — it is the visible and accessible heading for the panel.',
124
+ ].join('\n');
125
+
126
+ const RELATED_COMPONENTS = [
127
+ '## Related components',
128
+ '',
129
+ '[Modal](?path=/docs/components-modals-modal--docs) · [ModalManager](?path=/docs/components-modals-modalmanager--docs) · [Section](?path=/docs/components-section--docs) · [Button](?path=/docs/components-button--docs)',
130
+ ].join('\n');
131
+
132
+ // ---------------------------------------------------------------------------
133
+ // Docs page
134
+ // ---------------------------------------------------------------------------
135
+
136
+ function SlideoverManagerDocsPage() {
137
+ return (
138
+ <>
139
+ <Title />
140
+ <Subtitle />
141
+ <Markdown>{DESCRIPTION_INTRO}</Markdown>
142
+ <DocHeading>Usage guidance</DocHeading>
143
+ <Markdown>{USAGE_GUIDANCE}</Markdown>
144
+ <DocHeading>Developer notes</DocHeading>
145
+ <Markdown>{DEVELOPER_NOTES}</Markdown>
146
+ <DocHeading>Examples</DocHeading>
147
+ <Stories title="" />
148
+ <Markdown>{RELATED_COMPONENTS}</Markdown>
149
+ </>
150
+ );
151
+ }
152
+
153
+ // ---------------------------------------------------------------------------
154
+ // Meta
155
+ // ---------------------------------------------------------------------------
156
+
157
+ const meta = {
16
158
  title: 'Components/SlideoverManager',
159
+ component: SlideoverManager,
160
+ tags: ['autodocs'],
17
161
  parameters: {
18
162
  layout: 'fullscreen',
163
+ docs: {
164
+ page: SlideoverManagerDocsPage,
165
+ },
19
166
  },
20
167
  argTypes: {
21
- headerIcon: {
22
- control: { type: 'select' },
23
- options: Object.keys(allowedIcons),
24
- description: 'Icon to display in the slideover header',
168
+ slideovers: {
169
+ control: false,
170
+ description: 'Initial stack of `SlideoverProps` to display on mount. Pass `[]` for the standard programmatic use case.',
171
+ table: {
172
+ type: { summary: 'SlideoverProps[]' },
173
+ defaultValue: { summary: '[]' },
174
+ },
25
175
  },
26
- centerHeaderText: {
27
- control: { type: 'boolean' },
28
- description: 'Whether to center the header text',
29
- },
30
- },
31
- args: {
32
- centerHeaderText: true,
33
176
  },
34
- decorators: [
35
- Story => (
36
- <div>
37
- <Story />
38
- <div style={{ padding: '1rem' }}>
39
- <p>
40
- The SlideoverManager is a container that manages the display of slideovers. It listens for events to add or remove slideovers.
41
- </p>
42
- <p>
43
- Use the buttons below to add slideovers with different content.
44
- </p>
45
- </div>
46
- </div>
47
- ),
48
- ],
49
- };
177
+ } satisfies Meta<typeof SlideoverManager>;
50
178
 
51
179
  export default meta;
180
+ type Story = StoryObj<typeof meta>;
181
+
182
+ // ---------------------------------------------------------------------------
183
+ // Helper
184
+ // ---------------------------------------------------------------------------
185
+
186
+ const withDescription = (story: Omit<Story, 'args'>, description: string): Story => ({
187
+ ...(story as Story),
188
+ parameters: {
189
+ ...story.parameters,
190
+ docs: {
191
+ ...story.parameters?.docs,
192
+ description: {
193
+ story: description,
194
+ },
195
+ },
196
+ },
197
+ });
52
198
 
53
- type Story = StoryObj<SlideoverStoryArgs>;
199
+ // ---------------------------------------------------------------------------
200
+ // Page wrapper used in all templates
201
+ // ---------------------------------------------------------------------------
54
202
 
55
- let slideoverCount = 0;
203
+ const PageBackground = ({ children }: { children: React.ReactNode }) => (
204
+ <div style={{ padding: 'var(--spacing-xlarge)', minHeight: '100vh', background: 'var(--color-grey-050)' }}>
205
+ <h1 style={{ margin: '0 0 var(--spacing-large)', fontSize: 'var(--font-size-5-18)', fontWeight: 600 }}>
206
+ Pupil List
207
+ </h1>
208
+ <p style={{ margin: '0 0 var(--spacing-large)', color: 'var(--color-grey-600)' }}>
209
+ Click the button below to open a slideover panel.
210
+ </p>
211
+ {children}
212
+ </div>
213
+ );
56
214
 
57
- const addSlideoverWithContent = (content: React.ReactNode, headerIcon?: IconName, centerHeaderText?: boolean) => {
58
- slideoverCount++;
59
- SlideoverUtils.addSlideover({
60
- title: `Slideover ${slideoverCount}`,
61
- children: content,
62
- headerIcon,
63
- centerHeaderText,
64
- });
65
- };
215
+ // ---------------------------------------------------------------------------
216
+ // Templates
217
+ // ---------------------------------------------------------------------------
66
218
 
67
- const removeSlideover = () => {
68
- if (slideoverCount > 0) {
69
- slideoverCount--;
70
- }
71
- SlideoverUtils.removeSlideover();
72
- };
219
+ const DefaultTemplate = () => (
220
+ <PageBackground>
221
+ <SlideoverManager slideovers={[]} />
222
+ <div style={{ display: 'flex', gap: 'var(--spacing-small)' }}>
223
+ <Button
224
+ onClick={() =>
225
+ SlideoverUtils.addSlideover({
226
+ title: 'Pupil Record',
227
+ children: (
228
+ <p>Select a pupil from the list to view their record here.</p>
229
+ ),
230
+ })}
231
+ >
232
+ Open slideover
233
+ </Button>
234
+ <Button variant="secondary" onClick={SlideoverUtils.removeSlideover}>
235
+ Remove last
236
+ </Button>
237
+ <Button variant="primary-destructive" onClick={SlideoverUtils.removeAllSlideovers}>
238
+ Close all
239
+ </Button>
240
+ </div>
241
+ </PageBackground>
242
+ );
73
243
 
74
- const removeAllSlideovers = () => {
75
- slideoverCount = 0;
76
- SlideoverUtils.removeAllSlideovers();
77
- };
244
+ const WithFooterActionsTemplate = () => (
245
+ <PageBackground>
246
+ <SlideoverManager slideovers={[]} />
247
+ <Button
248
+ onClick={() =>
249
+ SlideoverUtils.addSlideover({
250
+ title: 'Edit Pupil Details',
251
+ children: (
252
+ <Section title="Personal details">
253
+ <FormField
254
+ id="pupil-name"
255
+ label="Full name"
256
+ inputType="text"
257
+ inputProps={{ placeholder: 'e.g. Alex Johnson', defaultValue: 'Alex Johnson' }}
258
+ />
259
+ <FormField
260
+ id="pupil-dob"
261
+ label="Date of birth"
262
+ inputType="text"
263
+ inputProps={{ placeholder: 'DD/MM/YYYY', defaultValue: '12/03/2015' }}
264
+ />
265
+ <FormField
266
+ id="pupil-year"
267
+ label="Year group"
268
+ inputType="text"
269
+ inputProps={{ defaultValue: 'Year 5' }}
270
+ />
271
+ </Section>
272
+ ),
273
+ footerContents: (
274
+ <div style={{ display: 'flex', gap: 'var(--spacing-small)', justifyContent: 'flex-end' }}>
275
+ <Button variant="secondary" onClick={SlideoverUtils.removeSlideover}>
276
+ Cancel
277
+ </Button>
278
+ <Button onClick={SlideoverUtils.removeSlideover}>
279
+ Save changes
280
+ </Button>
281
+ </div>
282
+ ),
283
+ })}
284
+ >
285
+ Edit pupil details
286
+ </Button>
287
+ </PageBackground>
288
+ );
78
289
 
79
- export const Default: Story = {
80
- render: args => (
81
- <>
290
+ const StackedSlideoverTemplate = () => (
291
+ <PageBackground>
292
+ <SlideoverManager slideovers={[]} />
293
+ <Button
294
+ onClick={() =>
295
+ SlideoverUtils.addSlideover({
296
+ title: 'Pupil: Alex Johnson',
297
+ children: (
298
+ <Section title="Assessments">
299
+ <p style={{ margin: '0 0 var(--spacing-medium)' }}>
300
+ 3 assessments recorded this term.
301
+ </p>
302
+ <Button
303
+ variant="secondary"
304
+ onClick={() =>
305
+ SlideoverUtils.addSlideover({
306
+ title: 'Edit Assessment',
307
+ children: (
308
+ <>
309
+ <FormField
310
+ id="assessment-name"
311
+ label="Assessment name"
312
+ inputType="text"
313
+ inputProps={{ defaultValue: 'Autumn Reading Assessment' }}
314
+ />
315
+ <FormField
316
+ id="assessment-score"
317
+ label="Score"
318
+ inputType="number"
319
+ inputProps={{ defaultValue: '78', min: 0, max: 100 }}
320
+ />
321
+ <FormField
322
+ id="assessment-notes"
323
+ label="Notes"
324
+ inputType="textarea"
325
+ inputProps={{ placeholder: 'Add a note…' }}
326
+ />
327
+ </>
328
+ ),
329
+ footerContents: (
330
+ <div style={{ display: 'flex', gap: 'var(--spacing-small)', justifyContent: 'flex-end' }}>
331
+ <Button variant="secondary" onClick={SlideoverUtils.removeSlideover}>
332
+ Cancel
333
+ </Button>
334
+ <Button onClick={SlideoverUtils.removeSlideover}>
335
+ Save
336
+ </Button>
337
+ </div>
338
+ ),
339
+ })}
340
+ >
341
+ Edit latest assessment
342
+ </Button>
343
+ </Section>
344
+ ),
345
+ })}
346
+ >
347
+ View pupil record
348
+ </Button>
349
+ </PageBackground>
350
+ );
351
+
352
+ const HideBackButtonTemplate = () => (
353
+ <PageBackground>
354
+ <SlideoverManager slideovers={[]} />
355
+ <Button
356
+ onClick={() =>
357
+ SlideoverUtils.addSlideover({
358
+ title: 'Confirm deletion',
359
+ hideBackButton: true,
360
+ children: (
361
+ <p>
362
+ Are you sure you want to remove
363
+ {' '}
364
+ <strong>Alex Johnson</strong>
365
+ {' '}
366
+ from Year 5?
367
+ This cannot be undone.
368
+ </p>
369
+ ),
370
+ footerContents: (
371
+ <div style={{ display: 'flex', gap: 'var(--spacing-small)', justifyContent: 'flex-end' }}>
372
+ <Button variant="secondary" onClick={SlideoverUtils.removeSlideover}>
373
+ Cancel
374
+ </Button>
375
+ <Button variant="primary-destructive" onClick={SlideoverUtils.removeSlideover}>
376
+ Remove pupil
377
+ </Button>
378
+ </div>
379
+ ),
380
+ })}
381
+ >
382
+ Remove pupil
383
+ </Button>
384
+ </PageBackground>
385
+ );
386
+
387
+ // ---------------------------------------------------------------------------
388
+ // Stories
389
+ // ---------------------------------------------------------------------------
390
+
391
+ export const Default: Story = withDescription(
392
+ {
393
+ render: DefaultTemplate,
394
+ parameters: {
395
+ controls: { disable: true },
396
+ docs: {
397
+ source: {
398
+ language: 'tsx',
399
+ code: `
400
+ import { SlideoverManager, SlideoverUtils } from '@arbor-education/design-system.components';
401
+
402
+ // Mount SlideoverManager once near your app root.
403
+ // Then call SlideoverUtils.addSlideover() from anywhere in the tree.
404
+ function AppRoot() {
405
+ return (
406
+ <div>
82
407
  <SlideoverManager slideovers={[]} />
83
- <div style={{ padding: '1rem', display: 'flex', gap: '1rem' }}>
84
- <Button
408
+ <main>
409
+ <button
410
+ type="button"
85
411
  onClick={() =>
86
- addSlideoverWithContent(<p>This is a simple slideover.</p>, args.headerIcon, args.centerHeaderText)}
412
+ SlideoverUtils.addSlideover({
413
+ title: 'Pupil Record',
414
+ children: <p>Pupil details go here.</p>,
415
+ })
416
+ }
87
417
  >
88
- Add Simple Slideover
89
- </Button>
90
- <Button onClick={removeSlideover} variant="secondary">
91
- Remove Last Slideover
92
- </Button>
93
- <Button onClick={removeAllSlideovers} variant="primary-destructive">
94
- Remove All
95
- </Button>
96
- </div>
97
- </>
98
- ),
99
- };
418
+ Open slideover
419
+ </button>
420
+ </main>
421
+ </div>
422
+ );
423
+ }
424
+ export default AppRoot;
425
+ `.trim(),
426
+ },
427
+ },
428
+ },
429
+ },
430
+ [
431
+ 'Mount `SlideoverManager` once near the root of your application.',
432
+ 'Then call `SlideoverUtils.addSlideover()` from anywhere — event handlers, Redux actions, or any component in the tree.',
433
+ 'The **Back** button in the panel header calls `SlideoverUtils.removeSlideover()` automatically.',
434
+ ].join(' '),
435
+ );
100
436
 
101
- export const WithSections: Story = {
102
- render: args => (
437
+ export const WithFooterActions: Story = withDescription(
438
+ {
439
+ render: WithFooterActionsTemplate,
440
+ parameters: {
441
+ controls: { disable: true },
442
+ docs: {
443
+ source: {
444
+ language: 'tsx',
445
+ code: `
446
+ import { Button, FormField, Section, SlideoverManager, SlideoverUtils } from '@arbor-education/design-system.components';
447
+
448
+ function EditPupilButton() {
449
+ return (
103
450
  <>
104
451
  <SlideoverManager slideovers={[]} />
105
- <div style={{ padding: '1rem', display: 'flex', gap: '1rem' }}>
106
- <Button
107
- onClick={() =>
108
- addSlideoverWithContent(
109
- <>
110
- <Section title="Section 1" collapsible>
111
- <p>Aliquip ea tempor officia irure do qui culpa. Laborum proident laboris aliqua ad Lorem eiusmod fugiat dolore qui occaecat adipisicing. Dolore quis nisi occaecat commodo labore ad nulla aliquip in. Enim labore nisi laborum nostrud officia ad nulla ut quis. Aute excepteur quis amet aliquip. Excepteur Lorem cupidatat adipisicing consectetur ipsum Lorem. Deserunt dolor veniam sit mollit elit aliquip duis.</p>
112
- </Section>
113
- <Section title="Section 2" collapsible collapsed>
114
- <p>Veniam adipisicing culpa id esse duis in officia consequat veniam ad ullamco sint sunt anim. Incididunt exercitation dolor Lorem anim aute ad deserunt. Nulla culpa sint aliqua ea Lorem sint. Elit sit consectetur minim cillum consectetur pariatur Lorem labore consectetur nisi consectetur officia exercitation. Est consectetur commodo deserunt ipsum aliqua occaecat qui sunt consectetur.</p>
115
- </Section>
116
- </>,
117
- args.headerIcon,
118
- args.centerHeaderText,
119
- )}
120
- >
121
- Add Slideover with Sections
122
- </Button>
123
- <Button onClick={removeSlideover} variant="secondary">
124
- Remove Last Slideover
125
- </Button>
126
- <Button onClick={removeAllSlideovers} variant="primary-destructive">
127
- Remove All
128
- </Button>
129
- </div>
452
+ <Button
453
+ onClick={() =>
454
+ SlideoverUtils.addSlideover({
455
+ title: 'Edit Pupil Details',
456
+ children: (
457
+ <Section title="Personal details">
458
+ <FormField id="pupil-name" label="Full name" inputType="text" inputProps={{ placeholder: 'e.g. Alex Johnson' }} />
459
+ <FormField id="pupil-dob" label="Date of birth" inputType="text" inputProps={{ placeholder: 'DD/MM/YYYY' }} />
460
+ </Section>
461
+ ),
462
+ footerContents: (
463
+ <div style={{ display: 'flex', gap: 'var(--spacing-small)', justifyContent: 'flex-end' }}>
464
+ <Button variant="secondary" onClick={SlideoverUtils.removeSlideover}>
465
+ Cancel
466
+ </Button>
467
+ <Button onClick={() => { /* save logic */ SlideoverUtils.removeSlideover(); }}>
468
+ Save changes
469
+ </Button>
470
+ </div>
471
+ ),
472
+ })
473
+ }
474
+ >
475
+ Edit pupil details
476
+ </Button>
130
477
  </>
131
- ),
132
- };
133
-
134
- export const WithFormFields: Story = {
135
- render: (args) => {
136
- const formFieldId = generateUuid();
137
- return (
138
- <>
139
- <SlideoverManager slideovers={[]} />
140
- <div style={{ padding: '1rem', display: 'flex', gap: '1rem' }}>
141
- <Button
142
- onClick={() =>
143
- addSlideoverWithContent(
144
- <>
145
- <FormField
146
- id={formFieldId}
147
- label="Your Name"
148
- inputType="text"
149
- inputProps={{ placeholder: 'e.g. Jane Doe' }}
150
- fieldDescription="Please enter your full name."
151
- />
152
- </>,
153
- args.headerIcon,
154
- args.centerHeaderText,
155
- )}
156
- >
157
- Add Slideover with Form
158
- </Button>
159
- <Button onClick={removeSlideover} variant="secondary">
160
- Remove Last Slideover
161
- </Button>
162
- <Button onClick={removeAllSlideovers} variant="primary-destructive">
163
- Remove All
164
- </Button>
165
- </div>
166
- </>
167
- );
478
+ );
479
+ }
480
+ export default EditPupilButton;
481
+ `.trim(),
482
+ },
483
+ },
484
+ },
168
485
  },
169
- };
486
+ [
487
+ 'Pass `footerContents` to render a sticky footer with action buttons.',
488
+ 'Use `SlideoverUtils.removeSlideover()` in your Save and Cancel handlers to close the panel after the action completes.',
489
+ ].join(' '),
490
+ );
170
491
 
171
- export const WithFooterContent: Story = {
172
- render: (args) => {
173
- const handleSave = () => {
174
- alert('Save clicked!');
175
- SlideoverUtils.removeSlideover();
176
- };
492
+ export const StackedSlideovers: Story = withDescription(
493
+ {
494
+ render: StackedSlideoverTemplate,
495
+ parameters: {
496
+ controls: { disable: true },
497
+ docs: {
498
+ source: {
499
+ language: 'tsx',
500
+ code: `
501
+ import { Button, FormField, Section, SlideoverManager, SlideoverUtils } from '@arbor-education/design-system.components';
177
502
 
178
- const handleCancel = () => {
179
- SlideoverUtils.removeSlideover();
180
- };
181
-
182
- const footerContent = (
183
- <div style={{ display: 'flex', gap: '1rem', justifyContent: 'flex-end' }}>
184
- <Button variant="secondary" onClick={handleCancel}>
185
- Cancel
186
- </Button>
187
- <Button variant="primary" onClick={handleSave}>
188
- Save Changes
189
- </Button>
190
- </div>
191
- );
192
-
193
- return (
194
- <>
195
- <SlideoverManager slideovers={[]} />
196
- <div style={{ padding: '1rem', display: 'flex', gap: '1rem' }}>
197
- <Button
198
- onClick={() => {
199
- slideoverCount++;
200
- SlideoverUtils.addSlideover({
201
- title: `Slideover ${slideoverCount}`,
202
- children: (
203
- <>
204
- <Section title="Edit Settings">
205
- <FormField
206
- id={generateUuid()}
207
- label="Setting Name"
208
- inputType="text"
209
- inputProps={{ placeholder: 'Enter setting name' }}
210
- />
211
- <FormField
212
- id={generateUuid()}
213
- label="Description"
214
- inputType="textarea"
215
- inputProps={{ placeholder: 'Enter description', rows: 4 }}
216
- />
217
- </Section>
218
- </>
219
- ),
220
- footerContents: footerContent,
221
- headerIcon: args.headerIcon,
222
- centerHeaderText: args.centerHeaderText,
223
- });
224
- }}
225
- >
226
- Add Slideover with Footer
227
- </Button>
228
- <Button onClick={removeSlideover} variant="secondary">
229
- Remove Last Slideover
230
- </Button>
231
- <Button onClick={removeAllSlideovers} variant="primary-destructive">
232
- Remove All
233
- </Button>
234
- </div>
235
- </>
236
- );
503
+ // Each addSlideover() call stacks a new panel on top.
504
+ // The Back button in each header pops the top panel.
505
+ function PupilDrillDown() {
506
+ return (
507
+ <>
508
+ <SlideoverManager slideovers={[]} />
509
+ <Button
510
+ onClick={() =>
511
+ SlideoverUtils.addSlideover({
512
+ title: 'Pupil: Alex Johnson',
513
+ children: (
514
+ <Section title="Assessments">
515
+ <Button
516
+ variant="secondary"
517
+ onClick={() =>
518
+ SlideoverUtils.addSlideover({
519
+ title: 'Edit Assessment',
520
+ children: (
521
+ <FormField id="score" label="Score" inputType="number" inputProps={{ defaultValue: '78' }} />
522
+ ),
523
+ footerContents: (
524
+ <Button onClick={SlideoverUtils.removeSlideover}>Save</Button>
525
+ ),
526
+ })
527
+ }
528
+ >
529
+ Edit latest assessment
530
+ </Button>
531
+ </Section>
532
+ ),
533
+ })
534
+ }
535
+ >
536
+ View pupil record
537
+ </Button>
538
+ </>
539
+ );
540
+ }
541
+ export default PupilDrillDown;
542
+ `.trim(),
543
+ },
544
+ },
545
+ },
237
546
  },
238
- };
547
+ [
548
+ 'Each `SlideoverUtils.addSlideover()` call stacks a new panel on top of the current one.',
549
+ 'The user can drill down through related records and navigate back with the **Back** button.',
550
+ 'This is the primary pattern for Pupil → Assessment → Edit flows in Arbor.',
551
+ ].join(' '),
552
+ );
239
553
 
240
- export const WithScrollableContent: Story = {
241
- render: (args) => {
242
- const footerContent = (
243
- <div style={{ display: 'flex', gap: '1rem', justifyContent: 'flex-end' }}>
244
- <Button variant="secondary" onClick={SlideoverUtils.removeSlideover}>
245
- Cancel
246
- </Button>
247
- <Button variant="primary" onClick={SlideoverUtils.removeSlideover}>
248
- Save
249
- </Button>
250
- </div>
251
- );
554
+ export const HideBackButton: Story = withDescription(
555
+ {
556
+ render: HideBackButtonTemplate,
557
+ parameters: {
558
+ controls: { disable: true },
559
+ docs: {
560
+ source: {
561
+ language: 'tsx',
562
+ code: `
563
+ import { Button, SlideoverManager, SlideoverUtils } from '@arbor-education/design-system.components';
252
564
 
253
- return (
254
- <>
255
- <SlideoverManager slideovers={[]} />
256
- <div style={{ padding: '1rem', display: 'flex', gap: '1rem' }}>
257
- <Button
258
- onClick={() => {
259
- slideoverCount++;
260
- SlideoverUtils.addSlideover({
261
- title: `Slideover ${slideoverCount}`,
262
- children: (
263
- <>
264
- <Section title="Section 1" collapsible>
265
- <p>
266
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
267
- Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
268
- </p>
269
- <FormField
270
- id={generateUuid()}
271
- label="Field 1"
272
- inputType="text"
273
- inputProps={{ placeholder: 'Enter value' }}
274
- />
275
- <FormField
276
- id={generateUuid()}
277
- label="Field 2"
278
- inputType="text"
279
- inputProps={{ placeholder: 'Enter value' }}
280
- />
281
- </Section>
282
- <Section title="Section 2" collapsible>
283
- <p>
284
- Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
285
- Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
286
- </p>
287
- <FormField
288
- id={generateUuid()}
289
- label="Field 3"
290
- inputType="textarea"
291
- inputProps={{ placeholder: 'Enter long text', rows: 6 }}
292
- />
293
- </Section>
294
- <Section title="Section 3" collapsible>
295
- <p>
296
- Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium,
297
- totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.
298
- </p>
299
- <FormField
300
- id={generateUuid()}
301
- label="Field 4"
302
- inputType="number"
303
- inputProps={{ placeholder: 'Enter number' }}
304
- />
305
- <FormField
306
- id={generateUuid()}
307
- label="Field 5"
308
- inputType="text"
309
- inputProps={{ placeholder: 'Enter value' }}
310
- />
311
- </Section>
312
- <Section title="Section 4" collapsible>
313
- <p>
314
- Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores
315
- eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet.
316
- </p>
317
- <FormField
318
- id={generateUuid()}
319
- label="Field 6"
320
- inputType="text"
321
- inputProps={{ placeholder: 'Enter value' }}
322
- />
323
- </Section>
324
- <Section title="Section 5" collapsible>
325
- <p>
326
- At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque
327
- corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident.
328
- </p>
329
- <FormField
330
- id={generateUuid()}
331
- label="Field 7"
332
- inputType="textarea"
333
- inputProps={{ placeholder: 'Enter description', rows: 4 }}
334
- />
335
- <FormField
336
- id={generateUuid()}
337
- label="Field 8"
338
- inputType="text"
339
- inputProps={{ placeholder: 'Enter value' }}
340
- />
341
- </Section>
342
- <Section title="Section 6" collapsible collapsed>
343
- <p>
344
- Similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga.
345
- Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio.
346
- </p>
347
- <FormField
348
- id={generateUuid()}
349
- label="Field 9"
350
- inputType="text"
351
- inputProps={{ placeholder: 'Enter value' }}
352
- />
353
- </Section>
354
- </>
355
- ),
356
- footerContents: footerContent,
357
- headerIcon: args.headerIcon,
358
- centerHeaderText: args.centerHeaderText,
359
- });
360
- }}
361
- >
362
- Add Slideover with Scrollable Content
363
- </Button>
364
- <Button onClick={removeSlideover} variant="secondary">
365
- Remove Last Slideover
366
- </Button>
367
- <Button onClick={removeAllSlideovers} variant="primary-destructive">
368
- Remove All
369
- </Button>
370
- </div>
371
- </>
372
- );
565
+ // hideBackButton prevents the user navigating back — use when the action must be
566
+ // explicitly confirmed or cancelled, not dismissed by accident.
567
+ function RemovePupilButton() {
568
+ return (
569
+ <>
570
+ <SlideoverManager slideovers={[]} />
571
+ <Button
572
+ variant="primary-destructive"
573
+ onClick={() =>
574
+ SlideoverUtils.addSlideover({
575
+ title: 'Confirm deletion',
576
+ hideBackButton: true,
577
+ children: (
578
+ <p>Are you sure you want to remove Alex Johnson from Year 5?</p>
579
+ ),
580
+ footerContents: (
581
+ <div style={{ display: 'flex', gap: 'var(--spacing-small)', justifyContent: 'flex-end' }}>
582
+ <Button variant="secondary" onClick={SlideoverUtils.removeSlideover}>Cancel</Button>
583
+ <Button variant="primary-destructive" onClick={SlideoverUtils.removeSlideover}>Remove pupil</Button>
584
+ </div>
585
+ ),
586
+ })
587
+ }
588
+ >
589
+ Remove pupil
590
+ </Button>
591
+ </>
592
+ );
593
+ }
594
+ export default RemovePupilButton;
595
+ `.trim(),
596
+ },
597
+ },
598
+ },
373
599
  },
374
- };
600
+ [
601
+ 'Set `hideBackButton={true}` when the panel represents an action the user must explicitly confirm or cancel.',
602
+ 'Without a Back button, the user must interact with the footer actions — reducing accidental dismissal.',
603
+ ].join(' '),
604
+ );