@lifesg/react-design-system 4.0.0-alpha.12 → 4.0.0-alpha.14

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 (323) hide show
  1. package/breadcrumb/breadcrumb.js +1 -1
  2. package/breadcrumb/breadcrumb.js.map +1 -1
  3. package/breadcrumb/breadcrumb.styles.d.ts +0 -8
  4. package/breadcrumb/breadcrumb.styles.js +1 -1
  5. package/breadcrumb/breadcrumb.styles.js.map +1 -1
  6. package/breadcrumb/breadcrumb.styles_1blzn8n.css +7 -0
  7. package/breadcrumb/types.d.ts +2 -13
  8. package/cjs/breadcrumb/breadcrumb.js +1 -1
  9. package/cjs/breadcrumb/breadcrumb.js.map +1 -1
  10. package/cjs/breadcrumb/breadcrumb.styles.js +1 -1
  11. package/cjs/breadcrumb/breadcrumb.styles.js.map +1 -1
  12. package/cjs/breadcrumb/breadcrumb.styles_1blzn8n.css +7 -0
  13. package/cjs/drawer/drawer.js +1 -1
  14. package/cjs/drawer/drawer.js.map +1 -1
  15. package/cjs/drawer/drawer.styles.js +1 -1
  16. package/cjs/drawer/drawer.styles.js.map +1 -1
  17. package/{drawer/drawer.styles_94hx3y.css → cjs/drawer/drawer.styles_a4bwe0.css} +6 -3
  18. package/cjs/external/dompurify/dist/purify.es.js +4 -2
  19. package/cjs/external/dompurify/dist/purify.es.js.map +1 -1
  20. package/cjs/file-upload/file-list/file-list.js +1 -1
  21. package/cjs/file-upload/file-list/file-list.js.map +1 -1
  22. package/cjs/file-upload/file-list/file-list.styles.js +1 -1
  23. package/cjs/file-upload/file-list/file-list.styles.js.map +1 -1
  24. package/cjs/file-upload/file-list/file-list.styles_1xbypnh.css +2 -0
  25. package/cjs/file-upload/file-list-item/file-item-actions.js +2 -0
  26. package/cjs/file-upload/file-list-item/file-item-actions.js.map +1 -0
  27. package/cjs/file-upload/file-list-item/file-item-actions.styles.js +2 -0
  28. package/cjs/file-upload/file-list-item/file-item-actions.styles.js.map +1 -0
  29. package/cjs/file-upload/file-list-item/file-item-actions.styles_1quulgy.css +8 -0
  30. package/cjs/file-upload/file-list-item/file-item-details.js +2 -0
  31. package/cjs/file-upload/file-list-item/file-item-details.js.map +1 -0
  32. package/cjs/file-upload/file-list-item/file-item-details.styles.js +2 -0
  33. package/cjs/file-upload/file-list-item/file-item-details.styles.js.map +1 -0
  34. package/cjs/file-upload/file-list-item/file-item-details.styles_1ce9akx.css +7 -0
  35. package/cjs/file-upload/file-list-item/file-list-item.js +1 -1
  36. package/cjs/file-upload/file-list-item/file-list-item.js.map +1 -1
  37. package/cjs/file-upload/file-list-item/file-list-item.styles.js +1 -1
  38. package/cjs/file-upload/file-list-item/file-list-item.styles.js.map +1 -1
  39. package/cjs/file-upload/file-list-item/file-list-item.styles_x3a500.css +10 -0
  40. package/cjs/file-upload/file-list-item/use-truncated-name.js +2 -0
  41. package/cjs/file-upload/file-list-item/use-truncated-name.js.map +1 -0
  42. package/cjs/local-nav/local-nav-dropdown/local-nav-dropdown.js +1 -1
  43. package/cjs/local-nav/local-nav-dropdown/local-nav-dropdown.js.map +1 -1
  44. package/cjs/local-nav/local-nav-dropdown/local-nav-dropdown.styles.js +1 -1
  45. package/cjs/local-nav/local-nav-dropdown/local-nav-dropdown.styles.js.map +1 -1
  46. package/{local-nav/local-nav-dropdown/local-nav-dropdown.styles_uhd4xl.css → cjs/local-nav/local-nav-dropdown/local-nav-dropdown.styles_kpel1m.css} +9 -6
  47. package/cjs/local-nav/local-nav-menu/local-nav-menu.js +1 -1
  48. package/cjs/local-nav/local-nav-menu/local-nav-menu.js.map +1 -1
  49. package/cjs/local-nav/local-nav-menu/local-nav-menu.styles.js +1 -1
  50. package/cjs/local-nav/local-nav-menu/local-nav-menu.styles.js.map +1 -1
  51. package/cjs/local-nav/local-nav-menu/local-nav-menu.styles_67fcyc.css +8 -0
  52. package/cjs/menu/menu-content.js +1 -1
  53. package/cjs/menu/menu-content.js.map +1 -1
  54. package/cjs/menu/menu-content.styles.js +1 -1
  55. package/cjs/menu/menu-content.styles.js.map +1 -1
  56. package/cjs/menu/menu-content.styles_1r8oxtk.css +5 -0
  57. package/cjs/menu/menu-item.styles.js +1 -1
  58. package/cjs/menu/menu-item.styles.js.map +1 -1
  59. package/cjs/menu/{menu-item.styles_liyed8.css → menu-item.styles_eut2j9.css} +1 -1
  60. package/cjs/menu/menu-link.styles.js +1 -1
  61. package/cjs/menu/menu-link.styles.js.map +1 -1
  62. package/cjs/menu/menu-link.styles_rng7n7.css +2 -0
  63. package/cjs/menu/menu-section.js +1 -1
  64. package/cjs/menu/menu-section.js.map +1 -1
  65. package/cjs/menu/menu-section.styles.js +1 -1
  66. package/cjs/menu/menu-section.styles.js.map +1 -1
  67. package/cjs/menu/menu-section.styles_1n0ppxl.css +5 -0
  68. package/cjs/modal-v2/slots/slot-styles.js +1 -1
  69. package/cjs/modal-v2/slots/slot-styles.js.map +1 -1
  70. package/cjs/modal-v2/slots/{slot-styles_ayb9il.css → slot-styles_ygu6zc.css} +1 -1
  71. package/cjs/navbar/navbar-items.js +1 -1
  72. package/cjs/navbar/navbar-items.js.map +1 -1
  73. package/cjs/notification-banner/notification-banner-hoc.js +1 -1
  74. package/cjs/notification-banner/notification-banner-hoc.js.map +1 -1
  75. package/cjs/pagination/pagination.js +1 -1
  76. package/cjs/pagination/pagination.js.map +1 -1
  77. package/cjs/shared/dropdown-list/dropdown-label.js +1 -1
  78. package/cjs/shared/dropdown-list/dropdown-label.js.map +1 -1
  79. package/cjs/shared/fade-wrapper/fade-wrapper.js +1 -1
  80. package/cjs/shared/fade-wrapper/fade-wrapper.js.map +1 -1
  81. package/cjs/theme/tokens/colour.js +1 -1
  82. package/cjs/theme/tokens/colour.js.map +1 -1
  83. package/cjs/theme/tokens/radius.js +1 -1
  84. package/cjs/theme/tokens/radius.js.map +1 -1
  85. package/codemods/run-codemod.js +8 -2
  86. package/codemods/run-codemod.js.map +1 -1
  87. package/codemods/run-codemod.ts +13 -4
  88. package/drawer/drawer.d.ts +1 -1
  89. package/drawer/drawer.js +1 -1
  90. package/drawer/drawer.js.map +1 -1
  91. package/drawer/drawer.styles.d.ts +3 -0
  92. package/drawer/drawer.styles.js +1 -1
  93. package/drawer/drawer.styles.js.map +1 -1
  94. package/{cjs/drawer/drawer.styles_94hx3y.css → drawer/drawer.styles_a4bwe0.css} +6 -3
  95. package/drawer/types.d.ts +7 -0
  96. package/external/dompurify/dist/purify.es.js +4 -2
  97. package/external/dompurify/dist/purify.es.js.map +1 -1
  98. package/file-upload/file-list/file-list.js +1 -1
  99. package/file-upload/file-list/file-list.js.map +1 -1
  100. package/file-upload/file-list/file-list.styles.d.ts +0 -1
  101. package/file-upload/file-list/file-list.styles.js +1 -1
  102. package/file-upload/file-list/file-list.styles.js.map +1 -1
  103. package/file-upload/file-list/file-list.styles_1xbypnh.css +2 -0
  104. package/file-upload/file-list-item/file-item-actions.d.ts +30 -0
  105. package/file-upload/file-list-item/file-item-actions.js +2 -0
  106. package/file-upload/file-list-item/file-item-actions.js.map +1 -0
  107. package/file-upload/file-list-item/file-item-actions.styles.d.ts +6 -0
  108. package/file-upload/file-list-item/file-item-actions.styles.js +2 -0
  109. package/file-upload/file-list-item/file-item-actions.styles.js.map +1 -0
  110. package/file-upload/file-list-item/file-item-actions.styles_1quulgy.css +8 -0
  111. package/file-upload/file-list-item/file-item-details.d.ts +15 -0
  112. package/file-upload/file-list-item/file-item-details.js +2 -0
  113. package/file-upload/file-list-item/file-item-details.js.map +1 -0
  114. package/file-upload/file-list-item/file-item-details.styles.d.ts +7 -0
  115. package/file-upload/file-list-item/file-item-details.styles.js +2 -0
  116. package/file-upload/file-list-item/file-item-details.styles.js.map +1 -0
  117. package/file-upload/file-list-item/file-item-details.styles_1ce9akx.css +7 -0
  118. package/file-upload/file-list-item/file-list-item.d.ts +1 -7
  119. package/file-upload/file-list-item/file-list-item.js +1 -1
  120. package/file-upload/file-list-item/file-list-item.js.map +1 -1
  121. package/file-upload/file-list-item/file-list-item.styles.d.ts +6 -13
  122. package/file-upload/file-list-item/file-list-item.styles.js +1 -1
  123. package/file-upload/file-list-item/file-list-item.styles.js.map +1 -1
  124. package/file-upload/file-list-item/file-list-item.styles_x3a500.css +10 -0
  125. package/file-upload/file-list-item/types.d.ts +10 -3
  126. package/file-upload/file-list-item/use-truncated-name.d.ts +1 -0
  127. package/file-upload/file-list-item/use-truncated-name.js +2 -0
  128. package/file-upload/file-list-item/use-truncated-name.js.map +1 -0
  129. package/input-group/types.d.ts +4 -1
  130. package/input-select/types.d.ts +1 -0
  131. package/local-nav/local-nav-dropdown/local-nav-dropdown.js +1 -1
  132. package/local-nav/local-nav-dropdown/local-nav-dropdown.js.map +1 -1
  133. package/local-nav/local-nav-dropdown/local-nav-dropdown.styles.d.ts +3 -0
  134. package/local-nav/local-nav-dropdown/local-nav-dropdown.styles.js +1 -1
  135. package/local-nav/local-nav-dropdown/local-nav-dropdown.styles.js.map +1 -1
  136. package/{cjs/local-nav/local-nav-dropdown/local-nav-dropdown.styles_uhd4xl.css → local-nav/local-nav-dropdown/local-nav-dropdown.styles_kpel1m.css} +9 -6
  137. package/local-nav/local-nav-menu/local-nav-menu.js +1 -1
  138. package/local-nav/local-nav-menu/local-nav-menu.js.map +1 -1
  139. package/local-nav/local-nav-menu/local-nav-menu.styles.d.ts +3 -0
  140. package/local-nav/local-nav-menu/local-nav-menu.styles.js +1 -1
  141. package/local-nav/local-nav-menu/local-nav-menu.styles.js.map +1 -1
  142. package/local-nav/local-nav-menu/local-nav-menu.styles_67fcyc.css +8 -0
  143. package/local-nav/types.d.ts +17 -0
  144. package/masked-input/types.d.ts +1 -2
  145. package/menu/menu-content.js +1 -1
  146. package/menu/menu-content.js.map +1 -1
  147. package/menu/menu-content.styles.d.ts +1 -0
  148. package/menu/menu-content.styles.js +1 -1
  149. package/menu/menu-content.styles.js.map +1 -1
  150. package/menu/menu-content.styles_1r8oxtk.css +5 -0
  151. package/menu/menu-item.styles.js +1 -1
  152. package/menu/menu-item.styles.js.map +1 -1
  153. package/menu/{menu-item.styles_liyed8.css → menu-item.styles_eut2j9.css} +1 -1
  154. package/menu/menu-link.styles.js +1 -1
  155. package/menu/menu-link.styles.js.map +1 -1
  156. package/menu/menu-link.styles_rng7n7.css +2 -0
  157. package/menu/menu-section.d.ts +1 -1
  158. package/menu/menu-section.js +1 -1
  159. package/menu/menu-section.js.map +1 -1
  160. package/menu/menu-section.styles.d.ts +7 -0
  161. package/menu/menu-section.styles.js +1 -1
  162. package/menu/menu-section.styles.js.map +1 -1
  163. package/menu/menu-section.styles_1n0ppxl.css +5 -0
  164. package/menu/menu.d.ts +1 -1
  165. package/menu/types.d.ts +10 -2
  166. package/modal-v2/slots/slot-styles.js +1 -1
  167. package/modal-v2/slots/slot-styles.js.map +1 -1
  168. package/modal-v2/slots/{slot-styles_ayb9il.css → slot-styles_ygu6zc.css} +1 -1
  169. package/navbar/navbar-items.js +1 -1
  170. package/navbar/navbar-items.js.map +1 -1
  171. package/navbar/types.d.ts +9 -0
  172. package/notification-banner/notification-banner-hoc.js +1 -1
  173. package/notification-banner/notification-banner-hoc.js.map +1 -1
  174. package/package.json +3 -4
  175. package/pagination/pagination.js +1 -1
  176. package/pagination/pagination.js.map +1 -1
  177. package/pagination/types.d.ts +8 -1
  178. package/scripts/cli.js +18 -0
  179. package/select-histogram/types.d.ts +1 -0
  180. package/shared/dropdown-list/dropdown-label.d.ts +2 -2
  181. package/shared/dropdown-list/dropdown-label.js +1 -1
  182. package/shared/dropdown-list/dropdown-label.js.map +1 -1
  183. package/shared/dropdown-list/types.d.ts +6 -2
  184. package/shared/fade-wrapper/fade-wrapper.js +1 -1
  185. package/shared/fade-wrapper/fade-wrapper.js.map +1 -1
  186. package/shared/fade-wrapper/types.d.ts +1 -0
  187. package/shared/styles/index.d.ts +5 -0
  188. package/skills/fds-build/SKILL.md +167 -0
  189. package/skills/fds-build/catalogue.md +181 -0
  190. package/skills/fds-build/evals/evals.json +519 -0
  191. package/skills/fds-build/resources/components/accordion.md +128 -0
  192. package/skills/fds-build/resources/components/alert.md +54 -0
  193. package/skills/fds-build/resources/components/animation.md +18 -0
  194. package/skills/fds-build/resources/components/avatar.md +10 -0
  195. package/skills/fds-build/resources/components/badge.md +18 -0
  196. package/skills/fds-build/resources/components/box-container.md +61 -0
  197. package/skills/fds-build/resources/components/breadcrumb.md +60 -0
  198. package/skills/fds-build/resources/components/button.md +74 -0
  199. package/skills/fds-build/resources/components/calendar.md +113 -0
  200. package/skills/fds-build/resources/components/card.md +43 -0
  201. package/skills/fds-build/resources/components/checkbox.md +53 -0
  202. package/skills/fds-build/resources/components/countdown-timer.md +20 -0
  203. package/skills/fds-build/resources/components/data-table.md +142 -0
  204. package/skills/fds-build/resources/components/date-navigator.md +25 -0
  205. package/skills/fds-build/resources/components/divider.md +23 -0
  206. package/skills/fds-build/resources/components/drawer.md +78 -0
  207. package/skills/fds-build/resources/components/error-display.md +137 -0
  208. package/skills/fds-build/resources/components/feedback-rating.md +61 -0
  209. package/skills/fds-build/resources/components/file-download.md +54 -0
  210. package/skills/fds-build/resources/components/file-upload.md +105 -0
  211. package/skills/fds-build/resources/components/filter.md +228 -0
  212. package/skills/fds-build/resources/components/footer.md +94 -0
  213. package/skills/fds-build/resources/components/form-date-input.md +85 -0
  214. package/skills/fds-build/resources/components/form-date-range-input.md +146 -0
  215. package/skills/fds-build/resources/components/form-e-signature.md +55 -0
  216. package/skills/fds-build/resources/components/form-input.md +65 -0
  217. package/skills/fds-build/resources/components/form-masked-input.md +69 -0
  218. package/skills/fds-build/resources/components/form-multi-select.md +100 -0
  219. package/skills/fds-build/resources/components/form-nested-multi-select.md +159 -0
  220. package/skills/fds-build/resources/components/form-nested-select.md +151 -0
  221. package/skills/fds-build/resources/components/form-otp-verification.md +175 -0
  222. package/skills/fds-build/resources/components/form-phone-number-input.md +87 -0
  223. package/skills/fds-build/resources/components/form-predictive-text-input.md +108 -0
  224. package/skills/fds-build/resources/components/form-select.md +103 -0
  225. package/skills/fds-build/resources/components/form-slider.md +116 -0
  226. package/skills/fds-build/resources/components/form-textarea.md +116 -0
  227. package/skills/fds-build/resources/components/form-time-range-picker.md +98 -0
  228. package/skills/fds-build/resources/components/form-timepicker.md +77 -0
  229. package/skills/fds-build/resources/components/form-unit-number-input.md +138 -0
  230. package/skills/fds-build/resources/components/fullscreen-image-carousel.md +159 -0
  231. package/skills/fds-build/resources/components/histogram-slider.md +41 -0
  232. package/skills/fds-build/resources/components/icon.md +167 -0
  233. package/skills/fds-build/resources/components/image-button.md +12 -0
  234. package/skills/fds-build/resources/components/input.md +51 -0
  235. package/skills/fds-build/resources/components/language-switcher.md +15 -0
  236. package/skills/fds-build/resources/components/layout.md +156 -0
  237. package/skills/fds-build/resources/components/link-list.md +120 -0
  238. package/skills/fds-build/resources/components/local-nav.md +119 -0
  239. package/skills/fds-build/resources/components/masthead.md +14 -0
  240. package/skills/fds-build/resources/components/menu.md +109 -0
  241. package/skills/fds-build/resources/components/modal.md +150 -0
  242. package/skills/fds-build/resources/components/navbar.md +270 -0
  243. package/skills/fds-build/resources/components/notification-banner.md +106 -0
  244. package/skills/fds-build/resources/components/pagination.md +104 -0
  245. package/skills/fds-build/resources/components/pill.md +55 -0
  246. package/skills/fds-build/resources/components/popover.md +80 -0
  247. package/skills/fds-build/resources/components/progress-indicator.md +47 -0
  248. package/skills/fds-build/resources/components/radio-button.md +66 -0
  249. package/skills/fds-build/resources/components/schedule.md +78 -0
  250. package/skills/fds-build/resources/components/sidenav.md +183 -0
  251. package/skills/fds-build/resources/components/singpass-button.md +14 -0
  252. package/skills/fds-build/resources/components/smart-app-banner.md +28 -0
  253. package/skills/fds-build/resources/components/tab.md +107 -0
  254. package/skills/fds-build/resources/components/table.md +65 -0
  255. package/skills/fds-build/resources/components/tag.md +68 -0
  256. package/skills/fds-build/resources/components/text-list.md +44 -0
  257. package/skills/fds-build/resources/components/time-slot-bar-week.md +66 -0
  258. package/skills/fds-build/resources/components/time-slot-bar.md +57 -0
  259. package/skills/fds-build/resources/components/time-slot-week-view.md +70 -0
  260. package/skills/fds-build/resources/components/timeline.md +69 -0
  261. package/skills/fds-build/resources/components/timetable.md +123 -0
  262. package/skills/fds-build/resources/components/toast.md +72 -0
  263. package/skills/fds-build/resources/components/toggle.md +119 -0
  264. package/skills/fds-build/resources/components/typography.md +86 -0
  265. package/skills/fds-build/resources/components/uneditable-section.md +84 -0
  266. package/skills/fds-build/resources/foundations/layout-composition-patterns.md +53 -0
  267. package/skills/fds-build/resources/foundations/tokens.md +547 -0
  268. package/skills/fds-build/resources/patterns/states.md +300 -0
  269. package/skills/fds-build/resources/setup/setup.md +202 -0
  270. package/skills/fds-build/resources/templates/form.md +427 -0
  271. package/skills/fds-build/resources/templates/listing.md +435 -0
  272. package/theme/styles/a11y-playground.css +52 -40
  273. package/theme/styles/bookingsg.css +52 -40
  274. package/theme/styles/careercompass.css +52 -40
  275. package/theme/styles/ccube.css +52 -40
  276. package/theme/styles/imda.css +52 -40
  277. package/theme/styles/lifesg.css +52 -40
  278. package/theme/styles/mylegacy.css +52 -40
  279. package/theme/styles/oneservice.css +52 -40
  280. package/theme/styles/pa.css +28 -22
  281. package/theme/styles/rbs.css +52 -40
  282. package/theme/styles/sgw-digital-lobby.css +52 -40
  283. package/theme/styles/smgs.css +52 -40
  284. package/theme/styles/spf.css +28 -27
  285. package/theme/styles/sportsg-orange.css +52 -40
  286. package/theme/styles/supportgowhere.css +52 -40
  287. package/theme/styles/tote-board.css +52 -40
  288. package/theme/styles/vica.css +52 -40
  289. package/theme/styles/websg.css +52 -40
  290. package/theme/styles/wise.css +52 -40
  291. package/theme/styles/wogaa.css +52 -40
  292. package/theme/tokens/colour.d.ts +6 -0
  293. package/theme/tokens/colour.js +1 -1
  294. package/theme/tokens/colour.js.map +1 -1
  295. package/theme/tokens/radius.d.ts +3 -0
  296. package/theme/tokens/radius.js +1 -1
  297. package/theme/tokens/radius.js.map +1 -1
  298. package/breadcrumb/breadcrumb.styles_1nl4aua.css +0 -18
  299. package/cjs/breadcrumb/breadcrumb.styles_1nl4aua.css +0 -18
  300. package/cjs/file-upload/file-item-edit.js +0 -2
  301. package/cjs/file-upload/file-item-edit.js.map +0 -1
  302. package/cjs/file-upload/file-item-edit.styles.js +0 -2
  303. package/cjs/file-upload/file-item-edit.styles.js.map +0 -1
  304. package/cjs/file-upload/file-item-edit.styles_19bvztn.css +0 -11
  305. package/cjs/file-upload/file-list/file-list.styles_1w7so98.css +0 -3
  306. package/cjs/file-upload/file-list-item/file-list-item.styles_kgtfke.css +0 -17
  307. package/cjs/local-nav/local-nav-menu/local-nav-menu.styles_pq19dh.css +0 -5
  308. package/cjs/menu/menu-content.styles_p7ijll.css +0 -2
  309. package/cjs/menu/menu-link.styles_hfxoez.css +0 -2
  310. package/cjs/menu/menu-section.styles_g7my4d.css +0 -3
  311. package/file-upload/file-item-edit.d.ts +0 -14
  312. package/file-upload/file-item-edit.js +0 -2
  313. package/file-upload/file-item-edit.js.map +0 -1
  314. package/file-upload/file-item-edit.styles.d.ts +0 -9
  315. package/file-upload/file-item-edit.styles.js +0 -2
  316. package/file-upload/file-item-edit.styles.js.map +0 -1
  317. package/file-upload/file-item-edit.styles_19bvztn.css +0 -11
  318. package/file-upload/file-list/file-list.styles_1w7so98.css +0 -3
  319. package/file-upload/file-list-item/file-list-item.styles_kgtfke.css +0 -17
  320. package/local-nav/local-nav-menu/local-nav-menu.styles_pq19dh.css +0 -5
  321. package/menu/menu-content.styles_p7ijll.css +0 -2
  322. package/menu/menu-link.styles_hfxoez.css +0 -2
  323. package/menu/menu-section.styles_g7my4d.css +0 -3
@@ -0,0 +1,54 @@
1
+ # Alert
2
+
3
+ Import: `import { Alert } from "@lifesg/react-design-system/alert"`
4
+
5
+ ## When to use
6
+
7
+ Use to call out important information within page sections — warnings before a user starts a task, informational notes relevant to a specific section, or non-transient status messages. Not for form validation errors (use form error patterns instead).
8
+
9
+ ## Variants
10
+
11
+ | `type` | When to use |
12
+ | --------------- | ------------------------------------------ |
13
+ | `"success"` | Action completed successfully |
14
+ | `"error"` | Action failed or system error |
15
+ | `"warning"` | User should proceed with caution |
16
+ | `"info"` | Neutral informational message |
17
+ | `"description"` | Descriptive content with no status meaning |
18
+
19
+ ## Usage
20
+
21
+ ```tsx
22
+ import { Alert } from "@lifesg/react-design-system/alert";
23
+
24
+ <Alert type="warning" showIcon role="alert">
25
+ Your session will expire in 5 minutes. Save your work to avoid losing
26
+ progress.
27
+ </Alert>;
28
+ ```
29
+
30
+ ## Props — `AlertProps`
31
+
32
+ | Prop | Type | Default | Description |
33
+ | -------------------- | ----------------------------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
34
+ | `type` \* | `AlertType` | — | Visual severity or purpose of the alert banner. |
35
+ | `actionLink` | `React.AnchorHTMLAttributes<HTMLAnchorElement>` | — | Anchor attributes for an optional call-to-action link rendered below the alert content. The link is styled with a trailing arrow icon by default; supply `actionLinkIcon` to replace that icon. |
36
+ | `showIcon` | `boolean` | false | Renders the type-specific icon to the left of the content. |
37
+ | `actionLinkIcon` | `JSX.Element` | <ArrowRightIcon /> | Replaces the default trailing arrow on the action link. Only visible when `actionLink` is also provided. |
38
+ | `sizeType` | `AlertSizeType` | — | Controls the overall size of the alert, affecting typography and icon dimensions. |
39
+ | `customIcon` | `JSX.Element` | — | Replaces the default type-specific icon. Only visible when `showIcon` is `true`. |
40
+ | `maxCollapsedHeight` | `number` | — | Maximum height in pixels before the content area is collapsed. When the rendered content exceeds this value a "Show more / Show less" toggle is displayed. The content container is marked as inert whenever the collapsed state is active. |
41
+
42
+ ## Rules
43
+
44
+ - Always use `showIcon` — icons provide immediate visual recognition of alert severity.
45
+ - Use `actionLink` for recoverable errors (retry, undo, view details).
46
+ - Set `role` based on how the alert appears: `"alert"` for dynamic alerts triggered by user action, `"status"` for background status updates, omit for static content visible on page load.
47
+ - Use `maxCollapsedHeight` to avoid long content overwhelming the layout.
48
+ - `role` is not set automatically — set `role="alert"` for dynamic alerts, `role="status"` for background updates, and omit for static content.
49
+
50
+ ## Anti-patterns
51
+
52
+ - Using Alert for form field validation errors — use inline form error patterns instead.
53
+ - Omitting `role` on dynamically injected alerts — screen readers will not announce them.
54
+ - Using `type="description"` with `showIcon` — description has no semantic status meaning.
@@ -0,0 +1,18 @@
1
+ # Animation
2
+
3
+ Import: `import { Animation } from "@lifesg/react-design-system/animation"`
4
+
5
+ ## Props — `AnimationProps`
6
+
7
+ | Prop | Type | Default | Description |
8
+ | ----------- | -------- | ------- | ----------- |
9
+ | `id` | `string` | — | — |
10
+ | `className` | `string` | — | — |
11
+
12
+ ## Props — `CustomisableAnimationProps`
13
+
14
+ | Prop | Type | Default | Description |
15
+ | ----------- | ------------------------------------------------------------------------- | ------- | -------------------------------------------------------- |
16
+ | `id` | `string` | — | — |
17
+ | `className` | `string` | — | — |
18
+ | `color` | `\| string \| ColourCSSVariableString \| ComponentTokenCSSVariableString` | — | The color that is to be applied on the animated elements |
@@ -0,0 +1,10 @@
1
+ # Avatar
2
+
3
+ Import: `import { Avatar } from "@lifesg/react-design-system/avatar"`
4
+
5
+ ## Props — `AvatarProps`
6
+
7
+ | Prop | Type | Default | Description |
8
+ | ------------- | ----------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
9
+ | `children` \* | `string \| JSX.Element` | — | A string or JSX element to display inside the avatar. When a string is provided, only the first Unicode code point is rendered as an uppercase initial. Pass a JSX element (e.g. an `<img>`) to render custom content. |
10
+ | `sizeType` | `AvatarSize` | — | Controls the visual size of the avatar. `"small"` renders a compact variant with reduced typography; `"default"` uses the standard size. |
@@ -0,0 +1,18 @@
1
+ # Badge
2
+
3
+ Import: `import { Badge } from "@lifesg/react-design-system/badge"`
4
+
5
+ ## Props — `BadgeProps`
6
+
7
+ | Prop | Type | Default | Description |
8
+ | ------------- | ------------------ | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
9
+ | `badgeOffset` | `[string, string]` | — | Horizontal and vertical offset applied to the badge when it overlays a child element. Provided as a `[x, y]` tuple of CSS length values (e.g. `["-4px", "-4px"]`). Ignored when no child is rendered. |
10
+ | `children` | `JSX.Element` | — | Element that the badge overlays. When provided, the badge is positioned absolutely over the top-right corner of this child. Omit to render the badge as a standalone indicator. |
11
+ | `color` | `BadgeColor` | "default" | Color scheme applied to the badge. |
12
+ | `count` | `number` | — | Numeric value displayed inside `number`, `number-with-border`, and `square-number` variants. Values above 1000 are capped and shown as `"1K"` or `"1K+"`. Has no effect on dot variants. |
13
+ | `variant` | `BadgeVariant` | "number" | Visual style of the badge indicator. |
14
+
15
+ ## Rules
16
+
17
+ - `count` only applies to `"number"`, `"number-with-border"`, and `"square-number"` variants.
18
+ - When `children` is provided, the badge overlays the top-right corner of the child element.
@@ -0,0 +1,61 @@
1
+ # BoxContainer
2
+
3
+ Import: `import { BoxContainer } from "@lifesg/react-design-system/box-container"`
4
+
5
+ ## When to use
6
+
7
+ Use for a single collapsible panel displaying form data or structured content — typically a named section within a form or detail view. Supports an optional header action and a status indicator to flag section-level errors or warnings.
8
+
9
+ ## Sub-components
10
+
11
+ ### BoxContainerSubComponentTestIds
12
+
13
+ | Prop | Type | Description |
14
+ | ------------------ | -------- | -------------------------------------- |
15
+ | `title` | `string` | Test id for the header title |
16
+ | `displayStateIcon` | `string` | Test id for the display state icon |
17
+ | `handle` | `string` | Test id for the expand/collapse handle |
18
+
19
+ ## Variants
20
+
21
+ | `displayState` | When to use |
22
+ | -------------- | ------------------------------------------ |
23
+ | `"default"` | Normal state — no icon |
24
+ | `"error"` | Section has validation errors |
25
+ | `"warning"` | Section has a warning that needs attention |
26
+
27
+ ## Props — `BoxContainerSubComponentTestIds`
28
+
29
+ | Prop | Type | Default | Description |
30
+ | ------------------ | -------- | ------- | ----------- |
31
+ | `title` | `string` | — | — |
32
+ | `handle` | `string` | — | — |
33
+ | `displayStateIcon` | `string` | — | — |
34
+
35
+ ## Props — `BoxContainerProps`
36
+
37
+ | Prop | Type | Default | Description |
38
+ | ----------------------- | --------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
39
+ | `children` \* | `JSX.Element \| JSX.Element[]` | — | — |
40
+ | `title` \* | `string \| JSX.Element` | — | — |
41
+ | `collapsible` | `boolean` | true | When `false`, the container is always expanded and the collapse handle is hidden. |
42
+ | `expanded` | `boolean` | false | Initial expanded state when `collapsible` is `true`. |
43
+ | `callToActionComponent` | `JSX.Element` | — | Optional element rendered in the header alongside the title, e.g. a link or button. |
44
+ | `displayState` | `BoxContainerDisplayState` | "default" | Renders an inline alert icon next to the title and announces the state to screen readers. Has no effect when set to `"default"`. |
45
+ | `className` | `string` | — | — |
46
+ | `subComponentTestIds` | `BoxContainerSubComponentTestIds` | — | — |
47
+ | `id` | `string` | — | — |
48
+ | `clickableHeader` | `boolean` | — | When `true` (and `collapsible` is also `true`), the entire header row becomes a click target for toggling expand/collapse, not just the chevron button. |
49
+
50
+ ## Rules
51
+
52
+ - Use `displayState` to indicate section-level status — not as a substitute for inline field errors.
53
+ - Use `callToActionComponent` for section-level actions only — not for form submission buttons.
54
+ - Use `collapsible={false}` when the content must always be visible.
55
+ - Use `clickableHeader` to make the full header row the expand/collapse trigger — improves usability for dense layouts.
56
+
57
+ ## Anti-patterns
58
+
59
+ - Using `displayState="error"` instead of inline form field errors — `displayState` signals section-level status only.
60
+ - Using `callToActionComponent` for form submission — use a dedicated submit button outside the container.
61
+ - Nesting BoxContainer inside another BoxContainer.
@@ -0,0 +1,60 @@
1
+ # Breadcrumb
2
+
3
+ Import: `import { Breadcrumb } from "@lifesg/react-design-system/breadcrumb"`
4
+
5
+ ## When to use
6
+
7
+ Use on pages within a multi-level hierarchy to help users navigate to parent pages.
8
+
9
+ Do not use on:
10
+
11
+ - The home page
12
+ - Pages with no parent
13
+ - Focused flows such as forms or wizards
14
+
15
+ ## Variants
16
+
17
+ | `separatorStyle` | When to use |
18
+ | --------------------- | ------------------------ |
19
+ | `"chevron"` (default) | Standard pages |
20
+ | `"slash"` | Alternative visual style |
21
+
22
+ ## Usage
23
+
24
+ ```tsx
25
+ import { Breadcrumb } from "@lifesg/react-design-system/breadcrumb";
26
+
27
+ <Breadcrumb
28
+ links={[
29
+ { children: "Home", href: "/" },
30
+ { children: "Services", href: "/services" },
31
+ { children: "Apply" },
32
+ ]}
33
+ />;
34
+ ```
35
+
36
+ ## Props
37
+
38
+ | Prop | Type | Default | Description |
39
+ | ---------------- | ------------------------------------------------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
40
+ | `links` \* | `React.AnchorHTMLAttributes<HTMLAnchorElement>[]` | — | Navigation items rendered as the breadcrumb trail. The last item is treated as the current page (`aria-current="page"`) and is not clickable. Items without `href` render as non-clickable labels. Items without `children` are skipped. |
41
+ | `fadeColor` | `string[] \| FadeColorSet` | — | Gradient color stops for the fade overlays shown on horizontal scroll. Pass a `string[]` to apply the same gradient to both edges, or a `FadeColorSet` to configure each edge independently. |
42
+ | `fadePosition` | `FadePosition` | "both" | Which edges display fade overlays when content overflows. |
43
+ | `separatorStyle` | `SeparatorStyle` | "chevron" | Visual separator between breadcrumb items. |
44
+ | `className` | `string` | — | — |
45
+ | `id` | `string` | "breadcrumb" | HTML `id` for the wrapper element. |
46
+
47
+ ## Rules
48
+
49
+ - Always place the current page last in `links` — omit `href` on the last item.
50
+ - Keep breadcrumb trails to 4 items or fewer; 5 or more items automatically collapse the middle into an overflow menu.
51
+ - Set `fadeColor` to match the page background so the horizontal scroll fade blends correctly on mobile.
52
+ - The last item in `links` is rendered as the current page (non-clickable, `aria-current="page"`). Omit `href` on the last item.
53
+ - When 5 or more items are present, middle items automatically collapse into an overflow menu.
54
+ - On mobile, breadcrumbs scroll horizontally with a fade effect at the edges controlled by `fadeColor` and `fadePosition`.
55
+
56
+ ## Anti-patterns
57
+
58
+ - Do not add `href` to the last breadcrumb item — it represents the current page and must not be clickable.
59
+ - Do not use breadcrumbs on single-level or flat navigation structures.
60
+ - Do not use breadcrumbs inside forms or wizard flows.
@@ -0,0 +1,74 @@
1
+ # Button
2
+
3
+ Import: `import { Button } from "@lifesg/react-design-system/button"`
4
+
5
+ ## When to use
6
+
7
+ `Button` handles all button variants in v4 — there are no separate `IconButton` or `ButtonWithIcon` components:
8
+
9
+ | Need | Usage |
10
+ | ------------------- | ---------------------------------------------------------------- |
11
+ | Text only | `<Button>Label</Button>` |
12
+ | Text + icon | `<Button icon={<Icon />}>Label</Button>` — icon defaults to left |
13
+ | Icon only (no text) | `<Button icon={<Icon />} aria-label="..." />` — renders square |
14
+
15
+ ## Size variants
16
+
17
+ | Usage | When to use |
18
+ | ------------------------------------------- | ------------------------------------------------------- |
19
+ | `<Button>` or `<Button sizeType="default">` | Standard size — use for all buttons including hero CTAs |
20
+ | `<Button sizeType="small">` | Dense layouts, toolbars |
21
+ | `<Button sizeType="large">` | Only when explicitly specified — do not use by default |
22
+
23
+ > **Deprecated:** `Button.Default`, `Button.Small`, `Button.Large` sub-components are deprecated in v4. Use `<Button sizeType="...">` instead.
24
+
25
+ ## Variants
26
+
27
+ | `styleType` | When to use |
28
+ | ------------- | ------------------------------------- |
29
+ | `"default"` | Main action on the page |
30
+ | `"secondary"` | Cancel, go back, alternative option |
31
+ | `"light"` | On colored or dark backgrounds |
32
+ | `"link"` | Tertiary, de-emphasized inline action |
33
+
34
+ Add `danger` for destructive actions (delete, remove) — applies to any `styleType`.
35
+
36
+ ## Usage
37
+
38
+ ```tsx
39
+ import { Button } from "@lifesg/react-design-system/button";
40
+
41
+ <Button styleType="default" onClick={() => {}}>
42
+ Save changes
43
+ </Button>;
44
+ ```
45
+
46
+ ## Props
47
+
48
+ | Prop | Type | Default | Description |
49
+ | ----------------------- | -------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
50
+ | `styleType` | `ButtonStyleType` | "default" | Visual style variant of the button. |
51
+ | `sizeType` | `ButtonSizeType` | "default" | Controls the button's size. |
52
+ | `danger` | `boolean` | false | Applies a red color scheme for destructive actions. |
53
+ | `loading` | `boolean` | false | Displays a loading spinner and sets `aria-busy` on the button. The spinner replaces the icon (if present); children continue to render. |
54
+ | `focusableWhenDisabled` | `boolean` | false | Keeps the button keyboard-focusable when disabled. When true, the HTML `disabled` attribute is not set, but `aria-disabled` remains true and the click handler is suppressed. |
55
+ | `icon` | `JSX.Element` | — | Icon element rendered inside the button. The icon receives `aria-hidden` automatically. When provided without children, the button renders in icon-only mode (square layout) — provide `aria-label` on the button for accessibility in that case. |
56
+ | `iconPosition` | `ButtonIconPosition` | "left" | Position of the icon relative to the button label. |
57
+
58
+ ## Rules
59
+
60
+ - `styleType` is mandatory.
61
+ - Use sentence case for all labels — "Save changes" not "Save Changes".
62
+ - Use concise verb + noun labels — avoid "OK", "Yes", "Click here".
63
+ - Do not use `sizeType="large"` unless explicitly required — default size is correct for hero CTAs.
64
+ - Combine `loading` and `disabled` during async operations to prevent double-submission.
65
+ - Never use raw `<button>` elements — always use design system button components.
66
+ - Do not nest buttons inside buttons or links.
67
+ - `danger` applies to any `styleType`.
68
+
69
+ ## Anti-patterns
70
+
71
+ - Do not use `sizeType="large"` as a default choice — it is a special case only.
72
+ - Do not use `Button.Default`, `Button.Small`, or `Button.Large` — these sub-components are deprecated in v4.
73
+ - Do not use vague labels like "OK" or "Yes" — labels must describe the action.
74
+ - Do not use `loading` alone without also setting `disabled`.
@@ -0,0 +1,113 @@
1
+ # Calendar
2
+
3
+ Import: `import { Calendar } from "@lifesg/react-design-system/calendar"`
4
+
5
+ ## When to use
6
+
7
+ - Displaying an inline date picker when a full-page or panel calendar is preferable over a dropdown.
8
+ - Use `variant="single"` for standard single-date selection.
9
+ - Use `variant="multi"` when the user must pick multiple non-contiguous dates (e.g. recurring appointments).
10
+
11
+ ## Usage
12
+
13
+ ### variant="single" — single date selection
14
+
15
+ ```tsx
16
+ import { useState } from "react";
17
+ import { Calendar } from "@lifesg/react-design-system/calendar";
18
+
19
+ const AppointmentCalendar = () => {
20
+ const [date, setDate] = useState("2024-06-15");
21
+
22
+ return (
23
+ <Calendar
24
+ variant="single"
25
+ value={date}
26
+ minDate="2024-01-01"
27
+ maxDate="2024-12-31"
28
+ onChange={(selected) => setDate(selected)}
29
+ />
30
+ );
31
+ };
32
+ ```
33
+
34
+ ### variant="multi" — multiple date selection
35
+
36
+ Note `values` (plural) and `onChange` receives the full updated array.
37
+
38
+ ```tsx
39
+ import { useState } from "react";
40
+ import { Calendar } from "@lifesg/react-design-system/calendar";
41
+
42
+ const MultiDateCalendar = () => {
43
+ const [dates, setDates] = useState<string[]>([]);
44
+
45
+ return (
46
+ <Calendar
47
+ variant="multi"
48
+ values={dates}
49
+ minDate="2024-01-01"
50
+ maxDate="2024-12-31"
51
+ maxSelectable={5}
52
+ onChange={(selected) => setDates(selected)}
53
+ />
54
+ );
55
+ };
56
+ ```
57
+
58
+ ## YearMonthDisplay
59
+
60
+ | Prop | Type | Description |
61
+ | ------- | -------- | ------------------------------------- |
62
+ | `year` | `number` | Current visible year in `YYYY` format |
63
+ | `month` | `number` | Current visible month, 1–12 |
64
+
65
+ ## Props — `CalendarSingleProps`
66
+
67
+ | Prop | Type | Default | Description |
68
+ | ---------- | --------------------------- | -------- | -------------------------------------- |
69
+ | `variant` | `"single"` | "single" | — |
70
+ | `value` | `string` | — | Selected date in `YYYY-MM-DD` format |
71
+ | `onChange` | `((value: string) => void)` | — | Called when the selected date changes. |
72
+ | `onSelect` | `((value: string) => void)` | — | Called when a date is selected. |
73
+
74
+ ## Props — `CalendarMultiProps`
75
+
76
+ | Prop | Type | Default | Description |
77
+ | --------------- | ------------------------------ | ------- | --------------------------------------------- |
78
+ | `variant` \* | `"multi"` | — | — |
79
+ | `values` | `string[]` | — | Selected dates in `YYYY-MM-DD` format |
80
+ | `minSelectable` | `number` | — | Minimum number of dates that must be selected |
81
+ | `maxSelectable` | `number` | — | Maximum number of dates that can be selected |
82
+ | `onChange` | `((values: string[]) => void)` | — | Called when the selection changes. |
83
+
84
+ ## Props — `CalendarProps`
85
+
86
+ | Prop | Type | Default | Description |
87
+ | -------------------------- | ------------------------------------- | ---------- | ----------------------------------------------------------------------------------------------------- |
88
+ | `className` | `string` | — | — |
89
+ | `id` | `string` | — | — |
90
+ | `styleType` | `"no-border" \| "bordered"` | "bordered" | Border style of the calendar container. |
91
+ | `onHover` | `((value: string) => void)` | — | Called when a day cell is hovered. |
92
+ | `onYearMonthDisplayChange` | `((value: YearMonthDisplay) => void)` | — | Called when the visible month or year changes. |
93
+ | `minDate` | `string` | — | The minimum date that can be selected (inclusive) in 'YYYY-MM-DD' format. |
94
+ | `maxDate` | `string` | — | The maximum date that can be selected (inclusive) in 'YYYY-MM-DD' format. |
95
+ | `disabledDates` | `string[]` | — | Dates to disable in `YYYY-MM-DD` format. Example: `["2023-04-30"]` |
96
+ | `allowDisabledSelection` | `boolean` | — | Specifies if dates normally disabled by `minDate`, `maxDate` and `disabledDates` are still selectable |
97
+ | `showActiveMonthDaysOnly` | `boolean` | — | Specifies if the calendar should display only dates for the selected month |
98
+ | `variant` | `"single"` | "single" | — |
99
+ | `onChange` | `((value: string) => void)` | — | Called when the selected date changes. |
100
+
101
+ ## Rules
102
+
103
+ - `variant="single"` uses `value: string` and `onChange: (date: string) => void`.
104
+ - `variant="multi"` uses `values: string[]` and `onChange: (dates: string[]) => void` — note the plural prop names.
105
+ - All dates must be in `YYYY-MM-DD` format.
106
+ - Use `minDate`/`maxDate` to constrain selectable range.
107
+ - Use `disabledDates` for specific non-selectable dates within the allowed range.
108
+
109
+ ## Anti-patterns
110
+
111
+ - Do not pass `value` to `variant="multi"` — the prop is `values` (plural).
112
+ - Do not pass `values` to `variant="single"` — the prop is `value` (singular).
113
+ - Do not use Calendar inside a form for simple date entry — prefer `Form.DateInput` for that pattern.
@@ -0,0 +1,43 @@
1
+ # Card
2
+
3
+ Import: `import { Card } from "@lifesg/react-design-system/card"`
4
+
5
+ ## When to use
6
+
7
+ Use to visually group related content — information panels, form sections, list items, or grid tiles.
8
+
9
+ ## Usage
10
+
11
+ ```tsx
12
+ import styles from "./Card.module.css";
13
+ import { Card } from "@lifesg/react-design-system/card";
14
+ import { Typography } from "@lifesg/react-design-system/typography";
15
+
16
+ <Card>
17
+ <div className={styles.cardBody}>
18
+ <Typography.HeadingSM>Card title</Typography.HeadingSM>
19
+ <Typography.BodyMD>Card content goes here.</Typography.BodyMD>
20
+ </div>
21
+ </Card>;
22
+ ```
23
+
24
+ ```css
25
+ /* Card.module.css */
26
+ .cardBody {
27
+ padding: var(--fds-spacing-24);
28
+ }
29
+ ```
30
+
31
+ ## Rules
32
+
33
+ - Card has no default padding — use `spacing-24` internal padding and `spacing-16` gap between content items as the standard.
34
+ - Shadow (`Shadow["md-subtle"]`) is applied automatically — do not add `box-shadow` manually.
35
+ - Do not nest cards inside cards.
36
+ - Use Typography components for all text inside Card — not raw HTML elements.
37
+ - Combine with `Layout.Container` and `Layout.ColDiv` for responsive card grids.
38
+
39
+ ## Anti-patterns
40
+
41
+ - Adding `box-shadow` via CSS — the Card component already applies the correct elevation shadow.
42
+ - Using raw `<div>` with custom styling instead of Card when the DS Card fits the use case.
43
+ - Nesting `<Card>` inside another `<Card>`.
@@ -0,0 +1,53 @@
1
+ # Checkbox
2
+
3
+ Import: `import { Checkbox } from "@lifesg/react-design-system/checkbox"`
4
+
5
+ ## When to use
6
+
7
+ - Simple boolean selections where a compact tick-box is sufficient.
8
+ - Table row selection (single or "select all").
9
+ - Filter lists with multiple independent options.
10
+ - "Select all" patterns using the `indeterminate` state.
11
+
12
+ Prefer `Toggle` over `Checkbox` when building form inputs that need a visible card-style label container.
13
+
14
+ ## Variants
15
+
16
+ | `displaySize` | When to use |
17
+ | ------------- | ------------------------------ |
18
+ | `"default"` | Standard use |
19
+ | `"small"` | Dense layouts, inline controls |
20
+
21
+ ## Usage
22
+
23
+ ```tsx
24
+ import { Checkbox } from "@lifesg/react-design-system/checkbox";
25
+
26
+ <label>
27
+ <Checkbox checked={agreed} onChange={(e) => {}} />I agree to the terms and
28
+ conditions
29
+ </label>;
30
+ ```
31
+
32
+ ## Props
33
+
34
+ | Prop | Type | Default | Description |
35
+ | ----------------------- | -------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
36
+ | `checked` | `boolean` | — | Controls the checked state of the checkbox. When omitted, the checkbox is uncontrolled. |
37
+ | `displaySize` | `CheckboxSize` | "default" | Controls the visual size of the checkbox. |
38
+ | `indeterminate` | `boolean` | — | Puts the checkbox into an indeterminate visual and accessibility state. |
39
+ | `focusableWhenDisabled` | `boolean` | — | Allows the checkbox to receive focus when `disabled` is true. When set alongside `disabled`, the native `disabled` attribute is omitted in favor of `aria-disabled="true"` and `tabIndex={0}`, keeping the element keyboard-reachable. `onChange` is still suppressed. |
40
+
41
+ ## Rules
42
+
43
+ - Always pair with a visible label — wrap in `<label>` or use `aria-label`.
44
+ - Use `indeterminate` for "select all" controls when only some items in a list are selected — not as a permanent state.
45
+ - Use the same `name` attribute when grouping checkboxes in a form.
46
+ - No dedicated `disabled` prop — use the inherited `disabled` from `InputHTMLAttributes`, or `focusableWhenDisabled` to retain focus while blocking interaction.
47
+ - `indeterminate` is a visual state; manage controlled `checked` separately.
48
+
49
+ ## Anti-patterns
50
+
51
+ - Do not use `indeterminate` as a permanent or final state — it is a transitional indicator only.
52
+ - Do not use `Checkbox` alone without a label — always provide accessible text.
53
+ - Do not use `Checkbox` when only one option from a set can be selected — use `RadioButton` instead.
@@ -0,0 +1,20 @@
1
+ # CountdownTimer
2
+
3
+ Import: `import { CountdownTimer } from "@lifesg/react-design-system/countdown-timer"`
4
+
5
+ ## Props
6
+
7
+ | Prop | Type | Default | Description |
8
+ | ------------------ | ----------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
9
+ | `show` \* | `boolean` | — | Controls whether the timer is visible and actively counting down. |
10
+ | `fixed` | `boolean` | true | When `true`, the timer switches to a fixed viewport overlay once its inline position scrolls out of view, keeping the countdown visible at all times. |
11
+ | `notifyTimer` | `number` | — | Remaining-seconds threshold at which the warning state activates. Once the countdown reaches this value, `onNotify` fires once and `onTick` fires every second until the timer finishes. |
12
+ | `offset` | `Offset` | — | Fine-tunes the fixed overlay position on tablet and desktop viewports. |
13
+ | `mobileOffset` | `MobileOffset` | { top: 80 } | Fine-tunes the fixed overlay position on mobile viewports. |
14
+ | `align` | `AlignPosition` | "right" | Side of the inline wrapper the fixed overlay is pinned to when scrolled into sticky mode. |
15
+ | `onTick` | `((seconds: number) => void)` | — | Called every second with the remaining seconds once the countdown falls at or below `notifyTimer`. |
16
+ | `onNotify` | `(() => void)` | — | Called once when the remaining seconds first reach the `notifyTimer` threshold. |
17
+ | `onFinish` | `(() => void)` | — | Called when the countdown reaches zero. |
18
+ | `reminderInterval` | `number` | 120 | Interval in seconds between polite screen-reader announcement of the remaining time while the timer is above the `notifyTimer` threshold. |
19
+ | `timer` \* | `number` | — | Duration of the countdown in seconds. |
20
+ | `timestamp` | `number` | — | — |