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

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 (753) 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 +1 -1
  23. package/button/button.js.map +1 -1
  24. package/button/button.styles.d.ts +1 -0
  25. package/button/button.styles.js +1 -1
  26. package/button/button.styles.js.map +1 -1
  27. package/button/button.styles_19i4dfq.css +21 -0
  28. package/button/types.d.ts +5 -0
  29. package/calendar/calendar.js.map +1 -1
  30. package/calendar/types.d.ts +3 -3
  31. package/card/card.js.map +1 -1
  32. package/checkbox/checkbox.js.map +1 -1
  33. package/checkbox/types.d.ts +4 -0
  34. package/cjs/accordion/accordion.js.map +1 -1
  35. package/cjs/alert/alert.js.map +1 -1
  36. package/cjs/animations/loading-dots/loading-dots.js.map +1 -1
  37. package/cjs/animations/loading-dots-spinner/loading-dots-spinner.js.map +1 -1
  38. package/cjs/animations/loading-dots-spinner/lottie-animation.js.map +1 -1
  39. package/cjs/animations/loading-spinner/loading-spinner.js.map +1 -1
  40. package/cjs/animations/themed-loading-spinner/themed-loading-spinner.js.map +1 -1
  41. package/cjs/avatar/avatar.js.map +1 -1
  42. package/cjs/badge/badge.js.map +1 -1
  43. package/cjs/box-container/box-container.js.map +1 -1
  44. package/cjs/breadcrumb/breadcrumb.js.map +1 -1
  45. package/cjs/button/button.js +1 -1
  46. package/cjs/button/button.js.map +1 -1
  47. package/cjs/button/button.styles.js +1 -1
  48. package/cjs/button/button.styles.js.map +1 -1
  49. package/cjs/button/button.styles_19i4dfq.css +21 -0
  50. package/cjs/calendar/calendar.js.map +1 -1
  51. package/cjs/card/card.js.map +1 -1
  52. package/cjs/checkbox/checkbox.js.map +1 -1
  53. package/cjs/countdown-timer/countdown-timer.js.map +1 -1
  54. package/cjs/dashed-border/dashed-border.js.map +1 -1
  55. package/cjs/data-table/data-table.js +1 -1
  56. package/cjs/data-table/data-table.js.map +1 -1
  57. package/cjs/data-table/data-table.styles.js +1 -1
  58. package/cjs/data-table/data-table.styles.js.map +1 -1
  59. package/cjs/data-table/{data-table.styles_rxganh.css → data-table.styles_1tnlmhe.css} +7 -6
  60. package/cjs/date-input/date-input.js.map +1 -1
  61. package/cjs/date-navigator/date-navigator.js.map +1 -1
  62. package/cjs/date-range-input/date-range-input.js.map +1 -1
  63. package/cjs/divider/divider.js.map +1 -1
  64. package/cjs/drawer/drawer.js.map +1 -1
  65. package/cjs/e-signature/e-signature.js.map +1 -1
  66. package/cjs/error-display/error-display-data.js +1 -1
  67. package/cjs/error-display/error-display-data.js.map +1 -1
  68. package/cjs/error-display/error-display.js.map +1 -1
  69. package/cjs/feedback-rating/feedback-rating.js.map +1 -1
  70. package/cjs/file-download/file-download.js.map +1 -1
  71. package/cjs/file-upload/file-item-edit.js.map +1 -1
  72. package/cjs/file-upload/file-list/file-list.js.map +1 -1
  73. package/cjs/file-upload/file-list-item/file-list-item.js.map +1 -1
  74. package/cjs/file-upload/file-list-item/file-list-item.styles.js +1 -1
  75. package/cjs/file-upload/file-list-item/file-list-item.styles.js.map +1 -1
  76. package/{file-upload/file-list-item/file-list-item.styles_o8000f.css → cjs/file-upload/file-list-item/file-list-item.styles_kgtfke.css} +1 -1
  77. package/cjs/file-upload/file-upload.js.map +1 -1
  78. package/cjs/filter/addons/filter-item-checkbox-helpers.js.map +1 -1
  79. package/cjs/filter/addons/filter-item-checkbox.js.map +1 -1
  80. package/cjs/filter/addons/filter-item-checkbox.styles.js +1 -1
  81. package/cjs/filter/addons/filter-item-checkbox.styles.js.map +1 -1
  82. package/cjs/filter/addons/{filter-item-checkbox.styles_7degw7.css → filter-item-checkbox.styles_6nbpdl.css} +1 -1
  83. package/cjs/filter/filter-item.js +1 -1
  84. package/cjs/filter/filter-item.js.map +1 -1
  85. package/cjs/filter/filter-item.styles.js +1 -1
  86. package/cjs/filter/filter-item.styles.js.map +1 -1
  87. package/cjs/filter/{filter-item.styles_cphjnj.css → filter-item.styles_1yixp8h.css} +1 -1
  88. package/cjs/filter/filter-modal.styles.js +1 -1
  89. package/cjs/filter/filter-modal.styles.js.map +1 -1
  90. package/{filter/filter-modal.styles_qw3xlg.css → cjs/filter/filter-modal.styles_kuth21.css} +1 -1
  91. package/cjs/filter/filter-sidebar.styles.js +1 -1
  92. package/cjs/filter/filter-sidebar.styles.js.map +1 -1
  93. package/cjs/filter/{filter-sidebar.styles_1otwpjl.css → filter-sidebar.styles_rbfq4f.css} +1 -1
  94. package/cjs/filter/filter.js.map +1 -1
  95. package/cjs/footer/footer.js.map +1 -1
  96. package/cjs/form/form-custom-field/form-custom-field.js +2 -0
  97. package/cjs/form/form-custom-field/form-custom-field.js.map +1 -0
  98. package/cjs/form/form-date-input/form-date-input.js +2 -0
  99. package/cjs/form/form-date-input/form-date-input.js.map +1 -0
  100. package/cjs/form/form-date-range-input/form-date-range-input.js +2 -0
  101. package/cjs/form/form-date-range-input/form-date-range-input.js.map +1 -0
  102. package/cjs/form/form-e-signature/form-e-signature.js +2 -0
  103. package/cjs/form/form-e-signature/form-e-signature.js.map +1 -0
  104. package/cjs/form/form-histogram-slider/form-histogram-slider.js +2 -0
  105. package/cjs/form/form-histogram-slider/form-histogram-slider.js.map +1 -0
  106. package/cjs/form/form-input/form-input.js +2 -0
  107. package/cjs/form/form-input/form-input.js.map +1 -0
  108. package/cjs/form/form-input-group/form-input-group.js +2 -0
  109. package/cjs/form/form-input-group/form-input-group.js.map +1 -0
  110. package/cjs/form/form-label/form-label-addon.js +2 -0
  111. package/cjs/form/form-label/form-label-addon.js.map +1 -0
  112. package/cjs/form/form-label/form-label-addon.styles.js +2 -0
  113. package/cjs/form/form-label/form-label-addon.styles.js.map +1 -0
  114. package/cjs/form/form-label/form-label-addon.styles_aztasj.css +1 -0
  115. package/cjs/form/form-label/form-label.js +2 -0
  116. package/cjs/form/form-label/form-label.js.map +1 -0
  117. package/cjs/form/form-label/form-label.styles.js +2 -0
  118. package/cjs/form/form-label/form-label.styles.js.map +1 -0
  119. package/cjs/form/form-label/form-label.styles_180zf7j.css +6 -0
  120. package/cjs/form/form-masked-input/form-masked-input.js +2 -0
  121. package/cjs/form/form-masked-input/form-masked-input.js.map +1 -0
  122. package/cjs/form/form-multi-select/form-multi-select.js +2 -0
  123. package/cjs/form/form-multi-select/form-multi-select.js.map +1 -0
  124. package/cjs/form/form-nested-multi-select/form-nested-multi-select.js +2 -0
  125. package/cjs/form/form-nested-multi-select/form-nested-multi-select.js.map +1 -0
  126. package/cjs/form/form-nested-select/form-nested-select.js +2 -0
  127. package/cjs/form/form-nested-select/form-nested-select.js.map +1 -0
  128. package/cjs/form/form-otp-verification/form-otp-verification.js +2 -0
  129. package/cjs/form/form-otp-verification/form-otp-verification.js.map +1 -0
  130. package/cjs/form/form-phone-number-input/form-phone-number-input.js +2 -0
  131. package/cjs/form/form-phone-number-input/form-phone-number-input.js.map +1 -0
  132. package/cjs/form/form-predictive-text-input/form-predictive-text-input.js +2 -0
  133. package/cjs/form/form-predictive-text-input/form-predictive-text-input.js.map +1 -0
  134. package/cjs/form/form-range-select/form-range-select.js +2 -0
  135. package/cjs/form/form-range-select/form-range-select.js.map +1 -0
  136. package/cjs/form/form-range-slider/form-range-slider.js +2 -0
  137. package/cjs/form/form-range-slider/form-range-slider.js.map +1 -0
  138. package/cjs/form/form-select/form-select.js +2 -0
  139. package/cjs/form/form-select/form-select.js.map +1 -0
  140. package/cjs/form/form-select-histogram/form-select-histogram.js +2 -0
  141. package/cjs/form/form-select-histogram/form-select-histogram.js.map +1 -0
  142. package/cjs/form/form-slider/form-slider.js +2 -0
  143. package/cjs/form/form-slider/form-slider.js.map +1 -0
  144. package/cjs/form/form-textarea/form-textarea.js +2 -0
  145. package/cjs/form/form-textarea/form-textarea.js.map +1 -0
  146. package/cjs/form/form-textarea/form-textarea.styles.js +2 -0
  147. package/cjs/form/form-textarea/form-textarea.styles.js.map +1 -0
  148. package/cjs/form/form-textarea/form-textarea.styles_1kneyif.css +3 -0
  149. package/cjs/form/form-time-range-picker/form-time-range-picker.js +2 -0
  150. package/cjs/form/form-time-range-picker/form-time-range-picker.js.map +1 -0
  151. package/cjs/form/form-timepicker/form-timepicker.js +2 -0
  152. package/cjs/form/form-timepicker/form-timepicker.js.map +1 -0
  153. package/cjs/form/form-unit-number-input/form-unit-number-input.js +2 -0
  154. package/cjs/form/form-unit-number-input/form-unit-number-input.js.map +1 -0
  155. package/cjs/form/form-wrapper.js +1 -1
  156. package/cjs/form/form-wrapper.js.map +1 -1
  157. package/cjs/form/index.js +1 -1
  158. package/cjs/form/index.js.map +1 -1
  159. package/cjs/fullscreen-image-carousel/fullscreen-image-carousel.js.map +1 -1
  160. package/cjs/histogram-slider/histogram-slider.js.map +1 -1
  161. package/cjs/image-button/image-button.js.map +1 -1
  162. package/cjs/input/input.js.map +1 -1
  163. package/cjs/input-group/input-group.js.map +1 -1
  164. package/cjs/input-multi-select/input-multi-select.js.map +1 -1
  165. package/cjs/input-nested-multi-select/input-nested-multi-select.js.map +1 -1
  166. package/cjs/input-nested-select/input-nested-select.js.map +1 -1
  167. package/cjs/input-range-select/input-range-select.js.map +1 -1
  168. package/cjs/input-range-slider/input-range-slider.js.map +1 -1
  169. package/cjs/input-select/input-select.js.map +1 -1
  170. package/cjs/input-slider/input-slider.js.map +1 -1
  171. package/cjs/input-textarea/textarea.js.map +1 -1
  172. package/cjs/input-textarea/textarea.styles.js +1 -1
  173. package/cjs/input-textarea/textarea.styles.js.map +1 -1
  174. package/cjs/input-textarea/{textarea.styles_22z4n3.css → textarea.styles_q77m5x.css} +1 -1
  175. package/cjs/language-switcher/language-switcher.js.map +1 -1
  176. package/cjs/layout/index.js.map +1 -1
  177. package/cjs/link-list/components/common.js.map +1 -1
  178. package/cjs/link-list/components/link-list-eager.js.map +1 -1
  179. package/cjs/link-list/components/link-list-lazy.js.map +1 -1
  180. package/cjs/link-list/link-list.js.map +1 -1
  181. package/cjs/local-nav/local-nav-dropdown/local-nav-dropdown.js.map +1 -1
  182. package/cjs/local-nav/local-nav-menu/local-nav-menu.js.map +1 -1
  183. package/cjs/markup/markup.js.map +1 -1
  184. package/cjs/masked-input/masked-input.js.map +1 -1
  185. package/cjs/masthead/masthead.js.map +1 -1
  186. package/cjs/menu/menu.js.map +1 -1
  187. package/cjs/modal/index.js.map +1 -1
  188. package/cjs/modal-v2/modal-v2.js.map +1 -1
  189. package/cjs/navbar/navbar.js.map +1 -1
  190. package/cjs/notification-banner/notification-banner.js.map +1 -1
  191. package/cjs/otp-input/otp-input.js +1 -1
  192. package/cjs/otp-input/otp-input.js.map +1 -1
  193. package/cjs/otp-verification/contact-input-section.js +1 -1
  194. package/cjs/otp-verification/contact-input-section.js.map +1 -1
  195. package/cjs/otp-verification/otp-verification.js.map +1 -1
  196. package/cjs/otp-verification/verification-section.js +1 -1
  197. package/cjs/otp-verification/verification-section.js.map +1 -1
  198. package/cjs/overlay/overlay.js.map +1 -1
  199. package/cjs/pagination/pagination.js.map +1 -1
  200. package/cjs/phone-number-input/phone-number-input.js.map +1 -1
  201. package/cjs/pill/pill.js.map +1 -1
  202. package/cjs/popover/popover-inline/popover-inline.js.map +1 -1
  203. package/cjs/popover/popover.js.map +1 -1
  204. package/cjs/predictive-text-input/predictive-text-input.js +1 -1
  205. package/cjs/predictive-text-input/predictive-text-input.js.map +1 -1
  206. package/cjs/progress-indicator/progress-indicator.js.map +1 -1
  207. package/cjs/radio-button/radio-button.js.map +1 -1
  208. package/cjs/schedule/schedule.js.map +1 -1
  209. package/cjs/select-histogram/select-histogram.js.map +1 -1
  210. package/cjs/shared/dropdown-list/dropdown-list.js +1 -1
  211. package/cjs/shared/dropdown-list/dropdown-list.js.map +1 -1
  212. package/cjs/shared/dropdown-wrapper/element-with-dropdown.js +1 -1
  213. package/cjs/shared/dropdown-wrapper/element-with-dropdown.js.map +1 -1
  214. package/cjs/sidenav/sidenav.js.map +1 -1
  215. package/cjs/singpass-button/singpass-button.js.map +1 -1
  216. package/cjs/singpass-button/singpass-button.styles.js +1 -1
  217. package/cjs/singpass-button/singpass-button.styles.js.map +1 -1
  218. package/cjs/singpass-button/{singpass-button.styles_1miyex3.css → singpass-button.styles_1fj2lru.css} +1 -1
  219. package/cjs/smart-app-banner/smart-app-banner.js.map +1 -1
  220. package/cjs/smart-app-banner/smart-app-banner.styles.js +1 -1
  221. package/cjs/smart-app-banner/smart-app-banner.styles.js.map +1 -1
  222. package/{smart-app-banner/smart-app-banner.styles_15u6yv4.css → cjs/smart-app-banner/smart-app-banner.styles_r6yjq9.css} +1 -1
  223. package/cjs/tab/tab.js.map +1 -1
  224. package/cjs/table/table.js.map +1 -1
  225. package/cjs/tag/tag.js.map +1 -1
  226. package/cjs/text-list/index.js.map +1 -1
  227. package/cjs/theme/theme-provider/hooks.js.map +1 -1
  228. package/cjs/theme/theme-provider/index.js.map +1 -1
  229. package/cjs/theme/tokens/border.js.map +1 -1
  230. package/cjs/theme/tokens/breakpoint.js.map +1 -1
  231. package/cjs/theme/tokens/colour.js.map +1 -1
  232. package/cjs/theme/tokens/component.js.map +1 -1
  233. package/cjs/theme/tokens/font.js.map +1 -1
  234. package/cjs/theme/tokens/media-query.js.map +1 -1
  235. package/cjs/theme/tokens/motion.js.map +1 -1
  236. package/cjs/theme/tokens/radius.js.map +1 -1
  237. package/cjs/theme/tokens/shadow.js.map +1 -1
  238. package/cjs/theme/tokens/spacing.js.map +1 -1
  239. package/cjs/theme/utils/use-apply-styles.js.map +1 -1
  240. package/cjs/theme/utils/use-design-token.js.map +1 -1
  241. package/cjs/theme/utils/use-media-query.js.map +1 -1
  242. package/cjs/time-range-picker/combobox-picker/combobox-picker.js +1 -1
  243. package/cjs/time-range-picker/combobox-picker/combobox-picker.js.map +1 -1
  244. package/cjs/time-range-picker/time-range-picker.js.map +1 -1
  245. package/cjs/time-slot-bar/time-slot-bar.js.map +1 -1
  246. package/cjs/time-slot-bar-week/time-slot-bar-week.js.map +1 -1
  247. package/cjs/time-slot-week-view/time-slot-week-view.js.map +1 -1
  248. package/cjs/timeline/timeline.js.map +1 -1
  249. package/cjs/timepicker/timepicker.js.map +1 -1
  250. package/cjs/timetable/timetable.js.map +1 -1
  251. package/cjs/toast/toast.js.map +1 -1
  252. package/cjs/toast/toast.styles.js +1 -1
  253. package/cjs/toast/toast.styles.js.map +1 -1
  254. package/{toast/toast.styles_1e0l60w.css → cjs/toast/toast.styles_57j3lf.css} +1 -1
  255. package/cjs/toggle/toggle.js.map +1 -1
  256. package/cjs/typography/index.js.map +1 -1
  257. package/cjs/uneditable-section/index.js.map +1 -1
  258. package/cjs/uneditable-section/section-item.js +1 -1
  259. package/cjs/uneditable-section/section-item.js.map +1 -1
  260. package/cjs/unit-number/unit-number-input.js.map +1 -1
  261. package/countdown-timer/countdown-timer.js.map +1 -1
  262. package/countdown-timer/types.d.ts +3 -3
  263. package/dashed-border/dashed-border.js.map +1 -1
  264. package/data-table/data-table.d.ts +1 -1
  265. package/data-table/data-table.js +1 -1
  266. package/data-table/data-table.js.map +1 -1
  267. package/data-table/data-table.styles.d.ts +1 -0
  268. package/data-table/data-table.styles.js +1 -1
  269. package/data-table/data-table.styles.js.map +1 -1
  270. package/data-table/{data-table.styles_rxganh.css → data-table.styles_1tnlmhe.css} +7 -6
  271. package/data-table/types.d.ts +2 -0
  272. package/date-input/date-input.js.map +1 -1
  273. package/date-input/types.d.ts +1 -1
  274. package/date-navigator/date-navigator.js.map +1 -1
  275. package/date-navigator/types.d.ts +1 -1
  276. package/date-range-input/date-range-input.js.map +1 -1
  277. package/date-range-input/types.d.ts +1 -1
  278. package/divider/divider.js.map +1 -1
  279. package/divider/types.d.ts +1 -1
  280. package/docs/component-catalog.json +644 -0
  281. package/drawer/drawer.js.map +1 -1
  282. package/e-signature/e-signature.js.map +1 -1
  283. package/error-display/error-display-data.js +1 -1
  284. package/error-display/error-display-data.js.map +1 -1
  285. package/error-display/error-display.js.map +1 -1
  286. package/feedback-rating/feedback-rating.js.map +1 -1
  287. package/file-download/file-download.js.map +1 -1
  288. package/file-download/types.d.ts +6 -1
  289. package/file-upload/file-item-edit.d.ts +1 -1
  290. package/file-upload/file-item-edit.js.map +1 -1
  291. package/file-upload/file-list/file-list.d.ts +1 -1
  292. package/file-upload/file-list/file-list.js.map +1 -1
  293. package/file-upload/file-list-item/file-list-item.d.ts +1 -1
  294. package/file-upload/file-list-item/file-list-item.js.map +1 -1
  295. package/file-upload/file-list-item/file-list-item.styles.js +1 -1
  296. package/file-upload/file-list-item/file-list-item.styles.js.map +1 -1
  297. package/{cjs/file-upload/file-list-item/file-list-item.styles_o8000f.css → file-upload/file-list-item/file-list-item.styles_kgtfke.css} +1 -1
  298. package/file-upload/file-upload.js.map +1 -1
  299. package/file-upload/types.d.ts +6 -2
  300. package/filter/addons/filter-item-checkbox-helpers.d.ts +2 -2
  301. package/filter/addons/filter-item-checkbox-helpers.js.map +1 -1
  302. package/filter/addons/filter-item-checkbox.d.ts +1 -1
  303. package/filter/addons/filter-item-checkbox.js.map +1 -1
  304. package/filter/addons/filter-item-checkbox.styles.js +1 -1
  305. package/filter/addons/filter-item-checkbox.styles.js.map +1 -1
  306. package/filter/addons/{filter-item-checkbox.styles_7degw7.css → filter-item-checkbox.styles_6nbpdl.css} +1 -1
  307. package/filter/addons/internal-types.d.ts +12 -0
  308. package/filter/addons/types.d.ts +60 -9
  309. package/filter/filter-item.js +1 -1
  310. package/filter/filter-item.js.map +1 -1
  311. package/filter/filter-item.styles.js +1 -1
  312. package/filter/filter-item.styles.js.map +1 -1
  313. package/filter/{filter-item.styles_cphjnj.css → filter-item.styles_1yixp8h.css} +1 -1
  314. package/filter/filter-modal.styles.js +1 -1
  315. package/filter/filter-modal.styles.js.map +1 -1
  316. package/{cjs/filter/filter-modal.styles_qw3xlg.css → filter/filter-modal.styles_kuth21.css} +1 -1
  317. package/filter/filter-sidebar.styles.js +1 -1
  318. package/filter/filter-sidebar.styles.js.map +1 -1
  319. package/filter/{filter-sidebar.styles_1otwpjl.css → filter-sidebar.styles_rbfq4f.css} +1 -1
  320. package/filter/filter.d.ts +1 -1
  321. package/filter/filter.js.map +1 -1
  322. package/filter/index.d.ts +1 -0
  323. package/filter/types.d.ts +31 -63
  324. package/footer/footer.js.map +1 -1
  325. package/form/form-custom-field/form-custom-field.js +2 -0
  326. package/form/form-custom-field/form-custom-field.js.map +1 -0
  327. package/form/form-custom-field/index.d.ts +2 -0
  328. package/form/form-custom-field/types.d.ts +7 -0
  329. package/form/form-date-input/form-date-input.js +2 -0
  330. package/form/form-date-input/form-date-input.js.map +1 -0
  331. package/form/form-date-input/index.d.ts +2 -0
  332. package/form/form-date-input/types.d.ts +8 -0
  333. package/form/form-date-range-input/form-date-range-input.js +2 -0
  334. package/form/form-date-range-input/form-date-range-input.js.map +1 -0
  335. package/form/form-date-range-input/index.d.ts +2 -0
  336. package/form/form-date-range-input/types.d.ts +8 -0
  337. package/form/form-e-signature/form-e-signature.js +2 -0
  338. package/form/form-e-signature/form-e-signature.js.map +1 -0
  339. package/form/form-e-signature/index.d.ts +2 -0
  340. package/form/form-e-signature/types.d.ts +8 -0
  341. package/form/form-histogram-slider/form-histogram-slider.js +2 -0
  342. package/form/form-histogram-slider/form-histogram-slider.js.map +1 -0
  343. package/form/form-histogram-slider/index.d.ts +2 -0
  344. package/form/form-histogram-slider/types.d.ts +8 -0
  345. package/form/form-input/form-input.js +2 -0
  346. package/form/form-input/form-input.js.map +1 -0
  347. package/form/form-input/index.d.ts +2 -0
  348. package/form/form-input/types.d.ts +8 -0
  349. package/form/form-input-group/form-input-group.js +2 -0
  350. package/form/form-input-group/form-input-group.js.map +1 -0
  351. package/form/form-input-group/index.d.ts +2 -0
  352. package/form/form-input-group/types.d.ts +10 -0
  353. package/form/form-label/form-label-addon.js +2 -0
  354. package/form/form-label/form-label-addon.js.map +1 -0
  355. package/form/form-label/form-label-addon.styles.js +2 -0
  356. package/form/form-label/form-label-addon.styles.js.map +1 -0
  357. package/form/form-label/form-label-addon.styles_aztasj.css +1 -0
  358. package/form/form-label/form-label.js +2 -0
  359. package/form/form-label/form-label.js.map +1 -0
  360. package/form/form-label/form-label.styles.js +2 -0
  361. package/form/form-label/form-label.styles.js.map +1 -0
  362. package/form/form-label/form-label.styles_180zf7j.css +6 -0
  363. package/form/form-label/index.d.ts +2 -0
  364. package/form/form-label/types.d.ts +39 -0
  365. package/form/form-masked-input/form-masked-input.js +2 -0
  366. package/form/form-masked-input/form-masked-input.js.map +1 -0
  367. package/form/form-masked-input/index.d.ts +2 -0
  368. package/form/form-masked-input/types.d.ts +8 -0
  369. package/form/form-multi-select/form-multi-select.js +2 -0
  370. package/form/form-multi-select/form-multi-select.js.map +1 -0
  371. package/form/form-multi-select/index.d.ts +2 -0
  372. package/form/form-multi-select/types.d.ts +10 -0
  373. package/form/form-nested-multi-select/form-nested-multi-select.js +2 -0
  374. package/form/form-nested-multi-select/form-nested-multi-select.js.map +1 -0
  375. package/form/form-nested-multi-select/index.d.ts +2 -0
  376. package/form/form-nested-multi-select/types.d.ts +11 -0
  377. package/form/form-nested-select/form-nested-select.js +2 -0
  378. package/form/form-nested-select/form-nested-select.js.map +1 -0
  379. package/form/form-nested-select/index.d.ts +2 -0
  380. package/form/form-nested-select/types.d.ts +11 -0
  381. package/form/{form-otp-verification.d.ts → form-otp-verification/form-otp-verification.d.ts} +1 -1
  382. package/form/form-otp-verification/form-otp-verification.js +2 -0
  383. package/form/form-otp-verification/form-otp-verification.js.map +1 -0
  384. package/form/form-otp-verification/index.d.ts +2 -0
  385. package/form/form-otp-verification/types.d.ts +1 -0
  386. package/form/form-phone-number-input/form-phone-number-input.js +2 -0
  387. package/form/form-phone-number-input/form-phone-number-input.js.map +1 -0
  388. package/form/form-phone-number-input/index.d.ts +2 -0
  389. package/form/form-phone-number-input/types.d.ts +8 -0
  390. package/form/form-predictive-text-input/form-predictive-text-input.js +2 -0
  391. package/form/form-predictive-text-input/form-predictive-text-input.js.map +1 -0
  392. package/form/form-predictive-text-input/index.d.ts +2 -0
  393. package/form/form-predictive-text-input/types.d.ts +10 -0
  394. package/form/form-range-select/form-range-select.js +2 -0
  395. package/form/form-range-select/form-range-select.js.map +1 -0
  396. package/form/form-range-select/index.d.ts +2 -0
  397. package/form/form-range-select/types.d.ts +10 -0
  398. package/form/form-range-slider/form-range-slider.js +2 -0
  399. package/form/form-range-slider/form-range-slider.js.map +1 -0
  400. package/form/form-range-slider/index.d.ts +2 -0
  401. package/form/form-range-slider/types.d.ts +8 -0
  402. package/form/form-select/form-select.js +2 -0
  403. package/form/form-select/form-select.js.map +1 -0
  404. package/form/form-select/index.d.ts +2 -0
  405. package/form/form-select/types.d.ts +10 -0
  406. package/form/form-select-histogram/form-select-histogram.js +2 -0
  407. package/form/form-select-histogram/form-select-histogram.js.map +1 -0
  408. package/form/form-select-histogram/index.d.ts +2 -0
  409. package/form/form-select-histogram/types.d.ts +8 -0
  410. package/form/form-slider/form-slider.js +2 -0
  411. package/form/form-slider/form-slider.js.map +1 -0
  412. package/form/form-slider/index.d.ts +2 -0
  413. package/form/form-slider/types.d.ts +8 -0
  414. package/form/form-textarea/form-textarea.js +2 -0
  415. package/form/form-textarea/form-textarea.js.map +1 -0
  416. package/form/form-textarea/form-textarea.styles.js +2 -0
  417. package/form/form-textarea/form-textarea.styles.js.map +1 -0
  418. package/form/form-textarea/form-textarea.styles_1kneyif.css +3 -0
  419. package/form/form-textarea/index.d.ts +2 -0
  420. package/form/form-textarea/types.d.ts +8 -0
  421. package/form/form-time-range-picker/form-time-range-picker.js +2 -0
  422. package/form/form-time-range-picker/form-time-range-picker.js.map +1 -0
  423. package/form/form-time-range-picker/index.d.ts +2 -0
  424. package/form/form-time-range-picker/types.d.ts +8 -0
  425. package/form/form-timepicker/form-timepicker.js +2 -0
  426. package/form/form-timepicker/form-timepicker.js.map +1 -0
  427. package/form/form-timepicker/index.d.ts +2 -0
  428. package/form/form-timepicker/types.d.ts +8 -0
  429. package/form/form-unit-number-input/form-unit-number-input.js +2 -0
  430. package/form/form-unit-number-input/form-unit-number-input.js.map +1 -0
  431. package/form/form-unit-number-input/index.d.ts +2 -0
  432. package/form/form-unit-number-input/types.d.ts +8 -0
  433. package/form/form-wrapper.js +1 -1
  434. package/form/form-wrapper.js.map +1 -1
  435. package/form/index.d.ts +47 -24
  436. package/form/index.js +1 -1
  437. package/form/index.js.map +1 -1
  438. package/form/types.d.ts +1 -208
  439. package/fullscreen-image-carousel/fullscreen-image-carousel.js.map +1 -1
  440. package/histogram-slider/histogram-slider.js.map +1 -1
  441. package/image-button/image-button.js.map +1 -1
  442. package/input/input.js.map +1 -1
  443. package/input-group/input-group.js.map +1 -1
  444. package/input-group/types.d.ts +1 -1
  445. package/input-multi-select/input-multi-select.js.map +1 -1
  446. package/input-multi-select/types.d.ts +1 -1
  447. package/input-nested-multi-select/input-nested-multi-select.js.map +1 -1
  448. package/input-nested-select/input-nested-select.js.map +1 -1
  449. package/input-nested-select/types.d.ts +1 -1
  450. package/input-range-select/input-range-select.js.map +1 -1
  451. package/input-range-select/types.d.ts +1 -1
  452. package/input-range-slider/input-range-slider.js.map +1 -1
  453. package/input-select/input-select.js.map +1 -1
  454. package/input-select/types.d.ts +1 -1
  455. package/input-slider/input-slider.js.map +1 -1
  456. package/input-slider/types.d.ts +1 -1
  457. package/input-textarea/textarea.js.map +1 -1
  458. package/input-textarea/textarea.styles.js +1 -1
  459. package/input-textarea/textarea.styles.js.map +1 -1
  460. package/input-textarea/{textarea.styles_22z4n3.css → textarea.styles_q77m5x.css} +1 -1
  461. package/language-switcher/language-switcher.js.map +1 -1
  462. package/layout/index.js.map +1 -1
  463. package/link-list/components/common.d.ts +1 -1
  464. package/link-list/components/common.js.map +1 -1
  465. package/link-list/components/link-list-eager.d.ts +2 -2
  466. package/link-list/components/link-list-eager.js.map +1 -1
  467. package/link-list/components/link-list-lazy.d.ts +2 -2
  468. package/link-list/components/link-list-lazy.js.map +1 -1
  469. package/link-list/link-list.js.map +1 -1
  470. package/link-list/types.d.ts +89 -3
  471. package/local-nav/local-nav-dropdown/local-nav-dropdown.js.map +1 -1
  472. package/local-nav/local-nav-menu/local-nav-menu.js.map +1 -1
  473. package/markup/markup.js.map +1 -1
  474. package/masked-input/masked-input.js.map +1 -1
  475. package/masthead/masthead.js.map +1 -1
  476. package/menu/menu.js.map +1 -1
  477. package/menu/types.d.ts +17 -1
  478. package/modal/index.js.map +1 -1
  479. package/modal/types.d.ts +3 -1
  480. package/modal-v2/modal-v2.js.map +1 -1
  481. package/modal-v2/types.d.ts +17 -0
  482. package/navbar/navbar.js.map +1 -1
  483. package/navbar/types.d.ts +1 -0
  484. package/notification-banner/notification-banner.js.map +1 -1
  485. package/otp-input/otp-input.js +1 -1
  486. package/otp-input/otp-input.js.map +1 -1
  487. package/otp-input/types.d.ts +14 -9
  488. package/otp-verification/contact-input-section.js +1 -1
  489. package/otp-verification/contact-input-section.js.map +1 -1
  490. package/otp-verification/otp-verification.js.map +1 -1
  491. package/otp-verification/verification-section.js +1 -1
  492. package/otp-verification/verification-section.js.map +1 -1
  493. package/overlay/overlay.js.map +1 -1
  494. package/package.json +1 -1
  495. package/pagination/pagination.js.map +1 -1
  496. package/phone-number-input/phone-number-input.js.map +1 -1
  497. package/pill/pill.js.map +1 -1
  498. package/popover/popover-inline/index.d.ts +1 -0
  499. package/popover/popover-inline/popover-inline.d.ts +1 -1
  500. package/popover/popover-inline/popover-inline.js.map +1 -1
  501. package/popover/popover-inline/types.d.ts +36 -0
  502. package/popover/popover.js.map +1 -1
  503. package/popover/types.d.ts +2 -35
  504. package/predictive-text-input/predictive-text-input.js +1 -1
  505. package/predictive-text-input/predictive-text-input.js.map +1 -1
  506. package/predictive-text-input/types.d.ts +1 -1
  507. package/progress-indicator/progress-indicator.js.map +1 -1
  508. package/radio-button/radio-button.js.map +1 -1
  509. package/radio-button/types.d.ts +3 -0
  510. package/schedule/schedule.js.map +1 -1
  511. package/select-histogram/select-histogram.js.map +1 -1
  512. package/select-histogram/types.d.ts +1 -1
  513. package/shared/dropdown-list/dropdown-list.js +1 -1
  514. package/shared/dropdown-list/dropdown-list.js.map +1 -1
  515. package/shared/dropdown-wrapper/element-with-dropdown.d.ts +5 -4
  516. package/shared/dropdown-wrapper/element-with-dropdown.js +1 -1
  517. package/shared/dropdown-wrapper/element-with-dropdown.js.map +1 -1
  518. package/sidenav/sidenav.js.map +1 -1
  519. package/sidenav/types.d.ts +1 -0
  520. package/singpass-button/singpass-button.js.map +1 -1
  521. package/singpass-button/singpass-button.styles.js +1 -1
  522. package/singpass-button/singpass-button.styles.js.map +1 -1
  523. package/singpass-button/{singpass-button.styles_1miyex3.css → singpass-button.styles_1fj2lru.css} +1 -1
  524. package/smart-app-banner/smart-app-banner.js.map +1 -1
  525. package/smart-app-banner/smart-app-banner.styles.js +1 -1
  526. package/smart-app-banner/smart-app-banner.styles.js.map +1 -1
  527. package/{cjs/smart-app-banner/smart-app-banner.styles_15u6yv4.css → smart-app-banner/smart-app-banner.styles_r6yjq9.css} +1 -1
  528. package/smart-app-banner/types.d.ts +2 -0
  529. package/tab/tab.js.map +1 -1
  530. package/table/table.d.ts +9 -8
  531. package/table/table.js.map +1 -1
  532. package/table/types.d.ts +35 -0
  533. package/tag/tag.js.map +1 -1
  534. package/text-list/index.js.map +1 -1
  535. package/theme/styles/pa.css +0 -41
  536. package/theme/theme-provider/hooks.js.map +1 -1
  537. package/theme/theme-provider/index.js.map +1 -1
  538. package/theme/tokens/border.d.ts +9 -3
  539. package/theme/tokens/border.js.map +1 -1
  540. package/theme/tokens/breakpoint.js.map +1 -1
  541. package/theme/tokens/colour.d.ts +9 -3
  542. package/theme/tokens/colour.js.map +1 -1
  543. package/theme/tokens/component.d.ts +3 -1
  544. package/theme/tokens/component.js.map +1 -1
  545. package/theme/tokens/font.d.ts +6 -2
  546. package/theme/tokens/font.js.map +1 -1
  547. package/theme/tokens/media-query.d.ts +3 -1
  548. package/theme/tokens/media-query.js.map +1 -1
  549. package/theme/tokens/motion.d.ts +3 -1
  550. package/theme/tokens/motion.js.map +1 -1
  551. package/theme/tokens/radius.d.ts +3 -1
  552. package/theme/tokens/radius.js.map +1 -1
  553. package/theme/tokens/shadow.d.ts +3 -1
  554. package/theme/tokens/shadow.js.map +1 -1
  555. package/theme/tokens/spacing.d.ts +3 -1
  556. package/theme/tokens/spacing.js.map +1 -1
  557. package/theme/utils/use-apply-styles.js.map +1 -1
  558. package/theme/utils/use-design-token.js.map +1 -1
  559. package/theme/utils/use-media-query.js.map +1 -1
  560. package/time-range-picker/combobox-picker/combobox-picker.js +1 -1
  561. package/time-range-picker/combobox-picker/combobox-picker.js.map +1 -1
  562. package/time-range-picker/time-range-picker.js.map +1 -1
  563. package/time-range-picker/types.d.ts +1 -1
  564. package/time-slot-bar/time-slot-bar.js.map +1 -1
  565. package/time-slot-bar/types.d.ts +5 -1
  566. package/time-slot-bar-week/time-slot-bar-week.js.map +1 -1
  567. package/time-slot-bar-week/types.d.ts +6 -0
  568. package/time-slot-week-view/time-slot-week-view.js.map +1 -1
  569. package/time-slot-week-view/types.d.ts +2 -0
  570. package/timeline/timeline.js.map +1 -1
  571. package/timeline/types.d.ts +1 -1
  572. package/timepicker/timepicker.js.map +1 -1
  573. package/timepicker/types.d.ts +2 -2
  574. package/timetable/timetable.js.map +1 -1
  575. package/toast/toast.js.map +1 -1
  576. package/toast/toast.styles.js +1 -1
  577. package/toast/toast.styles.js.map +1 -1
  578. package/{cjs/toast/toast.styles_1e0l60w.css → toast/toast.styles_57j3lf.css} +1 -1
  579. package/toast/types.d.ts +2 -0
  580. package/toggle/toggle.js.map +1 -1
  581. package/tools/shared/generated-file-formatter.d.ts +6 -0
  582. package/tools/shared/jsdoc-parser.d.ts +36 -0
  583. package/tools/shared/ts-morph-project-factory.d.ts +9 -0
  584. package/tools/shared/typescript-source-provider.d.ts +9 -0
  585. package/tools/storybook-argtypes/adapters/file-system-adapter.d.ts +69 -0
  586. package/tools/storybook-argtypes/arg-types-generator.d.ts +85 -0
  587. package/tools/storybook-argtypes/config/arg-types-config.d.ts +31 -0
  588. package/tools/storybook-argtypes/index.d.ts +11 -0
  589. package/tools/storybook-argtypes/services/arg-types-row-builder.d.ts +49 -0
  590. package/tools/storybook-argtypes/services/file-path-resolver.d.ts +118 -0
  591. package/tools/storybook-argtypes/services/index.d.ts +6 -0
  592. package/tools/storybook-argtypes/services/jsdoc-metadata-extractor.d.ts +33 -0
  593. package/tools/storybook-argtypes/services/story-registry-generator.d.ts +27 -0
  594. package/tools/storybook-argtypes/services/type-dependency-resolver.d.ts +46 -0
  595. package/tools/storybook-argtypes/services/type-formatting-service.d.ts +27 -0
  596. package/tools/storybook-argtypes/types.d.ts +114 -0
  597. package/typography/index.js.map +1 -1
  598. package/uneditable-section/index.js.map +1 -1
  599. package/uneditable-section/section-item.js +1 -1
  600. package/uneditable-section/section-item.js.map +1 -1
  601. package/uneditable-section/types.d.ts +2 -2
  602. package/unit-number/unit-number-input.js.map +1 -1
  603. package/button/button.styles_1pxy0co.css +0 -20
  604. package/cjs/button/button.styles_1pxy0co.css +0 -20
  605. package/cjs/form/form-custom-field.js +0 -2
  606. package/cjs/form/form-custom-field.js.map +0 -1
  607. package/cjs/form/form-date-input.js +0 -2
  608. package/cjs/form/form-date-input.js.map +0 -1
  609. package/cjs/form/form-date-range-input.js +0 -2
  610. package/cjs/form/form-date-range-input.js.map +0 -1
  611. package/cjs/form/form-e-signature.js +0 -2
  612. package/cjs/form/form-e-signature.js.map +0 -1
  613. package/cjs/form/form-histogram.js +0 -2
  614. package/cjs/form/form-histogram.js.map +0 -1
  615. package/cjs/form/form-input-group.js +0 -2
  616. package/cjs/form/form-input-group.js.map +0 -1
  617. package/cjs/form/form-input.js +0 -2
  618. package/cjs/form/form-input.js.map +0 -1
  619. package/cjs/form/form-label-addon.js +0 -2
  620. package/cjs/form/form-label-addon.js.map +0 -1
  621. package/cjs/form/form-label-addon.styles.js +0 -2
  622. package/cjs/form/form-label-addon.styles.js.map +0 -1
  623. package/cjs/form/form-label-addon.styles_b00z8p.css +0 -1
  624. package/cjs/form/form-label.js +0 -2
  625. package/cjs/form/form-label.js.map +0 -1
  626. package/cjs/form/form-label.styles.js +0 -2
  627. package/cjs/form/form-label.styles.js.map +0 -1
  628. package/cjs/form/form-label.styles_1nbe0bm.css +0 -6
  629. package/cjs/form/form-masked-input.js +0 -2
  630. package/cjs/form/form-masked-input.js.map +0 -1
  631. package/cjs/form/form-multi-select.js +0 -2
  632. package/cjs/form/form-multi-select.js.map +0 -1
  633. package/cjs/form/form-nested-multi-select.js +0 -2
  634. package/cjs/form/form-nested-multi-select.js.map +0 -1
  635. package/cjs/form/form-nested-select.js +0 -2
  636. package/cjs/form/form-nested-select.js.map +0 -1
  637. package/cjs/form/form-otp-verification.js +0 -2
  638. package/cjs/form/form-otp-verification.js.map +0 -1
  639. package/cjs/form/form-phone-number-input.js +0 -2
  640. package/cjs/form/form-phone-number-input.js.map +0 -1
  641. package/cjs/form/form-predictive-text-input.js +0 -2
  642. package/cjs/form/form-predictive-text-input.js.map +0 -1
  643. package/cjs/form/form-range-select.js +0 -2
  644. package/cjs/form/form-range-select.js.map +0 -1
  645. package/cjs/form/form-range-slider.js +0 -2
  646. package/cjs/form/form-range-slider.js.map +0 -1
  647. package/cjs/form/form-select-histogram.js +0 -2
  648. package/cjs/form/form-select-histogram.js.map +0 -1
  649. package/cjs/form/form-select.js +0 -2
  650. package/cjs/form/form-select.js.map +0 -1
  651. package/cjs/form/form-slider.js +0 -2
  652. package/cjs/form/form-slider.js.map +0 -1
  653. package/cjs/form/form-textarea.js +0 -2
  654. package/cjs/form/form-textarea.js.map +0 -1
  655. package/cjs/form/form-textarea.styles.js +0 -2
  656. package/cjs/form/form-textarea.styles.js.map +0 -1
  657. package/cjs/form/form-textarea.styles_3p9qoy.css +0 -3
  658. package/cjs/form/form-time-range-picker.js +0 -2
  659. package/cjs/form/form-time-range-picker.js.map +0 -1
  660. package/cjs/form/form-timepicker.js +0 -2
  661. package/cjs/form/form-timepicker.js.map +0 -1
  662. package/cjs/form/form-unit-number-input.js +0 -2
  663. package/cjs/form/form-unit-number-input.js.map +0 -1
  664. package/form/form-custom-field.js +0 -2
  665. package/form/form-custom-field.js.map +0 -1
  666. package/form/form-date-input.js +0 -2
  667. package/form/form-date-input.js.map +0 -1
  668. package/form/form-date-range-input.js +0 -2
  669. package/form/form-date-range-input.js.map +0 -1
  670. package/form/form-e-signature.js +0 -2
  671. package/form/form-e-signature.js.map +0 -1
  672. package/form/form-histogram.js +0 -2
  673. package/form/form-histogram.js.map +0 -1
  674. package/form/form-input-group.js +0 -2
  675. package/form/form-input-group.js.map +0 -1
  676. package/form/form-input.js +0 -2
  677. package/form/form-input.js.map +0 -1
  678. package/form/form-label-addon.js +0 -2
  679. package/form/form-label-addon.js.map +0 -1
  680. package/form/form-label-addon.styles.js +0 -2
  681. package/form/form-label-addon.styles.js.map +0 -1
  682. package/form/form-label-addon.styles_b00z8p.css +0 -1
  683. package/form/form-label.js +0 -2
  684. package/form/form-label.js.map +0 -1
  685. package/form/form-label.styles.js +0 -2
  686. package/form/form-label.styles.js.map +0 -1
  687. package/form/form-label.styles_1nbe0bm.css +0 -6
  688. package/form/form-masked-input.js +0 -2
  689. package/form/form-masked-input.js.map +0 -1
  690. package/form/form-multi-select.js +0 -2
  691. package/form/form-multi-select.js.map +0 -1
  692. package/form/form-nested-multi-select.js +0 -2
  693. package/form/form-nested-multi-select.js.map +0 -1
  694. package/form/form-nested-select.js +0 -2
  695. package/form/form-nested-select.js.map +0 -1
  696. package/form/form-otp-verification.js +0 -2
  697. package/form/form-otp-verification.js.map +0 -1
  698. package/form/form-phone-number-input.js +0 -2
  699. package/form/form-phone-number-input.js.map +0 -1
  700. package/form/form-predictive-text-input.js +0 -2
  701. package/form/form-predictive-text-input.js.map +0 -1
  702. package/form/form-range-select.js +0 -2
  703. package/form/form-range-select.js.map +0 -1
  704. package/form/form-range-slider.js +0 -2
  705. package/form/form-range-slider.js.map +0 -1
  706. package/form/form-select-histogram.js +0 -2
  707. package/form/form-select-histogram.js.map +0 -1
  708. package/form/form-select.js +0 -2
  709. package/form/form-select.js.map +0 -1
  710. package/form/form-slider.js +0 -2
  711. package/form/form-slider.js.map +0 -1
  712. package/form/form-textarea.js +0 -2
  713. package/form/form-textarea.js.map +0 -1
  714. package/form/form-textarea.styles.js +0 -2
  715. package/form/form-textarea.styles.js.map +0 -1
  716. package/form/form-textarea.styles_3p9qoy.css +0 -3
  717. package/form/form-time-range-picker.js +0 -2
  718. package/form/form-time-range-picker.js.map +0 -1
  719. package/form/form-timepicker.js +0 -2
  720. package/form/form-timepicker.js.map +0 -1
  721. package/form/form-unit-number-input.js +0 -2
  722. package/form/form-unit-number-input.js.map +0 -1
  723. package/link-list/internal-types.d.ts +0 -85
  724. /package/{codemod-utils.d.ts → codemods/codemod-utils.d.ts} +0 -0
  725. /package/{migrate-popover → codemods/migrate-popover}/index.d.ts +0 -0
  726. /package/{run-codemod.d.ts → codemods/run-codemod.d.ts} +0 -0
  727. /package/form/{form-custom-field.d.ts → form-custom-field/form-custom-field.d.ts} +0 -0
  728. /package/form/{form-date-input.d.ts → form-date-input/form-date-input.d.ts} +0 -0
  729. /package/form/{form-date-range-input.d.ts → form-date-range-input/form-date-range-input.d.ts} +0 -0
  730. /package/form/{form-e-signature.d.ts → form-e-signature/form-e-signature.d.ts} +0 -0
  731. /package/form/{form-histogram.d.ts → form-histogram-slider/form-histogram-slider.d.ts} +0 -0
  732. /package/form/{form-input.d.ts → form-input/form-input.d.ts} +0 -0
  733. /package/form/{form-input-group.d.ts → form-input-group/form-input-group.d.ts} +0 -0
  734. /package/form/{form-label-addon.d.ts → form-label/form-label-addon.d.ts} +0 -0
  735. /package/form/{form-label-addon.styles.d.ts → form-label/form-label-addon.styles.d.ts} +0 -0
  736. /package/form/{form-label.d.ts → form-label/form-label.d.ts} +0 -0
  737. /package/form/{form-label.styles.d.ts → form-label/form-label.styles.d.ts} +0 -0
  738. /package/form/{form-masked-input.d.ts → form-masked-input/form-masked-input.d.ts} +0 -0
  739. /package/form/{form-multi-select.d.ts → form-multi-select/form-multi-select.d.ts} +0 -0
  740. /package/form/{form-nested-multi-select.d.ts → form-nested-multi-select/form-nested-multi-select.d.ts} +0 -0
  741. /package/form/{form-nested-select.d.ts → form-nested-select/form-nested-select.d.ts} +0 -0
  742. /package/form/{form-phone-number-input.d.ts → form-phone-number-input/form-phone-number-input.d.ts} +0 -0
  743. /package/form/{form-predictive-text-input.d.ts → form-predictive-text-input/form-predictive-text-input.d.ts} +0 -0
  744. /package/form/{form-range-select.d.ts → form-range-select/form-range-select.d.ts} +0 -0
  745. /package/form/{form-range-slider.d.ts → form-range-slider/form-range-slider.d.ts} +0 -0
  746. /package/form/{form-select.d.ts → form-select/form-select.d.ts} +0 -0
  747. /package/form/{form-select-histogram.d.ts → form-select-histogram/form-select-histogram.d.ts} +0 -0
  748. /package/form/{form-slider.d.ts → form-slider/form-slider.d.ts} +0 -0
  749. /package/form/{form-textarea.d.ts → form-textarea/form-textarea.d.ts} +0 -0
  750. /package/form/{form-textarea.styles.d.ts → form-textarea/form-textarea.styles.d.ts} +0 -0
  751. /package/form/{form-time-range-picker.d.ts → form-time-range-picker/form-time-range-picker.d.ts} +0 -0
  752. /package/form/{form-timepicker.d.ts → form-timepicker/form-timepicker.d.ts} +0 -0
  753. /package/form/{form-unit-number-input.d.ts → form-unit-number-input/form-unit-number-input.d.ts} +0 -0
@@ -6,6 +6,9 @@ export type ModalAnimationDirection = "top" | "bottom" | "left" | "right";
6
6
  * Props for the `ModalV2.Card` sub-component.
7
7
  */
8
8
  export interface ModalCardProps extends React.HTMLAttributes<HTMLDivElement> {
9
+ /**
10
+ * @default "modal-card"
11
+ */
9
12
  "data-testid"?: string | undefined;
10
13
  children: React.ReactNode;
11
14
  /**
@@ -17,12 +20,18 @@ export interface ModalCardProps extends React.HTMLAttributes<HTMLDivElement> {
17
20
  * Props for the `ModalV2.CloseButton` slot.
18
21
  */
19
22
  export interface ModalCloseButtonProps extends React.HTMLAttributes<HTMLDivElement> {
23
+ /**
24
+ * @default "modal-close-button"
25
+ */
20
26
  "data-testid"?: string | undefined;
21
27
  }
22
28
  /**
23
29
  * Props for the `ModalV2.Content` slot.
24
30
  */
25
31
  export interface ModalContentProps extends React.HTMLAttributes<HTMLDivElement> {
32
+ /**
33
+ * @default "modal-content"
34
+ */
26
35
  "data-testid"?: string | undefined;
27
36
  children: React.ReactNode;
28
37
  }
@@ -30,6 +39,9 @@ export interface ModalContentProps extends React.HTMLAttributes<HTMLDivElement>
30
39
  * Props for the `ModalV2.Footer` slot.
31
40
  */
32
41
  export interface ModalFooterProps extends React.HTMLAttributes<HTMLDivElement> {
42
+ /**
43
+ * @default "modal-footer"
44
+ */
33
45
  "data-testid"?: string | undefined;
34
46
  /**
35
47
  * Node rendered in the primary action position.
@@ -44,9 +56,14 @@ export interface ModalFooterProps extends React.HTMLAttributes<HTMLDivElement> {
44
56
  * Props for the `ModalV2` component.
45
57
  */
46
58
  export interface ModalV2Props extends React.HTMLAttributes<HTMLDivElement> {
59
+ /**
60
+ * @default "modal"
61
+ */
47
62
  "data-testid"?: string | undefined;
48
63
  /**
49
64
  * Controls whether the modal is visible.
65
+ *
66
+ * @default false
50
67
  */
51
68
  show: boolean;
52
69
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"navbar.js","sources":["../../src/navbar/navbar.tsx"],"sourcesContent":["import { MenuIcon } from \"@lifesg/react-icons/menu\";\nimport clsx from \"clsx\";\nimport type React from \"react\";\nimport {\n forwardRef,\n useContext,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\n\nimport { Layout } from \"../layout\";\nimport { Masthead } from \"../masthead/masthead\";\nimport { Overlay } from \"../overlay/overlay\";\nimport { ClickableIcon } from \"../shared/clickable-icon\";\nimport {\n Breakpoint,\n parsePxOrRemValue,\n useResolvedBreakpointToken,\n} from \"../theme\";\nimport { ThemeContext } from \"../theme/theme-provider/context\";\nimport { Brand } from \"./brand\";\nimport { Drawer } from \"./drawer\";\nimport * as styles from \"./navbar.styles\";\nimport { NavbarActionButtons } from \"./navbar-action-buttons\";\nimport { NavbarHelper } from \"./navbar-helper\";\nimport { NavbarItems } from \"./navbar-items\";\nimport { getDefaultResourceLogo } from \"./navbar-logo-data\";\nimport type {\n BrandType,\n DrawerDismissalMethod,\n NavbarActionButtonsProps,\n NavbarButtonProps,\n NavbarDrawerApi,\n NavbarDrawerHandle,\n NavbarProps,\n NavItemCommonProps,\n NavItemProps,\n} from \"./types\";\n\nconst Component = <T,>(\n {\n items,\n className,\n id,\n selectedId,\n compress = false,\n fixed = true,\n resources,\n hideNavElements = false,\n hideNavBranding = false,\n hideLinkIndicator = false,\n drawerDismissalExclusions: blockDrawerDismissalMethods = [],\n actionButtons,\n onItemClick,\n onActionButtonClick,\n onBrandClick,\n masthead = true,\n layout = \"default\",\n headerLabel = \"Main navigation menu\",\n drawerLabel,\n ...otherProps\n }: NavbarProps<T>,\n ref: React.Ref<NavbarDrawerHandle>\n) => {\n // =============================================================================\n // CONST, STATE, REFS\n // =============================================================================\n const [showDrawer, setShowDrawer] = useState<boolean>(false);\n const [showOverlay, setShowOverlay] = useState<boolean>(false);\n const mobileMenuRef = useRef<HTMLButtonElement>(null);\n const isStretch = layout === \"stretch\";\n const elementRef = useRef<HTMLDivElement>(null);\n const theme = useContext(ThemeContext);\n const defaultResource = getDefaultResourceLogo(theme?.theme);\n const tabletWidth = parsePxOrRemValue(\n useResolvedBreakpointToken(Breakpoint[\"lg-max\"])\n );\n\n const primary = resources?.primary || defaultResource.primary;\n const secondary = resources?.secondary;\n\n useImperativeHandle(\n ref,\n () =>\n Object.assign<HTMLDivElement, NavbarDrawerApi>(\n elementRef.current!,\n {\n dismissDrawer: () => {\n dismissDrawer();\n },\n }\n ),\n [showDrawer]\n );\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n handleResize();\n window.addEventListener(\"resize\", handleResize);\n\n return () => {\n window.removeEventListener(\"resize\", handleResize);\n };\n }, []);\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n const dismissDrawer = () => {\n setShowDrawer(false);\n setTimeout(() => {\n setShowOverlay(false);\n }, 550); // For drawer animation to complete + buffer\n };\n\n const shouldDismissDrawer = (dismissalMethod: DrawerDismissalMethod) => {\n return (\n showDrawer &&\n blockDrawerDismissalMethods.indexOf(dismissalMethod) === -1\n );\n };\n\n const hasCollapsibleActionButtons = (\n actionButtons: NavbarActionButtonsProps\n ) => {\n const drawerActionButtons =\n actionButtons.mobile || actionButtons.desktop;\n if (drawerActionButtons) {\n return (\n drawerActionButtons.length &&\n drawerActionButtons.some(\n (actionButton) => !actionButton.uncollapsible\n )\n );\n }\n\n return false;\n };\n\n // =============================================================================\n // EVENT HANDLER\n // =============================================================================\n const handleResize = () => {\n if (window.innerWidth <= tabletWidth && showDrawer) {\n dismissDrawer();\n }\n };\n\n const handleBrandClick = (\n _event: React.MouseEvent<HTMLAnchorElement>,\n type: BrandType\n ) => {\n if (onBrandClick) {\n onBrandClick(type);\n }\n\n if (shouldDismissDrawer(\"brand-click\")) {\n dismissDrawer();\n }\n };\n\n const handleNavItemClick = <K extends T>(\n event: React.MouseEvent<HTMLAnchorElement>,\n item: NavItemProps<K> | NavItemCommonProps<K>\n ) => {\n if (NavbarHelper.isNavItemCommon(item) && item.onClick) {\n item.onClick(event);\n } else if (onItemClick) {\n event.preventDefault();\n onItemClick(item);\n }\n\n if (\n NavbarHelper.isNavItemLink(item) &&\n !item.subMenu &&\n shouldDismissDrawer(\"item-click\")\n ) {\n dismissDrawer();\n }\n };\n\n const handleActionButtonClick = (\n event: React.MouseEvent<HTMLButtonElement> | React.MouseEvent<Element>,\n actionButton: NavbarButtonProps\n ) => {\n if (\n (actionButton.type === \"button\" ||\n actionButton.type === \"download\") &&\n actionButton.args?.onClick\n ) {\n actionButton.args.onClick(\n event as React.MouseEvent<HTMLButtonElement>\n );\n } else if (onActionButtonClick) {\n event.preventDefault();\n onActionButtonClick(actionButton);\n }\n\n if (shouldDismissDrawer(\"item-click\")) {\n dismissDrawer();\n }\n };\n\n const handleMobileMenuButtonClick = () => {\n setShowDrawer(true);\n setShowOverlay(true);\n };\n\n const handleDrawerClose = () => {\n if (shouldDismissDrawer(\"close-button-click\")) {\n dismissDrawer();\n }\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n\n const renderDrawer = () => (\n <Overlay\n show={showOverlay}\n enableOverlayClick\n onOverlayClick={handleDrawerClose}\n >\n <Drawer\n show={showDrawer}\n resources={{ primary, secondary }}\n onClose={handleDrawerClose}\n onBrandClick={handleBrandClick}\n actionButtons={actionButtons}\n hideNavBranding={hideNavBranding}\n mobileMenuRef={mobileMenuRef}\n drawerLabel={drawerLabel}\n >\n <NavbarItems\n items={items.mobile || items.desktop}\n onItemClick={handleNavItemClick}\n selectedId={selectedId}\n mobile\n hideLinkIndicator={hideLinkIndicator}\n />\n <NavbarActionButtons\n actionButtons={actionButtons}\n onActionButtonClick={handleActionButtonClick}\n mobile\n />\n </Drawer>\n </Overlay>\n );\n\n const renderBrand = () => (\n <div\n className={clsx(\n styles.navBrandContainer,\n compress\n ? styles.navBrandContainerCompressed\n : styles.navBrandContainerFull,\n styles.navBrandContainerResponsive\n )}\n data-id=\"brand-container\"\n >\n {primary && (\n <Brand\n resources={primary}\n onClick={handleBrandClick}\n data-id=\"brand-primary\"\n data-testid=\"main__brand\"\n type=\"primary\"\n />\n )}\n {secondary && (\n <>\n <div\n className={clsx(\n styles.navSeparator,\n compress\n ? styles.navSeparatorCompressed\n : styles.navSeparatorFull,\n styles.navSeparatorResponsive\n )}\n />\n <Brand\n resources={secondary}\n onClick={handleBrandClick}\n data-id=\"brand-secondary\"\n data-testid=\"main__brand-secondary\"\n type=\"secondary\"\n />\n </>\n )}\n </div>\n );\n\n const renderMobileMenuButton = () => {\n const drawerItems = items.mobile || items.desktop;\n if (\n (drawerItems && drawerItems.length > 0) ||\n (actionButtons && hasCollapsibleActionButtons(actionButtons))\n ) {\n return (\n <ClickableIcon\n ref={mobileMenuRef}\n className={styles.mobileMenuButton}\n aria-label={showDrawer ? \"Close nav menu\" : \"Open nav menu\"}\n aria-expanded={showDrawer}\n data-testid=\"button__mobile-menu\"\n onClick={handleMobileMenuButtonClick}\n focusHighlight={true}\n >\n <MenuIcon className={styles.mobileMenuIcon} />\n </ClickableIcon>\n );\n }\n\n return null;\n };\n\n const renderNavbar = () => {\n return (\n <Layout.Content stretch={isStretch}>\n <nav\n className={clsx(\n styles.nav,\n compress && styles.navCompressed,\n theme?.mode === \"dark\" && styles.navDark\n )}\n aria-label={headerLabel}\n >\n {!hideNavBranding && renderBrand()}\n {!hideNavElements && (\n <div\n className={clsx(\n styles.navElementsContainer,\n !hideNavBranding &&\n styles.navElementsContainerWithBranding\n )}\n >\n <NavbarItems\n items={items.desktop}\n onItemClick={handleNavItemClick}\n selectedId={selectedId}\n hideNavBranding={hideNavBranding}\n hideLinkIndicator={hideLinkIndicator}\n />\n <NavbarActionButtons\n actionButtons={actionButtons}\n onActionButtonClick={handleActionButtonClick}\n />\n {renderMobileMenuButton()}\n </div>\n )}\n </nav>\n\n {!hideNavElements && renderDrawer()}\n </Layout.Content>\n );\n };\n\n return (\n <div\n ref={elementRef}\n className={clsx(\n styles.wrapper,\n fixed ? styles.wrapperFixed : styles.wrapperRelative,\n theme?.mode === \"dark\"\n ? styles.wrapperDark\n : styles.wrapperLight,\n className\n )}\n id={id || \"navbar-wrapper\"}\n data-testid={otherProps[\"data-testid\"] || \"navbar-wrapper\"}\n >\n {masthead && <Masthead stretch={isStretch} />}\n {renderNavbar()}\n </div>\n );\n};\n\n/**\n * The main site navigation bar with desktop and mobile drawer views.\n *\n * Use `Navbar` to render the primary navigation header. It displays brand\n * logos, navigation items, and action buttons in a desktop bar, and\n * automatically collapses items into a slide-in drawer for mobile viewports.\n */\nexport const Navbar = forwardRef(Component);\n"],"names":["Navbar","forwardRef","_a","ref","items","className","id","selectedId","compress","fixed","resources","hideNavElements","hideNavBranding","hideLinkIndicator","drawerDismissalExclusions","blockDrawerDismissalMethods","actionButtons","onItemClick","onActionButtonClick","onBrandClick","masthead","layout","headerLabel","drawerLabel","otherProps","__rest","showDrawer","setShowDrawer","useState","showOverlay","setShowOverlay","mobileMenuRef","useRef","isStretch","elementRef","theme","useContext","ThemeContext","defaultResource","getDefaultResourceLogo","tabletWidth","parsePxOrRemValue","useResolvedBreakpointToken","Breakpoint","primary","secondary","useImperativeHandle","Object","assign","current","dismissDrawer","useEffect","handleResize","window","addEventListener","removeEventListener","setTimeout","shouldDismissDrawer","dismissalMethod","indexOf","innerWidth","handleBrandClick","_event","type","handleNavItemClick","event","item","NavbarHelper","isNavItemCommon","onClick","preventDefault","isNavItemLink","subMenu","handleActionButtonClick","actionButton","args","handleMobileMenuButtonClick","handleDrawerClose","renderMobileMenuButton","drawerItems","mobile","desktop","length","drawerActionButtons","some","uncollapsible","hasCollapsibleActionButtons","_jsx","ClickableIcon","styles.mobileMenuButton","focusHighlight","children","MenuIcon","styles.mobileMenuIcon","_jsxs","clsx","styles.wrapper","styles.wrapperFixed","styles.wrapperRelative","mode","styles.wrapperDark","styles.wrapperLight","Masthead","stretch","Layout","Content","styles.nav","styles.navCompressed","styles.navDark","styles.navBrandContainer","styles.navBrandContainerCompressed","styles.navBrandContainerFull","styles.navBrandContainerResponsive","Brand","_Fragment","styles.navSeparator","styles.navSeparatorCompressed","styles.navSeparatorFull","styles.navSeparatorResponsive","styles.navElementsContainer","styles.navElementsContainerWithBranding","NavbarItems","NavbarActionButtons","Overlay","show","enableOverlayClick","onOverlayClick","Drawer","onClose"],"mappings":"s4DAyCA,MA4VaA,EAASC,GA5VJ,CACdC,EAsBAC,KAtBA,IAAAC,MACIA,EAAKC,UACLA,EAASC,GACTA,EAAEC,WACFA,EAAUC,SACVA,GAAW,EAAKC,MAChBA,GAAQ,EAAIC,UACZA,EAASC,gBACTA,IAAkB,EAAKC,gBACvBA,IAAkB,EAAKC,kBACvBA,IAAoB,EACpBC,0BAA2BC,GAA8B,GAAEC,cAC3DA,GAAaC,YACbA,GAAWC,oBACXA,GAAmBC,aACnBA,GAAYC,SACZA,IAAW,EAAIC,OACfA,GAAS,UAASC,YAClBA,GAAc,uBAAsBC,YACpCA,IAAWrB,EACRsB,GAAUC,EAAAvB,EApBjB,+QA2BA,MAAOwB,GAAYC,IAAiBC,GAAkB,IAC/CC,GAAaC,IAAkBF,GAAkB,GAClDG,GAAgBC,EAA0B,MAC1CC,GAAuB,YAAXZ,GACZa,GAAaF,EAAuB,MACpCG,GAAQC,EAAWC,GACnBC,GAAkBC,EAAuBJ,cAAK,EAALA,GAAOA,OAChDK,GAAcC,EAChBC,EAA2BC,EAAW,YAGpCC,IAAUlC,aAAS,EAATA,EAAWkC,UAAWN,GAAgBM,QAChDC,GAAYnC,aAAS,EAATA,EAAWmC,UAE7BC,EACI3C,GACA,IACI4C,OAAOC,OACHd,GAAWe,QACX,CACIC,cAAe,KACXA,IAAe,KAI/B,CAACxB,KAMLyB,GAAU,KACNC,KACAC,OAAOC,iBAAiB,SAAUF,IAE3B,KACHC,OAAOE,oBAAoB,SAAUH,GAAa,IAEvD,IAKH,MAAMF,GAAgB,KAClBvB,IAAc,GACd6B,YAAW,KACP1B,IAAe,EAAM,GACtB,IAAI,EAGL2B,GAAuBC,GAErBhC,KACyD,IAAzDX,GAA4B4C,QAAQD,GAwBtCN,GAAe,KACbC,OAAOO,YAAcpB,IAAed,IACpCwB,IACJ,EAGEW,GAAmB,CACrBC,EACAC,KAEI5C,IACAA,GAAa4C,GAGbN,GAAoB,gBACpBP,IACJ,EAGEc,GAAqB,CACvBC,EACAC,KAEIC,EAAaC,gBAAgBF,IAASA,EAAKG,QAC3CH,EAAKG,QAAQJ,GACNhD,KACPgD,EAAMK,iBACNrD,GAAYiD,IAIZC,EAAaI,cAAcL,KAC1BA,EAAKM,SACNf,GAAoB,eAEpBP,IACJ,EAGEuB,GAA0B,CAC5BR,EACAS,WAG2B,WAAtBA,EAAaX,MACY,aAAtBW,EAAaX,gBACjB7D,EAAAwE,EAAaC,2BAAMN,SAKZnD,KACP+C,EAAMK,iBACNpD,GAAoBwD,IALpBA,EAAaC,KAAKN,QACdJ,GAOJR,GAAoB,eACpBP,IACJ,EAGE0B,GAA8B,KAChCjD,IAAc,GACdG,IAAe,EAAK,EAGlB+C,GAAoB,KAClBpB,GAAoB,uBACpBP,IACJ,EAkFE4B,GAAyB,KAC3B,MAAMC,EAAc3E,EAAM4E,QAAU5E,EAAM6E,QAC1C,OACKF,GAAeA,EAAYG,OAAS,GACpClE,IA/K2B,CAChCA,IAEA,MAAMmE,EACFnE,EAAcgE,QAAUhE,EAAciE,QAC1C,QAAIE,GAEIA,EAAoBD,QACpBC,EAAoBC,MACfV,IAAkBA,EAAaW,eAKhC,EAiKUC,CAA4BtE,IAG1CuE,EAACC,EAAa,CACVrF,IAAK4B,GACL1B,UAAWoF,eACC/D,GAAa,iBAAmB,gCAC7BA,GAAU,cACb,sBACZ2C,QAASO,GACTc,gBAAgB,EAAIC,SAEpBJ,EAACK,EAAQ,CAACvF,UAAWwF,MAK1B,IAAI,EA4Cf,OACIC,EAAA,MAAA,CACI3F,IAAK+B,GACL7B,UAAW0F,EACPC,EACAvF,EAAQwF,EAAsBC,EACd,UAAhB/D,cAAK,EAALA,GAAOgE,MACDC,EACAC,EACNhG,GAEJC,GAAIA,GAAM,iBAAgB,cACbkB,GAAW,gBAAkB,iBAAgBmE,SAAA,CAEzDvE,IAAYmE,EAACe,EAAQ,CAACC,QAAStE,KArDhC6D,EAACU,EAAOC,QAAO,CAACF,QAAStE,GAAS0D,SAAA,CAC9BG,EAAA,MAAA,CACIzF,UAAW0F,EACPW,EACAlG,GAAYmG,EACI,UAAhBxE,cAAK,EAALA,GAAOgE,OAAmBS,GAC7B,aACWtF,GAAWqE,SAAA,EAErB/E,IA7EdkF,EAAA,MAAA,CACIzF,UAAW0F,EACPc,EACArG,EACMsG,EACAC,EACNC,GACH,UACO,4BAEPpE,IACG2C,EAAC0B,GACGvG,UAAWkC,GACXyB,QAASR,GAAgB,UACjB,8BACI,cACZE,KAAK,YAGZlB,IACGiD,EAAAoB,EAAA,CAAAvB,SAAA,CACIJ,EAAA,MAAA,CACIlF,UAAW0F,EACPoB,EACA3G,EACM4G,EACAC,EACNC,KAGR/B,EAAC0B,EAAK,CACFvG,UAAWmC,GACXwB,QAASR,GAAgB,UACjB,gCACI,wBACZE,KAAK,qBA2CPpD,IACEmF,EAAA,MAAA,CACIzF,UAAW0F,EACPwB,GACC3G,IACG4G,GACP7B,SAAA,CAEDJ,EAACkC,EAAW,CACRrH,MAAOA,EAAM6E,QACbhE,YAAa+C,GACbzD,WAAYA,EACZK,gBAAiBA,GACjBC,kBAAmBA,KAEvB0E,EAACmC,EAAmB,CAChB1G,cAAeA,GACfE,oBAAqBuD,KAExBK,YAKXnE,IAtIV4E,EAACoC,EAAO,CACJC,KAAM/F,GACNgG,sBACAC,eAAgBjD,GAAiBc,SAEjCG,EAACiC,EAAM,CACHH,KAAMlG,GACNhB,UAAW,CAAEkC,WAASC,cACtBmF,QAASnD,GACT1D,aAAc0C,GACd7C,cAAeA,GACfJ,gBAAiBA,GACjBmB,cAAeA,GACfR,YAAaA,aAEbgE,EAACkC,EAAW,CACRrH,MAAOA,EAAM4E,QAAU5E,EAAM6E,QAC7BhE,YAAa+C,GACbzD,WAAYA,EACZyE,UACAnE,kBAAmBA,KAEvB0E,EAACmC,EAAmB,CAChB1G,cAAeA,GACfE,oBAAqBuD,GACrBO,QAAM,cAkIZ"}
1
+ {"version":3,"file":"navbar.js","sources":["../../src/navbar/navbar.tsx"],"sourcesContent":["import { MenuIcon } from \"@lifesg/react-icons/menu\";\nimport clsx from \"clsx\";\nimport type React from \"react\";\nimport {\n forwardRef,\n useContext,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\n\nimport { Layout } from \"../layout\";\nimport { Masthead } from \"../masthead/masthead\";\nimport { Overlay } from \"../overlay/overlay\";\nimport { ClickableIcon } from \"../shared/clickable-icon\";\nimport {\n Breakpoint,\n parsePxOrRemValue,\n useResolvedBreakpointToken,\n} from \"../theme\";\nimport { ThemeContext } from \"../theme/theme-provider/context\";\nimport { Brand } from \"./brand\";\nimport { Drawer } from \"./drawer\";\nimport * as styles from \"./navbar.styles\";\nimport { NavbarActionButtons } from \"./navbar-action-buttons\";\nimport { NavbarHelper } from \"./navbar-helper\";\nimport { NavbarItems } from \"./navbar-items\";\nimport { getDefaultResourceLogo } from \"./navbar-logo-data\";\nimport type {\n BrandType,\n DrawerDismissalMethod,\n NavbarActionButtonsProps,\n NavbarButtonProps,\n NavbarDrawerApi,\n NavbarDrawerHandle,\n NavbarProps,\n NavItemCommonProps,\n NavItemProps,\n} from \"./types\";\n\nconst Component = <T,>(\n {\n items,\n className,\n id,\n selectedId,\n compress = false,\n fixed = true,\n resources,\n hideNavElements = false,\n hideNavBranding = false,\n hideLinkIndicator = false,\n drawerDismissalExclusions: blockDrawerDismissalMethods = [],\n actionButtons,\n onItemClick,\n onActionButtonClick,\n onBrandClick,\n masthead = true,\n layout = \"default\",\n headerLabel = \"Main navigation menu\",\n drawerLabel,\n ...otherProps\n }: NavbarProps<T>,\n ref: React.Ref<NavbarDrawerHandle>\n) => {\n // =============================================================================\n // CONST, STATE, REFS\n // =============================================================================\n const [showDrawer, setShowDrawer] = useState<boolean>(false);\n const [showOverlay, setShowOverlay] = useState<boolean>(false);\n const mobileMenuRef = useRef<HTMLButtonElement>(null);\n const isStretch = layout === \"stretch\";\n const elementRef = useRef<HTMLDivElement>(null);\n const theme = useContext(ThemeContext);\n const defaultResource = getDefaultResourceLogo(theme?.theme);\n const tabletWidth = parsePxOrRemValue(\n useResolvedBreakpointToken(Breakpoint[\"lg-max\"])\n );\n\n const primary = resources?.primary || defaultResource.primary;\n const secondary = resources?.secondary;\n\n useImperativeHandle(\n ref,\n () =>\n Object.assign<HTMLDivElement, NavbarDrawerApi>(\n elementRef.current!,\n {\n dismissDrawer: () => {\n dismissDrawer();\n },\n }\n ),\n [showDrawer]\n );\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n handleResize();\n window.addEventListener(\"resize\", handleResize);\n\n return () => {\n window.removeEventListener(\"resize\", handleResize);\n };\n }, []);\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n const dismissDrawer = () => {\n setShowDrawer(false);\n setTimeout(() => {\n setShowOverlay(false);\n }, 550); // For drawer animation to complete + buffer\n };\n\n const shouldDismissDrawer = (dismissalMethod: DrawerDismissalMethod) => {\n return (\n showDrawer &&\n blockDrawerDismissalMethods.indexOf(dismissalMethod) === -1\n );\n };\n\n const hasCollapsibleActionButtons = (\n actionButtons: NavbarActionButtonsProps\n ) => {\n const drawerActionButtons =\n actionButtons.mobile || actionButtons.desktop;\n if (drawerActionButtons) {\n return (\n drawerActionButtons.length &&\n drawerActionButtons.some(\n (actionButton) => !actionButton.uncollapsible\n )\n );\n }\n\n return false;\n };\n\n // =============================================================================\n // EVENT HANDLER\n // =============================================================================\n const handleResize = () => {\n if (window.innerWidth <= tabletWidth && showDrawer) {\n dismissDrawer();\n }\n };\n\n const handleBrandClick = (\n _event: React.MouseEvent<HTMLAnchorElement>,\n type: BrandType\n ) => {\n if (onBrandClick) {\n onBrandClick(type);\n }\n\n if (shouldDismissDrawer(\"brand-click\")) {\n dismissDrawer();\n }\n };\n\n const handleNavItemClick = <K extends T>(\n event: React.MouseEvent<HTMLAnchorElement>,\n item: NavItemProps<K> | NavItemCommonProps<K>\n ) => {\n if (NavbarHelper.isNavItemCommon(item) && item.onClick) {\n item.onClick(event);\n } else if (onItemClick) {\n event.preventDefault();\n onItemClick(item);\n }\n\n if (\n NavbarHelper.isNavItemLink(item) &&\n !item.subMenu &&\n shouldDismissDrawer(\"item-click\")\n ) {\n dismissDrawer();\n }\n };\n\n const handleActionButtonClick = (\n event: React.MouseEvent<HTMLButtonElement> | React.MouseEvent<Element>,\n actionButton: NavbarButtonProps\n ) => {\n if (\n (actionButton.type === \"button\" ||\n actionButton.type === \"download\") &&\n actionButton.args?.onClick\n ) {\n actionButton.args.onClick(\n event as React.MouseEvent<HTMLButtonElement>\n );\n } else if (onActionButtonClick) {\n event.preventDefault();\n onActionButtonClick(actionButton);\n }\n\n if (shouldDismissDrawer(\"item-click\")) {\n dismissDrawer();\n }\n };\n\n const handleMobileMenuButtonClick = () => {\n setShowDrawer(true);\n setShowOverlay(true);\n };\n\n const handleDrawerClose = () => {\n if (shouldDismissDrawer(\"close-button-click\")) {\n dismissDrawer();\n }\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n\n const renderDrawer = () => (\n <Overlay\n show={showOverlay}\n enableOverlayClick\n onOverlayClick={handleDrawerClose}\n >\n <Drawer\n show={showDrawer}\n resources={{ primary, secondary }}\n onClose={handleDrawerClose}\n onBrandClick={handleBrandClick}\n actionButtons={actionButtons}\n hideNavBranding={hideNavBranding}\n mobileMenuRef={mobileMenuRef}\n drawerLabel={drawerLabel}\n >\n <NavbarItems\n items={items.mobile || items.desktop}\n onItemClick={handleNavItemClick}\n selectedId={selectedId}\n mobile\n hideLinkIndicator={hideLinkIndicator}\n />\n <NavbarActionButtons\n actionButtons={actionButtons}\n onActionButtonClick={handleActionButtonClick}\n mobile\n />\n </Drawer>\n </Overlay>\n );\n\n const renderBrand = () => (\n <div\n className={clsx(\n styles.navBrandContainer,\n compress\n ? styles.navBrandContainerCompressed\n : styles.navBrandContainerFull,\n styles.navBrandContainerResponsive\n )}\n data-id=\"brand-container\"\n >\n {primary && (\n <Brand\n resources={primary}\n onClick={handleBrandClick}\n data-id=\"brand-primary\"\n data-testid=\"main__brand\"\n type=\"primary\"\n />\n )}\n {secondary && (\n <>\n <div\n className={clsx(\n styles.navSeparator,\n compress\n ? styles.navSeparatorCompressed\n : styles.navSeparatorFull,\n styles.navSeparatorResponsive\n )}\n />\n <Brand\n resources={secondary}\n onClick={handleBrandClick}\n data-id=\"brand-secondary\"\n data-testid=\"main__brand-secondary\"\n type=\"secondary\"\n />\n </>\n )}\n </div>\n );\n\n const renderMobileMenuButton = () => {\n const drawerItems = items.mobile || items.desktop;\n if (\n (drawerItems && drawerItems.length > 0) ||\n (actionButtons && hasCollapsibleActionButtons(actionButtons))\n ) {\n return (\n <ClickableIcon\n ref={mobileMenuRef}\n className={styles.mobileMenuButton}\n aria-label={showDrawer ? \"Close nav menu\" : \"Open nav menu\"}\n aria-expanded={showDrawer}\n data-testid=\"button__mobile-menu\"\n onClick={handleMobileMenuButtonClick}\n focusHighlight={true}\n >\n <MenuIcon className={styles.mobileMenuIcon} />\n </ClickableIcon>\n );\n }\n\n return null;\n };\n\n const renderNavbar = () => {\n return (\n <Layout.Content stretch={isStretch}>\n <nav\n className={clsx(\n styles.nav,\n compress && styles.navCompressed,\n theme?.mode === \"dark\" && styles.navDark\n )}\n aria-label={headerLabel}\n >\n {!hideNavBranding && renderBrand()}\n {!hideNavElements && (\n <div\n className={clsx(\n styles.navElementsContainer,\n !hideNavBranding &&\n styles.navElementsContainerWithBranding\n )}\n >\n <NavbarItems\n items={items.desktop}\n onItemClick={handleNavItemClick}\n selectedId={selectedId}\n hideNavBranding={hideNavBranding}\n hideLinkIndicator={hideLinkIndicator}\n />\n <NavbarActionButtons\n actionButtons={actionButtons}\n onActionButtonClick={handleActionButtonClick}\n />\n {renderMobileMenuButton()}\n </div>\n )}\n </nav>\n\n {!hideNavElements && renderDrawer()}\n </Layout.Content>\n );\n };\n\n return (\n <div\n ref={elementRef}\n className={clsx(\n styles.wrapper,\n fixed ? styles.wrapperFixed : styles.wrapperRelative,\n theme?.mode === \"dark\"\n ? styles.wrapperDark\n : styles.wrapperLight,\n className\n )}\n id={id || \"navbar-wrapper\"}\n data-testid={otherProps[\"data-testid\"] || \"navbar-wrapper\"}\n >\n {masthead && <Masthead stretch={isStretch} />}\n {renderNavbar()}\n </div>\n );\n};\n\n// @catalog\n/**\n * The main site navigation bar with desktop and mobile drawer views.\n *\n * Use `Navbar` to render the primary navigation header. It displays brand\n * logos, navigation items, and action buttons in a desktop bar, and\n * automatically collapses items into a slide-in drawer for mobile viewports.\n */\nexport const Navbar = forwardRef(Component);\n"],"names":["Navbar","forwardRef","_a","ref","items","className","id","selectedId","compress","fixed","resources","hideNavElements","hideNavBranding","hideLinkIndicator","drawerDismissalExclusions","blockDrawerDismissalMethods","actionButtons","onItemClick","onActionButtonClick","onBrandClick","masthead","layout","headerLabel","drawerLabel","otherProps","__rest","showDrawer","setShowDrawer","useState","showOverlay","setShowOverlay","mobileMenuRef","useRef","isStretch","elementRef","theme","useContext","ThemeContext","defaultResource","getDefaultResourceLogo","tabletWidth","parsePxOrRemValue","useResolvedBreakpointToken","Breakpoint","primary","secondary","useImperativeHandle","Object","assign","current","dismissDrawer","useEffect","handleResize","window","addEventListener","removeEventListener","setTimeout","shouldDismissDrawer","dismissalMethod","indexOf","innerWidth","handleBrandClick","_event","type","handleNavItemClick","event","item","NavbarHelper","isNavItemCommon","onClick","preventDefault","isNavItemLink","subMenu","handleActionButtonClick","actionButton","args","handleMobileMenuButtonClick","handleDrawerClose","renderMobileMenuButton","drawerItems","mobile","desktop","length","drawerActionButtons","some","uncollapsible","hasCollapsibleActionButtons","_jsx","ClickableIcon","styles.mobileMenuButton","focusHighlight","children","MenuIcon","styles.mobileMenuIcon","_jsxs","clsx","styles.wrapper","styles.wrapperFixed","styles.wrapperRelative","mode","styles.wrapperDark","styles.wrapperLight","Masthead","stretch","Layout","Content","styles.nav","styles.navCompressed","styles.navDark","styles.navBrandContainer","styles.navBrandContainerCompressed","styles.navBrandContainerFull","styles.navBrandContainerResponsive","Brand","_Fragment","styles.navSeparator","styles.navSeparatorCompressed","styles.navSeparatorFull","styles.navSeparatorResponsive","styles.navElementsContainer","styles.navElementsContainerWithBranding","NavbarItems","NavbarActionButtons","Overlay","show","enableOverlayClick","onOverlayClick","Drawer","onClose"],"mappings":"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"}
package/navbar/types.d.ts CHANGED
@@ -72,6 +72,7 @@ export interface NavbarActionButtonCtaProps {
72
72
  }
73
73
  /** Props for the internal `"component"` type action button wrapper. */
74
74
  interface NavbarButtonComponentProps {
75
+ /** The custom component to be rendered */
75
76
  render: JSX.Element;
76
77
  }
77
78
  /** Props for a `"component"` type action button in the navbar. */
@@ -1 +1 @@
1
- {"version":3,"file":"notification-banner.js","sources":["../../src/notification-banner/notification-banner.tsx"],"sourcesContent":["import { CrossIcon } from \"@lifesg/react-icons\";\nimport clsx from \"clsx\";\nimport type { NamedExoticComponent } from \"react\";\nimport React, { useEffect, useRef, useState } from \"react\";\nimport { useResizeDetector } from \"react-resize-detector\";\n\nimport { Layout } from \"../layout\";\nimport { VisuallyHidden } from \"../shared/accessibility\";\nimport { ClickableIcon } from \"../shared/clickable-icon\";\nimport { formatUnitValue, useApplyStyle } from \"../theme\";\nimport { Typography } from \"../typography\";\nimport * as styles from \"./notification-banner.styles\";\nimport type {\n NotificationBannerProps,\n NotificationBannerWithForwardedRefProps,\n} from \"./types\";\n\nexport const NBComponent = ({\n children,\n visible = true,\n dismissible = true,\n sticky = true,\n onDismiss,\n id,\n forwardedRef,\n maxCollapsedHeight,\n onClick,\n actionButton,\n icon,\n className,\n ...otherProps\n}: NotificationBannerWithForwardedRefProps) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const testId = otherProps[\"data-testid\"];\n\n const [isVisible, setVisible] = useState<boolean>(visible);\n const { height: contentHeight = 0, ref: contentRef } = useResizeDetector();\n const contentTextRef = useRef<HTMLDivElement>(null);\n\n const isCollapsed =\n maxCollapsedHeight && contentHeight > maxCollapsedHeight;\n\n useApplyStyle(contentTextRef, {\n [styles.tokens.contentText.maxCollapsedHeight]: isCollapsed\n ? formatUnitValue(maxCollapsedHeight, \"px\")\n : undefined,\n });\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n setVisible(visible);\n }, [visible]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleDismiss = (event: React.MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n setVisible(false);\n\n if (dismissible && onDismiss) onDismiss();\n };\n\n const handleActionButtonOnClick = (\n event: React.MouseEvent<HTMLButtonElement>\n ) => {\n if (!actionButton?.onClick) {\n // let it bubble\n return;\n }\n event.stopPropagation();\n actionButton.onClick(event);\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n if (!isVisible) return null;\n\n const renderDismissButton = () => (\n <ClickableIcon\n className={styles.dismissButton}\n tabIndex={0}\n onClick={handleDismiss}\n id={formatId(\"dismiss-button\", id)}\n data-testid={formatId(\"dismiss-button\", testId)}\n focusOutline=\"browser\"\n focusHighlight={false}\n type=\"button\"\n aria-label=\"close\"\n >\n <CrossIcon aria-hidden />\n </ClickableIcon>\n );\n\n const renderActionButton = () => {\n if (!actionButton) return null;\n\n return (\n <button\n className={styles.actionButton}\n id={formatId(\"action-button\", id)}\n data-testid={formatId(\"action-button\", testId)}\n type=\"button\"\n {...actionButton}\n onClick={handleActionButtonOnClick}\n >\n {actionButton.children}\n </button>\n );\n };\n\n const renderContent = () => (\n <div\n className={styles.content}\n data-testid={formatId(\"text-content\", testId)}\n >\n <div className={styles.contentWrapper}>\n <div\n ref={contentTextRef}\n className={clsx(\n styles.contentText,\n isCollapsed && styles.contentTextCollapsed\n )}\n >\n <div ref={contentRef}>{children}</div>\n </div>\n {renderActionButton()}\n </div>\n </div>\n );\n\n const renderAccessibleBannerButton = () => (\n <VisuallyHidden>\n <button aria-label={\"Clickable banner\"} type=\"button\" />\n </VisuallyHidden>\n );\n\n return (\n <div\n ref={forwardedRef}\n className={clsx(\n styles.wrapper,\n sticky && styles.wrapperSticky,\n !!onClick && styles.wrapperClickable,\n className\n )}\n onClick={onClick}\n role=\"region\"\n {...otherProps}\n >\n <Layout.Content id={formatId(\"container\", id)}>\n {icon && (\n <div className={styles.iconContainer} aria-hidden>\n {icon}\n </div>\n )}\n <div className={styles.contentContainer}>{renderContent()}</div>\n {dismissible && renderDismissButton()}\n </Layout.Content>\n {onClick && renderAccessibleBannerButton()}\n </div>\n );\n};\n\n/**\n * Intermediate component to handle passing the ref as a prop\n */\nconst NBWithRef = (\n props: NotificationBannerProps,\n ref: React.Ref<HTMLDivElement>\n) => {\n return <NBComponent {...props} forwardedRef={ref} />;\n};\n\nconst NBLink = React.forwardRef<\n HTMLAnchorElement,\n React.ComponentProps<typeof Typography.LinkBL>\n>(function NotificationBannerLink(props, ref) {\n return (\n <Typography.LinkBL\n ref={ref}\n className={clsx(styles.contentLink, props.className)}\n {...props}\n />\n );\n});\n(NBLink as NamedExoticComponent).displayName = \"NotificationBanner.Link\";\n\n// =============================================================================\n// HELPER FUNCTIONS\n// =============================================================================\nconst formatId = (componentName: string, id = \"wrapper\"): string => {\n return `${id}-${componentName}`;\n};\n\n// =============================================================================\n// EXPORTABLE\n// =============================================================================\nconst Base = React.forwardRef(NBWithRef);\n(Base as NamedExoticComponent).displayName = \"NotificationBanner\";\n\n/**\n * A full-width informational banner that sits at the top of the page.\n *\n * Use `NotificationBanner` to surface important or persistent messages that\n * should remain visible until the user dismisses them.\n */\nexport const NotificationBanner = Object.assign(Base, {\n /** Renders an inline link styled for use inside a `NotificationBanner`. */\n Link: NBLink,\n});\n"],"names":["NBComponent","_a","children","visible","dismissible","sticky","onDismiss","id","forwardedRef","maxCollapsedHeight","onClick","actionButton","icon","className","otherProps","__rest","testId","isVisible","setVisible","useState","height","contentHeight","ref","contentRef","useResizeDetector","contentTextRef","useRef","isCollapsed","useApplyStyle","styles.tokens","contentText","formatUnitValue","undefined","useEffect","handleDismiss","event","stopPropagation","handleActionButtonOnClick","_jsxs","clsx","styles.wrapper","styles.wrapperSticky","styles.wrapperClickable","role","Layout","Content","formatId","_jsx","styles.iconContainer","styles.contentContainer","styles.content","styles.contentWrapper","styles.contentText","styles.contentTextCollapsed","Object","assign","styles.actionButton","type","ClickableIcon","styles.dismissButton","tabIndex","focusOutline","focusHighlight","CrossIcon","VisuallyHidden","NBLink","React","forwardRef","props","Typography","LinkBL","styles.contentLink","displayName","componentName","Base","NotificationBanner","Link"],"mappings":"itCAiBO,MAAMA,EAAeC,IAAA,IAAAC,SACxBA,EAAQC,QACRA,GAAU,EAAIC,YACdA,GAAc,EAAIC,OAClBA,GAAS,EAAIC,UACbA,EAASC,GACTA,EAAEC,aACFA,EAAYC,mBACZA,EAAkBC,QAClBA,EAAOC,aACPA,EAAYC,KACZA,EAAIC,UACJA,GAASZ,EACNa,EAAUC,EAAAd,EAbW,gJAkBxB,MAAMe,EAASF,EAAW,gBAEnBG,EAAWC,GAAcC,EAAkBhB,IAC1CiB,OAAQC,EAAgB,EAAGC,IAAKC,GAAeC,IACjDC,EAAiBC,EAAuB,MAExCC,EACFlB,GAAsBY,EAAgBZ,EAE1CmB,EAAcH,EAAgB,CAC1B,CAACI,EAAcC,YAAYrB,oBAAqBkB,EAC1CI,EAAgBtB,EAAoB,WACpCuB,IAMVC,GAAU,KACNf,EAAWf,EAAQ,GACpB,CAACA,IAKJ,MAAM+B,EAAiBC,IACnBA,EAAMC,kBACNlB,GAAW,GAEPd,GAAeE,GAAWA,GAAW,EAGvC+B,EACFF,KAEKxB,aAAY,EAAZA,EAAcD,WAInByB,EAAMC,kBACNzB,EAAaD,QAAQyB,GAAM,EAM/B,IAAKlB,EAAW,OAAO,KA6DvB,OACIqB,uBACIhB,IAAKd,EACLK,UAAW0B,EACPC,EACAnC,GAAUoC,IACR/B,GAAWgC,EACb7B,GAEJH,QAASA,EACTiC,KAAK,UACD7B,aAEJwB,EAACM,EAAOC,QAAO,CAACtC,GAAIuC,EAAS,YAAavC,GAAGL,SAAA,CACxCU,GACGmC,SAAKlC,UAAWmC,4BACXpC,IAGTmC,EAAA,MAAA,CAAKlC,UAAWoC,EAAuB/C,SA5C/C6C,EAAA,MAAA,CACIlC,UAAWqC,EAAc,cACZJ,EAAS,eAAgB9B,GAAOd,SAE7CoC,EAAA,MAAA,CAAKzB,UAAWsC,EAAqBjD,SAAA,CACjC6C,EAAA,MAAA,CACIzB,IAAKG,EACLZ,UAAW0B,EACPa,EACAzB,GAAe0B,GAClBnD,SAED6C,EAAA,MAAA,CAAKzB,IAAKC,EAAUrB,SAAGA,MA7B9BS,EAGDoC,EAAA,SAAAO,OAAAC,OAAA,CACI1C,UAAW2C,EACXjD,GAAIuC,EAAS,gBAAiBvC,iBACjBuC,EAAS,gBAAiB9B,GACvCyC,KAAK,UACD9C,EAAY,CAChBD,QAAS2B,EAAyBnC,SAEjCS,EAAaT,YAXI,YA8DjBE,GA9ET2C,EAACW,EAAa,CACV7C,UAAW8C,EACXC,SAAU,EACVlD,QAASwB,EACT3B,GAAIuC,EAAS,iBAAkBvC,GAAG,cACrBuC,EAAS,iBAAkB9B,GACxC6C,aAAa,UACbC,gBAAgB,EAChBL,KAAK,SAAQ,aACF,QAAOvD,SAElB6C,EAACgB,EAAS,CAAA,eAAA,SAqETrD,GA3BLqC,EAACiB,EAAc,CAAA9D,SACX6C,EAAA,SAAA,CAAA,aAAoB,mBAAoBU,KAAK,gBA2B3C,EAcRQ,EAASC,EAAMC,YAGnB,SAAgCC,EAAO9C,GACrC,OACIyB,EAACsB,EAAWC,OAAMhB,OAAAC,OAAA,CACdjC,IAAKA,EACLT,UAAW0B,EAAKgC,EAAoBH,EAAMvD,YACtCuD,GAGhB,IACCH,EAAgCO,YAAc,0BAK/C,MAAM1B,EAAW,CAAC2B,EAAuBlE,EAAK,YACnC,GAAGA,KAAMkE,IAMdC,EAAOR,EAAMC,YA/BD,CACdC,EACA9C,IAEOyB,EAAC/C,EAAWsD,OAAAC,OAAA,GAAKa,GAAO5D,aAAcc,OA4BhDoD,EAA8BF,YAAc,2BAQhCG,EAAqBrB,OAAOC,OAAOmB,EAAM,CAElDE,KAAMX"}
1
+ {"version":3,"file":"notification-banner.js","sources":["../../src/notification-banner/notification-banner.tsx"],"sourcesContent":["import { CrossIcon } from \"@lifesg/react-icons\";\nimport clsx from \"clsx\";\nimport type { NamedExoticComponent } from \"react\";\nimport React, { useEffect, useRef, useState } from \"react\";\nimport { useResizeDetector } from \"react-resize-detector\";\n\nimport { Layout } from \"../layout\";\nimport { VisuallyHidden } from \"../shared/accessibility\";\nimport { ClickableIcon } from \"../shared/clickable-icon\";\nimport { formatUnitValue, useApplyStyle } from \"../theme\";\nimport { Typography } from \"../typography\";\nimport * as styles from \"./notification-banner.styles\";\nimport type {\n NotificationBannerProps,\n NotificationBannerWithForwardedRefProps,\n} from \"./types\";\n\nexport const NBComponent = ({\n children,\n visible = true,\n dismissible = true,\n sticky = true,\n onDismiss,\n id,\n forwardedRef,\n maxCollapsedHeight,\n onClick,\n actionButton,\n icon,\n className,\n ...otherProps\n}: NotificationBannerWithForwardedRefProps) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const testId = otherProps[\"data-testid\"];\n\n const [isVisible, setVisible] = useState<boolean>(visible);\n const { height: contentHeight = 0, ref: contentRef } = useResizeDetector();\n const contentTextRef = useRef<HTMLDivElement>(null);\n\n const isCollapsed =\n maxCollapsedHeight && contentHeight > maxCollapsedHeight;\n\n useApplyStyle(contentTextRef, {\n [styles.tokens.contentText.maxCollapsedHeight]: isCollapsed\n ? formatUnitValue(maxCollapsedHeight, \"px\")\n : undefined,\n });\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n setVisible(visible);\n }, [visible]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleDismiss = (event: React.MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n setVisible(false);\n\n if (dismissible && onDismiss) onDismiss();\n };\n\n const handleActionButtonOnClick = (\n event: React.MouseEvent<HTMLButtonElement>\n ) => {\n if (!actionButton?.onClick) {\n // let it bubble\n return;\n }\n event.stopPropagation();\n actionButton.onClick(event);\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n if (!isVisible) return null;\n\n const renderDismissButton = () => (\n <ClickableIcon\n className={styles.dismissButton}\n tabIndex={0}\n onClick={handleDismiss}\n id={formatId(\"dismiss-button\", id)}\n data-testid={formatId(\"dismiss-button\", testId)}\n focusOutline=\"browser\"\n focusHighlight={false}\n type=\"button\"\n aria-label=\"close\"\n >\n <CrossIcon aria-hidden />\n </ClickableIcon>\n );\n\n const renderActionButton = () => {\n if (!actionButton) return null;\n\n return (\n <button\n className={styles.actionButton}\n id={formatId(\"action-button\", id)}\n data-testid={formatId(\"action-button\", testId)}\n type=\"button\"\n {...actionButton}\n onClick={handleActionButtonOnClick}\n >\n {actionButton.children}\n </button>\n );\n };\n\n const renderContent = () => (\n <div\n className={styles.content}\n data-testid={formatId(\"text-content\", testId)}\n >\n <div className={styles.contentWrapper}>\n <div\n ref={contentTextRef}\n className={clsx(\n styles.contentText,\n isCollapsed && styles.contentTextCollapsed\n )}\n >\n <div ref={contentRef}>{children}</div>\n </div>\n {renderActionButton()}\n </div>\n </div>\n );\n\n const renderAccessibleBannerButton = () => (\n <VisuallyHidden>\n <button aria-label={\"Clickable banner\"} type=\"button\" />\n </VisuallyHidden>\n );\n\n return (\n <div\n ref={forwardedRef}\n className={clsx(\n styles.wrapper,\n sticky && styles.wrapperSticky,\n !!onClick && styles.wrapperClickable,\n className\n )}\n onClick={onClick}\n role=\"region\"\n {...otherProps}\n >\n <Layout.Content id={formatId(\"container\", id)}>\n {icon && (\n <div className={styles.iconContainer} aria-hidden>\n {icon}\n </div>\n )}\n <div className={styles.contentContainer}>{renderContent()}</div>\n {dismissible && renderDismissButton()}\n </Layout.Content>\n {onClick && renderAccessibleBannerButton()}\n </div>\n );\n};\n\n/**\n * Intermediate component to handle passing the ref as a prop\n */\nconst NBWithRef = (\n props: NotificationBannerProps,\n ref: React.Ref<HTMLDivElement>\n) => {\n return <NBComponent {...props} forwardedRef={ref} />;\n};\n\nconst NBLink = React.forwardRef<\n HTMLAnchorElement,\n React.ComponentProps<typeof Typography.LinkBL>\n>(function NotificationBannerLink(props, ref) {\n return (\n <Typography.LinkBL\n ref={ref}\n className={clsx(styles.contentLink, props.className)}\n {...props}\n />\n );\n});\n(NBLink as NamedExoticComponent).displayName = \"NotificationBanner.Link\";\n\n// =============================================================================\n// HELPER FUNCTIONS\n// =============================================================================\nconst formatId = (componentName: string, id = \"wrapper\"): string => {\n return `${id}-${componentName}`;\n};\n\n// =============================================================================\n// EXPORTABLE\n// =============================================================================\nconst Base = React.forwardRef(NBWithRef);\n(Base as NamedExoticComponent).displayName = \"NotificationBanner\";\n\n// @catalog\n/**\n * A full-width informational banner that sits at the top of the page.\n *\n * Use `NotificationBanner` to surface important or persistent messages that\n * should remain visible until the user dismisses them.\n */\nexport const NotificationBanner = Object.assign(Base, {\n /** Renders an inline link styled for use inside a `NotificationBanner`. */\n Link: NBLink,\n});\n"],"names":["NBComponent","_a","children","visible","dismissible","sticky","onDismiss","id","forwardedRef","maxCollapsedHeight","onClick","actionButton","icon","className","otherProps","__rest","testId","isVisible","setVisible","useState","height","contentHeight","ref","contentRef","useResizeDetector","contentTextRef","useRef","isCollapsed","useApplyStyle","styles.tokens","contentText","formatUnitValue","undefined","useEffect","handleDismiss","event","stopPropagation","handleActionButtonOnClick","_jsxs","clsx","styles.wrapper","styles.wrapperSticky","styles.wrapperClickable","role","Layout","Content","formatId","_jsx","styles.iconContainer","styles.contentContainer","styles.content","styles.contentWrapper","styles.contentText","styles.contentTextCollapsed","Object","assign","styles.actionButton","type","ClickableIcon","styles.dismissButton","tabIndex","focusOutline","focusHighlight","CrossIcon","VisuallyHidden","NBLink","React","forwardRef","props","Typography","LinkBL","styles.contentLink","displayName","componentName","Base","NotificationBanner","Link"],"mappings":"itCAiBO,MAAMA,EAAeC,IAAA,IAAAC,SACxBA,EAAQC,QACRA,GAAU,EAAIC,YACdA,GAAc,EAAIC,OAClBA,GAAS,EAAIC,UACbA,EAASC,GACTA,EAAEC,aACFA,EAAYC,mBACZA,EAAkBC,QAClBA,EAAOC,aACPA,EAAYC,KACZA,EAAIC,UACJA,GAASZ,EACNa,EAAUC,EAAAd,EAbW,gJAkBxB,MAAMe,EAASF,EAAW,gBAEnBG,EAAWC,GAAcC,EAAkBhB,IAC1CiB,OAAQC,EAAgB,EAAGC,IAAKC,GAAeC,IACjDC,EAAiBC,EAAuB,MAExCC,EACFlB,GAAsBY,EAAgBZ,EAE1CmB,EAAcH,EAAgB,CAC1B,CAACI,EAAcC,YAAYrB,oBAAqBkB,EAC1CI,EAAgBtB,EAAoB,WACpCuB,IAMVC,GAAU,KACNf,EAAWf,EAAQ,GACpB,CAACA,IAKJ,MAAM+B,EAAiBC,IACnBA,EAAMC,kBACNlB,GAAW,GAEPd,GAAeE,GAAWA,GAAW,EAGvC+B,EACFF,KAEKxB,aAAY,EAAZA,EAAcD,WAInByB,EAAMC,kBACNzB,EAAaD,QAAQyB,GAAM,EAM/B,IAAKlB,EAAW,OAAO,KA6DvB,OACIqB,uBACIhB,IAAKd,EACLK,UAAW0B,EACPC,EACAnC,GAAUoC,IACR/B,GAAWgC,EACb7B,GAEJH,QAASA,EACTiC,KAAK,UACD7B,aAEJwB,EAACM,EAAOC,QAAO,CAACtC,GAAIuC,EAAS,YAAavC,GAAGL,SAAA,CACxCU,GACGmC,SAAKlC,UAAWmC,4BACXpC,IAGTmC,EAAA,MAAA,CAAKlC,UAAWoC,EAAuB/C,SA5C/C6C,EAAA,MAAA,CACIlC,UAAWqC,EAAc,cACZJ,EAAS,eAAgB9B,GAAOd,SAE7CoC,EAAA,MAAA,CAAKzB,UAAWsC,EAAqBjD,SAAA,CACjC6C,EAAA,MAAA,CACIzB,IAAKG,EACLZ,UAAW0B,EACPa,EACAzB,GAAe0B,GAClBnD,SAED6C,EAAA,MAAA,CAAKzB,IAAKC,EAAUrB,SAAGA,MA7B9BS,EAGDoC,EAAA,SAAAO,OAAAC,OAAA,CACI1C,UAAW2C,EACXjD,GAAIuC,EAAS,gBAAiBvC,iBACjBuC,EAAS,gBAAiB9B,GACvCyC,KAAK,UACD9C,EAAY,CAChBD,QAAS2B,EAAyBnC,SAEjCS,EAAaT,YAXI,YA8DjBE,GA9ET2C,EAACW,EAAa,CACV7C,UAAW8C,EACXC,SAAU,EACVlD,QAASwB,EACT3B,GAAIuC,EAAS,iBAAkBvC,GAAG,cACrBuC,EAAS,iBAAkB9B,GACxC6C,aAAa,UACbC,gBAAgB,EAChBL,KAAK,SAAQ,aACF,QAAOvD,SAElB6C,EAACgB,EAAS,CAAA,eAAA,SAqETrD,GA3BLqC,EAACiB,EAAc,CAAA9D,SACX6C,EAAA,SAAA,CAAA,aAAoB,mBAAoBU,KAAK,gBA2B3C,EAcRQ,EAASC,EAAMC,YAGnB,SAAgCC,EAAO9C,GACrC,OACIyB,EAACsB,EAAWC,OAAMhB,OAAAC,OAAA,CACdjC,IAAKA,EACLT,UAAW0B,EAAKgC,EAAoBH,EAAMvD,YACtCuD,GAGhB,IACCH,EAAgCO,YAAc,0BAK/C,MAAM1B,EAAW,CAAC2B,EAAuBlE,EAAK,YACnC,GAAGA,KAAMkE,IAMdC,EAAOR,EAAMC,YA/BD,CACdC,EACA9C,IAEOyB,EAAC/C,EAAWsD,OAAAC,OAAA,GAAKa,GAAO5D,aAAcc,OA4BhDoD,EAA8BF,YAAc,2BAShCG,EAAqBrB,OAAOC,OAAOmB,EAAM,CAElDE,KAAMX"}
@@ -1,2 +1,2 @@
1
- import{__rest as e}from"../_virtual/_tslib.js";import{jsxs as t,jsx as r}from"react/jsx-runtime";import n from"clsx";import{forwardRef as o,useRef as a,useState as i,useEffect as s,useImperativeHandle as l}from"react";import{Button as d}from"../button/button.js";import{FormErrorMessage as c}from"../form/form-label.js";import{Input as u}from"../input/input.js";import{VisuallyHidden as p}from"../shared/accessibility/index.js";import{Typography as m}from"../typography/index.js";import"../util/calendar-helper.js";import"../external/dayjs/dayjs.min.js";import{useId as f}from"../util/simple-id-generator.js";import{StringHelper as v}from"../util/string-helper.js";import"@react-aria/live-announcer";import{inputContainer as y,prefix as g,inputField as h,ctaButton as b,wrapper as w}from"./otp-input.styles.js";import{stripOtpFromAutofill as j,validateUserInput as C}from"./utils.js";const O=o(((o,O)=>{var{id:$,value:x=[],"data-testid":D,className:T,cooldownDuration:P,actionButtonProps:N,errorMessage:k,numOfInput:B,prefix:R,onChange:I,onCooldownStart:A,onCooldownEnd:E,otpOnly:L,onCountdownChange:M}=o,S=e(o,["id","value","data-testid","className","cooldownDuration","actionButtonProps","errorMessage","numOfInput","prefix","onChange","onCooldownStart","onCooldownEnd","otpOnly","onCountdownChange"]);const _=null!=N?N:{},{disabled:z,onClick:K,styleType:q="secondary"}=_,F=e(_,["disabled","onClick","styleType"]),G=a([]),H=a(I),[J,Q]=i(new Array(B).fill("")),[U,V]=i(P),[W,X]=i(new Date),Y=f(),Z=!!k,ee=`${Y}-error`,te=`${Y}-timer`;s((()=>{var e;return null===(e=null==G?void 0:G.current[0])||void 0===e||e.focus(),document.addEventListener("paste",ae),()=>document.removeEventListener("paste",ae)}),[]),s((()=>{if(0!==P){A&&A();const e=se();return()=>e()}}),[W]),l(O,(()=>({startCooldown:()=>{X(new Date),V(P)}}))),s((()=>{H.current=I}),[I]),s((()=>{x.length===B&&Q(x)}),[x]);const re=e=>{if(e&&C(e,B)){const t=e.split("");return Q(t),H.current&&H.current(t),!0}return!1},ne=e=>t=>{var r;const n=t.target.value,o=J.every((e=>""===e)),a=j(n,B,R);if(o&&re(a))return;const i=n.replace(/[^0-9]/g,"");if(C(i)){const t=[...J];t[e]=i.substring(i.length-1),null===(r=G.current[e+1])||void 0===r||r.focus(),Q(t),I&&I(t)}},oe=e=>t=>{var r,n,o;const{key:a,code:i}=t;if("Backspace"===a||"Backspace"===i){const t=[...J];""!==t[e]?t[e]="":0!==e&&(t[e-1]="",null===(r=G.current[e-1])||void 0===r||r.focus()),Q(t),I&&I(t)}else"ArrowRight"===t.code?null===(n=G.current[e+1])||void 0===n||n.focus():"ArrowLeft"===t.code&&(null===(o=G.current[e-1])||void 0===o||o.focus())},ae=e=>{if(!e.clipboardData)return;const t=e.clipboardData.getData("text"),r=j(t,B,R);re(r)||e.preventDefault()},ie=()=>{const e=Date.now(),t=1e3*P;return e<W.valueOf()+t},se=()=>{const e=setInterval((()=>{const t=Date.now(),r=1e3*P,n=Math.ceil((W.valueOf()+r-t)/1e3);V(n),n<=0?(E&&E(),clearInterval(e)):M&&M(n)}),1e3);return()=>{clearInterval(e)}},le=(e,t,r)=>r?`${r}-${t}-${e+1}`:`${t}-${e+1}`,de=e=>`${e} second${1===e?"":"s"}`;return t("div",{id:$,"data-testid":D,className:n(w,T),children:[t("div",{className:y,role:"group","aria-label":`${B}-digit OTP input field`,children:[R&&t(m.BodyBL,{as:"span",className:g,"data-testid":"otp-prefix",weight:"semibold",children:[r(p,{children:"O T P prefix"}),`${R.value} ${R.separator}`]}),J.map(((e,t)=>r(u,Object.assign({className:h,id:le(t,"otp-input",$),"data-testid":le(t,"otp-input",D),"aria-label":`${v.formatOrdinal(t+1)} digit`,"aria-invalid":Z,"aria-describedby":Z?ee:void 0,ref:e=>G.current[t]=e,type:"text",inputMode:"numeric",value:e,error:Z,onChange:ne(t),onKeyDown:oe(t),autoComplete:"off"},S),t)))]}),k&&r(c,{id:ee,"data-testid":"otp-error-message",children:k}),t(p,{role:"timer",id:te,children:[de(U)," remaining"]}),r(p,{"aria-live":"polite",children:U>0?"":"Ready to resend OTP"}),!L&&r(d,Object.assign({className:b,styleType:q,type:"button",sizeType:"small"},F,{onClick:e=>{Q(new Array(B).fill("")),ie()||(X(new Date),V(P)),K&&K(e)},disabled:z||ie()},F.children?{children:F.children}:{children:U>0?`Resend OTP in ${de(U)}`:"Resend OTP","aria-label":U>0?`Resend OTP in ${de(P)}`:"Resend OTP","aria-describedby":te}))]})}));export{O as OtpInput};
1
+ import{__rest as e}from"../_virtual/_tslib.js";import{jsxs as t,jsx as r}from"react/jsx-runtime";import n from"clsx";import{forwardRef as o,useRef as a,useState as i,useEffect as l,useImperativeHandle as s}from"react";import{Button as d}from"../button/button.js";import{FormErrorMessage as c}from"../form/form-label/form-label.js";import{Input as u}from"../input/input.js";import{VisuallyHidden as p}from"../shared/accessibility/index.js";import{Typography as m}from"../typography/index.js";import"../util/calendar-helper.js";import"../external/dayjs/dayjs.min.js";import{useId as f}from"../util/simple-id-generator.js";import{StringHelper as v}from"../util/string-helper.js";import"@react-aria/live-announcer";import{inputContainer as y,prefix as g,inputField as h,ctaButton as b,wrapper as w}from"./otp-input.styles.js";import{stripOtpFromAutofill as j,validateUserInput as C}from"./utils.js";const O=o(((o,O)=>{var{id:$,value:x=[],"data-testid":D,className:T,cooldownDuration:P,actionButtonProps:N,errorMessage:k,numOfInput:B,prefix:R,onChange:I,onCooldownStart:A,onCooldownEnd:E,otpOnly:L,onCountdownChange:M}=o,S=e(o,["id","value","data-testid","className","cooldownDuration","actionButtonProps","errorMessage","numOfInput","prefix","onChange","onCooldownStart","onCooldownEnd","otpOnly","onCountdownChange"]);const _=null!=N?N:{},{disabled:z,onClick:K,styleType:q="secondary"}=_,F=e(_,["disabled","onClick","styleType"]),G=a([]),H=a(I),[J,Q]=i(new Array(B).fill("")),[U,V]=i(P),[W,X]=i(new Date),Y=f(),Z=!!k,ee=`${Y}-error`,te=`${Y}-timer`;l((()=>{var e;return null===(e=null==G?void 0:G.current[0])||void 0===e||e.focus(),document.addEventListener("paste",ae),()=>document.removeEventListener("paste",ae)}),[]),l((()=>{if(0!==P){A&&A();const e=le();return()=>e()}}),[W]),s(O,(()=>({startCooldown:()=>{X(new Date),V(P)}}))),l((()=>{H.current=I}),[I]),l((()=>{x.length===B&&Q(x)}),[x]);const re=e=>{if(e&&C(e,B)){const t=e.split("");return Q(t),H.current&&H.current(t),!0}return!1},ne=e=>t=>{var r;const n=t.target.value,o=J.every((e=>""===e)),a=j(n,B,R);if(o&&re(a))return;const i=n.replace(/[^0-9]/g,"");if(C(i)){const t=[...J];t[e]=i.substring(i.length-1),null===(r=G.current[e+1])||void 0===r||r.focus(),Q(t),I&&I(t)}},oe=e=>t=>{var r,n,o;const{key:a,code:i}=t;if("Backspace"===a||"Backspace"===i){const t=[...J];""!==t[e]?t[e]="":0!==e&&(t[e-1]="",null===(r=G.current[e-1])||void 0===r||r.focus()),Q(t),I&&I(t)}else"ArrowRight"===t.code?null===(n=G.current[e+1])||void 0===n||n.focus():"ArrowLeft"===t.code&&(null===(o=G.current[e-1])||void 0===o||o.focus())},ae=e=>{if(!e.clipboardData)return;const t=e.clipboardData.getData("text"),r=j(t,B,R);re(r)||e.preventDefault()},ie=()=>{const e=Date.now(),t=1e3*P;return e<W.valueOf()+t},le=()=>{const e=setInterval((()=>{const t=Date.now(),r=1e3*P,n=Math.ceil((W.valueOf()+r-t)/1e3);V(n),n<=0?(E&&E(),clearInterval(e)):M&&M(n)}),1e3);return()=>{clearInterval(e)}},se=(e,t,r)=>r?`${r}-${t}-${e+1}`:`${t}-${e+1}`,de=e=>`${e} second${1===e?"":"s"}`;return t("div",{id:$,"data-testid":D,className:n(w,T),children:[t("div",{className:y,role:"group","aria-label":`${B}-digit OTP input field`,children:[R&&t(m.BodyBL,{as:"span",className:g,"data-testid":"otp-prefix",weight:"semibold",children:[r(p,{children:"O T P prefix"}),`${R.value} ${R.separator}`]}),J.map(((e,t)=>r(u,Object.assign({className:h,id:se(t,"otp-input",$),"data-testid":se(t,"otp-input",D),"aria-label":`${v.formatOrdinal(t+1)} digit`,"aria-invalid":Z,"aria-describedby":Z?ee:void 0,ref:e=>G.current[t]=e,type:"text",inputMode:"numeric",value:e,error:Z,onChange:ne(t),onKeyDown:oe(t),autoComplete:"off"},S),t)))]}),k&&r(c,{id:ee,"data-testid":"otp-error-message",children:k}),t(p,{role:"timer",id:te,children:[de(U)," remaining"]}),r(p,{"aria-live":"polite",children:U>0?"":"Ready to resend OTP"}),!L&&r(d,Object.assign({className:b,styleType:q,type:"button",sizeType:"small"},F,{onClick:e=>{Q(new Array(B).fill("")),ie()||(X(new Date),V(P)),K&&K(e)},disabled:z||ie()},F.children?{children:F.children}:{children:U>0?`Resend OTP in ${de(U)}`:"Resend OTP","aria-label":U>0?`Resend OTP in ${de(P)}`:"Resend OTP","aria-describedby":te}))]})}));export{O as OtpInput};
2
2
  //# sourceMappingURL=otp-input.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"otp-input.js","sources":["../../src/otp-input/otp-input.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport type React from \"react\";\nimport {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\n\nimport { Button } from \"../button\";\nimport { FormErrorMessage } from \"../form/form-label\";\nimport { Input } from \"../input\";\nimport { VisuallyHidden } from \"../shared/accessibility\";\nimport { Typography } from \"../typography\";\nimport { StringHelper, useId } from \"../util\";\nimport * as styles from \"./otp-input.styles\";\nimport type { OtpInputProps, OtpInputRef } from \"./types\";\nimport { stripOtpFromAutofill, validateUserInput } from \"./utils\";\n\nconst Component = (\n {\n id,\n value = [],\n \"data-testid\": dataTestId,\n className,\n cooldownDuration,\n actionButtonProps,\n errorMessage,\n numOfInput,\n prefix,\n onChange,\n onCooldownStart,\n onCooldownEnd,\n otpOnly,\n onCountdownChange,\n ...otherProps\n }: OtpInputProps,\n ref: React.Ref<OtpInputRef>\n) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const {\n disabled,\n onClick,\n styleType = \"secondary\",\n ...otherCtaProps\n } = actionButtonProps ?? {};\n\n const inputRefs = useRef<(HTMLInputElement | null)[]>([]);\n const onChangeRef = useRef(onChange);\n\n const [otpValues, setOtpValues] = useState<string[]>(\n new Array(numOfInput).fill(\"\")\n );\n const [countDown, setCountDown] = useState<number>(cooldownDuration);\n const [lastCtaTimestamp, setLastCtaTimestamp] = useState<Date>(new Date());\n const internalId = useId();\n\n const hasError = !!errorMessage;\n const errorId = `${internalId}-error`;\n const timerId = `${internalId}-timer`;\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n inputRefs?.current[0]?.focus();\n document.addEventListener(\"paste\", handlePaste);\n return () => document.removeEventListener(\"paste\", handlePaste);\n }, []);\n\n useEffect(() => {\n if (cooldownDuration !== 0) {\n if (onCooldownStart) onCooldownStart();\n const cleanup = beginCountdown();\n\n return () => cleanup();\n }\n }, [lastCtaTimestamp]);\n\n useImperativeHandle(ref, () => ({\n startCooldown: () => {\n setLastCtaTimestamp(new Date());\n setCountDown(cooldownDuration);\n },\n }));\n\n useEffect(() => {\n onChangeRef.current = onChange;\n }, [onChange]);\n\n useEffect(() => {\n if (value.length === numOfInput) {\n setOtpValues(value);\n }\n }, [value]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleInputFullValue = (incomingValue: string) => {\n if (incomingValue && validateUserInput(incomingValue, numOfInput)) {\n const incomingValueArr = incomingValue.split(\"\");\n setOtpValues(incomingValueArr);\n if (onChangeRef.current) {\n onChangeRef.current(incomingValueArr);\n }\n\n return true;\n }\n\n return false;\n };\n\n const handleChange =\n (index: number) => (event: React.ChangeEvent<HTMLInputElement>) => {\n const eventValue = event.target.value;\n\n /* handle autofill */\n const fieldIsEmpty = otpValues.every((num) => num === \"\");\n const autofillOtp = stripOtpFromAutofill(\n eventValue,\n numOfInput,\n prefix\n );\n if (fieldIsEmpty && handleInputFullValue(autofillOtp)) {\n return;\n }\n\n /* handle normal input */\n const value = eventValue.replace(/[^0-9]/g, \"\");\n if (validateUserInput(value)) {\n const newOtpValues = [...otpValues];\n\n newOtpValues[index] = value.substring(value.length - 1);\n inputRefs.current[index + 1]?.focus();\n\n setOtpValues(newOtpValues);\n\n if (onChange) {\n onChange(newOtpValues);\n }\n }\n };\n\n const handleKeyDown =\n (index: number) => (event: React.KeyboardEvent<HTMLInputElement>) => {\n const { key, code } = event;\n\n if (key === \"Backspace\" || code === \"Backspace\") {\n const newOtpValues = [...otpValues];\n if (newOtpValues[index] !== \"\") {\n newOtpValues[index] = \"\";\n } else if (index !== 0) {\n newOtpValues[index - 1] = \"\";\n inputRefs.current[index - 1]?.focus();\n }\n\n setOtpValues(newOtpValues);\n\n if (onChange) {\n onChange(newOtpValues);\n }\n } else if (event.code === \"ArrowRight\") {\n inputRefs.current[index + 1]?.focus();\n } else if (event.code === \"ArrowLeft\") {\n inputRefs.current[index - 1]?.focus();\n }\n };\n\n const handlePaste = (event: ClipboardEvent): void => {\n if (!event.clipboardData) return;\n\n const pastedValue = event.clipboardData.getData(\"text\");\n const autofillOtp = stripOtpFromAutofill(\n pastedValue,\n numOfInput,\n prefix\n );\n if (!handleInputFullValue(autofillOtp)) {\n event.preventDefault();\n }\n };\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n setOtpValues(new Array(numOfInput).fill(\"\"));\n\n if (!isWithinCooldown()) {\n setLastCtaTimestamp(new Date());\n setCountDown(cooldownDuration);\n }\n\n if (onClick) {\n onClick(event);\n }\n };\n\n // =========================================================================\n // HELPER FUNCTIONS\n // =========================================================================\n const isWithinCooldown = (): boolean => {\n const currentTime = Date.now();\n const coolDownInMilliseconds = cooldownDuration * 1000;\n\n return (\n currentTime < lastCtaTimestamp.valueOf() + coolDownInMilliseconds\n );\n };\n\n const beginCountdown = () => {\n const interval = setInterval(() => {\n const currentTime = Date.now();\n const coolDownInMilliseconds = cooldownDuration * 1000;\n\n const timer = Math.ceil(\n (lastCtaTimestamp.valueOf() +\n coolDownInMilliseconds -\n currentTime) /\n 1000\n );\n setCountDown(timer);\n if (timer <= 0) {\n if (onCooldownEnd) onCooldownEnd();\n clearInterval(interval);\n } else if (onCountdownChange) {\n onCountdownChange(timer);\n }\n }, 1000);\n\n return () => {\n clearInterval(interval);\n };\n };\n\n const generateId = (index: number, name: string, prefix?: string) => {\n return prefix\n ? `${prefix}-${name}-${index + 1}`\n : `${name}-${index + 1}`;\n };\n\n const displaySeconds = (time: number) => {\n return `${time} second${time === 1 ? \"\" : \"s\"}`;\n };\n\n const getCTALabelProps = (): Partial<\n React.HTMLAttributes<HTMLButtonElement>\n > => {\n return otherCtaProps.children\n ? { children: otherCtaProps.children }\n : {\n children:\n countDown > 0\n ? `Resend OTP in ${displaySeconds(countDown)}`\n : \"Resend OTP\",\n // use a fixed label to avoid repeated screen reader updates when the button is focused\n \"aria-label\":\n countDown > 0\n ? `Resend OTP in ${displaySeconds(cooldownDuration)}`\n : \"Resend OTP\",\n // use a secondary element to reflect the latest countdown\n \"aria-describedby\": timerId,\n };\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n return (\n <div\n id={id}\n data-testid={dataTestId}\n className={clsx(styles.wrapper, className)}\n >\n <div\n className={styles.inputContainer}\n role=\"group\"\n aria-label={`${numOfInput}-digit OTP input field`}\n >\n {prefix && (\n <Typography.BodyBL\n as=\"span\"\n className={styles.prefix}\n data-testid=\"otp-prefix\"\n weight=\"semibold\"\n >\n <VisuallyHidden>O T P prefix</VisuallyHidden>\n {`${prefix.value} ${prefix.separator}`}\n </Typography.BodyBL>\n )}\n {otpValues.map((data, index) => {\n return (\n <Input\n className={styles.inputField}\n id={generateId(index, \"otp-input\", id)}\n data-testid={generateId(\n index,\n \"otp-input\",\n dataTestId\n )}\n aria-label={`${StringHelper.formatOrdinal(\n index + 1\n )} digit`}\n aria-invalid={hasError}\n aria-describedby={hasError ? errorId : undefined}\n key={index}\n ref={(el) => (inputRefs.current[index] = el)}\n type=\"text\"\n inputMode=\"numeric\"\n value={data}\n error={hasError}\n onChange={handleChange(index)}\n onKeyDown={handleKeyDown(index)}\n autoComplete=\"off\"\n {...otherProps}\n />\n );\n })}\n </div>\n {errorMessage && (\n <FormErrorMessage id={errorId} data-testid=\"otp-error-message\">\n {errorMessage}\n </FormErrorMessage>\n )}\n {/* visually hidden elements need to be rendered before the button so that Voiceover/Chrome doesn't skip the button */}\n <VisuallyHidden role=\"timer\" id={timerId}>\n {displaySeconds(countDown)} remaining\n </VisuallyHidden>\n <VisuallyHidden aria-live=\"polite\">\n {countDown > 0 ? \"\" : \"Ready to resend OTP\"}\n </VisuallyHidden>\n {!otpOnly && (\n <Button\n className={styles.ctaButton}\n styleType={styleType}\n type=\"button\"\n sizeType=\"small\"\n {...otherCtaProps}\n onClick={handleClick}\n disabled={disabled || isWithinCooldown()}\n {...getCTALabelProps()}\n />\n )}\n </div>\n );\n};\n\n/**\n * A field composed of individual inputs for a numeric one-time password\n * with an in-built countdown mechanism.\n *\n * Use `OtpInput` when users must enter the one-time password (OTP)\n * for multi-factored authentication methods.\n */\nexport const OtpInput = forwardRef(Component);\n"],"names":["OtpInput","forwardRef","_a","ref","id","value","dataTestId","className","cooldownDuration","actionButtonProps","errorMessage","numOfInput","prefix","onChange","onCooldownStart","onCooldownEnd","otpOnly","onCountdownChange","otherProps","__rest","_b","disabled","onClick","styleType","otherCtaProps","inputRefs","useRef","onChangeRef","otpValues","setOtpValues","useState","Array","fill","countDown","setCountDown","lastCtaTimestamp","setLastCtaTimestamp","Date","internalId","useId","hasError","errorId","timerId","useEffect","current","focus","document","addEventListener","handlePaste","removeEventListener","cleanup","beginCountdown","useImperativeHandle","startCooldown","length","handleInputFullValue","incomingValue","validateUserInput","incomingValueArr","split","handleChange","index","event","eventValue","target","fieldIsEmpty","every","num","autofillOtp","stripOtpFromAutofill","replace","newOtpValues","substring","handleKeyDown","key","code","_c","clipboardData","pastedValue","getData","preventDefault","isWithinCooldown","currentTime","now","coolDownInMilliseconds","valueOf","interval","setInterval","timer","Math","ceil","clearInterval","generateId","name","displaySeconds","time","_jsxs","clsx","styles.wrapper","children","styles.inputContainer","role","Typography","BodyBL","as","styles.prefix","weight","_jsx","VisuallyHidden","separator","map","data","Input","Object","assign","styles.inputField","StringHelper","formatOrdinal","undefined","el","type","inputMode","error","onKeyDown","autoComplete","FormErrorMessage","Button","styles.ctaButton","sizeType"],"mappings":"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"}
1
+ {"version":3,"file":"otp-input.js","sources":["../../src/otp-input/otp-input.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport type React from \"react\";\nimport {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from \"react\";\n\nimport { Button } from \"../button\";\nimport { FormErrorMessage } from \"../form/form-label\";\nimport { Input } from \"../input\";\nimport { VisuallyHidden } from \"../shared/accessibility\";\nimport { Typography } from \"../typography\";\nimport { StringHelper, useId } from \"../util\";\nimport * as styles from \"./otp-input.styles\";\nimport type { OtpInputProps, OtpInputRef } from \"./types\";\nimport { stripOtpFromAutofill, validateUserInput } from \"./utils\";\n\nconst Component = (\n {\n id,\n value = [],\n \"data-testid\": dataTestId,\n className,\n cooldownDuration,\n actionButtonProps,\n errorMessage,\n numOfInput,\n prefix,\n onChange,\n onCooldownStart,\n onCooldownEnd,\n otpOnly,\n onCountdownChange,\n ...otherProps\n }: OtpInputProps,\n ref: React.Ref<OtpInputRef>\n) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const {\n disabled,\n onClick,\n styleType = \"secondary\",\n ...otherCtaProps\n } = actionButtonProps ?? {};\n\n const inputRefs = useRef<(HTMLInputElement | null)[]>([]);\n const onChangeRef = useRef(onChange);\n\n const [otpValues, setOtpValues] = useState<string[]>(\n new Array(numOfInput).fill(\"\")\n );\n const [countDown, setCountDown] = useState<number>(cooldownDuration);\n const [lastCtaTimestamp, setLastCtaTimestamp] = useState<Date>(new Date());\n const internalId = useId();\n\n const hasError = !!errorMessage;\n const errorId = `${internalId}-error`;\n const timerId = `${internalId}-timer`;\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEffect(() => {\n inputRefs?.current[0]?.focus();\n document.addEventListener(\"paste\", handlePaste);\n return () => document.removeEventListener(\"paste\", handlePaste);\n }, []);\n\n useEffect(() => {\n if (cooldownDuration !== 0) {\n if (onCooldownStart) onCooldownStart();\n const cleanup = beginCountdown();\n\n return () => cleanup();\n }\n }, [lastCtaTimestamp]);\n\n useImperativeHandle(ref, () => ({\n startCooldown: () => {\n setLastCtaTimestamp(new Date());\n setCountDown(cooldownDuration);\n },\n }));\n\n useEffect(() => {\n onChangeRef.current = onChange;\n }, [onChange]);\n\n useEffect(() => {\n if (value.length === numOfInput) {\n setOtpValues(value);\n }\n }, [value]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleInputFullValue = (incomingValue: string) => {\n if (incomingValue && validateUserInput(incomingValue, numOfInput)) {\n const incomingValueArr = incomingValue.split(\"\");\n setOtpValues(incomingValueArr);\n if (onChangeRef.current) {\n onChangeRef.current(incomingValueArr);\n }\n\n return true;\n }\n\n return false;\n };\n\n const handleChange =\n (index: number) => (event: React.ChangeEvent<HTMLInputElement>) => {\n const eventValue = event.target.value;\n\n /* handle autofill */\n const fieldIsEmpty = otpValues.every((num) => num === \"\");\n const autofillOtp = stripOtpFromAutofill(\n eventValue,\n numOfInput,\n prefix\n );\n if (fieldIsEmpty && handleInputFullValue(autofillOtp)) {\n return;\n }\n\n /* handle normal input */\n const value = eventValue.replace(/[^0-9]/g, \"\");\n if (validateUserInput(value)) {\n const newOtpValues = [...otpValues];\n\n newOtpValues[index] = value.substring(value.length - 1);\n inputRefs.current[index + 1]?.focus();\n\n setOtpValues(newOtpValues);\n\n if (onChange) {\n onChange(newOtpValues);\n }\n }\n };\n\n const handleKeyDown =\n (index: number) => (event: React.KeyboardEvent<HTMLInputElement>) => {\n const { key, code } = event;\n\n if (key === \"Backspace\" || code === \"Backspace\") {\n const newOtpValues = [...otpValues];\n if (newOtpValues[index] !== \"\") {\n newOtpValues[index] = \"\";\n } else if (index !== 0) {\n newOtpValues[index - 1] = \"\";\n inputRefs.current[index - 1]?.focus();\n }\n\n setOtpValues(newOtpValues);\n\n if (onChange) {\n onChange(newOtpValues);\n }\n } else if (event.code === \"ArrowRight\") {\n inputRefs.current[index + 1]?.focus();\n } else if (event.code === \"ArrowLeft\") {\n inputRefs.current[index - 1]?.focus();\n }\n };\n\n const handlePaste = (event: ClipboardEvent): void => {\n if (!event.clipboardData) return;\n\n const pastedValue = event.clipboardData.getData(\"text\");\n const autofillOtp = stripOtpFromAutofill(\n pastedValue,\n numOfInput,\n prefix\n );\n if (!handleInputFullValue(autofillOtp)) {\n event.preventDefault();\n }\n };\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n setOtpValues(new Array(numOfInput).fill(\"\"));\n\n if (!isWithinCooldown()) {\n setLastCtaTimestamp(new Date());\n setCountDown(cooldownDuration);\n }\n\n if (onClick) {\n onClick(event);\n }\n };\n\n // =========================================================================\n // HELPER FUNCTIONS\n // =========================================================================\n const isWithinCooldown = (): boolean => {\n const currentTime = Date.now();\n const coolDownInMilliseconds = cooldownDuration * 1000;\n\n return (\n currentTime < lastCtaTimestamp.valueOf() + coolDownInMilliseconds\n );\n };\n\n const beginCountdown = () => {\n const interval = setInterval(() => {\n const currentTime = Date.now();\n const coolDownInMilliseconds = cooldownDuration * 1000;\n\n const timer = Math.ceil(\n (lastCtaTimestamp.valueOf() +\n coolDownInMilliseconds -\n currentTime) /\n 1000\n );\n setCountDown(timer);\n if (timer <= 0) {\n if (onCooldownEnd) onCooldownEnd();\n clearInterval(interval);\n } else if (onCountdownChange) {\n onCountdownChange(timer);\n }\n }, 1000);\n\n return () => {\n clearInterval(interval);\n };\n };\n\n const generateId = (index: number, name: string, prefix?: string) => {\n return prefix\n ? `${prefix}-${name}-${index + 1}`\n : `${name}-${index + 1}`;\n };\n\n const displaySeconds = (time: number) => {\n return `${time} second${time === 1 ? \"\" : \"s\"}`;\n };\n\n const getCTALabelProps = (): Partial<\n React.HTMLAttributes<HTMLButtonElement>\n > => {\n return otherCtaProps.children\n ? { children: otherCtaProps.children }\n : {\n children:\n countDown > 0\n ? `Resend OTP in ${displaySeconds(countDown)}`\n : \"Resend OTP\",\n // use a fixed label to avoid repeated screen reader updates when the button is focused\n \"aria-label\":\n countDown > 0\n ? `Resend OTP in ${displaySeconds(cooldownDuration)}`\n : \"Resend OTP\",\n // use a secondary element to reflect the latest countdown\n \"aria-describedby\": timerId,\n };\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n return (\n <div\n id={id}\n data-testid={dataTestId}\n className={clsx(styles.wrapper, className)}\n >\n <div\n className={styles.inputContainer}\n role=\"group\"\n aria-label={`${numOfInput}-digit OTP input field`}\n >\n {prefix && (\n <Typography.BodyBL\n as=\"span\"\n className={styles.prefix}\n data-testid=\"otp-prefix\"\n weight=\"semibold\"\n >\n <VisuallyHidden>O T P prefix</VisuallyHidden>\n {`${prefix.value} ${prefix.separator}`}\n </Typography.BodyBL>\n )}\n {otpValues.map((data, index) => {\n return (\n <Input\n className={styles.inputField}\n id={generateId(index, \"otp-input\", id)}\n data-testid={generateId(\n index,\n \"otp-input\",\n dataTestId\n )}\n aria-label={`${StringHelper.formatOrdinal(\n index + 1\n )} digit`}\n aria-invalid={hasError}\n aria-describedby={hasError ? errorId : undefined}\n key={index}\n ref={(el) => (inputRefs.current[index] = el)}\n type=\"text\"\n inputMode=\"numeric\"\n value={data}\n error={hasError}\n onChange={handleChange(index)}\n onKeyDown={handleKeyDown(index)}\n autoComplete=\"off\"\n {...otherProps}\n />\n );\n })}\n </div>\n {errorMessage && (\n <FormErrorMessage id={errorId} data-testid=\"otp-error-message\">\n {errorMessage}\n </FormErrorMessage>\n )}\n {/* visually hidden elements need to be rendered before the button so that Voiceover/Chrome doesn't skip the button */}\n <VisuallyHidden role=\"timer\" id={timerId}>\n {displaySeconds(countDown)} remaining\n </VisuallyHidden>\n <VisuallyHidden aria-live=\"polite\">\n {countDown > 0 ? \"\" : \"Ready to resend OTP\"}\n </VisuallyHidden>\n {!otpOnly && (\n <Button\n className={styles.ctaButton}\n styleType={styleType}\n type=\"button\"\n sizeType=\"small\"\n {...otherCtaProps}\n onClick={handleClick}\n disabled={disabled || isWithinCooldown()}\n {...getCTALabelProps()}\n />\n )}\n </div>\n );\n};\n\n// @catalog\n/**\n * A field composed of individual inputs for a numeric one-time password\n * with an in-built countdown mechanism.\n *\n * Use `OtpInput` when users must enter the one-time password (OTP)\n * for multi-factored authentication methods.\n */\nexport const OtpInput = forwardRef(Component);\n"],"names":["OtpInput","forwardRef","_a","ref","id","value","dataTestId","className","cooldownDuration","actionButtonProps","errorMessage","numOfInput","prefix","onChange","onCooldownStart","onCooldownEnd","otpOnly","onCountdownChange","otherProps","__rest","_b","disabled","onClick","styleType","otherCtaProps","inputRefs","useRef","onChangeRef","otpValues","setOtpValues","useState","Array","fill","countDown","setCountDown","lastCtaTimestamp","setLastCtaTimestamp","Date","internalId","useId","hasError","errorId","timerId","useEffect","current","focus","document","addEventListener","handlePaste","removeEventListener","cleanup","beginCountdown","useImperativeHandle","startCooldown","length","handleInputFullValue","incomingValue","validateUserInput","incomingValueArr","split","handleChange","index","event","eventValue","target","fieldIsEmpty","every","num","autofillOtp","stripOtpFromAutofill","replace","newOtpValues","substring","handleKeyDown","key","code","_c","clipboardData","pastedValue","getData","preventDefault","isWithinCooldown","currentTime","now","coolDownInMilliseconds","valueOf","interval","setInterval","timer","Math","ceil","clearInterval","generateId","name","displaySeconds","time","_jsxs","clsx","styles.wrapper","children","styles.inputContainer","role","Typography","BodyBL","as","styles.prefix","weight","_jsx","VisuallyHidden","separator","map","data","Input","Object","assign","styles.inputField","StringHelper","formatOrdinal","undefined","el","type","inputMode","error","onKeyDown","autoComplete","FormErrorMessage","Button","styles.ctaButton","sizeType"],"mappings":"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"}
@@ -1,4 +1,16 @@
1
1
  import type { ButtonProps } from "../button";
2
+ /**
3
+ * Props for the prefix label rendered before the OTP input cells.
4
+ */
5
+ type OtpInputPrefix = {
6
+ /** Prefix text, usually a few alphabetic characters. */
7
+ value: string;
8
+ /**
9
+ * Separator between the prefix and the OTP input.
10
+ * Only `"-"` is supported.
11
+ */
12
+ separator: "-";
13
+ };
2
14
  /**
3
15
  * Props for the `OtpInput` component.
4
16
  */
@@ -39,15 +51,7 @@ export interface OtpInputProps extends React.AriaAttributes {
39
51
  /**
40
52
  * Optional prefix label rendered before the input cells.
41
53
  */
42
- prefix?: {
43
- /** Prefix text, usually a few alphabetic characters. */
44
- value: string;
45
- /**
46
- * Separator between the prefix and the OTP input.
47
- * Only `"-"` is supported.
48
- */
49
- separator: "-";
50
- } | undefined;
54
+ prefix?: OtpInputPrefix | undefined;
51
55
  /**
52
56
  * Called when any input cell changes.
53
57
  *
@@ -75,3 +79,4 @@ export type OtpInputRef = {
75
79
  */
76
80
  startCooldown: () => void;
77
81
  };
82
+ export {};
@@ -1,2 +1,2 @@
1
- import{jsxs as e,jsx as i}from"react/jsx-runtime";import{TickCircleFillIcon as a}from"@lifesg/react-icons";import r from"clsx";import{Button as t}from"../button/button.js";import{FormErrorMessage as n}from"../form/form-label.js";import{InputGroup as d}from"../input-group/input-group.js";import{PhoneNumberInput as o}from"../phone-number-input/phone-number-input.js";import{concatIds as l}from"../shared/accessibility/index.js";import{contactSectionWrapper as s,contactInputSectionWrapper as m,verifiedIconWrapper as c,contactInputWrapper as u,contactInputWrapperError as b,contactInputWrapperDisabled as p,contactInputWrapperReadonly as v,contactButton as h,emailContactInput as f,emailContactInputDisabled as y,emailContactInputReadonly as g,phoneContactInput as O,phoneContactInputDisabled as N,phoneContactInputReadonly as j}from"./contact-input-section.styles.js";const x=({id:x,"data-testid":C,disabled:E,readOnly:P,inputId:$,type:V,sendOtpPlaceholder:S,emailValue:T,onEmailChange:R,phoneNumberValue:q,onPhoneNumberChange:w,fixedCountry:B,isLoading:L,isVerified:k,countdown:A,onSendOtp:I,onStateReset:z,sendOtpError:D,"aria-labelledby":F,"aria-describedby":G})=>{const H=x?`${x}-contact-error`:void 0,J=e=>{z(),"email"===V&&R&&R(e.target.value)},K=e=>{z(),"phone-number"===V&&w&&w(e)},M=e=>{var i;return`Enter your ${null!==(i=null==e?void 0:e.name)&&void 0!==i?i:""} mobile number to receive a verification OTP`.replace(/\s+/g," ")};return e("div",{id:x,"data-testid":C,className:s,children:[e("div",{className:m,children:[e("div",{"data-max-width":"email"===V,className:r(u,!!D&&b,E&&p,P&&v),children:["email"===V?i(d,{id:$,"data-testid":C?`${C}-contact-input`:void 0,placeholder:S||"Enter email",value:T,onChange:J,type:"email",noBorder:!0,"aria-invalid":!!D,"aria-required":!0,"aria-label":"Enter your email address to receive a verification OTP","aria-labelledby":F,"aria-describedby":l(D?H:void 0,G),disabled:E,readOnly:P,className:r(f,E&&y,P&&g)}):i(o,{id:$,"data-testid":C?`${C}-contact-input`:void 0,placeholder:S||"Enter mobile number",value:q,onChange:K,noBorder:!0,fixedCountry:B,"aria-invalid":!!D,"aria-required":!0,getAriaLabel:M,"aria-labelledby":F,"aria-describedby":l(D?H:void 0,G),disabled:E,readOnly:P,className:r(O,E&&N,P&&j)}),k&&i("div",{className:c,"aria-label":"Verified",role:"img",children:i(a,{})})]}),!E&&!P&&i(t,{type:"button","data-testid":C?`${C}-contact-button`:void 0,onClick:I,disabled:A.isRunning||k,loading:L,className:h,children:k?"Verified":L?"":A.isRunning?"Sent OTP":"Send OTP"})]}),D&&i(n,{id:H,"data-testid":C?`${C}-contact-error`:void 0,role:"alert",children:D})]})};export{x as ContactInputSection};
1
+ import{jsxs as e,jsx as i}from"react/jsx-runtime";import{TickCircleFillIcon as a}from"@lifesg/react-icons";import r from"clsx";import{Button as t}from"../button/button.js";import{FormErrorMessage as n}from"../form/form-label/form-label.js";import{InputGroup as o}from"../input-group/input-group.js";import{PhoneNumberInput as d}from"../phone-number-input/phone-number-input.js";import{concatIds as l}from"../shared/accessibility/index.js";import{contactSectionWrapper as s,contactInputSectionWrapper as m,verifiedIconWrapper as c,contactInputWrapper as u,contactInputWrapperError as b,contactInputWrapperDisabled as p,contactInputWrapperReadonly as v,contactButton as f,emailContactInput as h,emailContactInputDisabled as y,emailContactInputReadonly as g,phoneContactInput as O,phoneContactInputDisabled as N,phoneContactInputReadonly as j}from"./contact-input-section.styles.js";const x=({id:x,"data-testid":C,disabled:E,readOnly:P,inputId:$,type:V,sendOtpPlaceholder:S,emailValue:T,onEmailChange:R,phoneNumberValue:q,onPhoneNumberChange:w,fixedCountry:B,isLoading:L,isVerified:k,countdown:A,onSendOtp:I,onStateReset:z,sendOtpError:D,"aria-labelledby":F,"aria-describedby":G})=>{const H=x?`${x}-contact-error`:void 0,J=e=>{z(),"email"===V&&R&&R(e.target.value)},K=e=>{z(),"phone-number"===V&&w&&w(e)},M=e=>{var i;return`Enter your ${null!==(i=null==e?void 0:e.name)&&void 0!==i?i:""} mobile number to receive a verification OTP`.replace(/\s+/g," ")};return e("div",{id:x,"data-testid":C,className:s,children:[e("div",{className:m,children:[e("div",{"data-max-width":"email"===V,className:r(u,!!D&&b,E&&p,P&&v),children:["email"===V?i(o,{id:$,"data-testid":C?`${C}-contact-input`:void 0,placeholder:S||"Enter email",value:T,onChange:J,type:"email",noBorder:!0,"aria-invalid":!!D,"aria-required":!0,"aria-label":"Enter your email address to receive a verification OTP","aria-labelledby":F,"aria-describedby":l(D?H:void 0,G),disabled:E,readOnly:P,className:r(h,E&&y,P&&g)}):i(d,{id:$,"data-testid":C?`${C}-contact-input`:void 0,placeholder:S||"Enter mobile number",value:q,onChange:K,noBorder:!0,fixedCountry:B,"aria-invalid":!!D,"aria-required":!0,getAriaLabel:M,"aria-labelledby":F,"aria-describedby":l(D?H:void 0,G),disabled:E,readOnly:P,className:r(O,E&&N,P&&j)}),k&&i("div",{className:c,"aria-label":"Verified",role:"img",children:i(a,{})})]}),!E&&!P&&i(t,{type:"button","data-testid":C?`${C}-contact-button`:void 0,onClick:I,disabled:A.isRunning||k,loading:L,className:f,children:k?"Verified":L?"":A.isRunning?"Sent OTP":"Send OTP"})]}),D&&i(n,{id:H,"data-testid":C?`${C}-contact-error`:void 0,role:"alert",children:D})]})};export{x as ContactInputSection};
2
2
  //# sourceMappingURL=contact-input-section.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"contact-input-section.js","sources":["../../src/otp-verification/contact-input-section.tsx"],"sourcesContent":["import { TickCircleFillIcon } from \"@lifesg/react-icons\";\nimport clsx from \"clsx\";\n\nimport { Button } from \"../button\";\nimport { FormErrorMessage } from \"../form/form-label\";\nimport { InputGroup } from \"../input-group\";\nimport type {\n CountryValue,\n PhoneNumberInputValue,\n} from \"../phone-number-input\";\nimport { PhoneNumberInput } from \"../phone-number-input\";\nimport { concatIds } from \"../shared/accessibility\";\nimport * as styles from \"./contact-input-section.styles\";\nimport type { ContactInputSectionProps } from \"./internal-types\";\n\nexport const ContactInputSection = ({\n id,\n \"data-testid\": dataTestId,\n disabled,\n readOnly,\n inputId,\n type,\n sendOtpPlaceholder,\n emailValue,\n onEmailChange,\n phoneNumberValue,\n onPhoneNumberChange,\n fixedCountry,\n isLoading,\n isVerified,\n countdown,\n onSendOtp,\n onStateReset,\n sendOtpError,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n}: ContactInputSectionProps) => {\n const contactErrorId = id ? `${id}-contact-error` : undefined;\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleEmailInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onStateReset();\n if (type === \"email\" && onEmailChange) {\n onEmailChange(e.target.value);\n }\n };\n\n const handlePhoneInputChange = (value: PhoneNumberInputValue) => {\n onStateReset();\n if (type === \"phone-number\" && onPhoneNumberChange) {\n onPhoneNumberChange(value);\n }\n };\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n const getContactButtonText = () => {\n if (isVerified) {\n return \"Verified\";\n }\n\n if (isLoading) {\n return \"\";\n }\n\n if (countdown.isRunning) {\n return \"Sent OTP\";\n }\n\n return \"Send OTP\";\n };\n\n const getMobileAriaLabel = (country?: CountryValue) =>\n `Enter your ${\n country?.name ?? \"\"\n } mobile number to receive a verification OTP`.replace(/\\s+/g, \" \");\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderContactInput = () =>\n type === \"email\" ? (\n <InputGroup\n id={inputId}\n data-testid={\n dataTestId ? `${dataTestId}-contact-input` : undefined\n }\n placeholder={sendOtpPlaceholder || \"Enter email\"}\n value={emailValue}\n onChange={handleEmailInputChange}\n type=\"email\"\n noBorder\n aria-invalid={!!sendOtpError}\n aria-required={true}\n aria-label=\"Enter your email address to receive a verification OTP\"\n aria-labelledby={ariaLabelledBy}\n aria-describedby={concatIds(\n sendOtpError ? contactErrorId : undefined,\n ariaDescribedBy\n )}\n disabled={disabled}\n readOnly={readOnly}\n className={clsx(\n styles.emailContactInput,\n disabled && styles.emailContactInputDisabled,\n readOnly && styles.emailContactInputReadonly\n )}\n />\n ) : (\n <PhoneNumberInput\n id={inputId}\n data-testid={\n dataTestId ? `${dataTestId}-contact-input` : undefined\n }\n placeholder={sendOtpPlaceholder || \"Enter mobile number\"}\n value={phoneNumberValue}\n onChange={handlePhoneInputChange}\n noBorder\n fixedCountry={fixedCountry}\n aria-invalid={!!sendOtpError}\n aria-required={true}\n getAriaLabel={getMobileAriaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={concatIds(\n sendOtpError ? contactErrorId : undefined,\n ariaDescribedBy\n )}\n disabled={disabled}\n readOnly={readOnly}\n className={clsx(\n styles.phoneContactInput,\n disabled && styles.phoneContactInputDisabled,\n readOnly && styles.phoneContactInputReadonly\n )}\n />\n );\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n return (\n <div\n id={id}\n data-testid={dataTestId}\n className={styles.contactSectionWrapper}\n >\n <div className={styles.contactInputSectionWrapper}>\n <div\n data-max-width={type === \"email\"}\n className={clsx(\n styles.contactInputWrapper,\n !!sendOtpError && styles.contactInputWrapperError,\n disabled && styles.contactInputWrapperDisabled,\n readOnly && styles.contactInputWrapperReadonly\n )}\n >\n {renderContactInput()}\n {isVerified && (\n <div\n className={styles.verifiedIconWrapper}\n aria-label=\"Verified\"\n role=\"img\"\n >\n <TickCircleFillIcon />\n </div>\n )}\n </div>\n {!disabled && !readOnly && (\n <Button\n type=\"button\"\n data-testid={\n dataTestId\n ? `${dataTestId}-contact-button`\n : undefined\n }\n onClick={onSendOtp}\n disabled={countdown.isRunning || isVerified}\n loading={isLoading}\n className={styles.contactButton}\n >\n {getContactButtonText()}\n </Button>\n )}\n </div>\n {sendOtpError && (\n <FormErrorMessage\n id={contactErrorId}\n data-testid={\n dataTestId ? `${dataTestId}-contact-error` : undefined\n }\n role=\"alert\"\n >\n {sendOtpError}\n </FormErrorMessage>\n )}\n </div>\n );\n};\n"],"names":["ContactInputSection","id","dataTestId","disabled","readOnly","inputId","type","sendOtpPlaceholder","emailValue","onEmailChange","phoneNumberValue","onPhoneNumberChange","fixedCountry","isLoading","isVerified","countdown","onSendOtp","onStateReset","sendOtpError","ariaLabelledBy","ariaDescribedBy","contactErrorId","undefined","handleEmailInputChange","e","target","value","handlePhoneInputChange","getMobileAriaLabel","country","_a","name","replace","_jsxs","className","styles.contactSectionWrapper","styles.contactInputSectionWrapper","children","clsx","styles.contactInputWrapper","styles.contactInputWrapperError","styles.contactInputWrapperDisabled","styles.contactInputWrapperReadonly","_jsx","InputGroup","placeholder","onChange","noBorder","concatIds","styles.emailContactInput","styles.emailContactInputDisabled","styles.emailContactInputReadonly","PhoneNumberInput","getAriaLabel","styles.phoneContactInput","styles.phoneContactInputDisabled","styles.phoneContactInputReadonly","styles.verifiedIconWrapper","role","TickCircleFillIcon","Button","onClick","isRunning","loading","styles.contactButton","FormErrorMessage"],"mappings":"q2BAeO,MAAMA,EAAsB,EAC/BC,KACA,cAAeC,EACfC,WACAC,WACAC,UACAC,OACAC,qBACAC,aACAC,gBACAC,mBACAC,sBACAC,eACAC,YACAC,aACAC,YACAC,YACAC,eACAC,eACA,kBAAmBC,EACnB,mBAAoBC,MAEpB,MAAMC,EAAiBpB,EAAK,GAAGA,uBAAqBqB,EAK9CC,EAA0BC,IAC5BP,IACa,UAATX,GAAoBG,GACpBA,EAAce,EAAEC,OAAOC,MAC3B,EAGEC,EAA0BD,IAC5BT,IACa,iBAATX,GAA2BK,GAC3BA,EAAoBe,EACxB,EAsBEE,EAAsBC,UACxB,MAAA,sBACIC,EAAAD,aAAO,EAAPA,EAASE,oBAAQ,iDAC0BC,QAAQ,OAAQ,IAAI,EAiEvE,OACIC,SACIhC,GAAIA,EAAE,cACOC,EACbgC,UAAWC,YAEXF,EAAA,MAAA,CAAKC,UAAWE,EAAiCC,SAAA,CAC7CJ,EAAA,MAAA,CAAA,iBAC6B,UAAT3B,EAChB4B,UAAWI,EACPC,IACErB,GAAgBsB,EAClBrC,GAAYsC,EACZrC,GAAYsC,GACfL,SAAA,CAzEJ,UAAT/B,EACIqC,EAACC,GACG3C,GAAII,EAAO,cAEPH,EAAa,GAAGA,uBAA6BoB,EAEjDuB,YAAatC,GAAsB,cACnCmB,MAAOlB,EACPsC,SAAUvB,EACVjB,KAAK,QACLyC,6BACgB7B,EAAY,iBACb,eACJ,yDAAwD,kBAClDC,EAAc,mBACb6B,EACd9B,EAAeG,OAAiBC,EAChCF,GAEJjB,SAAUA,EACVC,SAAUA,EACV8B,UAAWI,EACPW,EACA9C,GAAY+C,EACZ9C,GAAY+C,KAIpBR,EAACS,EAAgB,CACbnD,GAAII,gBAEAH,EAAa,GAAGA,uBAA6BoB,EAEjDuB,YAAatC,GAAsB,sBACnCmB,MAAOhB,EACPoC,SAAUnB,EACVoB,UAAQ,EACRnC,aAAcA,mBACEM,EAAY,iBACb,EACfmC,aAAczB,oBACGT,EAAc,mBACb6B,EACd9B,EAAeG,OAAiBC,EAChCF,GAEJjB,SAAUA,EACVC,SAAUA,EACV8B,UAAWI,EACPgB,EACAnD,GAAYoD,EACZnD,GAAYoD,KAyBX1C,GACG6B,EAAA,MAAA,CACIT,UAAWuB,EAA0B,aAC1B,WACXC,KAAK,MAAKrB,SAEVM,EAACgB,EAAkB,CAAA,SAI7BxD,IAAaC,GACXuC,EAACiB,GACGtD,KAAK,SAAQ,cAETJ,EACM,GAAGA,wBACHoB,EAEVuC,QAAS7C,EACTb,SAAUY,EAAU+C,WAAahD,EACjCiD,QAASlD,EACTqB,UAAW8B,EAAoB3B,SAzH3CvB,EACO,WAGPD,EACO,GAGPE,EAAU+C,UACH,WAGJ,gBAmHF5C,GACGyB,EAACsB,EAAgB,CACbhE,GAAIoB,EAAc,cAEdnB,EAAa,GAAGA,uBAA6BoB,EAEjDoC,KAAK,QAAOrB,SAEXnB,MAGP"}
1
+ {"version":3,"file":"contact-input-section.js","sources":["../../src/otp-verification/contact-input-section.tsx"],"sourcesContent":["import { TickCircleFillIcon } from \"@lifesg/react-icons\";\nimport clsx from \"clsx\";\n\nimport { Button } from \"../button\";\nimport { FormErrorMessage } from \"../form/form-label\";\nimport { InputGroup } from \"../input-group\";\nimport type {\n CountryValue,\n PhoneNumberInputValue,\n} from \"../phone-number-input\";\nimport { PhoneNumberInput } from \"../phone-number-input\";\nimport { concatIds } from \"../shared/accessibility\";\nimport * as styles from \"./contact-input-section.styles\";\nimport type { ContactInputSectionProps } from \"./internal-types\";\n\nexport const ContactInputSection = ({\n id,\n \"data-testid\": dataTestId,\n disabled,\n readOnly,\n inputId,\n type,\n sendOtpPlaceholder,\n emailValue,\n onEmailChange,\n phoneNumberValue,\n onPhoneNumberChange,\n fixedCountry,\n isLoading,\n isVerified,\n countdown,\n onSendOtp,\n onStateReset,\n sendOtpError,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": ariaDescribedBy,\n}: ContactInputSectionProps) => {\n const contactErrorId = id ? `${id}-contact-error` : undefined;\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleEmailInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onStateReset();\n if (type === \"email\" && onEmailChange) {\n onEmailChange(e.target.value);\n }\n };\n\n const handlePhoneInputChange = (value: PhoneNumberInputValue) => {\n onStateReset();\n if (type === \"phone-number\" && onPhoneNumberChange) {\n onPhoneNumberChange(value);\n }\n };\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n const getContactButtonText = () => {\n if (isVerified) {\n return \"Verified\";\n }\n\n if (isLoading) {\n return \"\";\n }\n\n if (countdown.isRunning) {\n return \"Sent OTP\";\n }\n\n return \"Send OTP\";\n };\n\n const getMobileAriaLabel = (country?: CountryValue) =>\n `Enter your ${\n country?.name ?? \"\"\n } mobile number to receive a verification OTP`.replace(/\\s+/g, \" \");\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderContactInput = () =>\n type === \"email\" ? (\n <InputGroup\n id={inputId}\n data-testid={\n dataTestId ? `${dataTestId}-contact-input` : undefined\n }\n placeholder={sendOtpPlaceholder || \"Enter email\"}\n value={emailValue}\n onChange={handleEmailInputChange}\n type=\"email\"\n noBorder\n aria-invalid={!!sendOtpError}\n aria-required={true}\n aria-label=\"Enter your email address to receive a verification OTP\"\n aria-labelledby={ariaLabelledBy}\n aria-describedby={concatIds(\n sendOtpError ? contactErrorId : undefined,\n ariaDescribedBy\n )}\n disabled={disabled}\n readOnly={readOnly}\n className={clsx(\n styles.emailContactInput,\n disabled && styles.emailContactInputDisabled,\n readOnly && styles.emailContactInputReadonly\n )}\n />\n ) : (\n <PhoneNumberInput\n id={inputId}\n data-testid={\n dataTestId ? `${dataTestId}-contact-input` : undefined\n }\n placeholder={sendOtpPlaceholder || \"Enter mobile number\"}\n value={phoneNumberValue}\n onChange={handlePhoneInputChange}\n noBorder\n fixedCountry={fixedCountry}\n aria-invalid={!!sendOtpError}\n aria-required={true}\n getAriaLabel={getMobileAriaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={concatIds(\n sendOtpError ? contactErrorId : undefined,\n ariaDescribedBy\n )}\n disabled={disabled}\n readOnly={readOnly}\n className={clsx(\n styles.phoneContactInput,\n disabled && styles.phoneContactInputDisabled,\n readOnly && styles.phoneContactInputReadonly\n )}\n />\n );\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n return (\n <div\n id={id}\n data-testid={dataTestId}\n className={styles.contactSectionWrapper}\n >\n <div className={styles.contactInputSectionWrapper}>\n <div\n data-max-width={type === \"email\"}\n className={clsx(\n styles.contactInputWrapper,\n !!sendOtpError && styles.contactInputWrapperError,\n disabled && styles.contactInputWrapperDisabled,\n readOnly && styles.contactInputWrapperReadonly\n )}\n >\n {renderContactInput()}\n {isVerified && (\n <div\n className={styles.verifiedIconWrapper}\n aria-label=\"Verified\"\n role=\"img\"\n >\n <TickCircleFillIcon />\n </div>\n )}\n </div>\n {!disabled && !readOnly && (\n <Button\n type=\"button\"\n data-testid={\n dataTestId\n ? `${dataTestId}-contact-button`\n : undefined\n }\n onClick={onSendOtp}\n disabled={countdown.isRunning || isVerified}\n loading={isLoading}\n className={styles.contactButton}\n >\n {getContactButtonText()}\n </Button>\n )}\n </div>\n {sendOtpError && (\n <FormErrorMessage\n id={contactErrorId}\n data-testid={\n dataTestId ? `${dataTestId}-contact-error` : undefined\n }\n role=\"alert\"\n >\n {sendOtpError}\n </FormErrorMessage>\n )}\n </div>\n );\n};\n"],"names":["ContactInputSection","id","dataTestId","disabled","readOnly","inputId","type","sendOtpPlaceholder","emailValue","onEmailChange","phoneNumberValue","onPhoneNumberChange","fixedCountry","isLoading","isVerified","countdown","onSendOtp","onStateReset","sendOtpError","ariaLabelledBy","ariaDescribedBy","contactErrorId","undefined","handleEmailInputChange","e","target","value","handlePhoneInputChange","getMobileAriaLabel","country","_a","name","replace","_jsxs","className","styles.contactSectionWrapper","styles.contactInputSectionWrapper","children","clsx","styles.contactInputWrapper","styles.contactInputWrapperError","styles.contactInputWrapperDisabled","styles.contactInputWrapperReadonly","_jsx","InputGroup","placeholder","onChange","noBorder","concatIds","styles.emailContactInput","styles.emailContactInputDisabled","styles.emailContactInputReadonly","PhoneNumberInput","getAriaLabel","styles.phoneContactInput","styles.phoneContactInputDisabled","styles.phoneContactInputReadonly","styles.verifiedIconWrapper","role","TickCircleFillIcon","Button","onClick","isRunning","loading","styles.contactButton","FormErrorMessage"],"mappings":"g3BAeO,MAAMA,EAAsB,EAC/BC,KACA,cAAeC,EACfC,WACAC,WACAC,UACAC,OACAC,qBACAC,aACAC,gBACAC,mBACAC,sBACAC,eACAC,YACAC,aACAC,YACAC,YACAC,eACAC,eACA,kBAAmBC,EACnB,mBAAoBC,MAEpB,MAAMC,EAAiBpB,EAAK,GAAGA,uBAAqBqB,EAK9CC,EAA0BC,IAC5BP,IACa,UAATX,GAAoBG,GACpBA,EAAce,EAAEC,OAAOC,MAC3B,EAGEC,EAA0BD,IAC5BT,IACa,iBAATX,GAA2BK,GAC3BA,EAAoBe,EACxB,EAsBEE,EAAsBC,UACxB,MAAA,sBACIC,EAAAD,aAAO,EAAPA,EAASE,oBAAQ,iDAC0BC,QAAQ,OAAQ,IAAI,EAiEvE,OACIC,SACIhC,GAAIA,EAAE,cACOC,EACbgC,UAAWC,YAEXF,EAAA,MAAA,CAAKC,UAAWE,EAAiCC,SAAA,CAC7CJ,EAAA,MAAA,CAAA,iBAC6B,UAAT3B,EAChB4B,UAAWI,EACPC,IACErB,GAAgBsB,EAClBrC,GAAYsC,EACZrC,GAAYsC,GACfL,SAAA,CAzEJ,UAAT/B,EACIqC,EAACC,GACG3C,GAAII,EAAO,cAEPH,EAAa,GAAGA,uBAA6BoB,EAEjDuB,YAAatC,GAAsB,cACnCmB,MAAOlB,EACPsC,SAAUvB,EACVjB,KAAK,QACLyC,6BACgB7B,EAAY,iBACb,eACJ,yDAAwD,kBAClDC,EAAc,mBACb6B,EACd9B,EAAeG,OAAiBC,EAChCF,GAEJjB,SAAUA,EACVC,SAAUA,EACV8B,UAAWI,EACPW,EACA9C,GAAY+C,EACZ9C,GAAY+C,KAIpBR,EAACS,EAAgB,CACbnD,GAAII,gBAEAH,EAAa,GAAGA,uBAA6BoB,EAEjDuB,YAAatC,GAAsB,sBACnCmB,MAAOhB,EACPoC,SAAUnB,EACVoB,UAAQ,EACRnC,aAAcA,mBACEM,EAAY,iBACb,EACfmC,aAAczB,oBACGT,EAAc,mBACb6B,EACd9B,EAAeG,OAAiBC,EAChCF,GAEJjB,SAAUA,EACVC,SAAUA,EACV8B,UAAWI,EACPgB,EACAnD,GAAYoD,EACZnD,GAAYoD,KAyBX1C,GACG6B,EAAA,MAAA,CACIT,UAAWuB,EAA0B,aAC1B,WACXC,KAAK,MAAKrB,SAEVM,EAACgB,EAAkB,CAAA,SAI7BxD,IAAaC,GACXuC,EAACiB,GACGtD,KAAK,SAAQ,cAETJ,EACM,GAAGA,wBACHoB,EAEVuC,QAAS7C,EACTb,SAAUY,EAAU+C,WAAahD,EACjCiD,QAASlD,EACTqB,UAAW8B,EAAoB3B,SAzH3CvB,EACO,WAGPD,EACO,GAGPE,EAAU+C,UACH,WAGJ,gBAmHF5C,GACGyB,EAACsB,EAAgB,CACbhE,GAAIoB,EAAc,cAEdnB,EAAa,GAAGA,uBAA6BoB,EAEjDoC,KAAK,QAAOrB,SAEXnB,MAGP"}
@@ -1 +1 @@
1
- {"version":3,"file":"otp-verification.js","sources":["../../src/otp-verification/otp-verification.tsx"],"sourcesContent":["import { announce, clearAnnouncer } from \"@react-aria/live-announcer\";\nimport clsx from \"clsx\";\nimport { useState } from \"react\";\n\nimport { useCountdown } from \"../util\";\nimport { ContactInputSection } from \"./contact-input-section\";\nimport * as styles from \"./otp-verification.styles\";\nimport type { OtpVerificationProps } from \"./types\";\nimport { VerificationSection } from \"./verification-section\";\n\n/**\n * A multi-step form component that guides users through OTP-based verification.\n *\n * Use `OtpVerification` when you need to verify a user's identity through\n * email address or phone number.\n */\nexport const OtpVerification = (props: OtpVerificationProps) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const {\n id,\n \"data-testid\": dataTestId,\n className,\n inputId,\n onSendOtp,\n onVerifyOtp,\n verifyOtpCountdownTimer = 60,\n sendOtpError,\n verifyOtpError,\n otpValue,\n onOtpChange,\n otpState,\n onOtpStateChange,\n otpReminderInterval = 120,\n } = props;\n\n const [isLoading, setIsLoading] = useState(false);\n const [isVerifyLoading, setIsVerifyLoading] = useState(false);\n\n const countdown = useCountdown({\n duration: verifyOtpCountdownTimer,\n reminderInterval: otpReminderInterval,\n getStartMessage: (duration) =>\n `You can resend the OTP in ${duration} seconds`,\n getIntervalMessage: (remaining) => `${remaining} seconds remaining`,\n getCompletionMessage: () => \"You can now resend the OTP\",\n });\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n // Send OTP\n const handleSendOtp = async () => {\n if (!onSendOtp || isLoading) return;\n\n try {\n setIsLoading(true);\n await onSendOtp();\n onOtpStateChange(\"sent\");\n countdown.reset();\n countdown.start();\n } catch {\n // do nothing\n } finally {\n setIsLoading(false);\n }\n };\n\n // Verify OTP\n const handleVerifyOtp = async () => {\n if (!onVerifyOtp || isVerifyLoading || !otpValue?.value) return;\n\n try {\n setIsVerifyLoading(true);\n await onVerifyOtp(otpValue.value);\n\n onOtpStateChange(\"verified\");\n\n clearAnnouncer(\"polite\");\n announce(\n \"Success. Your email or mobile number has been verified.\",\n \"polite\"\n );\n\n // Reset the countdown and clear the OTP code in case user enter new OTP later\n countdown.reset();\n onOtpChange?.(\"\");\n } catch {\n // do nothing\n } finally {\n setIsVerifyLoading(false);\n }\n };\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n const resetToDefault = () => {\n if (otpState === \"verified\") {\n onOtpStateChange(\"default\");\n }\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n return (\n <div\n id={id}\n data-testid={dataTestId}\n className={clsx(styles.otpInputWrapper, className)}\n >\n <ContactInputSection\n {...props}\n inputId={inputId}\n data-testid={dataTestId ? `${dataTestId}-contact` : undefined}\n isLoading={isLoading}\n isVerified={otpState === \"verified\"}\n countdown={countdown}\n onSendOtp={handleSendOtp}\n onStateReset={resetToDefault}\n sendOtpError={sendOtpError}\n fixedCountry={\n props.type === \"phone-number\" ? props.fixedCountry : true\n }\n />\n\n {otpState === \"sent\" && (\n <VerificationSection\n {...props}\n data-testid={\n dataTestId ? `${dataTestId}-verification` : undefined\n }\n otpCode={otpValue?.value}\n otpPrefix={otpValue?.prefix}\n otpSeparator={otpValue?.separator}\n setOtpCode={onOtpChange}\n isVerifyLoading={isVerifyLoading}\n countdown={countdown}\n onVerifyOtp={handleVerifyOtp}\n verifyOtpError={verifyOtpError}\n />\n )}\n </div>\n );\n};\n"],"names":["OtpVerification","props","id","dataTestId","className","inputId","onSendOtp","onVerifyOtp","verifyOtpCountdownTimer","sendOtpError","verifyOtpError","otpValue","onOtpChange","otpState","onOtpStateChange","otpReminderInterval","isLoading","setIsLoading","useState","isVerifyLoading","setIsVerifyLoading","countdown","useCountdown","duration","reminderInterval","getStartMessage","getIntervalMessage","remaining","getCompletionMessage","_jsxs","clsx","styles.otpInputWrapper","children","_jsx","ContactInputSection","Object","assign","undefined","isVerified","__awaiter","reset","start","_a","onStateReset","fixedCountry","type","VerificationSection","otpCode","value","otpPrefix","prefix","otpSeparator","separator","setOtpCode","clearAnnouncer","announce"],"mappings":"6mBAgBO,MAAMA,EAAmBC,IAI5B,MAAMC,GACFA,EACA,cAAeC,EAAUC,UACzBA,EAASC,QACTA,EAAOC,UACPA,EAASC,YACTA,EAAWC,wBACXA,EAA0B,GAAEC,aAC5BA,EAAYC,eACZA,EAAcC,SACdA,EAAQC,YACRA,EAAWC,SACXA,EAAQC,iBACRA,EAAgBC,oBAChBA,EAAsB,KACtBd,GAEGe,EAAWC,GAAgBC,GAAS,IACpCC,EAAiBC,GAAsBF,GAAS,GAEjDG,EAAYC,EAAa,CAC3BC,SAAUf,EACVgB,iBAAkBT,EAClBU,gBAAkBF,GACd,6BAA6BA,YACjCG,mBAAqBC,GAAc,GAAGA,sBACtCC,qBAAsB,IAAM,+BA6DhC,OACIC,EAAA,MAAA,CACI3B,GAAIA,gBACSC,EACbC,UAAW0B,EAAKC,EAAwB3B,GAAU4B,SAAA,CAElDC,EAACC,EAAmBC,OAAAC,OAAA,CAAA,EACZnC,EAAK,CACTI,QAASA,EAAO,cACHF,EAAa,GAAGA,iBAAuBkC,EACpDrB,UAAWA,EACXsB,WAAyB,aAAbzB,EACZQ,UAAWA,EACXf,UAnEU,IAAWiC,OAAA,OAAA,OAAA,GAAA,YAC7B,GAAKjC,IAAaU,EAElB,IACIC,GAAa,SACPX,IACNQ,EAAiB,QACjBO,EAAUmB,QACVnB,EAAUoB,OACd,CAAE,MAAAC,GAEF,SACIzB,GAAa,EACjB,CACJ,IAsDY0B,aAvBW,KACF,aAAb9B,GACAC,EAAiB,UACrB,EAqBQL,aAAcA,EACdmC,aACmB,iBAAf3C,EAAM4C,MAA0B5C,EAAM2C,gBAIhC,SAAb/B,GACGoB,EAACa,mBACO7C,EAAK,CAAA,cAELE,EAAa,GAAGA,sBAA4BkC,EAEhDU,QAASpC,eAAAA,EAAUqC,MACnBC,UAAWtC,aAAQ,EAARA,EAAUuC,OACrBC,aAAcxC,aAAQ,EAARA,EAAUyC,UACxBC,WAAYzC,EACZO,gBAAiBA,EACjBE,UAAWA,EACXd,YAtEQ,IAAWgC,OAAA,OAAA,OAAA,GAAA,YAC/B,GAAKhC,IAAeY,IAAoBR,aAAQ,EAARA,EAAUqC,OAElD,IACI5B,GAAmB,SACbb,EAAYI,EAASqC,OAE3BlC,EAAiB,YAEjBwC,EAAe,UACfC,EACI,0DACA,UAIJlC,EAAUmB,QACV5B,SAAAA,EAAc,GAClB,CAAE,MAAA8B,GAEF,SACItB,GAAmB,EACvB,CACJ,IAgDgBV,eAAgBA,OAGtB"}
1
+ {"version":3,"file":"otp-verification.js","sources":["../../src/otp-verification/otp-verification.tsx"],"sourcesContent":["import { announce, clearAnnouncer } from \"@react-aria/live-announcer\";\nimport clsx from \"clsx\";\nimport { useState } from \"react\";\n\nimport { useCountdown } from \"../util\";\nimport { ContactInputSection } from \"./contact-input-section\";\nimport * as styles from \"./otp-verification.styles\";\nimport type { OtpVerificationProps } from \"./types\";\nimport { VerificationSection } from \"./verification-section\";\n\n// @catalog\n/**\n * A multi-step form component that guides users through OTP-based verification.\n *\n * Use `OtpVerification` when you need to verify a user's identity through\n * email address or phone number.\n */\nexport const OtpVerification = (props: OtpVerificationProps) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const {\n id,\n \"data-testid\": dataTestId,\n className,\n inputId,\n onSendOtp,\n onVerifyOtp,\n verifyOtpCountdownTimer = 60,\n sendOtpError,\n verifyOtpError,\n otpValue,\n onOtpChange,\n otpState,\n onOtpStateChange,\n otpReminderInterval = 120,\n } = props;\n\n const [isLoading, setIsLoading] = useState(false);\n const [isVerifyLoading, setIsVerifyLoading] = useState(false);\n\n const countdown = useCountdown({\n duration: verifyOtpCountdownTimer,\n reminderInterval: otpReminderInterval,\n getStartMessage: (duration) =>\n `You can resend the OTP in ${duration} seconds`,\n getIntervalMessage: (remaining) => `${remaining} seconds remaining`,\n getCompletionMessage: () => \"You can now resend the OTP\",\n });\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n // Send OTP\n const handleSendOtp = async () => {\n if (!onSendOtp || isLoading) return;\n\n try {\n setIsLoading(true);\n await onSendOtp();\n onOtpStateChange(\"sent\");\n countdown.reset();\n countdown.start();\n } catch {\n // do nothing\n } finally {\n setIsLoading(false);\n }\n };\n\n // Verify OTP\n const handleVerifyOtp = async () => {\n if (!onVerifyOtp || isVerifyLoading || !otpValue?.value) return;\n\n try {\n setIsVerifyLoading(true);\n await onVerifyOtp(otpValue.value);\n\n onOtpStateChange(\"verified\");\n\n clearAnnouncer(\"polite\");\n announce(\n \"Success. Your email or mobile number has been verified.\",\n \"polite\"\n );\n\n // Reset the countdown and clear the OTP code in case user enter new OTP later\n countdown.reset();\n onOtpChange?.(\"\");\n } catch {\n // do nothing\n } finally {\n setIsVerifyLoading(false);\n }\n };\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n const resetToDefault = () => {\n if (otpState === \"verified\") {\n onOtpStateChange(\"default\");\n }\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n return (\n <div\n id={id}\n data-testid={dataTestId}\n className={clsx(styles.otpInputWrapper, className)}\n >\n <ContactInputSection\n {...props}\n inputId={inputId}\n data-testid={dataTestId ? `${dataTestId}-contact` : undefined}\n isLoading={isLoading}\n isVerified={otpState === \"verified\"}\n countdown={countdown}\n onSendOtp={handleSendOtp}\n onStateReset={resetToDefault}\n sendOtpError={sendOtpError}\n fixedCountry={\n props.type === \"phone-number\" ? props.fixedCountry : true\n }\n />\n\n {otpState === \"sent\" && (\n <VerificationSection\n {...props}\n data-testid={\n dataTestId ? `${dataTestId}-verification` : undefined\n }\n otpCode={otpValue?.value}\n otpPrefix={otpValue?.prefix}\n otpSeparator={otpValue?.separator}\n setOtpCode={onOtpChange}\n isVerifyLoading={isVerifyLoading}\n countdown={countdown}\n onVerifyOtp={handleVerifyOtp}\n verifyOtpError={verifyOtpError}\n />\n )}\n </div>\n );\n};\n"],"names":["OtpVerification","props","id","dataTestId","className","inputId","onSendOtp","onVerifyOtp","verifyOtpCountdownTimer","sendOtpError","verifyOtpError","otpValue","onOtpChange","otpState","onOtpStateChange","otpReminderInterval","isLoading","setIsLoading","useState","isVerifyLoading","setIsVerifyLoading","countdown","useCountdown","duration","reminderInterval","getStartMessage","getIntervalMessage","remaining","getCompletionMessage","_jsxs","clsx","styles.otpInputWrapper","children","_jsx","ContactInputSection","Object","assign","undefined","isVerified","__awaiter","reset","start","_a","onStateReset","fixedCountry","type","VerificationSection","otpCode","value","otpPrefix","prefix","otpSeparator","separator","setOtpCode","clearAnnouncer","announce"],"mappings":"6mBAiBO,MAAMA,EAAmBC,IAI5B,MAAMC,GACFA,EACA,cAAeC,EAAUC,UACzBA,EAASC,QACTA,EAAOC,UACPA,EAASC,YACTA,EAAWC,wBACXA,EAA0B,GAAEC,aAC5BA,EAAYC,eACZA,EAAcC,SACdA,EAAQC,YACRA,EAAWC,SACXA,EAAQC,iBACRA,EAAgBC,oBAChBA,EAAsB,KACtBd,GAEGe,EAAWC,GAAgBC,GAAS,IACpCC,EAAiBC,GAAsBF,GAAS,GAEjDG,EAAYC,EAAa,CAC3BC,SAAUf,EACVgB,iBAAkBT,EAClBU,gBAAkBF,GACd,6BAA6BA,YACjCG,mBAAqBC,GAAc,GAAGA,sBACtCC,qBAAsB,IAAM,+BA6DhC,OACIC,EAAA,MAAA,CACI3B,GAAIA,gBACSC,EACbC,UAAW0B,EAAKC,EAAwB3B,GAAU4B,SAAA,CAElDC,EAACC,EAAmBC,OAAAC,OAAA,CAAA,EACZnC,EAAK,CACTI,QAASA,EAAO,cACHF,EAAa,GAAGA,iBAAuBkC,EACpDrB,UAAWA,EACXsB,WAAyB,aAAbzB,EACZQ,UAAWA,EACXf,UAnEU,IAAWiC,OAAA,OAAA,OAAA,GAAA,YAC7B,GAAKjC,IAAaU,EAElB,IACIC,GAAa,SACPX,IACNQ,EAAiB,QACjBO,EAAUmB,QACVnB,EAAUoB,OACd,CAAE,MAAAC,GAEF,SACIzB,GAAa,EACjB,CACJ,IAsDY0B,aAvBW,KACF,aAAb9B,GACAC,EAAiB,UACrB,EAqBQL,aAAcA,EACdmC,aACmB,iBAAf3C,EAAM4C,MAA0B5C,EAAM2C,gBAIhC,SAAb/B,GACGoB,EAACa,mBACO7C,EAAK,CAAA,cAELE,EAAa,GAAGA,sBAA4BkC,EAEhDU,QAASpC,eAAAA,EAAUqC,MACnBC,UAAWtC,aAAQ,EAARA,EAAUuC,OACrBC,aAAcxC,aAAQ,EAARA,EAAUyC,UACxBC,WAAYzC,EACZO,gBAAiBA,EACjBE,UAAWA,EACXd,YAtEQ,IAAWgC,OAAA,OAAA,OAAA,GAAA,YAC/B,GAAKhC,IAAeY,IAAoBR,aAAQ,EAARA,EAAUqC,OAElD,IACI5B,GAAmB,SACbb,EAAYI,EAASqC,OAE3BlC,EAAiB,YAEjBwC,EAAe,UACfC,EACI,0DACA,UAIJlC,EAAUmB,QACV5B,SAAAA,EAAc,GAClB,CAAE,MAAA8B,GAEF,SACItB,GAAmB,EACvB,CACJ,IAgDgBV,eAAgBA,OAGtB"}
@@ -1,2 +1,2 @@
1
- import{jsxs as i,jsx as e}from"react/jsx-runtime";import{Button as t}from"../button/button.js";import{FormErrorMessage as r}from"../form/form-label.js";import{InputGroup as o}from"../input-group/input-group.js";import{concatIds as d}from"../shared/accessibility/index.js";import{Typography as a}from"../typography/index.js";import"../util/calendar-helper.js";import"../external/dayjs/dayjs.min.js";import"react";import{useId as n}from"../util/simple-id-generator.js";import"../util/string-helper.js";import"@react-aria/live-announcer";import{EmailThumbnail as l}from"./thumbnail/email-thumbnail.js";import{PhoneThumbnail as s}from"./thumbnail/phone-thumbnail.js";import{verificationSectionWrapper as m,sectionContainer as p,verifyInputWrapper as u,verifyButton as c,resendMessage as v}from"./verification-section.styles.js";const y=({id:y,"data-testid":f,type:h,showVerifyOtpThumbnail:b=!1,verifyOtpTitle:g,verifyOtpMessage:j,otpCode:$,setOtpCode:O,isVerifyLoading:w,countdown:x,onVerifyOtp:T,verifyOtpError:N,otpPrefix:C,otpSeparator:M})=>{const V=n(),B=`${V}-title`,D=`${V}-message`,P=`${V}-verify-input-addon`,E=`${V}-verify-error`;return i("div",{id:y,"data-testid":f,role:"group",className:m,children:[b?e("div",{"aria-hidden":!0,children:e("email"===h?l:s,{})}):null,i("div",{className:p,children:[i("div",{children:[e(a.BodyMD,{weight:"semibold",id:B,"data-testid":f?`${f}-title`:void 0,children:g}),e(a.BodyMD,{weight:"regular",id:D,"data-testid":f?`${f}-message`:void 0,children:j})]}),i("div",{children:[i("div",{className:u,children:[e(o,{id:y?`${y}-verify-input`:void 0,"data-testid":f?`${f}-verify-input`:void 0,value:$,onChange:i=>null==O?void 0:O(i.target.value),placeholder:"Enter OTP",addon:{type:"label",attributes:{value:`${null!=C?C:""}${null!=M?M:""}`}},type:"number",error:!!N,"aria-labelledby":B,"aria-describedby":d(D,P,N?E:void 0),"aria-invalid":!!N,"aria-required":!0}),e(t,{id:y?`${y}-verify-button`:void 0,type:"button","data-testid":f?`${f}-verify-button`:void 0,onClick:T,loading:w,styleType:"light",disabled:!$||0===$.length,className:c,children:!w&&"Verify"})]}),N&&e(r,{id:E,"data-testid":f?`${f}-verify-error`:void 0,role:"alert",children:N})]}),x.isRunning&&i(a.BodyMD,{id:y?`${y}-countdown`:void 0,"data-testid":f?`${f}-countdown`:void 0,className:v,children:["Resend OTP in ",x.formatTime()]})]})]})};export{y as VerificationSection};
1
+ import{jsxs as i,jsx as e}from"react/jsx-runtime";import{Button as t}from"../button/button.js";import{FormErrorMessage as r}from"../form/form-label/form-label.js";import{InputGroup as o}from"../input-group/input-group.js";import{concatIds as d}from"../shared/accessibility/index.js";import{Typography as a}from"../typography/index.js";import"../util/calendar-helper.js";import"../external/dayjs/dayjs.min.js";import"react";import{useId as l}from"../util/simple-id-generator.js";import"../util/string-helper.js";import"@react-aria/live-announcer";import{EmailThumbnail as n}from"./thumbnail/email-thumbnail.js";import{PhoneThumbnail as s}from"./thumbnail/phone-thumbnail.js";import{verificationSectionWrapper as m,sectionContainer as p,verifyInputWrapper as u,verifyButton as c,resendMessage as v}from"./verification-section.styles.js";const y=({id:y,"data-testid":f,type:h,showVerifyOtpThumbnail:b=!1,verifyOtpTitle:g,verifyOtpMessage:j,otpCode:$,setOtpCode:O,isVerifyLoading:w,countdown:x,onVerifyOtp:T,verifyOtpError:N,otpPrefix:C,otpSeparator:M})=>{const V=l(),B=`${V}-title`,D=`${V}-message`,P=`${V}-verify-input-addon`,E=`${V}-verify-error`;return i("div",{id:y,"data-testid":f,role:"group",className:m,children:[b?e("div",{"aria-hidden":!0,children:e("email"===h?n:s,{})}):null,i("div",{className:p,children:[i("div",{children:[e(a.BodyMD,{weight:"semibold",id:B,"data-testid":f?`${f}-title`:void 0,children:g}),e(a.BodyMD,{weight:"regular",id:D,"data-testid":f?`${f}-message`:void 0,children:j})]}),i("div",{children:[i("div",{className:u,children:[e(o,{id:y?`${y}-verify-input`:void 0,"data-testid":f?`${f}-verify-input`:void 0,value:$,onChange:i=>null==O?void 0:O(i.target.value),placeholder:"Enter OTP",addon:{type:"label",attributes:{value:`${null!=C?C:""}${null!=M?M:""}`}},type:"number",error:!!N,"aria-labelledby":B,"aria-describedby":d(D,P,N?E:void 0),"aria-invalid":!!N,"aria-required":!0}),e(t,{id:y?`${y}-verify-button`:void 0,type:"button","data-testid":f?`${f}-verify-button`:void 0,onClick:T,loading:w,styleType:"light",disabled:!$||0===$.length,className:c,children:!w&&"Verify"})]}),N&&e(r,{id:E,"data-testid":f?`${f}-verify-error`:void 0,role:"alert",children:N})]}),x.isRunning&&i(a.BodyMD,{id:y?`${y}-countdown`:void 0,"data-testid":f?`${f}-countdown`:void 0,className:v,children:["Resend OTP in ",x.formatTime()]})]})]})};export{y as VerificationSection};
2
2
  //# sourceMappingURL=verification-section.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"verification-section.js","sources":["../../src/otp-verification/verification-section.tsx"],"sourcesContent":["import { Button } from \"../button\";\nimport { FormErrorMessage } from \"../form/form-label\";\nimport { InputGroup } from \"../input-group\";\nimport { concatIds } from \"../shared/accessibility\";\nimport { Typography } from \"../typography\";\nimport { useId } from \"../util\";\nimport type { VerificationSectionProps } from \"./internal-types\";\nimport { EmailThumbnail, PhoneThumbnail } from \"./thumbnail\";\nimport * as styles from \"./verification-section.styles\";\n\nexport const VerificationSection = ({\n id,\n \"data-testid\": dataTestId,\n type,\n showVerifyOtpThumbnail = false,\n verifyOtpTitle,\n verifyOtpMessage,\n otpCode,\n setOtpCode,\n isVerifyLoading,\n countdown,\n onVerifyOtp,\n verifyOtpError,\n otpPrefix,\n otpSeparator,\n}: VerificationSectionProps) => {\n const internalId = useId();\n\n const titleId = `${internalId}-title`;\n const messageId = `${internalId}-message`;\n const otpAddonId = `${internalId}-verify-input-addon`;\n const verifyErrorId = `${internalId}-verify-error`;\n\n const renderThumbnail = () => {\n if (!showVerifyOtpThumbnail) return null;\n\n return (\n <div aria-hidden>\n {type === \"email\" ? <EmailThumbnail /> : <PhoneThumbnail />}\n </div>\n );\n };\n\n return (\n <div\n id={id}\n data-testid={dataTestId}\n role=\"group\"\n className={styles.verificationSectionWrapper}\n >\n {renderThumbnail()}\n <div className={styles.sectionContainer}>\n <div>\n <Typography.BodyMD\n weight=\"semibold\"\n id={titleId}\n data-testid={\n dataTestId ? `${dataTestId}-title` : undefined\n }\n >\n {verifyOtpTitle}\n </Typography.BodyMD>\n <Typography.BodyMD\n weight=\"regular\"\n id={messageId}\n data-testid={\n dataTestId ? `${dataTestId}-message` : undefined\n }\n >\n {verifyOtpMessage}\n </Typography.BodyMD>\n </div>\n <div>\n <div className={styles.verifyInputWrapper}>\n <InputGroup\n id={id ? `${id}-verify-input` : undefined}\n data-testid={\n dataTestId\n ? `${dataTestId}-verify-input`\n : undefined\n }\n value={otpCode}\n onChange={(e) => setOtpCode?.(e.target.value)}\n placeholder=\"Enter OTP\"\n addon={{\n type: \"label\",\n attributes: {\n value: `${otpPrefix ?? \"\"}${\n otpSeparator ?? \"\"\n }`,\n },\n }}\n type=\"number\"\n error={!!verifyOtpError}\n aria-labelledby={titleId}\n aria-describedby={concatIds(\n messageId,\n otpAddonId,\n verifyOtpError ? verifyErrorId : undefined\n )}\n aria-invalid={!!verifyOtpError}\n aria-required={true}\n />\n <Button\n id={id ? `${id}-verify-button` : undefined}\n type=\"button\"\n data-testid={\n dataTestId\n ? `${dataTestId}-verify-button`\n : undefined\n }\n onClick={onVerifyOtp}\n loading={isVerifyLoading}\n styleType=\"light\"\n disabled={!otpCode || otpCode.length === 0}\n className={styles.verifyButton}\n >\n {!isVerifyLoading && \"Verify\"}\n </Button>\n </div>\n {verifyOtpError && (\n <FormErrorMessage\n id={verifyErrorId}\n data-testid={\n dataTestId\n ? `${dataTestId}-verify-error`\n : undefined\n }\n role=\"alert\"\n >\n {verifyOtpError}\n </FormErrorMessage>\n )}\n </div>\n {countdown.isRunning && (\n <Typography.BodyMD\n id={id ? `${id}-countdown` : undefined}\n data-testid={\n dataTestId ? `${dataTestId}-countdown` : undefined\n }\n className={styles.resendMessage}\n >\n Resend OTP in {countdown.formatTime()}\n </Typography.BodyMD>\n )}\n </div>\n </div>\n );\n};\n"],"names":["VerificationSection","id","dataTestId","type","showVerifyOtpThumbnail","verifyOtpTitle","verifyOtpMessage","otpCode","setOtpCode","isVerifyLoading","countdown","onVerifyOtp","verifyOtpError","otpPrefix","otpSeparator","internalId","useId","titleId","messageId","otpAddonId","verifyErrorId","_jsxs","role","className","styles.verificationSectionWrapper","children","_jsx","EmailThumbnail","PhoneThumbnail","styles.sectionContainer","Typography","BodyMD","weight","undefined","styles.verifyInputWrapper","InputGroup","value","onChange","e","target","placeholder","addon","attributes","error","concatIds","Button","onClick","loading","styleType","disabled","length","styles.verifyButton","FormErrorMessage","isRunning","styles.resendMessage","formatTime"],"mappings":"wzBAUO,MAAMA,EAAsB,EAC/BC,KACA,cAAeC,EACfC,OACAC,0BAAyB,EACzBC,iBACAC,mBACAC,UACAC,aACAC,kBACAC,YACAC,cACAC,iBACAC,YACAC,mBAEA,MAAMC,EAAaC,IAEbC,EAAU,GAAGF,UACbG,EAAY,GAAGH,YACfI,EAAa,GAAGJ,uBAChBK,EAAgB,GAAGL,iBAYzB,OACIM,EAAA,MAAA,CACIpB,GAAIA,gBACSC,EACboB,KAAK,QACLC,UAAWC,EAAiCC,SAAA,CAd3CrB,EAGDsB,EAAA,MAAA,CAAA,eAAA,EAAAD,SACwBC,EAAV,UAATvB,EAAoBwB,EAAqBC,EAAP,CAAA,KAJP,KAiBhCP,EAAA,MAAA,CAAKE,UAAWM,EAAuBJ,SAAA,CACnCJ,EAAA,MAAA,CAAAI,SAAA,CACIC,EAACI,EAAWC,QACRC,OAAO,WACP/B,GAAIgB,EAAO,cAEPf,EAAa,GAAGA,eAAqB+B,EAASR,SAGjDpB,IAELqB,EAACI,EAAWC,OAAM,CACdC,OAAO,UACP/B,GAAIiB,gBAEAhB,EAAa,GAAGA,iBAAuB+B,EAASR,SAGnDnB,OAGTe,EAAA,MAAA,CAAAI,SAAA,CACIJ,EAAA,MAAA,CAAKE,UAAWW,EAAyBT,SAAA,CACrCC,EAACS,EAAU,CACPlC,GAAIA,EAAK,GAAGA,sBAAoBgC,EAAS,cAErC/B,EACM,GAAGA,sBACH+B,EAEVG,MAAO7B,EACP8B,SAAWC,GAAM9B,aAAU,EAAVA,EAAa8B,EAAEC,OAAOH,OACvCI,YAAY,YACZC,MAAO,CACHtC,KAAM,QACNuC,WAAY,CACRN,MAAO,GAAGvB,QAAAA,EAAa,KACnBC,QAAAA,EAAgB,OAI5BX,KAAK,SACLwC,QAAS/B,EAAc,kBACNK,EAAO,mBACN2B,EACd1B,EACAC,EACAP,EAAiBQ,OAAgBa,oBAErBrB,EAAc,iBACf,IAEnBc,EAACmB,EAAM,CACH5C,GAAIA,EAAK,GAAGA,uBAAqBgC,EACjC9B,KAAK,SAAQ,cAETD,EACM,GAAGA,uBACH+B,EAEVa,QAASnC,EACToC,QAAStC,EACTuC,UAAU,QACVC,UAAW1C,GAA8B,IAAnBA,EAAQ2C,OAC9B3B,UAAW4B,EAAmB1B,UAE5BhB,GAAmB,cAG5BG,GACGc,EAAC0B,GACGnD,GAAImB,EAAa,cAEblB,EACM,GAAGA,sBACH+B,EAEVX,KAAK,QAAOG,SAEXb,OAIZF,EAAU2C,WACPhC,EAACS,EAAWC,OAAM,CACd9B,GAAIA,EAAK,GAAGA,mBAAiBgC,EAAS,cAElC/B,EAAa,GAAGA,mBAAyB+B,EAE7CV,UAAW+B,EAAoB7B,SAAA,CAAA,iBAEhBf,EAAU6C,qBAInC"}
1
+ {"version":3,"file":"verification-section.js","sources":["../../src/otp-verification/verification-section.tsx"],"sourcesContent":["import { Button } from \"../button\";\nimport { FormErrorMessage } from \"../form/form-label\";\nimport { InputGroup } from \"../input-group\";\nimport { concatIds } from \"../shared/accessibility\";\nimport { Typography } from \"../typography\";\nimport { useId } from \"../util\";\nimport type { VerificationSectionProps } from \"./internal-types\";\nimport { EmailThumbnail, PhoneThumbnail } from \"./thumbnail\";\nimport * as styles from \"./verification-section.styles\";\n\nexport const VerificationSection = ({\n id,\n \"data-testid\": dataTestId,\n type,\n showVerifyOtpThumbnail = false,\n verifyOtpTitle,\n verifyOtpMessage,\n otpCode,\n setOtpCode,\n isVerifyLoading,\n countdown,\n onVerifyOtp,\n verifyOtpError,\n otpPrefix,\n otpSeparator,\n}: VerificationSectionProps) => {\n const internalId = useId();\n\n const titleId = `${internalId}-title`;\n const messageId = `${internalId}-message`;\n const otpAddonId = `${internalId}-verify-input-addon`;\n const verifyErrorId = `${internalId}-verify-error`;\n\n const renderThumbnail = () => {\n if (!showVerifyOtpThumbnail) return null;\n\n return (\n <div aria-hidden>\n {type === \"email\" ? <EmailThumbnail /> : <PhoneThumbnail />}\n </div>\n );\n };\n\n return (\n <div\n id={id}\n data-testid={dataTestId}\n role=\"group\"\n className={styles.verificationSectionWrapper}\n >\n {renderThumbnail()}\n <div className={styles.sectionContainer}>\n <div>\n <Typography.BodyMD\n weight=\"semibold\"\n id={titleId}\n data-testid={\n dataTestId ? `${dataTestId}-title` : undefined\n }\n >\n {verifyOtpTitle}\n </Typography.BodyMD>\n <Typography.BodyMD\n weight=\"regular\"\n id={messageId}\n data-testid={\n dataTestId ? `${dataTestId}-message` : undefined\n }\n >\n {verifyOtpMessage}\n </Typography.BodyMD>\n </div>\n <div>\n <div className={styles.verifyInputWrapper}>\n <InputGroup\n id={id ? `${id}-verify-input` : undefined}\n data-testid={\n dataTestId\n ? `${dataTestId}-verify-input`\n : undefined\n }\n value={otpCode}\n onChange={(e) => setOtpCode?.(e.target.value)}\n placeholder=\"Enter OTP\"\n addon={{\n type: \"label\",\n attributes: {\n value: `${otpPrefix ?? \"\"}${\n otpSeparator ?? \"\"\n }`,\n },\n }}\n type=\"number\"\n error={!!verifyOtpError}\n aria-labelledby={titleId}\n aria-describedby={concatIds(\n messageId,\n otpAddonId,\n verifyOtpError ? verifyErrorId : undefined\n )}\n aria-invalid={!!verifyOtpError}\n aria-required={true}\n />\n <Button\n id={id ? `${id}-verify-button` : undefined}\n type=\"button\"\n data-testid={\n dataTestId\n ? `${dataTestId}-verify-button`\n : undefined\n }\n onClick={onVerifyOtp}\n loading={isVerifyLoading}\n styleType=\"light\"\n disabled={!otpCode || otpCode.length === 0}\n className={styles.verifyButton}\n >\n {!isVerifyLoading && \"Verify\"}\n </Button>\n </div>\n {verifyOtpError && (\n <FormErrorMessage\n id={verifyErrorId}\n data-testid={\n dataTestId\n ? `${dataTestId}-verify-error`\n : undefined\n }\n role=\"alert\"\n >\n {verifyOtpError}\n </FormErrorMessage>\n )}\n </div>\n {countdown.isRunning && (\n <Typography.BodyMD\n id={id ? `${id}-countdown` : undefined}\n data-testid={\n dataTestId ? `${dataTestId}-countdown` : undefined\n }\n className={styles.resendMessage}\n >\n Resend OTP in {countdown.formatTime()}\n </Typography.BodyMD>\n )}\n </div>\n </div>\n );\n};\n"],"names":["VerificationSection","id","dataTestId","type","showVerifyOtpThumbnail","verifyOtpTitle","verifyOtpMessage","otpCode","setOtpCode","isVerifyLoading","countdown","onVerifyOtp","verifyOtpError","otpPrefix","otpSeparator","internalId","useId","titleId","messageId","otpAddonId","verifyErrorId","_jsxs","role","className","styles.verificationSectionWrapper","children","_jsx","EmailThumbnail","PhoneThumbnail","styles.sectionContainer","Typography","BodyMD","weight","undefined","styles.verifyInputWrapper","InputGroup","value","onChange","e","target","placeholder","addon","attributes","error","concatIds","Button","onClick","loading","styleType","disabled","length","styles.verifyButton","FormErrorMessage","isRunning","styles.resendMessage","formatTime"],"mappings":"m0BAUO,MAAMA,EAAsB,EAC/BC,KACA,cAAeC,EACfC,OACAC,0BAAyB,EACzBC,iBACAC,mBACAC,UACAC,aACAC,kBACAC,YACAC,cACAC,iBACAC,YACAC,mBAEA,MAAMC,EAAaC,IAEbC,EAAU,GAAGF,UACbG,EAAY,GAAGH,YACfI,EAAa,GAAGJ,uBAChBK,EAAgB,GAAGL,iBAYzB,OACIM,EAAA,MAAA,CACIpB,GAAIA,gBACSC,EACboB,KAAK,QACLC,UAAWC,EAAiCC,SAAA,CAd3CrB,EAGDsB,EAAA,MAAA,CAAA,eAAA,EAAAD,SACwBC,EAAV,UAATvB,EAAoBwB,EAAqBC,EAAP,CAAA,KAJP,KAiBhCP,EAAA,MAAA,CAAKE,UAAWM,EAAuBJ,SAAA,CACnCJ,EAAA,MAAA,CAAAI,SAAA,CACIC,EAACI,EAAWC,QACRC,OAAO,WACP/B,GAAIgB,EAAO,cAEPf,EAAa,GAAGA,eAAqB+B,EAASR,SAGjDpB,IAELqB,EAACI,EAAWC,OAAM,CACdC,OAAO,UACP/B,GAAIiB,gBAEAhB,EAAa,GAAGA,iBAAuB+B,EAASR,SAGnDnB,OAGTe,EAAA,MAAA,CAAAI,SAAA,CACIJ,EAAA,MAAA,CAAKE,UAAWW,EAAyBT,SAAA,CACrCC,EAACS,EAAU,CACPlC,GAAIA,EAAK,GAAGA,sBAAoBgC,EAAS,cAErC/B,EACM,GAAGA,sBACH+B,EAEVG,MAAO7B,EACP8B,SAAWC,GAAM9B,aAAU,EAAVA,EAAa8B,EAAEC,OAAOH,OACvCI,YAAY,YACZC,MAAO,CACHtC,KAAM,QACNuC,WAAY,CACRN,MAAO,GAAGvB,QAAAA,EAAa,KACnBC,QAAAA,EAAgB,OAI5BX,KAAK,SACLwC,QAAS/B,EAAc,kBACNK,EAAO,mBACN2B,EACd1B,EACAC,EACAP,EAAiBQ,OAAgBa,oBAErBrB,EAAc,iBACf,IAEnBc,EAACmB,EAAM,CACH5C,GAAIA,EAAK,GAAGA,uBAAqBgC,EACjC9B,KAAK,SAAQ,cAETD,EACM,GAAGA,uBACH+B,EAEVa,QAASnC,EACToC,QAAStC,EACTuC,UAAU,QACVC,UAAW1C,GAA8B,IAAnBA,EAAQ2C,OAC9B3B,UAAW4B,EAAmB1B,UAE5BhB,GAAmB,cAG5BG,GACGc,EAAC0B,GACGnD,GAAImB,EAAa,cAEblB,EACM,GAAGA,sBACH+B,EAEVX,KAAK,QAAOG,SAEXb,OAIZF,EAAU2C,WACPhC,EAACS,EAAWC,OAAM,CACd9B,GAAIA,EAAK,GAAGA,mBAAiBgC,EAAS,cAElC/B,EAAa,GAAGA,mBAAyB+B,EAE7CV,UAAW+B,EAAoB7B,SAAA,CAAA,iBAEhBf,EAAU6C,qBAInC"}