@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,92 +1,537 @@
1
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
+
2
12
  import { Avatar } from './Avatar';
3
13
 
14
+ // ---------------------------------------------------------------------------
15
+ // Content strings
16
+ // ---------------------------------------------------------------------------
17
+
18
+ const DESCRIPTION_INTRO = [
19
+ '`Avatar` displays a visual identity for a person — a photograph, a set of initials, or a',
20
+ 'fallback silhouette — in a consistently-sized, circular container.',
21
+ 'It is the foundational building block for staff lists, pupil profiles, message threads,',
22
+ 'and anywhere a face or identity marker is needed across the Arbor platform.',
23
+ ].join('\n');
24
+
25
+ const PROPS_INTRO
26
+ = 'The preview below is wired to the **Controls** panel — adjust any prop and the canvas updates live. Try switching the `size`, clearing `src` to see initials mode, and then clearing `initials` too to see the placeholder silhouette.';
27
+
28
+ const USAGE_GUIDANCE = [
29
+ '### Choosing a size',
30
+ '',
31
+ '| Size | CSS token | Typical context |',
32
+ '|---|---|---|',
33
+ '| `small` | `--avatar-small-size` | Dense lists, table rows, inline chips |',
34
+ '| `medium` | `--avatar-medium-size` | Standard list items, message previews (default) |',
35
+ '| `large` | `--avatar-large-size` | Cards, sidebars, expanded list items |',
36
+ '| `extra-large` | `--avatar-extra-large-size` | Profile headers, detail pages |',
37
+ '',
38
+ '---',
39
+ '',
40
+ '### When to use',
41
+ '',
42
+ '- To represent a teacher, pupil, guardian, or staff member visually.',
43
+ '- In lists, tables, message threads, profile headers, and contact cards.',
44
+ '- When a face or personal identifier makes a list row easier to scan.',
45
+ '',
46
+ '---',
47
+ '',
48
+ '### When NOT to use',
49
+ '',
50
+ '| Situation | Use instead |',
51
+ '|---|---|',
52
+ '| Representing organisations, schools, or non-person entities | An icon or logo |',
53
+ '| Purely decorative circular shapes | A styled `<span>` or CSS directly |',
54
+ '| When a name alone is sufficient | Plain text — no avatar needed |',
55
+ ].join('\n');
56
+
57
+ const DEVELOPER_NOTES = [
58
+ '### Rendering priority',
59
+ '',
60
+ '`src` always wins. If you pass both `src` and `initials`, the image is rendered and',
61
+ 'the initials are ignored. Pass both props together if you want initials as a visual',
62
+ 'fallback — but note there is no built-in `onError` handler. If the image URL is broken,',
63
+ 'the browser\'s default broken-image treatment shows. Handle `onError` via `...rest`',
64
+ 'or manage `src` state externally.',
65
+ '',
66
+ '---',
67
+ '',
68
+ '### The `alt` prop serves three purposes',
69
+ '',
70
+ '| Mode | Where `alt` goes |',
71
+ '|---|---|',
72
+ '| Image | `<img alt={alt}>` |',
73
+ '| Initials | `<span aria-label={alt}>` around the initials text |',
74
+ '| Placeholder | `<span aria-label={alt \\|\\| "User avatar"}>` around the SVG |',
75
+ '',
76
+ 'When `alt` is an empty string (the default) and initials mode is active, screen readers',
77
+ 'read the raw initials text. Always set `alt` to the person\'s full name for initials and',
78
+ 'placeholder modes.',
79
+ '',
80
+ '---',
81
+ '',
82
+ '### Avatar is an inline element',
83
+ '',
84
+ 'The root renders as a `<span>` — an inline element.',
85
+ 'When placing Avatar next to text inside a flex container, always set `alignItems: "center"`',
86
+ 'on the wrapper so the avatar sits correctly alongside the text baseline.',
87
+ '',
88
+ '---',
89
+ '',
90
+ '### Design tokens',
91
+ '',
92
+ 'Each size has its own CSS custom properties:',
93
+ '',
94
+ '```',
95
+ '--avatar-small-size --avatar-small-radius',
96
+ '--avatar-small-color-border --avatar-small-color-background',
97
+ '',
98
+ '--avatar-medium-size --avatar-medium-radius',
99
+ '--avatar-medium-color-border --avatar-medium-color-background',
100
+ '--avatar-medium-color-text ← text colour, only defined for medium',
101
+ '',
102
+ '--avatar-large-size --avatar-large-radius',
103
+ '--avatar-large-color-border --avatar-large-color-background',
104
+ '',
105
+ '--avatar-extra-large-size --avatar-extra-large-radius',
106
+ '--avatar-extra-large-color-border --avatar-extra-large-color-background',
107
+ '```',
108
+ '',
109
+ '---',
110
+ '',
111
+ '### TypeScript types',
112
+ '',
113
+ '```ts',
114
+ "import { Avatar } from '@arbor-education/design-system.components';",
115
+ '',
116
+ 'type AvatarProps = Avatar.Props;',
117
+ "type AvatarSize = Avatar.Size; // 'small' | 'medium' | 'large' | 'extra-large'",
118
+ '```',
119
+ ].join('\n');
120
+
121
+ const RELATED_COMPONENTS = [
122
+ '## Related components',
123
+ '',
124
+ '[AvatarGroup](?path=/docs/components-avatargroup--docs) · [SingleUser](?path=/docs/components-singleuser--docs)',
125
+ ].join('\n');
126
+
127
+ // ---------------------------------------------------------------------------
128
+ // Custom DocsPage
129
+ // ---------------------------------------------------------------------------
130
+
131
+ function AvatarDocsPage() {
132
+ return (
133
+ <>
134
+ <Title />
135
+ <Subtitle />
136
+ <Markdown>{DESCRIPTION_INTRO}</Markdown>
137
+ <DocHeading>Interactive example</DocHeading>
138
+ <Markdown>{PROPS_INTRO}</Markdown>
139
+ <DocPrimary />
140
+ <Controls />
141
+ <DocHeading>Usage guidance</DocHeading>
142
+ <Markdown>{USAGE_GUIDANCE}</Markdown>
143
+ <DocHeading>Developer notes</DocHeading>
144
+ <Markdown>{DEVELOPER_NOTES}</Markdown>
145
+ <DocHeading>Examples</DocHeading>
146
+ <Stories title="" />
147
+ <Markdown>{RELATED_COMPONENTS}</Markdown>
148
+ </>
149
+ );
150
+ }
151
+
152
+ // ---------------------------------------------------------------------------
153
+ // Meta
154
+ // ---------------------------------------------------------------------------
155
+
4
156
  const meta: Meta<typeof Avatar> = {
5
157
  title: 'Components/Avatar',
6
158
  component: Avatar,
7
159
  tags: ['autodocs'],
8
160
  parameters: {
9
- docs: {
10
- description: {
11
- component:
12
- 'Renders a user avatar as a `<span>`',
13
- },
14
- },
161
+ layout: 'padded',
162
+ docs: { page: AvatarDocsPage },
15
163
  },
16
164
  argTypes: {
17
165
  size: {
18
- control: 'select',
166
+ description: [
167
+ 'Controls the diameter of the avatar.',
168
+ 'Use `small` for dense lists, `medium` (default) for standard contexts,',
169
+ '`large` for cards and sidebars, and `extra-large` for profile headers.',
170
+ 'Note: the correct value is `"extra-large"` — not `"xl"`.',
171
+ ].join(' '),
172
+ control: { type: 'select' },
19
173
  options: ['small', 'medium', 'large', 'extra-large'],
174
+ table: {
175
+ type: { summary: "'small' | 'medium' | 'large' | 'extra-large'" },
176
+ defaultValue: { summary: "'medium'" },
177
+ },
178
+ },
179
+ src: {
180
+ description: [
181
+ 'URL of the person\'s photograph.',
182
+ 'When provided, the image is rendered and `initials` is ignored entirely.',
183
+ 'There is no built-in `onError` fallback — handle broken images externally via `...rest` or by managing `src` state.',
184
+ ].join(' '),
185
+ control: { type: 'text' },
186
+ table: {
187
+ type: { summary: 'string' },
188
+ defaultValue: { summary: 'undefined' },
189
+ },
190
+ },
191
+ alt: {
192
+ description: [
193
+ 'Accessible label for the avatar.',
194
+ 'In image mode it becomes the `<img alt>` attribute.',
195
+ 'In initials mode it becomes `aria-label` on the initials span.',
196
+ 'In placeholder mode it becomes `aria-label` on the SVG wrapper (defaulting to `"User avatar"` when empty).',
197
+ 'Always set this to the person\'s full name.',
198
+ ].join(' '),
199
+ control: { type: 'text' },
200
+ table: {
201
+ type: { summary: 'string' },
202
+ defaultValue: { summary: "''" },
203
+ },
204
+ },
205
+ initials: {
206
+ description: [
207
+ 'Short string (typically 1–2 characters) shown when no `src` is provided.',
208
+ 'Rendered on a coloured circular background.',
209
+ 'Silently ignored when `src` is present.',
210
+ ].join(' '),
211
+ control: { type: 'text' },
212
+ table: {
213
+ type: { summary: 'string' },
214
+ defaultValue: { summary: 'undefined' },
215
+ },
216
+ },
217
+ className: {
218
+ description: [
219
+ 'Additional CSS class names applied to the root `<span>` element,',
220
+ 'alongside the built-in `ds-avatar` and `ds-avatar--{size}` classes.',
221
+ ].join(' '),
222
+ control: { type: 'text' },
223
+ table: {
224
+ type: { summary: 'string' },
225
+ defaultValue: { summary: 'undefined' },
226
+ },
20
227
  },
21
228
  },
22
229
  };
23
230
 
24
- type Story = StoryObj<typeof Avatar>;
231
+ export default meta;
232
+ type Story = StoryObj<typeof meta>;
233
+
234
+ // ---------------------------------------------------------------------------
235
+ // Helper
236
+ // ---------------------------------------------------------------------------
25
237
 
26
- export const Default: Story = {
27
- args: {
28
- size: 'medium',
29
- src: 'https://i.pravatar.cc/150?img=1',
30
- alt: 'User avatar',
238
+ const withDescription = (story: Story, description: string): Story => ({
239
+ ...story,
240
+ parameters: {
241
+ ...story.parameters,
242
+ docs: { ...story.parameters?.docs, description: { story: description } },
31
243
  },
32
- };
244
+ });
245
+
246
+ // ---------------------------------------------------------------------------
247
+ // Stories
248
+ // ---------------------------------------------------------------------------
33
249
 
34
- export const WithInitials: Story = {
35
- args: {
36
- size: 'medium',
37
- initials: 'CM',
38
- alt: 'Christine Montgomery',
250
+ export const Default: Story = withDescription(
251
+ {
252
+ args: {
253
+ size: 'medium',
254
+ src: 'https://i.pravatar.cc/150?img=1',
255
+ alt: 'Amara Osei-Bonsu',
256
+ },
257
+ render: args => <Avatar {...args} />,
39
258
  },
40
- };
259
+ 'The default story is wired to the Controls panel. Clear `src` to switch to initials mode, then clear `initials` to see the placeholder silhouette. Toggle `size` to compare the four diameter options.',
260
+ );
41
261
 
42
- export const Placeholder: Story = {
43
- args: {
44
- size: 'medium',
45
- alt: 'User avatar',
262
+ export const WithInitials: Story = withDescription(
263
+ {
264
+ parameters: {
265
+ controls: { disable: true },
266
+ docs: {
267
+ source: {
268
+ language: 'tsx',
269
+ code: `
270
+ import { Avatar } from '@arbor-education/design-system.components';
271
+
272
+ function WithInitialsExample() {
273
+ return (
274
+ <Avatar
275
+ size="medium"
276
+ initials="JB"
277
+ alt="Jacob Black"
278
+ />
279
+ );
280
+ }
281
+ export default WithInitialsExample;
282
+ `.trim(),
283
+ },
284
+ },
285
+ },
286
+ render: () => <Avatar size="medium" initials="JB" alt="Jacob Black" />,
46
287
  },
47
- };
288
+ 'When no photo is available, pass `initials` (typically the person\'s first and last initial). The component renders them on a coloured circular background. Screen readers announce the full name from the `alt` prop rather than spelling out the raw letters.',
289
+ );
48
290
 
49
- export const Small: Story = {
50
- args: {
51
- size: 'small',
52
- src: 'https://i.pravatar.cc/150?img=2',
53
- alt: 'User avatar',
291
+ export const Placeholder: Story = withDescription(
292
+ {
293
+ parameters: {
294
+ controls: { disable: true },
295
+ docs: {
296
+ source: {
297
+ language: 'tsx',
298
+ code: `
299
+ import { Avatar } from '@arbor-education/design-system.components';
300
+
301
+ function PlaceholderExample() {
302
+ return (
303
+ <Avatar
304
+ size="medium"
305
+ alt="Unknown staff member"
306
+ />
307
+ );
308
+ }
309
+ export default PlaceholderExample;
310
+ `.trim(),
311
+ },
312
+ },
313
+ },
314
+ render: () => <Avatar size="medium" alt="Unknown staff member" />,
54
315
  },
55
- };
316
+ 'When neither `src` nor `initials` is provided, a generic person-silhouette SVG renders. The `alt` prop becomes the `aria-label`; if `alt` is also empty it defaults to `"User avatar"`. Use this for anonymous or as-yet-unknown users.',
317
+ );
56
318
 
57
- export const Medium: Story = {
58
- args: {
59
- size: 'medium',
60
- src: 'https://i.pravatar.cc/150?img=3',
61
- alt: 'User avatar',
319
+ export const AllRenderingModes: Story = withDescription(
320
+ {
321
+ parameters: {
322
+ controls: { disable: true },
323
+ docs: {
324
+ source: {
325
+ language: 'tsx',
326
+ code: `
327
+ import { Avatar } from '@arbor-education/design-system.components';
328
+
329
+ function AllRenderingModesExample() {
330
+ return (
331
+ <div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>
332
+ <Avatar size="medium" src="https://i.pravatar.cc/150?img=5" alt="Sarah Thompson" />
333
+ <Avatar size="medium" initials="MP" alt="Mrs Patel" />
334
+ <Avatar size="medium" alt="Unknown user" />
335
+ </div>
336
+ );
337
+ }
338
+ export default AllRenderingModesExample;
339
+ `.trim(),
340
+ },
341
+ },
342
+ },
343
+ render: () => (
344
+ <div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>
345
+ <Avatar size="medium" src="https://i.pravatar.cc/150?img=5" alt="Sarah Thompson" />
346
+ <Avatar size="medium" initials="MP" alt="Mrs Patel" />
347
+ <Avatar size="medium" alt="Unknown user" />
348
+ </div>
349
+ ),
62
350
  },
63
- };
351
+ 'All three rendering modes side by side at the same size: **image** (left), **initials** (centre), **placeholder** (right). All three share the same container size and shape — only the inner content differs.',
352
+ );
353
+
354
+ export const AllSizes: Story = withDescription(
355
+ {
356
+ parameters: {
357
+ controls: { disable: true },
358
+ docs: {
359
+ source: {
360
+ language: 'tsx',
361
+ code: `
362
+ import { Avatar } from '@arbor-education/design-system.components';
64
363
 
65
- export const Large: Story = {
66
- args: {
67
- size: 'large',
68
- src: 'https://i.pravatar.cc/150?img=4',
69
- alt: 'User avatar',
364
+ function AllSizesExample() {
365
+ return (
366
+ <div style={{ display: 'flex', alignItems: 'center', gap: '1rem', padding: '1rem' }}>
367
+ <Avatar size="small" src="https://i.pravatar.cc/150?img=10" alt="Amara Osei-Bonsu" />
368
+ <Avatar size="medium" src="https://i.pravatar.cc/150?img=10" alt="Amara Osei-Bonsu" />
369
+ <Avatar size="large" src="https://i.pravatar.cc/150?img=10" alt="Amara Osei-Bonsu" />
370
+ <Avatar size="extra-large" src="https://i.pravatar.cc/150?img=10" alt="Amara Osei-Bonsu" />
371
+ </div>
372
+ );
373
+ }
374
+ export default AllSizesExample;
375
+ `.trim(),
376
+ },
377
+ },
378
+ },
379
+ render: () => (
380
+ <div style={{ display: 'flex', alignItems: 'center', gap: '1rem', padding: '1rem' }}>
381
+ <Avatar size="small" src="https://i.pravatar.cc/150?img=10" alt="Amara Osei-Bonsu" />
382
+ <Avatar size="medium" src="https://i.pravatar.cc/150?img=10" alt="Amara Osei-Bonsu" />
383
+ <Avatar size="large" src="https://i.pravatar.cc/150?img=10" alt="Amara Osei-Bonsu" />
384
+ <Avatar size="extra-large" src="https://i.pravatar.cc/150?img=10" alt="Amara Osei-Bonsu" />
385
+ </div>
386
+ ),
70
387
  },
71
- };
388
+ 'All four sizes — `small`, `medium`, `large`, and `extra-large` — shown together. Note the correct prop value is `"extra-large"`, not `"xl"`.',
389
+ );
72
390
 
73
- export const ExtraLarge: Story = {
74
- args: {
75
- size: 'extra-large',
76
- src: 'https://i.pravatar.cc/150?img=5',
77
- alt: 'User avatar',
391
+ export const ImageTakesPriorityOverInitials: Story = withDescription(
392
+ {
393
+ parameters: {
394
+ controls: { disable: true },
395
+ docs: {
396
+ source: {
397
+ language: 'tsx',
398
+ code: `
399
+ import { Avatar } from '@arbor-education/design-system.components';
400
+
401
+ function ImagePriorityExample() {
402
+ // Passing both src and initials is safe — src always wins.
403
+ // If the image later becomes unavailable, initials act as a visual fallback.
404
+ return (
405
+ <Avatar
406
+ size="large"
407
+ src="https://i.pravatar.cc/150?img=3"
408
+ initials="SD"
409
+ alt="Mr Davies"
410
+ />
411
+ );
412
+ }
413
+ export default ImagePriorityExample;
414
+ `.trim(),
415
+ },
416
+ },
417
+ },
418
+ render: () => (
419
+ <Avatar
420
+ size="large"
421
+ src="https://i.pravatar.cc/150?img=3"
422
+ initials="SD"
423
+ alt="Mr Davies"
424
+ />
425
+ ),
78
426
  },
79
- };
427
+ 'Both `src` and `initials` are passed here, but the photo always wins — initials are silently ignored when `src` is present. Passing both is a safe, intentional pattern for graceful degradation (though note there is no built-in `onError` handler for broken image URLs).',
428
+ );
429
+
430
+ export const SmallInListContext: Story = withDescription(
431
+ {
432
+ parameters: {
433
+ controls: { disable: true },
434
+ docs: {
435
+ source: {
436
+ language: 'tsx',
437
+ code: `
438
+ import { Avatar } from '@arbor-education/design-system.components';
439
+
440
+ const staffMembers = [
441
+ { src: 'https://i.pravatar.cc/150?img=20', initials: 'AO', name: 'Amara Osei-Bonsu', role: 'Head of Year 9' },
442
+ { src: 'https://i.pravatar.cc/150?img=21', initials: 'SD', name: 'Mr Davies', role: 'Mathematics' },
443
+ { src: undefined, initials: 'NP', name: 'Mrs Patel', role: 'Cover Supervisor' },
444
+ { src: undefined, initials: undefined, name: 'Supply Teacher', role: 'Not yet confirmed' },
445
+ ];
80
446
 
81
- export const AllSizes: Story = {
82
- render: () => (
83
- <div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>
84
- <Avatar size="small" src="https://i.pravatar.cc/150?img=6" alt="Small avatar" />
85
- <Avatar size="medium" src="https://i.pravatar.cc/150?img=7" alt="Medium avatar" />
86
- <Avatar size="large" src="https://i.pravatar.cc/150?img=8" alt="Large avatar" />
87
- <Avatar size="extra-large" src="https://i.pravatar.cc/150?img=9" alt="Extra large avatar" />
447
+ function StaffListExample() {
448
+ return (
449
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
450
+ {staffMembers.map(({ src, initials, name, role }) => (
451
+ <div key={name} style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
452
+ <Avatar size="small" src={src} initials={initials} alt={name} />
453
+ <span className="ds-text"><strong>{name}</strong> {role}</span>
454
+ </div>
455
+ ))}
88
456
  </div>
89
- ),
90
- };
457
+ );
458
+ }
459
+ export default StaffListExample;
460
+ `.trim(),
461
+ },
462
+ },
463
+ },
464
+ render: () => {
465
+ const staffMembers = [
466
+ { src: 'https://i.pravatar.cc/150?img=20', initials: 'AO', name: 'Amara Osei-Bonsu', role: 'Head of Year 9' },
467
+ { src: 'https://i.pravatar.cc/150?img=21', initials: 'SD', name: 'Mr Davies', role: 'Mathematics' },
468
+ { src: undefined, initials: 'NP', name: 'Mrs Patel', role: 'Cover Supervisor' },
469
+ { src: undefined, initials: undefined, name: 'Supply Teacher', role: 'Not yet confirmed' },
470
+ ];
471
+ return (
472
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
473
+ {staffMembers.map(({ src, initials, name, role }) => (
474
+ <div key={name} style={{ display: 'flex', alignItems: 'center', gap: '0.5rem' }}>
475
+ <Avatar size="small" src={src} initials={initials} alt={name} />
476
+ <span className="ds-text">
477
+ <strong>{name}</strong>
478
+ {' '}
479
+
480
+ {' '}
481
+ {role}
482
+ </span>
483
+ </div>
484
+ ))}
485
+ </div>
486
+ );
487
+ },
488
+ },
489
+ 'A realistic staff list showing all three rendering modes at `small` size. The first two rows have photos, the third has initials only, and the fourth shows the placeholder silhouette. Note `alignItems: "center"` on each row — required because Avatar is an inline `<span>` element.',
490
+ );
91
491
 
92
- export default meta;
492
+ export const ExtraLargeProfile: Story = withDescription(
493
+ {
494
+ parameters: {
495
+ controls: { disable: true },
496
+ docs: {
497
+ source: {
498
+ language: 'tsx',
499
+ code: `
500
+ import { Avatar } from '@arbor-education/design-system.components';
501
+
502
+ function ProfileHeaderExample() {
503
+ return (
504
+ <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '0.75rem' }}>
505
+ <Avatar
506
+ size="extra-large"
507
+ src="https://i.pravatar.cc/150?img=47"
508
+ alt="Jacob Black"
509
+ />
510
+ <div style={{ textAlign: 'center' }}>
511
+ <p className="ds-text"><strong>Jacob Black</strong></p>
512
+ <p className="ds-text">Year 10 · Form 10B</p>
513
+ </div>
514
+ </div>
515
+ );
516
+ }
517
+ export default ProfileHeaderExample;
518
+ `.trim(),
519
+ },
520
+ },
521
+ },
522
+ render: () => (
523
+ <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '0.75rem' }}>
524
+ <Avatar
525
+ size="extra-large"
526
+ src="https://i.pravatar.cc/150?img=47"
527
+ alt="Jacob Black"
528
+ />
529
+ <div style={{ textAlign: 'center' }}>
530
+ <p className="ds-text"><strong>Jacob Black</strong></p>
531
+ <p className="ds-text">Year 10 · Form 10B</p>
532
+ </div>
533
+ </div>
534
+ ),
535
+ },
536
+ 'The `extra-large` size (6rem / 96px) is designed for profile headers where the person\'s identity is the focal point of the view. Pair it with the person\'s full name and a short contextual label beneath.',
537
+ );