@uva-glass/component-library 3.57.2 → 3.57.3

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 (246) hide show
  1. package/dist/ActionList-D2GC2qPX.js.map +1 -1
  2. package/dist/AddCatalogueLinkForm-Di0xm7Ep.js.map +1 -1
  3. package/dist/ClipboardButton-Cg6LGUiD.js.map +1 -1
  4. package/dist/ControlsButton-Byx4XQtB.js.map +1 -1
  5. package/dist/CopyableText-BKsM-TuS.js.map +1 -1
  6. package/dist/DataTable-Cgn_RKTA.js.map +1 -1
  7. package/dist/{Lexical.prod-nAj5fF96.js → Lexical.prod-Dy5aDppc.js} +2449 -1794
  8. package/dist/Lexical.prod-Dy5aDppc.js.map +1 -0
  9. package/dist/LexicalClipboard.prod-CS8a49uL.js +398 -0
  10. package/dist/LexicalClipboard.prod-CS8a49uL.js.map +1 -0
  11. package/dist/{LexicalComposerContext.prod-DumMmRBt.js → LexicalComposerContext.prod-D4HOlWII.js} +3 -3
  12. package/dist/LexicalComposerContext.prod-D4HOlWII.js.map +1 -0
  13. package/dist/LexicalHtml.prod-BtzosUOH.js +1611 -0
  14. package/dist/LexicalHtml.prod-BtzosUOH.js.map +1 -0
  15. package/dist/LexicalLink.prod-DzgwWhQM.js +646 -0
  16. package/dist/LexicalLink.prod-DzgwWhQM.js.map +1 -0
  17. package/dist/LexicalList.prod-icY8mpm6.js +710 -0
  18. package/dist/LexicalList.prod-icY8mpm6.js.map +1 -0
  19. package/dist/{LexicalTable.prod-BpHQYpBM.js → LexicalTable.prod-Bf0is-op.js} +674 -750
  20. package/dist/LexicalTable.prod-Bf0is-op.js.map +1 -0
  21. package/dist/LexicalUtils.prod-CjGUKarD.js +259 -0
  22. package/dist/LexicalUtils.prod-CjGUKarD.js.map +1 -0
  23. package/dist/{LinkContextMenu-Byu3AEqp.js → LinkContextMenu-C8ehPbP8.js} +2 -2
  24. package/dist/{LinkContextMenu-Byu3AEqp.js.map → LinkContextMenu-C8ehPbP8.js.map} +1 -1
  25. package/dist/MenuLink-sK2_W2zs.js.map +1 -1
  26. package/dist/MetaDataList-Co9WCexh.js.map +1 -1
  27. package/dist/MultiSelectBox-D34qAgzc.js.map +1 -1
  28. package/dist/OverlayStepBar-BiC06Itd.js.map +1 -1
  29. package/dist/{PasteHandlerPlugin-DyTXcFsj.js → PasteHandlerPlugin-CSo_lOE8.js} +6 -6
  30. package/dist/{PasteHandlerPlugin-DyTXcFsj.js.map → PasteHandlerPlugin-CSo_lOE8.js.map} +1 -1
  31. package/dist/Periods-B4ms3N24.js.map +1 -1
  32. package/dist/SortableProvider-D-6Ttz0h.js.map +1 -1
  33. package/dist/{TableCellContextMenu--4IdoKAU.js → TableCellContextMenu-Cu5iXYSJ.js} +2 -2
  34. package/dist/{TableCellContextMenu--4IdoKAU.js.map → TableCellContextMenu-Cu5iXYSJ.js.map} +1 -1
  35. package/dist/{TableCellResizerPlugin-Dn8Ks2Lm.js → TableCellResizerPlugin-Bb2blXnq.js} +43 -43
  36. package/dist/TableCellResizerPlugin-Bb2blXnq.js.map +1 -0
  37. package/dist/VarIndicator-D0cnlcIf.js.map +1 -1
  38. package/dist/{chunk-5WKL7XVT-3IraU-Ja.js → chunk-5WKL7XVT-CvOIS3NE.js} +15 -15
  39. package/dist/{chunk-5WKL7XVT-3IraU-Ja.js.map → chunk-5WKL7XVT-CvOIS3NE.js.map} +1 -1
  40. package/dist/{client-BcEWjSJP.js → client-CXlG3hNo.js} +956 -957
  41. package/dist/{client-BcEWjSJP.js.map → client-CXlG3hNo.js.map} +1 -1
  42. package/dist/components/Accordion/Accordion.test.js +3 -3
  43. package/dist/components/Accordion/Accordion.test.js.map +1 -1
  44. package/dist/components/AccordionCard/AccordionCard.stories.js.map +1 -1
  45. package/dist/components/AccordionCard/AccordionCard.test.js +3 -3
  46. package/dist/components/AccordionCard/AccordionCard.test.js.map +1 -1
  47. package/dist/components/ActionList/ActionList.test.js +3 -3
  48. package/dist/components/ActionList/ActionList.test.js.map +1 -1
  49. package/dist/components/AppStatusBar/AppStatusBar.test.js +2 -2
  50. package/dist/components/AppStatusBar/AppStatusBar.test.js.map +1 -1
  51. package/dist/components/Attention/Attention.stories.js.map +1 -1
  52. package/dist/components/Attention/Attention.test.js +2 -2
  53. package/dist/components/Attention/Attention.test.js.map +1 -1
  54. package/dist/components/Backdrop/Backdrop.stories.js.map +1 -1
  55. package/dist/components/Backdrop/Backdrop.test.js +2 -2
  56. package/dist/components/Backdrop/Backdrop.test.js.map +1 -1
  57. package/dist/components/Buttons/Button.stories.js +1 -1
  58. package/dist/components/Buttons/Button.test.js +2 -2
  59. package/dist/components/Buttons/Button.test.js.map +1 -1
  60. package/dist/components/Buttons/LinkButton.stories.js +1 -1
  61. package/dist/components/Buttons/LinkButton.test.js +2 -2
  62. package/dist/components/Buttons/LinkButton.test.js.map +1 -1
  63. package/dist/components/Buttons/MenuButton.stories.js +1 -1
  64. package/dist/components/Buttons/MenuButton.test.js +2 -2
  65. package/dist/components/Buttons/MenuButton.test.js.map +1 -1
  66. package/dist/components/Card/Card.test.js +2 -2
  67. package/dist/components/Card/Card.test.js.map +1 -1
  68. package/dist/components/Checkbox/Checkbox.stories.js +1 -1
  69. package/dist/components/Checkbox/Checkbox.stories.js.map +1 -1
  70. package/dist/components/Checkbox/Checkbox.test.js +3 -3
  71. package/dist/components/Checkbox/Checkbox.test.js.map +1 -1
  72. package/dist/components/CheckboxButtonBar/CheckboxButtonBar.stories.js +1 -1
  73. package/dist/components/CheckboxButtonBar/CheckboxButtonBar.test.js +2 -2
  74. package/dist/components/CheckboxButtonBar/CheckboxButtonBar.test.js.map +1 -1
  75. package/dist/components/CheckboxTree/CheckboxTree.js +1 -1
  76. package/dist/components/CheckboxTree/CheckboxTree.stories.js +3 -3
  77. package/dist/components/CheckboxTree/CheckboxTree.stories.js.map +1 -1
  78. package/dist/components/CheckboxTree/index.js +1 -1
  79. package/dist/components/Chip/Chip.stories.js +1 -1
  80. package/dist/components/ControlsButton/ControlsButton.stories.js +1 -1
  81. package/dist/components/CopyableText/CopyableText.stories.js.map +1 -1
  82. package/dist/components/DataTable/DataTable.stories.js +2 -2
  83. package/dist/components/DataTable/DataTable.stories.js.map +1 -1
  84. package/dist/components/Drawer/Drawer.stories.js +1 -1
  85. package/dist/components/Drawer/Drawer.stories.js.map +1 -1
  86. package/dist/components/EmptyStateDataDisplay/EmptyStateDataDisplay.stories.js.map +1 -1
  87. package/dist/components/FeedbackBar/FeedbackBar.stories.js.map +1 -1
  88. package/dist/components/FeedbackBar/FeedbackBar.test.js +2 -2
  89. package/dist/components/FeedbackBar/FeedbackBar.test.js.map +1 -1
  90. package/dist/components/FormInput/FormInput.js +1 -1
  91. package/dist/components/FormInput/FormInput.stories.js +2 -2
  92. package/dist/components/FormInput/index.js +1 -1
  93. package/dist/components/GridRow/GridRow.stories.js.map +1 -1
  94. package/dist/components/Icon/Icon.stories.js.map +1 -1
  95. package/dist/components/IconButton/IconButton.stories.js +1 -1
  96. package/dist/components/IconButton/IconButton.stories.js.map +1 -1
  97. package/dist/components/InfoBanner/InfoBanner.stories.js.map +1 -1
  98. package/dist/components/InfoMessage/InfoMessage.stories.js.map +1 -1
  99. package/dist/components/InputField/InputField.stories.js +1 -1
  100. package/dist/components/InputField/InputField.stories.js.map +1 -1
  101. package/dist/components/Label/Label.test.js +2 -2
  102. package/dist/components/Label/Label.test.js.map +1 -1
  103. package/dist/components/MenuLink/MenuLink.stories.js.map +1 -1
  104. package/dist/components/MetaDataBar/MetaDataBar.stories.js.map +1 -1
  105. package/dist/components/MetaDataBar/MetaDataBar.test.js +1 -1
  106. package/dist/components/MetaDataBar/MetaDataBar.test.js.map +1 -1
  107. package/dist/components/MetaDataList/MetaDataList.stories.js.map +1 -1
  108. package/dist/components/ModalDialog/ModalDialog.stories.js +1 -1
  109. package/dist/components/ModalDialog/ModalDialog.stories.js.map +1 -1
  110. package/dist/components/MultiSelect/MultiSelect.js +1 -1
  111. package/dist/components/MultiSelect/MultiSelect.stories.js +2 -2
  112. package/dist/components/MultiSelect/MultiSelect.stories.js.map +1 -1
  113. package/dist/components/MultiSelect/components/MultiSelectHeader.js +1 -1
  114. package/dist/components/MultiSelect/index.js +1 -1
  115. package/dist/components/MultiSelectBox/MultiSelectBox.stories.js +1 -1
  116. package/dist/components/MultiSelectBox/MultiSelectBox.stories.js.map +1 -1
  117. package/dist/components/MultiSelectBox/MultiSelectBox.test.js +2 -2
  118. package/dist/components/MultiSelectBox/MultiSelectBox.test.js.map +1 -1
  119. package/dist/components/Notification/Notification.stories.js +1 -1
  120. package/dist/components/Notification/Notification.test.js +2 -2
  121. package/dist/components/Notification/Notification.test.js.map +1 -1
  122. package/dist/components/OverlayCloseButton/OverlayCloseButton.stories.js +1 -1
  123. package/dist/components/OverlayCloseButton/OverlayCloseButton.stories.js.map +1 -1
  124. package/dist/components/PageOverlay/PageOverlay.stories.js.map +1 -1
  125. package/dist/components/PeriodSelector/PeriodSelector.js +1 -1
  126. package/dist/components/PeriodSelector/PeriodSelector.stories.js +2 -2
  127. package/dist/components/PeriodSelector/PeriodSelector.stories.js.map +1 -1
  128. package/dist/components/PeriodSelector/index.js +1 -1
  129. package/dist/components/Periods/Periods.stories.js.map +1 -1
  130. package/dist/components/ProgrammeCard/ProgrammeCard.stories.js.map +1 -1
  131. package/dist/components/RadioButton/RadioButton.stories.js.map +1 -1
  132. package/dist/components/RadioGroup/RadioGroup.stories.js +1 -1
  133. package/dist/components/RadioGroup/RadioGroup.stories.js.map +1 -1
  134. package/dist/components/RadioGroup/Radiogroup.test.js +2 -2
  135. package/dist/components/RadioGroup/Radiogroup.test.js.map +1 -1
  136. package/dist/components/RadioTabSelector/RadioTabSelector.js +1 -1
  137. package/dist/components/RadioTabSelector/RadioTabSelector.stories.js +2 -2
  138. package/dist/components/RadioTabSelector/index.js +1 -1
  139. package/dist/components/Repeater/Repeater.stories.js.map +1 -1
  140. package/dist/components/RteEditor/EditorHeader/EditorHeader.js +1 -1
  141. package/dist/components/RteEditor/EditorHeader/index.js +1 -1
  142. package/dist/components/RteEditor/Plugins/BlockFormatPlugin/BlockFormatPlugin.js +4 -4
  143. package/dist/components/RteEditor/Plugins/CourseCataloguePlugin/CourseCataloguePlugin.js +35 -35
  144. package/dist/components/RteEditor/Plugins/CourseCataloguePlugin/CourseCataloguePlugin.js.map +1 -1
  145. package/dist/components/RteEditor/Plugins/HistoryPlugin/HistoryPlugin.js +1 -1
  146. package/dist/components/RteEditor/Plugins/HistoryPlugin/index.js +1 -1
  147. package/dist/components/RteEditor/Plugins/LinkPlugin/AddLinkForm/AddLinkFrom.js +1 -1
  148. package/dist/components/RteEditor/Plugins/LinkPlugin/LinkContextMenu/LinkContextMenu.js +1 -1
  149. package/dist/components/RteEditor/Plugins/LinkPlugin/LinkPlugin.js +1 -1
  150. package/dist/components/RteEditor/Plugins/LinkPlugin/helpers.js +1 -1
  151. package/dist/components/RteEditor/Plugins/LinkPlugin/index.js +1 -1
  152. package/dist/components/RteEditor/Plugins/ListPlugin/ListPlugin.js +15 -15
  153. package/dist/components/RteEditor/Plugins/PasteHandlerPlugin/PasteHandlerPlugin.js +1 -1
  154. package/dist/components/RteEditor/Plugins/PasteHandlerPlugin/index.js +1 -1
  155. package/dist/components/RteEditor/Plugins/TableCellResizerPlugin/TableCellResizerPlugin.js +1 -1
  156. package/dist/components/RteEditor/Plugins/TableCellResizerPlugin/index.js +1 -1
  157. package/dist/components/RteEditor/Plugins/TablePlugin/AddTableFrom.js +1 -1
  158. package/dist/components/RteEditor/Plugins/TablePlugin/TableCellContextMenu/TableCellContextMenu.js +1 -1
  159. package/dist/components/RteEditor/Plugins/TablePlugin/TableCellContextMenu/index.js +1 -1
  160. package/dist/components/RteEditor/Plugins/TablePlugin/TablePlugin.js +1 -1
  161. package/dist/components/RteEditor/Plugins/TablePlugin/helpers.js +33 -33
  162. package/dist/components/RteEditor/Plugins/TablePlugin/helpers.js.map +1 -1
  163. package/dist/components/RteEditor/Plugins/TablePlugin/index.js +2 -2
  164. package/dist/components/RteEditor/Plugins/ToolbarPlugin/ToolbarPlugin.js +1 -1
  165. package/dist/components/RteEditor/Plugins/ToolbarPlugin/index.js +1 -1
  166. package/dist/components/RteEditor/Plugins/index.js +4 -4
  167. package/dist/components/RteEditor/RteEditor.js +1 -1
  168. package/dist/components/RteEditor/RteEditor.stories.js +1 -1
  169. package/dist/components/RteEditor/RteEditor.stories.js.map +1 -1
  170. package/dist/components/RteEditor/helpers.js +7 -7
  171. package/dist/components/RteEditor/helpers.js.map +1 -1
  172. package/dist/components/RteEditor/index.js +1 -1
  173. package/dist/components/RteEditor/nodes/CourseCatalogueNode/CourseCatalogueNode.js +18 -18
  174. package/dist/components/RteEditor/nodes/CourseCatalogueNode/CourseCatalogueNode.js.map +1 -1
  175. package/dist/components/RteEditor/nodes/TableWrapperNode/TableWrapperNode.js +22 -22
  176. package/dist/components/SearchField/SearcheField.stories.js.map +1 -1
  177. package/dist/components/SectionNotification/SectionNotification.stories.js.map +1 -1
  178. package/dist/components/SelectListbox/SelectListBox.stories.js +1 -1
  179. package/dist/components/SelectListbox/SelectListBox.stories.js.map +1 -1
  180. package/dist/components/SelectListbox/SelectProvider.js.map +1 -1
  181. package/dist/components/SelectListbox/components/SelectButton.js.map +1 -1
  182. package/dist/components/SelectListbox/components/SelectOption.js.map +1 -1
  183. package/dist/components/Slider/Slider.stories.js.map +1 -1
  184. package/dist/components/Sortable/Sortable.stories.js +1 -1
  185. package/dist/components/Sortable/Sortable.stories.js.map +1 -1
  186. package/dist/components/Spinner/Spinner.stories.js.map +1 -1
  187. package/dist/components/StatusBadge/StatusBadge.test.js +2 -2
  188. package/dist/components/StatusBadge/StatusBadge.test.js.map +1 -1
  189. package/dist/components/StatusPill/StatusPill.stories.js.map +1 -1
  190. package/dist/components/TextArea/TextArea.stories.js +1 -1
  191. package/dist/components/TextArea/TextArea.test.js +3 -3
  192. package/dist/components/TextArea/TextArea.test.js.map +1 -1
  193. package/dist/components/ToggleSwitch/ToggleSwitch.stories.js +1 -1
  194. package/dist/components/Tooltip/Tooltip.stories.js.map +1 -1
  195. package/dist/components/VarIndicator/VarIndicator.stories.js +1 -1
  196. package/dist/components/VarIndicator/VarIndicator.test.js +3 -3
  197. package/dist/components/VarIndicator/VarIndicator.test.js.map +1 -1
  198. package/dist/components/WeekSelector/WeekSelector.js.map +1 -1
  199. package/dist/components/WeekSelector/WeekSelector.stories.js.map +1 -1
  200. package/dist/components/WeekSelector/components/WeekSelectorOption.js.map +1 -1
  201. package/dist/components/hooks/useOnClickOutside.js.map +1 -1
  202. package/dist/components/hooks/usePositionedFloaters.js.map +1 -1
  203. package/dist/components/hooks/useResponsive.js.map +1 -1
  204. package/dist/components/index.js +1 -1
  205. package/dist/components-CgBF6db6.js +2013 -0
  206. package/dist/components-CgBF6db6.js.map +1 -0
  207. package/dist/{dist-C6Ar8a59.js → dist-oLwM--0y.js} +14 -14
  208. package/dist/{dist-C6Ar8a59.js.map → dist-oLwM--0y.js.map} +1 -1
  209. package/dist/{esm-B6Pg-v2v.js → esm-BXzGXYWZ.js} +3 -3
  210. package/dist/{esm-B6Pg-v2v.js.map → esm-BXzGXYWZ.js.map} +1 -1
  211. package/dist/{helpers-BzYayeT-.js → helpers-MMNO9vlK.js} +9 -9
  212. package/dist/helpers-MMNO9vlK.js.map +1 -0
  213. package/dist/index.js +1 -1
  214. package/dist/{react-18-DbbN8Pdb.js → react-18-BwdnKC48.js} +3 -3
  215. package/dist/react-18-BwdnKC48.js.map +1 -0
  216. package/dist/{react.esm-56DGmlLk.js → react.esm-DwWzhs9e.js} +17 -17
  217. package/dist/react.esm-DwWzhs9e.js.map +1 -0
  218. package/dist/setupTests.js +2 -2
  219. package/dist/setupTests.js.map +1 -1
  220. package/dist/storybook__react.d.js +266 -266
  221. package/dist/storybook__react.d.js.map +1 -1
  222. package/dist/{test-WxLxsxwA.js → test-Gtly6H2f.js} +7 -5
  223. package/dist/{test-WxLxsxwA.js.map → test-Gtly6H2f.js.map} +1 -1
  224. package/dist/{test-utils-CMrZ33U0.js → test-utils-BVa31HVj.js} +2 -2
  225. package/dist/{test-utils-CMrZ33U0.js.map → test-utils-BVa31HVj.js.map} +1 -1
  226. package/package.json +21 -22
  227. package/dist/Lexical.prod-nAj5fF96.js.map +0 -1
  228. package/dist/LexicalClipboard.prod-B9sWgdS2.js +0 -348
  229. package/dist/LexicalClipboard.prod-B9sWgdS2.js.map +0 -1
  230. package/dist/LexicalComposerContext.prod-DumMmRBt.js.map +0 -1
  231. package/dist/LexicalHtml.prod-RCMsF0qt.js +0 -2139
  232. package/dist/LexicalHtml.prod-RCMsF0qt.js.map +0 -1
  233. package/dist/LexicalLink.prod-BcBNTFEb.js +0 -707
  234. package/dist/LexicalLink.prod-BcBNTFEb.js.map +0 -1
  235. package/dist/LexicalList.prod-THQt9B32.js +0 -890
  236. package/dist/LexicalList.prod-THQt9B32.js.map +0 -1
  237. package/dist/LexicalTable.prod-BpHQYpBM.js.map +0 -1
  238. package/dist/LexicalUtils.prod-7S6iuu9A.js +0 -347
  239. package/dist/LexicalUtils.prod-7S6iuu9A.js.map +0 -1
  240. package/dist/TableCellResizerPlugin-Dn8Ks2Lm.js.map +0 -1
  241. package/dist/components-KU0q76JR.js +0 -2150
  242. package/dist/components-KU0q76JR.js.map +0 -1
  243. package/dist/helpers-BzYayeT-.js.map +0 -1
  244. package/dist/react-18-DbbN8Pdb.js.map +0 -1
  245. package/dist/react.esm-56DGmlLk.js.map +0 -1
  246. /package/dist/{chunk-CWhphoD1.js → rolldown-runtime-CWhphoD1.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"ActionList-D2GC2qPX.js","names":[],"sources":["../src/components/ActionList/ActionList.module.css","../src/components/ActionList/ActionList.tsx"],"sourcesContent":[".action-list {\n background-color: var(--color-uva-white);\n border-radius: 0.5rem;\n box-shadow: 0 0 6px 2px rgb(0 0 0 / 15%);\n display: none;\n padding: 0.25rem;\n position: absolute;\n right: 0;\n top: calc(100% + 0.5rem);\n z-index: 100;\n}\n\n.action-list--open {\n display: block;\n}\n\n.action-list-container {\n position: relative;\n}\n\n.action-list [role=\"menuitem\"] > * {\n background: 0;\n border: 0;\n border-radius: 0.25rem;\n cursor: pointer;\n display: block;\n font: inherit;\n margin: 0;\n padding: 0.5rem 0.75rem;\n text-align: left;\n white-space: pre;\n width: 100%;\n}\n\n.action-list [role=\"menuitem\"] > *:not(:last-of-type) {\n border-bottom: 1px solid var(--color-grey-300);\n}\n\n.action-list [role=\"menuitem\"] > *:hover {\n background-color: var(--color-grey-200);\n}\n","import { clsx } from 'clsx';\nimport { Children, useEffect, useId, useRef, useState } from 'react';\n\nimport type { KeyboardEvent, MouseEvent as ReactMouseEvent, ReactElement, RefObject } from 'react';\nimport type { IconProps } from 'components/Icon';\nimport type { UIButtonVariant } from 'types/UserInterface';\n\nimport styles from './ActionList.module.css';\n\nimport { Icon } from 'components/Icon';\nimport { MenuButton } from 'components/Buttons';\n\nexport interface ActionListProps {\n /** The label that is displayed before the icon. */\n label: string;\n /** The icon that is shown in front of the label. */\n prefixIcon?: IconProps['name'];\n /** The icon that is shown to toggle the menu. If none is specified, CheveronUp and CheveronDown is used depending on whether the menu is opened or closed. */\n iconName?: IconProps['name'];\n /** Determines the button variant. */\n variant?: UIButtonVariant;\n /** The child component(s). */\n children: ReactElement | ReactElement[];\n}\n\nconst inactiveIndex = -1;\nconst indexIncrement = 1;\n\n/** A component to show an action list to toggle a menu. */\nexport function ActionList({ label, prefixIcon, iconName, variant = 'secondary', children }: ActionListProps) {\n const listId = useId();\n const triggerRef = useRef<HTMLButtonElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n const numberOfChildren = Children.count(children);\n\n const [activeIndex, setActiveIndex] = useState(inactiveIndex);\n const [isOpen, setIsOpen] = useState(false);\n\n function open() {\n setIsOpen(true);\n\n document.addEventListener('click', onClickOutside, { once: true, capture: true });\n }\n\n function close(event?: ReactMouseEvent<HTMLDivElement>) {\n // When a click occurs on an element that is not an immediate descendant of the action list container\n // (can happen when a modal window is triggered from a button in the action list), the setIsOpen state\n // handler should not be called, because this causes a re-render of the entire component and can lead\n // to undesired effects, like a select element closing immediately after it has been clicked.\n if (event && containerRef.current && !containerRef.current.contains(event.target as Node)) {\n return;\n }\n\n setActiveIndex(inactiveIndex);\n setIsOpen(false);\n\n document.removeEventListener('click', onClickOutside, { capture: true });\n }\n\n function toggle() {\n if (isOpen) close();\n else open();\n }\n\n function onKeyDown(event: KeyboardEvent) {\n if (!isOpen) return;\n\n const eventPreventCodes = ['ArrowUp', 'ArrowDown', 'Home', 'End'];\n\n if (eventPreventCodes.includes(event.code)) {\n // prevent page from scrolling when navigating through items in list\n event.preventDefault();\n }\n\n if (event.code === 'Tab') {\n close();\n }\n }\n\n function onKeyUp(event: KeyboardEvent) {\n if (event.code === 'Space' || event.key === 'Enter') {\n if (event.target === triggerRef.current) {\n toggle();\n } else if (event.key === 'Enter' && event.target !== listRef.current) {\n if ('firstChild' in event.target) {\n const firstChild = event.target.firstChild as HTMLButtonElement;\n\n firstChild.click();\n }\n }\n }\n\n if (event.code === 'Escape') close();\n\n if (event.code === 'ArrowUp') {\n setActiveIndex((prevState) => {\n if (prevState === 0) return numberOfChildren - indexIncrement;\n\n return prevState - indexIncrement;\n });\n }\n\n if (event.code === 'ArrowDown') {\n setActiveIndex((prevState) => {\n if (prevState === numberOfChildren - indexIncrement) return 0;\n\n return prevState + indexIncrement;\n });\n }\n\n if (event.code === 'Home') {\n setActiveIndex(0);\n }\n\n if (event.code === 'End') {\n setActiveIndex(numberOfChildren - indexIncrement);\n }\n }\n\n const onClickOutside = (event: MouseEvent) => {\n const { target } = event;\n\n if (!target || !containerRef.current) return;\n\n if (!containerRef.current.contains(target as Node)) {\n close();\n }\n };\n\n useEffect(() => {\n if (activeIndex < 0 || !listRef.current) return;\n\n const listItem = listRef.current.children.item(activeIndex);\n\n if (listItem) {\n (listItem as HTMLDivElement).focus();\n }\n }, [activeIndex]);\n\n useEffect(() => {\n if (!listRef.current || !listRef.current.hasChildNodes()) return;\n\n Array.from(listRef.current.children)\n .filter((overlayChild) => overlayChild.nodeType === Node.ELEMENT_NODE && overlayChild.hasChildNodes())\n .forEach((overlayChild) => {\n Array.from(overlayChild.children)\n .filter((childOfChild) => childOfChild.nodeType === Node.ELEMENT_NODE)\n .forEach((childOfChild) => {\n // internal children may be buttons and can get focus when tab is pressed; preventing those elements\n // from getting focus so that list can be tabbed over and traversed with arrow keys\n childOfChild.setAttribute('tabIndex', '-1');\n });\n });\n }, [children]);\n\n return (\n <div className={styles['action-list-container']} ref={containerRef}>\n <MenuButton\n onClick={toggle}\n onKeyDown={onKeyDown}\n onKeyUp={onKeyUp}\n buttonRef={triggerRef as RefObject<HTMLButtonElement>}\n variant={variant}\n >\n {prefixIcon && <Icon size={24} name={prefixIcon} />}\n {label}\n {iconName ? (\n <Icon size={24} name={iconName} />\n ) : (\n <Icon size={16} name={isOpen ? 'CheveronUp' : 'CheveronDown'} />\n )}\n </MenuButton>\n <div\n aria-activedescendant={`${listId}-child-${activeIndex}`}\n aria-label={label}\n className={clsx(styles['action-list'], {\n [styles['action-list--open']]: isOpen,\n })}\n onClickCapture={close}\n onKeyDown={onKeyDown}\n onKeyUp={onKeyUp}\n ref={listRef}\n role=\"menu\"\n tabIndex={-1}\n >\n {Children.map(children, (child, index) => (\n <div key={`${listId}-child-${index}`} role=\"menuitem\" tabIndex={-1}>\n {child}\n </div>\n ))}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;GCyBM,IAAgB,IAChB,IAAiB;AAGvB,SAAgB,EAAW,EAAE,UAAO,eAAY,aAAU,aAAU,aAAa,eAA6B;CAC5G,IAAM,IAAS,EAAM,GACf,IAAa,EAA0B,IAAI,GAC3C,IAAU,EAAuB,IAAI,GACrC,IAAe,EAAuB,IAAI,GAE1C,IAAmB,EAAS,MAAM,CAAQ,GAE1C,CAAC,GAAa,KAAkB,EAAS,CAAa,GACtD,CAAC,GAAQ,KAAa,EAAS,EAAK;CAE1C,SAAS,IAAO;EAGd,AAFA,EAAU,EAAI,GAEd,SAAS,iBAAiB,SAAS,GAAgB;GAAE,MAAM;GAAM,SAAS;EAAK,CAAC;CAClF;CAEA,SAAS,EAAM,GAAyC;EAKlD,KAAS,EAAa,WAAW,CAAC,EAAa,QAAQ,SAAS,EAAM,MAAc,MAIxF,EAAe,CAAa,GAC5B,EAAU,EAAK,GAEf,SAAS,oBAAoB,SAAS,GAAgB,EAAE,SAAS,GAAK,CAAC;CACzE;CAEA,SAAS,IAAS;EAChB,AAAI,IAAQ,EAAM,IACb,EAAK;CACZ;CAEA,SAAS,EAAU,GAAsB;EAClC,MAID;GAFuB;GAAW;GAAa;GAAQ;EAEvD,EAAkB,SAAS,EAAM,IAAI,KAEvC,EAAM,eAAe,GAGnB,EAAM,SAAS,SACjB,EAAM;CAEV;CAEA,SAAS,EAAQ,GAAsB;EAmCrC,CAlCI,EAAM,SAAS,WAAW,EAAM,QAAQ,aACtC,EAAM,WAAW,EAAW,UAC9B,EAAO,IACE,EAAM,QAAQ,WAAW,EAAM,WAAW,EAAQ,WACvD,gBAAgB,EAAM,UAGxB,EAFyB,OAAO,WAErB,MAAM,IAKnB,EAAM,SAAS,YAAU,EAAM,GAE/B,EAAM,SAAS,aACjB,GAAgB,MACV,MAAc,IAAU,IAAmB,IAExC,IAAY,CACpB,GAGC,EAAM,SAAS,eACjB,GAAgB,MACV,MAAc,IAAmB,IAAuB,IAErD,IAAY,CACpB,GAGC,EAAM,SAAS,UACjB,EAAe,CAAC,GAGd,EAAM,SAAS,SACjB,EAAe,IAAmB,CAAc;CAEpD;CAEA,IAAM,KAAkB,MAAsB;EAC5C,IAAM,EAAE,cAAW;EAEf,CAAC,KAAU,CAAC,EAAa,WAExB,EAAa,QAAQ,SAAS,CAAc,KAC/C,EAAM;CAEV;CA4BA,OA1BA,QAAgB;EACd,IAAI,IAAc,KAAK,CAAC,EAAQ,SAAS;EAEzC,IAAM,IAAW,EAAQ,QAAQ,SAAS,KAAK,CAAW;EAE1D,AAAI,KACF,EAA6B,MAAM;CAEvC,GAAG,CAAC,CAAW,CAAC,GAEhB,QAAgB;EACV,CAAC,EAAQ,WAAW,CAAC,EAAQ,QAAQ,cAAc,KAEvD,MAAM,KAAK,EAAQ,QAAQ,QAAQ,EAChC,QAAQ,MAAiB,EAAa,aAAa,KAAK,gBAAgB,EAAa,cAAc,CAAC,EACpG,SAAS,MAAiB;GACzB,MAAM,KAAK,EAAa,QAAQ,EAC7B,QAAQ,MAAiB,EAAa,aAAa,KAAK,YAAY,EACpE,SAAS,MAAiB;IAGzB,EAAa,aAAa,YAAY,IAAI;GAC5C,CAAC;EACL,CAAC;CACL,GAAG,CAAC,CAAQ,CAAC,GAGX,kBAAC,OAAD;EAAK,WAAW,EAAO;EAA0B,KAAK;YAAtD,CACE,kBAAC,GAAD;GACE,SAAS;GACE;GACF;GACT,WAAW;GACF;aALX;IAOG,KAAc,kBAAC,GAAD;KAAM,MAAM;KAAI,MAAM;IAAa,CAAA;IACjD;IACA,IACC,kBAAC,GAAD;KAAM,MAAM;KAAI,MAAM;IAAW,CAAA,IAEjC,kBAAC,GAAD;KAAM,MAAM;KAAI,MAAM,IAAS,eAAe;IAAiB,CAAA;GAEvD;MACZ,kBAAC,OAAD;GACE,yBAAuB,GAAG,EAAO,SAAS;GAC1C,cAAY;GACZ,WAAW,EAAK,EAAO,gBAAgB,GACpC,EAAO,uBAAuB,EACjC,CAAC;GACD,gBAAgB;GACL;GACF;GACT,KAAK;GACL,MAAK;GACL,UAAU;aAET,EAAS,IAAI,IAAW,GAAO,MAC9B,kBAAC,OAAD;IAAsC,MAAK;IAAW,UAAU;cAC7D;GACE,GAFK,GAAG,EAAO,SAAS,GAExB,CACN;EACE,CAAA,CACF;;AAET"}
1
+ {"version":3,"file":"ActionList-D2GC2qPX.js","names":[],"sources":["../src/components/ActionList/ActionList.module.css","../src/components/ActionList/ActionList.tsx"],"sourcesContent":[".action-list {\n background-color: var(--color-uva-white);\n border-radius: 0.5rem;\n box-shadow: 0 0 6px 2px rgb(0 0 0 / 15%);\n display: none;\n padding: 0.25rem;\n position: absolute;\n right: 0;\n top: calc(100% + 0.5rem);\n z-index: 100;\n}\n\n.action-list--open {\n display: block;\n}\n\n.action-list-container {\n position: relative;\n}\n\n.action-list [role=\"menuitem\"] > * {\n background: 0;\n border: 0;\n border-radius: 0.25rem;\n cursor: pointer;\n display: block;\n font: inherit;\n margin: 0;\n padding: 0.5rem 0.75rem;\n text-align: left;\n white-space: pre;\n width: 100%;\n}\n\n.action-list [role=\"menuitem\"] > *:not(:last-of-type) {\n border-bottom: 1px solid var(--color-grey-300);\n}\n\n.action-list [role=\"menuitem\"] > *:hover {\n background-color: var(--color-grey-200);\n}\n","import { clsx } from 'clsx';\nimport { Children, useEffect, useId, useRef, useState } from 'react';\n\nimport type { KeyboardEvent, MouseEvent as ReactMouseEvent, ReactElement, RefObject } from 'react';\nimport type { IconProps } from 'components/Icon';\nimport type { UIButtonVariant } from 'types/UserInterface';\n\nimport styles from './ActionList.module.css';\n\nimport { Icon } from 'components/Icon';\nimport { MenuButton } from 'components/Buttons';\n\nexport interface ActionListProps {\n /** The label that is displayed before the icon. */\n label: string;\n /** The icon that is shown in front of the label. */\n prefixIcon?: IconProps['name'];\n /** The icon that is shown to toggle the menu. If none is specified, CheveronUp and CheveronDown is used depending on whether the menu is opened or closed. */\n iconName?: IconProps['name'];\n /** Determines the button variant. */\n variant?: UIButtonVariant;\n /** The child component(s). */\n children: ReactElement | ReactElement[];\n}\n\nconst inactiveIndex = -1;\nconst indexIncrement = 1;\n\n/** A component to show an action list to toggle a menu. */\nexport function ActionList({ label, prefixIcon, iconName, variant = 'secondary', children }: ActionListProps) {\n const listId = useId();\n const triggerRef = useRef<HTMLButtonElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n const numberOfChildren = Children.count(children);\n\n const [activeIndex, setActiveIndex] = useState(inactiveIndex);\n const [isOpen, setIsOpen] = useState(false);\n\n function open() {\n setIsOpen(true);\n\n document.addEventListener('click', onClickOutside, { once: true, capture: true });\n }\n\n function close(event?: ReactMouseEvent<HTMLDivElement>) {\n // When a click occurs on an element that is not an immediate descendant of the action list container\n // (can happen when a modal window is triggered from a button in the action list), the setIsOpen state\n // handler should not be called, because this causes a re-render of the entire component and can lead\n // to undesired effects, like a select element closing immediately after it has been clicked.\n if (event && containerRef.current && !containerRef.current.contains(event.target as Node)) {\n return;\n }\n\n setActiveIndex(inactiveIndex);\n setIsOpen(false);\n\n document.removeEventListener('click', onClickOutside, { capture: true });\n }\n\n function toggle() {\n if (isOpen) close();\n else open();\n }\n\n function onKeyDown(event: KeyboardEvent) {\n if (!isOpen) return;\n\n const eventPreventCodes = ['ArrowUp', 'ArrowDown', 'Home', 'End'];\n\n if (eventPreventCodes.includes(event.code)) {\n // prevent page from scrolling when navigating through items in list\n event.preventDefault();\n }\n\n if (event.code === 'Tab') {\n close();\n }\n }\n\n function onKeyUp(event: KeyboardEvent) {\n if (event.code === 'Space' || event.key === 'Enter') {\n if (event.target === triggerRef.current) {\n toggle();\n } else if (event.key === 'Enter' && event.target !== listRef.current) {\n if ('firstChild' in event.target) {\n const firstChild = event.target.firstChild as HTMLButtonElement;\n\n firstChild.click();\n }\n }\n }\n\n if (event.code === 'Escape') close();\n\n if (event.code === 'ArrowUp') {\n setActiveIndex((prevState) => {\n if (prevState === 0) return numberOfChildren - indexIncrement;\n\n return prevState - indexIncrement;\n });\n }\n\n if (event.code === 'ArrowDown') {\n setActiveIndex((prevState) => {\n if (prevState === numberOfChildren - indexIncrement) return 0;\n\n return prevState + indexIncrement;\n });\n }\n\n if (event.code === 'Home') {\n setActiveIndex(0);\n }\n\n if (event.code === 'End') {\n setActiveIndex(numberOfChildren - indexIncrement);\n }\n }\n\n const onClickOutside = (event: MouseEvent) => {\n const { target } = event;\n\n if (!target || !containerRef.current) return;\n\n if (!containerRef.current.contains(target as Node)) {\n close();\n }\n };\n\n useEffect(() => {\n if (activeIndex < 0 || !listRef.current) return;\n\n const listItem = listRef.current.children.item(activeIndex);\n\n if (listItem) {\n (listItem as HTMLDivElement).focus();\n }\n }, [activeIndex]);\n\n useEffect(() => {\n if (!listRef.current || !listRef.current.hasChildNodes()) return;\n\n Array.from(listRef.current.children)\n .filter((overlayChild) => overlayChild.nodeType === Node.ELEMENT_NODE && overlayChild.hasChildNodes())\n .forEach((overlayChild) => {\n Array.from(overlayChild.children)\n .filter((childOfChild) => childOfChild.nodeType === Node.ELEMENT_NODE)\n .forEach((childOfChild) => {\n // internal children may be buttons and can get focus when tab is pressed; preventing those elements\n // from getting focus so that list can be tabbed over and traversed with arrow keys\n childOfChild.setAttribute('tabIndex', '-1');\n });\n });\n }, [children]);\n\n return (\n <div className={styles['action-list-container']} ref={containerRef}>\n <MenuButton\n onClick={toggle}\n onKeyDown={onKeyDown}\n onKeyUp={onKeyUp}\n buttonRef={triggerRef as RefObject<HTMLButtonElement>}\n variant={variant}\n >\n {prefixIcon && <Icon size={24} name={prefixIcon} />}\n {label}\n {iconName ? (\n <Icon size={24} name={iconName} />\n ) : (\n <Icon size={16} name={isOpen ? 'CheveronUp' : 'CheveronDown'} />\n )}\n </MenuButton>\n <div\n aria-activedescendant={`${listId}-child-${activeIndex}`}\n aria-label={label}\n className={clsx(styles['action-list'], {\n [styles['action-list--open']]: isOpen,\n })}\n onClickCapture={close}\n onKeyDown={onKeyDown}\n onKeyUp={onKeyUp}\n ref={listRef}\n role=\"menu\"\n tabIndex={-1}\n >\n {Children.map(children, (child, index) => (\n <div key={`${listId}-child-${index}`} role=\"menuitem\" tabIndex={-1}>\n {child}\n </div>\n ))}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"AddCatalogueLinkForm-Di0xm7Ep.js","names":[],"sources":["../src/components/RteEditor/Plugins/CourseCataloguePlugin/AddCatalogueLinkForm/AddCatalogueLinkForm.module.css","../src/components/RteEditor/Plugins/CourseCataloguePlugin/AddCatalogueLinkForm/AddCatalogueLinkForm.tsx"],"sourcesContent":[".courselinkform {\n font-family: inherit;\n font-size: inherit;\n width: 30rem;\n}\n\n.courselinkform__input-field {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.courselinkform__footer {\n display: flex;\n gap: 0.5rem;\n justify-content: flex-end;\n margin-top: 1rem;\n}\n\n.courselinkform__results-wrapper {\n position: relative;\n}\n\n.courselinkform__results-header {\n align-items: center;\n display: flex;\n font-size: var(--font-size-text-base);\n gap: 0.5rem;\n padding: 0.5rem;\n text-align: left;\n width: 100%;\n}\n\n.courselinkform__results {\n border: 1px solid var(--color-grey-300);\n border-radius: 0.25rem;\n max-height: 10rem;\n overflow-y: auto;\n}\n\n.courselinkform__result-message {\n align-items: center;\n color: var(--color-grey-600);\n display: flex;\n font-size: var(--font-size-text-non-essential);\n height: 2rem;\n justify-content: flex-start;\n padding: 0 0.5rem;\n}\n\n.courselinkform__result-item {\n align-items: center;\n appearance: none;\n background-color: transparent;\n border: none;\n cursor: pointer;\n display: flex;\n font-family: inherit;\n font-size: var(--font-size-text-base);\n gap: 0.5rem;\n min-height: 2.5rem;\n padding: 0.5rem;\n text-align: left;\n width: 100%;\n}\n\n.courselinkform__results-header span,\n.courselinkform__result-item span {\n line-height: 1.4;\n width: calc(100% - 9rem);\n}\n\n.courselinkform__results-header span:first-child,\n.courselinkform__result-item span:first-child {\n width: 9rem;\n}\n\n.courselinkform__result-item:focus-visible {\n background-color: var(--color-grey-300);\n outline: none;\n}\n\n.courselinkform__result-item:hover,\n.courselinkform__result-item:focus-visible {\n background-color: var(--color-grey-300);\n}\n\n.courselinkform__result-item:not(:last-child) {\n border-bottom: 1px solid var(--color-grey-300);\n}\n","import { useEffect, useId, useRef } from 'react';\r\n\r\nimport type { KeyboardEvent } from 'react';\r\n\r\nimport styles from './AddCatalogueLinkForm.module.css';\r\n\r\nimport { Button } from 'components/Buttons';\r\nimport { FormField } from 'components/FormField';\r\nimport { Label } from 'components/Label';\r\nimport { useTranslation } from 'components/RteEditor/hooks/useTranslation';\r\nimport { InputField } from 'components/InputField';\r\nimport { useLanguage } from 'components/RteEditor/Providers/LanguageProvider';\r\nimport { Repeater } from 'components/Repeater';\r\n\r\ntype SearchResult = {\r\n code: string;\r\n id: string;\r\n name: {\r\n EN: string;\r\n NL: string;\r\n };\r\n programmeType: string;\r\n};\r\n\r\nexport type SearchResponse = {\r\n state: 'idle' | 'pending' | 'ready';\r\n results: SearchResult[];\r\n};\r\n\r\ninterface AddCatalogueLinkFormProps {\r\n linkType: 'course' | 'programme';\r\n onCloseHandler: () => void;\r\n onSearchHandler: (query: string, type: 'course' | 'programme') => void;\r\n searchResponse?: SearchResponse;\r\n onSelect?: (code: string, label: string, type: 'course' | 'programme') => void;\r\n}\r\n\r\nexport const AddCatalogueLinkForm = ({\r\n linkType,\r\n onCloseHandler,\r\n onSearchHandler,\r\n searchResponse,\r\n onSelect,\r\n}: AddCatalogueLinkFormProps) => {\r\n const t = useTranslation();\r\n const searchId = `search_${useId()}`;\r\n const searchFieldRef = useRef<HTMLInputElement>(null);\r\n const resultListRef = useRef<HTMLDivElement>(null);\r\n const { currentLanguage } = useLanguage();\r\n\r\n const handleSearch = (event: React.ChangeEvent<HTMLInputElement>) => {\r\n const query = event.target.value;\r\n if (onSearchHandler) {\r\n onSearchHandler(query, linkType);\r\n }\r\n };\r\n\r\n const handleClose = () => {\r\n onCloseHandler();\r\n };\r\n\r\n const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\r\n if (event.key === 'ArrowDown') {\r\n event.preventDefault();\r\n const container = resultListRef.current;\r\n const firstFocusable = container?.querySelector<HTMLElement>('button');\r\n firstFocusable?.focus();\r\n }\r\n };\r\n\r\n const onResultKeyDown = (\r\n event: KeyboardEvent<HTMLButtonElement>,\r\n code: string,\r\n name: string,\r\n linkType: 'course' | 'programme'\r\n ) => {\r\n switch (event.key) {\r\n case 'Escape':\r\n event.preventDefault();\r\n event.stopPropagation();\r\n handleClose();\r\n break;\r\n case 'Enter':\r\n event.preventDefault();\r\n onSelect && onSelect(code, name, linkType);\r\n break;\r\n case 'ArrowDown': {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n const nextElement = event.currentTarget.nextElementSibling;\r\n (nextElement as HTMLButtonElement)?.focus();\r\n break;\r\n }\r\n case 'ArrowUp': {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n const previousElement = event.currentTarget.previousElementSibling;\r\n (previousElement as HTMLButtonElement)?.focus();\r\n break;\r\n }\r\n case 'Tab':\r\n event.preventDefault();\r\n handleClose();\r\n break;\r\n default:\r\n event.preventDefault();\r\n break;\r\n }\r\n };\r\n\r\n useEffect(() => {\r\n if (searchFieldRef.current) {\r\n onSearchHandler('', linkType);\r\n searchFieldRef.current.value = '';\r\n searchFieldRef.current.focus();\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, []);\r\n\r\n return (\r\n <div className={styles['courselinkform']}>\r\n <Repeater gap=\"050\">\r\n <FormField className={styles['courselinkform__input-field']}>\r\n <Label htmlFor={searchId}>\r\n {t.cataloguelinks[linkType === 'course' ? 'searchCourseFieldLabel' : 'searchProgrammeFieldLabel']}\r\n </Label>\r\n <div className={styles['linkform__input-url-wrapper']}>\r\n <InputField\r\n id={searchId}\r\n placeholder={t.cataloguelinks.searchFieldPlaceholder}\r\n onChange={handleSearch}\r\n onKeyDown={handleKeyDown}\r\n ref={searchFieldRef}\r\n aria-label={t.aria.labels.searchField}\r\n />\r\n </div>\r\n </FormField>\r\n {searchResponse && searchResponse.state === 'pending' && (\r\n <div className={styles['courselinkform__result-message']}>{t.cataloguelinks.loading}</div>\r\n )}\r\n {searchResponse && searchResponse.results.length === 0 && searchResponse.state === 'ready' && (\r\n <div className={styles['courselinkform__result-message']}>{t.cataloguelinks.noResults}</div>\r\n )}\r\n {searchResponse && searchResponse.results.length > 0 && (\r\n <div className={styles['courselinkform__results-wrapper']}>\r\n <div className={styles['courselinkform__results-header']}>\r\n <span>\r\n {\r\n t.cataloguelinks[\r\n linkType === 'course' ? 'resultCourseListCatalogNumber' : 'resultProgrammeListCatalogNumber'\r\n ]\r\n }\r\n </span>\r\n <span>{t.cataloguelinks.resultListName}</span>\r\n </div>\r\n <div className={styles['courselinkform__results']} ref={resultListRef}>\r\n {searchResponse.results.map(({ id, code, name }) => (\r\n <button\r\n key={id}\r\n type=\"button\"\r\n className={styles['courselinkform__result-item']}\r\n onClick={() => onSelect && onSelect(code, name[currentLanguage], linkType)}\r\n onKeyDown={(event) => onResultKeyDown(event, code, name[currentLanguage], linkType)}\r\n tabIndex={0}\r\n aria-label={`${code} ${name[currentLanguage]}`}\r\n >\r\n <span>{code}</span>\r\n <span>{name[currentLanguage]}</span>\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </Repeater>\r\n <div className={styles['courselinkform__footer']}>\r\n <Button variant={'secondary'} onClick={handleClose} aria-label={t.common.cancel} type=\"button\">\r\n {t.common.cancel}\r\n </Button>\r\n </div>\r\n </div>\r\n );\r\n};\r\n"],"mappings":";;;;;;;;;;;;;;;;;;GCqCa,KAAwB,EACnC,aACA,mBACA,oBACA,mBACA,kBAC+B;CAC/B,IAAM,IAAI,EAAe,GACnB,IAAW,UAAU,EAAM,KAC3B,IAAiB,EAAyB,IAAI,GAC9C,IAAgB,EAAuB,IAAI,GAC3C,EAAE,uBAAoB,EAAY,GAElC,KAAgB,MAA+C;EACnE,IAAM,IAAQ,EAAM,OAAO;EAC3B,AAAI,KACF,EAAgB,GAAO,CAAQ;CAEnC,GAEM,UAAoB;EACxB,EAAe;CACjB,GAEM,KAAiB,MAA2C;EAChE,AAAI,EAAM,QAAQ,gBAChB,EAAM,eAAe,IACH,EAAc,SACE,cAA2B,QAAQ,IACrD,MAAM;CAE1B,GAEM,KACJ,GACA,GACA,GACA,MACG;EACH,QAAQ,EAAM,KAAd;GACE,KAAK;IAGH,AAFA,EAAM,eAAe,GACrB,EAAM,gBAAgB,GACtB,EAAY;IACZ;GACF,KAAK;IAEH,AADA,EAAM,eAAe,GACrB,KAAY,EAAS,GAAM,GAAM,CAAQ;IACzC;GACF,KAAK;IAIH,AAHA,EAAM,eAAe,GACrB,EAAM,gBAAgB,GAEtB,EAD0B,cAAc,oBACJ,MAAM;IAC1C;GAEF,KAAK;IAIH,AAHA,EAAM,eAAe,GACrB,EAAM,gBAAgB,GAEtB,EAD8B,cAAc,wBACJ,MAAM;IAC9C;GAEF,KAAK;IAEH,AADA,EAAM,eAAe,GACrB,EAAY;IACZ;GACF;IACE,EAAM,eAAe;IACrB;EACJ;CACF;CAWA,OATA,QAAgB;EACd,AAAI,EAAe,YACjB,EAAgB,IAAI,CAAQ,GAC5B,EAAe,QAAQ,QAAQ,IAC/B,EAAe,QAAQ,MAAM;CAGjC,GAAG,CAAC,CAAC,GAGH,kBAAC,OAAD;EAAK,WAAW,EAAO;YAAvB,CACE,kBAAC,GAAD;GAAU,KAAI;aAAd;IACE,kBAAC,GAAD;KAAW,WAAW,EAAO;eAA7B,CACE,kBAAC,GAAD;MAAO,SAAS;gBACb,EAAE,eAAe,MAAa,WAAW,2BAA2B;KAChE,CAAA,GACP,kBAAC,OAAD;MAAK,WAAW,EAAO;gBACrB,kBAAC,GAAD;OACE,IAAI;OACJ,aAAa,EAAE,eAAe;OAC9B,UAAU;OACV,WAAW;OACX,KAAK;OACL,cAAY,EAAE,KAAK,OAAO;MAC3B,CAAA;KACE,CAAA,CACI;;IACV,KAAkB,EAAe,UAAU,aAC1C,kBAAC,OAAD;KAAK,WAAW,EAAO;eAAoC,EAAE,eAAe;IAAa,CAAA;IAE1F,KAAkB,EAAe,QAAQ,WAAW,KAAK,EAAe,UAAU,WACjF,kBAAC,OAAD;KAAK,WAAW,EAAO;eAAoC,EAAE,eAAe;IAAe,CAAA;IAE5F,KAAkB,EAAe,QAAQ,SAAS,KACjD,kBAAC,OAAD;KAAK,WAAW,EAAO;eAAvB,CACE,kBAAC,OAAD;MAAK,WAAW,EAAO;gBAAvB,CACE,kBAAC,QAAD,EAAA,UAEI,EAAE,eACA,MAAa,WAAW,kCAAkC,oCAG1D,CAAA,GACN,kBAAC,QAAD,EAAA,UAAO,EAAE,eAAe,eAAqB,CAAA,CAC1C;SACL,kBAAC,OAAD;MAAK,WAAW,EAAO;MAA4B,KAAK;gBACrD,EAAe,QAAQ,KAAK,EAAE,OAAI,SAAM,cACvC,kBAAC,UAAD;OAEE,MAAK;OACL,WAAW,EAAO;OAClB,eAAe,KAAY,EAAS,GAAM,EAAK,IAAkB,CAAQ;OACzE,YAAY,MAAU,EAAgB,GAAO,GAAM,EAAK,IAAkB,CAAQ;OAClF,UAAU;OACV,cAAY,GAAG,EAAK,GAAG,EAAK;iBAP9B,CASE,kBAAC,QAAD,EAAA,UAAO,EAAW,CAAA,GAClB,kBAAC,QAAD,EAAA,UAAO,EAAK,GAAuB,CAAA,CAC7B;SAVD,CAUC,CACT;KACE,CAAA,CACF;;GAEC;MACV,kBAAC,OAAD;GAAK,WAAW,EAAO;aACrB,kBAAC,GAAD;IAAQ,SAAS;IAAa,SAAS;IAAa,cAAY,EAAE,OAAO;IAAQ,MAAK;cACnF,EAAE,OAAO;GACJ,CAAA;EACL,CAAA,CACF;;AAET"}
1
+ {"version":3,"file":"AddCatalogueLinkForm-Di0xm7Ep.js","names":[],"sources":["../src/components/RteEditor/Plugins/CourseCataloguePlugin/AddCatalogueLinkForm/AddCatalogueLinkForm.module.css","../src/components/RteEditor/Plugins/CourseCataloguePlugin/AddCatalogueLinkForm/AddCatalogueLinkForm.tsx"],"sourcesContent":[".courselinkform {\n font-family: inherit;\n font-size: inherit;\n width: 30rem;\n}\n\n.courselinkform__input-field {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.courselinkform__footer {\n display: flex;\n gap: 0.5rem;\n justify-content: flex-end;\n margin-top: 1rem;\n}\n\n.courselinkform__results-wrapper {\n position: relative;\n}\n\n.courselinkform__results-header {\n align-items: center;\n display: flex;\n font-size: var(--font-size-text-base);\n gap: 0.5rem;\n padding: 0.5rem;\n text-align: left;\n width: 100%;\n}\n\n.courselinkform__results {\n border: 1px solid var(--color-grey-300);\n border-radius: 0.25rem;\n max-height: 10rem;\n overflow-y: auto;\n}\n\n.courselinkform__result-message {\n align-items: center;\n color: var(--color-grey-600);\n display: flex;\n font-size: var(--font-size-text-non-essential);\n height: 2rem;\n justify-content: flex-start;\n padding: 0 0.5rem;\n}\n\n.courselinkform__result-item {\n align-items: center;\n appearance: none;\n background-color: transparent;\n border: none;\n cursor: pointer;\n display: flex;\n font-family: inherit;\n font-size: var(--font-size-text-base);\n gap: 0.5rem;\n min-height: 2.5rem;\n padding: 0.5rem;\n text-align: left;\n width: 100%;\n}\n\n.courselinkform__results-header span,\n.courselinkform__result-item span {\n line-height: 1.4;\n width: calc(100% - 9rem);\n}\n\n.courselinkform__results-header span:first-child,\n.courselinkform__result-item span:first-child {\n width: 9rem;\n}\n\n.courselinkform__result-item:focus-visible {\n background-color: var(--color-grey-300);\n outline: none;\n}\n\n.courselinkform__result-item:hover,\n.courselinkform__result-item:focus-visible {\n background-color: var(--color-grey-300);\n}\n\n.courselinkform__result-item:not(:last-child) {\n border-bottom: 1px solid var(--color-grey-300);\n}\n","import { useEffect, useId, useRef } from 'react';\r\n\r\nimport type { KeyboardEvent } from 'react';\r\n\r\nimport styles from './AddCatalogueLinkForm.module.css';\r\n\r\nimport { Button } from 'components/Buttons';\r\nimport { FormField } from 'components/FormField';\r\nimport { Label } from 'components/Label';\r\nimport { useTranslation } from 'components/RteEditor/hooks/useTranslation';\r\nimport { InputField } from 'components/InputField';\r\nimport { useLanguage } from 'components/RteEditor/Providers/LanguageProvider';\r\nimport { Repeater } from 'components/Repeater';\r\n\r\ntype SearchResult = {\r\n code: string;\r\n id: string;\r\n name: {\r\n EN: string;\r\n NL: string;\r\n };\r\n programmeType: string;\r\n};\r\n\r\nexport type SearchResponse = {\r\n state: 'idle' | 'pending' | 'ready';\r\n results: SearchResult[];\r\n};\r\n\r\ninterface AddCatalogueLinkFormProps {\r\n linkType: 'course' | 'programme';\r\n onCloseHandler: () => void;\r\n onSearchHandler: (query: string, type: 'course' | 'programme') => void;\r\n searchResponse?: SearchResponse;\r\n onSelect?: (code: string, label: string, type: 'course' | 'programme') => void;\r\n}\r\n\r\nexport const AddCatalogueLinkForm = ({\r\n linkType,\r\n onCloseHandler,\r\n onSearchHandler,\r\n searchResponse,\r\n onSelect,\r\n}: AddCatalogueLinkFormProps) => {\r\n const t = useTranslation();\r\n const searchId = `search_${useId()}`;\r\n const searchFieldRef = useRef<HTMLInputElement>(null);\r\n const resultListRef = useRef<HTMLDivElement>(null);\r\n const { currentLanguage } = useLanguage();\r\n\r\n const handleSearch = (event: React.ChangeEvent<HTMLInputElement>) => {\r\n const query = event.target.value;\r\n if (onSearchHandler) {\r\n onSearchHandler(query, linkType);\r\n }\r\n };\r\n\r\n const handleClose = () => {\r\n onCloseHandler();\r\n };\r\n\r\n const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\r\n if (event.key === 'ArrowDown') {\r\n event.preventDefault();\r\n const container = resultListRef.current;\r\n const firstFocusable = container?.querySelector<HTMLElement>('button');\r\n firstFocusable?.focus();\r\n }\r\n };\r\n\r\n const onResultKeyDown = (\r\n event: KeyboardEvent<HTMLButtonElement>,\r\n code: string,\r\n name: string,\r\n linkType: 'course' | 'programme'\r\n ) => {\r\n switch (event.key) {\r\n case 'Escape':\r\n event.preventDefault();\r\n event.stopPropagation();\r\n handleClose();\r\n break;\r\n case 'Enter':\r\n event.preventDefault();\r\n onSelect && onSelect(code, name, linkType);\r\n break;\r\n case 'ArrowDown': {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n const nextElement = event.currentTarget.nextElementSibling;\r\n (nextElement as HTMLButtonElement)?.focus();\r\n break;\r\n }\r\n case 'ArrowUp': {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n const previousElement = event.currentTarget.previousElementSibling;\r\n (previousElement as HTMLButtonElement)?.focus();\r\n break;\r\n }\r\n case 'Tab':\r\n event.preventDefault();\r\n handleClose();\r\n break;\r\n default:\r\n event.preventDefault();\r\n break;\r\n }\r\n };\r\n\r\n useEffect(() => {\r\n if (searchFieldRef.current) {\r\n onSearchHandler('', linkType);\r\n searchFieldRef.current.value = '';\r\n searchFieldRef.current.focus();\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, []);\r\n\r\n return (\r\n <div className={styles['courselinkform']}>\r\n <Repeater gap=\"050\">\r\n <FormField className={styles['courselinkform__input-field']}>\r\n <Label htmlFor={searchId}>\r\n {t.cataloguelinks[linkType === 'course' ? 'searchCourseFieldLabel' : 'searchProgrammeFieldLabel']}\r\n </Label>\r\n <div className={styles['linkform__input-url-wrapper']}>\r\n <InputField\r\n id={searchId}\r\n placeholder={t.cataloguelinks.searchFieldPlaceholder}\r\n onChange={handleSearch}\r\n onKeyDown={handleKeyDown}\r\n ref={searchFieldRef}\r\n aria-label={t.aria.labels.searchField}\r\n />\r\n </div>\r\n </FormField>\r\n {searchResponse && searchResponse.state === 'pending' && (\r\n <div className={styles['courselinkform__result-message']}>{t.cataloguelinks.loading}</div>\r\n )}\r\n {searchResponse && searchResponse.results.length === 0 && searchResponse.state === 'ready' && (\r\n <div className={styles['courselinkform__result-message']}>{t.cataloguelinks.noResults}</div>\r\n )}\r\n {searchResponse && searchResponse.results.length > 0 && (\r\n <div className={styles['courselinkform__results-wrapper']}>\r\n <div className={styles['courselinkform__results-header']}>\r\n <span>\r\n {\r\n t.cataloguelinks[\r\n linkType === 'course' ? 'resultCourseListCatalogNumber' : 'resultProgrammeListCatalogNumber'\r\n ]\r\n }\r\n </span>\r\n <span>{t.cataloguelinks.resultListName}</span>\r\n </div>\r\n <div className={styles['courselinkform__results']} ref={resultListRef}>\r\n {searchResponse.results.map(({ id, code, name }) => (\r\n <button\r\n key={id}\r\n type=\"button\"\r\n className={styles['courselinkform__result-item']}\r\n onClick={() => onSelect && onSelect(code, name[currentLanguage], linkType)}\r\n onKeyDown={(event) => onResultKeyDown(event, code, name[currentLanguage], linkType)}\r\n tabIndex={0}\r\n aria-label={`${code} ${name[currentLanguage]}`}\r\n >\r\n <span>{code}</span>\r\n <span>{name[currentLanguage]}</span>\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </Repeater>\r\n <div className={styles['courselinkform__footer']}>\r\n <Button variant={'secondary'} onClick={handleClose} aria-label={t.common.cancel} type=\"button\">\r\n {t.common.cancel}\r\n </Button>\r\n </div>\r\n </div>\r\n );\r\n};\r\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ClipboardButton-Cg6LGUiD.js","names":[],"sources":["../src/storyComponents/ClipboardButton/ClipboardButton.module.css","../src/storyComponents/ClipboardButton/ClipboardButton.tsx"],"sourcesContent":[".clipboard-button {\n align-items: center;\n appearance: none;\n background-color: transparent;\n border: none;\n color: #000;\n cursor: pointer;\n display: inline-flex;\n font-size: 0.875rem;\n font-weight: 500;\n height: 1.5rem;\n justify-content: center;\n outline: none;\n transition: all 0.15s;\n width: 1.5rem;\n}\n\n.clipboard-button:focus-visible {\n box-shadow: 0 0 0 0.125rem #000;\n outline: 2px solid #000;\n}\n\n.clipboard-button:hover {\n color: #bd0032;\n}\n\n.clipboard-button:disabled {\n opacity: 0.5;\n pointer-events: none;\n}\n","import { useState } from 'react';\n\nimport styles from './ClipboardButton.module.css';\n\ninterface ClipboardButtonProps {\n text: string;\n}\n\nconst DELAY = 2000;\n\nexport const ClipboardButton = ({ text }: ClipboardButtonProps) => {\n const [isCopied, setIsCopied] = useState(false);\n\n const handleCopyClick = () => {\n if (!isCopied) {\n void navigator.clipboard.writeText(text).then(() => {\n setIsCopied(true);\n setTimeout(() => {\n setIsCopied(false);\n }, DELAY);\n });\n }\n };\n\n return (\n <div style={{ position: 'relative' }}>\n <button onClick={handleCopyClick} className={styles['clipboard-button']} aria-label={`Copy ${text}`}>\n <svg\n width=\"15\"\n height=\"15\"\n viewBox=\"0 0 15 15\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-3 w-3\"\n >\n {isCopied ? (\n <path\n d=\"M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n />\n ) : (\n <path\n d=\"M1 9.50006C1 10.3285 1.67157 11.0001 2.5 11.0001H4L4 10.0001H2.5C2.22386 10.0001 2 9.7762 2 9.50006L2 2.50006C2 2.22392 2.22386 2.00006 2.5 2.00006L9.5 2.00006C9.77614 2.00006 10 2.22392 10 2.50006V4.00002H5.5C4.67158 4.00002 4 4.67159 4 5.50002V12.5C4 13.3284 4.67158 14 5.5 14H12.5C13.3284 14 14 13.3284 14 12.5V5.50002C14 4.67159 13.3284 4.00002 12.5 4.00002H11V2.50006C11 1.67163 10.3284 1.00006 9.5 1.00006H2.5C1.67157 1.00006 1 1.67163 1 2.50006V9.50006ZM5 5.50002C5 5.22388 5.22386 5.00002 5.5 5.00002H12.5C12.7761 5.00002 13 5.22388 13 5.50002V12.5C13 12.7762 12.7761 13 12.5 13H5.5C5.22386 13 5 12.7762 5 12.5V5.50002Z\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n />\n )}\n </svg>\n </button>\n </div>\n );\n};\n"],"mappings":";;;6DCQM,IAAQ,KAED,KAAmB,EAAE,cAAiC;CACjE,IAAM,CAAC,GAAU,KAAe,EAAS,EAAK;CAa9C,OACE,kBAAC,OAAD;EAAK,OAAO,EAAE,UAAU,WAAW;YACjC,kBAAC,UAAD;GAAQ,eAbkB;IAC5B,AAAK,KACH,UAAe,UAAU,UAAU,CAAI,EAAE,WAAW;KAElD,AADA,EAAY,EAAI,GAChB,iBAAiB;MACf,EAAY,EAAK;KACnB,GAAG,CAAK;IACV,CAAC;GAEL;GAIsC,WAAW,EAAO;GAAqB,cAAY,QAAQ;aAC3F,kBAAC,OAAD;IACE,OAAM;IACN,QAAO;IACP,SAAQ;IACR,MAAK;IACL,OAAM;IACN,WAAU;cAET,IACC,kBAAC,QAAD;KACE,GAAE;KACF,MAAK;KACL,UAAS;KACT,UAAS;IACV,CAAA,IAED,kBAAC,QAAD;KACE,GAAE;KACF,MAAK;KACL,UAAS;KACT,UAAS;IACV,CAAA;GAEA,CAAA;EACC,CAAA;CACL,CAAA;AAET"}
1
+ {"version":3,"file":"ClipboardButton-Cg6LGUiD.js","names":[],"sources":["../src/storyComponents/ClipboardButton/ClipboardButton.module.css","../src/storyComponents/ClipboardButton/ClipboardButton.tsx"],"sourcesContent":[".clipboard-button {\n align-items: center;\n appearance: none;\n background-color: transparent;\n border: none;\n color: #000;\n cursor: pointer;\n display: inline-flex;\n font-size: 0.875rem;\n font-weight: 500;\n height: 1.5rem;\n justify-content: center;\n outline: none;\n transition: all 0.15s;\n width: 1.5rem;\n}\n\n.clipboard-button:focus-visible {\n box-shadow: 0 0 0 0.125rem #000;\n outline: 2px solid #000;\n}\n\n.clipboard-button:hover {\n color: #bd0032;\n}\n\n.clipboard-button:disabled {\n opacity: 0.5;\n pointer-events: none;\n}\n","import { useState } from 'react';\n\nimport styles from './ClipboardButton.module.css';\n\ninterface ClipboardButtonProps {\n text: string;\n}\n\nconst DELAY = 2000;\n\nexport const ClipboardButton = ({ text }: ClipboardButtonProps) => {\n const [isCopied, setIsCopied] = useState(false);\n\n const handleCopyClick = () => {\n if (!isCopied) {\n void navigator.clipboard.writeText(text).then(() => {\n setIsCopied(true);\n setTimeout(() => {\n setIsCopied(false);\n }, DELAY);\n });\n }\n };\n\n return (\n <div style={{ position: 'relative' }}>\n <button onClick={handleCopyClick} className={styles['clipboard-button']} aria-label={`Copy ${text}`}>\n <svg\n width=\"15\"\n height=\"15\"\n viewBox=\"0 0 15 15\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-3 w-3\"\n >\n {isCopied ? (\n <path\n d=\"M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n />\n ) : (\n <path\n d=\"M1 9.50006C1 10.3285 1.67157 11.0001 2.5 11.0001H4L4 10.0001H2.5C2.22386 10.0001 2 9.7762 2 9.50006L2 2.50006C2 2.22392 2.22386 2.00006 2.5 2.00006L9.5 2.00006C9.77614 2.00006 10 2.22392 10 2.50006V4.00002H5.5C4.67158 4.00002 4 4.67159 4 5.50002V12.5C4 13.3284 4.67158 14 5.5 14H12.5C13.3284 14 14 13.3284 14 12.5V5.50002C14 4.67159 13.3284 4.00002 12.5 4.00002H11V2.50006C11 1.67163 10.3284 1.00006 9.5 1.00006H2.5C1.67157 1.00006 1 1.67163 1 2.50006V9.50006ZM5 5.50002C5 5.22388 5.22386 5.00002 5.5 5.00002H12.5C12.7761 5.00002 13 5.22388 13 5.50002V12.5C13 12.7762 12.7761 13 12.5 13H5.5C5.22386 13 5 12.7762 5 12.5V5.50002Z\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n />\n )}\n </svg>\n </button>\n </div>\n );\n};\n"],"mappings":";;;6DCQM,IAAQ,KAED,KAAmB,EAAE,cAAiC;CACjE,IAAM,CAAC,GAAU,KAAe,EAAS,EAAK;CAa9C,OACE,kBAAC,OAAD;EAAK,OAAO,EAAE,UAAU,WAAW;YACjC,kBAAC,UAAD;GAAQ,eAbkB;IAC5B,AAAK,KACH,UAAe,UAAU,UAAU,CAAI,CAAC,CAAC,WAAW;KAElD,AADA,EAAY,EAAI,GAChB,iBAAiB;MACf,EAAY,EAAK;KACnB,GAAG,CAAK;IACV,CAAC;GAEL;GAIsC,WAAW,EAAO;GAAqB,cAAY,QAAQ;aAC3F,kBAAC,OAAD;IACE,OAAM;IACN,QAAO;IACP,SAAQ;IACR,MAAK;IACL,OAAM;IACN,WAAU;cAET,IACC,kBAAC,QAAD;KACE,GAAE;KACF,MAAK;KACL,UAAS;KACT,UAAS;IACV,CAAA,IAED,kBAAC,QAAD;KACE,GAAE;KACF,MAAK;KACL,UAAS;KACT,UAAS;IACV,CAAA;GAEA,CAAA;EACC,CAAA;CACL,CAAA;AAET"}
@@ -1 +1 @@
1
- {"version":3,"file":"ControlsButton-Byx4XQtB.js","names":[],"sources":["../src/components/ControlsButton/ControlsButton.module.css","../src/components/ControlsButton/ControlsButton.tsx"],"sourcesContent":[".controls-input {\n aspect-ratio: unset;\n cursor: pointer;\n height: 0;\n opacity: 0;\n position: absolute;\n width: 0;\n}\n\n.controls-input:focus-visible + label {\n outline: 0.125rem dotted var(--color-navy-600);\n outline-offset: 0.125rem;\n}\n\n.controls-input:checked + label,\n[type=\"radio\"]:checked:hover + label {\n background-color: var(--color-navy-600);\n color: var(--color-uva-white);\n font-weight: var(--semibold);\n}\n\n.controls-input:disabled + label,\n.controls-input:disabled:hover + label {\n background-color: var(--color-grey-400);\n color: var(--color-grey-700);\n cursor: not-allowed;\n}\n\n.controls-input:disabled:checked + label {\n background-color: var(--color-grey-500);\n color: var(--color-grey-900);\n font-weight: var(--semibold);\n}\n\n.controls-input:hover + label {\n background-color: var(--color-grey-300);\n color: var(--color-uva-black);\n}\n\n.controls-button {\n align-items: center;\n background-color: var(--color-uva-white);\n border: 1px solid transparent;\n border-radius: 0.25rem;\n box-sizing: border-box;\n cursor: pointer;\n display: inline-flex;\n font-size: var(--font-size-default);\n height: 2.25rem;\n justify-content: center;\n min-width: 2.25rem;\n padding: 0.5rem;\n position: relative;\n user-select: none;\n white-space: nowrap;\n}\n\n.controls-button--squared {\n width: 2.25rem;\n}\n\n.controls-button::after {\n content: \"\";\n min-height: 2.625rem;\n min-width: 2.625rem;\n position: absolute;\n width: 100%;\n}\n\n.controls-button--with-prefix {\n height: auto;\n padding: 0.125rem 0.5rem;\n width: auto;\n}\n\n.controls-button--with-icon {\n gap: 0.5rem;\n}\n\n.controls-button__wrapper {\n align-items: center;\n display: flex;\n flex-direction: column;\n}\n\n.controls-button__prefix {\n color: var(--color-uva-700);\n font-size: var(--font-size-text-non-essential);\n}\n\n.controls-button__tooltip {\n background-color: var(--color-uva-white);\n box-shadow: 0 0 0.25rem 0 rgba(0 0 0 / 25%);\n color: var(--color-grey-700);\n display: none;\n font-size: var(--font-size-text-non-essential);\n font-style: italic;\n font-weight: normal;\n padding: 0.5rem 1rem;\n position: absolute;\n text-align: center;\n top: calc(100% + 0.5rem);\n z-index: 1;\n}\n\n.controls-button__tooltip--left {\n left: 0rem;\n}\n\n.controls-button__tooltip--center {\n left: 50%;\n transform: translateX(-50%);\n}\n\n.controls-button__tooltip--right {\n right: 0rem;\n}\n\n.controls-button__tooltip::before {\n border-color: transparent transparent var(--color-grey-400) transparent;\n border-style: solid;\n border-width: 0.5rem;\n bottom: calc(100% + 0.125rem);\n content: \"\";\n filter: blur(0.125rem);\n position: absolute;\n z-index: -1;\n}\n\n.controls-button__tooltip::after {\n border-color: transparent transparent var(--color-uva-white) transparent;\n border-style: solid;\n border-width: 0.5rem;\n bottom: 100%;\n content: \"\";\n position: absolute;\n}\n\n.controls-button:hover .controls-button__tooltip,\n.controls-input:focus-visible + label .controls-button__tooltip {\n display: block;\n}\n\n.controls-button__tooltip--left::before,\n.controls-button__tooltip--left::after {\n left: 0.5rem;\n}\n\n.controls-button__tooltip--center::before,\n.controls-button__tooltip--center::after {\n left: 50%;\n transform: translateX(-50%);\n}\n\n.controls-button__tooltip--right::before,\n.controls-button__tooltip--right::after {\n right: 0.5rem;\n}\n\n.controls-button--checked span.periods__item,\n.controls-button--checked [data-period-item] {\n border: 1px solid var(--color-uva-white) !important;\n}\n","import { useId } from 'react';\r\nimport { clsx } from 'clsx';\r\n\r\nimport type { ChangeEvent, ReactNode } from 'react';\r\nimport type { IconProps } from 'components/Icon';\r\n\r\nimport styles from './ControlsButton.module.css';\r\n\r\nimport { Icon } from 'components/Icon';\r\n\r\nexport interface ControlsButtonProps {\r\n /** to set type/behaviour of input radio or checkbox */\r\n type?: 'radio' | 'checkbox';\r\n /** button label */\r\n label: string | ReactNode;\r\n /** button value */\r\n value: string;\r\n /** set if icon is needed in font of label */\r\n iconName?: IconProps['name'];\r\n /** set if prefix is needed above of label */\r\n prefix?: string;\r\n /** set tooltip */\r\n tooltip?: ReactNode;\r\n /** set horizontal position of the tooltip */\r\n tooltipPosition?: 'left' | 'center' | 'right';\r\n /** set if used as radiogroup */\r\n name?: string;\r\n /** `true` to set squared button; otherwise, `false`. The default is `false`. Note: hides icon */\r\n forceSquared?: boolean;\r\n /** to set default status */\r\n checked?: boolean;\r\n /** `true` to disable the button; otherwise, `false`. The default is `false`. */\r\n disabled?: boolean;\r\n /** The callback function that is invoked when the radio button changes value. */\r\n onSetValue: (event: ChangeEvent<HTMLInputElement>) => void;\r\n}\r\n\r\nexport const ControlsButton = ({\r\n type = 'checkbox',\r\n label,\r\n value,\r\n iconName,\r\n prefix,\r\n tooltip,\r\n tooltipPosition = 'center',\r\n name,\r\n forceSquared = false,\r\n checked,\r\n disabled,\r\n onSetValue,\r\n}: ControlsButtonProps) => {\r\n const idPrefix = useId();\r\n const labelString = typeof label === 'string' ? label : value;\r\n const sanitizedLabel = labelString.replace(/\\s+/g, '_');\r\n const baseId = `${idPrefix}${sanitizedLabel}`;\r\n const tooltipId = `${baseId}-tooltip`;\r\n\r\n return (\r\n <>\r\n <input\r\n type={type}\r\n id={baseId}\r\n name={name ?? sanitizedLabel}\r\n disabled={disabled}\r\n value={value}\r\n checked={checked}\r\n onChange={onSetValue}\r\n className={styles['controls-input']}\r\n aria-describedby={tooltip ? tooltipId : undefined}\r\n />\r\n <label\r\n htmlFor={baseId}\r\n className={clsx(styles['controls-button'], [\r\n forceSquared && styles['controls-button--squared'],\r\n prefix && styles['controls-button--with-prefix'],\r\n iconName && styles['controls-button--with-icon'],\r\n checked && styles['controls-button--checked'],\r\n ])}\r\n >\r\n {iconName && <Icon name={iconName} size={20} />}\r\n <div className={styles['controls-button__wrapper']}>\r\n {prefix && <div className={styles['controls-button__prefix']}>{prefix}</div>}\r\n {label}\r\n </div>\r\n {tooltip && (\r\n <div\r\n id={tooltipId}\r\n role=\"tooltip\"\r\n className={clsx(styles['controls-button__tooltip'], styles[`controls-button__tooltip--${tooltipPosition}`])}\r\n >\r\n {tooltip}\r\n </div>\r\n )}\r\n </label>\r\n </>\r\n );\r\n};\r\n"],"mappings":";;;;;;;;;;;;;;;;;;GCqCa,KAAkB,EAC7B,UAAO,YACP,UACA,UACA,aACA,WACA,YACA,qBAAkB,UAClB,SACA,kBAAe,IACf,YACA,aACA,oBACyB;CACzB,IAAM,IAAW,EAAM,GAEjB,KADc,OAAO,KAAU,WAAW,IAAQ,GACrB,QAAQ,QAAQ,GAAG,GAChD,IAAS,GAAG,IAAW,KACvB,IAAY,GAAG,EAAO;CAE5B,OACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,SAAD;EACQ;EACN,IAAI;EACJ,MAAM,KAAQ;EACJ;EACH;EACE;EACT,UAAU;EACV,WAAW,EAAO;EAClB,oBAAkB,IAAU,IAAY,KAAA;CACzC,CAAA,GACD,kBAAC,SAAD;EACE,SAAS;EACT,WAAW,EAAK,EAAO,oBAAoB;GACzC,KAAgB,EAAO;GACvB,KAAU,EAAO;GACjB,KAAY,EAAO;GACnB,KAAW,EAAO;EACpB,CAAC;YAPH;GASG,KAAY,kBAAC,GAAD;IAAM,MAAM;IAAU,MAAM;GAAK,CAAA;GAC9C,kBAAC,OAAD;IAAK,WAAW,EAAO;cAAvB,CACG,KAAU,kBAAC,OAAD;KAAK,WAAW,EAAO;eAA6B;IAAY,CAAA,GAC1E,CACE;;GACJ,KACC,kBAAC,OAAD;IACE,IAAI;IACJ,MAAK;IACL,WAAW,EAAK,EAAO,6BAA6B,EAAO,6BAA6B,IAAkB;cAEzG;GACE,CAAA;EAEF;GACP,EAAA,CAAA;AAEN"}
1
+ {"version":3,"file":"ControlsButton-Byx4XQtB.js","names":[],"sources":["../src/components/ControlsButton/ControlsButton.module.css","../src/components/ControlsButton/ControlsButton.tsx"],"sourcesContent":[".controls-input {\n aspect-ratio: unset;\n cursor: pointer;\n height: 0;\n opacity: 0;\n position: absolute;\n width: 0;\n}\n\n.controls-input:focus-visible + label {\n outline: 0.125rem dotted var(--color-navy-600);\n outline-offset: 0.125rem;\n}\n\n.controls-input:checked + label,\n[type=\"radio\"]:checked:hover + label {\n background-color: var(--color-navy-600);\n color: var(--color-uva-white);\n font-weight: var(--semibold);\n}\n\n.controls-input:disabled + label,\n.controls-input:disabled:hover + label {\n background-color: var(--color-grey-400);\n color: var(--color-grey-700);\n cursor: not-allowed;\n}\n\n.controls-input:disabled:checked + label {\n background-color: var(--color-grey-500);\n color: var(--color-grey-900);\n font-weight: var(--semibold);\n}\n\n.controls-input:hover + label {\n background-color: var(--color-grey-300);\n color: var(--color-uva-black);\n}\n\n.controls-button {\n align-items: center;\n background-color: var(--color-uva-white);\n border: 1px solid transparent;\n border-radius: 0.25rem;\n box-sizing: border-box;\n cursor: pointer;\n display: inline-flex;\n font-size: var(--font-size-default);\n height: 2.25rem;\n justify-content: center;\n min-width: 2.25rem;\n padding: 0.5rem;\n position: relative;\n user-select: none;\n white-space: nowrap;\n}\n\n.controls-button--squared {\n width: 2.25rem;\n}\n\n.controls-button::after {\n content: \"\";\n min-height: 2.625rem;\n min-width: 2.625rem;\n position: absolute;\n width: 100%;\n}\n\n.controls-button--with-prefix {\n height: auto;\n padding: 0.125rem 0.5rem;\n width: auto;\n}\n\n.controls-button--with-icon {\n gap: 0.5rem;\n}\n\n.controls-button__wrapper {\n align-items: center;\n display: flex;\n flex-direction: column;\n}\n\n.controls-button__prefix {\n color: var(--color-uva-700);\n font-size: var(--font-size-text-non-essential);\n}\n\n.controls-button__tooltip {\n background-color: var(--color-uva-white);\n box-shadow: 0 0 0.25rem 0 rgba(0 0 0 / 25%);\n color: var(--color-grey-700);\n display: none;\n font-size: var(--font-size-text-non-essential);\n font-style: italic;\n font-weight: normal;\n padding: 0.5rem 1rem;\n position: absolute;\n text-align: center;\n top: calc(100% + 0.5rem);\n z-index: 1;\n}\n\n.controls-button__tooltip--left {\n left: 0rem;\n}\n\n.controls-button__tooltip--center {\n left: 50%;\n transform: translateX(-50%);\n}\n\n.controls-button__tooltip--right {\n right: 0rem;\n}\n\n.controls-button__tooltip::before {\n border-color: transparent transparent var(--color-grey-400) transparent;\n border-style: solid;\n border-width: 0.5rem;\n bottom: calc(100% + 0.125rem);\n content: \"\";\n filter: blur(0.125rem);\n position: absolute;\n z-index: -1;\n}\n\n.controls-button__tooltip::after {\n border-color: transparent transparent var(--color-uva-white) transparent;\n border-style: solid;\n border-width: 0.5rem;\n bottom: 100%;\n content: \"\";\n position: absolute;\n}\n\n.controls-button:hover .controls-button__tooltip,\n.controls-input:focus-visible + label .controls-button__tooltip {\n display: block;\n}\n\n.controls-button__tooltip--left::before,\n.controls-button__tooltip--left::after {\n left: 0.5rem;\n}\n\n.controls-button__tooltip--center::before,\n.controls-button__tooltip--center::after {\n left: 50%;\n transform: translateX(-50%);\n}\n\n.controls-button__tooltip--right::before,\n.controls-button__tooltip--right::after {\n right: 0.5rem;\n}\n\n.controls-button--checked span.periods__item,\n.controls-button--checked [data-period-item] {\n border: 1px solid var(--color-uva-white) !important;\n}\n","import { useId } from 'react';\r\nimport { clsx } from 'clsx';\r\n\r\nimport type { ChangeEvent, ReactNode } from 'react';\r\nimport type { IconProps } from 'components/Icon';\r\n\r\nimport styles from './ControlsButton.module.css';\r\n\r\nimport { Icon } from 'components/Icon';\r\n\r\nexport interface ControlsButtonProps {\r\n /** to set type/behaviour of input radio or checkbox */\r\n type?: 'radio' | 'checkbox';\r\n /** button label */\r\n label: string | ReactNode;\r\n /** button value */\r\n value: string;\r\n /** set if icon is needed in font of label */\r\n iconName?: IconProps['name'];\r\n /** set if prefix is needed above of label */\r\n prefix?: string;\r\n /** set tooltip */\r\n tooltip?: ReactNode;\r\n /** set horizontal position of the tooltip */\r\n tooltipPosition?: 'left' | 'center' | 'right';\r\n /** set if used as radiogroup */\r\n name?: string;\r\n /** `true` to set squared button; otherwise, `false`. The default is `false`. Note: hides icon */\r\n forceSquared?: boolean;\r\n /** to set default status */\r\n checked?: boolean;\r\n /** `true` to disable the button; otherwise, `false`. The default is `false`. */\r\n disabled?: boolean;\r\n /** The callback function that is invoked when the radio button changes value. */\r\n onSetValue: (event: ChangeEvent<HTMLInputElement>) => void;\r\n}\r\n\r\nexport const ControlsButton = ({\r\n type = 'checkbox',\r\n label,\r\n value,\r\n iconName,\r\n prefix,\r\n tooltip,\r\n tooltipPosition = 'center',\r\n name,\r\n forceSquared = false,\r\n checked,\r\n disabled,\r\n onSetValue,\r\n}: ControlsButtonProps) => {\r\n const idPrefix = useId();\r\n const labelString = typeof label === 'string' ? label : value;\r\n const sanitizedLabel = labelString.replace(/\\s+/g, '_');\r\n const baseId = `${idPrefix}${sanitizedLabel}`;\r\n const tooltipId = `${baseId}-tooltip`;\r\n\r\n return (\r\n <>\r\n <input\r\n type={type}\r\n id={baseId}\r\n name={name ?? sanitizedLabel}\r\n disabled={disabled}\r\n value={value}\r\n checked={checked}\r\n onChange={onSetValue}\r\n className={styles['controls-input']}\r\n aria-describedby={tooltip ? tooltipId : undefined}\r\n />\r\n <label\r\n htmlFor={baseId}\r\n className={clsx(styles['controls-button'], [\r\n forceSquared && styles['controls-button--squared'],\r\n prefix && styles['controls-button--with-prefix'],\r\n iconName && styles['controls-button--with-icon'],\r\n checked && styles['controls-button--checked'],\r\n ])}\r\n >\r\n {iconName && <Icon name={iconName} size={20} />}\r\n <div className={styles['controls-button__wrapper']}>\r\n {prefix && <div className={styles['controls-button__prefix']}>{prefix}</div>}\r\n {label}\r\n </div>\r\n {tooltip && (\r\n <div\r\n id={tooltipId}\r\n role=\"tooltip\"\r\n className={clsx(styles['controls-button__tooltip'], styles[`controls-button__tooltip--${tooltipPosition}`])}\r\n >\r\n {tooltip}\r\n </div>\r\n )}\r\n </label>\r\n </>\r\n );\r\n};\r\n"],"mappings":";;;;;;;;;;;;;;;;;;GCqCa,KAAkB,EAC7B,UAAO,YACP,UACA,UACA,aACA,WACA,YACA,qBAAkB,UAClB,SACA,kBAAe,IACf,YACA,aACA,oBACyB;CACzB,IAAM,IAAW,EAAM,GAEjB,KADc,OAAO,KAAU,WAAW,IAAQ,EAAA,CACrB,QAAQ,QAAQ,GAAG,GAChD,IAAS,GAAG,IAAW,KACvB,IAAY,GAAG,EAAO;CAE5B,OACE,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,SAAD;EACQ;EACN,IAAI;EACJ,MAAM,KAAQ;EACJ;EACH;EACE;EACT,UAAU;EACV,WAAW,EAAO;EAClB,oBAAkB,IAAU,IAAY,KAAA;CACzC,CAAA,GACD,kBAAC,SAAD;EACE,SAAS;EACT,WAAW,EAAK,EAAO,oBAAoB;GACzC,KAAgB,EAAO;GACvB,KAAU,EAAO;GACjB,KAAY,EAAO;GACnB,KAAW,EAAO;EACpB,CAAC;YAPH;GASG,KAAY,kBAAC,GAAD;IAAM,MAAM;IAAU,MAAM;GAAK,CAAA;GAC9C,kBAAC,OAAD;IAAK,WAAW,EAAO;cAAvB,CACG,KAAU,kBAAC,OAAD;KAAK,WAAW,EAAO;eAA6B;IAAY,CAAA,GAC1E,CACE;;GACJ,KACC,kBAAC,OAAD;IACE,IAAI;IACJ,MAAK;IACL,WAAW,EAAK,EAAO,6BAA6B,EAAO,6BAA6B,IAAkB;cAEzG;GACE,CAAA;EAEF;GACP,EAAA,CAAA;AAEN"}
@@ -1 +1 @@
1
- {"version":3,"file":"CopyableText-BKsM-TuS.js","names":[],"sources":["../src/components/CopyableText/CopyableText.module.css","../src/components/CopyableText/CopyableText.tsx"],"sourcesContent":[".copyable-text-container {\n cursor: pointer;\n display: flex;\n position: relative;\n width: fit-content;\n}\n\n.copyable-text-copy-button {\n align-items: center;\n background-color: var(--color-grey-300);\n border: none;\n border-radius: 0.25rem;\n cursor: pointer;\n display: flex;\n font-family: inherit;\n font-size: inherit;\n font-weight: inherit;\n gap: 0.25rem;\n inset: calc(-0.25rem + 1px) auto auto -0.5rem;\n justify-content: center;\n padding: 0.25rem 0.5rem;\n position: absolute;\n transition: opacity 150ms ease;\n white-space: nowrap;\n z-index: 10;\n}\n\n.copyable-text-container:focus-within {\n outline: none;\n}\n\n.copyable-text-copy-visually-hidden {\n border-width: 0;\n clip: rect(0, 0, 0, 0);\n height: 1px;\n margin: -1px;\n overflow: hidden;\n padding: 0;\n position: absolute;\n white-space: nowrap;\n width: 1px;\n}\n","import { clsx } from 'clsx';\r\nimport { useState, useRef, useEffect } from 'react';\r\n\r\nimport type { KeyboardEvent, MouseEvent } from 'react';\r\n\r\nimport styles from './CopyableText.module.css';\r\n\r\nimport { Icon } from 'components/Icon';\r\n\r\nexport interface CopyableTextProps {\r\n /** The text to be copied */\r\n text: string;\r\n /** Additional class name to style the text so it suits the design */\r\n additionalClassName?: string;\r\n /** ARIA label for the copy button */\r\n ariaLabelCopy?: string;\r\n /** ARIA label for the copied state */\r\n ariaLabelHasBeenCopied?: string;\r\n /** custom value to be copied in place of the display text */\r\n customCopyValue?: string;\r\n}\r\n\r\nconst COPYTIME = 2000;\r\n\r\nexport const CopyableText = ({\r\n text,\r\n additionalClassName = '',\r\n ariaLabelCopy,\r\n ariaLabelHasBeenCopied,\r\n customCopyValue,\r\n}: CopyableTextProps) => {\r\n const [isCopying, setIsCopying] = useState(false);\r\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n const buttonRef = useRef<HTMLButtonElement | null>(null);\r\n const [buttonActive, setButtonActive] = useState(false);\r\n\r\n useEffect(() => {\r\n return () => {\r\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\r\n };\r\n }, []);\r\n\r\n const handleCopy = (event: MouseEvent<HTMLButtonElement> | KeyboardEvent<HTMLSpanElement>) => {\r\n // prevent event bubbling if placed inside another clikable element\r\n event.stopPropagation();\r\n event.preventDefault();\r\n\r\n setIsCopying(true);\r\n timeoutRef.current = setTimeout(() => {\r\n setIsCopying(false);\r\n setButtonActive(false);\r\n }, COPYTIME);\r\n navigator.clipboard.writeText(customCopyValue ?? text).catch(() => setIsCopying(false));\r\n };\r\n\r\n return (\r\n <span\r\n className={clsx(styles['copyable-text-container'], additionalClassName)}\r\n role=\"button\"\r\n tabIndex={0}\r\n onFocus={() => setButtonActive(true)}\r\n onBlur={() => !isCopying && setButtonActive(false)}\r\n onKeyDown={(event) => {\r\n setButtonActive(true);\r\n if (event.key === 'Enter' || event.key === ' ') {\r\n event.preventDefault();\r\n handleCopy(event);\r\n }\r\n }}\r\n onMouseEnter={() => setButtonActive(true)}\r\n onMouseLeave={() => !isCopying && setButtonActive(false)}\r\n >\r\n {text}\r\n {buttonActive && (\r\n <button\r\n ref={buttonRef}\r\n className={clsx(styles['copyable-text-copy-button'], additionalClassName)}\r\n onClick={handleCopy}\r\n type=\"button\"\r\n aria-keyshortcuts=\"Enter Space\"\r\n aria-label={isCopying ? (ariaLabelHasBeenCopied ?? 'Copied') : (ariaLabelCopy ?? 'Copy to clipboard')}\r\n tabIndex={-1}\r\n >\r\n {text}\r\n <Icon name={isCopying ? 'CheckSmall' : 'Copy'} size={20} />\r\n <span className={styles['copyable-text-copy-visually-hidden']} aria-live=\"polite\">\r\n {isCopying ? (ariaLabelHasBeenCopied ?? 'Copied') : (ariaLabelCopy ?? 'Copy to clipboard')}\r\n </span>\r\n </button>\r\n )}\r\n </span>\r\n );\r\n};\r\n"],"mappings":";;;;;;;;;GCsBM,IAAW,KAEJ,KAAgB,EAC3B,SACA,yBAAsB,IACtB,kBACA,2BACA,yBACuB;CACvB,IAAM,CAAC,GAAW,KAAgB,EAAS,EAAK,GAC1C,IAAa,EAA6C,IAAI,GAC9D,IAAY,EAAiC,IAAI,GACjD,CAAC,GAAc,KAAmB,EAAS,EAAK;CAEtD,cACe;EACX,AAAI,EAAW,WAAS,aAAa,EAAW,OAAO;CACzD,GACC,CAAC,CAAC;CAEL,IAAM,KAAc,MAA0E;EAU5F,AARA,EAAM,gBAAgB,GACtB,EAAM,eAAe,GAErB,EAAa,EAAI,GACjB,EAAW,UAAU,iBAAiB;GAEpC,AADA,EAAa,EAAK,GAClB,EAAgB,EAAK;EACvB,GAAG,CAAQ,GACX,UAAU,UAAU,UAAU,KAAmB,CAAI,EAAE,YAAY,EAAa,EAAK,CAAC;CACxF;CAEA,OACE,kBAAC,QAAD;EACE,WAAW,EAAK,EAAO,4BAA4B,CAAmB;EACtE,MAAK;EACL,UAAU;EACV,eAAe,EAAgB,EAAI;EACnC,cAAc,CAAC,KAAa,EAAgB,EAAK;EACjD,YAAY,MAAU;GAEpB,AADA,EAAgB,EAAI,IAChB,EAAM,QAAQ,WAAW,EAAM,QAAQ,SACzC,EAAM,eAAe,GACrB,EAAW,CAAK;EAEpB;EACA,oBAAoB,EAAgB,EAAI;EACxC,oBAAoB,CAAC,KAAa,EAAgB,EAAK;YAdzD,CAgBG,GACA,KACC,kBAAC,UAAD;GACE,KAAK;GACL,WAAW,EAAK,EAAO,8BAA8B,CAAmB;GACxE,SAAS;GACT,MAAK;GACL,qBAAkB;GAClB,cAAY,IAAa,KAA0B,WAAa,KAAiB;GACjF,UAAU;aAPZ;IASG;IACD,kBAAC,GAAD;KAAM,MAAM,IAAY,eAAe;KAAQ,MAAM;IAAK,CAAA;IAC1D,kBAAC,QAAD;KAAM,WAAW,EAAO;KAAuC,aAAU;eACtE,IAAa,KAA0B,WAAa,KAAiB;IAClE,CAAA;GACA;IAEN;;AAEV"}
1
+ {"version":3,"file":"CopyableText-BKsM-TuS.js","names":[],"sources":["../src/components/CopyableText/CopyableText.module.css","../src/components/CopyableText/CopyableText.tsx"],"sourcesContent":[".copyable-text-container {\n cursor: pointer;\n display: flex;\n position: relative;\n width: fit-content;\n}\n\n.copyable-text-copy-button {\n align-items: center;\n background-color: var(--color-grey-300);\n border: none;\n border-radius: 0.25rem;\n cursor: pointer;\n display: flex;\n font-family: inherit;\n font-size: inherit;\n font-weight: inherit;\n gap: 0.25rem;\n inset: calc(-0.25rem + 1px) auto auto -0.5rem;\n justify-content: center;\n padding: 0.25rem 0.5rem;\n position: absolute;\n transition: opacity 150ms ease;\n white-space: nowrap;\n z-index: 10;\n}\n\n.copyable-text-container:focus-within {\n outline: none;\n}\n\n.copyable-text-copy-visually-hidden {\n border-width: 0;\n clip: rect(0, 0, 0, 0);\n height: 1px;\n margin: -1px;\n overflow: hidden;\n padding: 0;\n position: absolute;\n white-space: nowrap;\n width: 1px;\n}\n","import { clsx } from 'clsx';\r\nimport { useState, useRef, useEffect } from 'react';\r\n\r\nimport type { KeyboardEvent, MouseEvent } from 'react';\r\n\r\nimport styles from './CopyableText.module.css';\r\n\r\nimport { Icon } from 'components/Icon';\r\n\r\nexport interface CopyableTextProps {\r\n /** The text to be copied */\r\n text: string;\r\n /** Additional class name to style the text so it suits the design */\r\n additionalClassName?: string;\r\n /** ARIA label for the copy button */\r\n ariaLabelCopy?: string;\r\n /** ARIA label for the copied state */\r\n ariaLabelHasBeenCopied?: string;\r\n /** custom value to be copied in place of the display text */\r\n customCopyValue?: string;\r\n}\r\n\r\nconst COPYTIME = 2000;\r\n\r\nexport const CopyableText = ({\r\n text,\r\n additionalClassName = '',\r\n ariaLabelCopy,\r\n ariaLabelHasBeenCopied,\r\n customCopyValue,\r\n}: CopyableTextProps) => {\r\n const [isCopying, setIsCopying] = useState(false);\r\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\r\n const buttonRef = useRef<HTMLButtonElement | null>(null);\r\n const [buttonActive, setButtonActive] = useState(false);\r\n\r\n useEffect(() => {\r\n return () => {\r\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\r\n };\r\n }, []);\r\n\r\n const handleCopy = (event: MouseEvent<HTMLButtonElement> | KeyboardEvent<HTMLSpanElement>) => {\r\n // prevent event bubbling if placed inside another clikable element\r\n event.stopPropagation();\r\n event.preventDefault();\r\n\r\n setIsCopying(true);\r\n timeoutRef.current = setTimeout(() => {\r\n setIsCopying(false);\r\n setButtonActive(false);\r\n }, COPYTIME);\r\n navigator.clipboard.writeText(customCopyValue ?? text).catch(() => setIsCopying(false));\r\n };\r\n\r\n return (\r\n <span\r\n className={clsx(styles['copyable-text-container'], additionalClassName)}\r\n role=\"button\"\r\n tabIndex={0}\r\n onFocus={() => setButtonActive(true)}\r\n onBlur={() => !isCopying && setButtonActive(false)}\r\n onKeyDown={(event) => {\r\n setButtonActive(true);\r\n if (event.key === 'Enter' || event.key === ' ') {\r\n event.preventDefault();\r\n handleCopy(event);\r\n }\r\n }}\r\n onMouseEnter={() => setButtonActive(true)}\r\n onMouseLeave={() => !isCopying && setButtonActive(false)}\r\n >\r\n {text}\r\n {buttonActive && (\r\n <button\r\n ref={buttonRef}\r\n className={clsx(styles['copyable-text-copy-button'], additionalClassName)}\r\n onClick={handleCopy}\r\n type=\"button\"\r\n aria-keyshortcuts=\"Enter Space\"\r\n aria-label={isCopying ? (ariaLabelHasBeenCopied ?? 'Copied') : (ariaLabelCopy ?? 'Copy to clipboard')}\r\n tabIndex={-1}\r\n >\r\n {text}\r\n <Icon name={isCopying ? 'CheckSmall' : 'Copy'} size={20} />\r\n <span className={styles['copyable-text-copy-visually-hidden']} aria-live=\"polite\">\r\n {isCopying ? (ariaLabelHasBeenCopied ?? 'Copied') : (ariaLabelCopy ?? 'Copy to clipboard')}\r\n </span>\r\n </button>\r\n )}\r\n </span>\r\n );\r\n};\r\n"],"mappings":";;;;;;;;;GCsBM,IAAW,KAEJ,KAAgB,EAC3B,SACA,yBAAsB,IACtB,kBACA,2BACA,yBACuB;CACvB,IAAM,CAAC,GAAW,KAAgB,EAAS,EAAK,GAC1C,IAAa,EAA6C,IAAI,GAC9D,IAAY,EAAiC,IAAI,GACjD,CAAC,GAAc,KAAmB,EAAS,EAAK;CAEtD,cACe;EACX,AAAI,EAAW,WAAS,aAAa,EAAW,OAAO;CACzD,GACC,CAAC,CAAC;CAEL,IAAM,KAAc,MAA0E;EAU5F,AARA,EAAM,gBAAgB,GACtB,EAAM,eAAe,GAErB,EAAa,EAAI,GACjB,EAAW,UAAU,iBAAiB;GAEpC,AADA,EAAa,EAAK,GAClB,EAAgB,EAAK;EACvB,GAAG,CAAQ,GACX,UAAU,UAAU,UAAU,KAAmB,CAAI,CAAC,CAAC,YAAY,EAAa,EAAK,CAAC;CACxF;CAEA,OACE,kBAAC,QAAD;EACE,WAAW,EAAK,EAAO,4BAA4B,CAAmB;EACtE,MAAK;EACL,UAAU;EACV,eAAe,EAAgB,EAAI;EACnC,cAAc,CAAC,KAAa,EAAgB,EAAK;EACjD,YAAY,MAAU;GAEpB,AADA,EAAgB,EAAI,IAChB,EAAM,QAAQ,WAAW,EAAM,QAAQ,SACzC,EAAM,eAAe,GACrB,EAAW,CAAK;EAEpB;EACA,oBAAoB,EAAgB,EAAI;EACxC,oBAAoB,CAAC,KAAa,EAAgB,EAAK;YAdzD,CAgBG,GACA,KACC,kBAAC,UAAD;GACE,KAAK;GACL,WAAW,EAAK,EAAO,8BAA8B,CAAmB;GACxE,SAAS;GACT,MAAK;GACL,qBAAkB;GAClB,cAAY,IAAa,KAA0B,WAAa,KAAiB;GACjF,UAAU;aAPZ;IASG;IACD,kBAAC,GAAD;KAAM,MAAM,IAAY,eAAe;KAAQ,MAAM;IAAK,CAAA;IAC1D,kBAAC,QAAD;KAAM,WAAW,EAAO;KAAuC,aAAU;eACtE,IAAa,KAA0B,WAAa,KAAiB;IAClE,CAAA;GACA;IAEN;;AAEV"}
@@ -1 +1 @@
1
- {"version":3,"file":"DataTable-Cgn_RKTA.js","names":[],"sources":["../src/components/DataTable/DataTable.module.css","../src/components/DataTable/DataTable.tsx"],"sourcesContent":[".data-table__container {\n height: 100%;\n overflow-y: auto;\n position: relative;\n width: 100%;\n}\n\n.data-table__spacer {\n background-color: transparent;\n width: 0.0625rem;\n}\n\n.data-table {\n border-collapse: collapse;\n left: 0;\n position: absolute;\n top: 0;\n width: 100%;\n}\n\n.data-table--virtualized {\n border-collapse: collapse;\n left: 0;\n position: sticky;\n top: 0;\n width: 100%;\n z-index: 10;\n}\n\n.data-table__row,\n.data-table__header-row {\n background-color: var(--color-uva-white);\n border-bottom: 0.0625rem solid var(--color-grey-300);\n}\n\n.data-table__row:hover {\n background-color: var(--color-grey-200);\n}\n\n.data-table__row--active {\n background-color: var(--color-navy-100);\n}\n\n.data-table__row--active:hover {\n background-color: var(--color-navy-200);\n}\n\n.data-table__cell {\n overflow: hidden;\n padding: 0.6875rem 0.75rem;\n text-align: left;\n vertical-align: baseline;\n white-space: nowrap;\n}\n\n.data-table__sticky-header {\n background-color: var(--color-uva-white);\n left: 0;\n position: sticky;\n top: 0;\n z-index: 1;\n}\n\n.data-table__sticky-header::after {\n border-bottom: 0.0625rem solid var(--color-grey-300);\n content: \"\";\n display: block;\n height: 0.0625rem;\n left: 0;\n position: absolute;\n top: 100%;\n width: 100%;\n}\n\n.data-table__empty-state {\n color: var(--color-grey-600);\n font-size: 1rem;\n padding: 2rem;\n text-align: center;\n}\n","import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode, type UIEvent } from 'react';\r\nimport { clsx } from 'clsx';\r\n\r\nimport styles from './DataTable.module.css';\r\nimport { useVirtualScroll } from './hooks/useVirtualScroll';\r\n\r\ntype DataTablePrimitive = string | number | boolean | null | undefined;\r\ntype DataTableRow = Record<string, DataTablePrimitive>;\r\nexport type DataTableColumnContent<TRow extends object> = ReactNode | ((row: TRow) => ReactNode);\r\ntype DataTableColumn<TRow extends object> = {\r\n key: Extract<keyof TRow, string>;\r\n label?: ReactNode | ((row: TRow) => ReactNode);\r\n cell?: ReactNode | ((row: TRow) => ReactNode);\r\n fixedWidth?: string;\r\n};\r\ntype DataRow<TRow extends object> = { visibleRows: Partial<TRow>[]; rowsToRender: TRow[] };\r\n\r\nexport type DataTableProps<TRow extends { id: string | number } = DataTableRow & { id: string | number }> = {\r\n /** The data to be displayed in the table */\r\n data: TRow[];\r\n /** The columns configuration for the table */\r\n columns?: DataTableColumn<TRow>[];\r\n /** Whether the table header should be sticky */\r\n stickyHeader?: boolean;\r\n /** Virtualization settings for the table */\r\n virtualize?: {\r\n /** The height of each row in pixels */\r\n rowHeight: number;\r\n /** The number of additional rows to render above and below the visible area for smoother scrolling */\r\n buffer?: number;\r\n } | null;\r\n /** The keys in the data objects that indicate whether a row is active (for styling purposes) */\r\n activeKeys?: (string | number)[];\r\n /** Message to display when there is no data */\r\n noDataMessage?: string;\r\n};\r\n\r\nconst DEFAULT_BUFFER = 4;\r\n\r\nexport const DataTable = <TRow extends { id: string | number } = DataTableRow & { id: string | number }>({\r\n data,\r\n columns,\r\n stickyHeader = false,\r\n virtualize = null,\r\n activeKeys = [],\r\n noDataMessage = 'No data to display',\r\n}: DataTableProps<TRow>) => {\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const headerRef = useRef<HTMLTableSectionElement>(null);\r\n const headerRowRef = useRef<HTMLTableRowElement>(null);\r\n const tbodyRef = useRef<HTMLTableSectionElement>(null);\r\n const { visibleItems, totalHeight, offsetTop, onScroll, setContainerHeight } = useVirtualScroll({\r\n rowHeight: virtualize?.rowHeight ?? 0,\r\n buffer: virtualize?.buffer ?? DEFAULT_BUFFER,\r\n totalItems: data.length,\r\n });\r\n const throttling = useRef(false);\r\n const resizeThrottling = useRef(false);\r\n const [columnWidths, setColumnWidths] = useState<number[]>([]);\r\n\r\n const tableData: DataRow<TRow> = useMemo(() => {\r\n if (!columns) return { visibleRows: data, rowsToRender: data };\r\n const rowsToRender = virtualize ? visibleItems.map((index) => data[index]) : data;\r\n const visibleRows = rowsToRender.map((row) => {\r\n const newRow: Partial<TRow> = {};\r\n columns.forEach((col) => {\r\n newRow[col.key] = row[col.key];\r\n });\r\n return newRow;\r\n });\r\n return { visibleRows, rowsToRender };\r\n }, [columns, data, virtualize, visibleItems]);\r\n\r\n const handleScroll = useCallback(\r\n (event: UIEvent<HTMLDivElement>) => {\r\n if (!virtualize) return;\r\n\r\n const scrollTop = event.currentTarget.scrollTop;\r\n\r\n if (!throttling.current) {\r\n throttling.current = true;\r\n\r\n requestAnimationFrame(() => {\r\n onScroll({ currentTarget: { scrollTop } } as UIEvent<HTMLElement>);\r\n throttling.current = false;\r\n });\r\n }\r\n },\r\n [virtualize, onScroll]\r\n );\r\n\r\n const onRenderValue = (value: ((row: TRow) => ReactNode) | ReactNode, row?: TRow) =>\r\n typeof value === 'function' ? value(row!) : value;\r\n\r\n useEffect(() => {\r\n if (!virtualize || !containerRef.current) {\r\n return;\r\n }\r\n\r\n const handleResize = () => {\r\n const containerHeight = containerRef.current?.parentElement?.clientHeight ?? 0;\r\n\r\n if (!resizeThrottling.current) {\r\n resizeThrottling.current = true;\r\n\r\n requestAnimationFrame(() => {\r\n setContainerHeight(containerHeight);\r\n resizeThrottling.current = false;\r\n });\r\n }\r\n };\r\n window.addEventListener('resize', handleResize);\r\n\r\n return () => {\r\n window.removeEventListener('resize', handleResize);\r\n };\r\n }, [virtualize, setContainerHeight]);\r\n\r\n useEffect(() => {\r\n if (containerRef.current) {\r\n setContainerHeight(containerRef.current.parentElement?.clientHeight ?? 0);\r\n }\r\n }, [setContainerHeight]);\r\n\r\n useEffect(() => {\r\n containerRef.current?.scrollTo({ top: 0 });\r\n }, [data]);\r\n\r\n useEffect(() => {\r\n if (!stickyHeader || !tbodyRef.current) return;\r\n\r\n const measureWidths = () => {\r\n const firstRow = tbodyRef.current?.querySelector('tr');\r\n if (!firstRow) return;\r\n\r\n const cells = firstRow.querySelectorAll('td');\r\n const widths = Array.from(cells).map((cell) => cell.getBoundingClientRect().width);\r\n\r\n setColumnWidths(widths);\r\n };\r\n\r\n const observer = new ResizeObserver(() => {\r\n requestAnimationFrame(measureWidths);\r\n });\r\n\r\n observer.observe(tbodyRef.current);\r\n\r\n measureWidths();\r\n\r\n return () => observer.disconnect();\r\n }, [stickyHeader, tableData.visibleRows]);\r\n\r\n return data.length ? (\r\n <div className={styles['data-table__container']} onScroll={handleScroll} ref={containerRef}>\r\n {/* sticky header if virtualized */}\r\n {virtualize && stickyHeader && columns && (\r\n <table className={styles['data-table--virtualized']}>\r\n <thead className={styles['data-table__sticky-header']}>\r\n <tr className={styles['data-table__header-row']} ref={headerRowRef}>\r\n {columns &&\r\n columns.map((column, index) => {\r\n const forcedWidth = columnWidths[index] ? `${columnWidths[index]}px` : column.fixedWidth;\r\n return (\r\n <th\r\n key={column.key}\r\n className={styles['data-table__cell']}\r\n style={{\r\n width: forcedWidth,\r\n minWidth: forcedWidth,\r\n maxWidth: forcedWidth,\r\n }}\r\n >\r\n {onRenderValue(column?.label)}\r\n </th>\r\n );\r\n })}\r\n </tr>\r\n </thead>\r\n </table>\r\n )}\r\n\r\n <div className={styles['data-table__spacer']} style={{ height: totalHeight }} />\r\n <table\r\n className={styles['data-table']}\r\n style={virtualize ? { transform: `translateY(${offsetTop}px)` } : undefined}\r\n >\r\n {/* header */}\r\n <thead className={clsx({ [styles['data-table__sticky-header']]: stickyHeader })} ref={headerRef}>\r\n <tr className={styles['data-table__header-row']}>\r\n {!virtualize || !stickyHeader ? (\r\n columns &&\r\n columns.map((column, index) => {\r\n const forcedWidth = columnWidths[index] ? `${columnWidths[index]}px` : column.fixedWidth;\r\n return (\r\n <th key={column.key} className={styles['data-table__cell']} style={{ width: forcedWidth }}>\r\n {onRenderValue(column?.label)}\r\n </th>\r\n );\r\n })\r\n ) : (\r\n <th colSpan={columns?.length} style={{ height: headerRowRef.current?.clientHeight }} />\r\n )}\r\n </tr>\r\n </thead>\r\n\r\n {/* data rows */}\r\n <tbody ref={tbodyRef}>\r\n {tableData.visibleRows.map((row, index) => (\r\n <tr\r\n key={tableData.rowsToRender[index].id}\r\n className={clsx(styles['data-table__row'], {\r\n [styles['data-table__row--active']]: activeKeys?.includes(tableData.rowsToRender[index].id),\r\n })}\r\n >\r\n {Object.entries(row as Record<string, unknown>).map(([key]) => {\r\n const column = columns?.find((col) => col.key === key);\r\n return (\r\n <td\r\n key={key}\r\n className={styles['data-table__cell']}\r\n style={{\r\n width: column?.fixedWidth,\r\n height: virtualize ? virtualize.rowHeight : undefined,\r\n maxHeight: virtualize ? virtualize.rowHeight : undefined,\r\n }}\r\n >\r\n {onRenderValue(column?.cell, tableData.rowsToRender[index])}\r\n </td>\r\n );\r\n })}\r\n </tr>\r\n ))}\r\n </tbody>\r\n </table>\r\n </div>\r\n ) : (\r\n <div className={styles['data-table__empty-state']}>{noDataMessage}</div>\r\n );\r\n};\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"DataTable-Cgn_RKTA.js","names":[],"sources":["../src/components/DataTable/DataTable.module.css","../src/components/DataTable/DataTable.tsx"],"sourcesContent":[".data-table__container {\n height: 100%;\n overflow-y: auto;\n position: relative;\n width: 100%;\n}\n\n.data-table__spacer {\n background-color: transparent;\n width: 0.0625rem;\n}\n\n.data-table {\n border-collapse: collapse;\n left: 0;\n position: absolute;\n top: 0;\n width: 100%;\n}\n\n.data-table--virtualized {\n border-collapse: collapse;\n left: 0;\n position: sticky;\n top: 0;\n width: 100%;\n z-index: 10;\n}\n\n.data-table__row,\n.data-table__header-row {\n background-color: var(--color-uva-white);\n border-bottom: 0.0625rem solid var(--color-grey-300);\n}\n\n.data-table__row:hover {\n background-color: var(--color-grey-200);\n}\n\n.data-table__row--active {\n background-color: var(--color-navy-100);\n}\n\n.data-table__row--active:hover {\n background-color: var(--color-navy-200);\n}\n\n.data-table__cell {\n overflow: hidden;\n padding: 0.6875rem 0.75rem;\n text-align: left;\n vertical-align: baseline;\n white-space: nowrap;\n}\n\n.data-table__sticky-header {\n background-color: var(--color-uva-white);\n left: 0;\n position: sticky;\n top: 0;\n z-index: 1;\n}\n\n.data-table__sticky-header::after {\n border-bottom: 0.0625rem solid var(--color-grey-300);\n content: \"\";\n display: block;\n height: 0.0625rem;\n left: 0;\n position: absolute;\n top: 100%;\n width: 100%;\n}\n\n.data-table__empty-state {\n color: var(--color-grey-600);\n font-size: 1rem;\n padding: 2rem;\n text-align: center;\n}\n","import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode, type UIEvent } from 'react';\r\nimport { clsx } from 'clsx';\r\n\r\nimport styles from './DataTable.module.css';\r\nimport { useVirtualScroll } from './hooks/useVirtualScroll';\r\n\r\ntype DataTablePrimitive = string | number | boolean | null | undefined;\r\ntype DataTableRow = Record<string, DataTablePrimitive>;\r\nexport type DataTableColumnContent<TRow extends object> = ReactNode | ((row: TRow) => ReactNode);\r\ntype DataTableColumn<TRow extends object> = {\r\n key: Extract<keyof TRow, string>;\r\n label?: ReactNode | ((row: TRow) => ReactNode);\r\n cell?: ReactNode | ((row: TRow) => ReactNode);\r\n fixedWidth?: string;\r\n};\r\ntype DataRow<TRow extends object> = { visibleRows: Partial<TRow>[]; rowsToRender: TRow[] };\r\n\r\nexport type DataTableProps<TRow extends { id: string | number } = DataTableRow & { id: string | number }> = {\r\n /** The data to be displayed in the table */\r\n data: TRow[];\r\n /** The columns configuration for the table */\r\n columns?: DataTableColumn<TRow>[];\r\n /** Whether the table header should be sticky */\r\n stickyHeader?: boolean;\r\n /** Virtualization settings for the table */\r\n virtualize?: {\r\n /** The height of each row in pixels */\r\n rowHeight: number;\r\n /** The number of additional rows to render above and below the visible area for smoother scrolling */\r\n buffer?: number;\r\n } | null;\r\n /** The keys in the data objects that indicate whether a row is active (for styling purposes) */\r\n activeKeys?: (string | number)[];\r\n /** Message to display when there is no data */\r\n noDataMessage?: string;\r\n};\r\n\r\nconst DEFAULT_BUFFER = 4;\r\n\r\nexport const DataTable = <TRow extends { id: string | number } = DataTableRow & { id: string | number }>({\r\n data,\r\n columns,\r\n stickyHeader = false,\r\n virtualize = null,\r\n activeKeys = [],\r\n noDataMessage = 'No data to display',\r\n}: DataTableProps<TRow>) => {\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const headerRef = useRef<HTMLTableSectionElement>(null);\r\n const headerRowRef = useRef<HTMLTableRowElement>(null);\r\n const tbodyRef = useRef<HTMLTableSectionElement>(null);\r\n const { visibleItems, totalHeight, offsetTop, onScroll, setContainerHeight } = useVirtualScroll({\r\n rowHeight: virtualize?.rowHeight ?? 0,\r\n buffer: virtualize?.buffer ?? DEFAULT_BUFFER,\r\n totalItems: data.length,\r\n });\r\n const throttling = useRef(false);\r\n const resizeThrottling = useRef(false);\r\n const [columnWidths, setColumnWidths] = useState<number[]>([]);\r\n\r\n const tableData: DataRow<TRow> = useMemo(() => {\r\n if (!columns) return { visibleRows: data, rowsToRender: data };\r\n const rowsToRender = virtualize ? visibleItems.map((index) => data[index]) : data;\r\n const visibleRows = rowsToRender.map((row) => {\r\n const newRow: Partial<TRow> = {};\r\n columns.forEach((col) => {\r\n newRow[col.key] = row[col.key];\r\n });\r\n return newRow;\r\n });\r\n return { visibleRows, rowsToRender };\r\n }, [columns, data, virtualize, visibleItems]);\r\n\r\n const handleScroll = useCallback(\r\n (event: UIEvent<HTMLDivElement>) => {\r\n if (!virtualize) return;\r\n\r\n const scrollTop = event.currentTarget.scrollTop;\r\n\r\n if (!throttling.current) {\r\n throttling.current = true;\r\n\r\n requestAnimationFrame(() => {\r\n onScroll({ currentTarget: { scrollTop } } as UIEvent<HTMLElement>);\r\n throttling.current = false;\r\n });\r\n }\r\n },\r\n [virtualize, onScroll]\r\n );\r\n\r\n const onRenderValue = (value: ((row: TRow) => ReactNode) | ReactNode, row?: TRow) =>\r\n typeof value === 'function' ? value(row!) : value;\r\n\r\n useEffect(() => {\r\n if (!virtualize || !containerRef.current) {\r\n return;\r\n }\r\n\r\n const handleResize = () => {\r\n const containerHeight = containerRef.current?.parentElement?.clientHeight ?? 0;\r\n\r\n if (!resizeThrottling.current) {\r\n resizeThrottling.current = true;\r\n\r\n requestAnimationFrame(() => {\r\n setContainerHeight(containerHeight);\r\n resizeThrottling.current = false;\r\n });\r\n }\r\n };\r\n window.addEventListener('resize', handleResize);\r\n\r\n return () => {\r\n window.removeEventListener('resize', handleResize);\r\n };\r\n }, [virtualize, setContainerHeight]);\r\n\r\n useEffect(() => {\r\n if (containerRef.current) {\r\n setContainerHeight(containerRef.current.parentElement?.clientHeight ?? 0);\r\n }\r\n }, [setContainerHeight]);\r\n\r\n useEffect(() => {\r\n containerRef.current?.scrollTo({ top: 0 });\r\n }, [data]);\r\n\r\n useEffect(() => {\r\n if (!stickyHeader || !tbodyRef.current) return;\r\n\r\n const measureWidths = () => {\r\n const firstRow = tbodyRef.current?.querySelector('tr');\r\n if (!firstRow) return;\r\n\r\n const cells = firstRow.querySelectorAll('td');\r\n const widths = Array.from(cells).map((cell) => cell.getBoundingClientRect().width);\r\n\r\n setColumnWidths(widths);\r\n };\r\n\r\n const observer = new ResizeObserver(() => {\r\n requestAnimationFrame(measureWidths);\r\n });\r\n\r\n observer.observe(tbodyRef.current);\r\n\r\n measureWidths();\r\n\r\n return () => observer.disconnect();\r\n }, [stickyHeader, tableData.visibleRows]);\r\n\r\n return data.length ? (\r\n <div className={styles['data-table__container']} onScroll={handleScroll} ref={containerRef}>\r\n {/* sticky header if virtualized */}\r\n {virtualize && stickyHeader && columns && (\r\n <table className={styles['data-table--virtualized']}>\r\n <thead className={styles['data-table__sticky-header']}>\r\n <tr className={styles['data-table__header-row']} ref={headerRowRef}>\r\n {columns &&\r\n columns.map((column, index) => {\r\n const forcedWidth = columnWidths[index] ? `${columnWidths[index]}px` : column.fixedWidth;\r\n return (\r\n <th\r\n key={column.key}\r\n className={styles['data-table__cell']}\r\n style={{\r\n width: forcedWidth,\r\n minWidth: forcedWidth,\r\n maxWidth: forcedWidth,\r\n }}\r\n >\r\n {onRenderValue(column?.label)}\r\n </th>\r\n );\r\n })}\r\n </tr>\r\n </thead>\r\n </table>\r\n )}\r\n\r\n <div className={styles['data-table__spacer']} style={{ height: totalHeight }} />\r\n <table\r\n className={styles['data-table']}\r\n style={virtualize ? { transform: `translateY(${offsetTop}px)` } : undefined}\r\n >\r\n {/* header */}\r\n <thead className={clsx({ [styles['data-table__sticky-header']]: stickyHeader })} ref={headerRef}>\r\n <tr className={styles['data-table__header-row']}>\r\n {!virtualize || !stickyHeader ? (\r\n columns &&\r\n columns.map((column, index) => {\r\n const forcedWidth = columnWidths[index] ? `${columnWidths[index]}px` : column.fixedWidth;\r\n return (\r\n <th key={column.key} className={styles['data-table__cell']} style={{ width: forcedWidth }}>\r\n {onRenderValue(column?.label)}\r\n </th>\r\n );\r\n })\r\n ) : (\r\n <th colSpan={columns?.length} style={{ height: headerRowRef.current?.clientHeight }} />\r\n )}\r\n </tr>\r\n </thead>\r\n\r\n {/* data rows */}\r\n <tbody ref={tbodyRef}>\r\n {tableData.visibleRows.map((row, index) => (\r\n <tr\r\n key={tableData.rowsToRender[index].id}\r\n className={clsx(styles['data-table__row'], {\r\n [styles['data-table__row--active']]: activeKeys?.includes(tableData.rowsToRender[index].id),\r\n })}\r\n >\r\n {Object.entries(row as Record<string, unknown>).map(([key]) => {\r\n const column = columns?.find((col) => col.key === key);\r\n return (\r\n <td\r\n key={key}\r\n className={styles['data-table__cell']}\r\n style={{\r\n width: column?.fixedWidth,\r\n height: virtualize ? virtualize.rowHeight : undefined,\r\n maxHeight: virtualize ? virtualize.rowHeight : undefined,\r\n }}\r\n >\r\n {onRenderValue(column?.cell, tableData.rowsToRender[index])}\r\n </td>\r\n );\r\n })}\r\n </tr>\r\n ))}\r\n </tbody>\r\n </table>\r\n </div>\r\n ) : (\r\n <div className={styles['data-table__empty-state']}>{noDataMessage}</div>\r\n );\r\n};\r\n"],"mappings":"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"}