@lifesg/react-design-system 4.0.0-alpha.7 → 4.0.0-alpha.9

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 (268) hide show
  1. package/accordion/accordion-item.js.map +1 -1
  2. package/accordion/accordion.js.map +1 -1
  3. package/alert/alert.js.map +1 -1
  4. package/button/button.js +1 -1
  5. package/button/button.js.map +1 -1
  6. package/button/button.styles.d.ts +1 -0
  7. package/button/button.styles.js +1 -1
  8. package/button/button.styles.js.map +1 -1
  9. package/button/button.styles_19i4dfq.css +21 -0
  10. package/cjs/accordion/accordion-item.js.map +1 -1
  11. package/cjs/accordion/accordion.js.map +1 -1
  12. package/cjs/alert/alert.js.map +1 -1
  13. package/cjs/button/button.js +1 -1
  14. package/cjs/button/button.js.map +1 -1
  15. package/cjs/button/button.styles.js +1 -1
  16. package/cjs/button/button.styles.js.map +1 -1
  17. package/cjs/button/button.styles_19i4dfq.css +21 -0
  18. package/cjs/countdown-timer/countdown-timer.js.map +1 -1
  19. package/cjs/data-table/data-table.js +1 -1
  20. package/cjs/data-table/data-table.js.map +1 -1
  21. package/cjs/data-table/data-table.styles.js +1 -1
  22. package/cjs/data-table/data-table.styles.js.map +1 -1
  23. package/{data-table/data-table.styles_rxganh.css → cjs/data-table/data-table.styles_1tnlmhe.css} +7 -6
  24. package/cjs/date-range-input/date-range-input.js.map +1 -1
  25. package/cjs/e-signature/e-signature-canvas.js.map +1 -1
  26. package/cjs/error-display/error-display-data.js +1 -1
  27. package/cjs/error-display/error-display-data.js.map +1 -1
  28. package/cjs/error-display/inactivity-timer.js.map +1 -1
  29. package/cjs/external/dompurify/dist/purify.es.js +2 -2
  30. package/cjs/external/dompurify/dist/purify.es.js.map +1 -1
  31. package/cjs/file-download/file-list-card/file-list-card.js.map +1 -1
  32. package/cjs/file-upload/custom-sensors.js.map +1 -1
  33. package/cjs/file-upload/file-list/file-list.js.map +1 -1
  34. package/cjs/filter/addons/filter-item-checkbox-helpers.js.map +1 -1
  35. package/cjs/filter/addons/filter-item-checkbox.js.map +1 -1
  36. package/cjs/filter/addons/filter-item-checkbox.styles.js +1 -1
  37. package/cjs/filter/addons/filter-item-checkbox.styles.js.map +1 -1
  38. package/{filter/addons/filter-item-checkbox.styles_7degw7.css → cjs/filter/addons/filter-item-checkbox.styles_6nbpdl.css} +1 -1
  39. package/cjs/filter/filter-item.js.map +1 -1
  40. package/cjs/filter/filter-item.styles.js +1 -1
  41. package/cjs/filter/filter-item.styles.js.map +1 -1
  42. package/cjs/filter/{filter-item.styles_cphjnj.css → filter-item.styles_1yixp8h.css} +1 -1
  43. package/cjs/filter/filter-modal.styles.js +1 -1
  44. package/cjs/filter/filter-modal.styles.js.map +1 -1
  45. package/{filter/filter-modal.styles_qw3xlg.css → cjs/filter/filter-modal.styles_kuth21.css} +1 -1
  46. package/cjs/filter/filter-sidebar.styles.js +1 -1
  47. package/cjs/filter/filter-sidebar.styles.js.map +1 -1
  48. package/cjs/filter/{filter-sidebar.styles_1otwpjl.css → filter-sidebar.styles_rbfq4f.css} +1 -1
  49. package/cjs/filter/filter.js.map +1 -1
  50. package/cjs/form/form-textarea/form-textarea.js +1 -1
  51. package/cjs/form/form-textarea/form-textarea.js.map +1 -1
  52. package/cjs/fullscreen-image-carousel/stateful-image.js.map +1 -1
  53. package/cjs/histogram-slider/histogram-slider.js.map +1 -1
  54. package/cjs/input-range-slider/input-range-slider.js.map +1 -1
  55. package/cjs/input-slider/input-slider.js.map +1 -1
  56. package/cjs/input-textarea/textarea-counter.js.map +1 -1
  57. package/cjs/input-textarea/textarea.js +1 -1
  58. package/cjs/input-textarea/textarea.js.map +1 -1
  59. package/cjs/input-textarea/textarea.styles.js +1 -1
  60. package/cjs/input-textarea/textarea.styles.js.map +1 -1
  61. package/cjs/input-textarea/{textarea.styles_q77m5x.css → textarea.styles_6we7bs.css} +3 -1
  62. package/cjs/modal/index.js.map +1 -1
  63. package/cjs/modal-v2/modal-v2.js +1 -1
  64. package/cjs/modal-v2/modal-v2.js.map +1 -1
  65. package/cjs/modal-v2/slots/card.js +1 -1
  66. package/cjs/modal-v2/slots/card.js.map +1 -1
  67. package/cjs/modal-v2/slots/header.js +2 -0
  68. package/cjs/modal-v2/slots/header.js.map +1 -0
  69. package/cjs/modal-v2/slots/slot-styles.js +1 -1
  70. package/cjs/modal-v2/slots/slot-styles.js.map +1 -1
  71. package/cjs/modal-v2/slots/{slot-styles_13sd376.css → slot-styles_10ut1v7.css} +5 -1
  72. package/cjs/navbar/navbar-items.js +1 -1
  73. package/cjs/navbar/navbar-items.js.map +1 -1
  74. package/cjs/navbar/navbar-items.styles.js +1 -1
  75. package/cjs/navbar/navbar-items.styles.js.map +1 -1
  76. package/cjs/navbar/{navbar-items.styles_1i3ltot.css → navbar-items.styles_1b1zx.css} +9 -8
  77. package/cjs/navbar/navbar-logo-data.js +1 -1
  78. package/cjs/navbar/navbar-logo-data.js.map +1 -1
  79. package/cjs/navbar/navbar.js.map +1 -1
  80. package/cjs/otp-input/otp-input.js.map +1 -1
  81. package/cjs/overlay/overlay.js.map +1 -1
  82. package/cjs/pagination/pagination.js.map +1 -1
  83. package/cjs/phone-number-input/phone-number-input.js.map +1 -1
  84. package/cjs/predictive-text-input/predictive-text-input.js.map +1 -1
  85. package/cjs/shared/dropdown-list/dropdown-list.js.map +1 -1
  86. package/cjs/shared/internal-calendar/calendar-manager.js.map +1 -1
  87. package/cjs/shared/standalone-date-input/standalone-date-input.js.map +1 -1
  88. package/cjs/singpass-button/singpass-button.styles.js +1 -1
  89. package/cjs/singpass-button/singpass-button.styles.js.map +1 -1
  90. package/cjs/singpass-button/{singpass-button.styles_1miyex3.css → singpass-button.styles_1fj2lru.css} +1 -1
  91. package/cjs/smart-app-banner/smart-app-banner.styles.js +1 -1
  92. package/cjs/smart-app-banner/smart-app-banner.styles.js.map +1 -1
  93. package/cjs/smart-app-banner/{smart-app-banner.styles_15u6yv4.css → smart-app-banner.styles_r6yjq9.css} +1 -1
  94. package/cjs/theme/types.js +1 -1
  95. package/cjs/theme/types.js.map +1 -1
  96. package/cjs/time-slot-bar/time-slot-bar.js.map +1 -1
  97. package/cjs/time-slot-bar-week/time-slot-bar-week-days.js.map +1 -1
  98. package/cjs/timetable/timetable.js.map +1 -1
  99. package/cjs/toast/toast.styles.js +1 -1
  100. package/cjs/toast/toast.styles.js.map +1 -1
  101. package/{toast/toast.styles_1e0l60w.css → cjs/toast/toast.styles_57j3lf.css} +1 -1
  102. package/cjs/toggle/toggle-icon.js +1 -1
  103. package/cjs/toggle/toggle-icon.js.map +1 -1
  104. package/cjs/toggle/toggle-icon.styles.js +1 -1
  105. package/cjs/toggle/toggle-icon.styles.js.map +1 -1
  106. package/cjs/toggle/{toggle-icon.styles_ba71y.css → toggle-icon.styles_o6dxr3.css} +3 -2
  107. package/cjs/toggle/toggle.js +1 -1
  108. package/cjs/toggle/toggle.js.map +1 -1
  109. package/cjs/toggle/toggle.styles.js +1 -1
  110. package/cjs/toggle/toggle.styles.js.map +1 -1
  111. package/cjs/toggle/toggle.styles_11tmfsr.css +41 -0
  112. package/cjs/unit-number/unit-number-input.js.map +1 -1
  113. package/cjs/util/is-styled-components.js.map +1 -1
  114. package/cjs/util/string-helper.js +1 -1
  115. package/cjs/util/string-helper.js.map +1 -1
  116. package/cjs/util/use-event-listener.js.map +1 -1
  117. package/cjs/util/use-state-actions.js.map +1 -1
  118. package/countdown-timer/countdown-timer.js.map +1 -1
  119. package/data-table/data-table.d.ts +1 -1
  120. package/data-table/data-table.js +1 -1
  121. package/data-table/data-table.js.map +1 -1
  122. package/data-table/data-table.styles.d.ts +1 -0
  123. package/data-table/data-table.styles.js +1 -1
  124. package/data-table/data-table.styles.js.map +1 -1
  125. package/{cjs/data-table/data-table.styles_rxganh.css → data-table/data-table.styles_1tnlmhe.css} +7 -6
  126. package/data-table/types.d.ts +4 -2
  127. package/date-range-input/date-range-input.js.map +1 -1
  128. package/docs/component-catalog.json +1 -1
  129. package/e-signature/e-signature-canvas.js.map +1 -1
  130. package/error-display/error-display-data.js +1 -1
  131. package/error-display/error-display-data.js.map +1 -1
  132. package/error-display/inactivity-timer.js.map +1 -1
  133. package/external/dompurify/dist/purify.es.js +2 -2
  134. package/external/dompurify/dist/purify.es.js.map +1 -1
  135. package/file-download/file-list-card/file-list-card.js.map +1 -1
  136. package/file-upload/custom-sensors.d.ts +2 -2
  137. package/file-upload/custom-sensors.js.map +1 -1
  138. package/file-upload/file-list/file-list.js.map +1 -1
  139. package/filter/addons/filter-item-checkbox-helpers.js.map +1 -1
  140. package/filter/addons/filter-item-checkbox.js.map +1 -1
  141. package/filter/addons/filter-item-checkbox.styles.js +1 -1
  142. package/filter/addons/filter-item-checkbox.styles.js.map +1 -1
  143. package/{cjs/filter/addons/filter-item-checkbox.styles_7degw7.css → filter/addons/filter-item-checkbox.styles_6nbpdl.css} +1 -1
  144. package/filter/filter-item.js.map +1 -1
  145. package/filter/filter-item.styles.js +1 -1
  146. package/filter/filter-item.styles.js.map +1 -1
  147. package/filter/{filter-item.styles_cphjnj.css → filter-item.styles_1yixp8h.css} +1 -1
  148. package/filter/filter-modal.styles.js +1 -1
  149. package/filter/filter-modal.styles.js.map +1 -1
  150. package/{cjs/filter/filter-modal.styles_qw3xlg.css → filter/filter-modal.styles_kuth21.css} +1 -1
  151. package/filter/filter-sidebar.styles.js +1 -1
  152. package/filter/filter-sidebar.styles.js.map +1 -1
  153. package/filter/{filter-sidebar.styles_1otwpjl.css → filter-sidebar.styles_rbfq4f.css} +1 -1
  154. package/filter/filter.js.map +1 -1
  155. package/form/form-textarea/form-textarea.js +1 -1
  156. package/form/form-textarea/form-textarea.js.map +1 -1
  157. package/fullscreen-image-carousel/stateful-image.js.map +1 -1
  158. package/fullscreen-image-carousel/types.d.ts +2 -2
  159. package/histogram-slider/histogram-slider.js.map +1 -1
  160. package/input-range-slider/input-range-slider.js.map +1 -1
  161. package/input-slider/input-slider.js.map +1 -1
  162. package/input-textarea/textarea-counter.js.map +1 -1
  163. package/input-textarea/textarea.js +1 -1
  164. package/input-textarea/textarea.js.map +1 -1
  165. package/input-textarea/textarea.styles.d.ts +2 -0
  166. package/input-textarea/textarea.styles.js +1 -1
  167. package/input-textarea/textarea.styles.js.map +1 -1
  168. package/input-textarea/{textarea.styles_q77m5x.css → textarea.styles_6we7bs.css} +3 -1
  169. package/input-textarea/types.d.ts +7 -0
  170. package/modal/index.d.ts +4 -0
  171. package/modal/index.js.map +1 -1
  172. package/modal/types.d.ts +2 -0
  173. package/modal-v2/modal-v2.d.ts +6 -0
  174. package/modal-v2/modal-v2.js +1 -1
  175. package/modal-v2/modal-v2.js.map +1 -1
  176. package/modal-v2/slots/card.js +1 -1
  177. package/modal-v2/slots/card.js.map +1 -1
  178. package/modal-v2/slots/header.d.ts +5 -0
  179. package/modal-v2/slots/header.js +2 -0
  180. package/modal-v2/slots/header.js.map +1 -0
  181. package/modal-v2/slots/index.d.ts +1 -0
  182. package/modal-v2/slots/slot-styles.d.ts +4 -0
  183. package/modal-v2/slots/slot-styles.js +1 -1
  184. package/modal-v2/slots/slot-styles.js.map +1 -1
  185. package/modal-v2/slots/{slot-styles_13sd376.css → slot-styles_10ut1v7.css} +5 -1
  186. package/modal-v2/types.d.ts +21 -0
  187. package/navbar/navbar-items.js +1 -1
  188. package/navbar/navbar-items.js.map +1 -1
  189. package/navbar/navbar-items.styles.d.ts +2 -1
  190. package/navbar/navbar-items.styles.js +1 -1
  191. package/navbar/navbar-items.styles.js.map +1 -1
  192. package/navbar/{navbar-items.styles_1i3ltot.css → navbar-items.styles_1b1zx.css} +9 -8
  193. package/navbar/navbar-logo-data.js +1 -1
  194. package/navbar/navbar-logo-data.js.map +1 -1
  195. package/navbar/navbar.js.map +1 -1
  196. package/otp-input/otp-input.js.map +1 -1
  197. package/overlay/overlay.js.map +1 -1
  198. package/package.json +1 -1
  199. package/pagination/pagination.js.map +1 -1
  200. package/phone-number-input/phone-number-input.js.map +1 -1
  201. package/predictive-text-input/predictive-text-input.js.map +1 -1
  202. package/shared/dropdown-list/dropdown-list.js.map +1 -1
  203. package/shared/internal-calendar/calendar-manager.js.map +1 -1
  204. package/shared/standalone-date-input/standalone-date-input.js.map +1 -1
  205. package/singpass-button/singpass-button.styles.js +1 -1
  206. package/singpass-button/singpass-button.styles.js.map +1 -1
  207. package/singpass-button/{singpass-button.styles_1miyex3.css → singpass-button.styles_1fj2lru.css} +1 -1
  208. package/smart-app-banner/smart-app-banner.styles.js +1 -1
  209. package/smart-app-banner/smart-app-banner.styles.js.map +1 -1
  210. package/smart-app-banner/{smart-app-banner.styles_15u6yv4.css → smart-app-banner.styles_r6yjq9.css} +1 -1
  211. package/theme/styles/a11y-playground.css +358 -87
  212. package/theme/styles/bookingsg.css +391 -85
  213. package/theme/styles/careercompass.css +396 -90
  214. package/theme/styles/ccube.css +402 -45
  215. package/theme/styles/imda.css +348 -85
  216. package/theme/styles/lifesg.css +377 -87
  217. package/theme/styles/mylegacy.css +382 -85
  218. package/theme/styles/oneservice.css +349 -86
  219. package/theme/styles/pa.css +172 -104
  220. package/theme/styles/rbs.css +403 -46
  221. package/theme/styles/sgw-digital-lobby.css +352 -87
  222. package/theme/styles/smgs.css +401 -95
  223. package/theme/styles/spf.css +208 -99
  224. package/theme/styles/supportgowhere.css +387 -90
  225. package/theme/styles/tote-board.css +816 -0
  226. package/theme/types.d.ts +1 -1
  227. package/theme/types.js +1 -1
  228. package/theme/types.js.map +1 -1
  229. package/time-slot-bar/time-slot-bar.js.map +1 -1
  230. package/time-slot-bar-week/time-slot-bar-week-days.js.map +1 -1
  231. package/timetable/timetable.js.map +1 -1
  232. package/toast/toast.styles.js +1 -1
  233. package/toast/toast.styles.js.map +1 -1
  234. package/{cjs/toast/toast.styles_1e0l60w.css → toast/toast.styles_57j3lf.css} +1 -1
  235. package/toggle/toggle-icon.d.ts +2 -1
  236. package/toggle/toggle-icon.js +1 -1
  237. package/toggle/toggle-icon.js.map +1 -1
  238. package/toggle/toggle-icon.styles.d.ts +1 -0
  239. package/toggle/toggle-icon.styles.js +1 -1
  240. package/toggle/toggle-icon.styles.js.map +1 -1
  241. package/toggle/{toggle-icon.styles_ba71y.css → toggle-icon.styles_o6dxr3.css} +3 -2
  242. package/toggle/toggle.js +1 -1
  243. package/toggle/toggle.js.map +1 -1
  244. package/toggle/toggle.styles.d.ts +18 -15
  245. package/toggle/toggle.styles.js +1 -1
  246. package/toggle/toggle.styles.js.map +1 -1
  247. package/toggle/toggle.styles_11tmfsr.css +41 -0
  248. package/tools/storybook-argtypes/services/arg-types-row-builder.d.ts +6 -0
  249. package/tools/storybook-argtypes/types.d.ts +13 -1
  250. package/unit-number/unit-number-input.js.map +1 -1
  251. package/util/is-styled-components.js.map +1 -1
  252. package/util/string-helper.d.ts +2 -2
  253. package/util/string-helper.js +1 -1
  254. package/util/string-helper.js.map +1 -1
  255. package/util/use-event-listener.js.map +1 -1
  256. package/util/use-state-actions.js.map +1 -1
  257. package/button/button.styles_1pxy0co.css +0 -20
  258. package/cjs/button/button.styles_1pxy0co.css +0 -20
  259. package/cjs/form/form-textarea/form-textarea.styles.js +0 -2
  260. package/cjs/form/form-textarea/form-textarea.styles.js.map +0 -1
  261. package/cjs/form/form-textarea/form-textarea.styles_1kneyif.css +0 -3
  262. package/cjs/toggle/toggle.styles_1t5qrye.css +0 -38
  263. package/form/form-textarea/form-textarea.styles.d.ts +0 -3
  264. package/form/form-textarea/form-textarea.styles.js +0 -2
  265. package/form/form-textarea/form-textarea.styles.js.map +0 -1
  266. package/form/form-textarea/form-textarea.styles_1kneyif.css +0 -3
  267. package/theme/styles/default.css +0 -158
  268. package/toggle/toggle.styles_1t5qrye.css +0 -38
@@ -1 +1 @@
1
- {"version":3,"file":"time-slot-bar-week-days.js","sources":["../../../src/time-slot-bar-week/time-slot-bar-week-days.tsx"],"sourcesContent":["import { ChevronUpIcon } from \"@lifesg/react-icons\";\nimport { animated, useSpring } from \"@react-spring/web\";\nimport clsx from \"clsx\";\nimport type { Dayjs } from \"dayjs\";\nimport dayjs from \"dayjs\";\nimport isEmpty from \"lodash/isEmpty\";\nimport maxBy from \"lodash/maxBy\";\nimport minBy from \"lodash/minBy\";\nimport { useMemo, useRef, useState } from \"react\";\nimport { useResizeDetector } from \"react-resize-detector\";\n\nimport { Button } from \"../button\";\nimport type { InternalCalendarProps } from \"../shared/internal-calendar\";\nimport type { CellStyleProps } from \"../shared/internal-calendar/day-cell\";\nimport { DayCell } from \"../shared/internal-calendar/day-cell\";\nimport { Colour, formatUnitValue, useApplyStyle } from \"../theme\";\nimport type { TimeSlot } from \"../time-slot-bar/types\";\nimport { Typography } from \"../typography\";\nimport { DateHelper, useIsMounted } from \"../util\";\nimport { CalendarHelper } from \"../util/calendar-helper\";\nimport { StringHelper } from \"../util/string-helper\";\nimport { TimeHelper } from \"../util/time-helper\";\nimport { ROW_HEIGHT, SLOT_GAP } from \"./consts\";\nimport * as styles from \"./time-slot-bar-week-days.styles\";\nimport type { FocusableSlotMeta, TimeSlotCell } from \"./time-slot-cell\";\nimport { WeekTimeSlotCell } from \"./time-slot-cell\";\nimport type { TimeSlotCellsVariant } from \"./types\";\n\ninterface TimeSlotWeekDaysProps\n extends Pick<\n InternalCalendarProps,\n \"disabledDates\" | \"minDate\" | \"maxDate\"\n > {\n selectedDate: string | undefined;\n calendarDate: Dayjs;\n onSelect: (value: Dayjs) => void;\n slots: { [date: string]: TimeSlot[] };\n startTime?: string | undefined;\n endTime?: string | undefined;\n maxVisibleCellHeight?: number | undefined;\n interval?: number | undefined;\n variant?: TimeSlotCellsVariant | undefined;\n enableSelection?: boolean | undefined;\n onSlotClick?: ((date: string, timeSlot: TimeSlot) => void) | undefined;\n}\n\nexport const TimeSlotBarWeekDays = ({\n calendarDate,\n disabledDates,\n selectedDate,\n onSelect,\n minDate,\n maxDate,\n startTime,\n endTime,\n maxVisibleCellHeight,\n slots: daySlots,\n interval = 30,\n variant = \"flexible\",\n enableSelection = true,\n onSlotClick,\n}: TimeSlotWeekDaysProps) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const dateFormat = \"YYYY-MM-DD\";\n const [expandAll, setExpandAll] = useState<boolean>(false);\n const [hoverDay, setHoverDay] = useState<Dayjs>();\n const isMounted = useIsMounted();\n const slotButtonRefs = useRef<Record<string, HTMLButtonElement | null>>({});\n const timeColumnRef = useRef<HTMLDivElement>(null);\n const currentCalendarWeek = useMemo((): Dayjs[] => {\n return CalendarHelper.generateDaysForCurrentWeek(calendarDate);\n }, [calendarDate]);\n\n const flattenedSlots = Object.values(daySlots ?? {}).flat();\n const minStartTime =\n startTime ?? minBy(flattenedSlots, \"startTime\")?.startTime ?? \"00:00\";\n const maxEndTime =\n endTime ?? maxBy(flattenedSlots, \"endTime\")?.endTime ?? \"24:00\";\n const numberOfCells = Math.ceil(\n DateHelper.getTimeDiffInMinutes(minStartTime, maxEndTime) / interval\n );\n\n // React spring animation configuration\n const { height: actualHeight = 0, ref: cellsRef } = useResizeDetector();\n const hasCollapsedContent =\n !!maxVisibleCellHeight && actualHeight > maxVisibleCellHeight;\n const visibleRowCount =\n maxVisibleCellHeight !== undefined\n ? Math.max(\n 1,\n Math.floor((maxVisibleCellHeight + SLOT_GAP) / ROW_HEIGHT)\n )\n : 0;\n const collapsedHeight =\n visibleRowCount > 0\n ? visibleRowCount * ROW_HEIGHT - SLOT_GAP\n : maxVisibleCellHeight;\n const height = maxVisibleCellHeight\n ? !hasCollapsedContent || expandAll\n ? actualHeight\n : collapsedHeight\n : actualHeight;\n const expandableStyles = useSpring({ height });\n\n const generatedDaySlots = useMemo((): {\n [date: string]: TimeSlotCell[];\n } => {\n if (daySlots) {\n const transformedDaySlots: Record<string, TimeSlotCell[]> = {};\n Object.entries(daySlots).forEach(([key, slots]) => {\n const cellsArray = initializeAndFillSlots(slots);\n transformedDaySlots[key] = populateEmptyCells(cellsArray);\n });\n return transformedDaySlots;\n }\n return {};\n }, [daySlots]);\n\n const focusableSlotsByDate = useMemo(() => {\n return currentCalendarWeek.reduce<Record<string, FocusableSlotMeta[]>>(\n (result, day) => {\n const formattedDate = day.format(dateFormat);\n\n result[formattedDate] = getCellsForDate(formattedDate)\n .filter(\n (\n slot\n ): slot is TimeSlotCell & {\n isActualSlot: true;\n rowIndex: number;\n } => !!slot.isActualSlot && slot.rowIndex !== undefined\n )\n .map((slot) => ({\n key: `${formattedDate}-${slot.id}`,\n date: formattedDate,\n rowIndex: slot.rowIndex,\n }))\n .sort((a, b) => a.rowIndex - b.rowIndex);\n\n return result;\n },\n {}\n );\n }, [currentCalendarWeek, generatedDaySlots]);\n\n useApplyStyle(timeColumnRef, {\n [styles.tokens.timeColumn.height]: formatUnitValue(height, \"px\"),\n });\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleDayClick = (value: Dayjs, isDisabled: boolean) => {\n if (isDisabled || !enableSelection) return;\n\n onSelect(value);\n };\n\n const handleDayHover = (value: Dayjs) => {\n setHoverDay(value);\n };\n\n const handleDayHoverClear = () => {\n setHoverDay(undefined);\n };\n\n const handleSlotClick = (date: string, slot: TimeSlot) => {\n onSlotClick?.(date, slot);\n };\n\n const handleSlotButtonClick =\n (date: string, slot: TimeSlot) =>\n (event: React.MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n\n handleSlotClick(date, slot);\n };\n\n const handleExpandCollapseClick = (event: React.MouseEvent) => {\n event.preventDefault();\n setExpandAll((prevExpandValue) => !prevExpandValue);\n };\n\n const handleSlotKeyDown = (\n event: React.KeyboardEvent<HTMLButtonElement>,\n currentSlot: FocusableSlotMeta\n ) => {\n const sameColumnSlots = focusableSlotsByDate[currentSlot.date] ?? [];\n\n const focusSlot = (slot?: FocusableSlotMeta) => {\n if (!slot) return;\n slotButtonRefs.current[slot.key]?.focus();\n };\n\n switch (event.key) {\n case \"ArrowRight\":\n case \"ArrowDown\": {\n event.preventDefault();\n const currentIndex = sameColumnSlots.findIndex(\n (slot) => slot.key === currentSlot.key\n );\n focusSlot(sameColumnSlots[currentIndex + 1]);\n break;\n }\n case \"ArrowLeft\":\n case \"ArrowUp\": {\n event.preventDefault();\n const currentIndex = sameColumnSlots.findIndex(\n (slot) => slot.key === currentSlot.key\n );\n focusSlot(sameColumnSlots[currentIndex - 1]);\n break;\n }\n case \"Home\":\n event.preventDefault();\n focusSlot(sameColumnSlots[0]);\n break;\n case \"End\":\n event.preventDefault();\n focusSlot(sameColumnSlots[sameColumnSlots.length - 1]);\n break;\n case \"PageUp\":\n event.preventDefault();\n focusSlot(sameColumnSlots[0]);\n break;\n case \"PageDown\": {\n event.preventDefault();\n if (hasCollapsedContent && !expandAll) {\n setExpandAll(true);\n const lastVisibleSlot = [...sameColumnSlots]\n .reverse()\n .find((slot) => slot.rowIndex < visibleRowCount);\n focusSlot(lastVisibleSlot ?? sameColumnSlots[0]);\n break;\n }\n\n focusSlot(sameColumnSlots[sameColumnSlots.length - 1]);\n break;\n }\n default:\n break;\n }\n };\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n const isDisabled = (day: Dayjs): boolean => {\n const isWithinRange = CalendarHelper.isWithinRange(\n day,\n minDate ? dayjs(minDate) : undefined,\n maxDate ? dayjs(maxDate) : undefined\n );\n\n const isDisabledDate =\n (disabledDates && disabledDates.includes(day.format(dateFormat))) ??\n false;\n\n return !isWithinRange || isDisabledDate;\n };\n\n const generateStyleProps = (day: Dayjs) => {\n const dateStartWithYear = day.format(dateFormat);\n const disabled = isDisabled(day);\n const dayCellStyleProps: CellStyleProps = {};\n const isHoverEnabled = enableSelection && !disabled;\n\n if (disabled) {\n dayCellStyleProps.disabled = true;\n }\n\n dayCellStyleProps.interactive = enableSelection\n ? isHoverEnabled\n : false;\n\n const isHover =\n isHoverEnabled && hoverDay && day.isSame(hoverDay, \"day\");\n const isSelected = [selectedDate].includes(dateStartWithYear);\n\n if (isSelected && isHover) {\n dayCellStyleProps.labelType = \"selected-hover\";\n dayCellStyleProps.circleLeft = \"selected-hover-outline\";\n dayCellStyleProps.circleRight = \"selected-hover-outline\";\n } else if (isSelected) {\n dayCellStyleProps.labelType = \"selected\";\n dayCellStyleProps.circleLeft = \"selected-outline\";\n dayCellStyleProps.circleRight = \"selected-outline\";\n } else if (isHover) {\n dayCellStyleProps.labelType = \"hover\";\n dayCellStyleProps.circleLeft = \"hover-subtle\";\n dayCellStyleProps.circleRight = \"hover-subtle\";\n }\n\n return dayCellStyleProps;\n };\n\n function generateFallbackCell(\n prefix: string | number,\n cellLength = 1\n ): TimeSlotCell {\n return {\n id: `${prefix.toString()}-${new Date().getTime()}`,\n startTime: \"\",\n endTime: \"\",\n clickable: false,\n isActualSlot: false,\n styleAttributes: {\n backgroundColor: Colour[\"bg-stronger\"],\n },\n cellLength,\n };\n }\n\n function getSlotAriaLabel(date: string, slot: TimeSlot) {\n const { startTime: slotStartTime, endTime: slotEndTime } = slot;\n\n return StringHelper.joinNonEmptyStrings([\n dayjs(date).format(\"D MMMM YYYY dddd\"),\n slotStartTime && slotEndTime\n ? TimeHelper.formatTimeRange(slotStartTime, slotEndTime)\n : undefined,\n slot.label,\n slot.clickable ?? true ? \"Available\" : \"Unavailable\",\n ]);\n }\n\n function initializeAndFillSlots(slots: TimeSlot[]): TimeSlotCell[] {\n const cellsArray = Array(numberOfCells).fill({});\n\n slots.forEach((slot) => {\n const startIndex = Math.max(\n 0,\n DateHelper.getTimeDiffInMinutes(minStartTime, slot.startTime) /\n interval\n );\n const endIndex = Math.min(\n numberOfCells,\n DateHelper.getTimeDiffInMinutes(minStartTime, slot.endTime) /\n interval\n );\n const cellLength = Math.ceil(endIndex) - Math.floor(startIndex);\n\n switch (variant) {\n case \"fixed\":\n // Keep fixed slots as 1 long cell\n cellsArray[Math.floor(startIndex)] = {\n ...slot,\n isActualSlot: true,\n rowIndex: Math.floor(startIndex),\n cellLength: endIndex - startIndex,\n };\n break;\n case \"flexible\":\n // Split long slot into multiple cells of length 1\n for (let i = 0; i < cellLength; i++) {\n const startTime = DateHelper.addMinutesToTime(\n minStartTime,\n Math.floor(startIndex + i) * interval\n );\n const endTime = DateHelper.addMinutesToTime(\n startTime,\n interval\n );\n\n let halfFill: \"default\" | \"top\" | \"bottom\";\n\n if (!isEmpty(cellsArray[Math.floor(startIndex + i)])) {\n // Previous cell extends into current cell, fill entire cell\n halfFill = \"default\";\n } else if (i === 0 && startIndex % 1 !== 0) {\n halfFill = \"top\";\n } else if (i === cellLength - 1 && endIndex % 1 !== 0) {\n halfFill = \"bottom\";\n } else {\n halfFill = \"default\";\n }\n\n cellsArray[Math.floor(startIndex + i)] = {\n ...slot,\n id: `${slot.id}-${i}`,\n startTime,\n endTime,\n isActualSlot: true,\n rowIndex: Math.floor(startIndex + i),\n cellLength: 1,\n halfFill,\n };\n }\n break;\n }\n });\n return cellsArray;\n }\n\n function populateEmptyCells(cellsArray: any[]): TimeSlotCell[] {\n let i = 0;\n switch (variant) {\n case \"fixed\":\n // Truncate consecutive empty cells into 1 [{},{},{...},{},{}] -> [{},{...},{}]\n cellsArray = cellsArray.reduce(\n (result, obj) => {\n const lastObj =\n result.length > 0\n ? result[result.length - 1]\n : result[0];\n if (isEmpty(obj) && isEmpty(lastObj)) {\n return result;\n }\n return [...result, obj];\n },\n [{}]\n );\n\n // Fill in empty cells with timings & corresponding cell lengths\n while (i < cellsArray.length) {\n if (isEmpty(cellsArray[i])) {\n const startTime =\n cellsArray[i - 1]?.endTime ?? minStartTime;\n const endTime =\n cellsArray[i + 1]?.startTime ?? maxEndTime;\n if (startTime !== endTime) {\n const cellLength =\n DateHelper.getTimeDiffInMinutes(\n startTime,\n endTime\n ) / interval;\n cellsArray[i] = {\n ...generateFallbackCell(i),\n startTime,\n endTime,\n cellLength,\n };\n }\n }\n i++;\n }\n break;\n case \"flexible\":\n // Fill in individual empty cell with interval timings\n while (i < cellsArray.length) {\n if (isEmpty(cellsArray[i])) {\n cellsArray[i] = generateFallbackCell(i);\n i++;\n } else {\n i += cellsArray[i].cellLength;\n }\n }\n break;\n }\n return cellsArray.filter(\n (slot) => !isEmpty(slot) && slot.cellLength > 0\n );\n }\n\n function getCellsForDate(formattedDate: string) {\n return (\n generatedDaySlots[formattedDate] ??\n Array(variant === \"flexible\" ? numberOfCells : 1)\n .fill(undefined)\n .map((_, index) =>\n generateFallbackCell(\n index,\n variant === \"fixed\" ? numberOfCells : undefined\n )\n )\n );\n }\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderWeek = () => {\n return (\n <div className={styles.headerCellWeekColumn} role=\"row\">\n {currentCalendarWeek.map((day, index) => (\n <div\n key={`week-day-${index}`}\n className={styles.headerCellWeek}\n role=\"gridcell\"\n >\n <Typography.BodyXS\n weight={\"semibold\"}\n className={clsx(\n isDisabled(day) && styles.cellWeekTextDisabled\n )}\n >\n {dayjs(day).format(\"ddd\")}\n </Typography.BodyXS>\n </div>\n ))}\n </div>\n );\n };\n\n const renderHeader = () => {\n return (\n <div\n className={styles.headerCellWeekColumn}\n role=\"row\"\n onBlur={handleDayHoverClear}\n >\n {currentCalendarWeek.map((day, dayIndex) => {\n const dayCellStyleProps = generateStyleProps(day);\n\n return (\n <DayCell\n key={`day-${dayIndex}`}\n date={day}\n calendarDate={dayjs(selectedDate)}\n role=\"columnheader\"\n tabIndex={dayCellStyleProps.interactive ? 0 : -1}\n onSelect={() => {\n handleDayClick(\n day,\n !dayCellStyleProps.interactive\n );\n }}\n onHover={handleDayHover}\n onHoverEnd={handleDayHoverClear}\n onFocus={handleDayHover}\n {...dayCellStyleProps}\n ></DayCell>\n );\n })}\n </div>\n );\n };\n\n const renderTimeColumn = () => {\n let hasSetFirstAfternoonHour = false;\n\n const formatTime = (index: number) => {\n const parsedTime = dayjs(minStartTime, \"HH:mm\").add(\n index * 4 * interval,\n \"minutes\"\n );\n const hour = parsedTime.format(\"h\");\n const minutes = parsedTime.format(\"mm\");\n const amPm = parsedTime.format(\"a\");\n\n let formattedTime = `${hour}${\n minutes !== \"00\" ? ` ${minutes}` : \"\"\n }`;\n\n if (\n !hasSetFirstAfternoonHour &&\n amPm === \"pm\" &&\n minutes === \"00\"\n ) {\n formattedTime += ` ${amPm}`;\n hasSetFirstAfternoonHour = true;\n }\n\n return formattedTime;\n };\n\n return (\n <div className={styles.timeColumn} ref={timeColumnRef} aria-hidden>\n {Array(Math.ceil(numberOfCells / 4))\n .fill(undefined)\n .map((_, index) => (\n <div\n key={`time-${index}`}\n className={styles.timeColumnWrapper}\n >\n <div className={styles.timeColumnText}>\n {formatTime(index)}\n </div>\n </div>\n ))}\n </div>\n );\n };\n\n const renderSlotCell = (formattedDate: string, slot: TimeSlotCell) => {\n return (\n <WeekTimeSlotCell\n key={slot.id}\n formattedDate={formattedDate}\n slot={slot}\n variant={variant}\n hasCollapsedContent={hasCollapsedContent}\n expandAll={expandAll}\n visibleRowCount={visibleRowCount}\n onSlotClick={handleSlotClick}\n getSlotAriaLabel={getSlotAriaLabel}\n onSlotKeyDown={handleSlotKeyDown}\n onSlotButtonClick={handleSlotButtonClick}\n slotButtonRefs={slotButtonRefs}\n />\n );\n };\n\n const renderTimeSlotBarCells = () => {\n return (\n <animated.div\n className={styles.expandable}\n style={isMounted ? expandableStyles : undefined}\n role=\"row\"\n >\n <div\n className={styles.columnWeekCell}\n ref={cellsRef}\n key={`week-cell-${calendarDate.format(dateFormat)}`}\n >\n {currentCalendarWeek.map((day, dayIndex) => {\n const formattedDate = day.format(dateFormat);\n const cellsArray = getCellsForDate(formattedDate);\n return (\n <div\n key={`wrapper-${dayIndex}`}\n className={styles.timeSlotWrapper}\n role=\"gridcell\"\n >\n {cellsArray.map((slot) =>\n renderSlotCell(formattedDate, slot)\n )}\n </div>\n );\n })}\n </div>\n </animated.div>\n );\n };\n\n const renderCollapseExpandAll = () => {\n if (!maxVisibleCellHeight || !cellsRef.current) return;\n return (\n <div className={styles.collapseExpandAllWrapper}>\n <Button\n data-testid=\"time-bar-expand-collapse-button\"\n styleType=\"light\"\n sizeType=\"small\"\n aria-expanded={expandAll}\n onClick={handleExpandCollapseClick}\n className={styles.collapseExpandAllButton}\n >\n <span className={styles.collapseExpandAllButtonContent}>\n <ChevronUpIcon\n className={clsx(\n styles.chevronIcon,\n expandAll && styles.chevronIconExpanded\n )}\n />\n {`${expandAll ? \"Hide\" : \"Show\"} later times`}\n </span>\n </Button>\n </div>\n );\n };\n\n return (\n <div className={styles.wrapper}>\n <div className={styles.gridWrapper} role=\"grid\">\n {renderHeader()}\n {renderWeek()}\n {renderTimeColumn()}\n {renderTimeSlotBarCells()}\n </div>\n {renderCollapseExpandAll()}\n </div>\n );\n};\n"],"names":["calendarDate","disabledDates","selectedDate","onSelect","minDate","maxDate","startTime","endTime","maxVisibleCellHeight","slots","daySlots","interval","variant","enableSelection","onSlotClick","dateFormat","expandAll","setExpandAll","useState","hoverDay","setHoverDay","isMounted","useIsMounted","slotButtonRefs","useRef","timeColumnRef","currentCalendarWeek","useMemo","CalendarHelper","generateDaysForCurrentWeek","flattenedSlots","Object","values","flat","minStartTime","_b","_a","minBy","maxEndTime","_d","_c","maxBy","numberOfCells","Math","ceil","DateHelper","getTimeDiffInMinutes","height","actualHeight","ref","cellsRef","useResizeDetector","hasCollapsedContent","visibleRowCount","undefined","max","floor","SLOT_GAP","ROW_HEIGHT","collapsedHeight","expandableStyles","useSpring","generatedDaySlots","transformedDaySlots","entries","forEach","key","cellsArray","Array","fill","slot","startIndex","endIndex","min","cellLength","assign","isActualSlot","rowIndex","i","addMinutesToTime","halfFill","isEmpty","id","initializeAndFillSlots","reduce","result","obj","lastObj","length","generateFallbackCell","filter","populateEmptyCells","focusableSlotsByDate","day","formattedDate","format","getCellsForDate","map","date","sort","a","b","useApplyStyle","styles.tokens","timeColumn","formatUnitValue","handleDayHover","value","handleDayHoverClear","handleSlotClick","handleSlotButtonClick","event","stopPropagation","handleExpandCollapseClick","preventDefault","prevExpandValue","handleSlotKeyDown","currentSlot","sameColumnSlots","focusSlot","current","focus","currentIndex","findIndex","lastVisibleSlot","reverse","find","isDisabled","isWithinRange","dayjs","isDisabledDate","includes","prefix","toString","Date","getTime","clickable","styleAttributes","backgroundColor","Colour","getSlotAriaLabel","slotStartTime","slotEndTime","StringHelper","joinNonEmptyStrings","TimeHelper","formatTimeRange","label","_","index","_jsxs","className","styles.wrapper","children","styles.gridWrapper","role","_jsx","styles.headerCellWeekColumn","onBlur","dayIndex","dayCellStyleProps","dateStartWithYear","disabled","isHoverEnabled","interactive","isHover","isSame","isSelected","labelType","circleLeft","circleRight","generateStyleProps","DayCell","tabIndex","handleDayClick","onHover","onHoverEnd","onFocus","styles.headerCellWeek","Typography","BodyXS","weight","clsx","styles.cellWeekTextDisabled","hasSetFirstAfternoonHour","formatTime","parsedTime","add","hour","minutes","amPm","formattedTime","styles.timeColumn","styles.timeColumnWrapper","styles.timeColumnText","renderTimeColumn","animated","div","styles.expandable","style","styles.columnWeekCell","styles.timeSlotWrapper","WeekTimeSlotCell","onSlotKeyDown","onSlotButtonClick","renderSlotCell","styles.collapseExpandAllWrapper","Button","styleType","sizeType","onClick","styles.collapseExpandAllButton","styles.collapseExpandAllButtonContent","ChevronUpIcon","styles.chevronIcon","styles.chevronIconExpanded","renderCollapseExpandAll"],"mappings":"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"}
1
+ {"version":3,"file":"time-slot-bar-week-days.js","sources":["../../../src/time-slot-bar-week/time-slot-bar-week-days.tsx"],"sourcesContent":["import { ChevronUpIcon } from \"@lifesg/react-icons\";\nimport { animated, useSpring } from \"@react-spring/web\";\nimport clsx from \"clsx\";\nimport type { Dayjs } from \"dayjs\";\nimport dayjs from \"dayjs\";\nimport isEmpty from \"lodash/isEmpty\";\nimport maxBy from \"lodash/maxBy\";\nimport minBy from \"lodash/minBy\";\nimport { useMemo, useRef, useState } from \"react\";\nimport { useResizeDetector } from \"react-resize-detector\";\n\nimport { Button } from \"../button\";\nimport type { InternalCalendarProps } from \"../shared/internal-calendar\";\nimport type { CellStyleProps } from \"../shared/internal-calendar/day-cell\";\nimport { DayCell } from \"../shared/internal-calendar/day-cell\";\nimport { Colour, formatUnitValue, useApplyStyle } from \"../theme\";\nimport type { TimeSlot } from \"../time-slot-bar/types\";\nimport { Typography } from \"../typography\";\nimport { DateHelper, useIsMounted } from \"../util\";\nimport { CalendarHelper } from \"../util/calendar-helper\";\nimport { StringHelper } from \"../util/string-helper\";\nimport { TimeHelper } from \"../util/time-helper\";\nimport { ROW_HEIGHT, SLOT_GAP } from \"./consts\";\nimport * as styles from \"./time-slot-bar-week-days.styles\";\nimport type { FocusableSlotMeta, TimeSlotCell } from \"./time-slot-cell\";\nimport { WeekTimeSlotCell } from \"./time-slot-cell\";\nimport type { TimeSlotCellsVariant } from \"./types\";\n\ninterface TimeSlotWeekDaysProps\n extends Pick<\n InternalCalendarProps,\n \"disabledDates\" | \"minDate\" | \"maxDate\"\n > {\n selectedDate: string | undefined;\n calendarDate: Dayjs;\n onSelect: (value: Dayjs) => void;\n slots: { [date: string]: TimeSlot[] };\n startTime?: string | undefined;\n endTime?: string | undefined;\n maxVisibleCellHeight?: number | undefined;\n interval?: number | undefined;\n variant?: TimeSlotCellsVariant | undefined;\n enableSelection?: boolean | undefined;\n onSlotClick?: ((date: string, timeSlot: TimeSlot) => void) | undefined;\n}\n\nexport const TimeSlotBarWeekDays = ({\n calendarDate,\n disabledDates,\n selectedDate,\n onSelect,\n minDate,\n maxDate,\n startTime,\n endTime,\n maxVisibleCellHeight,\n slots: daySlots,\n interval = 30,\n variant = \"flexible\",\n enableSelection = true,\n onSlotClick,\n}: TimeSlotWeekDaysProps) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const dateFormat = \"YYYY-MM-DD\";\n const [expandAll, setExpandAll] = useState<boolean>(false);\n const [hoverDay, setHoverDay] = useState<Dayjs>();\n const isMounted = useIsMounted();\n const slotButtonRefs = useRef<Record<string, HTMLButtonElement | null>>({});\n const timeColumnRef = useRef<HTMLDivElement>(null);\n const currentCalendarWeek = useMemo((): Dayjs[] => {\n return CalendarHelper.generateDaysForCurrentWeek(calendarDate);\n }, [calendarDate]);\n\n const flattenedSlots = Object.values(daySlots ?? {}).flat();\n const minStartTime =\n startTime ?? minBy(flattenedSlots, \"startTime\")?.startTime ?? \"00:00\";\n const maxEndTime =\n endTime ?? maxBy(flattenedSlots, \"endTime\")?.endTime ?? \"24:00\";\n const numberOfCells = Math.ceil(\n DateHelper.getTimeDiffInMinutes(minStartTime, maxEndTime) / interval\n );\n\n // React spring animation configuration\n const { height: actualHeight = 0, ref: cellsRef } = useResizeDetector();\n const hasCollapsedContent =\n !!maxVisibleCellHeight && actualHeight > maxVisibleCellHeight;\n const visibleRowCount =\n maxVisibleCellHeight !== undefined\n ? Math.max(\n 1,\n Math.floor((maxVisibleCellHeight + SLOT_GAP) / ROW_HEIGHT)\n )\n : 0;\n const collapsedHeight =\n visibleRowCount > 0\n ? visibleRowCount * ROW_HEIGHT - SLOT_GAP\n : maxVisibleCellHeight;\n const height = maxVisibleCellHeight\n ? !hasCollapsedContent || expandAll\n ? actualHeight\n : collapsedHeight\n : actualHeight;\n const expandableStyles = useSpring({ height });\n\n const generatedDaySlots = useMemo((): {\n [date: string]: TimeSlotCell[];\n } => {\n if (daySlots) {\n const transformedDaySlots: Record<string, TimeSlotCell[]> = {};\n Object.entries(daySlots).forEach(([key, slots]) => {\n const cellsArray = initializeAndFillSlots(slots);\n transformedDaySlots[key] = populateEmptyCells(cellsArray);\n });\n return transformedDaySlots;\n }\n return {};\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [daySlots]);\n\n const focusableSlotsByDate = useMemo(() => {\n return currentCalendarWeek.reduce<Record<string, FocusableSlotMeta[]>>(\n (result, day) => {\n const formattedDate = day.format(dateFormat);\n\n result[formattedDate] = getCellsForDate(formattedDate)\n .filter(\n (\n slot\n ): slot is TimeSlotCell & {\n isActualSlot: true;\n rowIndex: number;\n } => !!slot.isActualSlot && slot.rowIndex !== undefined\n )\n .map((slot) => ({\n key: `${formattedDate}-${slot.id}`,\n date: formattedDate,\n rowIndex: slot.rowIndex,\n }))\n .sort((a, b) => a.rowIndex - b.rowIndex);\n\n return result;\n },\n {}\n );\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [currentCalendarWeek, generatedDaySlots]);\n\n useApplyStyle(timeColumnRef, {\n [styles.tokens.timeColumn.height]: formatUnitValue(height, \"px\"),\n });\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleDayClick = (value: Dayjs, isDisabled: boolean) => {\n if (isDisabled || !enableSelection) return;\n\n onSelect(value);\n };\n\n const handleDayHover = (value: Dayjs) => {\n setHoverDay(value);\n };\n\n const handleDayHoverClear = () => {\n setHoverDay(undefined);\n };\n\n const handleSlotClick = (date: string, slot: TimeSlot) => {\n onSlotClick?.(date, slot);\n };\n\n const handleSlotButtonClick =\n (date: string, slot: TimeSlot) =>\n (event: React.MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n\n handleSlotClick(date, slot);\n };\n\n const handleExpandCollapseClick = (event: React.MouseEvent) => {\n event.preventDefault();\n setExpandAll((prevExpandValue) => !prevExpandValue);\n };\n\n const handleSlotKeyDown = (\n event: React.KeyboardEvent<HTMLButtonElement>,\n currentSlot: FocusableSlotMeta\n ) => {\n const sameColumnSlots = focusableSlotsByDate[currentSlot.date] ?? [];\n\n const focusSlot = (slot?: FocusableSlotMeta) => {\n if (!slot) return;\n slotButtonRefs.current[slot.key]?.focus();\n };\n\n switch (event.key) {\n case \"ArrowRight\":\n case \"ArrowDown\": {\n event.preventDefault();\n const currentIndex = sameColumnSlots.findIndex(\n (slot) => slot.key === currentSlot.key\n );\n focusSlot(sameColumnSlots[currentIndex + 1]);\n break;\n }\n case \"ArrowLeft\":\n case \"ArrowUp\": {\n event.preventDefault();\n const currentIndex = sameColumnSlots.findIndex(\n (slot) => slot.key === currentSlot.key\n );\n focusSlot(sameColumnSlots[currentIndex - 1]);\n break;\n }\n case \"Home\":\n event.preventDefault();\n focusSlot(sameColumnSlots[0]);\n break;\n case \"End\":\n event.preventDefault();\n focusSlot(sameColumnSlots[sameColumnSlots.length - 1]);\n break;\n case \"PageUp\":\n event.preventDefault();\n focusSlot(sameColumnSlots[0]);\n break;\n case \"PageDown\": {\n event.preventDefault();\n if (hasCollapsedContent && !expandAll) {\n setExpandAll(true);\n const lastVisibleSlot = [...sameColumnSlots]\n .reverse()\n .find((slot) => slot.rowIndex < visibleRowCount);\n focusSlot(lastVisibleSlot ?? sameColumnSlots[0]);\n break;\n }\n\n focusSlot(sameColumnSlots[sameColumnSlots.length - 1]);\n break;\n }\n default:\n break;\n }\n };\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n const isDisabled = (day: Dayjs): boolean => {\n const isWithinRange = CalendarHelper.isWithinRange(\n day,\n minDate ? dayjs(minDate) : undefined,\n maxDate ? dayjs(maxDate) : undefined\n );\n\n const isDisabledDate =\n (disabledDates && disabledDates.includes(day.format(dateFormat))) ??\n false;\n\n return !isWithinRange || isDisabledDate;\n };\n\n const generateStyleProps = (day: Dayjs) => {\n const dateStartWithYear = day.format(dateFormat);\n const disabled = isDisabled(day);\n const dayCellStyleProps: CellStyleProps = {};\n const isHoverEnabled = enableSelection && !disabled;\n\n if (disabled) {\n dayCellStyleProps.disabled = true;\n }\n\n dayCellStyleProps.interactive = enableSelection\n ? isHoverEnabled\n : false;\n\n const isHover =\n isHoverEnabled && hoverDay && day.isSame(hoverDay, \"day\");\n const isSelected = [selectedDate].includes(dateStartWithYear);\n\n if (isSelected && isHover) {\n dayCellStyleProps.labelType = \"selected-hover\";\n dayCellStyleProps.circleLeft = \"selected-hover-outline\";\n dayCellStyleProps.circleRight = \"selected-hover-outline\";\n } else if (isSelected) {\n dayCellStyleProps.labelType = \"selected\";\n dayCellStyleProps.circleLeft = \"selected-outline\";\n dayCellStyleProps.circleRight = \"selected-outline\";\n } else if (isHover) {\n dayCellStyleProps.labelType = \"hover\";\n dayCellStyleProps.circleLeft = \"hover-subtle\";\n dayCellStyleProps.circleRight = \"hover-subtle\";\n }\n\n return dayCellStyleProps;\n };\n\n function generateFallbackCell(\n prefix: string | number,\n cellLength = 1\n ): TimeSlotCell {\n return {\n id: `${prefix.toString()}-${new Date().getTime()}`,\n startTime: \"\",\n endTime: \"\",\n clickable: false,\n isActualSlot: false,\n styleAttributes: {\n backgroundColor: Colour[\"bg-stronger\"],\n },\n cellLength,\n };\n }\n\n function getSlotAriaLabel(date: string, slot: TimeSlot) {\n const { startTime: slotStartTime, endTime: slotEndTime } = slot;\n\n return StringHelper.joinNonEmptyStrings([\n dayjs(date).format(\"D MMMM YYYY dddd\"),\n slotStartTime && slotEndTime\n ? TimeHelper.formatTimeRange(slotStartTime, slotEndTime)\n : undefined,\n slot.label,\n slot.clickable ?? true ? \"Available\" : \"Unavailable\",\n ]);\n }\n\n function initializeAndFillSlots(slots: TimeSlot[]): TimeSlotCell[] {\n const cellsArray = Array(numberOfCells).fill({});\n\n slots.forEach((slot) => {\n const startIndex = Math.max(\n 0,\n DateHelper.getTimeDiffInMinutes(minStartTime, slot.startTime) /\n interval\n );\n const endIndex = Math.min(\n numberOfCells,\n DateHelper.getTimeDiffInMinutes(minStartTime, slot.endTime) /\n interval\n );\n const cellLength = Math.ceil(endIndex) - Math.floor(startIndex);\n\n switch (variant) {\n case \"fixed\":\n // Keep fixed slots as 1 long cell\n cellsArray[Math.floor(startIndex)] = {\n ...slot,\n isActualSlot: true,\n rowIndex: Math.floor(startIndex),\n cellLength: endIndex - startIndex,\n };\n break;\n case \"flexible\":\n // Split long slot into multiple cells of length 1\n for (let i = 0; i < cellLength; i++) {\n const startTime = DateHelper.addMinutesToTime(\n minStartTime,\n Math.floor(startIndex + i) * interval\n );\n const endTime = DateHelper.addMinutesToTime(\n startTime,\n interval\n );\n\n let halfFill: \"default\" | \"top\" | \"bottom\";\n\n if (!isEmpty(cellsArray[Math.floor(startIndex + i)])) {\n // Previous cell extends into current cell, fill entire cell\n halfFill = \"default\";\n } else if (i === 0 && startIndex % 1 !== 0) {\n halfFill = \"top\";\n } else if (i === cellLength - 1 && endIndex % 1 !== 0) {\n halfFill = \"bottom\";\n } else {\n halfFill = \"default\";\n }\n\n cellsArray[Math.floor(startIndex + i)] = {\n ...slot,\n id: `${slot.id}-${i}`,\n startTime,\n endTime,\n isActualSlot: true,\n rowIndex: Math.floor(startIndex + i),\n cellLength: 1,\n halfFill,\n };\n }\n break;\n }\n });\n return cellsArray;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n function populateEmptyCells(cellsArray: any[]): TimeSlotCell[] {\n let i = 0;\n switch (variant) {\n case \"fixed\":\n // Truncate consecutive empty cells into 1 [{},{},{...},{},{}] -> [{},{...},{}]\n cellsArray = cellsArray.reduce(\n (result, obj) => {\n const lastObj =\n result.length > 0\n ? result[result.length - 1]\n : result[0];\n if (isEmpty(obj) && isEmpty(lastObj)) {\n return result;\n }\n return [...result, obj];\n },\n [{}]\n );\n\n // Fill in empty cells with timings & corresponding cell lengths\n while (i < cellsArray.length) {\n if (isEmpty(cellsArray[i])) {\n const startTime =\n cellsArray[i - 1]?.endTime ?? minStartTime;\n const endTime =\n cellsArray[i + 1]?.startTime ?? maxEndTime;\n if (startTime !== endTime) {\n const cellLength =\n DateHelper.getTimeDiffInMinutes(\n startTime,\n endTime\n ) / interval;\n cellsArray[i] = {\n ...generateFallbackCell(i),\n startTime,\n endTime,\n cellLength,\n };\n }\n }\n i++;\n }\n break;\n case \"flexible\":\n // Fill in individual empty cell with interval timings\n while (i < cellsArray.length) {\n if (isEmpty(cellsArray[i])) {\n cellsArray[i] = generateFallbackCell(i);\n i++;\n } else {\n i += cellsArray[i].cellLength;\n }\n }\n break;\n }\n return cellsArray.filter(\n (slot) => !isEmpty(slot) && slot.cellLength > 0\n );\n }\n\n function getCellsForDate(formattedDate: string) {\n return (\n generatedDaySlots[formattedDate] ??\n Array(variant === \"flexible\" ? numberOfCells : 1)\n .fill(undefined)\n .map((_, index) =>\n generateFallbackCell(\n index,\n variant === \"fixed\" ? numberOfCells : undefined\n )\n )\n );\n }\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderWeek = () => {\n return (\n <div className={styles.headerCellWeekColumn} role=\"row\">\n {currentCalendarWeek.map((day, index) => (\n <div\n key={`week-day-${index}`}\n className={styles.headerCellWeek}\n role=\"gridcell\"\n >\n <Typography.BodyXS\n weight={\"semibold\"}\n className={clsx(\n isDisabled(day) && styles.cellWeekTextDisabled\n )}\n >\n {dayjs(day).format(\"ddd\")}\n </Typography.BodyXS>\n </div>\n ))}\n </div>\n );\n };\n\n const renderHeader = () => {\n return (\n <div\n className={styles.headerCellWeekColumn}\n role=\"row\"\n onBlur={handleDayHoverClear}\n >\n {currentCalendarWeek.map((day, dayIndex) => {\n const dayCellStyleProps = generateStyleProps(day);\n\n return (\n <DayCell\n key={`day-${dayIndex}`}\n date={day}\n calendarDate={dayjs(selectedDate)}\n role=\"columnheader\"\n tabIndex={dayCellStyleProps.interactive ? 0 : -1}\n onSelect={() => {\n handleDayClick(\n day,\n !dayCellStyleProps.interactive\n );\n }}\n onHover={handleDayHover}\n onHoverEnd={handleDayHoverClear}\n onFocus={handleDayHover}\n {...dayCellStyleProps}\n ></DayCell>\n );\n })}\n </div>\n );\n };\n\n const renderTimeColumn = () => {\n let hasSetFirstAfternoonHour = false;\n\n const formatTime = (index: number) => {\n const parsedTime = dayjs(minStartTime, \"HH:mm\").add(\n index * 4 * interval,\n \"minutes\"\n );\n const hour = parsedTime.format(\"h\");\n const minutes = parsedTime.format(\"mm\");\n const amPm = parsedTime.format(\"a\");\n\n let formattedTime = `${hour}${\n minutes !== \"00\" ? ` ${minutes}` : \"\"\n }`;\n\n if (\n !hasSetFirstAfternoonHour &&\n amPm === \"pm\" &&\n minutes === \"00\"\n ) {\n formattedTime += ` ${amPm}`;\n hasSetFirstAfternoonHour = true;\n }\n\n return formattedTime;\n };\n\n return (\n <div className={styles.timeColumn} ref={timeColumnRef} aria-hidden>\n {Array(Math.ceil(numberOfCells / 4))\n .fill(undefined)\n .map((_, index) => (\n <div\n key={`time-${index}`}\n className={styles.timeColumnWrapper}\n >\n <div className={styles.timeColumnText}>\n {formatTime(index)}\n </div>\n </div>\n ))}\n </div>\n );\n };\n\n const renderSlotCell = (formattedDate: string, slot: TimeSlotCell) => {\n return (\n <WeekTimeSlotCell\n key={slot.id}\n formattedDate={formattedDate}\n slot={slot}\n variant={variant}\n hasCollapsedContent={hasCollapsedContent}\n expandAll={expandAll}\n visibleRowCount={visibleRowCount}\n onSlotClick={handleSlotClick}\n getSlotAriaLabel={getSlotAriaLabel}\n onSlotKeyDown={handleSlotKeyDown}\n onSlotButtonClick={handleSlotButtonClick}\n slotButtonRefs={slotButtonRefs}\n />\n );\n };\n\n const renderTimeSlotBarCells = () => {\n return (\n <animated.div\n className={styles.expandable}\n style={isMounted ? expandableStyles : undefined}\n role=\"row\"\n >\n <div\n className={styles.columnWeekCell}\n ref={cellsRef}\n key={`week-cell-${calendarDate.format(dateFormat)}`}\n >\n {currentCalendarWeek.map((day, dayIndex) => {\n const formattedDate = day.format(dateFormat);\n const cellsArray = getCellsForDate(formattedDate);\n return (\n <div\n key={`wrapper-${dayIndex}`}\n className={styles.timeSlotWrapper}\n role=\"gridcell\"\n >\n {cellsArray.map((slot) =>\n renderSlotCell(formattedDate, slot)\n )}\n </div>\n );\n })}\n </div>\n </animated.div>\n );\n };\n\n const renderCollapseExpandAll = () => {\n if (!maxVisibleCellHeight || !cellsRef.current) return;\n return (\n <div className={styles.collapseExpandAllWrapper}>\n <Button\n data-testid=\"time-bar-expand-collapse-button\"\n styleType=\"light\"\n sizeType=\"small\"\n aria-expanded={expandAll}\n onClick={handleExpandCollapseClick}\n className={styles.collapseExpandAllButton}\n >\n <span className={styles.collapseExpandAllButtonContent}>\n <ChevronUpIcon\n className={clsx(\n styles.chevronIcon,\n expandAll && styles.chevronIconExpanded\n )}\n />\n {`${expandAll ? \"Hide\" : \"Show\"} later times`}\n </span>\n </Button>\n </div>\n );\n };\n\n return (\n <div className={styles.wrapper}>\n <div className={styles.gridWrapper} role=\"grid\">\n {renderHeader()}\n {renderWeek()}\n {renderTimeColumn()}\n {renderTimeSlotBarCells()}\n </div>\n {renderCollapseExpandAll()}\n </div>\n );\n};\n"],"names":["calendarDate","disabledDates","selectedDate","onSelect","minDate","maxDate","startTime","endTime","maxVisibleCellHeight","slots","daySlots","interval","variant","enableSelection","onSlotClick","dateFormat","expandAll","setExpandAll","useState","hoverDay","setHoverDay","isMounted","useIsMounted","slotButtonRefs","useRef","timeColumnRef","currentCalendarWeek","useMemo","CalendarHelper","generateDaysForCurrentWeek","flattenedSlots","Object","values","flat","minStartTime","_b","_a","minBy","maxEndTime","_d","_c","maxBy","numberOfCells","Math","ceil","DateHelper","getTimeDiffInMinutes","height","actualHeight","ref","cellsRef","useResizeDetector","hasCollapsedContent","visibleRowCount","undefined","max","floor","SLOT_GAP","ROW_HEIGHT","collapsedHeight","expandableStyles","useSpring","generatedDaySlots","transformedDaySlots","entries","forEach","key","cellsArray","Array","fill","slot","startIndex","endIndex","min","cellLength","assign","isActualSlot","rowIndex","i","addMinutesToTime","halfFill","isEmpty","id","initializeAndFillSlots","reduce","result","obj","lastObj","length","generateFallbackCell","filter","populateEmptyCells","focusableSlotsByDate","day","formattedDate","format","getCellsForDate","map","date","sort","a","b","useApplyStyle","styles.tokens","timeColumn","formatUnitValue","handleDayHover","value","handleDayHoverClear","handleSlotClick","handleSlotButtonClick","event","stopPropagation","handleExpandCollapseClick","preventDefault","prevExpandValue","handleSlotKeyDown","currentSlot","sameColumnSlots","focusSlot","current","focus","currentIndex","findIndex","lastVisibleSlot","reverse","find","isDisabled","isWithinRange","dayjs","isDisabledDate","includes","prefix","toString","Date","getTime","clickable","styleAttributes","backgroundColor","Colour","getSlotAriaLabel","slotStartTime","slotEndTime","StringHelper","joinNonEmptyStrings","TimeHelper","formatTimeRange","label","_","index","_jsxs","className","styles.wrapper","children","styles.gridWrapper","role","_jsx","styles.headerCellWeekColumn","onBlur","dayIndex","dayCellStyleProps","dateStartWithYear","disabled","isHoverEnabled","interactive","isHover","isSame","isSelected","labelType","circleLeft","circleRight","generateStyleProps","DayCell","tabIndex","handleDayClick","onHover","onHoverEnd","onFocus","styles.headerCellWeek","Typography","BodyXS","weight","clsx","styles.cellWeekTextDisabled","hasSetFirstAfternoonHour","formatTime","parsedTime","add","hour","minutes","amPm","formattedTime","styles.timeColumn","styles.timeColumnWrapper","styles.timeColumnText","renderTimeColumn","animated","div","styles.expandable","style","styles.columnWeekCell","styles.timeSlotWrapper","WeekTimeSlotCell","onSlotKeyDown","onSlotButtonClick","renderSlotCell","styles.collapseExpandAllWrapper","Button","styleType","sizeType","onClick","styles.collapseExpandAllButton","styles.collapseExpandAllButtonContent","ChevronUpIcon","styles.chevronIcon","styles.chevronIconExpanded","renderCollapseExpandAll"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"timetable.js","sources":["../../../src/timetable/timetable.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport dayjs from \"dayjs\";\nimport { isEmpty, throttle } from \"lodash\";\nimport {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\nimport { useResizeDetector } from \"react-resize-detector\";\n\nimport { LoadingDotsSpinner } from \"../animations\";\nimport { ErrorDisplay } from \"../error-display\";\nimport type { PopoverTriggerProps } from \"../popover\";\nimport { PopoverTrigger } from \"../popover\";\nimport { VisuallyHidden } from \"../shared/accessibility\";\nimport { useApplyStyle } from \"../theme\";\nimport { Typography } from \"../typography\";\nimport { TimeHelper } from \"../util/time-helper\";\nimport {\n MIN_INTERVAL_WIDTH,\n ROW_BAR_COLOR_ALTERNATE_COLOR,\n ROW_BAR_COLOR_SEQUENCE,\n ROW_HEADER_WIDTH,\n ROW_INTERVAL,\n} from \"./const\";\nimport * as styles from \"./timetable.styles\";\nimport { TimeTableHeader } from \"./timetable-header/timetable-header\";\nimport { RowBar } from \"./timetable-row/row-bar\";\nimport type { TimeTableProps, TimeTableRef, TimeTableRowData } from \"./types\";\n\nconst Component = (props: TimeTableProps, ref: React.Ref<TimeTableRef>) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const {\n date,\n emptyContentMessage,\n rowData,\n loading,\n minTime = \"00:00\",\n maxTime = \"23:00\",\n initialScrollTime,\n minDate,\n maxDate,\n totalRecords,\n showCurrentDateAsToday,\n showDateAsShortForm,\n onPage,\n onRefresh,\n onNextDayClick,\n onPreviousDayClick,\n onCalendarDateSelect,\n roundInitialScrollTime = true,\n ...otherProps\n } = props;\n const testId = otherProps[\"data-testid\"] || \"timetable\";\n const timetableMinTime = TimeHelper.roundToNearestInterval(minTime, 60);\n const timetableMaxTime = TimeHelper.roundToNearestInterval(\n maxTime,\n 60,\n true\n );\n const hourlyIntervals = TimeHelper.generateHourlyIntervals(\n timetableMinTime,\n timetableMaxTime\n );\n const numberOfIntervals = Math.ceil(\n (hourlyIntervals.length * 60) / ROW_INTERVAL\n );\n const formattedDate = dayjs(date).format(\"D MMMM YYYY\");\n const timetableAriaLabel = `Timetable of resource availability, for ${formattedDate}, from ${dayjs(\n timetableMinTime,\n \"HH:mm\"\n ).format(\"ha\")} to ${dayjs(timetableMaxTime, \"HH:mm\").format(\"ha\")}`;\n const ariaRowCount = (totalRecords || rowData.length) + 1;\n const ariaColCount = numberOfIntervals + 1;\n\n const isEmptyContent = totalRecords === 0 || isEmpty(rowData);\n const allRecordsLoaded = isEmptyContent || rowData.length === totalRecords;\n const hasLazyLoad = !allRecordsLoaded && !!onPage;\n const tableContainerRef = useRef<HTMLDivElement>(null);\n const contentContainerRef = useRef<HTMLDivElement>(null);\n const columnHeaderRowRef = useRef<HTMLDivElement>(null);\n const loadingWrapperRef = useRef<HTMLDivElement>(null);\n const [isScrolledX, setIsScrolledX] = useState<boolean>(false);\n const [isScrolledY, setIsScrolledY] = useState<boolean>(false);\n const [intervalWidth, setIntervalWidth] = useState<number>(0);\n const [loadMore, setLoadMore] = useState<boolean>(false);\n\n // Expose imperative handle\n useImperativeHandle(ref, () => ({\n resetScroll,\n }));\n\n useApplyStyle(columnHeaderRowRef, {\n [styles.tokens.columnHeaderRow.columnWidth]: `${intervalWidth * 4}px`,\n });\n\n useApplyStyle(loadingWrapperRef, {\n [styles.tokens.loadingWrapper.cellWidth]: `${intervalWidth * 4}px`,\n });\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n const handleScroll = throttle(() => {\n if (tableContainerRef.current) {\n setIsScrolledX(tableContainerRef.current.scrollLeft > 0);\n setIsScrolledY(tableContainerRef.current.scrollTop > 0);\n }\n\n if (loadMore || !tableContainerRef.current) return;\n\n const { scrollTop, clientHeight, scrollHeight } =\n tableContainerRef.current;\n const scrollBottomTolerance = 1;\n const isEndReached =\n Math.ceil(scrollTop + clientHeight) >=\n scrollHeight - scrollBottomTolerance;\n const shouldLoadMore =\n isEndReached && !allRecordsLoaded && onPage && !loading;\n\n if (shouldLoadMore) {\n setLoadMore(true);\n onPage();\n }\n }, 100);\n\n const tableContainer = tableContainerRef.current;\n\n if (tableContainer) {\n tableContainer.addEventListener(\"scroll\", handleScroll);\n }\n\n return () => {\n if (tableContainer) {\n tableContainer.removeEventListener(\"scroll\", handleScroll);\n }\n };\n }, [allRecordsLoaded, loadMore, loading, onPage]);\n\n useEffect(() => {\n setLoadMore(false);\n }, [rowData]);\n\n // Initial scroll on mount and when dependencies change\n useEffect(() => {\n resetScroll();\n }, [initialScrollTime, intervalWidth, timetableMinTime, timetableMaxTime]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n /**\n * Handles when the TimeTable component is resized.\n *\n * @remarks\n * When the component is resized, we recalculate the width of each interval\n * in the Timetable. We do this by dividing the width of the container by\n * the number of intervals per row bar. We also make sure that the width\n * of each interval is at least 21px, otherwise it becomes too small.\n */\n const handleResize = () => {\n if (tableContainerRef.current) {\n const numberOfIntervalsPerRowBar = Math.ceil(\n (hourlyIntervals.length * 60) / ROW_INTERVAL\n );\n const tableContainerWidth =\n tableContainerRef.current.clientWidth - ROW_HEADER_WIDTH;\n const calcWidth = tableContainerWidth / numberOfIntervalsPerRowBar;\n const width =\n calcWidth > MIN_INTERVAL_WIDTH ? calcWidth : MIN_INTERVAL_WIDTH;\n setIntervalWidth(width);\n }\n };\n\n useResizeDetector({\n onResize: handleResize,\n targetRef: tableContainerRef,\n refreshMode: \"debounce\",\n refreshRate: 50,\n });\n\n const handleRowNameClick = (\n data: TimeTableRowData,\n event: React.MouseEvent\n ) => {\n if (data.onRowNameClick) {\n data.onRowNameClick(data, event);\n }\n };\n\n // ===========================================================================\n // HELPER FUNCTIONS\n // ===========================================================================\n /**\n * Using closures to more efficiently loop through and wrap the color sequencing instead of modding large numbers repeatedly\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures#closure\n */\n const getColorFromSequence = (() => {\n let colorIndex = 0;\n const colorSequenceLength = ROW_BAR_COLOR_SEQUENCE.length;\n\n return () => {\n const mainColor = ROW_BAR_COLOR_SEQUENCE[colorIndex];\n const alternateColor = ROW_BAR_COLOR_ALTERNATE_COLOR[colorIndex];\n colorIndex = (colorIndex + 1) % colorSequenceLength;\n return { mainColor, alternateColor };\n };\n })();\n\n const buildPopoverTrigger = (\n data: TimeTableRowData,\n child: JSX.Element\n ) => {\n if (!data.rowHeaderPopover) {\n return child;\n }\n\n const popoverTriggerProps: PopoverTriggerProps = {\n position: \"bottom-start\",\n customOffset: data.rowHeaderPopover.offset,\n children: child,\n trigger: data.rowHeaderPopover.trigger,\n delay: data.rowHeaderPopover.delay,\n popoverContent: data.rowHeaderPopover.content,\n };\n\n return (\n <PopoverTrigger\n {...popoverTriggerProps}\n className={styles.popoverTrigger}\n key={`${data.id}-popover-trigger`}\n zIndex={2}\n >\n {child}\n </PopoverTrigger>\n );\n };\n\n // Function to reset scroll to initialScrollTime\n const resetScroll = () => {\n if (\n initialScrollTime &&\n tableContainerRef.current &&\n intervalWidth > 0\n ) {\n const scrollPosition = TimeHelper.calculateScrollPosition({\n scrollTime: initialScrollTime,\n minTime: timetableMinTime,\n maxTime: timetableMaxTime,\n interval: ROW_INTERVAL,\n intervalWidth,\n options: {\n roundToInterval: roundInitialScrollTime,\n },\n });\n\n if (scrollPosition !== null) {\n tableContainerRef.current.scrollLeft = scrollPosition;\n }\n }\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderRowHeader = (data: TimeTableRowData) => {\n const rowHeaderContent = (\n <>\n <Typography.BodyMD\n className={clsx(\n styles.clickableRowHeaderTitle,\n !!data.onRowNameClick &&\n styles.clickableRowHeaderTitleClickable\n )}\n onClick={(event: React.MouseEvent) =>\n handleRowNameClick(data, event)\n }\n weight=\"semibold\"\n data-testid={`${data.id}-row-header-title`}\n >\n {data.name}\n </Typography.BodyMD>\n\n <Typography.BodyXS\n weight=\"bold\"\n className={clsx(\n styles.rowHeaderSubtitle,\n !data.subtitle && styles.rowHeaderSubtitleHidden\n )}\n data-testid={`${data.id}-row-header-subtitle`}\n >\n {data.subtitle}\n </Typography.BodyXS>\n </>\n );\n\n return (\n <div\n className={clsx(\n styles.rowHeader,\n isScrolledX && styles.rowHeaderScrolled\n )}\n key={`${data.id}-row-header`}\n role=\"rowheader\"\n aria-colindex={1}\n >\n {buildPopoverTrigger(data, rowHeaderContent)}\n </div>\n );\n };\n\n const renderColumnHeaders = () => {\n // Don't render first column if there are no rows\n\n return hourlyIntervals.map((columnHeader: string) => (\n <div\n className={styles.columnHeader}\n key={`${columnHeader}-column-key`}\n data-testid={`${columnHeader}-column`}\n >\n <Typography.BodySM\n className={styles.columnHeaderTitle}\n weight={\"semibold\"}\n >\n {columnHeader}\n </Typography.BodySM>\n </div>\n ));\n };\n\n const renderRows = () => {\n if (loading) {\n return (\n <LoadingDotsSpinner\n data-testid=\"timetable-loading-spinner\"\n className={clsx(\n styles.loadingSpinner,\n isEmptyContent\n ? styles.loadingSpinnerEmptyContent\n : styles.loadingSpinnerHasContent\n )}\n />\n );\n }\n\n return (\n <div\n className={styles.timeTableBody}\n data-testid=\"content-container-id\"\n ref={contentContainerRef}\n role=\"rowgroup\"\n >\n {rowData.map((data, index) => {\n return (\n <div\n className={styles.timeTableRow}\n key={`${index}-timetable-row`}\n role=\"row\"\n aria-rowindex={index + 2}\n aria-label={data.name}\n >\n {renderRowHeader(data)}\n <RowBar\n key={`${index}-row-bar`}\n timetableMinTime={timetableMinTime}\n timetableMaxTime={timetableMaxTime}\n rowBarColor={getColorFromSequence()}\n intervalWidth={intervalWidth}\n containerRef={contentContainerRef}\n {...data}\n />\n </div>\n );\n })}\n {renderLazyLoadRow()}\n </div>\n );\n };\n\n const renderLazyLoadRow = () => {\n if (loading || !loadMore) return;\n return (\n <div className={styles.timeTableRow}>\n <div\n className={clsx(\n styles.rowHeader,\n isScrolledX && styles.rowHeaderScrolled\n )}\n >\n <div className={styles.loadingBar} />\n </div>\n <div\n ref={loadingWrapperRef}\n className={styles.loadingWrapper}\n data-testid=\"lazy-loader\"\n role=\"presentation\"\n >\n {hourlyIntervals.map((_, index) => (\n <div\n className={styles.loadingCell}\n key={`lazy-load-cell-${index}`}\n >\n <div className={styles.loadingBar} />\n </div>\n ))}\n </div>\n </div>\n );\n };\n\n if (isEmptyContent) {\n return (\n <div {...otherProps} data-testid={testId}>\n <TimeTableHeader\n selectedDate={date}\n loading={loading || loadMore}\n tableContainerRef={tableContainerRef}\n minDate={minDate}\n maxDate={maxDate}\n totalRecords={totalRecords}\n showCurrentDateAsToday={showCurrentDateAsToday}\n showDateAsShortForm={showDateAsShortForm}\n onPreviousDayClick={onPreviousDayClick}\n onNextDayClick={onNextDayClick}\n onRefresh={onRefresh}\n onCalendarDateSelect={onCalendarDateSelect}\n />\n <div\n className={clsx(\n styles.emptyTableContainer,\n \"empty-container\"\n )}\n tabIndex={0}\n aria-live=\"polite\"\n aria-atomic\n aria-busy={loading}\n >\n {!loading ? (\n <ErrorDisplay\n className={styles.noResultsFound}\n type=\"no-item-found\"\n description={emptyContentMessage}\n />\n ) : (\n <>\n <VisuallyHidden>{`Loading ${timetableAriaLabel}`}</VisuallyHidden>\n <LoadingDotsSpinner\n data-testid=\"timetable-loading-spinner\"\n className={clsx(\n styles.loadingSpinner,\n isEmptyContent\n ? styles.loadingSpinnerEmptyContent\n : styles.loadingSpinnerHasContent\n )}\n />\n </>\n )}\n </div>\n </div>\n );\n }\n\n return (\n <div {...otherProps} data-testid={testId}>\n <TimeTableHeader\n data-id=\"timetable-date-navigator\"\n selectedDate={date}\n loading={loading || loadMore}\n tableContainerRef={tableContainerRef}\n minDate={minDate}\n maxDate={maxDate}\n totalRecords={totalRecords}\n showCurrentDateAsToday={showCurrentDateAsToday}\n showDateAsShortForm={showDateAsShortForm}\n onPreviousDayClick={onPreviousDayClick}\n onNextDayClick={onNextDayClick}\n onRefresh={onRefresh}\n onCalendarDateSelect={onCalendarDateSelect}\n />\n <div\n data-id=\"timetable-container\"\n data-testid=\"timetable-container\"\n ref={tableContainerRef}\n className={clsx(\n styles.timeTableContainer,\n hasLazyLoad && styles.timeTableContainerNotAllLoaded,\n loading && styles.timeTableContainerLoading\n )}\n role=\"grid\"\n aria-label={timetableAriaLabel}\n aria-rowcount={ariaRowCount}\n aria-colcount={ariaColCount}\n aria-busy={loadMore}\n tabIndex={0}\n >\n <div\n className={styles.timeTableHeaderRow}\n role=\"row\"\n aria-rowindex={1}\n data-testid={\"row-header-column-id\"}\n >\n <div\n className={clsx(\n styles.rowColumnHeader,\n (isScrolledX || isScrolledY) &&\n styles.rowColumnHeaderScrolled,\n isScrolledX && styles.rowColumnHeaderScrolledX,\n isScrolledY && styles.rowColumnHeaderScrolledY\n )}\n role=\"columnheader\"\n aria-colindex={1}\n >\n <VisuallyHidden>Resource</VisuallyHidden>\n </div>\n <div\n ref={columnHeaderRowRef}\n className={clsx(\n styles.columnHeaderRow,\n isScrolledY && styles.columnHeaderRowScrolled\n )}\n role=\"presentation\"\n >\n {renderColumnHeaders()}\n </div>\n </div>\n {renderRows()}\n </div>\n </div>\n );\n};\n\n// @catalog\n/**\n * A scrollable grid that visualises time slot availability across a day.\n *\n * Use `TimeTable` to display one day's schedule for multiple resources side by\n * side.\n */\nexport const TimeTable = forwardRef<TimeTableRef, TimeTableProps>(Component);\n"],"names":["TimeTable","forwardRef","props","ref","date","emptyContentMessage","rowData","loading","minTime","maxTime","initialScrollTime","minDate","maxDate","totalRecords","showCurrentDateAsToday","showDateAsShortForm","onPage","onRefresh","onNextDayClick","onPreviousDayClick","onCalendarDateSelect","roundInitialScrollTime","otherProps","testId","timetableMinTime","TimeHelper","roundToNearestInterval","timetableMaxTime","hourlyIntervals","generateHourlyIntervals","numberOfIntervals","Math","ceil","length","ROW_INTERVAL","timetableAriaLabel","dayjs","format","ariaRowCount","ariaColCount","isEmptyContent","isEmpty","allRecordsLoaded","hasLazyLoad","tableContainerRef","useRef","contentContainerRef","columnHeaderRowRef","loadingWrapperRef","isScrolledX","setIsScrolledX","useState","isScrolledY","setIsScrolledY","intervalWidth","setIntervalWidth","loadMore","setLoadMore","useImperativeHandle","resetScroll","useApplyStyle","styles.tokens","columnHeaderRow","columnWidth","loadingWrapper","cellWidth","useEffect","handleScroll","throttle","current","scrollLeft","scrollTop","clientHeight","scrollHeight","tableContainer","addEventListener","removeEventListener","useResizeDetector","onResize","numberOfIntervalsPerRowBar","calcWidth","clientWidth","ROW_HEADER_WIDTH","width","MIN_INTERVAL_WIDTH","targetRef","refreshMode","refreshRate","getColorFromSequence","colorIndex","colorSequenceLength","ROW_BAR_COLOR_SEQUENCE","mainColor","alternateColor","ROW_BAR_COLOR_ALTERNATE_COLOR","buildPopoverTrigger","data","child","rowHeaderPopover","popoverTriggerProps","position","customOffset","offset","children","trigger","delay","popoverContent","content","_createElement","PopoverTrigger","Object","assign","className","styles.popoverTrigger","key","id","zIndex","scrollPosition","calculateScrollPosition","scrollTime","interval","options","roundToInterval","renderRowHeader","rowHeaderContent","_jsxs","_Fragment","_jsx","Typography","BodyMD","clsx","styles.clickableRowHeaderTitle","onRowNameClick","styles.clickableRowHeaderTitleClickable","onClick","event","handleRowNameClick","weight","name","BodyXS","styles.rowHeaderSubtitle","subtitle","styles.rowHeaderSubtitleHidden","styles.rowHeader","styles.rowHeaderScrolled","role","renderLazyLoadRow","styles.timeTableRow","styles.loadingBar","styles.loadingWrapper","map","_","index","styles.loadingCell","TimeTableHeader","selectedDate","styles.emptyTableContainer","tabIndex","VisuallyHidden","LoadingDotsSpinner","styles.loadingSpinner","styles.loadingSpinnerEmptyContent","styles.loadingSpinnerHasContent","ErrorDisplay","styles.noResultsFound","type","description","styles.timeTableContainer","styles.timeTableContainerNotAllLoaded","styles.timeTableContainerLoading","styles.timeTableHeaderRow","styles.rowColumnHeader","styles.rowColumnHeaderScrolled","styles.rowColumnHeaderScrolledX","styles.rowColumnHeaderScrolledY","styles.columnHeaderRow","styles.columnHeaderRowScrolled","columnHeader","styles.columnHeader","BodySM","styles.columnHeaderTitle","styles.timeTableBody","RowBar","rowBarColor","containerRef"],"mappings":"m/CAgCA,MA+faA,EAAYC,EAAAA,YA/fP,CAACC,EAAuBC,KAItC,MAAMC,KACFA,EAAIC,oBACJA,EAAmBC,QACnBA,EAAOC,QACPA,EAAOC,QACPA,EAAU,QAAOC,QACjBA,EAAU,QAAOC,kBACjBA,EAAiBC,QACjBA,EAAOC,QACPA,EAAOC,aACPA,EAAYC,uBACZA,EAAsBC,oBACtBA,EAAmBC,OACnBA,EAAMC,UACNA,EAASC,eACTA,EAAcC,mBACdA,EAAkBC,qBAClBA,EAAoBC,uBACpBA,GAAyB,GAEzBnB,EADGoB,WACHpB,EApBE,CAAA,OAAA,sBAAA,UAAA,UAAA,UAAA,UAAA,oBAAA,UAAA,UAAA,eAAA,yBAAA,sBAAA,SAAA,YAAA,iBAAA,qBAAA,uBAAA,2BAqBAqB,EAASD,EAAW,gBAAkB,YACtCE,EAAmBC,EAAAA,WAAWC,uBAAuBlB,EAAS,IAC9DmB,EAAmBF,EAAAA,WAAWC,uBAChCjB,EACA,IACA,GAEEmB,EAAkBH,EAAAA,WAAWI,wBAC/BL,EACAG,GAEEG,EAAoBC,KAAKC,KACD,GAAzBJ,EAAgBK,OAAeC,gBAG9BC,EAAqB,2CADLC,EAAAA,QAAMhC,GAAMiC,OAAO,wBACoDD,UACzFZ,EACA,SACFa,OAAO,YAAYD,EAAAA,QAAMT,EAAkB,SAASU,OAAO,QACvDC,GAAgBzB,GAAgBP,EAAQ2B,QAAU,EAClDM,EAAeT,EAAoB,EAEnCU,EAAkC,IAAjB3B,GAAsB4B,EAAAA,cAAAA,QAAQnC,GAC/CoC,EAAmBF,GAAkBlC,EAAQ2B,SAAWpB,EACxD8B,GAAeD,KAAsB1B,EACrC4B,EAAoBC,EAAAA,OAAuB,MAC3CC,EAAsBD,EAAAA,OAAuB,MAC7CE,EAAqBF,EAAAA,OAAuB,MAC5CG,EAAoBH,EAAAA,OAAuB,OAC1CI,GAAaC,IAAkBC,EAAAA,UAAkB,IACjDC,GAAaC,IAAkBF,EAAAA,UAAkB,IACjDG,GAAeC,IAAoBJ,EAAAA,SAAiB,IACpDK,GAAUC,IAAeN,EAAAA,UAAkB,GAGlDO,EAAAA,oBAAoBvD,GAAK,KAAA,CACrBwD,mBAGJC,EAAAA,cAAcb,EAAoB,CAC9B,CAACc,EAAAA,OAAcC,gBAAgBC,aAAiC,EAAhBT,GAAH,OAGjDM,EAAAA,cAAcZ,EAAmB,CAC7B,CAACa,EAAAA,OAAcG,eAAeC,WAA+B,EAAhBX,GAAH,OAM9CY,EAAAA,WAAU,KACN,MAAMC,EAAeC,EAAAA,cAAAA,UAAS,KAM1B,GALIxB,EAAkByB,UAClBnB,GAAeN,EAAkByB,QAAQC,WAAa,GACtDjB,GAAeT,EAAkByB,QAAQE,UAAY,IAGrDf,KAAaZ,EAAkByB,QAAS,OAE5C,MAAME,UAAEA,EAASC,aAAEA,EAAYC,aAAEA,GAC7B7B,EAAkByB,QAGlBtC,KAAKC,KAAKuC,EAAYC,IACtBC,EAH0B,IAKT/B,GAAoB1B,IAAWT,IAGhDkD,IAAY,GACZzC,IACJ,GACD,KAEG0D,EAAiB9B,EAAkByB,QAMzC,OAJIK,GACAA,EAAeC,iBAAiB,SAAUR,GAGvC,KACCO,GACAA,EAAeE,oBAAoB,SAAUT,EACjD,CACH,GACF,CAACzB,EAAkBc,GAAUjD,EAASS,IAEzCkD,EAAAA,WAAU,KACNT,IAAY,EAAM,GACnB,CAACnD,IAGJ4D,EAAAA,WAAU,KACNP,IAAa,GACd,CAACjD,EAAmB4C,GAAe9B,EAAkBG,IA4BxDkD,oBAAkB,CACdC,SAfiB,KACjB,GAAIlC,EAAkByB,QAAS,CAC3B,MAAMU,EAA6BhD,KAAKC,KACV,GAAzBJ,EAAgBK,OAAeC,gBAI9B8C,GADFpC,EAAkByB,QAAQY,YAAcC,EAAAA,kBACJH,EAClCI,EACFH,EAAYI,EAAAA,mBAAqBJ,EAAYI,EAAAA,mBACjD7B,GAAiB4B,EACrB,GAKAE,UAAWzC,EACX0C,YAAa,WACbC,YAAa,KAGjB,MAgBMC,GAAuB,MACzB,IAAIC,EAAa,EACjB,MAAMC,EAAsBC,EAAAA,uBAAuB1D,OAEnD,MAAO,KACH,MAAM2D,EAAYD,EAAAA,uBAAuBF,GACnCI,EAAiBC,EAAAA,8BAA8BL,GAErD,OADAA,GAAcA,EAAa,GAAKC,EACzB,CAAEE,YAAWC,iBAAgB,CAE3C,EAV4B,GAYvBE,GAAsB,CACxBC,EACAC,KAEA,IAAKD,EAAKE,iBACN,OAAOD,EAGX,MAAME,EAA2C,CAC7CC,SAAU,eACVC,aAAcL,EAAKE,iBAAiBI,OACpCC,SAAUN,EACVO,QAASR,EAAKE,iBAAiBM,QAC/BC,MAAOT,EAAKE,iBAAiBO,MAC7BC,eAAgBV,EAAKE,iBAAiBS,SAG1C,OACIC,EAAAA,cAACC,EAAAA,eAAcC,OAAAC,OAAA,CAAA,EACPZ,EAAmB,CACvBa,UAAWC,EAAAA,eACXC,IAAK,GAAGlB,EAAKmB,qBACbC,OAAQ,IAEPnB,EACY,EAKnBtC,GAAc,KAChB,GACIjD,GACAkC,EAAkByB,SAClBf,GAAgB,EAClB,CACE,MAAM+D,EAAiB5F,EAAAA,WAAW6F,wBAAwB,CACtDC,WAAY7G,EACZF,QAASgB,EACTf,QAASkB,EACT6F,SAAUtF,EAAAA,aACVoB,iBACAmE,QAAS,CACLC,gBAAiBrG,KAIF,OAAnBgG,IACAzE,EAAkByB,QAAQC,WAAa+C,EAE/C,GAMEM,GAAmB3B,IACrB,MAAM4B,EACFC,EAAAA,KAAAC,EAAAA,SAAA,CAAAvB,SAAA,CACIwB,EAAAA,IAACC,EAAAA,WAAWC,OAAM,CACdjB,UAAWkB,EAAAA,QACPC,EAAAA,0BACEnC,EAAKoC,gBACHC,oCAERC,QAAUC,GA7FC,EACvBvC,EACAuC,KAEIvC,EAAKoC,gBACLpC,EAAKoC,eAAepC,EAAMuC,EAC9B,EAwFgBC,CAAmBxC,EAAMuC,GAE7BE,OAAO,WAAU,cACJ,GAAGzC,EAAKmB,sBAAqBZ,SAEzCP,EAAK0C,OAGVX,EAAAA,IAACC,EAAAA,WAAWW,OAAM,CACdF,OAAO,OACPzB,UAAWkB,EAAAA,QACPU,EAAAA,mBACC5C,EAAK6C,UAAYC,EAAAA,yBACrB,cACY,GAAG9C,EAAKmB,yBAAwBZ,SAE5CP,EAAK6C,cAKlB,OACId,EAAAA,IAAA,MAAA,CACIf,UAAWkB,EAAAA,QACPa,EAAAA,UACA9F,IAAe+F,EAAAA,mBAGnBC,KAAK,4BACU,EAAC1C,SAEfR,GAAoBC,EAAM4B,IAJtB,GAAG5B,EAAKmB,gBAKX,EAwER+B,GAAoB,KACtB,IAAI3I,GAAYiD,GAChB,OACIqE,EAAAA,KAAA,MAAA,CAAKb,UAAWmC,EAAAA,aAAmB5C,SAAA,CAC/BwB,EAAAA,IAAA,MAAA,CACIf,UAAWkB,EAAAA,QACPa,EAAAA,UACA9F,IAAe+F,EAAAA,mBAClBzC,SAEDwB,EAAAA,IAAA,MAAA,CAAKf,UAAWoC,EAAAA,eAEpBrB,EAAAA,IAAA,MAAA,CACI5H,IAAK6C,EACLgE,UAAWqC,EAAAA,eAAqB,cACpB,cACZJ,KAAK,eAAc1C,SAElB3E,EAAgB0H,KAAI,CAACC,EAAGC,IACrBzB,EAAAA,WACIf,UAAWyC,EAAAA,YAAkBlD,SAG7BwB,EAAAA,IAAA,MAAA,CAAKf,UAAWoC,EAAAA,cAFX,kBAAkBI,WAMjC,EAId,OAAIhH,EAEIqF,EAAAA,KAAA,MAAAf,OAAAC,OAAA,CAAA,EAASzF,EAAU,CAAA,cAAeC,EAAMgF,SAAA,CACpCwB,MAAC2B,EAAAA,gBAAe,CACZC,aAAcvJ,EACdG,QAASA,GAAWiD,GACpBZ,kBAAmBA,EACnBjC,QAASA,EACTC,QAASA,EACTC,aAAcA,EACdC,uBAAwBA,EACxBC,oBAAqBA,EACrBI,mBAAoBA,EACpBD,eAAgBA,EAChBD,UAAWA,EACXG,qBAAsBA,IAE1B2G,EAAAA,IAAA,MAAA,CACIf,UAAWkB,EAAAA,QACP0B,sBACA,mBAEJC,SAAU,EAAC,YACD,SAAQ,eAAA,EAAA,YAEPtJ,EAAOgG,SAEhBhG,EAOEsH,EAAAA,KAAAC,EAAAA,SAAA,CAAAvB,SAAA,CACIwB,EAAAA,IAAC+B,EAAAA,eAAc,CAAAvD,SAAE,WAAWpE,MAC5B4F,EAAAA,IAACgC,qBAAkB,CAAA,cACH,4BACZ/C,UAAWkB,EAAAA,QACP8B,iBACAxH,EACMyH,EAAAA,2BACAC,EAAAA,+BAdlBnC,EAAAA,IAACoC,EAAAA,aAAY,CACTnD,UAAWoD,EAAAA,eACXC,KAAK,gBACLC,YAAajK,UAsBjCwH,EAAAA,KAAA,MAAAf,OAAAC,OAAA,CAAA,EAASzF,EAAU,CAAA,cAAeC,EAAMgF,SAAA,CACpCwB,EAAAA,IAAC2B,EAAAA,gBAAe,CAAA,UACJ,2BACRC,aAAcvJ,EACdG,QAASA,GAAWiD,GACpBZ,kBAAmBA,EACnBjC,QAASA,EACTC,QAASA,EACTC,aAAcA,EACdC,uBAAwBA,EACxBC,oBAAqBA,EACrBI,mBAAoBA,EACpBD,eAAgBA,EAChBD,UAAWA,EACXG,qBAAsBA,IAE1ByG,EAAAA,KAAA,MAAA,CAAA,UACY,sBAAqB,cACjB,sBACZ1H,IAAKyC,EACLoE,UAAWkB,EAAAA,QACPqC,qBACA5H,GAAe6H,EAAAA,+BACfjK,GAAWkK,EAAAA,2BAEfxB,KAAK,OAAM,aACC9G,EAAkB,gBACfG,EAAY,gBACZC,EAAY,YAChBiB,GACXqG,SAAU,EAACtD,SAAA,CAEXsB,EAAAA,KAAA,MAAA,CACIb,UAAW0D,EAAAA,mBACXzB,KAAK,MAAK,gBACK,EAAC,cACH,uBAAsB1C,SAAA,CAEnCwB,EAAAA,IAAA,MAAA,CACIf,UAAWkB,UACPyC,EAAAA,iBACC1H,IAAeG,KACZwH,0BACJ3H,IAAe4H,EAAAA,yBACfzH,IAAe0H,EAAAA,0BAEnB7B,KAAK,eAAc,gBACJ,EAAC1C,SAEhBwB,EAAAA,IAAC+B,EAAAA,eAAc,CAAAvD,SAAA,eAEnBwB,EAAAA,IAAA,MAAA,CACI5H,IAAK4C,EACLiE,UAAWkB,UACP6C,EAAAA,gBACA3H,IAAe4H,EAAAA,yBAEnB/B,KAAK,eAAc1C,SA9M5B3E,EAAgB0H,KAAK2B,GACxBlD,EAAAA,WACIf,UAAWkE,EAAAA,2BAEE,GAAGD,WAAqB1E,SAErCwB,EAAAA,IAACC,EAAAA,WAAWmD,QACRnE,UAAWoE,EAAAA,kBACX3C,OAAQ,WAAUlC,SAEjB0E,KAPA,GAAGA,uBAcZ1K,EAEIwH,EAAAA,IAACgC,EAAAA,mBAAkB,CAAA,cACH,4BACZ/C,UAAWkB,EAAAA,QACP8B,iBACAxH,EACMyH,EAAAA,2BACAC,EAAAA,4BAOlBrC,EAAAA,KAAA,MAAA,CACIb,UAAWqE,EAAAA,cAAoB,cACnB,uBACZlL,IAAK2C,EACLmG,KAAK,WAAU1C,SAAA,CAEdjG,EAAQgJ,KAAI,CAACtD,EAAMwD,IAEZ3B,EAAAA,KAAA,MAAA,CACIb,UAAWmC,EAAAA,aAEXF,KAAK,MAAK,gBACKO,EAAQ,EAAC,aACZxD,EAAK0C,KAAInC,SAAA,CAEpBoB,GAAgB3B,GACjB+B,EAAAA,IAACuD,SAAMxE,OAAAC,OAAA,CAEHvF,iBAAkBA,EAClBG,iBAAkBA,EAClB4J,YAAa/F,KACblC,cAAeA,GACfkI,aAAc1I,GACVkD,GANC,GAAGwD,eAPP,GAAGA,qBAkBnBN,cAyJH"}
1
+ {"version":3,"file":"timetable.js","sources":["../../../src/timetable/timetable.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport dayjs from \"dayjs\";\nimport { isEmpty, throttle } from \"lodash\";\nimport {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\nimport { useResizeDetector } from \"react-resize-detector\";\n\nimport { LoadingDotsSpinner } from \"../animations\";\nimport { ErrorDisplay } from \"../error-display\";\nimport type { PopoverTriggerProps } from \"../popover\";\nimport { PopoverTrigger } from \"../popover\";\nimport { VisuallyHidden } from \"../shared/accessibility\";\nimport { useApplyStyle } from \"../theme\";\nimport { Typography } from \"../typography\";\nimport { TimeHelper } from \"../util/time-helper\";\nimport {\n MIN_INTERVAL_WIDTH,\n ROW_BAR_COLOR_ALTERNATE_COLOR,\n ROW_BAR_COLOR_SEQUENCE,\n ROW_HEADER_WIDTH,\n ROW_INTERVAL,\n} from \"./const\";\nimport * as styles from \"./timetable.styles\";\nimport { TimeTableHeader } from \"./timetable-header/timetable-header\";\nimport { RowBar } from \"./timetable-row/row-bar\";\nimport type { TimeTableProps, TimeTableRef, TimeTableRowData } from \"./types\";\n\nconst Component = (props: TimeTableProps, ref: React.Ref<TimeTableRef>) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const {\n date,\n emptyContentMessage,\n rowData,\n loading,\n minTime = \"00:00\",\n maxTime = \"23:00\",\n initialScrollTime,\n minDate,\n maxDate,\n totalRecords,\n showCurrentDateAsToday,\n showDateAsShortForm,\n onPage,\n onRefresh,\n onNextDayClick,\n onPreviousDayClick,\n onCalendarDateSelect,\n roundInitialScrollTime = true,\n ...otherProps\n } = props;\n const testId = otherProps[\"data-testid\"] || \"timetable\";\n const timetableMinTime = TimeHelper.roundToNearestInterval(minTime, 60);\n const timetableMaxTime = TimeHelper.roundToNearestInterval(\n maxTime,\n 60,\n true\n );\n const hourlyIntervals = TimeHelper.generateHourlyIntervals(\n timetableMinTime,\n timetableMaxTime\n );\n const numberOfIntervals = Math.ceil(\n (hourlyIntervals.length * 60) / ROW_INTERVAL\n );\n const formattedDate = dayjs(date).format(\"D MMMM YYYY\");\n const timetableAriaLabel = `Timetable of resource availability, for ${formattedDate}, from ${dayjs(\n timetableMinTime,\n \"HH:mm\"\n ).format(\"ha\")} to ${dayjs(timetableMaxTime, \"HH:mm\").format(\"ha\")}`;\n const ariaRowCount = (totalRecords || rowData.length) + 1;\n const ariaColCount = numberOfIntervals + 1;\n\n const isEmptyContent = totalRecords === 0 || isEmpty(rowData);\n const allRecordsLoaded = isEmptyContent || rowData.length === totalRecords;\n const hasLazyLoad = !allRecordsLoaded && !!onPage;\n const tableContainerRef = useRef<HTMLDivElement>(null);\n const contentContainerRef = useRef<HTMLDivElement>(null);\n const columnHeaderRowRef = useRef<HTMLDivElement>(null);\n const loadingWrapperRef = useRef<HTMLDivElement>(null);\n const [isScrolledX, setIsScrolledX] = useState<boolean>(false);\n const [isScrolledY, setIsScrolledY] = useState<boolean>(false);\n const [intervalWidth, setIntervalWidth] = useState<number>(0);\n const [loadMore, setLoadMore] = useState<boolean>(false);\n\n // Expose imperative handle\n useImperativeHandle(ref, () => ({\n resetScroll,\n }));\n\n useApplyStyle(columnHeaderRowRef, {\n [styles.tokens.columnHeaderRow.columnWidth]: `${intervalWidth * 4}px`,\n });\n\n useApplyStyle(loadingWrapperRef, {\n [styles.tokens.loadingWrapper.cellWidth]: `${intervalWidth * 4}px`,\n });\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n const handleScroll = throttle(() => {\n if (tableContainerRef.current) {\n setIsScrolledX(tableContainerRef.current.scrollLeft > 0);\n setIsScrolledY(tableContainerRef.current.scrollTop > 0);\n }\n\n if (loadMore || !tableContainerRef.current) return;\n\n const { scrollTop, clientHeight, scrollHeight } =\n tableContainerRef.current;\n const scrollBottomTolerance = 1;\n const isEndReached =\n Math.ceil(scrollTop + clientHeight) >=\n scrollHeight - scrollBottomTolerance;\n const shouldLoadMore =\n isEndReached && !allRecordsLoaded && onPage && !loading;\n\n if (shouldLoadMore) {\n setLoadMore(true);\n onPage();\n }\n }, 100);\n\n const tableContainer = tableContainerRef.current;\n\n if (tableContainer) {\n tableContainer.addEventListener(\"scroll\", handleScroll);\n }\n\n return () => {\n if (tableContainer) {\n tableContainer.removeEventListener(\"scroll\", handleScroll);\n }\n };\n }, [allRecordsLoaded, loadMore, loading, onPage]);\n\n useEffect(() => {\n setLoadMore(false);\n }, [rowData]);\n\n // Initial scroll on mount and when dependencies change\n useEffect(() => {\n resetScroll();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [initialScrollTime, intervalWidth, timetableMinTime, timetableMaxTime]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n /**\n * Handles when the TimeTable component is resized.\n *\n * @remarks\n * When the component is resized, we recalculate the width of each interval\n * in the Timetable. We do this by dividing the width of the container by\n * the number of intervals per row bar. We also make sure that the width\n * of each interval is at least 21px, otherwise it becomes too small.\n */\n const handleResize = () => {\n if (tableContainerRef.current) {\n const numberOfIntervalsPerRowBar = Math.ceil(\n (hourlyIntervals.length * 60) / ROW_INTERVAL\n );\n const tableContainerWidth =\n tableContainerRef.current.clientWidth - ROW_HEADER_WIDTH;\n const calcWidth = tableContainerWidth / numberOfIntervalsPerRowBar;\n const width =\n calcWidth > MIN_INTERVAL_WIDTH ? calcWidth : MIN_INTERVAL_WIDTH;\n setIntervalWidth(width);\n }\n };\n\n useResizeDetector({\n onResize: handleResize,\n targetRef: tableContainerRef,\n refreshMode: \"debounce\",\n refreshRate: 50,\n });\n\n const handleRowNameClick = (\n data: TimeTableRowData,\n event: React.MouseEvent\n ) => {\n if (data.onRowNameClick) {\n data.onRowNameClick(data, event);\n }\n };\n\n // ===========================================================================\n // HELPER FUNCTIONS\n // ===========================================================================\n /**\n * Using closures to more efficiently loop through and wrap the color sequencing instead of modding large numbers repeatedly\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures#closure\n */\n const getColorFromSequence = (() => {\n let colorIndex = 0;\n const colorSequenceLength = ROW_BAR_COLOR_SEQUENCE.length;\n\n return () => {\n const mainColor = ROW_BAR_COLOR_SEQUENCE[colorIndex];\n const alternateColor = ROW_BAR_COLOR_ALTERNATE_COLOR[colorIndex];\n colorIndex = (colorIndex + 1) % colorSequenceLength;\n return { mainColor, alternateColor };\n };\n })();\n\n const buildPopoverTrigger = (\n data: TimeTableRowData,\n child: JSX.Element\n ) => {\n if (!data.rowHeaderPopover) {\n return child;\n }\n\n const popoverTriggerProps: PopoverTriggerProps = {\n position: \"bottom-start\",\n customOffset: data.rowHeaderPopover.offset,\n children: child,\n trigger: data.rowHeaderPopover.trigger,\n delay: data.rowHeaderPopover.delay,\n popoverContent: data.rowHeaderPopover.content,\n };\n\n return (\n <PopoverTrigger\n {...popoverTriggerProps}\n className={styles.popoverTrigger}\n key={`${data.id}-popover-trigger`}\n zIndex={2}\n >\n {child}\n </PopoverTrigger>\n );\n };\n\n // Function to reset scroll to initialScrollTime\n const resetScroll = () => {\n if (\n initialScrollTime &&\n tableContainerRef.current &&\n intervalWidth > 0\n ) {\n const scrollPosition = TimeHelper.calculateScrollPosition({\n scrollTime: initialScrollTime,\n minTime: timetableMinTime,\n maxTime: timetableMaxTime,\n interval: ROW_INTERVAL,\n intervalWidth,\n options: {\n roundToInterval: roundInitialScrollTime,\n },\n });\n\n if (scrollPosition !== null) {\n tableContainerRef.current.scrollLeft = scrollPosition;\n }\n }\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderRowHeader = (data: TimeTableRowData) => {\n const rowHeaderContent = (\n <>\n <Typography.BodyMD\n className={clsx(\n styles.clickableRowHeaderTitle,\n !!data.onRowNameClick &&\n styles.clickableRowHeaderTitleClickable\n )}\n onClick={(event: React.MouseEvent) =>\n handleRowNameClick(data, event)\n }\n weight=\"semibold\"\n data-testid={`${data.id}-row-header-title`}\n >\n {data.name}\n </Typography.BodyMD>\n\n <Typography.BodyXS\n weight=\"bold\"\n className={clsx(\n styles.rowHeaderSubtitle,\n !data.subtitle && styles.rowHeaderSubtitleHidden\n )}\n data-testid={`${data.id}-row-header-subtitle`}\n >\n {data.subtitle}\n </Typography.BodyXS>\n </>\n );\n\n return (\n <div\n className={clsx(\n styles.rowHeader,\n isScrolledX && styles.rowHeaderScrolled\n )}\n key={`${data.id}-row-header`}\n role=\"rowheader\"\n aria-colindex={1}\n >\n {buildPopoverTrigger(data, rowHeaderContent)}\n </div>\n );\n };\n\n const renderColumnHeaders = () => {\n // Don't render first column if there are no rows\n\n return hourlyIntervals.map((columnHeader: string) => (\n <div\n className={styles.columnHeader}\n key={`${columnHeader}-column-key`}\n data-testid={`${columnHeader}-column`}\n >\n <Typography.BodySM\n className={styles.columnHeaderTitle}\n weight={\"semibold\"}\n >\n {columnHeader}\n </Typography.BodySM>\n </div>\n ));\n };\n\n const renderRows = () => {\n if (loading) {\n return (\n <LoadingDotsSpinner\n data-testid=\"timetable-loading-spinner\"\n className={clsx(\n styles.loadingSpinner,\n isEmptyContent\n ? styles.loadingSpinnerEmptyContent\n : styles.loadingSpinnerHasContent\n )}\n />\n );\n }\n\n return (\n <div\n className={styles.timeTableBody}\n data-testid=\"content-container-id\"\n ref={contentContainerRef}\n role=\"rowgroup\"\n >\n {rowData.map((data, index) => {\n return (\n <div\n className={styles.timeTableRow}\n key={`${index}-timetable-row`}\n role=\"row\"\n aria-rowindex={index + 2}\n aria-label={data.name}\n >\n {renderRowHeader(data)}\n <RowBar\n key={`${index}-row-bar`}\n timetableMinTime={timetableMinTime}\n timetableMaxTime={timetableMaxTime}\n rowBarColor={getColorFromSequence()}\n intervalWidth={intervalWidth}\n containerRef={contentContainerRef}\n {...data}\n />\n </div>\n );\n })}\n {renderLazyLoadRow()}\n </div>\n );\n };\n\n const renderLazyLoadRow = () => {\n if (loading || !loadMore) return;\n return (\n <div className={styles.timeTableRow}>\n <div\n className={clsx(\n styles.rowHeader,\n isScrolledX && styles.rowHeaderScrolled\n )}\n >\n <div className={styles.loadingBar} />\n </div>\n <div\n ref={loadingWrapperRef}\n className={styles.loadingWrapper}\n data-testid=\"lazy-loader\"\n role=\"presentation\"\n >\n {hourlyIntervals.map((_, index) => (\n <div\n className={styles.loadingCell}\n key={`lazy-load-cell-${index}`}\n >\n <div className={styles.loadingBar} />\n </div>\n ))}\n </div>\n </div>\n );\n };\n\n if (isEmptyContent) {\n return (\n <div {...otherProps} data-testid={testId}>\n <TimeTableHeader\n selectedDate={date}\n loading={loading || loadMore}\n tableContainerRef={tableContainerRef}\n minDate={minDate}\n maxDate={maxDate}\n totalRecords={totalRecords}\n showCurrentDateAsToday={showCurrentDateAsToday}\n showDateAsShortForm={showDateAsShortForm}\n onPreviousDayClick={onPreviousDayClick}\n onNextDayClick={onNextDayClick}\n onRefresh={onRefresh}\n onCalendarDateSelect={onCalendarDateSelect}\n />\n <div\n className={clsx(\n styles.emptyTableContainer,\n \"empty-container\"\n )}\n tabIndex={0}\n aria-live=\"polite\"\n aria-atomic\n aria-busy={loading}\n >\n {!loading ? (\n <ErrorDisplay\n className={styles.noResultsFound}\n type=\"no-item-found\"\n description={emptyContentMessage}\n />\n ) : (\n <>\n <VisuallyHidden>{`Loading ${timetableAriaLabel}`}</VisuallyHidden>\n <LoadingDotsSpinner\n data-testid=\"timetable-loading-spinner\"\n className={clsx(\n styles.loadingSpinner,\n isEmptyContent\n ? styles.loadingSpinnerEmptyContent\n : styles.loadingSpinnerHasContent\n )}\n />\n </>\n )}\n </div>\n </div>\n );\n }\n\n return (\n <div {...otherProps} data-testid={testId}>\n <TimeTableHeader\n data-id=\"timetable-date-navigator\"\n selectedDate={date}\n loading={loading || loadMore}\n tableContainerRef={tableContainerRef}\n minDate={minDate}\n maxDate={maxDate}\n totalRecords={totalRecords}\n showCurrentDateAsToday={showCurrentDateAsToday}\n showDateAsShortForm={showDateAsShortForm}\n onPreviousDayClick={onPreviousDayClick}\n onNextDayClick={onNextDayClick}\n onRefresh={onRefresh}\n onCalendarDateSelect={onCalendarDateSelect}\n />\n <div\n data-id=\"timetable-container\"\n data-testid=\"timetable-container\"\n ref={tableContainerRef}\n className={clsx(\n styles.timeTableContainer,\n hasLazyLoad && styles.timeTableContainerNotAllLoaded,\n loading && styles.timeTableContainerLoading\n )}\n role=\"grid\"\n aria-label={timetableAriaLabel}\n aria-rowcount={ariaRowCount}\n aria-colcount={ariaColCount}\n aria-busy={loadMore}\n tabIndex={0}\n >\n <div\n className={styles.timeTableHeaderRow}\n role=\"row\"\n aria-rowindex={1}\n data-testid={\"row-header-column-id\"}\n >\n <div\n className={clsx(\n styles.rowColumnHeader,\n (isScrolledX || isScrolledY) &&\n styles.rowColumnHeaderScrolled,\n isScrolledX && styles.rowColumnHeaderScrolledX,\n isScrolledY && styles.rowColumnHeaderScrolledY\n )}\n role=\"columnheader\"\n aria-colindex={1}\n >\n <VisuallyHidden>Resource</VisuallyHidden>\n </div>\n <div\n ref={columnHeaderRowRef}\n className={clsx(\n styles.columnHeaderRow,\n isScrolledY && styles.columnHeaderRowScrolled\n )}\n role=\"presentation\"\n >\n {renderColumnHeaders()}\n </div>\n </div>\n {renderRows()}\n </div>\n </div>\n );\n};\n\n// @catalog\n/**\n * A scrollable grid that visualises time slot availability across a day.\n *\n * Use `TimeTable` to display one day's schedule for multiple resources side by\n * side.\n */\nexport const TimeTable = forwardRef<TimeTableRef, TimeTableProps>(Component);\n"],"names":["TimeTable","forwardRef","props","ref","date","emptyContentMessage","rowData","loading","minTime","maxTime","initialScrollTime","minDate","maxDate","totalRecords","showCurrentDateAsToday","showDateAsShortForm","onPage","onRefresh","onNextDayClick","onPreviousDayClick","onCalendarDateSelect","roundInitialScrollTime","otherProps","testId","timetableMinTime","TimeHelper","roundToNearestInterval","timetableMaxTime","hourlyIntervals","generateHourlyIntervals","numberOfIntervals","Math","ceil","length","ROW_INTERVAL","timetableAriaLabel","dayjs","format","ariaRowCount","ariaColCount","isEmptyContent","isEmpty","allRecordsLoaded","hasLazyLoad","tableContainerRef","useRef","contentContainerRef","columnHeaderRowRef","loadingWrapperRef","isScrolledX","setIsScrolledX","useState","isScrolledY","setIsScrolledY","intervalWidth","setIntervalWidth","loadMore","setLoadMore","useImperativeHandle","resetScroll","useApplyStyle","styles.tokens","columnHeaderRow","columnWidth","loadingWrapper","cellWidth","useEffect","handleScroll","throttle","current","scrollLeft","scrollTop","clientHeight","scrollHeight","tableContainer","addEventListener","removeEventListener","useResizeDetector","onResize","numberOfIntervalsPerRowBar","calcWidth","clientWidth","ROW_HEADER_WIDTH","width","MIN_INTERVAL_WIDTH","targetRef","refreshMode","refreshRate","getColorFromSequence","colorIndex","colorSequenceLength","ROW_BAR_COLOR_SEQUENCE","mainColor","alternateColor","ROW_BAR_COLOR_ALTERNATE_COLOR","buildPopoverTrigger","data","child","rowHeaderPopover","popoverTriggerProps","position","customOffset","offset","children","trigger","delay","popoverContent","content","_createElement","PopoverTrigger","Object","assign","className","styles.popoverTrigger","key","id","zIndex","scrollPosition","calculateScrollPosition","scrollTime","interval","options","roundToInterval","renderRowHeader","rowHeaderContent","_jsxs","_Fragment","_jsx","Typography","BodyMD","clsx","styles.clickableRowHeaderTitle","onRowNameClick","styles.clickableRowHeaderTitleClickable","onClick","event","handleRowNameClick","weight","name","BodyXS","styles.rowHeaderSubtitle","subtitle","styles.rowHeaderSubtitleHidden","styles.rowHeader","styles.rowHeaderScrolled","role","renderLazyLoadRow","styles.timeTableRow","styles.loadingBar","styles.loadingWrapper","map","_","index","styles.loadingCell","TimeTableHeader","selectedDate","styles.emptyTableContainer","tabIndex","VisuallyHidden","LoadingDotsSpinner","styles.loadingSpinner","styles.loadingSpinnerEmptyContent","styles.loadingSpinnerHasContent","ErrorDisplay","styles.noResultsFound","type","description","styles.timeTableContainer","styles.timeTableContainerNotAllLoaded","styles.timeTableContainerLoading","styles.timeTableHeaderRow","styles.rowColumnHeader","styles.rowColumnHeaderScrolled","styles.rowColumnHeaderScrolledX","styles.rowColumnHeaderScrolledY","styles.columnHeaderRow","styles.columnHeaderRowScrolled","columnHeader","styles.columnHeader","BodySM","styles.columnHeaderTitle","styles.timeTableBody","RowBar","rowBarColor","containerRef"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";require("./toast.styles_1e0l60w.css");exports.actionButton="a10z10pl",exports.contentWrapper="c1ll5mdk",exports.description="dmmbr7j",exports.dismissButton="d1jd4l4i",exports.textContainer="t1j1n9on",exports.textIconWrapper="t1mt05g8",exports.title="t1see4ey",exports.wrapper="wqf508q";
1
+ "use strict";require("./toast.styles_57j3lf.css");exports.actionButton="a10z10pl",exports.contentWrapper="c1ll5mdk",exports.description="dmmbr7j",exports.dismissButton="d1jd4l4i",exports.textContainer="t1j1n9on",exports.textIconWrapper="t1mt05g8",exports.title="t1see4ey",exports.wrapper="wqf508q";
2
2
  //# sourceMappingURL=toast.styles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"toast.styles.js","sources":["../../../src/toast/toast.styles.ts"],"sourcesContent":["import { css } from \"@linaria/core\";\n\nimport { Colour, Font, MediaQuery, Radius } from \"../theme\";\n\nexport const wrapper = css`\n display: flex;\n flex-direction: row;\n position: relative;\n margin: 0;\n top: 0;\n right: 0;\n padding: 1rem;\n border-radius: ${Radius[\"md\"]};\n z-index: 10;\n align-items: center;\n gap: 2rem;\n\n ${MediaQuery.MaxWidth.lg} {\n left: 0;\n }\n\n &[data-fixed=\"true\"] {\n position: fixed;\n margin: 1rem;\n }\n\n &[data-type=\"success\"] {\n background: ${Colour[\"bg-success\"]};\n border: 1px solid ${Colour[\"border-success\"]};\n color: ${Colour[\"text-success\"]};\n }\n\n &[data-type=\"warning\"] {\n background: ${Colour[\"bg-warning\"]};\n border: 1px solid ${Colour[\"border-warning\"]};\n color: ${Colour[\"text-warning\"]};\n }\n\n &[data-type=\"error\"] {\n background: ${Colour[\"bg-error\"]};\n border: 1px solid ${Colour[\"border-error\"]};\n color: ${Colour[\"text-error\"]};\n }\n\n &[data-type=\"info\"] {\n background: ${Colour[\"bg-info\"]};\n border: 1px solid ${Colour[\"border-info\"]};\n color: ${Colour[\"text-info\"]};\n }\n`;\n\nexport const contentWrapper = css`\n display: flex;\n align-items: center;\n gap: 2rem;\n flex: 1;\n justify-content: space-between;\n\n ${MediaQuery.MaxWidth.sm} {\n display: flex;\n align-items: flex-start;\n flex-direction: column;\n gap: 0.75rem;\n }\n`;\n\nexport const textIconWrapper = css`\n display: flex;\n flex-direction: row;\n align-items: flex-start;\n\n & > svg {\n flex-shrink: 0;\n width: 1.5rem;\n height: 1.5rem;\n margin-top: 0.0625rem;\n margin-right: 0.5rem;\n }\n\n &[data-type=\"success\"] > svg {\n color: ${Colour[\"icon-success\"]};\n }\n\n &[data-type=\"warning\"] > svg {\n color: ${Colour[\"icon-warning\"]};\n }\n\n &[data-type=\"error\"] > svg {\n color: ${Colour[\"icon-error\"]};\n }\n\n &[data-type=\"info\"] > svg {\n color: ${Colour[\"icon-info\"]};\n }\n`;\n\nexport const textContainer = css`\n display: flex;\n flex-direction: column;\n`;\n\nexport const title = css`\n display: flex;\n ${Font[\"body-baseline-semibold\"]}\n color: inherit;\n`;\n\nexport const description = css`\n color: inherit;\n`;\n\nexport const actionButton = css`\n align-self: center;\n margin-left: auto;\n height: auto;\n width: fit-content;\n flex-shrink: 0;\n\n ${MediaQuery.MaxWidth.sm} {\n align-self: flex-start;\n margin-left: 2rem;\n }\n`;\n\nexport const dismissButton = css`\n padding: 0.75rem;\n margin: -0.75rem;\n align-self: stretch;\n color: inherit;\n\n &:hover {\n background: transparent;\n }\n\n svg {\n width: 1.5rem;\n height: 1.5rem;\n color: inherit;\n }\n\n ${MediaQuery.MaxWidth.sm} {\n align-self: center;\n }\n`;\n"],"names":[],"mappings":"6FA+GyB,kCA5DE,+BAwDH,gCAiBE,iCA5BA,mCA9BE,yBAmCV,2BAjGE"}
1
+ {"version":3,"file":"toast.styles.js","sources":["../../../src/toast/toast.styles.ts"],"sourcesContent":["import { css } from \"@linaria/core\";\n\nimport { Colour, Font, MediaQuery, Radius } from \"../theme\";\n\nexport const wrapper = css`\n display: flex;\n flex-direction: row;\n position: relative;\n margin: 0;\n top: 0;\n right: 0;\n padding: 1rem;\n border-radius: ${Radius[\"md\"]};\n z-index: 10;\n align-items: center;\n gap: 2rem;\n\n ${MediaQuery.MaxWidth.lg} {\n left: 0;\n }\n\n &[data-fixed=\"true\"] {\n position: fixed;\n margin: 1rem;\n }\n\n &[data-type=\"success\"] {\n background: ${Colour[\"bg-success\"]};\n border: 1px solid ${Colour[\"border-success\"]};\n color: ${Colour[\"text-success\"]};\n }\n\n &[data-type=\"warning\"] {\n background: ${Colour[\"bg-warning\"]};\n border: 1px solid ${Colour[\"border-warning\"]};\n color: ${Colour[\"text-warning\"]};\n }\n\n &[data-type=\"error\"] {\n background: ${Colour[\"bg-error\"]};\n border: 1px solid ${Colour[\"border-error\"]};\n color: ${Colour[\"text-error\"]};\n }\n\n &[data-type=\"info\"] {\n background: ${Colour[\"bg-info\"]};\n border: 1px solid ${Colour[\"border-info\"]};\n color: ${Colour[\"text-info\"]};\n }\n`;\n\nexport const contentWrapper = css`\n display: flex;\n align-items: center;\n gap: 2rem;\n flex: 1;\n justify-content: space-between;\n\n ${MediaQuery.MaxWidth.sm} {\n display: flex;\n align-items: flex-start;\n flex-direction: column;\n gap: 0.75rem;\n }\n`;\n\nexport const textIconWrapper = css`\n display: flex;\n flex-direction: row;\n align-items: flex-start;\n\n & > svg {\n flex-shrink: 0;\n width: 1.5rem;\n height: 1.5rem;\n margin-top: 0.0625rem;\n margin-right: 0.5rem;\n }\n\n &[data-type=\"success\"] > svg {\n color: ${Colour[\"icon-success\"]};\n }\n\n &[data-type=\"warning\"] > svg {\n color: ${Colour[\"icon-warning\"]};\n }\n\n &[data-type=\"error\"] > svg {\n color: ${Colour[\"icon-error\"]};\n }\n\n &[data-type=\"info\"] > svg {\n color: ${Colour[\"icon-info\"]};\n }\n`;\n\nexport const textContainer = css`\n display: flex;\n flex-direction: column;\n`;\n\nexport const title = css`\n display: flex;\n ${Font[\"body-baseline-semibold\"]}\n color: inherit;\n`;\n\nexport const description = css`\n color: inherit;\n`;\n\nexport const actionButton = css`\n align-self: center;\n margin-left: auto;\n width: fit-content;\n flex-shrink: 0;\n\n ${MediaQuery.MaxWidth.sm} {\n align-self: flex-start;\n margin-left: 2rem;\n }\n`;\n\nexport const dismissButton = css`\n padding: 0.75rem;\n margin: -0.75rem;\n align-self: stretch;\n color: inherit;\n\n &:hover {\n background: transparent;\n }\n\n svg {\n width: 1.5rem;\n height: 1.5rem;\n color: inherit;\n }\n\n ${MediaQuery.MaxWidth.sm} {\n align-self: center;\n }\n`;\n"],"names":[],"mappings":"4FA+GyB,kCA5DE,+BAwDH,gCAgBE,iCA3BA,mCA9BE,yBAmCV,2BAjGE"}
@@ -4,5 +4,5 @@
4
4
  .t1j1n9on{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}
5
5
  .t1see4ey{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;font-family:var(--fds-font-family-body);font-variant:var(--fds-font-variant);font-size:var(--fds-font-body-size-baseline);font-weight:var(--fds-font-weight-semibold);line-height:var(--fds-font-body-lh-baseline);letter-spacing:var(--fds-font-body-ls-baseline);color:inherit;}
6
6
  .dmmbr7j{color:inherit;}
7
- .a10z10pl{-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;margin-left:auto;height:auto;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}:where(body.fds-breakpoint-sm-max) .a10z10pl{-webkit-align-self:flex-start;-ms-flex-item-align:start;align-self:flex-start;margin-left:2rem;}
7
+ .a10z10pl{-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;margin-left:auto;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}:where(body.fds-breakpoint-sm-max) .a10z10pl{-webkit-align-self:flex-start;-ms-flex-item-align:start;align-self:flex-start;margin-left:2rem;}
8
8
  .d1jd4l4i{padding:0.75rem;margin:-0.75rem;-webkit-align-self:stretch;-ms-flex-item-align:stretch;-ms-grid-row-align:stretch;align-self:stretch;color:inherit;}.d1jd4l4i:hover{background:transparent;}.d1jd4l4i svg{width:1.5rem;height:1.5rem;color:inherit;}:where(body.fds-breakpoint-sm-max) .d1jd4l4i{-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;}}
@@ -1,2 +1,2 @@
1
- "use strict";var e=require("react/jsx-runtime"),r=require("@lifesg/react-icons/circle"),c=require("@lifesg/react-icons/circle-dot"),i=require("@lifesg/react-icons/cross"),s=require("@lifesg/react-icons/square"),a=require("@lifesg/react-icons/square-tick-fill"),t=require("@lifesg/react-icons/tick"),l=require("clsx"),o=require("./toggle-icon.styles.js");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var u=n(l);exports.ToggleIcon=({type:l,active:n=!1,disabled:d,className:f})=>{let q;switch(l){case"checkbox":q=n?e.jsx(a.SquareTickFillIcon,{}):e.jsx(s.SquareIcon,{});break;case"radio":q=n?e.jsx(c.CircleDotIcon,{}):e.jsx(r.CircleIcon,{});break;case"tick":q=e.jsx(t.TickIcon,{});break;case"cross":q=e.jsx(i.CrossIcon,{});break;default:q=null}return e.jsx("div",{className:u.default(o.wrapperBase,n&&d?o.wrapperActiveDisabled:d?o.wrapperDisabled:n?o.wrapperActive:void 0,f),"aria-hidden":!0,children:q})};
1
+ "use strict";var e=require("react/jsx-runtime"),r=require("@lifesg/react-icons/circle"),c=require("@lifesg/react-icons/circle-dot"),i=require("@lifesg/react-icons/cross"),s=require("@lifesg/react-icons/square"),a=require("@lifesg/react-icons/square-tick-fill"),t=require("@lifesg/react-icons/tick"),l=require("clsx"),o=require("./toggle-icon.styles.js");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var u=n(l);exports.ToggleIcon=({type:l,active:n=!1,disabled:d,className:f,error:p})=>{let q;switch(l){case"checkbox":q=n?e.jsx(a.SquareTickFillIcon,{}):e.jsx(s.SquareIcon,{});break;case"radio":q=n?e.jsx(c.CircleDotIcon,{}):e.jsx(r.CircleIcon,{});break;case"tick":q=e.jsx(t.TickIcon,{});break;case"cross":q=e.jsx(i.CrossIcon,{});break;default:q=null}return e.jsx("div",{className:u.default(o.wrapperBase,n?d?o.wrapperActiveDisabled:p?o.wrapperError:o.wrapperActive:d?o.wrapperDisabled:void 0,f),"aria-hidden":!0,children:q})};
2
2
  //# sourceMappingURL=toggle-icon.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"toggle-icon.js","sources":["../../../src/toggle/toggle-icon.tsx"],"sourcesContent":["import { CircleIcon } from \"@lifesg/react-icons/circle\";\nimport { CircleDotIcon } from \"@lifesg/react-icons/circle-dot\";\nimport { CrossIcon } from \"@lifesg/react-icons/cross\";\nimport { SquareIcon } from \"@lifesg/react-icons/square\";\nimport { SquareTickFillIcon } from \"@lifesg/react-icons/square-tick-fill\";\nimport { TickIcon } from \"@lifesg/react-icons/tick\";\nimport clsx from \"clsx\";\n\nimport * as styles from \"./toggle-icon.styles\";\n\nexport type ToggleIconType = \"checkbox\" | \"radio\" | \"tick\" | \"cross\";\n\nexport interface ToggleIconProps {\n type: ToggleIconType;\n active?: boolean | undefined;\n disabled?: boolean | undefined;\n className?: string | undefined;\n}\n\nexport const ToggleIcon = ({\n type,\n active = false,\n disabled,\n className,\n}: ToggleIconProps) => {\n let component: JSX.Element | null;\n\n const getWrapperStateClass = () => {\n if (active && disabled) {\n return styles.wrapperActiveDisabled;\n }\n\n if (disabled) {\n return styles.wrapperDisabled;\n }\n\n if (active) {\n return styles.wrapperActive;\n }\n\n return undefined;\n };\n\n switch (type) {\n case \"checkbox\":\n component = active ? <SquareTickFillIcon /> : <SquareIcon />;\n break;\n case \"radio\":\n component = active ? <CircleDotIcon /> : <CircleIcon />;\n break;\n case \"tick\":\n component = <TickIcon />;\n break;\n case \"cross\":\n component = <CrossIcon />;\n break;\n default:\n component = null;\n break;\n }\n\n return (\n <div\n className={clsx(\n styles.wrapperBase,\n getWrapperStateClass(),\n className\n )}\n aria-hidden\n >\n {component}\n </div>\n );\n};\n"],"names":["type","active","disabled","className","component","_jsx","SquareTickFillIcon","SquareIcon","CircleDotIcon","CircleIcon","TickIcon","CrossIcon","clsx","styles.wrapperBase","styles.wrapperActiveDisabled","styles.wrapperDisabled","styles.wrapperActive"],"mappings":"wcAmB0B,EACtBA,OACAC,UAAS,EACTC,WACAC,gBAEA,IAAIC,EAkBJ,OAAQJ,GACJ,IAAK,WACDI,EAAYH,EAASI,EAAAA,IAACC,EAAAA,mBAAkB,CAAA,GAAMD,EAAAA,IAACE,EAAAA,eAC/C,MACJ,IAAK,QACDH,EAAYH,EAASI,EAAAA,IAACG,EAAAA,cAAa,CAAA,GAAMH,EAAAA,IAACI,EAAAA,eAC1C,MACJ,IAAK,OACDL,EAAYC,EAAAA,IAACK,EAAAA,SAAQ,IACrB,MACJ,IAAK,QACDN,EAAYC,EAAAA,IAACM,EAAAA,UAAS,IACtB,MACJ,QACIP,EAAY,KAIpB,OACIC,EAAAA,IAAA,MAAA,CACIF,UAAWS,EAAAA,QACPC,EAAAA,YApCJZ,GAAUC,EACHY,EAAAA,sBAGPZ,EACOa,EAAAA,gBAGPd,EACOe,EAAAA,mBADX,EA8BQb,6BAIHC,GACC"}
1
+ {"version":3,"file":"toggle-icon.js","sources":["../../../src/toggle/toggle-icon.tsx"],"sourcesContent":["import { CircleIcon } from \"@lifesg/react-icons/circle\";\nimport { CircleDotIcon } from \"@lifesg/react-icons/circle-dot\";\nimport { CrossIcon } from \"@lifesg/react-icons/cross\";\nimport { SquareIcon } from \"@lifesg/react-icons/square\";\nimport { SquareTickFillIcon } from \"@lifesg/react-icons/square-tick-fill\";\nimport { TickIcon } from \"@lifesg/react-icons/tick\";\nimport clsx from \"clsx\";\n\nimport * as styles from \"./toggle-icon.styles\";\n\nexport type ToggleIconType = \"checkbox\" | \"radio\" | \"tick\" | \"cross\";\n\nexport interface ToggleIconProps {\n type: ToggleIconType;\n active?: boolean | undefined;\n disabled?: boolean | undefined;\n error?: boolean | undefined;\n className?: string | undefined;\n}\n\nexport const ToggleIcon = ({\n type,\n active = false,\n disabled,\n className,\n error,\n}: ToggleIconProps) => {\n let component: JSX.Element | null;\n\n const getWrapperStateClass = () => {\n if (active) {\n if (disabled) {\n return styles.wrapperActiveDisabled;\n }\n\n if (error) {\n return styles.wrapperError;\n }\n\n return styles.wrapperActive;\n }\n\n if (disabled) {\n return styles.wrapperDisabled;\n }\n\n return undefined;\n };\n\n switch (type) {\n case \"checkbox\":\n component = active ? <SquareTickFillIcon /> : <SquareIcon />;\n break;\n case \"radio\":\n component = active ? <CircleDotIcon /> : <CircleIcon />;\n break;\n case \"tick\":\n component = <TickIcon />;\n break;\n case \"cross\":\n component = <CrossIcon />;\n break;\n default:\n component = null;\n break;\n }\n\n return (\n <div\n className={clsx(\n styles.wrapperBase,\n getWrapperStateClass(),\n className\n )}\n aria-hidden\n >\n {component}\n </div>\n );\n};\n"],"names":["type","active","disabled","className","error","component","_jsx","SquareTickFillIcon","SquareIcon","CircleDotIcon","CircleIcon","TickIcon","CrossIcon","clsx","styles.wrapperBase","styles.wrapperActiveDisabled","styles.wrapperError","styles.wrapperActive","styles.wrapperDisabled"],"mappings":"wcAoB0B,EACtBA,OACAC,UAAS,EACTC,WACAC,YACAC,YAEA,IAAIC,EAsBJ,OAAQL,GACJ,IAAK,WACDK,EAAYJ,EAASK,EAAAA,IAACC,EAAAA,mBAAkB,CAAA,GAAMD,EAAAA,IAACE,EAAAA,eAC/C,MACJ,IAAK,QACDH,EAAYJ,EAASK,EAAAA,IAACG,EAAAA,cAAa,CAAA,GAAMH,EAAAA,IAACI,EAAAA,eAC1C,MACJ,IAAK,OACDL,EAAYC,EAAAA,IAACK,EAAAA,SAAQ,IACrB,MACJ,IAAK,QACDN,EAAYC,EAAAA,IAACM,EAAAA,UAAS,IACtB,MACJ,QACIP,EAAY,KAIpB,OACIC,EAAAA,IAAA,MAAA,CACIH,UAAWU,EAAAA,QACPC,EAAAA,YAxCJb,EACIC,EACOa,EAAAA,sBAGPX,EACOY,EAAAA,aAGJC,EAAAA,cAGPf,EACOgB,EAAAA,qBADX,EA8BQf,6BAIHE,GACC"}
@@ -1,2 +1,2 @@
1
- "use strict";require("./toggle-icon.styles_ba71y.css");exports.wrapperActive="w1tlwg9n",exports.wrapperActiveDisabled="w1d4lch6",exports.wrapperBase="wxufi5f",exports.wrapperDisabled="wo9gzbp";
1
+ "use strict";require("./toggle-icon.styles_o6dxr3.css");exports.wrapperActive="w1d4lch6",exports.wrapperActiveDisabled="w1egk5xb",exports.wrapperBase="wxufi5f",exports.wrapperDisabled="wo9gzbp",exports.wrapperError="w1tlwg9n";
2
2
  //# sourceMappingURL=toggle-icon.styles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"toggle-icon.styles.js","sources":["../../../src/toggle/toggle-icon.styles.ts"],"sourcesContent":["import { css } from \"@linaria/core\";\n\nimport { Colour } from \"../theme\";\n\n// =============================================================================\n// STYLING\n// =============================================================================\nexport const wrapperBase = css`\n height: 1.625rem;\n width: 1.625rem;\n margin-right: 0.5rem;\n flex-shrink: 0;\n color: ${Colour[\"icon-subtle\"]};\n\n svg {\n height: 100%;\n width: 100%;\n }\n`;\n\nexport const wrapperDisabled = css`\n color: ${Colour[\"icon-disabled-subtle\"]};\n`;\n\nexport const wrapperActive = css`\n color: ${Colour[\"icon-selected\"]};\n`;\n\nexport const wrapperActiveDisabled = css`\n color: ${Colour[\"icon-selected-disabled\"]};\n`;\n"],"names":[],"mappings":"mGAwB0B,yCAIQ,+BArBV,kCAaI"}
1
+ {"version":3,"file":"toggle-icon.styles.js","sources":["../../../src/toggle/toggle-icon.styles.ts"],"sourcesContent":["import { css } from \"@linaria/core\";\n\nimport { Colour } from \"../theme\";\n\n// =============================================================================\n// STYLING\n// =============================================================================\nexport const wrapperBase = css`\n height: 1.625rem;\n width: 1.625rem;\n margin-right: 0.5rem;\n flex-shrink: 0;\n color: ${Colour[\"icon-subtle\"]};\n\n svg {\n height: 100%;\n width: 100%;\n }\n`;\n\nexport const wrapperDisabled = css`\n color: ${Colour[\"icon-disabled-subtle\"]};\n`;\n\nexport const wrapperError = css`\n color: ${Colour[\"icon-error-strong\"]};\n`;\n\nexport const wrapperActive = css`\n color: ${Colour[\"icon-selected\"]};\n`;\n\nexport const wrapperActiveDisabled = css`\n color: ${Colour[\"icon-selected-disabled\"]};\n`;\n"],"names":[],"mappings":"oGA4B0B,yCAIQ,+BAzBV,kCAaI,+BAIH"}
@@ -1,4 +1,5 @@
1
1
  @layer fds{.wxufi5f{height:1.625rem;width:1.625rem;margin-right:0.5rem;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;color:var(--fds-colour-icon-subtle);}.wxufi5f svg{height:100%;width:100%;}
2
2
  .wo9gzbp{color:var(--fds-colour-icon-disabled-subtle);}
3
- .w1tlwg9n{color:var(--fds-colour-icon-selected);}
4
- .w1d4lch6{color:var(--fds-colour-icon-selected-disabled);}}
3
+ .w1tlwg9n{color:var(--fds-colour-icon-error-strong);}
4
+ .w1d4lch6{color:var(--fds-colour-icon-selected);}
5
+ .w1egk5xb{color:var(--fds-colour-icon-selected-disabled);}}
@@ -1,2 +1,2 @@
1
- "use strict";var e=require("../_virtual/_tslib.js"),r=require("react/jsx-runtime"),t=require("@lifesg/react-icons/chevron-down"),l=require("@lifesg/react-icons/chevron-up"),i=require("clsx"),a=require("react"),o=require("../alert/alert.js"),n=require("../markup/markup.js"),s=require("../text-list/index.js");require("../theme/theme-provider/index.js"),require("../theme/theme-provider/context.js"),require("../theme/tokens/border.js"),require("../theme/tokens/colour.js"),require("../theme/tokens/font.js"),require("../theme/tokens/media-query.js");var d=require("../theme/utils/use-apply-styles.js");require("../theme/utils/use-media-query.js");var c=require("../typography/index.js");require("../util/calendar-helper.js"),require("../external/dayjs/dayjs.min.js");var u=require("../util/simple-id-generator.js");require("../util/string-helper.js"),require("@react-aria/live-announcer");var b=require("./toggle.styles.js"),h=require("./toggle-icon.js");function g(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var m=g(i);exports.Toggle=i=>{var{type:g="checkbox",indicator:p,checked:x,styleType:j="default",children:v,childrenMaxLines:C,subLabel:f,disabled:y,error:k,name:q,id:N,className:D,compositeSection:T,removable:S,focusableWhenDisabled:$,useContentWidth:L,onRemove:B,onChange:E,"data-testid":I,"aria-describedby":w}=i,A=e.__rest(i,["type","indicator","checked","styleType","children","childrenMaxLines","subLabel","disabled","error","name","id","className","compositeSection","removable","focusableWhenDisabled","useContentWidth","onRemove","onChange","data-testid","aria-describedby"]);const{collapsible:M=!0,errors:R,children:W,initialExpanded:_}=T||{},[F,P]=a.useState(x),[H,U]=a.useState(!!_),z=a.useMemo((()=>{const e=Array.isArray(R)&&(null==R?void 0:R.length)>0,r=!Array.isArray(R)&&!!R;return e||r}),[R]),O=u.useId(),G=N?`${N}`:`tg-${O}`,J=a.useRef(null),K=a.useRef(null);d.useApplyStyle(K,{[b.tokens.label.desktopLineClamp]:null==(null==C?void 0:C.desktop)?null:`${C.desktop}`,[b.tokens.label.tabletLineClamp]:null==(null==C?void 0:C.tablet)?null:`${C.tablet}`,[b.tokens.label.mobileLineClamp]:null==(null==C?void 0:C.mobile)?null:`${C.mobile}`});const Q=!!y&&!!$,V=!!y&&!$,X=!!y;a.useEffect((()=>{P(x)}),[x]),a.useEffect((()=>{F&&U(null==_||_)}),[F]);const Y=e=>{if(X)e.preventDefault();else if(E)E(e);else switch(g){case"checkbox":P((e=>!e));break;case"radio":case"yes":case"no":F||P(!0)}},Z=()=>{y||U(!H)},ee=()=>{y||!B||B()},re=()=>{var e;null===(e=null==J?void 0:J.current)||void 0===e||e.click()},te=e=>{e.stopPropagation()},le=()=>{let e;switch(g){case"yes":e="tick";break;case"no":e="cross";break;case"checkbox":case"radio":e=g}return r.jsx(h.ToggleIcon,{type:e,active:F,disabled:y})},ie=()=>{if(!f)return null;let e;return e="function"==typeof f?f():f,r.jsx("div",{"data-id":"toggle-sublabel",id:`${G}-sublabel`,"aria-hidden":!0,className:b.subLabel,children:e})},ae=()=>{const e=!H&&!z;return M&&r.jsxs("button",{className:m.default(b.expandButton,y&&b.disabledColorCursor,e&&b.expandButtonPaddingTopRequired),disabled:y,onClick:Z,"data-testid":H?"collapse-button":"expand-button",children:[H?"Show less":"Show more",H?r.jsx(l.ChevronUpIcon,{"aria-hidden":!0}):r.jsx(t.ChevronDownIcon,{"aria-hidden":!0})]})},oe=e=>r.jsxs(r.Fragment,{children:[r.jsx(c.Typography.BodyMD,{weight:"semibold",className:m.default(b.colorTextError,y&&b.colorTextDisabled),children:"Error"}),r.jsx(s.TextList.Ul,{className:m.default(b.colorTextError,y&&b.colorTextDisabled),children:null==e?void 0:e.map(((e,t)=>r.jsx("li",{id:`${G}-error-list-item-${t}`,children:r.jsx(c.Typography.BodyMD,{weight:"semibold",className:m.default(b.colorTextError,y&&b.colorTextDisabled),children:e})},t)))})]});return r.jsxs("div",{className:m.default(b.container,"no-border"===j?k?m.default(b.colorBorderError,!y&&b.toggleContainerError):y?F?b.toggleContainerNoBorderDisabledSelected:b.toggleContainerNoBorderDisabled:F?b.toggleContainerNoBorderSelected:b.toggleContainerNoBorder:k?y?b.colorBorderError:b.toggleContainerError:y?F?b.toggleContainerDisabledSelected:b.toggleContainerDisabled:F?b.toggleContainerSelected:b.toggleContainer,(()=>{if(!y)return!k&&F?b.toggleContainerHoverSelected:b.toggleContainerHoverDefault})(),!p&&b.noIndicatorContainer,L&&b.useContentWidthContainer,D),id:N,"data-testid":I,children:[(()=>{const e=["string"==typeof f?`${G}-sublabel`:null,w].filter(Boolean).join(" ")||void 0;return r.jsxs("div",{id:`${G}-header-container`,className:b.headerContainer,children:[r.jsx("div",{className:m.default(b.indicatorLabelContainer,S&&b.indicatorLabelContainerAddPadding),children:r.jsxs("div",{id:`${G}-input-container`,onClick:re,className:b.inputContainer,children:[r.jsx("input",Object.assign({ref:J,name:q,id:`${G}-input`,type:"checkbox"===g?"checkbox":"radio","data-testid":"toggle-input",className:m.default(b.input,y&&b.toggleInputDisabled),disabled:V,"aria-disabled":Q,onChange:Y,onClick:te,checked:F,tabIndex:Q?0:void 0,"aria-describedby":e},A)),p&&le(),r.jsxs("div",{className:m.default(b.textContainer,y?F?b.toggleTextContainerDisabledSelected:b.colorTextDisabled:F?b.toggleTextContainerSelected:void 0),children:[r.jsx("label",{ref:K,htmlFor:`${G}-input`,"data-testid":"toggle-label",id:`${G}-label`,className:m.default(b.label,F?b.toggleLabelSelected:b.toggleLabelDefault),children:v}),f&&ie()]})]})}),S&&r.jsx("button",{type:"button",className:m.default(b.removeButton,y&&b.disabledColorCursor),onClick:ee,id:`${G}-remove-button`,children:"Remove"})]})})(),W&&r.jsxs("div",{children:[(!M||H)&&r.jsx("div",{"data-id":"toggle-composite-children",className:m.default(b.children,!M&&b.childrenIsFinalItem,y&&b.colorTextDisabled),children:r.jsx(n.Markup,{baseTextSize:"body-md",children:W})}),M&&!H&&z&&r.jsx("div",{className:m.default(b.errorContainer,y&&b.disabledColorCursor),onClick:Z,id:`${G}-error-alert`,children:r.jsx(o.Alert,{type:y?"description":"error",className:b.alertContainer,showIcon:!0,children:Array.isArray(R)?oe(R):R})}),ae()]})]})};
1
+ "use strict";var e=require("../_virtual/_tslib.js"),r=require("react/jsx-runtime"),t=require("@lifesg/react-icons/chevron-down"),l=require("@lifesg/react-icons/chevron-up"),i=require("clsx"),a=require("react"),o=require("../alert/alert.js"),s=require("../markup/markup.js"),n=require("../text-list/index.js");require("../theme/theme-provider/index.js"),require("../theme/theme-provider/context.js"),require("../theme/tokens/border.js"),require("../theme/tokens/colour.js"),require("../theme/tokens/font.js"),require("../theme/tokens/media-query.js");var d=require("../theme/utils/use-apply-styles.js");require("../theme/utils/use-media-query.js");var c=require("../typography/index.js");require("../util/calendar-helper.js"),require("../external/dayjs/dayjs.min.js");var u=require("../util/simple-id-generator.js");require("../util/string-helper.js"),require("@react-aria/live-announcer");var b=require("./toggle.styles.js"),h=require("./toggle-icon.js");function m(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var p=m(i);exports.Toggle=i=>{var{type:m="checkbox",indicator:x,checked:g,styleType:j="default",children:v,childrenMaxLines:f,subLabel:y,disabled:C,error:k,name:q,id:D,className:N,compositeSection:T,removable:S,focusableWhenDisabled:$,useContentWidth:L,onRemove:E,onChange:w,"data-testid":A,"aria-describedby":I}=i,B=e.__rest(i,["type","indicator","checked","styleType","children","childrenMaxLines","subLabel","disabled","error","name","id","className","compositeSection","removable","focusableWhenDisabled","useContentWidth","onRemove","onChange","data-testid","aria-describedby"]);const{collapsible:M=!0,errors:R,children:F,initialExpanded:W}=T||{},[P,_]=a.useState(g),[H,U]=a.useState(!!W),z=a.useMemo((()=>{const e=Array.isArray(R)&&(null==R?void 0:R.length)>0,r=!Array.isArray(R)&&!!R;return e||r}),[R]),O=u.useId(),G=D?`${D}`:`tg-${O}`,J=a.useRef(null),K=a.useRef(null);d.useApplyStyle(K,{[b.tokens.label.desktopLineClamp]:null==(null==f?void 0:f.desktop)?null:`${f.desktop}`,[b.tokens.label.tabletLineClamp]:null==(null==f?void 0:f.tablet)?null:`${f.tablet}`,[b.tokens.label.mobileLineClamp]:null==(null==f?void 0:f.mobile)?null:`${f.mobile}`});const Q=!!C&&!!$,V=!!C&&!$,X=!!C;a.useEffect((()=>{_(g)}),[g]),a.useEffect((()=>{P&&U(null==W||W)}),[P]);const Y=e=>{if(X)e.preventDefault();else if(w)w(e);else switch(m){case"checkbox":_((e=>!e));break;case"radio":case"yes":case"no":P||_(!0)}},Z=()=>{C||U(!H)},ee=()=>{C||!E||E()},re=()=>{var e;null===(e=null==J?void 0:J.current)||void 0===e||e.click()},te=e=>{e.stopPropagation()},le=()=>{let e;switch(m){case"yes":e="tick";break;case"no":e="cross";break;case"checkbox":case"radio":e=m}return r.jsx(h.ToggleIcon,{type:e,active:P,disabled:C,error:k})},ie=()=>{if(!y)return null;let e;return e="function"==typeof y?y():y,r.jsx("div",{"data-id":"toggle-sublabel",id:`${G}-sublabel`,"aria-hidden":!0,className:b.subLabel,children:e})},ae=()=>{const e=!H&&!z;return M&&r.jsx("button",{className:p.default(b.expandButton,C?b.disabledColorCursor:b.colorTextPrimary,e&&b.expandButtonPaddingTopRequired),disabled:C,onClick:Z,"data-testid":H?"collapse-button":"expand-button",children:H?r.jsxs(r.Fragment,{children:["Show less",r.jsx(l.ChevronUpIcon,{"aria-hidden":!0})]}):r.jsxs(r.Fragment,{children:["Show more",r.jsx(t.ChevronDownIcon,{"aria-hidden":!0})]})})},oe=e=>{const t=p.default(b.colorTextError,C&&b.colorTextDisabled);return r.jsxs(r.Fragment,{children:[r.jsx(c.Typography.BodyMD,{weight:"semibold",className:t,children:"Error"}),r.jsx(n.TextList.Ul,{className:t,children:null==e?void 0:e.map(((e,l)=>r.jsx("li",{id:`${G}-error-list-item-${l}`,children:r.jsx(c.Typography.BodyMD,{weight:"semibold",className:t,children:e})},l)))})]})};return r.jsxs("div",{className:p.default(b.container,!P&&k?b.borderError:"no-border"===j?b.borderNone:P&&C?b.borderSelectedDisabled:C?b.borderDisabled:k?b.borderError:P?b.borderSelected:b.borderDefault,P?k?b.bgError:C?b.bgSelectedDisabled:b.bgSelected:C&&"no-border"!==j?b.bgDisabled:b.bgDefault,C?null:P?k?b.toggleContainerHoverError:b.toggleContainerHoverSelected:b.toggleContainerHoverDefault,!x&&b.containerNoIndicator,L&&b.containerUseContentWidth,N),id:D,"data-testid":A,children:[(()=>{const e=["string"==typeof y?`${G}-sublabel`:null,I].filter(Boolean).join(" ")||void 0;return r.jsxs("div",{id:`${G}-header-container`,className:b.headerContainer,children:[r.jsx("div",{className:p.default(b.indicatorLabelContainer,S&&b.indicatorLabelContainerAddPadding),children:r.jsxs("div",{id:`${G}-input-container`,onClick:re,className:b.inputContainer,children:[r.jsx("input",Object.assign({ref:J,name:q,id:`${G}-input`,type:"checkbox"===m?"checkbox":"radio","data-testid":"toggle-input",className:p.default(b.input,C&&b.disabledColorCursor),disabled:V,"aria-disabled":Q,onChange:Y,onClick:te,checked:P,tabIndex:Q?0:void 0,"aria-describedby":e},B)),x&&le(),r.jsxs("div",{className:p.default(b.textContainer,P?k?b.colorTextError:C?b.toggleTextContainerDisabledSelected:b.toggleTextContainerSelected:C?b.colorTextDisabled:b.colorTextDefault),children:[r.jsx("label",{ref:K,htmlFor:`${G}-input`,"data-testid":"toggle-label",id:`${G}-label`,className:p.default(b.label,P?b.toggleLabelSelected:b.toggleLabelDefault),children:v}),y&&ie()]})]})}),S&&r.jsx("button",{type:"button",className:p.default(b.removeButton,C&&b.disabledColorCursor),onClick:ee,id:`${G}-remove-button`,children:"Remove"})]})})(),F&&r.jsxs("div",{children:[(!M||H)&&r.jsx("div",{"data-id":"toggle-composite-children",className:p.default(b.children,!M&&b.childrenIsFinalItem,C?b.colorTextDisabled:b.colorTextDefault),children:r.jsx(s.Markup,{baseTextSize:"body-md",children:F})}),M&&!H&&z&&r.jsx("div",{className:p.default(b.errorContainer,C?b.disabledColorCursor:b.colorTextDefault),onClick:Z,id:`${G}-error-alert`,children:r.jsx(o.Alert,{type:C?"description":"error",className:b.alertContainer,showIcon:!0,children:Array.isArray(R)?oe(R):R})}),ae()]})]})};
2
2
  //# sourceMappingURL=toggle.js.map