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

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 (684) hide show
  1. package/accordion/accordion.js.map +1 -1
  2. package/alert/alert.js.map +1 -1
  3. package/alert/types.d.ts +2 -0
  4. package/animations/loading-dots/loading-dots.d.ts +5 -2
  5. package/animations/loading-dots/loading-dots.js.map +1 -1
  6. package/animations/loading-dots-spinner/loading-dots-spinner.d.ts +3 -0
  7. package/animations/loading-dots-spinner/loading-dots-spinner.js.map +1 -1
  8. package/animations/loading-dots-spinner/lottie-animation.d.ts +2 -2
  9. package/animations/loading-dots-spinner/lottie-animation.js.map +1 -1
  10. package/animations/loading-spinner/loading-spinner.d.ts +5 -2
  11. package/animations/loading-spinner/loading-spinner.js.map +1 -1
  12. package/animations/themed-loading-spinner/themed-loading-spinner.d.ts +5 -2
  13. package/animations/themed-loading-spinner/themed-loading-spinner.js.map +1 -1
  14. package/animations/types.d.ts +13 -6
  15. package/avatar/avatar.js.map +1 -1
  16. package/badge/badge.js.map +1 -1
  17. package/badge/types.d.ts +13 -2
  18. package/box-container/box-container.js.map +1 -1
  19. package/box-container/types.d.ts +2 -0
  20. package/breadcrumb/breadcrumb.js.map +1 -1
  21. package/breadcrumb/types.d.ts +7 -2
  22. package/button/button.js.map +1 -1
  23. package/button/types.d.ts +5 -0
  24. package/calendar/calendar.js.map +1 -1
  25. package/calendar/types.d.ts +3 -3
  26. package/card/card.js.map +1 -1
  27. package/checkbox/checkbox.js.map +1 -1
  28. package/checkbox/types.d.ts +4 -0
  29. package/cjs/accordion/accordion.js.map +1 -1
  30. package/cjs/alert/alert.js.map +1 -1
  31. package/cjs/animations/loading-dots/loading-dots.js.map +1 -1
  32. package/cjs/animations/loading-dots-spinner/loading-dots-spinner.js.map +1 -1
  33. package/cjs/animations/loading-dots-spinner/lottie-animation.js.map +1 -1
  34. package/cjs/animations/loading-spinner/loading-spinner.js.map +1 -1
  35. package/cjs/animations/themed-loading-spinner/themed-loading-spinner.js.map +1 -1
  36. package/cjs/avatar/avatar.js.map +1 -1
  37. package/cjs/badge/badge.js.map +1 -1
  38. package/cjs/box-container/box-container.js.map +1 -1
  39. package/cjs/breadcrumb/breadcrumb.js.map +1 -1
  40. package/cjs/button/button.js.map +1 -1
  41. package/cjs/calendar/calendar.js.map +1 -1
  42. package/cjs/card/card.js.map +1 -1
  43. package/cjs/checkbox/checkbox.js.map +1 -1
  44. package/cjs/countdown-timer/countdown-timer.js.map +1 -1
  45. package/cjs/dashed-border/dashed-border.js.map +1 -1
  46. package/cjs/data-table/data-table.js.map +1 -1
  47. package/cjs/date-input/date-input.js.map +1 -1
  48. package/cjs/date-navigator/date-navigator.js.map +1 -1
  49. package/cjs/date-range-input/date-range-input.js.map +1 -1
  50. package/cjs/divider/divider.js.map +1 -1
  51. package/cjs/drawer/drawer.js.map +1 -1
  52. package/cjs/e-signature/e-signature.js.map +1 -1
  53. package/cjs/error-display/error-display.js.map +1 -1
  54. package/cjs/feedback-rating/feedback-rating.js.map +1 -1
  55. package/cjs/file-download/file-download.js.map +1 -1
  56. package/cjs/file-upload/file-item-edit.js.map +1 -1
  57. package/cjs/file-upload/file-list/file-list.js.map +1 -1
  58. package/cjs/file-upload/file-list-item/file-list-item.js.map +1 -1
  59. package/cjs/file-upload/file-list-item/file-list-item.styles.js +1 -1
  60. package/cjs/file-upload/file-list-item/file-list-item.styles.js.map +1 -1
  61. package/cjs/file-upload/file-list-item/{file-list-item.styles_o8000f.css → file-list-item.styles_kgtfke.css} +1 -1
  62. package/cjs/file-upload/file-upload.js.map +1 -1
  63. package/cjs/filter/addons/filter-item-checkbox-helpers.js.map +1 -1
  64. package/cjs/filter/addons/filter-item-checkbox.js.map +1 -1
  65. package/cjs/filter/filter-item.js +1 -1
  66. package/cjs/filter/filter-item.js.map +1 -1
  67. package/cjs/filter/filter.js.map +1 -1
  68. package/cjs/footer/footer.js.map +1 -1
  69. package/cjs/form/form-custom-field/form-custom-field.js +2 -0
  70. package/cjs/form/form-custom-field/form-custom-field.js.map +1 -0
  71. package/cjs/form/form-date-input/form-date-input.js +2 -0
  72. package/cjs/form/form-date-input/form-date-input.js.map +1 -0
  73. package/cjs/form/form-date-range-input/form-date-range-input.js +2 -0
  74. package/cjs/form/form-date-range-input/form-date-range-input.js.map +1 -0
  75. package/cjs/form/form-e-signature/form-e-signature.js +2 -0
  76. package/cjs/form/form-e-signature/form-e-signature.js.map +1 -0
  77. package/cjs/form/form-histogram-slider/form-histogram-slider.js +2 -0
  78. package/cjs/form/form-histogram-slider/form-histogram-slider.js.map +1 -0
  79. package/cjs/form/form-input/form-input.js +2 -0
  80. package/cjs/form/form-input/form-input.js.map +1 -0
  81. package/cjs/form/form-input-group/form-input-group.js +2 -0
  82. package/cjs/form/form-input-group/form-input-group.js.map +1 -0
  83. package/cjs/form/form-label/form-label-addon.js +2 -0
  84. package/cjs/form/form-label/form-label-addon.js.map +1 -0
  85. package/cjs/form/form-label/form-label-addon.styles.js +2 -0
  86. package/cjs/form/form-label/form-label-addon.styles.js.map +1 -0
  87. package/cjs/form/form-label/form-label-addon.styles_aztasj.css +1 -0
  88. package/cjs/form/form-label/form-label.js +2 -0
  89. package/cjs/form/form-label/form-label.js.map +1 -0
  90. package/cjs/form/form-label/form-label.styles.js +2 -0
  91. package/cjs/form/form-label/form-label.styles.js.map +1 -0
  92. package/cjs/form/form-label/form-label.styles_180zf7j.css +6 -0
  93. package/cjs/form/form-masked-input/form-masked-input.js +2 -0
  94. package/cjs/form/form-masked-input/form-masked-input.js.map +1 -0
  95. package/cjs/form/form-multi-select/form-multi-select.js +2 -0
  96. package/cjs/form/form-multi-select/form-multi-select.js.map +1 -0
  97. package/cjs/form/form-nested-multi-select/form-nested-multi-select.js +2 -0
  98. package/cjs/form/form-nested-multi-select/form-nested-multi-select.js.map +1 -0
  99. package/cjs/form/form-nested-select/form-nested-select.js +2 -0
  100. package/cjs/form/form-nested-select/form-nested-select.js.map +1 -0
  101. package/cjs/form/form-otp-verification/form-otp-verification.js +2 -0
  102. package/cjs/form/form-otp-verification/form-otp-verification.js.map +1 -0
  103. package/cjs/form/form-phone-number-input/form-phone-number-input.js +2 -0
  104. package/cjs/form/form-phone-number-input/form-phone-number-input.js.map +1 -0
  105. package/cjs/form/form-predictive-text-input/form-predictive-text-input.js +2 -0
  106. package/cjs/form/form-predictive-text-input/form-predictive-text-input.js.map +1 -0
  107. package/cjs/form/form-range-select/form-range-select.js +2 -0
  108. package/cjs/form/form-range-select/form-range-select.js.map +1 -0
  109. package/cjs/form/form-range-slider/form-range-slider.js +2 -0
  110. package/cjs/form/form-range-slider/form-range-slider.js.map +1 -0
  111. package/cjs/form/form-select/form-select.js +2 -0
  112. package/cjs/form/form-select/form-select.js.map +1 -0
  113. package/cjs/form/form-select-histogram/form-select-histogram.js +2 -0
  114. package/cjs/form/form-select-histogram/form-select-histogram.js.map +1 -0
  115. package/cjs/form/form-slider/form-slider.js +2 -0
  116. package/cjs/form/form-slider/form-slider.js.map +1 -0
  117. package/cjs/form/form-textarea/form-textarea.js +2 -0
  118. package/cjs/form/form-textarea/form-textarea.js.map +1 -0
  119. package/cjs/form/form-textarea/form-textarea.styles.js +2 -0
  120. package/cjs/form/form-textarea/form-textarea.styles.js.map +1 -0
  121. package/cjs/form/form-textarea/form-textarea.styles_1kneyif.css +3 -0
  122. package/cjs/form/form-time-range-picker/form-time-range-picker.js +2 -0
  123. package/cjs/form/form-time-range-picker/form-time-range-picker.js.map +1 -0
  124. package/cjs/form/form-timepicker/form-timepicker.js +2 -0
  125. package/cjs/form/form-timepicker/form-timepicker.js.map +1 -0
  126. package/cjs/form/form-unit-number-input/form-unit-number-input.js +2 -0
  127. package/cjs/form/form-unit-number-input/form-unit-number-input.js.map +1 -0
  128. package/cjs/form/form-wrapper.js +1 -1
  129. package/cjs/form/form-wrapper.js.map +1 -1
  130. package/cjs/form/index.js +1 -1
  131. package/cjs/form/index.js.map +1 -1
  132. package/cjs/fullscreen-image-carousel/fullscreen-image-carousel.js.map +1 -1
  133. package/cjs/histogram-slider/histogram-slider.js.map +1 -1
  134. package/cjs/image-button/image-button.js.map +1 -1
  135. package/cjs/input/input.js.map +1 -1
  136. package/cjs/input-group/input-group.js.map +1 -1
  137. package/cjs/input-multi-select/input-multi-select.js.map +1 -1
  138. package/cjs/input-nested-multi-select/input-nested-multi-select.js.map +1 -1
  139. package/cjs/input-nested-select/input-nested-select.js.map +1 -1
  140. package/cjs/input-range-select/input-range-select.js.map +1 -1
  141. package/cjs/input-range-slider/input-range-slider.js.map +1 -1
  142. package/cjs/input-select/input-select.js.map +1 -1
  143. package/cjs/input-slider/input-slider.js.map +1 -1
  144. package/cjs/input-textarea/textarea.js.map +1 -1
  145. package/cjs/input-textarea/textarea.styles.js +1 -1
  146. package/cjs/input-textarea/textarea.styles.js.map +1 -1
  147. package/cjs/input-textarea/{textarea.styles_22z4n3.css → textarea.styles_q77m5x.css} +1 -1
  148. package/cjs/language-switcher/language-switcher.js.map +1 -1
  149. package/cjs/layout/index.js.map +1 -1
  150. package/cjs/link-list/components/common.js.map +1 -1
  151. package/cjs/link-list/components/link-list-eager.js.map +1 -1
  152. package/cjs/link-list/components/link-list-lazy.js.map +1 -1
  153. package/cjs/link-list/link-list.js.map +1 -1
  154. package/cjs/local-nav/local-nav-dropdown/local-nav-dropdown.js.map +1 -1
  155. package/cjs/local-nav/local-nav-menu/local-nav-menu.js.map +1 -1
  156. package/cjs/markup/markup.js.map +1 -1
  157. package/cjs/masked-input/masked-input.js.map +1 -1
  158. package/cjs/masthead/masthead.js.map +1 -1
  159. package/cjs/menu/menu.js.map +1 -1
  160. package/cjs/modal/index.js.map +1 -1
  161. package/cjs/modal-v2/modal-v2.js.map +1 -1
  162. package/cjs/navbar/navbar.js.map +1 -1
  163. package/cjs/notification-banner/notification-banner.js.map +1 -1
  164. package/cjs/otp-input/otp-input.js +1 -1
  165. package/cjs/otp-input/otp-input.js.map +1 -1
  166. package/cjs/otp-verification/contact-input-section.js +1 -1
  167. package/cjs/otp-verification/contact-input-section.js.map +1 -1
  168. package/cjs/otp-verification/otp-verification.js.map +1 -1
  169. package/cjs/otp-verification/verification-section.js +1 -1
  170. package/cjs/otp-verification/verification-section.js.map +1 -1
  171. package/cjs/overlay/overlay.js.map +1 -1
  172. package/cjs/pagination/pagination.js.map +1 -1
  173. package/cjs/phone-number-input/phone-number-input.js.map +1 -1
  174. package/cjs/pill/pill.js.map +1 -1
  175. package/cjs/popover/popover-inline/popover-inline.js.map +1 -1
  176. package/cjs/popover/popover.js.map +1 -1
  177. package/cjs/predictive-text-input/predictive-text-input.js +1 -1
  178. package/cjs/predictive-text-input/predictive-text-input.js.map +1 -1
  179. package/cjs/progress-indicator/progress-indicator.js.map +1 -1
  180. package/cjs/radio-button/radio-button.js.map +1 -1
  181. package/cjs/schedule/schedule.js.map +1 -1
  182. package/cjs/select-histogram/select-histogram.js.map +1 -1
  183. package/cjs/shared/dropdown-list/dropdown-list.js +1 -1
  184. package/cjs/shared/dropdown-list/dropdown-list.js.map +1 -1
  185. package/cjs/shared/dropdown-wrapper/element-with-dropdown.js +1 -1
  186. package/cjs/shared/dropdown-wrapper/element-with-dropdown.js.map +1 -1
  187. package/cjs/sidenav/sidenav.js.map +1 -1
  188. package/cjs/singpass-button/singpass-button.js.map +1 -1
  189. package/cjs/smart-app-banner/smart-app-banner.js.map +1 -1
  190. package/cjs/tab/tab.js.map +1 -1
  191. package/cjs/table/table.js.map +1 -1
  192. package/cjs/tag/tag.js.map +1 -1
  193. package/cjs/text-list/index.js.map +1 -1
  194. package/cjs/theme/theme-provider/hooks.js.map +1 -1
  195. package/cjs/theme/theme-provider/index.js.map +1 -1
  196. package/cjs/theme/tokens/border.js.map +1 -1
  197. package/cjs/theme/tokens/breakpoint.js.map +1 -1
  198. package/cjs/theme/tokens/colour.js.map +1 -1
  199. package/cjs/theme/tokens/component.js.map +1 -1
  200. package/cjs/theme/tokens/font.js.map +1 -1
  201. package/cjs/theme/tokens/media-query.js.map +1 -1
  202. package/cjs/theme/tokens/motion.js.map +1 -1
  203. package/cjs/theme/tokens/radius.js.map +1 -1
  204. package/cjs/theme/tokens/shadow.js.map +1 -1
  205. package/cjs/theme/tokens/spacing.js.map +1 -1
  206. package/cjs/theme/utils/use-apply-styles.js.map +1 -1
  207. package/cjs/theme/utils/use-design-token.js.map +1 -1
  208. package/cjs/theme/utils/use-media-query.js.map +1 -1
  209. package/cjs/time-range-picker/combobox-picker/combobox-picker.js +1 -1
  210. package/cjs/time-range-picker/combobox-picker/combobox-picker.js.map +1 -1
  211. package/cjs/time-range-picker/time-range-picker.js.map +1 -1
  212. package/cjs/time-slot-bar/time-slot-bar.js.map +1 -1
  213. package/cjs/time-slot-bar-week/time-slot-bar-week.js.map +1 -1
  214. package/cjs/time-slot-week-view/time-slot-week-view.js.map +1 -1
  215. package/cjs/timeline/timeline.js.map +1 -1
  216. package/cjs/timepicker/timepicker.js.map +1 -1
  217. package/cjs/timetable/timetable.js.map +1 -1
  218. package/cjs/toast/toast.js.map +1 -1
  219. package/cjs/toggle/toggle.js.map +1 -1
  220. package/cjs/typography/index.js.map +1 -1
  221. package/cjs/uneditable-section/index.js.map +1 -1
  222. package/cjs/uneditable-section/section-item.js +1 -1
  223. package/cjs/uneditable-section/section-item.js.map +1 -1
  224. package/cjs/unit-number/unit-number-input.js.map +1 -1
  225. package/countdown-timer/countdown-timer.js.map +1 -1
  226. package/countdown-timer/types.d.ts +3 -3
  227. package/dashed-border/dashed-border.js.map +1 -1
  228. package/data-table/data-table.js.map +1 -1
  229. package/date-input/date-input.js.map +1 -1
  230. package/date-input/types.d.ts +1 -1
  231. package/date-navigator/date-navigator.js.map +1 -1
  232. package/date-navigator/types.d.ts +1 -1
  233. package/date-range-input/date-range-input.js.map +1 -1
  234. package/date-range-input/types.d.ts +1 -1
  235. package/divider/divider.js.map +1 -1
  236. package/divider/types.d.ts +1 -1
  237. package/docs/component-catalog.json +644 -0
  238. package/drawer/drawer.js.map +1 -1
  239. package/e-signature/e-signature.js.map +1 -1
  240. package/error-display/error-display.js.map +1 -1
  241. package/feedback-rating/feedback-rating.js.map +1 -1
  242. package/file-download/file-download.js.map +1 -1
  243. package/file-download/types.d.ts +6 -1
  244. package/file-upload/file-item-edit.d.ts +1 -1
  245. package/file-upload/file-item-edit.js.map +1 -1
  246. package/file-upload/file-list/file-list.d.ts +1 -1
  247. package/file-upload/file-list/file-list.js.map +1 -1
  248. package/file-upload/file-list-item/file-list-item.d.ts +1 -1
  249. package/file-upload/file-list-item/file-list-item.js.map +1 -1
  250. package/file-upload/file-list-item/file-list-item.styles.js +1 -1
  251. package/file-upload/file-list-item/file-list-item.styles.js.map +1 -1
  252. package/file-upload/file-list-item/{file-list-item.styles_o8000f.css → file-list-item.styles_kgtfke.css} +1 -1
  253. package/file-upload/file-upload.js.map +1 -1
  254. package/file-upload/types.d.ts +6 -2
  255. package/filter/addons/filter-item-checkbox-helpers.d.ts +2 -2
  256. package/filter/addons/filter-item-checkbox-helpers.js.map +1 -1
  257. package/filter/addons/filter-item-checkbox.d.ts +1 -1
  258. package/filter/addons/filter-item-checkbox.js.map +1 -1
  259. package/filter/addons/internal-types.d.ts +12 -0
  260. package/filter/addons/types.d.ts +60 -9
  261. package/filter/filter-item.js +1 -1
  262. package/filter/filter-item.js.map +1 -1
  263. package/filter/filter.d.ts +1 -1
  264. package/filter/filter.js.map +1 -1
  265. package/filter/index.d.ts +1 -0
  266. package/filter/types.d.ts +31 -63
  267. package/footer/footer.js.map +1 -1
  268. package/form/form-custom-field/form-custom-field.js +2 -0
  269. package/form/form-custom-field/form-custom-field.js.map +1 -0
  270. package/form/form-custom-field/index.d.ts +2 -0
  271. package/form/form-custom-field/types.d.ts +7 -0
  272. package/form/form-date-input/form-date-input.js +2 -0
  273. package/form/form-date-input/form-date-input.js.map +1 -0
  274. package/form/form-date-input/index.d.ts +2 -0
  275. package/form/form-date-input/types.d.ts +8 -0
  276. package/form/form-date-range-input/form-date-range-input.js +2 -0
  277. package/form/form-date-range-input/form-date-range-input.js.map +1 -0
  278. package/form/form-date-range-input/index.d.ts +2 -0
  279. package/form/form-date-range-input/types.d.ts +8 -0
  280. package/form/form-e-signature/form-e-signature.js +2 -0
  281. package/form/form-e-signature/form-e-signature.js.map +1 -0
  282. package/form/form-e-signature/index.d.ts +2 -0
  283. package/form/form-e-signature/types.d.ts +8 -0
  284. package/form/form-histogram-slider/form-histogram-slider.js +2 -0
  285. package/form/form-histogram-slider/form-histogram-slider.js.map +1 -0
  286. package/form/form-histogram-slider/index.d.ts +2 -0
  287. package/form/form-histogram-slider/types.d.ts +8 -0
  288. package/form/form-input/form-input.js +2 -0
  289. package/form/form-input/form-input.js.map +1 -0
  290. package/form/form-input/index.d.ts +2 -0
  291. package/form/form-input/types.d.ts +8 -0
  292. package/form/form-input-group/form-input-group.js +2 -0
  293. package/form/form-input-group/form-input-group.js.map +1 -0
  294. package/form/form-input-group/index.d.ts +2 -0
  295. package/form/form-input-group/types.d.ts +10 -0
  296. package/form/form-label/form-label-addon.js +2 -0
  297. package/form/form-label/form-label-addon.js.map +1 -0
  298. package/form/form-label/form-label-addon.styles.js +2 -0
  299. package/form/form-label/form-label-addon.styles.js.map +1 -0
  300. package/form/form-label/form-label-addon.styles_aztasj.css +1 -0
  301. package/form/form-label/form-label.js +2 -0
  302. package/form/form-label/form-label.js.map +1 -0
  303. package/form/form-label/form-label.styles.js +2 -0
  304. package/form/form-label/form-label.styles.js.map +1 -0
  305. package/form/form-label/form-label.styles_180zf7j.css +6 -0
  306. package/form/form-label/index.d.ts +2 -0
  307. package/form/form-label/types.d.ts +39 -0
  308. package/form/form-masked-input/form-masked-input.js +2 -0
  309. package/form/form-masked-input/form-masked-input.js.map +1 -0
  310. package/form/form-masked-input/index.d.ts +2 -0
  311. package/form/form-masked-input/types.d.ts +8 -0
  312. package/form/form-multi-select/form-multi-select.js +2 -0
  313. package/form/form-multi-select/form-multi-select.js.map +1 -0
  314. package/form/form-multi-select/index.d.ts +2 -0
  315. package/form/form-multi-select/types.d.ts +10 -0
  316. package/form/form-nested-multi-select/form-nested-multi-select.js +2 -0
  317. package/form/form-nested-multi-select/form-nested-multi-select.js.map +1 -0
  318. package/form/form-nested-multi-select/index.d.ts +2 -0
  319. package/form/form-nested-multi-select/types.d.ts +11 -0
  320. package/form/form-nested-select/form-nested-select.js +2 -0
  321. package/form/form-nested-select/form-nested-select.js.map +1 -0
  322. package/form/form-nested-select/index.d.ts +2 -0
  323. package/form/form-nested-select/types.d.ts +11 -0
  324. package/form/{form-otp-verification.d.ts → form-otp-verification/form-otp-verification.d.ts} +1 -1
  325. package/form/form-otp-verification/form-otp-verification.js +2 -0
  326. package/form/form-otp-verification/form-otp-verification.js.map +1 -0
  327. package/form/form-otp-verification/index.d.ts +2 -0
  328. package/form/form-otp-verification/types.d.ts +1 -0
  329. package/form/form-phone-number-input/form-phone-number-input.js +2 -0
  330. package/form/form-phone-number-input/form-phone-number-input.js.map +1 -0
  331. package/form/form-phone-number-input/index.d.ts +2 -0
  332. package/form/form-phone-number-input/types.d.ts +8 -0
  333. package/form/form-predictive-text-input/form-predictive-text-input.js +2 -0
  334. package/form/form-predictive-text-input/form-predictive-text-input.js.map +1 -0
  335. package/form/form-predictive-text-input/index.d.ts +2 -0
  336. package/form/form-predictive-text-input/types.d.ts +10 -0
  337. package/form/form-range-select/form-range-select.js +2 -0
  338. package/form/form-range-select/form-range-select.js.map +1 -0
  339. package/form/form-range-select/index.d.ts +2 -0
  340. package/form/form-range-select/types.d.ts +10 -0
  341. package/form/form-range-slider/form-range-slider.js +2 -0
  342. package/form/form-range-slider/form-range-slider.js.map +1 -0
  343. package/form/form-range-slider/index.d.ts +2 -0
  344. package/form/form-range-slider/types.d.ts +8 -0
  345. package/form/form-select/form-select.js +2 -0
  346. package/form/form-select/form-select.js.map +1 -0
  347. package/form/form-select/index.d.ts +2 -0
  348. package/form/form-select/types.d.ts +10 -0
  349. package/form/form-select-histogram/form-select-histogram.js +2 -0
  350. package/form/form-select-histogram/form-select-histogram.js.map +1 -0
  351. package/form/form-select-histogram/index.d.ts +2 -0
  352. package/form/form-select-histogram/types.d.ts +8 -0
  353. package/form/form-slider/form-slider.js +2 -0
  354. package/form/form-slider/form-slider.js.map +1 -0
  355. package/form/form-slider/index.d.ts +2 -0
  356. package/form/form-slider/types.d.ts +8 -0
  357. package/form/form-textarea/form-textarea.js +2 -0
  358. package/form/form-textarea/form-textarea.js.map +1 -0
  359. package/form/form-textarea/form-textarea.styles.js +2 -0
  360. package/form/form-textarea/form-textarea.styles.js.map +1 -0
  361. package/form/form-textarea/form-textarea.styles_1kneyif.css +3 -0
  362. package/form/form-textarea/index.d.ts +2 -0
  363. package/form/form-textarea/types.d.ts +8 -0
  364. package/form/form-time-range-picker/form-time-range-picker.js +2 -0
  365. package/form/form-time-range-picker/form-time-range-picker.js.map +1 -0
  366. package/form/form-time-range-picker/index.d.ts +2 -0
  367. package/form/form-time-range-picker/types.d.ts +8 -0
  368. package/form/form-timepicker/form-timepicker.js +2 -0
  369. package/form/form-timepicker/form-timepicker.js.map +1 -0
  370. package/form/form-timepicker/index.d.ts +2 -0
  371. package/form/form-timepicker/types.d.ts +8 -0
  372. package/form/form-unit-number-input/form-unit-number-input.js +2 -0
  373. package/form/form-unit-number-input/form-unit-number-input.js.map +1 -0
  374. package/form/form-unit-number-input/index.d.ts +2 -0
  375. package/form/form-unit-number-input/types.d.ts +8 -0
  376. package/form/form-wrapper.js +1 -1
  377. package/form/form-wrapper.js.map +1 -1
  378. package/form/index.d.ts +47 -24
  379. package/form/index.js +1 -1
  380. package/form/index.js.map +1 -1
  381. package/form/types.d.ts +1 -208
  382. package/fullscreen-image-carousel/fullscreen-image-carousel.js.map +1 -1
  383. package/histogram-slider/histogram-slider.js.map +1 -1
  384. package/image-button/image-button.js.map +1 -1
  385. package/input/input.js.map +1 -1
  386. package/input-group/input-group.js.map +1 -1
  387. package/input-group/types.d.ts +1 -1
  388. package/input-multi-select/input-multi-select.js.map +1 -1
  389. package/input-multi-select/types.d.ts +1 -1
  390. package/input-nested-multi-select/input-nested-multi-select.js.map +1 -1
  391. package/input-nested-select/input-nested-select.js.map +1 -1
  392. package/input-nested-select/types.d.ts +1 -1
  393. package/input-range-select/input-range-select.js.map +1 -1
  394. package/input-range-select/types.d.ts +1 -1
  395. package/input-range-slider/input-range-slider.js.map +1 -1
  396. package/input-select/input-select.js.map +1 -1
  397. package/input-select/types.d.ts +1 -1
  398. package/input-slider/input-slider.js.map +1 -1
  399. package/input-slider/types.d.ts +1 -1
  400. package/input-textarea/textarea.js.map +1 -1
  401. package/input-textarea/textarea.styles.js +1 -1
  402. package/input-textarea/textarea.styles.js.map +1 -1
  403. package/input-textarea/{textarea.styles_22z4n3.css → textarea.styles_q77m5x.css} +1 -1
  404. package/language-switcher/language-switcher.js.map +1 -1
  405. package/layout/index.js.map +1 -1
  406. package/link-list/components/common.d.ts +1 -1
  407. package/link-list/components/common.js.map +1 -1
  408. package/link-list/components/link-list-eager.d.ts +2 -2
  409. package/link-list/components/link-list-eager.js.map +1 -1
  410. package/link-list/components/link-list-lazy.d.ts +2 -2
  411. package/link-list/components/link-list-lazy.js.map +1 -1
  412. package/link-list/link-list.js.map +1 -1
  413. package/link-list/types.d.ts +89 -3
  414. package/local-nav/local-nav-dropdown/local-nav-dropdown.js.map +1 -1
  415. package/local-nav/local-nav-menu/local-nav-menu.js.map +1 -1
  416. package/markup/markup.js.map +1 -1
  417. package/masked-input/masked-input.js.map +1 -1
  418. package/masthead/masthead.js.map +1 -1
  419. package/menu/menu.js.map +1 -1
  420. package/menu/types.d.ts +17 -1
  421. package/modal/index.js.map +1 -1
  422. package/modal/types.d.ts +3 -1
  423. package/modal-v2/modal-v2.js.map +1 -1
  424. package/modal-v2/types.d.ts +17 -0
  425. package/navbar/navbar.js.map +1 -1
  426. package/navbar/types.d.ts +1 -0
  427. package/notification-banner/notification-banner.js.map +1 -1
  428. package/otp-input/otp-input.js +1 -1
  429. package/otp-input/otp-input.js.map +1 -1
  430. package/otp-input/types.d.ts +14 -9
  431. package/otp-verification/contact-input-section.js +1 -1
  432. package/otp-verification/contact-input-section.js.map +1 -1
  433. package/otp-verification/otp-verification.js.map +1 -1
  434. package/otp-verification/verification-section.js +1 -1
  435. package/otp-verification/verification-section.js.map +1 -1
  436. package/overlay/overlay.js.map +1 -1
  437. package/package.json +1 -1
  438. package/pagination/pagination.js.map +1 -1
  439. package/phone-number-input/phone-number-input.js.map +1 -1
  440. package/pill/pill.js.map +1 -1
  441. package/popover/popover-inline/index.d.ts +1 -0
  442. package/popover/popover-inline/popover-inline.d.ts +1 -1
  443. package/popover/popover-inline/popover-inline.js.map +1 -1
  444. package/popover/popover-inline/types.d.ts +36 -0
  445. package/popover/popover.js.map +1 -1
  446. package/popover/types.d.ts +2 -35
  447. package/predictive-text-input/predictive-text-input.js +1 -1
  448. package/predictive-text-input/predictive-text-input.js.map +1 -1
  449. package/predictive-text-input/types.d.ts +1 -1
  450. package/progress-indicator/progress-indicator.js.map +1 -1
  451. package/radio-button/radio-button.js.map +1 -1
  452. package/radio-button/types.d.ts +3 -0
  453. package/schedule/schedule.js.map +1 -1
  454. package/select-histogram/select-histogram.js.map +1 -1
  455. package/select-histogram/types.d.ts +1 -1
  456. package/shared/dropdown-list/dropdown-list.js +1 -1
  457. package/shared/dropdown-list/dropdown-list.js.map +1 -1
  458. package/shared/dropdown-wrapper/element-with-dropdown.d.ts +5 -4
  459. package/shared/dropdown-wrapper/element-with-dropdown.js +1 -1
  460. package/shared/dropdown-wrapper/element-with-dropdown.js.map +1 -1
  461. package/sidenav/sidenav.js.map +1 -1
  462. package/sidenav/types.d.ts +1 -0
  463. package/singpass-button/singpass-button.js.map +1 -1
  464. package/smart-app-banner/smart-app-banner.js.map +1 -1
  465. package/smart-app-banner/types.d.ts +2 -0
  466. package/tab/tab.js.map +1 -1
  467. package/table/table.d.ts +9 -8
  468. package/table/table.js.map +1 -1
  469. package/table/types.d.ts +35 -0
  470. package/tag/tag.js.map +1 -1
  471. package/text-list/index.js.map +1 -1
  472. package/theme/theme-provider/hooks.js.map +1 -1
  473. package/theme/theme-provider/index.js.map +1 -1
  474. package/theme/tokens/border.d.ts +9 -3
  475. package/theme/tokens/border.js.map +1 -1
  476. package/theme/tokens/breakpoint.js.map +1 -1
  477. package/theme/tokens/colour.d.ts +9 -3
  478. package/theme/tokens/colour.js.map +1 -1
  479. package/theme/tokens/component.d.ts +3 -1
  480. package/theme/tokens/component.js.map +1 -1
  481. package/theme/tokens/font.d.ts +6 -2
  482. package/theme/tokens/font.js.map +1 -1
  483. package/theme/tokens/media-query.d.ts +3 -1
  484. package/theme/tokens/media-query.js.map +1 -1
  485. package/theme/tokens/motion.d.ts +3 -1
  486. package/theme/tokens/motion.js.map +1 -1
  487. package/theme/tokens/radius.d.ts +3 -1
  488. package/theme/tokens/radius.js.map +1 -1
  489. package/theme/tokens/shadow.d.ts +3 -1
  490. package/theme/tokens/shadow.js.map +1 -1
  491. package/theme/tokens/spacing.d.ts +3 -1
  492. package/theme/tokens/spacing.js.map +1 -1
  493. package/theme/utils/use-apply-styles.js.map +1 -1
  494. package/theme/utils/use-design-token.js.map +1 -1
  495. package/theme/utils/use-media-query.js.map +1 -1
  496. package/time-range-picker/combobox-picker/combobox-picker.js +1 -1
  497. package/time-range-picker/combobox-picker/combobox-picker.js.map +1 -1
  498. package/time-range-picker/time-range-picker.js.map +1 -1
  499. package/time-range-picker/types.d.ts +1 -1
  500. package/time-slot-bar/time-slot-bar.js.map +1 -1
  501. package/time-slot-bar/types.d.ts +5 -1
  502. package/time-slot-bar-week/time-slot-bar-week.js.map +1 -1
  503. package/time-slot-bar-week/types.d.ts +6 -0
  504. package/time-slot-week-view/time-slot-week-view.js.map +1 -1
  505. package/time-slot-week-view/types.d.ts +2 -0
  506. package/timeline/timeline.js.map +1 -1
  507. package/timeline/types.d.ts +1 -1
  508. package/timepicker/timepicker.js.map +1 -1
  509. package/timepicker/types.d.ts +2 -2
  510. package/timetable/timetable.js.map +1 -1
  511. package/toast/toast.js.map +1 -1
  512. package/toast/types.d.ts +2 -0
  513. package/toggle/toggle.js.map +1 -1
  514. package/tools/shared/generated-file-formatter.d.ts +6 -0
  515. package/tools/shared/jsdoc-parser.d.ts +36 -0
  516. package/tools/shared/ts-morph-project-factory.d.ts +9 -0
  517. package/tools/shared/typescript-source-provider.d.ts +9 -0
  518. package/tools/storybook-argtypes/adapters/file-system-adapter.d.ts +69 -0
  519. package/tools/storybook-argtypes/arg-types-generator.d.ts +85 -0
  520. package/tools/storybook-argtypes/config/arg-types-config.d.ts +31 -0
  521. package/tools/storybook-argtypes/index.d.ts +11 -0
  522. package/tools/storybook-argtypes/services/arg-types-row-builder.d.ts +43 -0
  523. package/tools/storybook-argtypes/services/file-path-resolver.d.ts +118 -0
  524. package/tools/storybook-argtypes/services/index.d.ts +6 -0
  525. package/tools/storybook-argtypes/services/jsdoc-metadata-extractor.d.ts +33 -0
  526. package/tools/storybook-argtypes/services/story-registry-generator.d.ts +27 -0
  527. package/tools/storybook-argtypes/services/type-dependency-resolver.d.ts +46 -0
  528. package/tools/storybook-argtypes/services/type-formatting-service.d.ts +27 -0
  529. package/tools/storybook-argtypes/types.d.ts +102 -0
  530. package/typography/index.js.map +1 -1
  531. package/uneditable-section/index.js.map +1 -1
  532. package/uneditable-section/section-item.js +1 -1
  533. package/uneditable-section/section-item.js.map +1 -1
  534. package/uneditable-section/types.d.ts +2 -2
  535. package/unit-number/unit-number-input.js.map +1 -1
  536. package/cjs/form/form-custom-field.js +0 -2
  537. package/cjs/form/form-custom-field.js.map +0 -1
  538. package/cjs/form/form-date-input.js +0 -2
  539. package/cjs/form/form-date-input.js.map +0 -1
  540. package/cjs/form/form-date-range-input.js +0 -2
  541. package/cjs/form/form-date-range-input.js.map +0 -1
  542. package/cjs/form/form-e-signature.js +0 -2
  543. package/cjs/form/form-e-signature.js.map +0 -1
  544. package/cjs/form/form-histogram.js +0 -2
  545. package/cjs/form/form-histogram.js.map +0 -1
  546. package/cjs/form/form-input-group.js +0 -2
  547. package/cjs/form/form-input-group.js.map +0 -1
  548. package/cjs/form/form-input.js +0 -2
  549. package/cjs/form/form-input.js.map +0 -1
  550. package/cjs/form/form-label-addon.js +0 -2
  551. package/cjs/form/form-label-addon.js.map +0 -1
  552. package/cjs/form/form-label-addon.styles.js +0 -2
  553. package/cjs/form/form-label-addon.styles.js.map +0 -1
  554. package/cjs/form/form-label-addon.styles_b00z8p.css +0 -1
  555. package/cjs/form/form-label.js +0 -2
  556. package/cjs/form/form-label.js.map +0 -1
  557. package/cjs/form/form-label.styles.js +0 -2
  558. package/cjs/form/form-label.styles.js.map +0 -1
  559. package/cjs/form/form-label.styles_1nbe0bm.css +0 -6
  560. package/cjs/form/form-masked-input.js +0 -2
  561. package/cjs/form/form-masked-input.js.map +0 -1
  562. package/cjs/form/form-multi-select.js +0 -2
  563. package/cjs/form/form-multi-select.js.map +0 -1
  564. package/cjs/form/form-nested-multi-select.js +0 -2
  565. package/cjs/form/form-nested-multi-select.js.map +0 -1
  566. package/cjs/form/form-nested-select.js +0 -2
  567. package/cjs/form/form-nested-select.js.map +0 -1
  568. package/cjs/form/form-otp-verification.js +0 -2
  569. package/cjs/form/form-otp-verification.js.map +0 -1
  570. package/cjs/form/form-phone-number-input.js +0 -2
  571. package/cjs/form/form-phone-number-input.js.map +0 -1
  572. package/cjs/form/form-predictive-text-input.js +0 -2
  573. package/cjs/form/form-predictive-text-input.js.map +0 -1
  574. package/cjs/form/form-range-select.js +0 -2
  575. package/cjs/form/form-range-select.js.map +0 -1
  576. package/cjs/form/form-range-slider.js +0 -2
  577. package/cjs/form/form-range-slider.js.map +0 -1
  578. package/cjs/form/form-select-histogram.js +0 -2
  579. package/cjs/form/form-select-histogram.js.map +0 -1
  580. package/cjs/form/form-select.js +0 -2
  581. package/cjs/form/form-select.js.map +0 -1
  582. package/cjs/form/form-slider.js +0 -2
  583. package/cjs/form/form-slider.js.map +0 -1
  584. package/cjs/form/form-textarea.js +0 -2
  585. package/cjs/form/form-textarea.js.map +0 -1
  586. package/cjs/form/form-textarea.styles.js +0 -2
  587. package/cjs/form/form-textarea.styles.js.map +0 -1
  588. package/cjs/form/form-textarea.styles_3p9qoy.css +0 -3
  589. package/cjs/form/form-time-range-picker.js +0 -2
  590. package/cjs/form/form-time-range-picker.js.map +0 -1
  591. package/cjs/form/form-timepicker.js +0 -2
  592. package/cjs/form/form-timepicker.js.map +0 -1
  593. package/cjs/form/form-unit-number-input.js +0 -2
  594. package/cjs/form/form-unit-number-input.js.map +0 -1
  595. package/form/form-custom-field.js +0 -2
  596. package/form/form-custom-field.js.map +0 -1
  597. package/form/form-date-input.js +0 -2
  598. package/form/form-date-input.js.map +0 -1
  599. package/form/form-date-range-input.js +0 -2
  600. package/form/form-date-range-input.js.map +0 -1
  601. package/form/form-e-signature.js +0 -2
  602. package/form/form-e-signature.js.map +0 -1
  603. package/form/form-histogram.js +0 -2
  604. package/form/form-histogram.js.map +0 -1
  605. package/form/form-input-group.js +0 -2
  606. package/form/form-input-group.js.map +0 -1
  607. package/form/form-input.js +0 -2
  608. package/form/form-input.js.map +0 -1
  609. package/form/form-label-addon.js +0 -2
  610. package/form/form-label-addon.js.map +0 -1
  611. package/form/form-label-addon.styles.js +0 -2
  612. package/form/form-label-addon.styles.js.map +0 -1
  613. package/form/form-label-addon.styles_b00z8p.css +0 -1
  614. package/form/form-label.js +0 -2
  615. package/form/form-label.js.map +0 -1
  616. package/form/form-label.styles.js +0 -2
  617. package/form/form-label.styles.js.map +0 -1
  618. package/form/form-label.styles_1nbe0bm.css +0 -6
  619. package/form/form-masked-input.js +0 -2
  620. package/form/form-masked-input.js.map +0 -1
  621. package/form/form-multi-select.js +0 -2
  622. package/form/form-multi-select.js.map +0 -1
  623. package/form/form-nested-multi-select.js +0 -2
  624. package/form/form-nested-multi-select.js.map +0 -1
  625. package/form/form-nested-select.js +0 -2
  626. package/form/form-nested-select.js.map +0 -1
  627. package/form/form-otp-verification.js +0 -2
  628. package/form/form-otp-verification.js.map +0 -1
  629. package/form/form-phone-number-input.js +0 -2
  630. package/form/form-phone-number-input.js.map +0 -1
  631. package/form/form-predictive-text-input.js +0 -2
  632. package/form/form-predictive-text-input.js.map +0 -1
  633. package/form/form-range-select.js +0 -2
  634. package/form/form-range-select.js.map +0 -1
  635. package/form/form-range-slider.js +0 -2
  636. package/form/form-range-slider.js.map +0 -1
  637. package/form/form-select-histogram.js +0 -2
  638. package/form/form-select-histogram.js.map +0 -1
  639. package/form/form-select.js +0 -2
  640. package/form/form-select.js.map +0 -1
  641. package/form/form-slider.js +0 -2
  642. package/form/form-slider.js.map +0 -1
  643. package/form/form-textarea.js +0 -2
  644. package/form/form-textarea.js.map +0 -1
  645. package/form/form-textarea.styles.js +0 -2
  646. package/form/form-textarea.styles.js.map +0 -1
  647. package/form/form-textarea.styles_3p9qoy.css +0 -3
  648. package/form/form-time-range-picker.js +0 -2
  649. package/form/form-time-range-picker.js.map +0 -1
  650. package/form/form-timepicker.js +0 -2
  651. package/form/form-timepicker.js.map +0 -1
  652. package/form/form-unit-number-input.js +0 -2
  653. package/form/form-unit-number-input.js.map +0 -1
  654. package/link-list/internal-types.d.ts +0 -85
  655. /package/{codemod-utils.d.ts → codemods/codemod-utils.d.ts} +0 -0
  656. /package/{migrate-popover → codemods/migrate-popover}/index.d.ts +0 -0
  657. /package/{run-codemod.d.ts → codemods/run-codemod.d.ts} +0 -0
  658. /package/form/{form-custom-field.d.ts → form-custom-field/form-custom-field.d.ts} +0 -0
  659. /package/form/{form-date-input.d.ts → form-date-input/form-date-input.d.ts} +0 -0
  660. /package/form/{form-date-range-input.d.ts → form-date-range-input/form-date-range-input.d.ts} +0 -0
  661. /package/form/{form-e-signature.d.ts → form-e-signature/form-e-signature.d.ts} +0 -0
  662. /package/form/{form-histogram.d.ts → form-histogram-slider/form-histogram-slider.d.ts} +0 -0
  663. /package/form/{form-input.d.ts → form-input/form-input.d.ts} +0 -0
  664. /package/form/{form-input-group.d.ts → form-input-group/form-input-group.d.ts} +0 -0
  665. /package/form/{form-label-addon.d.ts → form-label/form-label-addon.d.ts} +0 -0
  666. /package/form/{form-label-addon.styles.d.ts → form-label/form-label-addon.styles.d.ts} +0 -0
  667. /package/form/{form-label.d.ts → form-label/form-label.d.ts} +0 -0
  668. /package/form/{form-label.styles.d.ts → form-label/form-label.styles.d.ts} +0 -0
  669. /package/form/{form-masked-input.d.ts → form-masked-input/form-masked-input.d.ts} +0 -0
  670. /package/form/{form-multi-select.d.ts → form-multi-select/form-multi-select.d.ts} +0 -0
  671. /package/form/{form-nested-multi-select.d.ts → form-nested-multi-select/form-nested-multi-select.d.ts} +0 -0
  672. /package/form/{form-nested-select.d.ts → form-nested-select/form-nested-select.d.ts} +0 -0
  673. /package/form/{form-phone-number-input.d.ts → form-phone-number-input/form-phone-number-input.d.ts} +0 -0
  674. /package/form/{form-predictive-text-input.d.ts → form-predictive-text-input/form-predictive-text-input.d.ts} +0 -0
  675. /package/form/{form-range-select.d.ts → form-range-select/form-range-select.d.ts} +0 -0
  676. /package/form/{form-range-slider.d.ts → form-range-slider/form-range-slider.d.ts} +0 -0
  677. /package/form/{form-select.d.ts → form-select/form-select.d.ts} +0 -0
  678. /package/form/{form-select-histogram.d.ts → form-select-histogram/form-select-histogram.d.ts} +0 -0
  679. /package/form/{form-slider.d.ts → form-slider/form-slider.d.ts} +0 -0
  680. /package/form/{form-textarea.d.ts → form-textarea/form-textarea.d.ts} +0 -0
  681. /package/form/{form-textarea.styles.d.ts → form-textarea/form-textarea.styles.d.ts} +0 -0
  682. /package/form/{form-time-range-picker.d.ts → form-time-range-picker/form-time-range-picker.d.ts} +0 -0
  683. /package/form/{form-timepicker.d.ts → form-timepicker/form-timepicker.d.ts} +0 -0
  684. /package/form/{form-unit-number-input.d.ts → form-unit-number-input/form-unit-number-input.d.ts} +0 -0
@@ -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/**\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","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
+ {"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","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 +1 @@
1
- {"version":3,"file":"toast.js","sources":["../../src/toast/toast.tsx"],"sourcesContent":["import {\n CrossIcon,\n ExclamationCircleFillIcon,\n ExclamationTriangleFillIcon,\n ICircleFillIcon,\n TickCircleFillIcon,\n} from \"@lifesg/react-icons\";\nimport { animated, easings, useSpring } from \"@react-spring/web\";\nimport clsx from \"clsx\";\nimport React, { useEffect, useRef, useState } from \"react\";\n\nimport { Button } from \"../button\";\nimport { inertValue, VisuallyHidden } from \"../shared/accessibility\";\nimport { ClickableIcon } from \"../shared/clickable-icon\";\nimport { useMaxWidthMediaQuery } from \"../theme\";\nimport { Typography } from \"../typography\";\nimport * as styles from \"./toast.styles\";\nimport type { ToastProps } from \"./types\";\n\nconst DEFAULT_AUTO_DISMISS_TIME = 4000;\nconst EASING_DURATION = 1000;\n\nconst TOAST_ICON_MAP = {\n success: TickCircleFillIcon,\n warning: ExclamationTriangleFillIcon,\n error: ExclamationCircleFillIcon,\n info: ICircleFillIcon,\n};\n\n/**\n * A brief notification that appears on screen to provide feedback about an\n * operation or event.\n *\n * Use `Toast` to surface status messages without interrupting the user's workflow.\n */\nexport const Toast = ({\n type = \"success\",\n title,\n label,\n className,\n autoDismiss,\n autoDismissTime = DEFAULT_AUTO_DISMISS_TIME,\n onDismiss,\n fixed = true,\n actionButton,\n ...otherProps\n}: ToastProps) => {\n // =============================================================================\n // CONST, STATE\n // =============================================================================\n const toastRef = useRef<HTMLDivElement>(null);\n const [isVisible, setVisible] = useState<boolean>(false);\n\n const isMobile = useMaxWidthMediaQuery(\"lg\");\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n setVisible(true);\n }, []);\n\n useEffect(() => {\n if (!autoDismiss) return;\n\n const timeout = setTimeout(() => {\n setVisible(false);\n }, autoDismissTime);\n\n return () => clearTimeout(timeout);\n }, [autoDismiss, autoDismissTime]);\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (\n event.key === \"Escape\" &&\n toastRef.current?.contains(document.activeElement)\n ) {\n handleDismiss();\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, []);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleDismiss = () => {\n setVisible(false);\n };\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n const transitions = useSpring({\n opacity: isVisible ? 1 : 0,\n transform: isVisible\n ? isMobile\n ? `translateY(0%)`\n : `translateX(0%)`\n : isMobile\n ? `translateY(-1500%)`\n : `translateX(150%)`,\n config: {\n easing: easings.easeInOutQuart,\n duration: EASING_DURATION,\n },\n onRest: () => {\n if (!isVisible) onDismiss?.();\n },\n });\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderIcon = () => {\n const Icon = TOAST_ICON_MAP[type];\n return Icon && <Icon aria-hidden />;\n };\n\n const renderTitle = () => {\n if (React.isValidElement(title)) {\n return title;\n } else {\n return (\n <h2 className={styles.title} role=\"presentation\">\n {title}\n </h2>\n );\n }\n };\n\n const renderDesc = () => {\n if (React.isValidElement(label)) {\n return label;\n } else if (title) {\n return (\n <Typography.BodyMD className={styles.description}>\n {label}\n </Typography.BodyMD>\n );\n } else {\n return (\n <Typography.BodyBL className={styles.description}>\n {label}\n </Typography.BodyBL>\n );\n }\n };\n\n return (\n <animated.div\n ref={toastRef}\n style={transitions}\n className={clsx(styles.wrapper, className)}\n data-type={type}\n data-fixed={fixed}\n role=\"alert\"\n inert={inertValue(!isVisible)}\n {...otherProps}\n >\n <VisuallyHidden>{type}</VisuallyHidden>\n <div className={styles.contentWrapper}>\n <div className={styles.textIconWrapper} data-type={type}>\n {renderIcon()}\n <div className={styles.textContainer}>\n {title && renderTitle()}\n {label && renderDesc()}\n </div>\n </div>\n\n {actionButton && (\n <Button\n className={styles.actionButton}\n styleType=\"light\"\n onClick={actionButton.onClick}\n sizeType=\"small\"\n >\n {actionButton.label}\n </Button>\n )}\n </div>\n <ClickableIcon\n className={styles.dismissButton}\n onClick={handleDismiss}\n >\n <VisuallyHidden role=\"presentation\">\n Close notification\n </VisuallyHidden>\n <CrossIcon aria-hidden />\n </ClickableIcon>\n </animated.div>\n );\n};\n"],"names":["DEFAULT_AUTO_DISMISS_TIME","TOAST_ICON_MAP","success","TickCircleFillIcon","warning","ExclamationTriangleFillIcon","error","ExclamationCircleFillIcon","info","ICircleFillIcon","Toast","_a","type","title","label","className","autoDismiss","autoDismissTime","onDismiss","fixed","actionButton","otherProps","__rest","toastRef","useRef","isVisible","setVisible","useState","isMobile","useMaxWidthMediaQuery","useEffect","timeout","setTimeout","clearTimeout","handleKeyDown","event","key","current","contains","document","activeElement","handleDismiss","addEventListener","removeEventListener","transitions","useSpring","opacity","transform","config","easing","easings","easeInOutQuart","duration","onRest","_jsxs","animated","div","Object","assign","ref","style","clsx","styles.wrapper","role","inert","inertValue","children","_jsx","VisuallyHidden","styles.contentWrapper","styles.textIconWrapper","Icon","renderIcon","styles.textContainer","React","isValidElement","styles.title","Typography","BodyMD","BodyBL","styles.description","Button","styles.actionButton","styleType","onClick","sizeType","ClickableIcon","styles.dismissButton","CrossIcon"],"mappings":"+xCAmBA,MAAMA,EAA4B,IAG5BC,EAAiB,CACnBC,QAASC,EACTC,QAASC,EACTC,MAAOC,EACPC,KAAMC,GASGC,EAASC,IAAA,IAAAC,KAClBA,EAAO,gBACPC,EAAKC,MACLA,EAAKC,UACLA,EAASC,YACTA,EAAWC,gBACXA,EAAkBjB,EAAyBkB,UAC3CA,EAASC,MACTA,GAAQ,EAAIC,aACZA,GAAYT,EACTU,EAAUC,EAAAX,EAVK,CAAA,OAAA,QAAA,QAAA,YAAA,cAAA,kBAAA,YAAA,QAAA,iBAelB,MAAMY,EAAWC,EAAuB,OACjCC,EAAWC,GAAcC,GAAkB,GAE5CC,EAAWC,EAAsB,MAKvCC,GAAU,KACNJ,GAAW,EAAK,GACjB,IAEHI,GAAU,KACN,IAAKd,EAAa,OAElB,MAAMe,EAAUC,YAAW,KACvBN,GAAW,EAAM,GAClBT,GAEH,MAAO,IAAMgB,aAAaF,EAAQ,GACnC,CAACf,EAAaC,IAEjBa,GAAU,KACN,MAAMI,EAAiBC,UAED,WAAdA,EAAMC,MACU,QAAhBzB,EAAAY,EAASc,eAAO,IAAA1B,OAAA,EAAAA,EAAE2B,SAASC,SAASC,iBAEpCC,GACJ,EAIJ,OADAF,SAASG,iBAAiB,UAAWR,GAC9B,KACHK,SAASI,oBAAoB,UAAWT,EAAc,CACzD,GACF,IAKH,MAAMO,EAAgB,KAClBf,GAAW,EAAM,EAMfkB,EAAcC,EAAU,CAC1BC,QAASrB,EAAY,EAAI,EACzBsB,UAAWtB,EACLG,EACI,iBACA,iBACJA,EACA,qBACA,mBACNoB,OAAQ,CACJC,OAAQC,EAAQC,eAChBC,SAzFY,KA2FhBC,OAAQ,KACC5B,GAAWP,SAAAA,GAAa,IA0CrC,OACIoC,EAACC,EAASC,IAAGC,OAAAC,OAAA,CACTC,IAAKpC,EACLqC,MAAOhB,EACP7B,UAAW8C,EAAKC,EAAgB/C,GAAU,YAC/BH,EAAI,aACHO,EACZ4C,KAAK,QACLC,MAAOC,GAAYxC,IACfJ,EAAU,CAAA6C,SAAA,CAEdC,EAACC,EAAc,CAAAF,SAAEtD,IACjB0C,EAAA,MAAA,CAAKvC,UAAWsD,EAAqBH,SAAA,CACjCZ,EAAA,MAAA,CAAKvC,UAAWuD,EAAsB,YAAa1D,EAAIsD,SAAA,CAhDhD,MACf,MAAMK,EAAOtE,EAAeW,GAC5B,OAAO2D,GAAQJ,EAACI,qBAAmB,EA+CtBC,GACDlB,EAAA,MAAA,CAAKvC,UAAW0D,EAAoBP,SAAA,CAC/BrD,IA7Cb6D,EAAMC,eAAe9D,GACdA,EAGHsD,EAAA,KAAA,CAAIpD,UAAW6D,EAAcb,KAAK,eAAcG,SAC3CrD,KAyCIC,IAlCb4D,EAAMC,eAAe7D,GACdA,EAGHqD,EAFGtD,EAEFgE,EAAWC,OAMXD,EAAWE,OANM,CAAChE,UAAWiE,EAAkBd,SAC3CpD,WAiCJM,GACG+C,EAACc,EAAM,CACHlE,UAAWmE,EACXC,UAAU,QACVC,QAAShE,EAAagE,QACtBC,SAAS,QAAOnB,SAEf9C,EAAaN,WAI1BwC,EAACgC,GACGvE,UAAWwE,EACXH,QAAS3C,EAAayB,SAAA,CAEtBC,EAACC,EAAc,CAACL,KAAK,eAAcG,SAAA,uBAGnCC,EAACqB,EAAS,CAAA,eAAA,UAEH"}
1
+ {"version":3,"file":"toast.js","sources":["../../src/toast/toast.tsx"],"sourcesContent":["import {\n CrossIcon,\n ExclamationCircleFillIcon,\n ExclamationTriangleFillIcon,\n ICircleFillIcon,\n TickCircleFillIcon,\n} from \"@lifesg/react-icons\";\nimport { animated, easings, useSpring } from \"@react-spring/web\";\nimport clsx from \"clsx\";\nimport React, { useEffect, useRef, useState } from \"react\";\n\nimport { Button } from \"../button\";\nimport { inertValue, VisuallyHidden } from \"../shared/accessibility\";\nimport { ClickableIcon } from \"../shared/clickable-icon\";\nimport { useMaxWidthMediaQuery } from \"../theme\";\nimport { Typography } from \"../typography\";\nimport * as styles from \"./toast.styles\";\nimport type { ToastProps } from \"./types\";\n\nconst DEFAULT_AUTO_DISMISS_TIME = 4000;\nconst EASING_DURATION = 1000;\n\nconst TOAST_ICON_MAP = {\n success: TickCircleFillIcon,\n warning: ExclamationTriangleFillIcon,\n error: ExclamationCircleFillIcon,\n info: ICircleFillIcon,\n};\n\n// @catalog\n/**\n * A brief notification that appears on screen to provide feedback about an\n * operation or event.\n *\n * Use `Toast` to surface status messages without interrupting the user's workflow.\n */\nexport const Toast = ({\n type = \"success\",\n title,\n label,\n className,\n autoDismiss,\n autoDismissTime = DEFAULT_AUTO_DISMISS_TIME,\n onDismiss,\n fixed = true,\n actionButton,\n ...otherProps\n}: ToastProps) => {\n // =============================================================================\n // CONST, STATE\n // =============================================================================\n const toastRef = useRef<HTMLDivElement>(null);\n const [isVisible, setVisible] = useState<boolean>(false);\n\n const isMobile = useMaxWidthMediaQuery(\"lg\");\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n setVisible(true);\n }, []);\n\n useEffect(() => {\n if (!autoDismiss) return;\n\n const timeout = setTimeout(() => {\n setVisible(false);\n }, autoDismissTime);\n\n return () => clearTimeout(timeout);\n }, [autoDismiss, autoDismissTime]);\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (\n event.key === \"Escape\" &&\n toastRef.current?.contains(document.activeElement)\n ) {\n handleDismiss();\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, []);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleDismiss = () => {\n setVisible(false);\n };\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n const transitions = useSpring({\n opacity: isVisible ? 1 : 0,\n transform: isVisible\n ? isMobile\n ? `translateY(0%)`\n : `translateX(0%)`\n : isMobile\n ? `translateY(-1500%)`\n : `translateX(150%)`,\n config: {\n easing: easings.easeInOutQuart,\n duration: EASING_DURATION,\n },\n onRest: () => {\n if (!isVisible) onDismiss?.();\n },\n });\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderIcon = () => {\n const Icon = TOAST_ICON_MAP[type];\n return Icon && <Icon aria-hidden />;\n };\n\n const renderTitle = () => {\n if (React.isValidElement(title)) {\n return title;\n } else {\n return (\n <h2 className={styles.title} role=\"presentation\">\n {title}\n </h2>\n );\n }\n };\n\n const renderDesc = () => {\n if (React.isValidElement(label)) {\n return label;\n } else if (title) {\n return (\n <Typography.BodyMD className={styles.description}>\n {label}\n </Typography.BodyMD>\n );\n } else {\n return (\n <Typography.BodyBL className={styles.description}>\n {label}\n </Typography.BodyBL>\n );\n }\n };\n\n return (\n <animated.div\n ref={toastRef}\n style={transitions}\n className={clsx(styles.wrapper, className)}\n data-type={type}\n data-fixed={fixed}\n role=\"alert\"\n inert={inertValue(!isVisible)}\n {...otherProps}\n >\n <VisuallyHidden>{type}</VisuallyHidden>\n <div className={styles.contentWrapper}>\n <div className={styles.textIconWrapper} data-type={type}>\n {renderIcon()}\n <div className={styles.textContainer}>\n {title && renderTitle()}\n {label && renderDesc()}\n </div>\n </div>\n\n {actionButton && (\n <Button\n className={styles.actionButton}\n styleType=\"light\"\n onClick={actionButton.onClick}\n sizeType=\"small\"\n >\n {actionButton.label}\n </Button>\n )}\n </div>\n <ClickableIcon\n className={styles.dismissButton}\n onClick={handleDismiss}\n >\n <VisuallyHidden role=\"presentation\">\n Close notification\n </VisuallyHidden>\n <CrossIcon aria-hidden />\n </ClickableIcon>\n </animated.div>\n );\n};\n"],"names":["DEFAULT_AUTO_DISMISS_TIME","TOAST_ICON_MAP","success","TickCircleFillIcon","warning","ExclamationTriangleFillIcon","error","ExclamationCircleFillIcon","info","ICircleFillIcon","Toast","_a","type","title","label","className","autoDismiss","autoDismissTime","onDismiss","fixed","actionButton","otherProps","__rest","toastRef","useRef","isVisible","setVisible","useState","isMobile","useMaxWidthMediaQuery","useEffect","timeout","setTimeout","clearTimeout","handleKeyDown","event","key","current","contains","document","activeElement","handleDismiss","addEventListener","removeEventListener","transitions","useSpring","opacity","transform","config","easing","easings","easeInOutQuart","duration","onRest","_jsxs","animated","div","Object","assign","ref","style","clsx","styles.wrapper","role","inert","inertValue","children","_jsx","VisuallyHidden","styles.contentWrapper","styles.textIconWrapper","Icon","renderIcon","styles.textContainer","React","isValidElement","styles.title","Typography","BodyMD","BodyBL","styles.description","Button","styles.actionButton","styleType","onClick","sizeType","ClickableIcon","styles.dismissButton","CrossIcon"],"mappings":"+xCAmBA,MAAMA,EAA4B,IAG5BC,EAAiB,CACnBC,QAASC,EACTC,QAASC,EACTC,MAAOC,EACPC,KAAMC,GAUGC,EAASC,IAAA,IAAAC,KAClBA,EAAO,gBACPC,EAAKC,MACLA,EAAKC,UACLA,EAASC,YACTA,EAAWC,gBACXA,EAAkBjB,EAAyBkB,UAC3CA,EAASC,MACTA,GAAQ,EAAIC,aACZA,GAAYT,EACTU,EAAUC,EAAAX,EAVK,CAAA,OAAA,QAAA,QAAA,YAAA,cAAA,kBAAA,YAAA,QAAA,iBAelB,MAAMY,EAAWC,EAAuB,OACjCC,EAAWC,GAAcC,GAAkB,GAE5CC,EAAWC,EAAsB,MAKvCC,GAAU,KACNJ,GAAW,EAAK,GACjB,IAEHI,GAAU,KACN,IAAKd,EAAa,OAElB,MAAMe,EAAUC,YAAW,KACvBN,GAAW,EAAM,GAClBT,GAEH,MAAO,IAAMgB,aAAaF,EAAQ,GACnC,CAACf,EAAaC,IAEjBa,GAAU,KACN,MAAMI,EAAiBC,UAED,WAAdA,EAAMC,MACU,QAAhBzB,EAAAY,EAASc,eAAO,IAAA1B,OAAA,EAAAA,EAAE2B,SAASC,SAASC,iBAEpCC,GACJ,EAIJ,OADAF,SAASG,iBAAiB,UAAWR,GAC9B,KACHK,SAASI,oBAAoB,UAAWT,EAAc,CACzD,GACF,IAKH,MAAMO,EAAgB,KAClBf,GAAW,EAAM,EAMfkB,EAAcC,EAAU,CAC1BC,QAASrB,EAAY,EAAI,EACzBsB,UAAWtB,EACLG,EACI,iBACA,iBACJA,EACA,qBACA,mBACNoB,OAAQ,CACJC,OAAQC,EAAQC,eAChBC,SA1FY,KA4FhBC,OAAQ,KACC5B,GAAWP,SAAAA,GAAa,IA0CrC,OACIoC,EAACC,EAASC,IAAGC,OAAAC,OAAA,CACTC,IAAKpC,EACLqC,MAAOhB,EACP7B,UAAW8C,EAAKC,EAAgB/C,GAAU,YAC/BH,EAAI,aACHO,EACZ4C,KAAK,QACLC,MAAOC,GAAYxC,IACfJ,EAAU,CAAA6C,SAAA,CAEdC,EAACC,EAAc,CAAAF,SAAEtD,IACjB0C,EAAA,MAAA,CAAKvC,UAAWsD,EAAqBH,SAAA,CACjCZ,EAAA,MAAA,CAAKvC,UAAWuD,EAAsB,YAAa1D,EAAIsD,SAAA,CAhDhD,MACf,MAAMK,EAAOtE,EAAeW,GAC5B,OAAO2D,GAAQJ,EAACI,qBAAmB,EA+CtBC,GACDlB,EAAA,MAAA,CAAKvC,UAAW0D,EAAoBP,SAAA,CAC/BrD,IA7Cb6D,EAAMC,eAAe9D,GACdA,EAGHsD,EAAA,KAAA,CAAIpD,UAAW6D,EAAcb,KAAK,eAAcG,SAC3CrD,KAyCIC,IAlCb4D,EAAMC,eAAe7D,GACdA,EAGHqD,EAFGtD,EAEFgE,EAAWC,OAMXD,EAAWE,OANM,CAAChE,UAAWiE,EAAkBd,SAC3CpD,WAiCJM,GACG+C,EAACc,EAAM,CACHlE,UAAWmE,EACXC,UAAU,QACVC,QAAShE,EAAagE,QACtBC,SAAS,QAAOnB,SAEf9C,EAAaN,WAI1BwC,EAACgC,GACGvE,UAAWwE,EACXH,QAAS3C,EAAayB,SAAA,CAEtBC,EAACC,EAAc,CAACL,KAAK,eAAcG,SAAA,uBAGnCC,EAACqB,EAAS,CAAA,eAAA,UAEH"}
package/toast/types.d.ts CHANGED
@@ -8,7 +8,9 @@ export type ToastType = "success" | "warning" | "error" | "info";
8
8
  * Configuration for the optional action button rendered inside a `Toast`.
9
9
  */
10
10
  export interface ToastActionButtonProps {
11
+ /** The label of the action button */
11
12
  label: string;
13
+ /** Called when the action button is clicked */
12
14
  onClick: () => void;
13
15
  }
14
16
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"toggle.js","sources":["../../src/toggle/toggle.tsx"],"sourcesContent":["import { ChevronDownIcon } from \"@lifesg/react-icons/chevron-down\";\nimport { ChevronUpIcon } from \"@lifesg/react-icons/chevron-up\";\nimport clsx from \"clsx\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { Alert } from \"../alert\";\nimport { Markup } from \"../markup\";\nimport { TextList } from \"../text-list\";\nimport { useApplyStyle } from \"../theme\";\nimport { Typography } from \"../typography\";\nimport { useId } from \"../util\";\nimport * as styles from \"./toggle.styles\";\nimport type { ToggleIconType } from \"./toggle-icon\";\nimport { ToggleIcon } from \"./toggle-icon\";\nimport type { ToggleProps } from \"./types\";\n\n/**\n * A selectable control for checkbox and radio interaction patterns.\n *\n * Use `Toggle` to present a labeled option that the user can select or\n * deselect.\n */\nexport const Toggle = ({\n type = \"checkbox\",\n indicator,\n checked,\n styleType = \"default\",\n children,\n childrenMaxLines,\n subLabel,\n disabled,\n error,\n name,\n id,\n className,\n compositeSection,\n removable,\n focusableWhenDisabled,\n useContentWidth,\n onRemove,\n onChange,\n \"data-testid\": testId,\n \"aria-describedby\": ariaDescribedBy,\n ...otherProps\n}: ToggleProps) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const {\n collapsible = true,\n errors,\n children: compositeSectionChildren,\n initialExpanded,\n } = compositeSection || {};\n const [selected, setSelected] = useState<boolean | undefined>(checked);\n const [expanded, setExpanded] = useState<boolean>(!!initialExpanded);\n const hasCompositeSectionError = useMemo(() => {\n const hasErrorList = Array.isArray(errors) && errors?.length > 0;\n const hasErrorElement = !Array.isArray(errors) && !!errors;\n return hasErrorList || hasErrorElement;\n }, [errors]);\n const uniqueId = useId();\n const generatedId = id ? `${id}` : `tg-${uniqueId}`;\n\n const inputRef = useRef<HTMLInputElement>(null);\n const labelRef = useRef<HTMLLabelElement>(null);\n\n useApplyStyle(labelRef, {\n [styles.tokens.label.desktopLineClamp]:\n childrenMaxLines?.desktop == null\n ? null\n : `${childrenMaxLines.desktop}`,\n [styles.tokens.label.tabletLineClamp]:\n childrenMaxLines?.tablet == null\n ? null\n : `${childrenMaxLines.tablet}`,\n [styles.tokens.label.mobileLineClamp]:\n childrenMaxLines?.mobile == null\n ? null\n : `${childrenMaxLines.mobile}`,\n });\n\n const isFocusableWhenDisabled = !!disabled && !!focusableWhenDisabled;\n const isNativeDisabled = !!disabled && !focusableWhenDisabled;\n const isInteractionBlocked = !!disabled;\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n setSelected(checked);\n }, [checked]);\n\n useEffect(() => {\n if (selected) {\n setExpanded(initialExpanded ?? true);\n }\n }, [selected]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleOnChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n if (isInteractionBlocked) {\n event.preventDefault();\n return;\n }\n\n if (onChange) {\n onChange(event);\n return;\n }\n\n switch (type) {\n case \"checkbox\":\n setSelected((prevSelected) => {\n return !prevSelected;\n });\n break;\n case \"radio\":\n case \"yes\":\n case \"no\":\n if (!selected) {\n setSelected(true);\n }\n break;\n }\n };\n\n const handleExpandCollapseClick = () => {\n if (!disabled) {\n setExpanded(!expanded);\n }\n };\n\n const handleOnRemove = () => {\n if (!disabled) {\n if (onRemove) {\n onRemove();\n return;\n }\n }\n };\n\n const handleContainerClick = () => {\n inputRef?.current?.click();\n };\n\n const handleInputClick = (e: React.MouseEvent<HTMLInputElement>) => {\n e.stopPropagation();\n };\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n\n const getContainerStateClass = () => {\n if (styleType === \"no-border\") {\n if (error) {\n return clsx(\n styles.colorBorderError,\n !disabled && styles.toggleContainerError\n );\n }\n\n if (disabled) {\n return selected\n ? styles.toggleContainerNoBorderDisabledSelected\n : styles.toggleContainerNoBorderDisabled;\n }\n\n if (selected) {\n return styles.toggleContainerNoBorderSelected;\n }\n\n return styles.toggleContainerNoBorder;\n }\n\n if (error) {\n return disabled\n ? styles.colorBorderError\n : styles.toggleContainerError;\n }\n\n if (disabled) {\n return selected\n ? styles.toggleContainerDisabledSelected\n : styles.toggleContainerDisabled;\n }\n\n if (selected) {\n return styles.toggleContainerSelected;\n }\n\n return styles.toggleContainer;\n };\n\n const getContainerHoverClass = () => {\n if (disabled) {\n return undefined;\n }\n\n if (!error && selected) {\n return styles.toggleContainerHoverSelected;\n }\n\n return styles.toggleContainerHoverDefault;\n };\n\n const getTextContainerStateClass = () => {\n if (disabled) {\n return selected\n ? styles.toggleTextContainerDisabledSelected\n : styles.colorTextDisabled;\n }\n\n if (selected) {\n return styles.toggleTextContainerSelected;\n }\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderIndicator = () => {\n let toggleIconType: ToggleIconType;\n\n switch (type) {\n case \"yes\":\n toggleIconType = \"tick\";\n break;\n case \"no\":\n toggleIconType = \"cross\";\n break;\n case \"checkbox\":\n case \"radio\":\n toggleIconType = type;\n break;\n }\n\n return (\n <ToggleIcon\n type={toggleIconType}\n active={selected}\n disabled={disabled}\n />\n );\n };\n\n const renderSubLabel = () => {\n if (!subLabel) {\n return null;\n }\n\n let component: string | JSX.Element;\n\n if (typeof subLabel === \"function\") {\n component = subLabel();\n } else {\n component = subLabel;\n }\n\n // Hide sublabel from screen readers as the main input already has aria-describedby that points to the sublabel\n return (\n <div\n data-id=\"toggle-sublabel\"\n id={`${generatedId}-sublabel`}\n aria-hidden\n className={styles.subLabel}\n >\n {component}\n </div>\n );\n };\n\n const renderCompositeChildren = () => {\n return (\n (!collapsible || expanded) && (\n <div\n data-id=\"toggle-composite-children\"\n className={clsx(\n styles.children,\n !collapsible && styles.childrenIsFinalItem,\n disabled && styles.colorTextDisabled\n )}\n >\n <Markup baseTextSize=\"body-md\">\n {compositeSectionChildren}\n </Markup>\n </div>\n )\n );\n };\n\n const renderExpandButton = () => {\n const collapsedWithoutErrors = !expanded && !hasCompositeSectionError;\n\n return (\n collapsible && (\n <button\n className={clsx(\n styles.expandButton,\n disabled && styles.disabledColorCursor,\n collapsedWithoutErrors &&\n styles.expandButtonPaddingTopRequired\n )}\n disabled={disabled}\n onClick={handleExpandCollapseClick}\n data-testid={expanded ? \"collapse-button\" : \"expand-button\"}\n >\n {expanded ? \"Show less\" : \"Show more\"}\n {expanded ? (\n <ChevronUpIcon aria-hidden />\n ) : (\n <ChevronDownIcon aria-hidden />\n )}\n </button>\n )\n );\n };\n\n const renderToggleWithRemoveButton = () => {\n const ariaDescriptions =\n [\n typeof subLabel === \"string\" ? `${generatedId}-sublabel` : null,\n ariaDescribedBy,\n ]\n .filter(Boolean)\n .join(\" \") || undefined;\n\n return (\n <div\n id={`${generatedId}-header-container`}\n className={styles.headerContainer}\n >\n <div\n className={clsx(\n styles.indicatorLabelContainer,\n removable && styles.indicatorLabelContainerAddPadding\n )}\n >\n <div\n id={`${generatedId}-input-container`}\n onClick={handleContainerClick}\n className={styles.inputContainer}\n >\n <input\n ref={inputRef}\n name={name}\n id={`${generatedId}-input`}\n type={type === \"checkbox\" ? \"checkbox\" : \"radio\"}\n data-testid=\"toggle-input\"\n className={clsx(\n styles.input,\n disabled && styles.toggleInputDisabled\n )}\n disabled={isNativeDisabled}\n aria-disabled={isFocusableWhenDisabled}\n onChange={handleOnChange}\n onClick={handleInputClick}\n checked={selected}\n tabIndex={isFocusableWhenDisabled ? 0 : undefined}\n aria-describedby={ariaDescriptions}\n {...otherProps}\n />\n {indicator && renderIndicator()}\n <div\n className={clsx(\n styles.textContainer,\n getTextContainerStateClass()\n )}\n >\n <label\n ref={labelRef}\n htmlFor={`${generatedId}-input`}\n data-testid={`toggle-label`}\n id={`${generatedId}-label`}\n className={clsx(\n styles.label,\n selected\n ? styles.toggleLabelSelected\n : styles.toggleLabelDefault\n )}\n >\n {children}\n </label>\n {subLabel && renderSubLabel()}\n </div>\n </div>\n </div>\n {removable && (\n <button\n type=\"button\"\n className={clsx(\n styles.removeButton,\n disabled && styles.disabledColorCursor\n )}\n onClick={handleOnRemove}\n id={`${generatedId}-remove-button`}\n >\n Remove\n </button>\n )}\n </div>\n );\n };\n\n const renderErrorList = (errors: string[]) => {\n return (\n <>\n <Typography.BodyMD\n weight=\"semibold\"\n className={clsx(\n styles.colorTextError,\n disabled && styles.colorTextDisabled\n )}\n >\n Error\n </Typography.BodyMD>\n <TextList.Ul\n className={clsx(\n styles.colorTextError,\n disabled && styles.colorTextDisabled\n )}\n >\n {errors?.map((item, index) => {\n return (\n <li\n key={index}\n id={`${generatedId}-error-list-item-${index}`}\n >\n <Typography.BodyMD\n weight=\"semibold\"\n className={clsx(\n styles.colorTextError,\n disabled && styles.colorTextDisabled\n )}\n >\n {item}\n </Typography.BodyMD>\n </li>\n );\n })}\n </TextList.Ul>\n </>\n );\n };\n\n const renderError = () => {\n return (\n collapsible &&\n !expanded &&\n hasCompositeSectionError && (\n <div\n className={clsx(\n styles.errorContainer,\n disabled && styles.disabledColorCursor\n )}\n onClick={handleExpandCollapseClick}\n id={`${generatedId}-error-alert`}\n >\n <Alert\n type={disabled ? \"description\" : \"error\"}\n className={styles.alertContainer}\n showIcon\n >\n {Array.isArray(errors)\n ? renderErrorList(errors)\n : errors}\n </Alert>\n </div>\n )\n );\n };\n\n const renderCompositeSection = () => {\n return (\n compositeSectionChildren && (\n <div>\n {renderCompositeChildren()}\n {renderError()}\n {renderExpandButton()}\n </div>\n )\n );\n };\n\n return (\n <div\n className={clsx(\n styles.container,\n getContainerStateClass(),\n getContainerHoverClass(),\n !indicator && styles.noIndicatorContainer,\n useContentWidth && styles.useContentWidthContainer,\n className\n )}\n id={id}\n data-testid={testId}\n >\n {renderToggleWithRemoveButton()}\n {renderCompositeSection()}\n </div>\n );\n};\n"],"names":["Toggle","_a","type","indicator","checked","styleType","children","childrenMaxLines","subLabel","disabled","error","name","id","className","compositeSection","removable","focusableWhenDisabled","useContentWidth","onRemove","onChange","testId","ariaDescribedBy","otherProps","__rest","collapsible","errors","compositeSectionChildren","initialExpanded","selected","setSelected","useState","expanded","setExpanded","hasCompositeSectionError","useMemo","hasErrorList","Array","isArray","length","hasErrorElement","uniqueId","useId","generatedId","inputRef","useRef","labelRef","useApplyStyle","styles.tokens","label","desktopLineClamp","desktop","tabletLineClamp","tablet","mobileLineClamp","mobile","isFocusableWhenDisabled","isNativeDisabled","isInteractionBlocked","useEffect","handleOnChange","event","preventDefault","prevSelected","handleExpandCollapseClick","handleOnRemove","handleContainerClick","current","click","handleInputClick","e","stopPropagation","renderIndicator","toggleIconType","_jsx","ToggleIcon","active","renderSubLabel","component","styles.subLabel","renderErrorList","_jsxs","_Fragment","Typography","BodyMD","weight","clsx","styles.colorTextError","styles.colorTextDisabled","TextList","Ul","map","item","index","styles.container","styles.colorBorderError","styles.toggleContainerError","styles.toggleContainerNoBorderDisabledSelected","styles.toggleContainerNoBorderDisabled","styles.toggleContainerNoBorderSelected","styles.toggleContainerNoBorder","styles.toggleContainerDisabledSelected","styles.toggleContainerDisabled","styles.toggleContainerSelected","styles.toggleContainer","styles.toggleContainerHoverSelected","styles.toggleContainerHoverDefault","getContainerHoverClass","styles.noIndicatorContainer","styles.useContentWidthContainer","ariaDescriptions","filter","Boolean","join","undefined","styles.headerContainer","styles.indicatorLabelContainer","styles.indicatorLabelContainerAddPadding","onClick","styles.inputContainer","ref","styles.input","styles.toggleInputDisabled","tabIndex","styles.textContainer","styles.toggleTextContainerDisabledSelected","styles.toggleTextContainerSelected","htmlFor","styles.label","styles.toggleLabelSelected","styles.toggleLabelDefault","styles.removeButton","styles.disabledColorCursor","renderToggleWithRemoveButton","styles.children","styles.childrenIsFinalItem","Markup","baseTextSize","styles.errorContainer","Alert","styles.alertContainer","showIcon","styles.expandButton","styles.expandButtonPaddingTopRequired","ChevronUpIcon","ChevronDownIcon"],"mappings":"6kEAsBO,MAAMA,GAAUC,SAAAC,KACnBA,GAAO,WAAUC,UACjBA,GAASC,QACTA,GAAOC,UACPA,GAAY,UAASC,SACrBA,GAAQC,iBACRA,YACAC,GAAQC,SACRA,GAAQC,MACRA,GAAKC,KACLA,GAAIC,GACJA,GAAEC,UACFA,GAASC,iBACTA,GAAgBC,UAChBA,GAASC,sBACTA,GAAqBC,gBACrBA,GAAeC,SACfA,GAAQC,SACRA,GACA,cAAeC,GACf,mBAAoBC,OACjBC,GAAUC,EAAAtB,GArBM,CAAA,OAAA,YAAA,UAAA,YAAA,WAAA,mBAAA,WAAA,WAAA,QAAA,OAAA,KAAA,YAAA,mBAAA,YAAA,wBAAA,kBAAA,WAAA,WAAA,cAAA,qBA0BnB,MAAMuB,YACFA,IAAc,EAAIC,OAClBA,GACAnB,SAAUoB,GAAwBC,gBAClCA,IACAb,IAAoB,CAAA,GACjBc,GAAUC,IAAeC,EAA8B1B,KACvD2B,GAAUC,IAAeF,IAAoBH,IAC9CM,GAA2BC,GAAQ,KACrC,MAAMC,EAAeC,MAAMC,QAAQZ,MAAWA,cAAM,EAANA,GAAQa,QAAS,EACzDC,GAAmBH,MAAMC,QAAQZ,OAAaA,GACpD,OAAOU,GAAgBI,CAAe,GACvC,CAACd,KACEe,GAAWC,IACXC,GAAc9B,GAAK,GAAGA,KAAO,MAAM4B,KAEnCG,GAAWC,EAAyB,MACpCC,GAAWD,EAAyB,MAE1CE,EAAcD,GAAU,CACpB,CAACE,EAAcC,MAAMC,kBACY,OAA7B1C,cAAgB,EAAhBA,GAAkB2C,SACZ,KACA,GAAG3C,GAAiB2C,UAC9B,CAACH,EAAcC,MAAMG,iBACW,OAA5B5C,cAAgB,EAAhBA,GAAkB6C,QACZ,KACA,GAAG7C,GAAiB6C,SAC9B,CAACL,EAAcC,MAAMK,iBACW,OAA5B9C,cAAgB,EAAhBA,GAAkB+C,QACZ,KACA,GAAG/C,GAAiB+C,WAGlC,MAAMC,KAA4B9C,MAAcO,GAC1CwC,KAAqB/C,KAAaO,GAClCyC,KAAyBhD,GAK/BiD,GAAU,KACN7B,GAAYzB,GAAQ,GACrB,CAACA,KAEJsD,GAAU,KACF9B,IACAI,GAAYL,UAAAA,GAChB,GACD,CAACC,KAKJ,MAAM+B,GAAkBC,IACpB,GAAIH,GACAG,EAAMC,sBAIV,GAAI1C,GACAA,GAASyC,QAIb,OAAQ1D,IACJ,IAAK,WACD2B,IAAaiC,IACDA,IAEZ,MACJ,IAAK,QACL,IAAK,MACL,IAAK,KACIlC,IACDC,IAAY,KAMtBkC,GAA4B,KACzBtD,IACDuB,IAAaD,GACjB,EAGEiC,GAAiB,KACdvD,KACGS,IACAA,IAGR,EAGE+C,GAAuB,WACR,QAAjBhE,EAAA0C,cAAQ,EAARA,GAAUuB,eAAO,IAAAjE,GAAAA,EAAEkE,OAAO,EAGxBC,GAAoBC,IACtBA,EAAEC,iBAAiB,EA2EjBC,GAAkB,KACpB,IAAIC,EAEJ,OAAQtE,IACJ,IAAK,MACDsE,EAAiB,OACjB,MACJ,IAAK,KACDA,EAAiB,QACjB,MACJ,IAAK,WACL,IAAK,QACDA,EAAiBtE,GAIzB,OACIuE,EAACC,GAAU,CACPxE,KAAMsE,EACNG,OAAQ/C,GACRnB,SAAUA,IACZ,EAIJmE,GAAiB,KACnB,IAAKpE,GACD,OAAO,KAGX,IAAIqE,EASJ,OANIA,EADoB,mBAAbrE,GACKA,KAEAA,GAKZiE,EAAA,MAAA,CAAA,UACY,kBACR7D,GAAI,GAAG8B,+BAEP7B,UAAWiE,WAEVD,GACC,EAwIRE,GAAmBtD,GAEjBuD,EAAAC,EAAA,CAAA3E,SAAA,CACImE,EAACS,EAAWC,OAAM,CACdC,OAAO,WACPvE,UAAWwE,EACPC,GACA7E,IAAY8E,GACfjF,SAAA,UAILmE,EAACe,EAASC,GAAE,CACR5E,UAAWwE,EACPC,GACA7E,IAAY8E,GACfjF,SAEAmB,aAAM,EAANA,EAAQiE,KAAI,CAACC,EAAMC,IAEZnB,EAAA,KAAA,CAEI7D,GAAI,GAAG8B,sBAA+BkD,IAAOtF,SAE7CmE,EAACS,EAAWC,QACRC,OAAO,WACPvE,UAAWwE,EACPC,GACA7E,IAAY8E,YAGfI,KAVAC,UA2DjC,OACIZ,SACInE,UAAWwE,EACPQ,EA7UU,cAAdxF,GACIK,GACO2E,EACHS,GACCrF,IAAYsF,GAIjBtF,GACOmB,GACDoE,EACAC,EAGNrE,GACOsE,EAGJC,EAGPzF,GACOD,GACDqF,EACAC,EAGNtF,GACOmB,GACDwE,EACAC,EAGNzE,GACO0E,EAGJC,EAGoB,MAC3B,IAAI9F,GAIJ,OAAKC,IAASkB,GACH4E,EAGJC,CAAkC,EA8RjCC,IACCvG,IAAawG,EACd1F,IAAmB2F,EACnB/F,IAEJD,GAAIA,GAAE,cACOQ,aAjLgB,MACjC,MAAMyF,EACF,CACwB,iBAAbrG,GAAwB,GAAGkC,cAAyB,KAC3DrB,IAECyF,OAAOC,SACPC,KAAK,WAAQC,EAEtB,OACIjC,EAAA,MAAA,CACIpE,GAAI,GAAG8B,sBACP7B,UAAWqG,EAAsB5G,SAAA,CAEjCmE,SACI5D,UAAWwE,EACP8B,EACApG,IAAaqG,GAChB9G,SAED0E,EAAA,MAAA,CACIpE,GAAI,GAAG8B,qBACP2E,QAASpD,GACTpD,UAAWyG,EAAqBhH,SAAA,CAEhCmE,yBACI8C,IAAK5E,GACLhC,KAAMA,GACNC,GAAI,GAAG8B,WACPxC,KAAe,aAATA,GAAsB,WAAa,QAAO,cACpC,eACZW,UAAWwE,EACPmC,EACA/G,IAAYgH,GAEhBhH,SAAU+C,GAAgB,gBACXD,GACfpC,SAAUwC,GACV0D,QAASjD,GACThE,QAASwB,GACT8F,SAAUnE,GAA0B,OAAI0D,EAAS,mBAC/BJ,GACdvF,KAEPnB,IAAaoE,KACdS,EAAA,MAAA,CACInE,UAAWwE,EACPsC,EA9JpBlH,GACOmB,GACDgG,EACArC,EAGN3D,GACOiG,OADX,GA0JqBvH,SAAA,CAEDmE,WACI8C,IAAK1E,GACLiF,QAAS,GAAGpF,WAAmB,cAClB,eACb9B,GAAI,GAAG8B,WACP7B,UAAWwE,EACP0C,EACAnG,GACMoG,EACAC,YAGT3H,KAEJE,IAAYoE,aAIxB7D,IACG0D,EAAA,SAAA,CACIvE,KAAK,SACLW,UAAWwE,EACP6C,EACAzH,IAAY0H,GAEhBd,QAASrD,GACTpD,GAAI,GAAG8B,mBAA2BpC,SAAA,aAKxC,EAiGL8H,GAvBD1G,IACIsD,EAAA,MAAA,CAAA1E,SAAA,GAzMFkB,IAAeO,KACb0C,EAAA,MAAA,CAAA,UACY,4BACR5D,UAAWwE,EACPgD,GACC7G,IAAe8G,EAChB7H,IAAY8E,GACfjF,SAEDmE,EAAC8D,EAAM,CAACC,aAAa,UAASlI,SACzBoB,OAmKbF,KACCO,IACDE,IACIwC,EAAA,MAAA,CACI5D,UAAWwE,EACPoD,EACAhI,IAAY0H,GAEhBd,QAAStD,GACTnD,GAAI,GAAG8B,iBAAyBpC,SAEhCmE,EAACiE,EAAK,CACFxI,KAAMO,GAAW,cAAgB,QACjCI,UAAW8H,EACXC,UAAQ,EAAAtI,SAEP8B,MAAMC,QAAQZ,IACTsD,GAAgBtD,IAChBA,OA1KlBD,IACIwD,EAAA,SAAA,CACInE,UAAWwE,EACPwD,EACApI,IAAY0H,GAPIpG,KAAaE,IASzB6G,IAERrI,SAAUA,GACV4G,QAAStD,GAAyB,cACrBhC,GAAW,kBAAoB,gBAAezB,SAAA,CAE1DyB,GAAW,YAAc,YAEtB0C,EADH1C,GACIgH,EAEAC,EAFa,CAAA,eAAA,YA8LxB"}
1
+ {"version":3,"file":"toggle.js","sources":["../../src/toggle/toggle.tsx"],"sourcesContent":["import { ChevronDownIcon } from \"@lifesg/react-icons/chevron-down\";\nimport { ChevronUpIcon } from \"@lifesg/react-icons/chevron-up\";\nimport clsx from \"clsx\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { Alert } from \"../alert\";\nimport { Markup } from \"../markup\";\nimport { TextList } from \"../text-list\";\nimport { useApplyStyle } from \"../theme\";\nimport { Typography } from \"../typography\";\nimport { useId } from \"../util\";\nimport * as styles from \"./toggle.styles\";\nimport type { ToggleIconType } from \"./toggle-icon\";\nimport { ToggleIcon } from \"./toggle-icon\";\nimport type { ToggleProps } from \"./types\";\n\n// @catalog\n/**\n * A selectable control for checkbox and radio interaction patterns.\n *\n * Use `Toggle` to present a labeled option that the user can select or\n * deselect.\n */\nexport const Toggle = ({\n type = \"checkbox\",\n indicator,\n checked,\n styleType = \"default\",\n children,\n childrenMaxLines,\n subLabel,\n disabled,\n error,\n name,\n id,\n className,\n compositeSection,\n removable,\n focusableWhenDisabled,\n useContentWidth,\n onRemove,\n onChange,\n \"data-testid\": testId,\n \"aria-describedby\": ariaDescribedBy,\n ...otherProps\n}: ToggleProps) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const {\n collapsible = true,\n errors,\n children: compositeSectionChildren,\n initialExpanded,\n } = compositeSection || {};\n const [selected, setSelected] = useState<boolean | undefined>(checked);\n const [expanded, setExpanded] = useState<boolean>(!!initialExpanded);\n const hasCompositeSectionError = useMemo(() => {\n const hasErrorList = Array.isArray(errors) && errors?.length > 0;\n const hasErrorElement = !Array.isArray(errors) && !!errors;\n return hasErrorList || hasErrorElement;\n }, [errors]);\n const uniqueId = useId();\n const generatedId = id ? `${id}` : `tg-${uniqueId}`;\n\n const inputRef = useRef<HTMLInputElement>(null);\n const labelRef = useRef<HTMLLabelElement>(null);\n\n useApplyStyle(labelRef, {\n [styles.tokens.label.desktopLineClamp]:\n childrenMaxLines?.desktop == null\n ? null\n : `${childrenMaxLines.desktop}`,\n [styles.tokens.label.tabletLineClamp]:\n childrenMaxLines?.tablet == null\n ? null\n : `${childrenMaxLines.tablet}`,\n [styles.tokens.label.mobileLineClamp]:\n childrenMaxLines?.mobile == null\n ? null\n : `${childrenMaxLines.mobile}`,\n });\n\n const isFocusableWhenDisabled = !!disabled && !!focusableWhenDisabled;\n const isNativeDisabled = !!disabled && !focusableWhenDisabled;\n const isInteractionBlocked = !!disabled;\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n setSelected(checked);\n }, [checked]);\n\n useEffect(() => {\n if (selected) {\n setExpanded(initialExpanded ?? true);\n }\n }, [selected]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleOnChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n if (isInteractionBlocked) {\n event.preventDefault();\n return;\n }\n\n if (onChange) {\n onChange(event);\n return;\n }\n\n switch (type) {\n case \"checkbox\":\n setSelected((prevSelected) => {\n return !prevSelected;\n });\n break;\n case \"radio\":\n case \"yes\":\n case \"no\":\n if (!selected) {\n setSelected(true);\n }\n break;\n }\n };\n\n const handleExpandCollapseClick = () => {\n if (!disabled) {\n setExpanded(!expanded);\n }\n };\n\n const handleOnRemove = () => {\n if (!disabled) {\n if (onRemove) {\n onRemove();\n return;\n }\n }\n };\n\n const handleContainerClick = () => {\n inputRef?.current?.click();\n };\n\n const handleInputClick = (e: React.MouseEvent<HTMLInputElement>) => {\n e.stopPropagation();\n };\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n\n const getContainerStateClass = () => {\n if (styleType === \"no-border\") {\n if (error) {\n return clsx(\n styles.colorBorderError,\n !disabled && styles.toggleContainerError\n );\n }\n\n if (disabled) {\n return selected\n ? styles.toggleContainerNoBorderDisabledSelected\n : styles.toggleContainerNoBorderDisabled;\n }\n\n if (selected) {\n return styles.toggleContainerNoBorderSelected;\n }\n\n return styles.toggleContainerNoBorder;\n }\n\n if (error) {\n return disabled\n ? styles.colorBorderError\n : styles.toggleContainerError;\n }\n\n if (disabled) {\n return selected\n ? styles.toggleContainerDisabledSelected\n : styles.toggleContainerDisabled;\n }\n\n if (selected) {\n return styles.toggleContainerSelected;\n }\n\n return styles.toggleContainer;\n };\n\n const getContainerHoverClass = () => {\n if (disabled) {\n return undefined;\n }\n\n if (!error && selected) {\n return styles.toggleContainerHoverSelected;\n }\n\n return styles.toggleContainerHoverDefault;\n };\n\n const getTextContainerStateClass = () => {\n if (disabled) {\n return selected\n ? styles.toggleTextContainerDisabledSelected\n : styles.colorTextDisabled;\n }\n\n if (selected) {\n return styles.toggleTextContainerSelected;\n }\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderIndicator = () => {\n let toggleIconType: ToggleIconType;\n\n switch (type) {\n case \"yes\":\n toggleIconType = \"tick\";\n break;\n case \"no\":\n toggleIconType = \"cross\";\n break;\n case \"checkbox\":\n case \"radio\":\n toggleIconType = type;\n break;\n }\n\n return (\n <ToggleIcon\n type={toggleIconType}\n active={selected}\n disabled={disabled}\n />\n );\n };\n\n const renderSubLabel = () => {\n if (!subLabel) {\n return null;\n }\n\n let component: string | JSX.Element;\n\n if (typeof subLabel === \"function\") {\n component = subLabel();\n } else {\n component = subLabel;\n }\n\n // Hide sublabel from screen readers as the main input already has aria-describedby that points to the sublabel\n return (\n <div\n data-id=\"toggle-sublabel\"\n id={`${generatedId}-sublabel`}\n aria-hidden\n className={styles.subLabel}\n >\n {component}\n </div>\n );\n };\n\n const renderCompositeChildren = () => {\n return (\n (!collapsible || expanded) && (\n <div\n data-id=\"toggle-composite-children\"\n className={clsx(\n styles.children,\n !collapsible && styles.childrenIsFinalItem,\n disabled && styles.colorTextDisabled\n )}\n >\n <Markup baseTextSize=\"body-md\">\n {compositeSectionChildren}\n </Markup>\n </div>\n )\n );\n };\n\n const renderExpandButton = () => {\n const collapsedWithoutErrors = !expanded && !hasCompositeSectionError;\n\n return (\n collapsible && (\n <button\n className={clsx(\n styles.expandButton,\n disabled && styles.disabledColorCursor,\n collapsedWithoutErrors &&\n styles.expandButtonPaddingTopRequired\n )}\n disabled={disabled}\n onClick={handleExpandCollapseClick}\n data-testid={expanded ? \"collapse-button\" : \"expand-button\"}\n >\n {expanded ? \"Show less\" : \"Show more\"}\n {expanded ? (\n <ChevronUpIcon aria-hidden />\n ) : (\n <ChevronDownIcon aria-hidden />\n )}\n </button>\n )\n );\n };\n\n const renderToggleWithRemoveButton = () => {\n const ariaDescriptions =\n [\n typeof subLabel === \"string\" ? `${generatedId}-sublabel` : null,\n ariaDescribedBy,\n ]\n .filter(Boolean)\n .join(\" \") || undefined;\n\n return (\n <div\n id={`${generatedId}-header-container`}\n className={styles.headerContainer}\n >\n <div\n className={clsx(\n styles.indicatorLabelContainer,\n removable && styles.indicatorLabelContainerAddPadding\n )}\n >\n <div\n id={`${generatedId}-input-container`}\n onClick={handleContainerClick}\n className={styles.inputContainer}\n >\n <input\n ref={inputRef}\n name={name}\n id={`${generatedId}-input`}\n type={type === \"checkbox\" ? \"checkbox\" : \"radio\"}\n data-testid=\"toggle-input\"\n className={clsx(\n styles.input,\n disabled && styles.toggleInputDisabled\n )}\n disabled={isNativeDisabled}\n aria-disabled={isFocusableWhenDisabled}\n onChange={handleOnChange}\n onClick={handleInputClick}\n checked={selected}\n tabIndex={isFocusableWhenDisabled ? 0 : undefined}\n aria-describedby={ariaDescriptions}\n {...otherProps}\n />\n {indicator && renderIndicator()}\n <div\n className={clsx(\n styles.textContainer,\n getTextContainerStateClass()\n )}\n >\n <label\n ref={labelRef}\n htmlFor={`${generatedId}-input`}\n data-testid={`toggle-label`}\n id={`${generatedId}-label`}\n className={clsx(\n styles.label,\n selected\n ? styles.toggleLabelSelected\n : styles.toggleLabelDefault\n )}\n >\n {children}\n </label>\n {subLabel && renderSubLabel()}\n </div>\n </div>\n </div>\n {removable && (\n <button\n type=\"button\"\n className={clsx(\n styles.removeButton,\n disabled && styles.disabledColorCursor\n )}\n onClick={handleOnRemove}\n id={`${generatedId}-remove-button`}\n >\n Remove\n </button>\n )}\n </div>\n );\n };\n\n const renderErrorList = (errors: string[]) => {\n return (\n <>\n <Typography.BodyMD\n weight=\"semibold\"\n className={clsx(\n styles.colorTextError,\n disabled && styles.colorTextDisabled\n )}\n >\n Error\n </Typography.BodyMD>\n <TextList.Ul\n className={clsx(\n styles.colorTextError,\n disabled && styles.colorTextDisabled\n )}\n >\n {errors?.map((item, index) => {\n return (\n <li\n key={index}\n id={`${generatedId}-error-list-item-${index}`}\n >\n <Typography.BodyMD\n weight=\"semibold\"\n className={clsx(\n styles.colorTextError,\n disabled && styles.colorTextDisabled\n )}\n >\n {item}\n </Typography.BodyMD>\n </li>\n );\n })}\n </TextList.Ul>\n </>\n );\n };\n\n const renderError = () => {\n return (\n collapsible &&\n !expanded &&\n hasCompositeSectionError && (\n <div\n className={clsx(\n styles.errorContainer,\n disabled && styles.disabledColorCursor\n )}\n onClick={handleExpandCollapseClick}\n id={`${generatedId}-error-alert`}\n >\n <Alert\n type={disabled ? \"description\" : \"error\"}\n className={styles.alertContainer}\n showIcon\n >\n {Array.isArray(errors)\n ? renderErrorList(errors)\n : errors}\n </Alert>\n </div>\n )\n );\n };\n\n const renderCompositeSection = () => {\n return (\n compositeSectionChildren && (\n <div>\n {renderCompositeChildren()}\n {renderError()}\n {renderExpandButton()}\n </div>\n )\n );\n };\n\n return (\n <div\n className={clsx(\n styles.container,\n getContainerStateClass(),\n getContainerHoverClass(),\n !indicator && styles.noIndicatorContainer,\n useContentWidth && styles.useContentWidthContainer,\n className\n )}\n id={id}\n data-testid={testId}\n >\n {renderToggleWithRemoveButton()}\n {renderCompositeSection()}\n </div>\n );\n};\n"],"names":["Toggle","_a","type","indicator","checked","styleType","children","childrenMaxLines","subLabel","disabled","error","name","id","className","compositeSection","removable","focusableWhenDisabled","useContentWidth","onRemove","onChange","testId","ariaDescribedBy","otherProps","__rest","collapsible","errors","compositeSectionChildren","initialExpanded","selected","setSelected","useState","expanded","setExpanded","hasCompositeSectionError","useMemo","hasErrorList","Array","isArray","length","hasErrorElement","uniqueId","useId","generatedId","inputRef","useRef","labelRef","useApplyStyle","styles.tokens","label","desktopLineClamp","desktop","tabletLineClamp","tablet","mobileLineClamp","mobile","isFocusableWhenDisabled","isNativeDisabled","isInteractionBlocked","useEffect","handleOnChange","event","preventDefault","prevSelected","handleExpandCollapseClick","handleOnRemove","handleContainerClick","current","click","handleInputClick","e","stopPropagation","renderIndicator","toggleIconType","_jsx","ToggleIcon","active","renderSubLabel","component","styles.subLabel","renderErrorList","_jsxs","_Fragment","Typography","BodyMD","weight","clsx","styles.colorTextError","styles.colorTextDisabled","TextList","Ul","map","item","index","styles.container","styles.colorBorderError","styles.toggleContainerError","styles.toggleContainerNoBorderDisabledSelected","styles.toggleContainerNoBorderDisabled","styles.toggleContainerNoBorderSelected","styles.toggleContainerNoBorder","styles.toggleContainerDisabledSelected","styles.toggleContainerDisabled","styles.toggleContainerSelected","styles.toggleContainer","styles.toggleContainerHoverSelected","styles.toggleContainerHoverDefault","getContainerHoverClass","styles.noIndicatorContainer","styles.useContentWidthContainer","ariaDescriptions","filter","Boolean","join","undefined","styles.headerContainer","styles.indicatorLabelContainer","styles.indicatorLabelContainerAddPadding","onClick","styles.inputContainer","ref","styles.input","styles.toggleInputDisabled","tabIndex","styles.textContainer","styles.toggleTextContainerDisabledSelected","styles.toggleTextContainerSelected","htmlFor","styles.label","styles.toggleLabelSelected","styles.toggleLabelDefault","styles.removeButton","styles.disabledColorCursor","renderToggleWithRemoveButton","styles.children","styles.childrenIsFinalItem","Markup","baseTextSize","styles.errorContainer","Alert","styles.alertContainer","showIcon","styles.expandButton","styles.expandButtonPaddingTopRequired","ChevronUpIcon","ChevronDownIcon"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Shared formatter for generated files.
3
+ */
4
+ export declare class GeneratedFileFormatter {
5
+ format(pattern: string): void;
6
+ }
@@ -0,0 +1,36 @@
1
+ type JsDocTagLike = {
2
+ getCommentText: () => string | undefined;
3
+ getTagName: () => string;
4
+ };
5
+ type JsDocBlockLike = {
6
+ getCommentText: () => string | undefined;
7
+ getTags: () => JsDocTagLike[];
8
+ };
9
+ type JsDocNodeLike = {
10
+ getJsDocs: () => JsDocBlockLike[];
11
+ };
12
+ type LeadingCommentNodeLike = {
13
+ getLeadingCommentRanges: () => Array<{
14
+ getText: () => string;
15
+ }>;
16
+ };
17
+ /**
18
+ * Shared parser for JSDoc tags and leading comments.
19
+ */
20
+ export declare class JsDocParser {
21
+ getTagCommentText(tag: {
22
+ getCommentText: () => string | undefined;
23
+ }): string | undefined;
24
+ getDescriptionFromNode(node: JsDocNodeLike, options?: {
25
+ joinWith?: string;
26
+ normalizeNewlinesToSpaces?: boolean;
27
+ }): string | undefined;
28
+ getTags(node: JsDocNodeLike): JsDocTagLike[];
29
+ getLeadingNonJsDocComments(node: LeadingCommentNodeLike): string[];
30
+ getMarkerValuesFromLeadingComments(node: LeadingCommentNodeLike, marker: string): string[];
31
+ splitCommaSeparatedValues(rawValue: string | undefined): string[];
32
+ normalizeCommentText(text: string | undefined, options?: {
33
+ normalizeNewlinesToSpaces?: boolean;
34
+ }): string | undefined;
35
+ }
36
+ export {};
@@ -0,0 +1,9 @@
1
+ import { Project } from "ts-morph";
2
+ /**
3
+ * Shared singleton factory for ts-morph Project instances.
4
+ */
5
+ export declare class TsMorphProjectFactory {
6
+ private static _instance;
7
+ static getProject(): Project;
8
+ static reset(): void;
9
+ }
@@ -0,0 +1,9 @@
1
+ import { type Project, type SourceFile } from "ts-morph";
2
+ /**
3
+ * Shared source provider for ts-morph project and source-file operations.
4
+ */
5
+ export declare class TypeScriptSourceProvider {
6
+ getProject(): Project;
7
+ getSourceFile(filePath: string): SourceFile;
8
+ getSourceFilesByGlobs(globs: readonly string[]): SourceFile[];
9
+ }
@@ -0,0 +1,69 @@
1
+ /**
2
+ * FileSystemAdapter - Minimal abstraction for filesystem operations.
3
+ *
4
+ * This adapter abstracts path resolution and file existence checks,
5
+ * making file operations testable via mocking without filesystem access.
6
+ */
7
+ import type { FileStat } from "../types";
8
+ /**
9
+ * Interface for filesystem operations used by path resolution services.
10
+ * Allows mocking during tests without real filesystem access.
11
+ */
12
+ export interface IFileSystemAdapter {
13
+ /**
14
+ * Check if a path exists (file or directory).
15
+ * @param path The path to check
16
+ * @returns true if path exists, false otherwise
17
+ */
18
+ existsSync(path: string): boolean;
19
+ /**
20
+ * Get file statistics for a path.
21
+ * @param path The path to stat
22
+ * @returns File stat object with isFile() and isDirectory() methods
23
+ * @throws If path doesn't exist
24
+ */
25
+ statSync(path: string): FileStat;
26
+ /**
27
+ * Resolve one or more path segments relative to working directory.
28
+ * @param segments Path segments to resolve
29
+ * @returns Absolute resolved path
30
+ */
31
+ resolvePath(...segments: string[]): string;
32
+ /**
33
+ * Remove a file or directory.
34
+ * @param path The path to remove
35
+ * @param options.force If true, suppress errors if path doesn't exist
36
+ */
37
+ rm(path: string, options?: {
38
+ force?: boolean;
39
+ }): Promise<void>;
40
+ /**
41
+ * Create a directory.
42
+ * @param path The directory path
43
+ * @param options.recursive If true, create parent directories as needed
44
+ */
45
+ mkdir(path: string, options?: {
46
+ recursive?: boolean;
47
+ }): Promise<void>;
48
+ /**
49
+ * Write text content to a file.
50
+ * @param path The file path
51
+ * @param data The content to write
52
+ */
53
+ writeFile(path: string, data: string): Promise<void>;
54
+ }
55
+ /**
56
+ * Default FileSystemAdapter implementation using Node.js fs module.
57
+ */
58
+ export declare class FileSystemAdapter implements IFileSystemAdapter {
59
+ existsSync(path: string): boolean;
60
+ statSync(path: string): FileStat;
61
+ resolvePath(...segments: string[]): string;
62
+ rm(path: string, options?: {
63
+ force?: boolean;
64
+ }): Promise<void>;
65
+ mkdir(path: string, options?: {
66
+ recursive?: boolean;
67
+ }): Promise<void>;
68
+ writeFile(path: string, data: string): Promise<void>;
69
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * ArgTypesGenerator - Orchestrator for Storybook argTypes generation.
3
+ *
4
+ * Composes all services to generate argTypes files from TypeScript sources
5
+ * and the registry mapping story titles to their argTypes.
6
+ *
7
+ * This class mirrors the logic in the original procedural script but with
8
+ * clear method boundaries and injectable dependencies.
9
+ */
10
+ import type { IFileSystemAdapter } from "./adapters/file-system-adapter";
11
+ /**
12
+ * Orchestrates the full Storybook argTypes generation pipeline.
13
+ * Coordinates all services: source analysis, type formatting, row building, and registry generation.
14
+ *
15
+ * Usage:
16
+ * ```typescript
17
+ * const generator = new ArgTypesGenerator();
18
+ * await generator.generateAll();
19
+ * ```
20
+ */
21
+ export declare class ArgTypesGenerator {
22
+ private readonly sourceProvider;
23
+ private readonly jsDocExtractor;
24
+ private readonly typeDependencyResolver;
25
+ private readonly typeFormatter;
26
+ private readonly rowBuilder;
27
+ private readonly resolver;
28
+ private readonly storyRegistryGenerator;
29
+ private readonly generatedFileFormatter;
30
+ private readonly fsAdapter;
31
+ /**
32
+ * Create a new ArgTypesGenerator.
33
+ *
34
+ * @param fsAdapter Optional filesystem adapter for testability
35
+ */
36
+ constructor(fsAdapter?: IFileSystemAdapter);
37
+ /**
38
+ * Generate all component argTypes files and the registry.
39
+ * This is the main entry point for full generation.
40
+ */
41
+ generateAll(): Promise<void>;
42
+ /**
43
+ * Generate argTypes for a single component types.ts file.
44
+ *
45
+ * @param sourceFilePath Path to the source types.ts file
46
+ */
47
+ generateForSourceFile(sourceFilePath: string): Promise<void>;
48
+ /**
49
+ * Generate the global registry mapping story titles to their argTypes imports.
50
+ * Scans all story files to discover which component types.ts each story uses.
51
+ */
52
+ generateStorybookArgTypesRegistry(): Promise<void>;
53
+ /**
54
+ * Format all generated files using prettier.
55
+ */
56
+ formatGenerated(): void;
57
+ /**
58
+ * Get the output file path for generated argTypes.
59
+ */
60
+ getOutputFile(sourceFilePath: string): string;
61
+ /**
62
+ * Delete the generated argTypes output file for a given source file path.
63
+ * Used when the source file is removed during watch mode.
64
+ */
65
+ deleteOutputFile(sourceFilePath: string): Promise<void>;
66
+ /**
67
+ * Get the export name for the component's argTypes object.
68
+ * e.g. "form-custom-field" → "formCustomFieldExtraArgTypes"
69
+ */
70
+ getExportName(sourceFilePath: string): string;
71
+ /**
72
+ * Get the relative import path for a generated argTypes file.
73
+ */
74
+ getArgTypesImportPath(outputFile: string): string;
75
+ private getPropertyName;
76
+ private getCategoryName;
77
+ private findReferencedTypeNames;
78
+ private getWrappedTypeNames;
79
+ private getInheritedHtmlAttributesRow;
80
+ private getInheritedInterfacesDescription;
81
+ private getInterfaceArgTypes;
82
+ private getTypeAliasArgTypes;
83
+ private generateImportedTypeRows;
84
+ private shouldSkipImportedTypeRows;
85
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Configuration constants for Storybook argTypes generation.
3
+ * Centralizes all configuration to improve testability and maintainability.
4
+ */
5
+ /**
6
+ * Glob patterns for source files containing type definitions.
7
+ * Used to discover which component types.ts files to generate argTypes from.
8
+ */
9
+ export declare const SOURCE_FILE_GLOBS: readonly ["src/*/types.ts", "src/filter/addons/types.ts", "src/form/form-*/types.ts", "src/popover/popover-inline/types.ts"];
10
+ /**
11
+ * Root directories to watch for file changes (when in watch mode).
12
+ */
13
+ export declare const WATCH_ROOTS: string[];
14
+ /**
15
+ * Glob pattern for story files to scan for component references.
16
+ */
17
+ export declare const STORY_FILE_GLOB = "stories/**/*.stories.@(ts|tsx)";
18
+ /**
19
+ * Output file path for the generated registry mapping stories to argTypes imports.
20
+ */
21
+ export declare const STORYBOOK_ARGTYPES_FILE: string;
22
+ /**
23
+ * TypeScript type formatting flags for consistent text representation.
24
+ * NoTruncation: Show full type text without truncation
25
+ * UseSingleQuotesForStringLiteralType: Prefer 'string' over "string"
26
+ */
27
+ export declare const TYPE_FORMAT_FLAGS: number;
28
+ /**
29
+ * Header comment for all generated files.
30
+ */
31
+ export declare const GENERATED_FILE_HEADER: "// This file is generated. Do not edit manually.\n// Run: npm run storybook:argtypes\n";
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Storybook ArgTypes Generation Tool - Public API
3
+ *
4
+ * Main entry point for the storybook-argtypes utility.
5
+ * Exports all public interfaces, classes, and utilities.
6
+ */
7
+ export { ArgTypesGenerator } from "./arg-types-generator";
8
+ export { GENERATED_FILE_HEADER, SOURCE_FILE_GLOBS, STORY_FILE_GLOB, STORYBOOK_ARGTYPES_FILE, TYPE_FORMAT_FLAGS, WATCH_ROOTS, } from "./config/arg-types-config";
9
+ export type * as StorybookArgtypesTypes from "./types";
10
+ export { FileSystemAdapter, type IFileSystemAdapter, } from "./adapters/file-system-adapter";
11
+ export * from "./services";