@lifesg/react-design-system 4.0.0-alpha.4 → 4.0.0-alpha.5

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 (545) hide show
  1. package/accordion/accordion-item.styles_1j4eb32.css +2 -2
  2. package/accordion/accordion.d.ts +19 -0
  3. package/accordion/accordion.js.map +1 -1
  4. package/accordion/accordion.styles_bzrfrs.css +2 -2
  5. package/accordion/types.d.ts +42 -2
  6. package/alert/alert.d.ts +8 -0
  7. package/alert/alert.js.map +1 -1
  8. package/alert/alert.styles_patwo2.css +2 -2
  9. package/alert/types.d.ts +26 -2
  10. package/animations/loading-dots/loading-dots.styles_1rgrrmw.css +2 -2
  11. package/animations/loading-dots/lottie-animation.styles_1m15v69.css +1 -1
  12. package/animations/loading-dots-spinner/loading-dots-spinner.styles_1hcqkhs.css +2 -2
  13. package/animations/loading-dots-spinner/lottie-animation.styles_13d1unb.css +1 -1
  14. package/animations/loading-spinner/loading-spinner.styles_n6xoft.css +2 -2
  15. package/animations/loading-spinner/lottie-animation.styles_bnn4qt.css +1 -1
  16. package/avatar/avatar.d.ts +7 -0
  17. package/avatar/avatar.js.map +1 -1
  18. package/avatar/avatar.styles_16efw4.css +2 -2
  19. package/avatar/types.d.ts +11 -0
  20. package/badge/badge.d.ts +7 -0
  21. package/badge/badge.js.map +1 -1
  22. package/badge/badge.styles_1c3c6wj.css +2 -2
  23. package/badge/types.d.ts +20 -0
  24. package/box-container/box-container.d.ts +8 -0
  25. package/box-container/box-container.js.map +1 -1
  26. package/box-container/box-container.styles_5t2j9k.css +2 -2
  27. package/box-container/types.d.ts +24 -0
  28. package/breadcrumb/breadcrumb.styles_1nl4aua.css +2 -2
  29. package/button/button.styles_1pxy0co.css +2 -2
  30. package/calendar/calendar.styles_11ho5x8.css +2 -2
  31. package/card/card.styles_1gh9gs3.css +2 -2
  32. package/checkbox/checkbox.styles_gm5bu1.css +2 -2
  33. package/cjs/accordion/accordion-item.styles_1j4eb32.css +2 -2
  34. package/cjs/accordion/accordion.js.map +1 -1
  35. package/cjs/accordion/accordion.styles_bzrfrs.css +2 -2
  36. package/cjs/alert/alert.js.map +1 -1
  37. package/cjs/alert/alert.styles_patwo2.css +2 -2
  38. package/cjs/animations/loading-dots/loading-dots.styles_1rgrrmw.css +2 -2
  39. package/cjs/animations/loading-dots/lottie-animation.styles_1m15v69.css +1 -1
  40. package/cjs/animations/loading-dots-spinner/loading-dots-spinner.styles_1hcqkhs.css +2 -2
  41. package/cjs/animations/loading-dots-spinner/lottie-animation.styles_13d1unb.css +1 -1
  42. package/cjs/animations/loading-spinner/loading-spinner.styles_n6xoft.css +2 -2
  43. package/cjs/animations/loading-spinner/lottie-animation.styles_bnn4qt.css +1 -1
  44. package/cjs/avatar/avatar.js.map +1 -1
  45. package/cjs/avatar/avatar.styles_16efw4.css +2 -2
  46. package/cjs/badge/badge.js.map +1 -1
  47. package/cjs/badge/badge.styles_1c3c6wj.css +2 -2
  48. package/cjs/box-container/box-container.js.map +1 -1
  49. package/cjs/box-container/box-container.styles_5t2j9k.css +2 -2
  50. package/cjs/breadcrumb/breadcrumb.styles_1nl4aua.css +2 -2
  51. package/cjs/button/button.styles_1pxy0co.css +2 -2
  52. package/cjs/calendar/calendar.styles_11ho5x8.css +2 -2
  53. package/cjs/card/card.styles_1gh9gs3.css +2 -2
  54. package/cjs/checkbox/checkbox.styles_gm5bu1.css +2 -2
  55. package/cjs/countdown-timer/countdown-timer.js.map +1 -1
  56. package/cjs/countdown-timer/countdown-timer.styles_ipn1b0.css +2 -2
  57. package/cjs/dashed-border/dashed-border.js.map +1 -1
  58. package/cjs/dashed-border/dashed-border.styles_zszoox.css +2 -2
  59. package/cjs/data-table/data-table.js.map +1 -1
  60. package/cjs/data-table/data-table.styles_1iqq1g7.css +2 -2
  61. package/cjs/date-input/date-input.js.map +1 -1
  62. package/cjs/date-input/date-input.styles_1r5kcc7.css +1 -1
  63. package/cjs/date-navigator/date-navigator.js.map +1 -1
  64. package/cjs/date-navigator/date-navigator.styles_wokh56.css +2 -2
  65. package/cjs/date-range-input/date-range-input.js.map +1 -1
  66. package/cjs/date-range-input/date-range-input.styles_1s7ojnj.css +2 -2
  67. package/cjs/divider/divider.js.map +1 -1
  68. package/cjs/divider/divider.styles_1xpzh8p.css +2 -2
  69. package/cjs/drawer/drawer.js.map +1 -1
  70. package/cjs/drawer/drawer.styles_94hx3y.css +2 -2
  71. package/cjs/e-signature/e-signature-canvas.js +1 -1
  72. package/cjs/e-signature/e-signature-canvas.js.map +1 -1
  73. package/cjs/e-signature/e-signature.js.map +1 -1
  74. package/cjs/e-signature/e-signature.styles_lukd9f.css +2 -2
  75. package/cjs/error-display/error-display.js.map +1 -1
  76. package/cjs/error-display/error-display.styles_d3tql1.css +2 -2
  77. package/cjs/external/dompurify/dist/purify.es.js +3 -3
  78. package/cjs/external/dompurify/dist/purify.es.js.map +1 -1
  79. package/cjs/feedback-rating/feedback-rating-stars-container.styles_dmi8z9.css +2 -2
  80. package/cjs/feedback-rating/feedback-rating.js.map +1 -1
  81. package/cjs/feedback-rating/feedback-rating.styles_1kdklb6.css +2 -2
  82. package/cjs/file-download/file-download.js.map +1 -1
  83. package/cjs/file-download/file-download.styles_iggk8q.css +2 -2
  84. package/cjs/file-download/file-list-card/file-list-card.styles.js +1 -1
  85. package/cjs/file-download/file-list-card/file-list-card.styles.js.map +1 -1
  86. package/cjs/file-download/file-list-card/{file-list-card.styles_oom8ii.css → file-list-card.styles_18j2gut.css} +3 -3
  87. package/cjs/file-upload/dropzone.styles_1pllsau.css +2 -2
  88. package/cjs/file-upload/file-item-edit.js +1 -1
  89. package/cjs/file-upload/file-item-edit.js.map +1 -1
  90. package/cjs/file-upload/file-item-edit.styles.js +1 -1
  91. package/cjs/file-upload/file-item-edit.styles.js.map +1 -1
  92. package/cjs/file-upload/{file-item-edit.styles_1qbpbxj.css → file-item-edit.styles_19bvztn.css} +6 -5
  93. package/cjs/file-upload/file-list/file-list.js +1 -1
  94. package/cjs/file-upload/file-list/file-list.js.map +1 -1
  95. package/cjs/file-upload/file-list/file-list.styles.js +1 -1
  96. package/cjs/file-upload/file-list/file-list.styles.js.map +1 -1
  97. package/cjs/file-upload/file-list/file-list.styles_1w7so98.css +3 -0
  98. package/cjs/file-upload/file-list-item/file-list-item-thumbnail.styles_1y4si19.css +2 -2
  99. package/cjs/file-upload/file-list-item/file-list-item.js +1 -1
  100. package/cjs/file-upload/file-list-item/file-list-item.js.map +1 -1
  101. package/cjs/file-upload/file-list-item/file-list-item.styles.js +1 -1
  102. package/cjs/file-upload/file-list-item/file-list-item.styles.js.map +1 -1
  103. package/cjs/file-upload/file-list-item/file-list-item.styles_o8000f.css +17 -0
  104. package/cjs/file-upload/file-upload.js +1 -1
  105. package/cjs/file-upload/file-upload.js.map +1 -1
  106. package/cjs/file-upload/file-upload.styles_9ffwcd.css +2 -2
  107. package/cjs/filter/addons/filter-item-checkbox.styles_7degw7.css +2 -2
  108. package/cjs/filter/filter-item-page.styles_17ewfrz.css +1 -1
  109. package/cjs/filter/filter-item.js.map +1 -1
  110. package/cjs/filter/filter-item.styles_cphjnj.css +2 -2
  111. package/cjs/filter/filter-modal.styles_qw3xlg.css +2 -2
  112. package/cjs/filter/filter-sidebar.styles_1otwpjl.css +2 -2
  113. package/cjs/filter/filter.js.map +1 -1
  114. package/cjs/filter/filter.styles_1ykijwm.css +2 -2
  115. package/cjs/footer/footer-download-app.styles_1v1j2us.css +2 -2
  116. package/cjs/footer/footer-resource-addon.styles_1jepb1d.css +2 -2
  117. package/cjs/footer/footer.js +1 -1
  118. package/cjs/footer/footer.js.map +1 -1
  119. package/cjs/footer/footer.styles_1msorhc.css +2 -2
  120. package/cjs/form/form-label-addon.styles_b00z8p.css +1 -1
  121. package/cjs/form/form-label.styles.js +1 -1
  122. package/cjs/form/form-label.styles.js.map +1 -1
  123. package/cjs/form/{form-label.styles_11r0652.css → form-label.styles_1nbe0bm.css} +2 -2
  124. package/cjs/form/form-textarea.styles_3p9qoy.css +2 -2
  125. package/cjs/form/form-wrapper.styles_199rslu.css +1 -1
  126. package/cjs/fullscreen-image-carousel/fullscreen-image-carousel.styles_vc6y5c.css +2 -2
  127. package/cjs/fullscreen-image-carousel/stateful-image.styles_1xe8ypm.css +2 -2
  128. package/cjs/histogram-slider/histogram-slider.styles_wvd4w.css +2 -2
  129. package/cjs/image-button/image-button.styles_6n1qsr.css +2 -2
  130. package/cjs/index.js +1 -1
  131. package/cjs/input/input.styles_1cblor0.css +2 -2
  132. package/cjs/input-group/input-group-list-addon.styles_17iuqtw.css +2 -2
  133. package/cjs/input-group/input-group.styles_bqye6f.css +2 -2
  134. package/cjs/input-range-select/input-range-select.styles_adbrbm.css +2 -2
  135. package/cjs/input-range-slider/input-range-slider.styles_aljl2v.css +2 -2
  136. package/cjs/input-textarea/textarea-counter.styles_1n3wsnv.css +1 -1
  137. package/cjs/input-textarea/textarea.styles_22z4n3.css +2 -2
  138. package/cjs/language-switcher/dropdown-panel.styles_1qsjf8d.css +2 -2
  139. package/cjs/language-switcher/dropdown-variant.styles_1vrdfky.css +2 -2
  140. package/cjs/language-switcher/link-container-variant.styles_1iw6zux.css +2 -2
  141. package/cjs/layout/col-div.styles_16o6mwx.css +1 -1
  142. package/cjs/layout/container.styles_v70ec6.css +2 -2
  143. package/cjs/layout/section.styles_hstcaf.css +1 -1
  144. package/cjs/link-list/link-list.styles_m57vks.css +2 -2
  145. package/cjs/local-nav/local-nav-dropdown/local-nav-dropdown.styles_uhd4xl.css +2 -2
  146. package/cjs/local-nav/local-nav-menu/local-nav-menu.styles_pq19dh.css +2 -2
  147. package/cjs/markup/markup.style_1iu40x9.css +2 -2
  148. package/cjs/masked-input/masked-input.styles_1cm388a.css +2 -2
  149. package/cjs/masthead/masthead.styles_1huzon9.css +2 -2
  150. package/cjs/menu/menu-content.styles_p7ijll.css +2 -2
  151. package/cjs/menu/menu-item.styles_liyed8.css +2 -2
  152. package/cjs/menu/menu-link.styles_hfxoez.css +2 -2
  153. package/cjs/menu/menu-section.styles_g7my4d.css +2 -2
  154. package/cjs/modal/modal-box.styles_y52cts.css +2 -2
  155. package/cjs/modal/modal.styles_1lbblx6.css +2 -2
  156. package/cjs/modal-v2/modal-v2.styles_a8gv5i.css +2 -2
  157. package/cjs/modal-v2/slots/slot-styles_13sd376.css +2 -2
  158. package/cjs/navbar/brand.styles_zcgddp.css +1 -1
  159. package/cjs/navbar/drawer.js +1 -1
  160. package/cjs/navbar/drawer.js.map +1 -1
  161. package/cjs/navbar/drawer.styles_7hnxp5.css +2 -2
  162. package/cjs/navbar/menu.styles_gdpqc.css +2 -2
  163. package/cjs/navbar/navbar-action-buttons.styles_1vpm0nk.css +2 -2
  164. package/cjs/navbar/navbar-items.styles_1i3ltot.css +2 -2
  165. package/cjs/navbar/navbar.js +1 -1
  166. package/cjs/navbar/navbar.js.map +1 -1
  167. package/cjs/navbar/navbar.styles_koy0c7.css +2 -2
  168. package/cjs/notification-banner/notification-banner.styles_uxlysy.css +2 -2
  169. package/cjs/otp-input/otp-input.styles_5sbutl.css +2 -2
  170. package/cjs/otp-verification/contact-input-section.styles_odrjvt.css +2 -2
  171. package/cjs/otp-verification/otp-verification.styles_dg9bm8.css +1 -1
  172. package/cjs/otp-verification/thumbnail/thumbnail.styles_shqylh.css +2 -2
  173. package/cjs/otp-verification/verification-section.styles_x8jj.css +2 -2
  174. package/cjs/overlay/overlay.js +1 -1
  175. package/cjs/overlay/overlay.js.map +1 -1
  176. package/cjs/overlay/overlay.styles_12wym18.css +2 -2
  177. package/cjs/pagination/pagination.styles_6bcgva.css +2 -2
  178. package/cjs/pill/pill.styles_xwrniu.css +2 -2
  179. package/cjs/popover/popover-inline/popover-inline.styles_bkopnt.css +2 -2
  180. package/cjs/popover/popover-trigger.styles_8zokig.css +1 -1
  181. package/cjs/popover/popover.styles_ujnf0h.css +2 -2
  182. package/cjs/progress-indicator/progress-indicator.styles_1c038s4.css +2 -2
  183. package/cjs/radio-button/radio-button.styles_1c4v6v.css +2 -2
  184. package/cjs/schedule/schedule-day-view/schedule-day-view.styles_8ti149.css +2 -2
  185. package/cjs/schedule/schedule-header/schedule-header.js +1 -1
  186. package/cjs/schedule/schedule-header/schedule-header.js.map +1 -1
  187. package/cjs/schedule/schedule-header/schedule-header.styles_1n2u5vj.css +2 -2
  188. package/cjs/schedule/schedule-week-view/schedule-week-view.styles_x7x50m.css +2 -2
  189. package/cjs/schedule/schedule-week-view/time-cell.styles_1sorjz8.css +2 -2
  190. package/cjs/schedule/schedule.styles_fdy5a1.css +2 -2
  191. package/cjs/schedule/shared/with-optional-popover.styles_7mv3p2.css +1 -1
  192. package/cjs/schedule/time-indicator/time-indicator.styles_1eaxyes.css +2 -2
  193. package/cjs/select-histogram/select-histogram.styles_n260dy.css +2 -2
  194. package/cjs/shared/accessibility/index_13g9vp.css +1 -1
  195. package/cjs/shared/clickable-icon/clickable-icon.styles_1v2imml.css +2 -2
  196. package/cjs/shared/component-loading-spinner/component-loading-spinner.styles_15eq02i.css +2 -2
  197. package/cjs/shared/dropdown-list/dropdown-label.styles_mloii0.css +2 -2
  198. package/cjs/shared/dropdown-list/dropdown-list.styles_konwm.css +2 -2
  199. package/cjs/shared/dropdown-list/dropdown-search.styles_1hc1gkh.css +2 -2
  200. package/cjs/shared/dropdown-list/expandable-element.styles_rkkvqr.css +2 -2
  201. package/cjs/shared/dropdown-list/nested-dropdown-list.styles_wdhxoe.css +2 -2
  202. package/cjs/shared/dropdown-wrapper/dropdown-wrapper.styles_15hwwoj.css +2 -2
  203. package/cjs/shared/fade-wrapper/fade-wrapper.styles_16iug7l.css +2 -2
  204. package/cjs/shared/image-placeholder/image-placeholder.styles_44nwil.css +1 -1
  205. package/cjs/shared/input-wrapper/input-wrapper.styles_je6maw.css +2 -2
  206. package/cjs/shared/internal-calendar/calendar-dropdown.styles_wybjai.css +1 -1
  207. package/cjs/shared/internal-calendar/calendar-manager.js +1 -1
  208. package/cjs/shared/internal-calendar/calendar-manager.js.map +1 -1
  209. package/cjs/shared/internal-calendar/calendar-manager.styles.js +1 -1
  210. package/cjs/shared/internal-calendar/calendar-manager.styles.js.map +1 -1
  211. package/cjs/shared/internal-calendar/{calendar-manager.styles_1iuq5zw.css → calendar-manager.styles_1njwkj2.css} +3 -3
  212. package/cjs/shared/internal-calendar/day-cell/day-cell.styles_1t5oqc1.css +2 -2
  213. package/cjs/shared/internal-calendar/internal-calendar-month.styles_14oh57f.css +2 -2
  214. package/cjs/shared/internal-calendar/internal-calendar-year.styles_therlc.css +2 -2
  215. package/cjs/shared/internal-calendar/internal-calendar.styles_gnc3eq.css +1 -1
  216. package/cjs/shared/internal-calendar/standard/standard-calendar-day-view.styles_1bw26au.css +2 -2
  217. package/cjs/shared/progress-bar/progress-bar.styles_125ri7a.css +1 -1
  218. package/cjs/shared/range-input-inner-container/range-input-inner-container.styles_1v61utg.css +2 -2
  219. package/cjs/shared/standalone-date-input/standalone-date-input.styles_157qo89.css +2 -2
  220. package/cjs/shared/time-slot/time-slot.styles_18s0to7.css +2 -2
  221. package/cjs/shared/timepicker-dropdown/timepicker-dropdown.styles_119l6k6.css +2 -2
  222. package/cjs/sidenav/sidenav-drawer-item.styles_1ljnyx2.css +2 -2
  223. package/cjs/sidenav/sidenav-drawer-subitem.styles_2y58kf.css +1 -1
  224. package/cjs/sidenav/sidenav-group.styles_1x604sw.css +2 -2
  225. package/cjs/sidenav/sidenav-item.styles_lqw3kh.css +2 -2
  226. package/cjs/sidenav/sidenav.styles_1vxezie.css +2 -2
  227. package/cjs/singpass-button/singpass-button.styles_1miyex3.css +2 -2
  228. package/cjs/smart-app-banner/smart-app-banner.styles_15u6yv4.css +2 -2
  229. package/cjs/tab/tab-link-chain.styles_49got4.css +2 -2
  230. package/cjs/tab/tab.styles_1najffw.css +1 -1
  231. package/cjs/table/table.styles_1af5ipv.css +2 -2
  232. package/cjs/tag/tag.style_d98c53.css +2 -2
  233. package/cjs/text-list/text-list.styles_w3fvyt.css +2 -2
  234. package/cjs/theme/types.js +1 -1
  235. package/cjs/theme/types.js.map +1 -1
  236. package/cjs/theme/utils/use-design-token-override.js +2 -0
  237. package/cjs/theme/utils/use-design-token-override.js.map +1 -0
  238. package/cjs/time-range-picker/combobox-picker/combobox-picker.styles_7i9vso.css +1 -1
  239. package/cjs/time-range-picker/common.styles_1qwp4xa.css +2 -2
  240. package/cjs/time-slot-bar/time-slot-bar.styles_wigbyd.css +2 -2
  241. package/cjs/time-slot-bar-week/time-slot-bar-week-days.styles_evdvs9.css +2 -2
  242. package/cjs/time-slot-bar-week/time-slot-bar-week.styles_11ybf42.css +1 -1
  243. package/cjs/time-slot-week-view/time-slot-week-days.styles_1h21vyw.css +2 -2
  244. package/cjs/time-slot-week-view/time-slot-week-view.styles_gqgsw2.css +1 -1
  245. package/cjs/timeline/timeline.styles_1jxzik4.css +2 -2
  246. package/cjs/timepicker/timepicker.styles_1jm33yw.css +1 -1
  247. package/cjs/timetable/timetable-header/timetable-header.styles_11gl1h4.css +2 -2
  248. package/cjs/timetable/timetable-row/row-bar.styles_1x0vrsz.css +1 -1
  249. package/cjs/timetable/timetable-row/row-cell.styles_y1dl5j.css +2 -2
  250. package/cjs/timetable/timetable.styles_7rp8kz.css +2 -2
  251. package/cjs/toast/toast.styles_1e0l60w.css +2 -2
  252. package/cjs/toggle/toggle-icon.styles_ba71y.css +2 -2
  253. package/cjs/toggle/toggle.styles_1t5qrye.css +2 -2
  254. package/cjs/typography/typography-text.styles_1734x2k.css +2 -2
  255. package/cjs/typography/typography.styles.js +1 -1
  256. package/cjs/typography/typography.styles.js.map +1 -1
  257. package/cjs/typography/{typography.styles_1155j4c.css → typography.styles_1wd82dn.css} +2 -2
  258. package/cjs/uneditable-section/section-item.styles_mwx8ht.css +2 -2
  259. package/cjs/uneditable-section/uneditable-section.js +1 -1
  260. package/cjs/uneditable-section/uneditable-section.js.map +1 -1
  261. package/cjs/uneditable-section/uneditable-section.styles_aj9zun.css +2 -2
  262. package/cjs/unit-number/unit-number-input.styles_8yizj.css +2 -2
  263. package/countdown-timer/countdown-timer.d.ts +6 -0
  264. package/countdown-timer/countdown-timer.js.map +1 -1
  265. package/countdown-timer/countdown-timer.styles_ipn1b0.css +2 -2
  266. package/countdown-timer/types.d.ts +55 -11
  267. package/dashed-border/dashed-border.d.ts +6 -0
  268. package/dashed-border/dashed-border.js.map +1 -1
  269. package/dashed-border/dashed-border.styles_zszoox.css +2 -2
  270. package/dashed-border/types.d.ts +27 -5
  271. package/data-table/data-table.d.ts +8 -0
  272. package/data-table/data-table.js.map +1 -1
  273. package/data-table/data-table.styles_1iqq1g7.css +2 -2
  274. package/data-table/types.d.ts +58 -12
  275. package/date-input/date-input.d.ts +5 -0
  276. package/date-input/date-input.js.map +1 -1
  277. package/date-input/date-input.styles_1r5kcc7.css +1 -1
  278. package/date-input/types.d.ts +32 -16
  279. package/date-navigator/date-navigator.d.ts +6 -0
  280. package/date-navigator/date-navigator.js.map +1 -1
  281. package/date-navigator/date-navigator.styles_wokh56.css +2 -2
  282. package/date-navigator/types.d.ts +44 -7
  283. package/date-range-input/date-range-input.d.ts +4 -0
  284. package/date-range-input/date-range-input.js.map +1 -1
  285. package/date-range-input/date-range-input.styles_1s7ojnj.css +2 -2
  286. package/date-range-input/types.d.ts +50 -14
  287. package/divider/divider.d.ts +6 -0
  288. package/divider/divider.js.map +1 -1
  289. package/divider/divider.styles_1xpzh8p.css +2 -2
  290. package/divider/types.d.ts +27 -4
  291. package/drawer/drawer.d.ts +7 -0
  292. package/drawer/drawer.js.map +1 -1
  293. package/drawer/drawer.styles_94hx3y.css +2 -2
  294. package/drawer/types.d.ts +16 -4
  295. package/e-signature/e-signature-canvas.js +1 -1
  296. package/e-signature/e-signature-canvas.js.map +1 -1
  297. package/e-signature/e-signature.d.ts +5 -0
  298. package/e-signature/e-signature.js.map +1 -1
  299. package/e-signature/e-signature.styles_lukd9f.css +2 -2
  300. package/e-signature/types.d.ts +23 -1
  301. package/error-display/error-display.d.ts +7 -0
  302. package/error-display/error-display.js.map +1 -1
  303. package/error-display/error-display.styles_d3tql1.css +2 -2
  304. package/error-display/types.d.ts +36 -6
  305. package/external/dompurify/dist/purify.es.js +2 -2
  306. package/external/dompurify/dist/purify.es.js.map +1 -1
  307. package/feedback-rating/feedback-rating-stars-container.styles_dmi8z9.css +2 -2
  308. package/feedback-rating/feedback-rating.d.ts +6 -0
  309. package/feedback-rating/feedback-rating.js.map +1 -1
  310. package/feedback-rating/feedback-rating.styles_1kdklb6.css +2 -2
  311. package/feedback-rating/types.d.ts +29 -0
  312. package/file-download/file-download.d.ts +6 -0
  313. package/file-download/file-download.js.map +1 -1
  314. package/file-download/file-download.styles_iggk8q.css +2 -2
  315. package/file-download/file-list-card/file-list-card.styles.js +1 -1
  316. package/file-download/file-list-card/file-list-card.styles.js.map +1 -1
  317. package/file-download/file-list-card/{file-list-card.styles_oom8ii.css → file-list-card.styles_18j2gut.css} +3 -3
  318. package/file-download/types.d.ts +44 -11
  319. package/file-upload/dropzone.styles_1pllsau.css +2 -2
  320. package/file-upload/file-item-edit.d.ts +4 -1
  321. package/file-upload/file-item-edit.js +1 -1
  322. package/file-upload/file-item-edit.js.map +1 -1
  323. package/file-upload/file-item-edit.styles.d.ts +1 -0
  324. package/file-upload/file-item-edit.styles.js +1 -1
  325. package/file-upload/file-item-edit.styles.js.map +1 -1
  326. package/file-upload/{file-item-edit.styles_1qbpbxj.css → file-item-edit.styles_19bvztn.css} +6 -5
  327. package/file-upload/file-list/file-list.d.ts +3 -0
  328. package/file-upload/file-list/file-list.js +1 -1
  329. package/file-upload/file-list/file-list.js.map +1 -1
  330. package/file-upload/file-list/file-list.styles.js +1 -1
  331. package/file-upload/file-list/file-list.styles.js.map +1 -1
  332. package/file-upload/file-list/file-list.styles_1w7so98.css +3 -0
  333. package/file-upload/file-list-item/file-list-item-thumbnail.styles_1y4si19.css +2 -2
  334. package/file-upload/file-list-item/file-list-item.d.ts +3 -1
  335. package/file-upload/file-list-item/file-list-item.js +1 -1
  336. package/file-upload/file-list-item/file-list-item.js.map +1 -1
  337. package/file-upload/file-list-item/file-list-item.styles.d.ts +3 -0
  338. package/file-upload/file-list-item/file-list-item.styles.js +1 -1
  339. package/file-upload/file-list-item/file-list-item.styles.js.map +1 -1
  340. package/file-upload/file-list-item/file-list-item.styles_o8000f.css +17 -0
  341. package/file-upload/file-upload.d.ts +2 -1
  342. package/file-upload/file-upload.js +1 -1
  343. package/file-upload/file-upload.js.map +1 -1
  344. package/file-upload/file-upload.styles_9ffwcd.css +2 -2
  345. package/file-upload/types.d.ts +125 -20
  346. package/filter/addons/filter-item-checkbox.styles_7degw7.css +2 -2
  347. package/filter/filter-item-page.styles_17ewfrz.css +1 -1
  348. package/filter/filter-item.js.map +1 -1
  349. package/filter/filter-item.styles_cphjnj.css +2 -2
  350. package/filter/filter-modal.styles_qw3xlg.css +2 -2
  351. package/filter/filter-sidebar.styles_1otwpjl.css +2 -2
  352. package/filter/filter.d.ts +21 -0
  353. package/filter/filter.js.map +1 -1
  354. package/filter/filter.styles_1ykijwm.css +2 -2
  355. package/filter/types.d.ts +161 -21
  356. package/footer/footer-download-app.styles_1v1j2us.css +2 -2
  357. package/footer/footer-resource-addon.styles_1jepb1d.css +2 -2
  358. package/footer/footer.d.ts +8 -1
  359. package/footer/footer.js +1 -1
  360. package/footer/footer.js.map +1 -1
  361. package/footer/footer.styles_1msorhc.css +2 -2
  362. package/footer/types.d.ts +55 -4
  363. package/form/form-label-addon.styles_b00z8p.css +1 -1
  364. package/form/form-label.styles.js +1 -1
  365. package/form/form-label.styles.js.map +1 -1
  366. package/form/{form-label.styles_11r0652.css → form-label.styles_1nbe0bm.css} +2 -2
  367. package/form/form-textarea.styles_3p9qoy.css +2 -2
  368. package/form/form-wrapper.styles_199rslu.css +1 -1
  369. package/fullscreen-image-carousel/fullscreen-image-carousel.styles_vc6y5c.css +2 -2
  370. package/fullscreen-image-carousel/stateful-image.styles_1xe8ypm.css +2 -2
  371. package/histogram-slider/histogram-slider.styles_wvd4w.css +2 -2
  372. package/image-button/image-button.styles_6n1qsr.css +2 -2
  373. package/index.d.ts +0 -1
  374. package/index.js +1 -1
  375. package/input/input.styles_1cblor0.css +2 -2
  376. package/input-group/input-group-list-addon.styles_17iuqtw.css +2 -2
  377. package/input-group/input-group.styles_bqye6f.css +2 -2
  378. package/input-range-select/input-range-select.styles_adbrbm.css +2 -2
  379. package/input-range-slider/input-range-slider.styles_aljl2v.css +2 -2
  380. package/input-textarea/textarea-counter.styles_1n3wsnv.css +1 -1
  381. package/input-textarea/textarea.styles_22z4n3.css +2 -2
  382. package/language-switcher/dropdown-panel.styles_1qsjf8d.css +2 -2
  383. package/language-switcher/dropdown-variant.styles_1vrdfky.css +2 -2
  384. package/language-switcher/link-container-variant.styles_1iw6zux.css +2 -2
  385. package/layout/col-div.styles_16o6mwx.css +1 -1
  386. package/layout/container.styles_v70ec6.css +2 -2
  387. package/layout/section.styles_hstcaf.css +1 -1
  388. package/link-list/link-list.styles_m57vks.css +2 -2
  389. package/local-nav/local-nav-dropdown/local-nav-dropdown.styles_uhd4xl.css +2 -2
  390. package/local-nav/local-nav-menu/local-nav-menu.styles_pq19dh.css +2 -2
  391. package/markup/markup.style_1iu40x9.css +2 -2
  392. package/masked-input/masked-input.styles_1cm388a.css +2 -2
  393. package/masthead/masthead.styles_1huzon9.css +2 -2
  394. package/menu/menu-content.styles_p7ijll.css +2 -2
  395. package/menu/menu-item.styles_liyed8.css +2 -2
  396. package/menu/menu-link.styles_hfxoez.css +2 -2
  397. package/menu/menu-section.styles_g7my4d.css +2 -2
  398. package/modal/modal-box.styles_y52cts.css +2 -2
  399. package/modal/modal.styles_1lbblx6.css +2 -2
  400. package/modal-v2/modal-v2.styles_a8gv5i.css +2 -2
  401. package/modal-v2/slots/slot-styles_13sd376.css +2 -2
  402. package/navbar/brand.styles_zcgddp.css +1 -1
  403. package/navbar/drawer.js +1 -1
  404. package/navbar/drawer.js.map +1 -1
  405. package/navbar/drawer.styles_7hnxp5.css +2 -2
  406. package/navbar/menu.styles_gdpqc.css +2 -2
  407. package/navbar/navbar-action-buttons.styles_1vpm0nk.css +2 -2
  408. package/navbar/navbar-items.styles_1i3ltot.css +2 -2
  409. package/navbar/navbar.js +1 -1
  410. package/navbar/navbar.js.map +1 -1
  411. package/navbar/navbar.styles_koy0c7.css +2 -2
  412. package/notification-banner/notification-banner.styles_uxlysy.css +2 -2
  413. package/otp-input/otp-input.styles_5sbutl.css +2 -2
  414. package/otp-verification/contact-input-section.styles_odrjvt.css +2 -2
  415. package/otp-verification/otp-verification.styles_dg9bm8.css +1 -1
  416. package/otp-verification/thumbnail/thumbnail.styles_shqylh.css +2 -2
  417. package/otp-verification/verification-section.styles_x8jj.css +2 -2
  418. package/overlay/overlay.js +1 -1
  419. package/overlay/overlay.js.map +1 -1
  420. package/overlay/overlay.styles_12wym18.css +2 -2
  421. package/overlay/types.d.ts +0 -13
  422. package/package.json +1 -7
  423. package/pagination/pagination.styles_6bcgva.css +2 -2
  424. package/pill/pill.styles_xwrniu.css +2 -2
  425. package/popover/popover-inline/popover-inline.styles_bkopnt.css +2 -2
  426. package/popover/popover-trigger.styles_8zokig.css +1 -1
  427. package/popover/popover.styles_ujnf0h.css +2 -2
  428. package/progress-indicator/progress-indicator.styles_1c038s4.css +2 -2
  429. package/radio-button/radio-button.styles_1c4v6v.css +2 -2
  430. package/schedule/schedule-day-view/schedule-day-view.styles_8ti149.css +2 -2
  431. package/schedule/schedule-header/schedule-header.js +1 -1
  432. package/schedule/schedule-header/schedule-header.js.map +1 -1
  433. package/schedule/schedule-header/schedule-header.styles_1n2u5vj.css +2 -2
  434. package/schedule/schedule-week-view/schedule-week-view.styles_x7x50m.css +2 -2
  435. package/schedule/schedule-week-view/time-cell.styles_1sorjz8.css +2 -2
  436. package/schedule/schedule.styles_fdy5a1.css +2 -2
  437. package/schedule/shared/with-optional-popover.styles_7mv3p2.css +1 -1
  438. package/schedule/time-indicator/time-indicator.styles_1eaxyes.css +2 -2
  439. package/select-histogram/select-histogram.styles_n260dy.css +2 -2
  440. package/shared/accessibility/index_13g9vp.css +1 -1
  441. package/shared/clickable-icon/clickable-icon.styles_1v2imml.css +2 -2
  442. package/shared/component-loading-spinner/component-loading-spinner.styles_15eq02i.css +2 -2
  443. package/shared/dropdown-list/dropdown-label.styles_mloii0.css +2 -2
  444. package/shared/dropdown-list/dropdown-list.styles_konwm.css +2 -2
  445. package/shared/dropdown-list/dropdown-search.styles_1hc1gkh.css +2 -2
  446. package/shared/dropdown-list/expandable-element.styles_rkkvqr.css +2 -2
  447. package/shared/dropdown-list/nested-dropdown-list.styles_wdhxoe.css +2 -2
  448. package/shared/dropdown-wrapper/dropdown-wrapper.styles_15hwwoj.css +2 -2
  449. package/shared/fade-wrapper/fade-wrapper.styles_16iug7l.css +2 -2
  450. package/shared/image-placeholder/image-placeholder.styles_44nwil.css +1 -1
  451. package/shared/input-wrapper/input-wrapper.styles_je6maw.css +2 -2
  452. package/shared/internal-calendar/calendar-dropdown.styles_wybjai.css +1 -1
  453. package/shared/internal-calendar/calendar-manager.js +1 -1
  454. package/shared/internal-calendar/calendar-manager.js.map +1 -1
  455. package/shared/internal-calendar/calendar-manager.styles.js +1 -1
  456. package/shared/internal-calendar/calendar-manager.styles.js.map +1 -1
  457. package/shared/internal-calendar/{calendar-manager.styles_1iuq5zw.css → calendar-manager.styles_1njwkj2.css} +3 -3
  458. package/shared/internal-calendar/day-cell/day-cell.styles_1t5oqc1.css +2 -2
  459. package/shared/internal-calendar/internal-calendar-month.styles_14oh57f.css +2 -2
  460. package/shared/internal-calendar/internal-calendar-year.styles_therlc.css +2 -2
  461. package/shared/internal-calendar/internal-calendar.styles_gnc3eq.css +1 -1
  462. package/shared/internal-calendar/standard/standard-calendar-day-view.styles_1bw26au.css +2 -2
  463. package/shared/progress-bar/progress-bar.styles_125ri7a.css +1 -1
  464. package/shared/range-input-inner-container/range-input-inner-container.styles_1v61utg.css +2 -2
  465. package/shared/standalone-date-input/standalone-date-input.styles_157qo89.css +2 -2
  466. package/shared/time-slot/time-slot.styles_18s0to7.css +2 -2
  467. package/shared/timepicker-dropdown/timepicker-dropdown.styles_119l6k6.css +2 -2
  468. package/sidenav/sidenav-drawer-item.styles_1ljnyx2.css +2 -2
  469. package/sidenav/sidenav-drawer-subitem.styles_2y58kf.css +1 -1
  470. package/sidenav/sidenav-group.styles_1x604sw.css +2 -2
  471. package/sidenav/sidenav-item.styles_lqw3kh.css +2 -2
  472. package/sidenav/sidenav.styles_1vxezie.css +2 -2
  473. package/singpass-button/singpass-button.styles_1miyex3.css +2 -2
  474. package/smart-app-banner/smart-app-banner.styles_15u6yv4.css +2 -2
  475. package/tab/tab-link-chain.styles_49got4.css +2 -2
  476. package/tab/tab.styles_1najffw.css +1 -1
  477. package/table/table.styles_1af5ipv.css +2 -2
  478. package/tag/tag.style_d98c53.css +2 -2
  479. package/text-list/text-list.styles_w3fvyt.css +2 -2
  480. package/theme/styles/a11y-playground.css +3 -0
  481. package/theme/styles/bookingsg.css +7 -4
  482. package/theme/styles/careercompass.css +4 -1
  483. package/theme/styles/ccube.css +3 -0
  484. package/theme/styles/default.css +9 -5
  485. package/theme/styles/imda.css +3 -0
  486. package/theme/styles/lifesg.css +3 -0
  487. package/theme/styles/mylegacy.css +7 -4
  488. package/theme/styles/oneservice.css +52 -0
  489. package/theme/styles/pa.css +3 -0
  490. package/theme/styles/rbs.css +3 -0
  491. package/theme/styles/sgw-digital-lobby.css +5 -2
  492. package/theme/styles/smgs.css +3 -0
  493. package/theme/styles/spf.css +3 -0
  494. package/theme/styles/supportgowhere.css +3 -0
  495. package/theme/types.d.ts +1 -1
  496. package/theme/types.js +1 -1
  497. package/theme/types.js.map +1 -1
  498. package/theme/utils/index.d.ts +1 -0
  499. package/theme/utils/use-design-token-override.d.ts +11 -0
  500. package/theme/utils/use-design-token-override.js +2 -0
  501. package/theme/utils/use-design-token-override.js.map +1 -0
  502. package/time-range-picker/combobox-picker/combobox-picker.styles_7i9vso.css +1 -1
  503. package/time-range-picker/common.styles_1qwp4xa.css +2 -2
  504. package/time-slot-bar/time-slot-bar.styles_wigbyd.css +2 -2
  505. package/time-slot-bar-week/time-slot-bar-week-days.styles_evdvs9.css +2 -2
  506. package/time-slot-bar-week/time-slot-bar-week.styles_11ybf42.css +1 -1
  507. package/time-slot-week-view/time-slot-week-days.styles_1h21vyw.css +2 -2
  508. package/time-slot-week-view/time-slot-week-view.styles_gqgsw2.css +1 -1
  509. package/timeline/timeline.styles_1jxzik4.css +2 -2
  510. package/timepicker/timepicker.styles_1jm33yw.css +1 -1
  511. package/timetable/timetable-header/timetable-header.styles_11gl1h4.css +2 -2
  512. package/timetable/timetable-row/row-bar.styles_1x0vrsz.css +1 -1
  513. package/timetable/timetable-row/row-cell.styles_y1dl5j.css +2 -2
  514. package/timetable/timetable.styles_7rp8kz.css +2 -2
  515. package/toast/toast.styles_1e0l60w.css +2 -2
  516. package/toggle/toggle-icon.styles_ba71y.css +2 -2
  517. package/toggle/toggle.styles_1t5qrye.css +2 -2
  518. package/typography/typography-text.styles_1734x2k.css +2 -2
  519. package/typography/typography.styles.js +1 -1
  520. package/typography/typography.styles.js.map +1 -1
  521. package/typography/{typography.styles_1155j4c.css → typography.styles_1wd82dn.css} +2 -2
  522. package/uneditable-section/index.d.ts +1 -1
  523. package/uneditable-section/section-item.styles_mwx8ht.css +2 -2
  524. package/uneditable-section/uneditable-section.d.ts +2 -1
  525. package/uneditable-section/uneditable-section.js +1 -1
  526. package/uneditable-section/uneditable-section.js.map +1 -1
  527. package/uneditable-section/uneditable-section.styles_aj9zun.css +2 -2
  528. package/unit-number/unit-number-input.styles_8yizj.css +2 -2
  529. package/cjs/example/example.js +0 -2
  530. package/cjs/example/example.js.map +0 -1
  531. package/cjs/example/example_r47nvz.css +0 -1
  532. package/cjs/example/index.js +0 -2
  533. package/cjs/example/index.js.map +0 -1
  534. package/cjs/file-upload/file-list/file-list.styles_1ea12kj.css +0 -3
  535. package/cjs/file-upload/file-list-item/file-list-item.styles_y7my2m.css +0 -14
  536. package/example/example.d.ts +0 -2
  537. package/example/example.js +0 -2
  538. package/example/example.js.map +0 -1
  539. package/example/example_r47nvz.css +0 -1
  540. package/example/index.d.ts +0 -1
  541. package/example/index.js +0 -2
  542. package/example/index.js.map +0 -1
  543. package/example/types.d.ts +0 -3
  544. package/file-upload/file-list/file-list.styles_1ea12kj.css +0 -3
  545. package/file-upload/file-list-item/file-list-item.styles_y7my2m.css +0 -14
@@ -1 +1 @@
1
- {"version":3,"file":"file-list.js","sources":["../../../src/file-upload/file-list/file-list.tsx"],"sourcesContent":["import type { DragEndEvent, DragStartEvent } from \"@dnd-kit/core\";\nimport {\n DndContext,\n KeyboardSensor,\n TouchSensor,\n useSensor,\n useSensors,\n} from \"@dnd-kit/core\";\nimport {\n arrayMove,\n SortableContext,\n sortableKeyboardCoordinates,\n verticalListSortingStrategy,\n} from \"@dnd-kit/sortable\";\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\";\nimport { useResizeDetector } from \"react-resize-detector\";\n\nimport { VisuallyHidden } from \"../../shared/accessibility\";\nimport { FileUploadContext } from \"../context\";\nimport { MouseSensor } from \"../custom-sensors\";\nimport { FileItemEdit } from \"../file-item-edit\";\nimport { FileListItem } from \"../file-list-item\";\nimport { FileUploadHelper } from \"../helper\";\nimport type { FileItemProps } from \"../types\";\nimport * as styles from \"./file-list.styles\";\n\n// =============================================================================\n// INTERFACES\n// =============================================================================\ntype RenderMode = \"edit\" | \"display\" | \"error\";\n\ntype FileItemRenderModes = Record<string, RenderMode>;\ntype FileEditedDescriptions = Record<string, string>;\n\ntype RenderItem = FileItemProps | FileItemProps[];\n\ninterface Props {\n fileItems: FileItemProps[] | undefined;\n editableFileItems: boolean;\n fileDescriptionMaxLength?: number | undefined;\n sortable?: boolean | undefined;\n disabled?: boolean | undefined;\n readOnly?: boolean | undefined;\n onItemUpdate: (item: FileItemProps) => void;\n onItemDelete: (item: FileItemProps) => void;\n onSort?: ((reorderedFileItems: FileItemProps[]) => void) | undefined;\n}\n\ntype AnnouncementProgress = Record<\n string,\n {\n progress: number;\n timestamp: number;\n status: \"in-progress\" | \"complete\" | \"error\";\n }\n>;\n\nexport interface FileListRef {\n focus: () => void;\n}\n\n// =============================================================================\n// COMPONENT\n// =============================================================================\n\nfunction Component(\n {\n fileItems = [],\n editableFileItems,\n fileDescriptionMaxLength,\n sortable,\n disabled,\n readOnly,\n onItemUpdate,\n onItemDelete,\n onSort,\n }: Props,\n ref: React.Ref<FileListRef>\n) {\n // =========================================================================\n // CONST, STATE, REFS\n // =========================================================================\n const [renderModes, setRenderModes] = useState<FileItemRenderModes>({});\n const { setActiveId } = useContext(FileUploadContext);\n\n // Progress announcement state (for aria-live) - announces start and completion only\n const [progressAnnouncement, setProgressAnnouncement] = useState(\"\");\n const lastAnnouncedRef = useRef<AnnouncementProgress>({});\n\n useImperativeHandle(ref, () => ({\n focus: () => {\n wrapperRef.current?.focus();\n },\n }));\n const { width: wrapperWidth = 0, ref: wrapperRef } = useResizeDetector();\n\n // Keep track of edited description without re-rendering\n const descriptionsValueRef = useRef<FileEditedDescriptions>({});\n\n /**\n * As the default drag sensors interfere with click events\n * on the file items, we'll need to configure the sensor to\n * only activate the drag if the mouse moves a certain distance\n */\n const sensors = useSensors(\n useSensor(MouseSensor, {\n activationConstraint: {\n distance: 8, // mouse drag of 8px then activate the drag event\n },\n }),\n useSensor(TouchSensor, {\n activationConstraint: {\n delay: 150,\n tolerance: 5,\n },\n }),\n useSensor(KeyboardSensor, {\n coordinateGetter: sortableKeyboardCoordinates,\n })\n );\n\n // =========================================================================\n // REF METHODS\n // =========================================================================\n const removeDescription = (itemId: string) => {\n delete descriptionsValueRef.current[itemId];\n };\n\n const shallowCompareRenderModes = (\n prev: FileItemRenderModes,\n next: FileItemRenderModes\n ) => {\n const prevKeys = Object.keys(prev);\n const nextKeys = Object.keys(next);\n if (prevKeys.length !== nextKeys.length) {\n return false;\n }\n for (const k of nextKeys) {\n if (prev[k] !== next[k]) {\n return false;\n }\n }\n return true;\n };\n\n // =========================================================================\n // EFFECTS\n // =========================================================================\n useEffect(() => {\n const nextModes = getItemsRenderMode(fileItems);\n const prevModes = renderModes;\n // We perform shallowCompare to avoid infinite re-render loop\n if (shallowCompareRenderModes(prevModes, nextModes)) {\n return;\n }\n setRenderModes(nextModes);\n }, [fileItems, editableFileItems, readOnly]);\n\n // Progress announcements only at start and completion\n useEffect(() => {\n if (!fileItems || fileItems.length === 0) {\n setProgressAnnouncement(\"\");\n return;\n }\n const now = Date.now();\n const messages: string[] = [];\n\n for (const item of fileItems) {\n const fileStatus = lastAnnouncedRef.current[item.id];\n\n if (item.errorMessage) {\n if (fileStatus?.status !== \"error\") {\n messages.push(\n typeof item.errorMessage === \"string\"\n ? `Error uploading ${item.name}: ${item.errorMessage}`\n : `Error uploading ${item.name}`\n );\n lastAnnouncedRef.current[item.id] = {\n progress: item.progress ?? 1,\n timestamp: now,\n status: \"error\",\n };\n }\n continue;\n }\n\n if (item.progress === undefined) {\n continue;\n }\n\n if (item.progress >= 1) {\n if (fileStatus?.status !== \"complete\") {\n messages.push(`${item.name} upload is complete`);\n lastAnnouncedRef.current[item.id] = {\n progress: 1,\n timestamp: now,\n status: \"complete\",\n };\n }\n continue;\n }\n\n // In progress - only announce start, not progress updates\n if (typeof item.progress === \"number\" && item.progress < 1) {\n // Only announce when starting upload (no previous status or status was not in-progress)\n const shouldAnnounce =\n !fileStatus || fileStatus.status !== \"in-progress\";\n\n if (shouldAnnounce) {\n messages.push(`Starting upload of ${item.name}`);\n lastAnnouncedRef.current[item.id] = {\n progress: item.progress,\n timestamp: now,\n status: \"in-progress\",\n };\n }\n }\n }\n\n if (messages.length > 0) {\n // Update aria-live region once with aggregated message\n setProgressAnnouncement(messages.join(\", \"));\n }\n }, [fileItems]);\n\n // =========================================================================\n // EVENT HANDLERS\n // =========================================================================\n const handleSaveEdit = (item: FileItemProps) => (description: string) => {\n updateRenderModes(item.id, \"display\");\n removeDescription(item.id);\n\n const updatedItem = { ...item, description };\n onItemUpdate(updatedItem);\n };\n\n const handleBlurEdit = (item: FileItemProps) => (value: string) => {\n descriptionsValueRef.current[item.id] = value;\n };\n\n const handleCancel = (item: FileItemProps) => () => {\n if (!item.description || item.description.length === 0) {\n // New addition\n onItemDelete(item);\n } else {\n updateRenderModes(item.id, \"display\");\n }\n removeDescription(item.id);\n };\n\n const handleInitiateEdit = (item: FileItemProps) => () => {\n updateRenderModes(item.id, \"edit\");\n };\n\n const handleDelete = (item: FileItemProps) => () => {\n onItemDelete(item);\n if (wrapperRef.current) {\n wrapperRef.current.focus();\n }\n };\n\n const handleDragEnd = (event: DragEndEvent) => {\n if (onSort && fileItems) {\n const { active, over } = event;\n\n if (over && active.id !== over.id) {\n const oldIndex = fileItems.findIndex(\n (item) => item.id === active.id\n );\n const newIndex = fileItems.findIndex(\n (item) => item.id === over.id\n );\n\n const updatedFileItems = arrayMove(\n fileItems,\n oldIndex,\n newIndex\n );\n\n onSort(updatedFileItems);\n }\n }\n\n setActiveId(undefined);\n };\n\n const handleDragStart = (event: DragStartEvent) => {\n const { active } = event;\n setActiveId(active.id as string);\n };\n\n // =========================================================================\n // HELPER FUNCTIONS\n // =========================================================================\n const checkEditable = (item: FileItemProps) => {\n return (\n editableFileItems &&\n FileUploadHelper.isSupportedImageType(item.type)\n );\n };\n\n const shouldRenderEditMode = (item: FileItemProps) => {\n return (\n !item.errorMessage &&\n !readOnly &&\n !(typeof item.progress === \"number\" && item.progress < 1) &&\n checkEditable(item) &&\n !item.description\n );\n };\n\n const getItemsRenderMode = (\n fileItems: FileItemProps[] | undefined\n ): FileItemRenderModes => {\n if (!fileItems || fileItems.length === 0) return {};\n\n const newRenderModes: FileItemRenderModes = {};\n\n for (const item of fileItems) {\n if (item.errorMessage) {\n newRenderModes[item.id] = \"error\";\n } else if (!renderModes[item.id]) {\n newRenderModes[item.id] = shouldRenderEditMode(item)\n ? \"edit\"\n : \"display\";\n } else {\n newRenderModes[item.id] = renderModes[item.id];\n }\n }\n\n return newRenderModes;\n };\n\n const updateRenderModes = (itemId: string, mode: RenderMode) => {\n setRenderModes((prevRenderModes) => {\n return {\n ...prevRenderModes,\n [itemId]: mode,\n };\n });\n };\n\n /**\n * Due to a UI requirement, we will render the items\n * with edit modes as a group\n */\n const getArrangedItems = (\n fileItems: FileItemProps[] | undefined,\n renderModes: FileItemRenderModes\n ) => {\n if (!fileItems || fileItems.length === 0) return [];\n\n const arrangedItems: RenderItem[] = [];\n\n for (const fileItem of fileItems) {\n if (renderModes[fileItem.id] === \"edit\") {\n const previousElement = arrangedItems[arrangedItems.length - 1];\n if (Array.isArray(previousElement)) {\n previousElement.push(fileItem);\n } else {\n arrangedItems.push([fileItem]);\n }\n } else {\n arrangedItems.push(fileItem);\n }\n }\n\n return arrangedItems;\n };\n\n const areAllItemsInDisplayViews = () => {\n return Object.values(renderModes).every((mode) => mode === \"display\");\n };\n\n const shouldEnableSort = () => {\n return (\n fileItems &&\n fileItems.length > 1 &&\n sortable &&\n areAllItemsInDisplayViews()\n );\n };\n\n /**\n * If there are no files, return \"No files uploaded\".\n * If readOnly is true, return \"Read-only file list\".\n * If there are files, return a summary of the file statuses.\n * For example, \"File list. 2 completed files, 1 file in progress, 1 file with error\".\n *\n * @returns aria label\n */\n const getWrapperAriaLabel = () => {\n if (fileItems.length === 0) {\n return \"No files uploaded\";\n }\n const completedCount = fileItems.filter(\n (item) =>\n !item?.errorMessage &&\n (item.progress === 1 || item.progress === undefined)\n ).length;\n const inProgressCount = fileItems.filter(\n (item) => typeof item.progress === \"number\" && item.progress < 1\n ).length;\n const errorCount = fileItems.filter((item) => item.errorMessage).length;\n if (completedCount === 0 && inProgressCount === 0 && errorCount === 0) {\n return `File list`;\n }\n const completedText =\n completedCount > 0 ? `${completedCount} completed files` : \"\";\n const inProgressText =\n inProgressCount > 0 ? `${inProgressCount} file in progress` : \"\";\n const errorText =\n errorCount > 0\n ? `${errorCount} ${\n errorCount > 1 ? \"files\" : \"file\"\n } with error`\n : \"\";\n const parts = [completedText, inProgressText, errorText].filter(\n Boolean\n );\n const prefix = readOnly ? \"Read-only file list\" : \"File list\";\n return `${prefix}. ${parts.join(\", \")}`;\n };\n\n // =========================================================================\n // RENDER FUNCTIONS\n // =========================================================================\n const renderItemsInEditMode = (\n fileItems: FileItemProps[],\n keyToUse: number\n ) => {\n const itemsToRender = fileItems.map((item) => {\n const updatedFileItem = { ...item };\n if (descriptionsValueRef.current[item.id] !== undefined) {\n updatedFileItem.description =\n descriptionsValueRef.current[item.id];\n }\n\n return (\n <FileItemEdit\n key={item.id}\n fileItem={updatedFileItem}\n wrapperWidth={wrapperWidth}\n fileDescriptionMaxLength={fileDescriptionMaxLength}\n onSave={handleSaveEdit(item)}\n onCancel={handleCancel(item)}\n onBlur={handleBlurEdit(item)}\n />\n );\n });\n\n return (\n <li\n key={`editable-${keyToUse}`}\n className={styles.editableItemsContainer}\n >\n <ul>{itemsToRender}</ul>\n </li>\n );\n };\n\n const renderItems = () => {\n const arrangedItems = getArrangedItems(fileItems, renderModes);\n\n if (arrangedItems.length === 0) return null;\n\n return arrangedItems.map((item, index) => {\n if (Array.isArray(item)) {\n return renderItemsInEditMode(item, index);\n } else {\n return (\n <FileListItem\n key={item.id}\n fileItem={item}\n editable={checkEditable(item)}\n wrapperWidth={wrapperWidth}\n sortable={shouldEnableSort()}\n disabled={disabled}\n readOnly={readOnly}\n onDelete={handleDelete(item)}\n onEditClick={handleInitiateEdit(item)}\n />\n );\n }\n });\n };\n\n /**\n * Renders the progress status of each file upload.\n * In progress: 25% complete for uploading filename.pdf\n * Complete: filename.pdf upload is complete\n * Error: Error uploading filename.pdf: error message\n *\n * @returns A visually hidden element announcing the progress status.\n */\n const renderProgressStatus = () => (\n <VisuallyHidden aria-live=\"polite\" aria-atomic=\"true\">\n {progressAnnouncement}\n </VisuallyHidden>\n );\n\n const renderItemsWithWrapper = () => {\n return (\n <>\n {renderProgressStatus()}\n <ul\n tabIndex={-1}\n className={clsx(\n styles.listWrapper,\n readOnly && styles.listWrapperReadOnly\n )}\n ref={wrapperRef}\n aria-label={getWrapperAriaLabel()}\n >\n {renderItems()}\n </ul>\n </>\n );\n };\n\n if (disabled || readOnly || !shouldEnableSort()) {\n return renderItemsWithWrapper();\n } else {\n return (\n <DndContext\n sensors={sensors}\n onDragEnd={handleDragEnd}\n onDragStart={handleDragStart}\n >\n <SortableContext\n items={fileItems}\n strategy={verticalListSortingStrategy}\n >\n {renderItemsWithWrapper()}\n </SortableContext>\n </DndContext>\n );\n }\n}\n\nexport const FileList = forwardRef<FileListRef, Props>(Component);\n"],"names":["FileList","forwardRef","fileItems","editableFileItems","fileDescriptionMaxLength","sortable","disabled","readOnly","onItemUpdate","onItemDelete","onSort","ref","renderModes","setRenderModes","useState","setActiveId","useContext","FileUploadContext","progressAnnouncement","setProgressAnnouncement","lastAnnouncedRef","useRef","useImperativeHandle","focus","_a","wrapperRef","current","width","wrapperWidth","useResizeDetector","descriptionsValueRef","sensors","useSensors","useSensor","MouseSensor","activationConstraint","distance","TouchSensor","delay","tolerance","KeyboardSensor","coordinateGetter","sortableKeyboardCoordinates","removeDescription","itemId","useEffect","nextModes","getItemsRenderMode","prev","next","prevKeys","Object","keys","nextKeys","length","k","shallowCompareRenderModes","now","Date","messages","item","fileStatus","id","errorMessage","status","push","name","progress","timestamp","undefined","join","handleSaveEdit","description","updateRenderModes","updatedItem","assign","handleBlurEdit","value","handleCancel","handleInitiateEdit","handleDelete","handleDragEnd","event","active","over","oldIndex","findIndex","newIndex","updatedFileItems","arrayMove","handleDragStart","checkEditable","FileUploadHelper","isSupportedImageType","type","shouldRenderEditMode","newRenderModes","mode","prevRenderModes","shouldEnableSort","values","every","getWrapperAriaLabel","completedCount","filter","inProgressCount","errorCount","parts","Boolean","renderItems","arrangedItems","fileItem","previousElement","Array","isArray","getArrangedItems","map","index","keyToUse","itemsToRender","updatedFileItem","_jsx","FileItemEdit","onSave","onCancel","onBlur","className","styles.editableItemsContainer","children","renderItemsInEditMode","FileListItem","editable","onDelete","onEditClick","renderItemsWithWrapper","_jsxs","_Fragment","VisuallyHidden","tabIndex","clsx","styles.listWrapper","styles.listWrapperReadOnly","DndContext","onDragEnd","onDragStart","SortableContext","items","strategy","verticalListSortingStrategy"],"mappings":"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"}
1
+ {"version":3,"file":"file-list.js","sources":["../../../src/file-upload/file-list/file-list.tsx"],"sourcesContent":["import type { DragEndEvent, DragStartEvent } from \"@dnd-kit/core\";\nimport {\n DndContext,\n KeyboardSensor,\n TouchSensor,\n useSensor,\n useSensors,\n} from \"@dnd-kit/core\";\nimport {\n arrayMove,\n SortableContext,\n sortableKeyboardCoordinates,\n verticalListSortingStrategy,\n} from \"@dnd-kit/sortable\";\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\";\nimport { useResizeDetector } from \"react-resize-detector\";\n\nimport type { FormLabelProps } from \"../../form/types\";\nimport { VisuallyHidden } from \"../../shared/accessibility\";\nimport { FileUploadContext } from \"../context\";\nimport { MouseSensor } from \"../custom-sensors\";\nimport { FileItemEdit } from \"../file-item-edit\";\nimport { FileListItem } from \"../file-list-item\";\nimport { FileUploadHelper } from \"../helper\";\nimport type { FileItemProps } from \"../types\";\nimport * as styles from \"./file-list.styles\";\n\n// =============================================================================\n// INTERFACES\n// =============================================================================\ntype RenderMode = \"edit\" | \"display\" | \"error\";\n\ntype FileItemRenderModes = Record<string, RenderMode>;\ntype FileEditedDescriptions = Record<string, string>;\n\ntype RenderItem = FileItemProps | FileItemProps[];\n\ninterface Props {\n fileItems: FileItemProps[] | undefined;\n editableFileItems: boolean;\n fileDescriptionMaxLength?: number | undefined;\n descriptionRequired?: boolean | undefined;\n descriptionLabel?: FormLabelProps | undefined;\n sortable?: boolean | undefined;\n disabled?: boolean | undefined;\n readOnly?: boolean | undefined;\n onItemUpdate: (item: FileItemProps) => void;\n onItemDelete: (item: FileItemProps) => void;\n onSort?: ((reorderedFileItems: FileItemProps[]) => void) | undefined;\n}\n\ntype AnnouncementProgress = Record<\n string,\n {\n progress: number;\n timestamp: number;\n status: \"in-progress\" | \"complete\" | \"error\";\n }\n>;\n\nexport interface FileListRef {\n focus: () => void;\n}\n\n// =============================================================================\n// COMPONENT\n// =============================================================================\n\nfunction Component(\n {\n fileItems = [],\n editableFileItems,\n fileDescriptionMaxLength,\n descriptionRequired,\n descriptionLabel,\n sortable,\n disabled,\n readOnly,\n onItemUpdate,\n onItemDelete,\n onSort,\n }: Props,\n ref: React.Ref<FileListRef>\n) {\n // =========================================================================\n // CONST, STATE, REFS\n // =========================================================================\n const [renderModes, setRenderModes] = useState<FileItemRenderModes>({});\n const { setActiveId } = useContext(FileUploadContext);\n\n // Progress announcement state (for aria-live) - announces start and completion only\n const [progressAnnouncement, setProgressAnnouncement] = useState(\"\");\n const lastAnnouncedRef = useRef<AnnouncementProgress>({});\n\n useImperativeHandle(ref, () => ({\n focus: () => {\n wrapperRef.current?.focus();\n },\n }));\n const { width: wrapperWidth = 0, ref: wrapperRef } = useResizeDetector();\n\n // Keep track of edited description without re-rendering\n const descriptionsValueRef = useRef<FileEditedDescriptions>({});\n\n /**\n * As the default drag sensors interfere with click events\n * on the file items, we'll need to configure the sensor to\n * only activate the drag if the mouse moves a certain distance\n */\n const sensors = useSensors(\n useSensor(MouseSensor, {\n activationConstraint: {\n distance: 8, // mouse drag of 8px then activate the drag event\n },\n }),\n useSensor(TouchSensor, {\n activationConstraint: {\n delay: 150,\n tolerance: 5,\n },\n }),\n useSensor(KeyboardSensor, {\n coordinateGetter: sortableKeyboardCoordinates,\n })\n );\n\n // =========================================================================\n // REF METHODS\n // =========================================================================\n const removeDescription = (itemId: string) => {\n delete descriptionsValueRef.current[itemId];\n };\n\n const shallowCompareRenderModes = (\n prev: FileItemRenderModes,\n next: FileItemRenderModes\n ) => {\n const prevKeys = Object.keys(prev);\n const nextKeys = Object.keys(next);\n if (prevKeys.length !== nextKeys.length) {\n return false;\n }\n for (const k of nextKeys) {\n if (prev[k] !== next[k]) {\n return false;\n }\n }\n return true;\n };\n\n // =========================================================================\n // EFFECTS\n // =========================================================================\n useEffect(() => {\n const nextModes = getItemsRenderMode(fileItems);\n const prevModes = renderModes;\n // We perform shallowCompare to avoid infinite re-render loop\n if (shallowCompareRenderModes(prevModes, nextModes)) {\n return;\n }\n setRenderModes(nextModes);\n }, [fileItems, editableFileItems, readOnly]);\n\n // Progress announcements only at start and completion\n useEffect(() => {\n if (!fileItems || fileItems.length === 0) {\n setProgressAnnouncement(\"\");\n return;\n }\n const now = Date.now();\n const messages: string[] = [];\n\n for (const item of fileItems) {\n const fileStatus = lastAnnouncedRef.current[item.id];\n\n if (item.errorMessage) {\n if (fileStatus?.status !== \"error\") {\n messages.push(\n typeof item.errorMessage === \"string\"\n ? `Error uploading ${item.name}: ${item.errorMessage}`\n : `Error uploading ${item.name}`\n );\n lastAnnouncedRef.current[item.id] = {\n progress: item.progress ?? 1,\n timestamp: now,\n status: \"error\",\n };\n }\n continue;\n }\n\n if (item.progress === undefined) {\n continue;\n }\n\n if (item.progress >= 1) {\n if (fileStatus?.status !== \"complete\") {\n messages.push(`${item.name} upload is complete`);\n lastAnnouncedRef.current[item.id] = {\n progress: 1,\n timestamp: now,\n status: \"complete\",\n };\n }\n continue;\n }\n\n // In progress - only announce start, not progress updates\n if (typeof item.progress === \"number\" && item.progress < 1) {\n // Only announce when starting upload (no previous status or status was not in-progress)\n const shouldAnnounce =\n !fileStatus || fileStatus.status !== \"in-progress\";\n\n if (shouldAnnounce) {\n messages.push(`Starting upload of ${item.name}`);\n lastAnnouncedRef.current[item.id] = {\n progress: item.progress,\n timestamp: now,\n status: \"in-progress\",\n };\n }\n }\n }\n\n if (messages.length > 0) {\n // Update aria-live region once with aggregated message\n setProgressAnnouncement(messages.join(\", \"));\n }\n }, [fileItems]);\n\n // =========================================================================\n // EVENT HANDLERS\n // =========================================================================\n const handleSaveEdit = (item: FileItemProps) => (description: string) => {\n updateRenderModes(item.id, \"display\");\n removeDescription(item.id);\n\n const updatedItem = { ...item, description };\n onItemUpdate(updatedItem);\n };\n\n const handleBlurEdit = (item: FileItemProps) => (value: string) => {\n descriptionsValueRef.current[item.id] = value;\n };\n\n const handleCancel = (item: FileItemProps) => () => {\n if (!item.description || item.description.length === 0) {\n // New addition\n onItemDelete(item);\n } else {\n updateRenderModes(item.id, \"display\");\n }\n removeDescription(item.id);\n };\n\n const handleInitiateEdit = (item: FileItemProps) => () => {\n updateRenderModes(item.id, \"edit\");\n };\n\n const handleDelete = (item: FileItemProps) => () => {\n onItemDelete(item);\n if (wrapperRef.current) {\n wrapperRef.current.focus();\n }\n };\n\n const handleDragEnd = (event: DragEndEvent) => {\n if (onSort && fileItems) {\n const { active, over } = event;\n\n if (over && active.id !== over.id) {\n const oldIndex = fileItems.findIndex(\n (item) => item.id === active.id\n );\n const newIndex = fileItems.findIndex(\n (item) => item.id === over.id\n );\n\n const updatedFileItems = arrayMove(\n fileItems,\n oldIndex,\n newIndex\n );\n\n onSort(updatedFileItems);\n }\n }\n\n setActiveId(undefined);\n };\n\n const handleDragStart = (event: DragStartEvent) => {\n const { active } = event;\n setActiveId(active.id as string);\n };\n\n // =========================================================================\n // HELPER FUNCTIONS\n // =========================================================================\n const checkEditable = (item: FileItemProps) => {\n return (\n editableFileItems &&\n FileUploadHelper.isSupportedImageType(item.type)\n );\n };\n\n const shouldRenderEditMode = (item: FileItemProps) => {\n return (\n !item.errorMessage &&\n !readOnly &&\n !(typeof item.progress === \"number\" && item.progress < 1) &&\n checkEditable(item) &&\n !item.description\n );\n };\n\n const getItemsRenderMode = (\n fileItems: FileItemProps[] | undefined\n ): FileItemRenderModes => {\n if (!fileItems || fileItems.length === 0) return {};\n\n const newRenderModes: FileItemRenderModes = {};\n\n for (const item of fileItems) {\n if (item.errorMessage) {\n newRenderModes[item.id] = \"error\";\n } else if (!renderModes[item.id]) {\n newRenderModes[item.id] = shouldRenderEditMode(item)\n ? \"edit\"\n : \"display\";\n } else {\n newRenderModes[item.id] = renderModes[item.id];\n }\n }\n\n return newRenderModes;\n };\n\n const updateRenderModes = (itemId: string, mode: RenderMode) => {\n setRenderModes((prevRenderModes) => {\n return {\n ...prevRenderModes,\n [itemId]: mode,\n };\n });\n };\n\n /**\n * Due to a UI requirement, we will render the items\n * with edit modes as a group\n */\n const getArrangedItems = (\n fileItems: FileItemProps[] | undefined,\n renderModes: FileItemRenderModes\n ) => {\n if (!fileItems || fileItems.length === 0) return [];\n\n const arrangedItems: RenderItem[] = [];\n\n for (const fileItem of fileItems) {\n if (renderModes[fileItem.id] === \"edit\") {\n const previousElement = arrangedItems[arrangedItems.length - 1];\n if (Array.isArray(previousElement)) {\n previousElement.push(fileItem);\n } else {\n arrangedItems.push([fileItem]);\n }\n } else {\n arrangedItems.push(fileItem);\n }\n }\n\n return arrangedItems;\n };\n\n const areAllItemsInDisplayViews = () => {\n return Object.values(renderModes).every((mode) => mode === \"display\");\n };\n\n const shouldEnableSort = () => {\n return (\n fileItems &&\n fileItems.length > 1 &&\n sortable &&\n areAllItemsInDisplayViews()\n );\n };\n\n /**\n * If there are no files, return \"No files uploaded\".\n * If readOnly is true, return \"Read-only file list\".\n * If there are files, return a summary of the file statuses.\n * For example, \"File list. 2 completed files, 1 file in progress, 1 file with error\".\n *\n * @returns aria label\n */\n const getWrapperAriaLabel = () => {\n if (fileItems.length === 0) {\n return \"No files uploaded\";\n }\n const completedCount = fileItems.filter(\n (item) =>\n !item?.errorMessage &&\n (item.progress === 1 || item.progress === undefined)\n ).length;\n const inProgressCount = fileItems.filter(\n (item) => typeof item.progress === \"number\" && item.progress < 1\n ).length;\n const errorCount = fileItems.filter((item) => item.errorMessage).length;\n if (completedCount === 0 && inProgressCount === 0 && errorCount === 0) {\n return `File list`;\n }\n const completedText =\n completedCount > 0 ? `${completedCount} completed files` : \"\";\n const inProgressText =\n inProgressCount > 0 ? `${inProgressCount} file in progress` : \"\";\n const errorText =\n errorCount > 0\n ? `${errorCount} ${\n errorCount > 1 ? \"files\" : \"file\"\n } with error`\n : \"\";\n const parts = [completedText, inProgressText, errorText].filter(\n Boolean\n );\n const prefix = readOnly ? \"Read-only file list\" : \"File list\";\n return `${prefix}. ${parts.join(\", \")}`;\n };\n\n // =========================================================================\n // RENDER FUNCTIONS\n // =========================================================================\n const renderItemsInEditMode = (\n fileItems: FileItemProps[],\n keyToUse: number\n ) => {\n const itemsToRender = fileItems.map((item) => {\n const updatedFileItem = { ...item };\n if (descriptionsValueRef.current[item.id] !== undefined) {\n updatedFileItem.description =\n descriptionsValueRef.current[item.id];\n }\n\n return (\n <FileItemEdit\n key={item.id}\n fileItem={updatedFileItem}\n wrapperWidth={wrapperWidth}\n fileDescriptionMaxLength={fileDescriptionMaxLength}\n descriptionRequired={descriptionRequired}\n descriptionLabel={descriptionLabel}\n onSave={handleSaveEdit(item)}\n onCancel={handleCancel(item)}\n onBlur={handleBlurEdit(item)}\n />\n );\n });\n\n return (\n <li\n key={`editable-${keyToUse}`}\n className={styles.editableItemsContainer}\n >\n <ul>{itemsToRender}</ul>\n </li>\n );\n };\n\n const renderItems = () => {\n const arrangedItems = getArrangedItems(fileItems, renderModes);\n\n if (arrangedItems.length === 0) return null;\n\n return arrangedItems.map((item, index) => {\n if (Array.isArray(item)) {\n return renderItemsInEditMode(item, index);\n } else {\n return (\n <FileListItem\n key={item.id}\n fileItem={item}\n editable={checkEditable(item)}\n wrapperWidth={wrapperWidth}\n sortable={shouldEnableSort()}\n disabled={disabled}\n readOnly={readOnly}\n descriptionLabel={descriptionLabel}\n onDelete={handleDelete(item)}\n onEditClick={handleInitiateEdit(item)}\n />\n );\n }\n });\n };\n\n /**\n * Renders the progress status of each file upload.\n * In progress: 25% complete for uploading filename.pdf\n * Complete: filename.pdf upload is complete\n * Error: Error uploading filename.pdf: error message\n *\n * @returns A visually hidden element announcing the progress status.\n */\n const renderProgressStatus = () => (\n <VisuallyHidden aria-live=\"polite\" aria-atomic=\"true\">\n {progressAnnouncement}\n </VisuallyHidden>\n );\n\n const renderItemsWithWrapper = () => {\n return (\n <>\n {renderProgressStatus()}\n <ul\n tabIndex={-1}\n className={clsx(\n styles.listWrapper,\n readOnly && styles.listWrapperReadOnly\n )}\n ref={wrapperRef}\n aria-label={getWrapperAriaLabel()}\n >\n {renderItems()}\n </ul>\n </>\n );\n };\n\n if (disabled || readOnly || !shouldEnableSort()) {\n return renderItemsWithWrapper();\n } else {\n return (\n <DndContext\n sensors={sensors}\n onDragEnd={handleDragEnd}\n onDragStart={handleDragStart}\n >\n <SortableContext\n items={fileItems}\n strategy={verticalListSortingStrategy}\n >\n {renderItemsWithWrapper()}\n </SortableContext>\n </DndContext>\n );\n }\n}\n\nexport const FileList = forwardRef<FileListRef, Props>(Component);\n"],"names":["FileList","forwardRef","fileItems","editableFileItems","fileDescriptionMaxLength","descriptionRequired","descriptionLabel","sortable","disabled","readOnly","onItemUpdate","onItemDelete","onSort","ref","renderModes","setRenderModes","useState","setActiveId","useContext","FileUploadContext","progressAnnouncement","setProgressAnnouncement","lastAnnouncedRef","useRef","useImperativeHandle","focus","_a","wrapperRef","current","width","wrapperWidth","useResizeDetector","descriptionsValueRef","sensors","useSensors","useSensor","MouseSensor","activationConstraint","distance","TouchSensor","delay","tolerance","KeyboardSensor","coordinateGetter","sortableKeyboardCoordinates","removeDescription","itemId","useEffect","nextModes","getItemsRenderMode","prev","next","prevKeys","Object","keys","nextKeys","length","k","shallowCompareRenderModes","now","Date","messages","item","fileStatus","id","errorMessage","status","push","name","progress","timestamp","undefined","join","handleSaveEdit","description","updateRenderModes","updatedItem","assign","handleBlurEdit","value","handleCancel","handleInitiateEdit","handleDelete","handleDragEnd","event","active","over","oldIndex","findIndex","newIndex","updatedFileItems","arrayMove","handleDragStart","checkEditable","FileUploadHelper","isSupportedImageType","type","shouldRenderEditMode","newRenderModes","mode","prevRenderModes","shouldEnableSort","values","every","getWrapperAriaLabel","completedCount","filter","inProgressCount","errorCount","parts","Boolean","renderItems","arrangedItems","fileItem","previousElement","Array","isArray","getArrangedItems","map","index","keyToUse","itemsToRender","updatedFileItem","_jsx","FileItemEdit","onSave","onCancel","onBlur","className","styles.editableItemsContainer","children","renderItemsInEditMode","FileListItem","editable","onDelete","onEditClick","renderItemsWithWrapper","_jsxs","_Fragment","VisuallyHidden","tabIndex","clsx","styles.listWrapper","styles.listWrapperReadOnly","DndContext","onDragEnd","onDragStart","SortableContext","items","strategy","verticalListSortingStrategy"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import"./file-list.styles_1ea12kj.css";const l="l14goqmf",s="l1spcgo1",e="e1y5148f";export{e as editableItemsContainer,l as listWrapper,s as listWrapperReadOnly};
1
+ import"./file-list.styles_1w7so98.css";const l="l14goqmf",s="l1spcgo1",o="e1y5148f";export{o as editableItemsContainer,l as listWrapper,s as listWrapperReadOnly};
2
2
  //# sourceMappingURL=file-list.styles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-list.styles.js","sources":["../../../src/file-upload/file-list/file-list.styles.ts"],"sourcesContent":["import { css } from \"@linaria/core\";\n\nimport { Border, Colour, Spacing } from \"../../theme\";\n\nexport const listWrapper = css`\n list-style-type: none;\n margin-bottom: ${Spacing[\"spacing-32\"]};\n`;\n\nexport const listWrapperReadOnly = css`\n margin-bottom: 0;\n`;\n\nexport const editableItemsContainer = css`\n border-top: ${Border[\"width-010\"]} ${Border.solid} ${Colour.border};\n border-bottom: ${Border[\"width-010\"]} ${Border.solid} ${Colour.border};\n\n &:not(:last-child) {\n margin-bottom: ${Spacing[\"spacing-32\"]};\n }\n\n &:not(:first-child) {\n margin-top: ${Spacing[\"spacing-32\"]};\n }\n\n ul {\n list-style-type: none;\n }\n`;\n"],"names":["listWrapper","listWrapperReadOnly","editableItemsContainer"],"mappings":"4EAIO,MAAMA,EAAW,WAKXC,EAAmB,WAInBC,EAAsB"}
1
+ {"version":3,"file":"file-list.styles.js","sources":["../../../src/file-upload/file-list/file-list.styles.ts"],"sourcesContent":["import { css } from \"@linaria/core\";\n\nimport { Spacing } from \"../../theme\";\n\nexport const listWrapper = css`\n list-style-type: none;\n margin-bottom: ${Spacing[\"spacing-32\"]};\n`;\n\nexport const listWrapperReadOnly = css`\n margin-bottom: 0;\n`;\n\nexport const editableItemsContainer = css`\n &:not(:last-child) {\n margin-bottom: ${Spacing[\"spacing-16\"]};\n }\n\n ul {\n list-style-type: none;\n }\n`;\n"],"names":["listWrapper","listWrapperReadOnly","editableItemsContainer"],"mappings":"4EAIO,MAAMA,EAAW,WAKXC,EAAmB,WAInBC,EAAsB"}
@@ -0,0 +1,3 @@
1
+ @layer fds{.l14goqmf{list-style-type:none;margin-bottom:var(--fds-spacing-32);}
2
+ .l1spcgo1{margin-bottom:0;}
3
+ .e1y5148f:not(:last-child){margin-bottom:var(--fds-spacing-16);}.e1y5148f ul{list-style-type:none;}}
@@ -1,4 +1,4 @@
1
- .c1hu6y7h{width:auto;margin-right:var(--fds-spacing-32);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;}
1
+ @layer fds{.c1hu6y7h{width:auto;margin-right:var(--fds-spacing-32);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;}
2
2
  .t18h6q7y{width:96px;height:96px;aspect-ratio:1;border-radius:var(--fds-radius-sm);border:var(--fds-border-width-010) var(--fds-border-style-solid) var(--fds-colour-border);object-fit:cover;}:where(body.fds-breakpoint-md-max) .t18h6q7y{width:64px;height:64px;}
3
3
  .t1w2z01d{border:none;}
4
- .r5e5ep6{width:100%;height:1.625rem;margin-top:var(--fds-spacing-8);border:none;background:transparent;cursor:pointer;font-family:var(--fds-font-family-body);font-variant:var(--fds-font-variant);font-size:var(--fds-font-body-size-md);font-weight:var(--fds-font-weight-semibold);line-height:var(--fds-font-body-lh-md);letter-spacing:var(--fds-font-body-ls-md);color:var(--fds-colour-text-primary);}.r5e5ep6:hover{color:var(--fds-colour-text-hover);}
4
+ .r5e5ep6{width:100%;height:1.625rem;margin-top:var(--fds-spacing-8);border:none;background:transparent;cursor:pointer;font-family:var(--fds-font-family-body);font-variant:var(--fds-font-variant);font-size:var(--fds-font-body-size-md);font-weight:var(--fds-font-weight-semibold);line-height:var(--fds-font-body-lh-md);letter-spacing:var(--fds-font-body-ls-md);color:var(--fds-colour-text-primary);}.r5e5ep6:hover{color:var(--fds-colour-text-hover);}}
@@ -1,6 +1,8 @@
1
+ import type { FormLabelProps } from "../../form/types";
1
2
  import type { FileListItemProps } from "./types";
2
3
  interface Props extends FileListItemProps {
3
4
  readOnly?: boolean | undefined;
5
+ descriptionLabel?: FormLabelProps | undefined;
4
6
  }
5
- export declare const FileListItem: import("react").MemoExoticComponent<({ fileItem, editable, sortable, wrapperWidth, disabled, readOnly, onDelete, onEditClick, }: Props) => import("react/jsx-runtime").JSX.Element>;
7
+ export declare const FileListItem: import("react").MemoExoticComponent<({ fileItem, editable, sortable, wrapperWidth, disabled, readOnly, descriptionLabel, onDelete, onEditClick, }: Props) => import("react/jsx-runtime").JSX.Element>;
6
8
  export {};
@@ -1,2 +1,2 @@
1
- import{jsxs as e,jsx as i,Fragment as t}from"react/jsx-runtime";import{useSortable as a}from"../../external/@dnd-kit/sortable/dist/sortable.esm.js";import{CSS as r}from"../../external/@dnd-kit/utilities/dist/utilities.esm.js";import{BinIcon as s}from"@lifesg/react-icons/bin";import{DragHandleIcon as l}from"@lifesg/react-icons/drag-handle";import{ExclamationCircleFillIcon as d}from"@lifesg/react-icons/exclamation-circle-fill";import{PencilIcon as n}from"@lifesg/react-icons/pencil";import{memo as o,useState as m,useContext as c,useRef as h,useCallback as p,useEffect as b}from"react";import{Button as f}from"../../button/button.js";import{ProgressBar as u}from"../../shared/progress-bar/progress-bar.js";import{Typography as y}from"../../typography/index.js";import"../../util/calendar-helper.js";import"../../external/dayjs/dayjs.min.js";import"../../util/simple-id-generator.js";import{StringHelper as g}from"../../util/string-helper.js";import"@react-aria/live-announcer";import{FileUploadContext as N}from"../context.js";import{FileUploadHelper as v}from"../helper.js";import{item as j,dragHandleIcon as x,box as D,contentSection as $,iconButton as M,actionContainer as T,nameSection as B,desktopErrorMessage as k,errorIcon as w,fileSizeSection as z,fileSizeText as C,mobileErrorMessage as I,extendedNameSection as O,itemDescriptionText as S}from"./file-list-item.styles.js";import{FileListItemThumbnail as E}from"./file-list-item-thumbnail.js";const P=o((({fileItem:o,editable:P,sortable:F,wrapperWidth:K,disabled:R,readOnly:U,onDelete:_,onEditClick:L})=>{const{id:W,name:Y,size:q,description:A,progress:G=1,errorMessage:H,thumbnailImageDataUrl:J,truncateText:Q=!0}=o,[V,X]=m(),{activeId:Z}=c(N),{attributes:ee,listeners:ie,setNodeRef:te,transform:ae,transition:re}=a({id:W}),se=h(null),le={transform:r.Translate.toString(ae),transition:re},de=Object.assign(Object.assign({style:le},ee),ie),ne=G<1,oe=v.formatFileSizeDisplay(q),me=Z?Z===W?"self":"others":"none",ce=p((e=>{if(!Q)return e;const i=se&&se.current?se.current.getBoundingClientRect().width:0;return g.truncateOneLine(e,i,i/2,i/2/8,16)}),[Q]);b((()=>{X(ce(Y))}),[K,ce,Y]);const he=()=>{_()},pe=()=>{L&&L()},be=e=>{F&&e.stopPropagation()},fe=()=>R||!!Z,ue=()=>!!F&&!U,ye=()=>e(t,{children:[i(y.BodyMD,{weight:A?"semibold":"regular",children:V}),A&&i(y.BodyMD,{className:S,children:A})]});return e("li",Object.assign({id:W,ref:te,className:j,"data-item-state":fe()&&"none"===me?"disabled":ue()&&"self"===me?"sortable-active":ue()?"sortable":void 0,"data-testid":`${W}-item`},ue()?de:{},{children:[ue()&&i(l,{"data-testid":`${W}-drag-handle`,className:x,"data-drag-handle-state":"self"===me?"active":fe()?"disabled":void 0}),e("div",{className:D,"data-box-state":"self"===me?"focused":fe()?"disabled":H?"error":void 0,"data-stack-mobile":!H&&(ne||P),children:[(()=>{let a;const r=!!J||o.type===v.PDF_MIME_TYPE;return a=H?e(t,{children:[e("div",{ref:se,className:B,children:[ye(),H&&e(y.BodySM,{className:k,weight:"semibold",children:[i(d,{className:w,"aria-hidden":!0}),H]})]}),i("div",{className:z,"data-mobile-visibility":ne?"hidden":"expand",children:i(y.BodyMD,{className:C,children:oe})}),H&&e(y.BodySM,{className:I,weight:"semibold",children:[i(d,{className:w,"aria-hidden":!0}),H]})]}):r?(a=>e(t,{children:[i(E,{thumbnailImageDataUrl:a,fileType:o.type,"data-testid":`${W}-thumbnail`}),e("div",{className:O,children:[i("div",{ref:se,className:B,children:ye()}),i("div",{className:z,"data-mobile-visibility":ne?"hidden":"expand",children:i(y.BodyMD,{className:C,children:oe})})]})]}))(J||""):e(t,{children:[i("div",{ref:se,className:B,children:ye()}),i("div",{className:z,"data-mobile-visibility":ne?"hidden":"expand",children:i(y.BodyMD,{className:C,children:oe})})]}),i("div",{className:$,"data-has-thumbnail":r,children:a})})(),!U&&(()=>{let a;return a=H?i(f,{"data-testid":`${W}-error-delete-button`,"data-no-dnd":"true",type:"button",styleType:"light",sizeType:"small","aria-label":`delete ${Y}, error: ${H}`,onClick:he,className:M,icon:i(s,{"aria-hidden":!0})}):ne?i(u,{progress:G,"data-testid":`${W}-progress-bar`}):e(t,{children:[P&&i(f,{"data-testid":`${W}-edit-button`,"data-no-dnd":"true",type:"button",styleType:"light",sizeType:"small","aria-label":`edit ${Y}`,disabled:fe(),onClick:pe,onKeyDown:be,icon:i(n,{"aria-hidden":!0}),className:M},"edit"),i(f,{"data-testid":`${W}-delete-button`,"data-no-dnd":"true",type:"button",styleType:"light",sizeType:"small","aria-label":`delete ${Y}`,disabled:fe(),onClick:he,onKeyDown:be,icon:i(s,{"aria-hidden":!0}),className:M},"delete")]}),i("div",{className:T,"data-mobile-layout":!H&&ne?"loading":!H&&P?"editable":void 0,children:a})})()]})]}))}));export{P as FileListItem};
1
+ import{jsxs as e,jsx as t,Fragment as i}from"react/jsx-runtime";import{useSortable as a}from"../../external/@dnd-kit/sortable/dist/sortable.esm.js";import{CSS as l}from"../../external/@dnd-kit/utilities/dist/utilities.esm.js";import{BinIcon as r}from"@lifesg/react-icons/bin";import{DragHandleIcon as s}from"@lifesg/react-icons/drag-handle";import{ExclamationCircleFillIcon as d}from"@lifesg/react-icons/exclamation-circle-fill";import{PencilIcon as n}from"@lifesg/react-icons/pencil";import{memo as o,useState as c,useContext as m,useRef as h,useCallback as p,useEffect as b}from"react";import{Button as u}from"../../button/button.js";import{ProgressBar as y}from"../../shared/progress-bar/progress-bar.js";import{Typography as f}from"../../typography/index.js";import"../../util/calendar-helper.js";import"../../external/dayjs/dayjs.min.js";import"../../util/simple-id-generator.js";import{StringHelper as g}from"../../util/string-helper.js";import"@react-aria/live-announcer";import{FileUploadContext as N}from"../context.js";import{FileUploadHelper as v}from"../helper.js";import{item as j,dragHandleIcon as D,box as M,contentSection as T,iconButton as $,actionContainer as B,nameSection as x,desktopErrorMessage as w,errorIcon as k,fileSizeSection as z,fileSizeText as C,mobileErrorMessage as P,descriptionFileSizeText as I,itemDescriptionLabel as E,itemDescriptionText as O,extendedNameSection as K,inlineActionContainer as S}from"./file-list-item.styles.js";import{FileListItemThumbnail as _}from"./file-list-item-thumbnail.js";const F=o((({fileItem:o,editable:F,sortable:L,wrapperWidth:R,disabled:U,readOnly:Y,descriptionLabel:W,onDelete:q,onEditClick:A})=>{const{id:G,name:H,size:J,description:Q,progress:V=1,errorMessage:X,thumbnailImageDataUrl:Z,truncateText:ee=!0}=o,[te,ie]=c(),{activeId:ae}=m(N),{attributes:le,listeners:re,setNodeRef:se,transform:de,transition:ne}=a({id:G}),oe=h(null),ce={transform:l.Translate.toString(de),transition:ne},me=Object.assign(Object.assign({style:ce},le),re),he=V<1,pe=v.formatFileSizeDisplay(J),be=!!Q&&!!F,ue=ae?ae===G?"self":"others":"none",ye=p((e=>{if(!ee)return e;const t=oe&&oe.current?oe.current.getBoundingClientRect().width:0;return g.truncateOneLine(e,t,t/2,t/2/8,16)}),[ee]);b((()=>{ie(ye(H))}),[R,ye,H]);const fe=()=>{q()},ge=()=>{A&&A()},Ne=e=>{L&&e.stopPropagation()},ve=()=>U||!!ae,je=()=>!!L&&!Y,De=()=>{var a;return e(i,{children:[t(f.BodyMD,{weight:Q?"semibold":"regular",children:te}),Q&&e(i,{children:[t(f.BodyMD,{className:E,children:null!==(a=null==W?void 0:W.children)&&void 0!==a?a:"Photo description"}),t(f.BodyMD,{className:O,children:Q})]})]})};return e("li",Object.assign({id:G,ref:se,className:j,"data-item-state":ve()&&"none"===ue?"disabled":je()&&"self"===ue?"sortable-active":je()?"sortable":void 0,"data-testid":`${G}-item`},je()?me:{},{children:[je()&&t(s,{"data-testid":`${G}-drag-handle`,className:D,"data-drag-handle-state":"self"===ue?"active":ve()?"disabled":void 0}),e("div",{className:M,"data-box-state":"self"===ue?"focused":ve()?"disabled":X?"error":void 0,"data-stack-mobile":!X&&(he||F),children:[(()=>{const a=!!Z||o.type===v.PDF_MIME_TYPE,l=X?e(i,{children:[e("div",{ref:oe,className:x,children:[De(),X&&e(f.BodySM,{className:w,weight:"semibold",children:[t(d,{className:k,"aria-hidden":!0}),X]})]}),t("div",{className:z,"data-mobile-visibility":he?"hidden":"expand",children:t(f.BodyMD,{className:C,children:pe})}),X&&e(f.BodySM,{className:P,weight:"semibold",children:[t(d,{className:k,"aria-hidden":!0}),X]})]}):(a=>{const l=a||o.type===v.PDF_MIME_TYPE?t(_,{thumbnailImageDataUrl:a||"",fileType:o.type,"data-testid":`${G}-thumbnail`}):null;return e(i,be?{children:[l,e("div",{ref:oe,className:K,children:[t(f.BodyMD,{weight:"semibold",children:te}),t(f.BodyMD,{className:E,children:null!==(s=null==W?void 0:W.children)&&void 0!==s?s:"Photo description"}),t(f.BodyMD,{className:O,children:Q}),t(f.BodyMD,{className:I,children:pe}),!Y&&be&&e("div",{className:S,children:[t(u,{"data-testid":`${G}-edit-button`,"data-no-dnd":"true",type:"button",styleType:"light",sizeType:"small","aria-label":`edit ${H}`,disabled:ve(),onClick:ge,onKeyDown:Ne,icon:t(n,{"aria-hidden":!0}),className:$},"edit"),t(u,{"data-testid":`${G}-delete-button`,"data-no-dnd":"true",type:"button",styleType:"light",sizeType:"small","aria-label":`delete ${H}`,disabled:ve(),onClick:fe,onKeyDown:Ne,icon:t(r,{"aria-hidden":!0}),className:$},"delete")]})]})]}:{children:[l,e("div",{ref:oe,className:x,children:[De(),!he&&t(f.BodyMD,{className:I,children:pe})]})]});var s})(Z);return t("div",{className:T,"data-has-thumbnail":a,children:l})})(),!Y&&!be&&(()=>{let a;return a=X?t(u,{"data-testid":`${G}-error-delete-button`,"data-no-dnd":"true",type:"button",styleType:"light",sizeType:"small","aria-label":`delete ${H}, error: ${X}`,onClick:fe,className:$,icon:t(r,{"aria-hidden":!0})}):he?t(y,{progress:V,"data-testid":`${G}-progress-bar`}):e(i,{children:[F&&t(u,{"data-testid":`${G}-edit-button`,"data-no-dnd":"true",type:"button",styleType:"light",sizeType:"small","aria-label":`edit ${H}`,disabled:ve(),onClick:ge,onKeyDown:Ne,icon:t(n,{"aria-hidden":!0}),className:$},"edit"),t(u,{"data-testid":`${G}-delete-button`,"data-no-dnd":"true",type:"button",styleType:"light",sizeType:"small","aria-label":`delete ${H}`,disabled:ve(),onClick:fe,onKeyDown:Ne,icon:t(r,{"aria-hidden":!0}),className:$},"delete")]}),t("div",{className:B,"data-mobile-layout":!X&&he?"loading":!X&&F?"editable":void 0,children:a})})()]})]}))}));export{F as FileListItem};
2
2
  //# sourceMappingURL=file-list-item.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-list-item.js","sources":["../../../src/file-upload/file-list-item/file-list-item.tsx"],"sourcesContent":["import { useSortable } from \"@dnd-kit/sortable\";\nimport { CSS } from \"@dnd-kit/utilities\";\nimport { BinIcon } from \"@lifesg/react-icons/bin\";\nimport { DragHandleIcon as DSDragHandleIcon } from \"@lifesg/react-icons/drag-handle\";\nimport { ExclamationCircleFillIcon } from \"@lifesg/react-icons/exclamation-circle-fill\";\nimport { PencilIcon } from \"@lifesg/react-icons/pencil\";\nimport {\n memo,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n} from \"react\";\n\nimport { Button } from \"../../button\";\nimport { ProgressBar } from \"../../shared/progress-bar\";\nimport { Typography } from \"../../typography\";\nimport { StringHelper } from \"../../util\";\nimport { FileUploadContext } from \"../context\";\nimport { FileUploadHelper } from \"../helper\";\nimport type { ItemFocusType } from \"./file-list-item.styles\";\nimport * as styles from \"./file-list-item.styles\";\nimport { FileListItemThumbnail } from \"./file-list-item-thumbnail\";\nimport type { FileListItemProps } from \"./types\";\n\ninterface Props extends FileListItemProps {\n readOnly?: boolean | undefined;\n}\n\nconst Component = ({\n fileItem,\n editable,\n sortable,\n wrapperWidth,\n disabled,\n readOnly,\n onDelete,\n onEditClick,\n}: Props) => {\n // =========================================================================\n // CONST, STATE, REFS\n // =========================================================================\n const {\n id,\n name,\n size,\n description,\n progress = 1,\n errorMessage,\n thumbnailImageDataUrl,\n truncateText = true,\n } = fileItem;\n const [formattedName, setFormattedName] = useState<string>();\n const { activeId } = useContext(FileUploadContext);\n\n // Sortable mechanism\n const { attributes, listeners, setNodeRef, transform, transition } =\n useSortable({ id });\n const detailSectionRef = useRef<HTMLDivElement>(null);\n const style = {\n transform: CSS.Translate.toString(transform),\n transition,\n };\n\n const sortableProps = {\n style,\n ...attributes,\n ...listeners,\n };\n\n // Local variables\n const isLoading = progress < 1;\n const fileSize = FileUploadHelper.formatFileSizeDisplay(size);\n const focusType: ItemFocusType = activeId\n ? activeId === id\n ? \"self\"\n : \"others\"\n : \"none\";\n\n // =========================================================================\n // HELPER FUNCTIONS\n // =========================================================================\n const getTruncatedText = useCallback(\n (value: string) => {\n if (!truncateText) return value;\n\n const widthOfElement =\n detailSectionRef && detailSectionRef.current\n ? detailSectionRef.current.getBoundingClientRect().width\n : 0;\n\n return StringHelper.truncateOneLine(\n value,\n widthOfElement,\n widthOfElement / 2,\n widthOfElement / 2 / 8, // Arbitrary\n 16 // Font size\n );\n },\n [truncateText]\n );\n\n // =========================================================================\n // EFFECTS\n // =========================================================================\n useEffect(() => {\n setFormattedName(getTruncatedText(name));\n }, [wrapperWidth, getTruncatedText, name]);\n\n // =========================================================================\n // EVENT HANDLERS\n // =========================================================================\n const handleDelete = () => {\n onDelete();\n };\n\n const handleEdit = () => {\n if (onEditClick) {\n onEditClick();\n }\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n /**\n * Circumvent issue of keydown action activating the sort mechanism\n * rather than the actual action\n */\n if (sortable) {\n event.stopPropagation();\n }\n };\n\n const shouldDisable = () => disabled || !!activeId;\n\n const shouldEnableSort = () => !!sortable && !readOnly;\n\n const getItemState = () => {\n if (shouldDisable() && focusType === \"none\") {\n return \"disabled\";\n }\n\n if (shouldEnableSort() && focusType === \"self\") {\n return \"sortable-active\";\n }\n\n if (shouldEnableSort()) {\n return \"sortable\";\n }\n\n return undefined;\n };\n\n const getDragHandleState = () => {\n if (focusType === \"self\") {\n return \"active\";\n }\n\n if (shouldDisable()) {\n return \"disabled\";\n }\n\n return undefined;\n };\n\n const getBoxState = () => {\n if (focusType === \"self\") {\n return \"focused\";\n }\n\n if (shouldDisable()) {\n return \"disabled\";\n }\n\n if (errorMessage) {\n return \"error\";\n }\n\n return undefined;\n };\n\n const getActionContainerLayout = () => {\n if (!errorMessage && isLoading) {\n return \"loading\";\n }\n\n if (!errorMessage && editable) {\n return \"editable\";\n }\n\n return undefined;\n };\n\n // =========================================================================\n // RENDER FUNCTIONS\n // =========================================================================\n const renderNameDescription = () => (\n <>\n <Typography.BodyMD weight={description ? \"semibold\" : \"regular\"}>\n {formattedName}\n </Typography.BodyMD>\n {description && (\n <Typography.BodyMD className={styles.itemDescriptionText}>\n {description}\n </Typography.BodyMD>\n )}\n </>\n );\n\n const renderErrorState = () => (\n <>\n <div ref={detailSectionRef} className={styles.nameSection}>\n {renderNameDescription()}\n {errorMessage && (\n <Typography.BodySM\n className={styles.desktopErrorMessage}\n weight=\"semibold\"\n >\n <ExclamationCircleFillIcon\n className={styles.errorIcon}\n aria-hidden\n />\n {errorMessage}\n </Typography.BodySM>\n )}\n </div>\n <div\n className={styles.fileSizeSection}\n data-mobile-visibility={isLoading ? \"hidden\" : \"expand\"}\n >\n <Typography.BodyMD className={styles.fileSizeText}>\n {fileSize}\n </Typography.BodyMD>\n </div>\n {errorMessage && (\n <Typography.BodySM\n className={styles.mobileErrorMessage}\n weight=\"semibold\"\n >\n <ExclamationCircleFillIcon\n className={styles.errorIcon}\n aria-hidden\n />\n {errorMessage}\n </Typography.BodySM>\n )}\n </>\n );\n\n const renderWithThumbnail = (thumbnailImageDataUrl: string) => (\n <>\n <FileListItemThumbnail\n thumbnailImageDataUrl={thumbnailImageDataUrl}\n fileType={fileItem.type}\n data-testid={`${id}-thumbnail`}\n />\n <div className={styles.extendedNameSection}>\n <div ref={detailSectionRef} className={styles.nameSection}>\n {renderNameDescription()}\n </div>\n <div\n className={styles.fileSizeSection}\n data-mobile-visibility={isLoading ? \"hidden\" : \"expand\"}\n >\n <Typography.BodyMD className={styles.fileSizeText}>\n {fileSize}\n </Typography.BodyMD>\n </div>\n </div>\n </>\n );\n\n const renderDefault = () => (\n <>\n <div ref={detailSectionRef} className={styles.nameSection}>\n {renderNameDescription()}\n </div>\n <div\n className={styles.fileSizeSection}\n data-mobile-visibility={isLoading ? \"hidden\" : \"expand\"}\n >\n <Typography.BodyMD className={styles.fileSizeText}>\n {fileSize}\n </Typography.BodyMD>\n </div>\n </>\n );\n\n const renderContents = () => {\n let content: JSX.Element;\n const shouldShowThumbnail =\n !!thumbnailImageDataUrl ||\n fileItem.type === FileUploadHelper.PDF_MIME_TYPE;\n\n if (errorMessage) {\n content = renderErrorState();\n } else if (shouldShowThumbnail) {\n content = renderWithThumbnail(thumbnailImageDataUrl || \"\");\n } else {\n content = renderDefault();\n }\n\n return (\n <div\n className={styles.contentSection}\n data-has-thumbnail={shouldShowThumbnail}\n >\n {content}\n </div>\n );\n };\n\n const renderActions = () => {\n let content: JSX.Element;\n\n if (errorMessage) {\n content = (\n <Button\n data-testid={`${id}-error-delete-button`}\n data-no-dnd=\"true\"\n type=\"button\"\n styleType=\"light\"\n sizeType=\"small\"\n aria-label={`delete ${name}, error: ${errorMessage}`}\n onClick={handleDelete}\n className={styles.iconButton}\n icon={<BinIcon aria-hidden />}\n />\n );\n } else if (isLoading) {\n content = (\n <ProgressBar\n progress={progress}\n data-testid={`${id}-progress-bar`}\n />\n );\n } else {\n content = (\n <>\n {editable && (\n <Button\n key=\"edit\"\n data-testid={`${id}-edit-button`}\n data-no-dnd=\"true\"\n type=\"button\"\n styleType=\"light\"\n sizeType=\"small\"\n aria-label={`edit ${name}`}\n disabled={shouldDisable()}\n onClick={handleEdit}\n onKeyDown={handleKeyDown}\n icon={<PencilIcon aria-hidden />}\n className={styles.iconButton}\n />\n )}\n <Button\n key=\"delete\"\n data-testid={`${id}-delete-button`}\n data-no-dnd=\"true\"\n type=\"button\"\n styleType=\"light\"\n sizeType=\"small\"\n aria-label={`delete ${name}`}\n disabled={shouldDisable()}\n onClick={handleDelete}\n onKeyDown={handleKeyDown}\n icon={<BinIcon aria-hidden />}\n className={styles.iconButton}\n />\n </>\n );\n }\n\n return (\n <div\n className={styles.actionContainer}\n data-mobile-layout={getActionContainerLayout()}\n >\n {content}\n </div>\n );\n };\n\n return (\n <li\n id={id}\n ref={setNodeRef}\n className={styles.item}\n data-item-state={getItemState()}\n data-testid={`${id}-item`}\n {...(shouldEnableSort() ? sortableProps : {})}\n >\n {shouldEnableSort() && (\n <DSDragHandleIcon\n data-testid={`${id}-drag-handle`}\n className={styles.dragHandleIcon}\n data-drag-handle-state={getDragHandleState()}\n />\n )}\n <div\n className={styles.box}\n data-box-state={getBoxState()}\n data-stack-mobile={!errorMessage && (isLoading || editable)}\n >\n {renderContents()}\n {!readOnly && renderActions()}\n </div>\n </li>\n );\n};\n\nexport const FileListItem = memo(Component);\n"],"names":["FileListItem","memo","fileItem","editable","sortable","wrapperWidth","disabled","readOnly","onDelete","onEditClick","id","name","size","description","progress","errorMessage","thumbnailImageDataUrl","truncateText","formattedName","setFormattedName","useState","activeId","useContext","FileUploadContext","attributes","listeners","setNodeRef","transform","transition","useSortable","detailSectionRef","useRef","style","CSS","Translate","toString","sortableProps","isLoading","fileSize","FileUploadHelper","formatFileSizeDisplay","focusType","getTruncatedText","useCallback","value","widthOfElement","current","getBoundingClientRect","width","StringHelper","truncateOneLine","useEffect","handleDelete","handleEdit","handleKeyDown","event","stopPropagation","shouldDisable","shouldEnableSort","renderNameDescription","_jsxs","_Fragment","children","_jsx","Typography","BodyMD","weight","className","styles.itemDescriptionText","Object","assign","ref","styles.item","DSDragHandleIcon","styles.dragHandleIcon","styles.box","content","shouldShowThumbnail","type","PDF_MIME_TYPE","styles.nameSection","BodySM","styles.desktopErrorMessage","ExclamationCircleFillIcon","styles.errorIcon","styles.fileSizeSection","styles.fileSizeText","styles.mobileErrorMessage","FileListItemThumbnail","fileType","styles.extendedNameSection","renderWithThumbnail","styles.contentSection","renderContents","Button","styleType","sizeType","onClick","styles.iconButton","icon","BinIcon","ProgressBar","onKeyDown","PencilIcon","styles.actionContainer","renderActions"],"mappings":"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"}
1
+ {"version":3,"file":"file-list-item.js","sources":["../../../src/file-upload/file-list-item/file-list-item.tsx"],"sourcesContent":["import { useSortable } from \"@dnd-kit/sortable\";\nimport { CSS } from \"@dnd-kit/utilities\";\nimport { BinIcon } from \"@lifesg/react-icons/bin\";\nimport { DragHandleIcon as DSDragHandleIcon } from \"@lifesg/react-icons/drag-handle\";\nimport { ExclamationCircleFillIcon } from \"@lifesg/react-icons/exclamation-circle-fill\";\nimport { PencilIcon } from \"@lifesg/react-icons/pencil\";\nimport {\n memo,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n} from \"react\";\n\nimport { Button } from \"../../button\";\nimport type { FormLabelProps } from \"../../form/types\";\nimport { ProgressBar } from \"../../shared/progress-bar\";\nimport { Typography } from \"../../typography\";\nimport { StringHelper } from \"../../util\";\nimport { FileUploadContext } from \"../context\";\nimport { FileUploadHelper } from \"../helper\";\nimport type { ItemFocusType } from \"./file-list-item.styles\";\nimport * as styles from \"./file-list-item.styles\";\nimport { FileListItemThumbnail } from \"./file-list-item-thumbnail\";\nimport type { FileListItemProps } from \"./types\";\n\ninterface Props extends FileListItemProps {\n readOnly?: boolean | undefined;\n descriptionLabel?: FormLabelProps | undefined;\n}\n\nconst Component = ({\n fileItem,\n editable,\n sortable,\n wrapperWidth,\n disabled,\n readOnly,\n descriptionLabel,\n onDelete,\n onEditClick,\n}: Props) => {\n // =========================================================================\n // CONST, STATE, REFS\n // =========================================================================\n const {\n id,\n name,\n size,\n description,\n progress = 1,\n errorMessage,\n thumbnailImageDataUrl,\n truncateText = true,\n } = fileItem;\n const [formattedName, setFormattedName] = useState<string>();\n const { activeId } = useContext(FileUploadContext);\n\n // Sortable mechanism\n const { attributes, listeners, setNodeRef, transform, transition } =\n useSortable({ id });\n const detailSectionRef = useRef<HTMLDivElement>(null);\n const style = {\n transform: CSS.Translate.toString(transform),\n transition,\n };\n\n const sortableProps = {\n style,\n ...attributes,\n ...listeners,\n };\n\n // Local variables\n const isLoading = progress < 1;\n const fileSize = FileUploadHelper.formatFileSizeDisplay(size);\n const hasInlineActions = !!description && !!editable;\n const focusType: ItemFocusType = activeId\n ? activeId === id\n ? \"self\"\n : \"others\"\n : \"none\";\n\n // =========================================================================\n // HELPER FUNCTIONS\n // =========================================================================\n const getTruncatedText = useCallback(\n (value: string) => {\n if (!truncateText) return value;\n\n const widthOfElement =\n detailSectionRef && detailSectionRef.current\n ? detailSectionRef.current.getBoundingClientRect().width\n : 0;\n\n return StringHelper.truncateOneLine(\n value,\n widthOfElement,\n widthOfElement / 2,\n widthOfElement / 2 / 8, // Arbitrary\n 16 // Font size\n );\n },\n [truncateText]\n );\n\n // =========================================================================\n // EFFECTS\n // =========================================================================\n useEffect(() => {\n setFormattedName(getTruncatedText(name));\n }, [wrapperWidth, getTruncatedText, name]);\n\n // =========================================================================\n // EVENT HANDLERS\n // =========================================================================\n const handleDelete = () => {\n onDelete();\n };\n\n const handleEdit = () => {\n if (onEditClick) {\n onEditClick();\n }\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLButtonElement>) => {\n /**\n * Circumvent issue of keydown action activating the sort mechanism\n * rather than the actual action\n */\n if (sortable) {\n event.stopPropagation();\n }\n };\n\n const shouldDisable = () => disabled || !!activeId;\n\n const shouldEnableSort = () => !!sortable && !readOnly;\n\n const getItemState = () => {\n if (shouldDisable() && focusType === \"none\") {\n return \"disabled\";\n }\n\n if (shouldEnableSort() && focusType === \"self\") {\n return \"sortable-active\";\n }\n\n if (shouldEnableSort()) {\n return \"sortable\";\n }\n\n return undefined;\n };\n\n const getDragHandleState = () => {\n if (focusType === \"self\") {\n return \"active\";\n }\n\n if (shouldDisable()) {\n return \"disabled\";\n }\n\n return undefined;\n };\n\n const getBoxState = () => {\n if (focusType === \"self\") {\n return \"focused\";\n }\n\n if (shouldDisable()) {\n return \"disabled\";\n }\n\n if (errorMessage) {\n return \"error\";\n }\n\n return undefined;\n };\n\n const getActionContainerLayout = () => {\n if (!errorMessage && isLoading) {\n return \"loading\";\n }\n\n if (!errorMessage && editable) {\n return \"editable\";\n }\n\n return undefined;\n };\n\n // =========================================================================\n // RENDER FUNCTIONS\n // =========================================================================\n const renderNameDescription = () => (\n <>\n <Typography.BodyMD weight={description ? \"semibold\" : \"regular\"}>\n {formattedName}\n </Typography.BodyMD>\n {description && (\n <>\n <Typography.BodyMD className={styles.itemDescriptionLabel}>\n {descriptionLabel?.children ?? \"Photo description\"}\n </Typography.BodyMD>\n <Typography.BodyMD className={styles.itemDescriptionText}>\n {description}\n </Typography.BodyMD>\n </>\n )}\n </>\n );\n\n const renderErrorState = () => (\n <>\n <div ref={detailSectionRef} className={styles.nameSection}>\n {renderNameDescription()}\n {errorMessage && (\n <Typography.BodySM\n className={styles.desktopErrorMessage}\n weight=\"semibold\"\n >\n <ExclamationCircleFillIcon\n className={styles.errorIcon}\n aria-hidden\n />\n {errorMessage}\n </Typography.BodySM>\n )}\n </div>\n <div\n className={styles.fileSizeSection}\n data-mobile-visibility={isLoading ? \"hidden\" : \"expand\"}\n >\n <Typography.BodyMD className={styles.fileSizeText}>\n {fileSize}\n </Typography.BodyMD>\n </div>\n {errorMessage && (\n <Typography.BodySM\n className={styles.mobileErrorMessage}\n weight=\"semibold\"\n >\n <ExclamationCircleFillIcon\n className={styles.errorIcon}\n aria-hidden\n />\n {errorMessage}\n </Typography.BodySM>\n )}\n </>\n );\n\n const renderInlineActions = () => (\n <div className={styles.inlineActionContainer}>\n <Button\n key=\"edit\"\n data-testid={`${id}-edit-button`}\n data-no-dnd=\"true\"\n type=\"button\"\n styleType=\"light\"\n sizeType=\"small\"\n aria-label={`edit ${name}`}\n disabled={shouldDisable()}\n onClick={handleEdit}\n onKeyDown={handleKeyDown}\n icon={<PencilIcon aria-hidden />}\n className={styles.iconButton}\n />\n <Button\n key=\"delete\"\n data-testid={`${id}-delete-button`}\n data-no-dnd=\"true\"\n type=\"button\"\n styleType=\"light\"\n sizeType=\"small\"\n aria-label={`delete ${name}`}\n disabled={shouldDisable()}\n onClick={handleDelete}\n onKeyDown={handleKeyDown}\n icon={<BinIcon aria-hidden />}\n className={styles.iconButton}\n />\n </div>\n );\n\n const renderDescriptionContent = () => (\n <div ref={detailSectionRef} className={styles.extendedNameSection}>\n <Typography.BodyMD weight=\"semibold\">\n {formattedName}\n </Typography.BodyMD>\n <Typography.BodyMD className={styles.itemDescriptionLabel}>\n {descriptionLabel?.children ?? \"Photo description\"}\n </Typography.BodyMD>\n <Typography.BodyMD className={styles.itemDescriptionText}>\n {description}\n </Typography.BodyMD>\n <Typography.BodyMD className={styles.descriptionFileSizeText}>\n {fileSize}\n </Typography.BodyMD>\n {!readOnly && hasInlineActions && renderInlineActions()}\n </div>\n );\n\n const renderFileContent = (thumbnailImageDataUrl?: string) => {\n const shouldShowThumbnail =\n !!thumbnailImageDataUrl ||\n fileItem.type === FileUploadHelper.PDF_MIME_TYPE;\n\n const thumbnail = shouldShowThumbnail ? (\n <FileListItemThumbnail\n thumbnailImageDataUrl={thumbnailImageDataUrl || \"\"}\n fileType={fileItem.type}\n data-testid={`${id}-thumbnail`}\n />\n ) : null;\n\n if (hasInlineActions) {\n return (\n <>\n {thumbnail}\n {renderDescriptionContent()}\n </>\n );\n }\n\n return (\n <>\n {thumbnail}\n <div ref={detailSectionRef} className={styles.nameSection}>\n {renderNameDescription()}\n {!isLoading && (\n <Typography.BodyMD\n className={styles.descriptionFileSizeText}\n >\n {fileSize}\n </Typography.BodyMD>\n )}\n </div>\n </>\n );\n };\n\n const renderContents = () => {\n const shouldShowThumbnail =\n !!thumbnailImageDataUrl ||\n fileItem.type === FileUploadHelper.PDF_MIME_TYPE;\n\n const content = errorMessage\n ? renderErrorState()\n : renderFileContent(thumbnailImageDataUrl);\n\n return (\n <div\n className={styles.contentSection}\n data-has-thumbnail={shouldShowThumbnail}\n >\n {content}\n </div>\n );\n };\n\n const renderActions = () => {\n let content: JSX.Element;\n\n if (errorMessage) {\n content = (\n <Button\n data-testid={`${id}-error-delete-button`}\n data-no-dnd=\"true\"\n type=\"button\"\n styleType=\"light\"\n sizeType=\"small\"\n aria-label={`delete ${name}, error: ${errorMessage}`}\n onClick={handleDelete}\n className={styles.iconButton}\n icon={<BinIcon aria-hidden />}\n />\n );\n } else if (isLoading) {\n content = (\n <ProgressBar\n progress={progress}\n data-testid={`${id}-progress-bar`}\n />\n );\n } else {\n content = (\n <>\n {editable && (\n <Button\n key=\"edit\"\n data-testid={`${id}-edit-button`}\n data-no-dnd=\"true\"\n type=\"button\"\n styleType=\"light\"\n sizeType=\"small\"\n aria-label={`edit ${name}`}\n disabled={shouldDisable()}\n onClick={handleEdit}\n onKeyDown={handleKeyDown}\n icon={<PencilIcon aria-hidden />}\n className={styles.iconButton}\n />\n )}\n <Button\n key=\"delete\"\n data-testid={`${id}-delete-button`}\n data-no-dnd=\"true\"\n type=\"button\"\n styleType=\"light\"\n sizeType=\"small\"\n aria-label={`delete ${name}`}\n disabled={shouldDisable()}\n onClick={handleDelete}\n onKeyDown={handleKeyDown}\n icon={<BinIcon aria-hidden />}\n className={styles.iconButton}\n />\n </>\n );\n }\n\n return (\n <div\n className={styles.actionContainer}\n data-mobile-layout={getActionContainerLayout()}\n >\n {content}\n </div>\n );\n };\n\n return (\n <li\n id={id}\n ref={setNodeRef}\n className={styles.item}\n data-item-state={getItemState()}\n data-testid={`${id}-item`}\n {...(shouldEnableSort() ? sortableProps : {})}\n >\n {shouldEnableSort() && (\n <DSDragHandleIcon\n data-testid={`${id}-drag-handle`}\n className={styles.dragHandleIcon}\n data-drag-handle-state={getDragHandleState()}\n />\n )}\n <div\n className={styles.box}\n data-box-state={getBoxState()}\n data-stack-mobile={!errorMessage && (isLoading || editable)}\n >\n {renderContents()}\n {!readOnly && !hasInlineActions && renderActions()}\n </div>\n </li>\n );\n};\n\nexport const FileListItem = memo(Component);\n"],"names":["FileListItem","memo","fileItem","editable","sortable","wrapperWidth","disabled","readOnly","descriptionLabel","onDelete","onEditClick","id","name","size","description","progress","errorMessage","thumbnailImageDataUrl","truncateText","formattedName","setFormattedName","useState","activeId","useContext","FileUploadContext","attributes","listeners","setNodeRef","transform","transition","useSortable","detailSectionRef","useRef","style","CSS","Translate","toString","sortableProps","isLoading","fileSize","FileUploadHelper","formatFileSizeDisplay","hasInlineActions","focusType","getTruncatedText","useCallback","value","widthOfElement","current","getBoundingClientRect","width","StringHelper","truncateOneLine","useEffect","handleDelete","handleEdit","handleKeyDown","event","stopPropagation","shouldDisable","shouldEnableSort","renderNameDescription","_jsxs","_Fragment","children","_jsx","Typography","BodyMD","weight","className","styles.itemDescriptionLabel","_a","styles.itemDescriptionText","Object","assign","ref","styles.item","DSDragHandleIcon","styles.dragHandleIcon","styles.box","shouldShowThumbnail","type","PDF_MIME_TYPE","content","styles.nameSection","BodySM","styles.desktopErrorMessage","ExclamationCircleFillIcon","styles.errorIcon","styles.fileSizeSection","styles.fileSizeText","styles.mobileErrorMessage","thumbnail","FileListItemThumbnail","fileType","styles.extendedNameSection","styles.descriptionFileSizeText","styles.inlineActionContainer","Button","styleType","sizeType","onClick","onKeyDown","icon","PencilIcon","styles.iconButton","BinIcon","renderFileContent","styles.contentSection","renderContents","ProgressBar","styles.actionContainer","renderActions"],"mappings":"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"}
@@ -7,9 +7,12 @@ export declare const nameSection: import("@linaria/core").LinariaClassName;
7
7
  export declare const extendedNameSection: import("@linaria/core").LinariaClassName;
8
8
  export declare const fileSizeSection: import("@linaria/core").LinariaClassName;
9
9
  export declare const fileSizeText: import("@linaria/core").LinariaClassName;
10
+ export declare const descriptionFileSizeText: import("@linaria/core").LinariaClassName;
11
+ export declare const itemDescriptionLabel: import("@linaria/core").LinariaClassName;
10
12
  export declare const itemDescriptionText: import("@linaria/core").LinariaClassName;
11
13
  export declare const errorIcon: import("@linaria/core").LinariaClassName;
12
14
  export declare const desktopErrorMessage: import("@linaria/core").LinariaClassName;
13
15
  export declare const mobileErrorMessage: import("@linaria/core").LinariaClassName;
14
16
  export declare const actionContainer: import("@linaria/core").LinariaClassName;
17
+ export declare const inlineActionContainer: import("@linaria/core").LinariaClassName;
15
18
  export declare const iconButton: import("@linaria/core").LinariaClassName;
@@ -1,2 +1,2 @@
1
- import"./file-list-item.styles_y7my2m.css";const e="i18pxk0j",i="dqb8x5u",l="bddx9rr",t="c1dhzflv",s="nk38w4a",d="elwke9e",f="f14h64yt",m="f1wv8fjl",o="iivlkvo",k="e1jm950n",p="d1vgco4e",v="map0p9n",a="a1gk2zsk",c="i1wh4bod";export{a as actionContainer,l as box,t as contentSection,p as desktopErrorMessage,i as dragHandleIcon,k as errorIcon,d as extendedNameSection,f as fileSizeSection,m as fileSizeText,c as iconButton,e as item,o as itemDescriptionText,v as mobileErrorMessage,s as nameSection};
1
+ import"./file-list-item.styles_o8000f.css";const i="i18pxk0j",e="dqb8x5u",l="bddx9rr",o="c1dhzflv",f="nk38w4a",t="elwke9e",d="f14h64yt",s="f1wv8fjl",v="divlkvo",k="i1jm950n",p="i1vgco4e",m="eap0p9n",r="d1gk2zsk",a="m1wh4bod",c="a3rvfgv",n="i5ozu70",u="ilou5qo";export{c as actionContainer,l as box,o as contentSection,v as descriptionFileSizeText,r as desktopErrorMessage,e as dragHandleIcon,m as errorIcon,t as extendedNameSection,d as fileSizeSection,s as fileSizeText,u as iconButton,n as inlineActionContainer,i as item,k as itemDescriptionLabel,p as itemDescriptionText,a as mobileErrorMessage,f as nameSection};
2
2
  //# sourceMappingURL=file-list-item.styles.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-list-item.styles.js","sources":["../../../src/file-upload/file-list-item/file-list-item.styles.ts"],"sourcesContent":["import { css } from \"@linaria/core\";\n\nimport {\n Border,\n Colour,\n MediaQuery,\n Radius,\n Shadow,\n Spacing,\n} from \"../../theme\";\n\nexport type ItemFocusType = \"self\" | \"others\" | \"none\";\n\nexport const item = css`\n display: flex;\n align-items: center;\n width: 100%;\n border: none;\n\n &:not(:last-child) {\n margin-bottom: ${Spacing[\"spacing-16\"]};\n }\n &[data-item-state=\"disabled\"] {\n cursor: not-allowed;\n }\n\n &[data-item-state=\"sortable\"] {\n &:hover {\n cursor: grab;\n }\n\n // Following recommendation by the library for touch events\n // https://docs.dndkit.com/api-documentation/sensors/touch#recommendations\n touch-action: manipulation;\n }\n\n &[data-item-state=\"sortable-active\"] {\n cursor: grabbing;\n\n // Following recommendation by the library for touch events\n // https://docs.dndkit.com/api-documentation/sensors/touch#recommendations\n touch-action: manipulation;\n }\n`;\n\nexport const dragHandleIcon = css`\n margin-right: ${Spacing[\"spacing-16\"]};\n height: 1.5rem;\n width: 1.5rem;\n color: ${Colour[\"icon\"]};\n\n &[data-drag-handle-state=\"active\"] {\n color: ${Colour[\"icon-primary\"]};\n }\n\n &[data-drag-handle-state=\"disabled\"] {\n color: ${Colour[\"icon-disabled\"]};\n }\n`;\n\nexport const box = css`\n background: ${Colour[\"bg-primary-subtlest\"]};\n border: ${Border[\"width-010\"]} ${Border[\"solid\"]} ${Colour[\"border\"]};\n border-radius: ${Radius[\"sm\"]};\n padding: ${Spacing[\"spacing-16\"]} ${Spacing[\"spacing-32\"]};\n display: flex;\n align-items: center;\n width: 100%;\n\n ${MediaQuery.MaxWidth.md} {\n padding: ${Spacing[\"spacing-16\"]};\n }\n\n &[data-box-state=\"focused\"] {\n border-color: ${Colour[\"border-focus\"]};\n box-shadow: ${Shadow[\"xs-focus-strong\"]};\n }\n\n &[data-box-state=\"disabled\"] {\n border-color: ${Colour[\"border-disabled\"]};\n }\n\n &[data-box-state=\"error\"] {\n background: ${Colour[\"bg-error\"]};\n border-color: ${Colour[\"border-error\"]};\n }\n\n &[data-stack-mobile=\"true\"] {\n ${MediaQuery.MaxWidth.md} {\n flex-direction: column;\n align-items: flex-start;\n }\n }\n`;\n\nexport const contentSection = css`\n display: flex;\n flex: 1;\n align-items: center;\n\n ${MediaQuery.MaxWidth.md} {\n flex-direction: column;\n width: 100%;\n align-items: flex-start;\n }\n\n &[data-has-thumbnail=\"true\"] {\n ${MediaQuery.MaxWidth.md} {\n flex-direction: row;\n align-items: center;\n }\n }\n`;\n\nexport const nameSection = css`\n display: flex;\n flex: 1;\n flex-direction: column;\n width: 100%;\n`;\n\nexport const extendedNameSection = css`\n display: flex;\n flex: 1;\n align-items: center;\n\n ${MediaQuery.MaxWidth.md} {\n flex-direction: column;\n align-items: flex-start;\n width: 100%;\n }\n`;\n\nexport const fileSizeSection = css`\n display: flex;\n width: 5rem;\n margin-left: ${Spacing[\"spacing-8\"]};\n justify-content: flex-end;\n\n &[data-mobile-visibility=\"hidden\"] {\n ${MediaQuery.MaxWidth.md} {\n display: none;\n visibility: hidden;\n }\n }\n\n &[data-mobile-visibility=\"expand\"] {\n ${MediaQuery.MaxWidth.md} {\n width: 100%;\n margin-left: 0;\n margin-top: ${Spacing[\"spacing-8\"]};\n justify-content: flex-start;\n }\n }\n`;\n\nexport const fileSizeText = css`\n color: ${Colour[\"text-subtler\"]};\n`;\n\nexport const itemDescriptionText = css`\n margin-top: ${Spacing[\"spacing-4\"]};\n`;\n\nexport const errorIcon = css`\n height: 1lh;\n width: 1em;\n flex-shrink: 0;\n color: ${Colour[\"icon-error-strong\"]};\n`;\n\nexport const desktopErrorMessage = css`\n color: ${Colour[\"text-error\"]};\n margin-top: ${Spacing[\"spacing-4\"]};\n display: flex;\n gap: ${Spacing[\"spacing-4\"]};\n\n ${MediaQuery.MaxWidth.md} {\n display: none;\n visibility: hidden;\n }\n`;\n\nexport const mobileErrorMessage = css`\n color: ${Colour[\"text-error\"]};\n display: none;\n visibility: hidden;\n\n ${MediaQuery.MaxWidth.md} {\n display: flex;\n gap: ${Spacing[\"spacing-4\"]};\n visibility: visible;\n margin-top: ${Spacing[\"spacing-8\"]};\n }\n`;\n\nexport const actionContainer = css`\n width: 6rem;\n margin-left: ${Spacing[\"spacing-32\"]};\n display: flex;\n justify-content: flex-end;\n align-items: center;\n\n ${MediaQuery.MaxWidth.md} {\n width: fit-content;\n }\n\n &[data-mobile-layout=\"loading\"] {\n ${MediaQuery.MaxWidth.md} {\n margin-left: 0;\n margin-top: ${Spacing[\"spacing-16\"]};\n width: 100%;\n }\n }\n\n &[data-mobile-layout=\"editable\"] {\n ${MediaQuery.MaxWidth.md} {\n margin-left: 0;\n margin-top: ${Spacing[\"spacing-16\"]};\n align-self: flex-end;\n }\n }\n`;\n\nexport const iconButton = css`\n min-width: unset;\n\n &:not(:last-child) {\n margin-right: ${Spacing[\"spacing-16\"]};\n }\n`;\n"],"names":["item","dragHandleIcon","box","contentSection","nameSection","extendedNameSection","fileSizeSection","fileSizeText","itemDescriptionText","errorIcon","desktopErrorMessage","mobileErrorMessage","actionContainer","iconButton"],"mappings":"qFAaO,MAAMA,EAAI,WAgCJC,EAAc,UAedC,EAAG,UAmCHC,EAAc,WAmBdC,EAAW,UAOXC,EAAmB,UAYnBC,EAAe,WAuBfC,EAAY,WAIZC,EAAmB,UAInBC,EAAS,WAOTC,EAAmB,WAYnBC,EAAkB,UAalBC,EAAe,WA4BfC,EAAU"}
1
+ {"version":3,"file":"file-list-item.styles.js","sources":["../../../src/file-upload/file-list-item/file-list-item.styles.ts"],"sourcesContent":["import { css } from \"@linaria/core\";\n\nimport {\n Border,\n Colour,\n Font,\n MediaQuery,\n Radius,\n Shadow,\n Spacing,\n} from \"../../theme\";\n\nexport type ItemFocusType = \"self\" | \"others\" | \"none\";\n\nexport const item = css`\n display: flex;\n align-items: center;\n width: 100%;\n border: none;\n\n &:not(:last-child) {\n margin-bottom: ${Spacing[\"spacing-16\"]};\n }\n &[data-item-state=\"disabled\"] {\n cursor: not-allowed;\n }\n\n &[data-item-state=\"sortable\"] {\n &:hover {\n cursor: grab;\n }\n\n // Following recommendation by the library for touch events\n // https://docs.dndkit.com/api-documentation/sensors/touch#recommendations\n touch-action: manipulation;\n }\n\n &[data-item-state=\"sortable-active\"] {\n cursor: grabbing;\n\n // Following recommendation by the library for touch events\n // https://docs.dndkit.com/api-documentation/sensors/touch#recommendations\n touch-action: manipulation;\n }\n`;\n\nexport const dragHandleIcon = css`\n margin-right: ${Spacing[\"spacing-16\"]};\n height: 1.5rem;\n width: 1.5rem;\n color: ${Colour[\"icon\"]};\n\n &[data-drag-handle-state=\"active\"] {\n color: ${Colour[\"icon-primary\"]};\n }\n\n &[data-drag-handle-state=\"disabled\"] {\n color: ${Colour[\"icon-disabled\"]};\n }\n`;\n\nexport const box = css`\n background: ${Colour[\"bg-primary-subtlest\"]};\n border: ${Border[\"width-010\"]} ${Border[\"solid\"]} ${Colour[\"border\"]};\n border-radius: ${Radius[\"sm\"]};\n padding: ${Spacing[\"spacing-16\"]} ${Spacing[\"spacing-32\"]};\n display: flex;\n align-items: center;\n width: 100%;\n\n ${MediaQuery.MaxWidth.md} {\n padding: ${Spacing[\"spacing-16\"]};\n }\n\n &[data-box-state=\"focused\"] {\n border-color: ${Colour[\"border-focus\"]};\n box-shadow: ${Shadow[\"xs-focus-strong\"]};\n }\n\n &[data-box-state=\"disabled\"] {\n border-color: ${Colour[\"border-disabled\"]};\n }\n\n &[data-box-state=\"error\"] {\n background: ${Colour[\"bg-error\"]};\n border-color: ${Colour[\"border-error\"]};\n }\n\n &[data-stack-mobile=\"true\"] {\n ${MediaQuery.MaxWidth.md} {\n flex-direction: column;\n align-items: flex-start;\n }\n }\n`;\n\nexport const contentSection = css`\n display: flex;\n flex: 1;\n align-items: center;\n\n ${MediaQuery.MaxWidth.md} {\n flex-direction: column;\n width: 100%;\n align-items: flex-start;\n }\n\n &[data-has-thumbnail=\"true\"] {\n ${MediaQuery.MaxWidth.md} {\n flex-direction: row;\n align-items: center;\n }\n }\n`;\n\nexport const nameSection = css`\n display: flex;\n flex: 1;\n flex-direction: column;\n width: 100%;\n`;\n\nexport const extendedNameSection = css`\n display: flex;\n flex: 1;\n flex-direction: column;\n align-items: flex-start;\n\n ${MediaQuery.MaxWidth.md} {\n width: 100%;\n }\n`;\n\nexport const fileSizeSection = css`\n display: flex;\n width: 5rem;\n margin-left: ${Spacing[\"spacing-8\"]};\n justify-content: flex-end;\n\n &[data-mobile-visibility=\"hidden\"] {\n ${MediaQuery.MaxWidth.md} {\n display: none;\n visibility: hidden;\n }\n }\n\n &[data-mobile-visibility=\"expand\"] {\n ${MediaQuery.MaxWidth.md} {\n width: 100%;\n margin-left: 0;\n margin-top: ${Spacing[\"spacing-8\"]};\n justify-content: flex-start;\n }\n }\n`;\n\nexport const fileSizeText = css`\n color: ${Colour[\"text-subtler\"]};\n`;\n\nexport const descriptionFileSizeText = css`\n color: ${Colour[\"text-subtler\"]};\n margin-top: ${Spacing[\"spacing-16\"]};\n`;\n\nexport const itemDescriptionLabel = css`\n ${Font[\"form-label\"]}\n font-weight: ${Font.Spec[\"weight-semibold\"]};\n color: ${Colour[\"text-subtle\"]};\n margin-top: ${Spacing[\"spacing-16\"]};\n`;\n\nexport const itemDescriptionText = css`\n margin-top: ${Spacing[\"spacing-4\"]};\n`;\n\nexport const errorIcon = css`\n height: 1lh;\n width: 1em;\n flex-shrink: 0;\n color: ${Colour[\"icon-error-strong\"]};\n`;\n\nexport const desktopErrorMessage = css`\n color: ${Colour[\"text-error\"]};\n margin-top: ${Spacing[\"spacing-4\"]};\n display: flex;\n gap: ${Spacing[\"spacing-4\"]};\n\n ${MediaQuery.MaxWidth.md} {\n display: none;\n visibility: hidden;\n }\n`;\n\nexport const mobileErrorMessage = css`\n color: ${Colour[\"text-error\"]};\n display: none;\n visibility: hidden;\n\n ${MediaQuery.MaxWidth.md} {\n display: flex;\n gap: ${Spacing[\"spacing-4\"]};\n visibility: visible;\n margin-top: ${Spacing[\"spacing-8\"]};\n }\n`;\n\nexport const actionContainer = css`\n width: 6rem;\n margin-left: ${Spacing[\"spacing-32\"]};\n display: flex;\n justify-content: flex-end;\n align-items: center;\n\n ${MediaQuery.MaxWidth.md} {\n width: fit-content;\n }\n\n &[data-mobile-layout=\"loading\"] {\n ${MediaQuery.MaxWidth.md} {\n margin-left: 0;\n margin-top: ${Spacing[\"spacing-16\"]};\n width: 100%;\n }\n }\n\n &[data-mobile-layout=\"editable\"] {\n ${MediaQuery.MaxWidth.md} {\n margin-left: 0;\n margin-top: ${Spacing[\"spacing-16\"]};\n align-self: flex-end;\n }\n }\n`;\n\nexport const inlineActionContainer = css`\n width: 100%;\n margin-top: ${Spacing[\"spacing-16\"]};\n display: flex;\n justify-content: flex-end;\n align-items: center;\n`;\n\nexport const iconButton = css`\n min-width: unset;\n\n &:not(:last-child) {\n margin-right: ${Spacing[\"spacing-8\"]};\n }\n`;\n"],"names":["item","dragHandleIcon","box","contentSection","nameSection","extendedNameSection","fileSizeSection","fileSizeText","descriptionFileSizeText","itemDescriptionLabel","itemDescriptionText","errorIcon","desktopErrorMessage","mobileErrorMessage","actionContainer","inlineActionContainer","iconButton"],"mappings":"qFAcO,MAAMA,EAAI,WAgCJC,EAAc,UAedC,EAAG,UAmCHC,EAAc,WAmBdC,EAAW,UAOXC,EAAmB,UAWnBC,EAAe,WAuBfC,EAAY,WAIZC,EAAuB,UAKvBC,EAAoB,WAOpBC,EAAmB,WAInBC,EAAS,UAOTC,EAAmB,WAYnBC,EAAkB,WAalBC,EAAe,UA4BfC,EAAqB,UAQrBC,EAAU"}
@@ -0,0 +1,17 @@
1
+ @layer fds{.i18pxk0j{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%;border:none;}.i18pxk0j:not(:last-child){margin-bottom:var(--fds-spacing-16);}.i18pxk0j[data-item-state="disabled"]{cursor:not-allowed;}.i18pxk0j[data-item-state="sortable"]{touch-action:manipulation;}.i18pxk0j[data-item-state="sortable"]:hover{cursor:-webkit-grab;cursor:grab;}.i18pxk0j[data-item-state="sortable-active"]{cursor:-webkit-grabbing;cursor:grabbing;touch-action:manipulation;}
2
+ .dqb8x5u{margin-right:var(--fds-spacing-16);height:1.5rem;width:1.5rem;color:var(--fds-colour-icon);}.dqb8x5u[data-drag-handle-state="active"]{color:var(--fds-colour-icon-primary);}.dqb8x5u[data-drag-handle-state="disabled"]{color:var(--fds-colour-icon-disabled);}
3
+ .bddx9rr{background:var(--fds-colour-bg-primary-subtlest);border:var(--fds-border-width-010) var(--fds-border-style-solid) var(--fds-colour-border);border-radius:var(--fds-radius-sm);padding:var(--fds-spacing-16) var(--fds-spacing-32);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%;}:where(body.fds-breakpoint-md-max) .bddx9rr{padding:var(--fds-spacing-16);}.bddx9rr[data-box-state="focused"]{border-color:var(--fds-colour-border-focus);box-shadow:var(--fds-shadow-xs-focus-strong);}.bddx9rr[data-box-state="disabled"]{border-color:var(--fds-colour-border-disabled);}.bddx9rr[data-box-state="error"]{background:var(--fds-colour-bg-error);border-color:var(--fds-colour-border-error);}:where(body.fds-breakpoint-md-max) .bddx9rr[data-stack-mobile="true"]{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:flex-start;-webkit-box-align:flex-start;-ms-flex-align:flex-start;align-items:flex-start;}
4
+ .c1dhzflv{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:1;-ms-flex:1;flex:1;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}:where(body.fds-breakpoint-md-max) .c1dhzflv{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;width:100%;-webkit-align-items:flex-start;-webkit-box-align:flex-start;-ms-flex-align:flex-start;align-items:flex-start;}:where(body.fds-breakpoint-md-max) .c1dhzflv[data-has-thumbnail="true"]{-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}
5
+ .nk38w4a{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:1;-ms-flex:1;flex:1;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;width:100%;}
6
+ .elwke9e{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:1;-ms-flex:1;flex:1;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:flex-start;-webkit-box-align:flex-start;-ms-flex-align:flex-start;align-items:flex-start;}:where(body.fds-breakpoint-md-max) .elwke9e{width:100%;}
7
+ .f14h64yt{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;width:5rem;margin-left:var(--fds-spacing-8);-webkit-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end;}:where(body.fds-breakpoint-md-max) .f14h64yt[data-mobile-visibility="hidden"]{display:none;visibility:hidden;}:where(body.fds-breakpoint-md-max) .f14h64yt[data-mobile-visibility="expand"]{width:100%;margin-left:0;margin-top:var(--fds-spacing-8);-webkit-box-pack:start;-ms-flex-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start;}
8
+ .f1wv8fjl{color:var(--fds-colour-text-subtler);}
9
+ .divlkvo{color:var(--fds-colour-text-subtler);margin-top:var(--fds-spacing-16);}
10
+ .i1jm950n{font-family:var(--fds-font-family-body);font-variant:var(--fds-font-variant);font-size:var(--fds-font-form-label-size);font-weight:var(--fds-font-weight-semibold);line-height:var(--fds-font-form-label-lh);letter-spacing:var(--fds-font-form-label-ls);font-weight:var(--fds-font-weight-semibold);color:var(--fds-colour-text-subtle);margin-top:var(--fds-spacing-16);}
11
+ .i1vgco4e{margin-top:var(--fds-spacing-4);}
12
+ .eap0p9n{height:1lh;width:1em;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;color:var(--fds-colour-icon-error-strong);}
13
+ .d1gk2zsk{color:var(--fds-colour-text-error);margin-top:var(--fds-spacing-4);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;gap:var(--fds-spacing-4);}:where(body.fds-breakpoint-md-max) .d1gk2zsk{display:none;visibility:hidden;}
14
+ .m1wh4bod{color:var(--fds-colour-text-error);display:none;visibility:hidden;}:where(body.fds-breakpoint-md-max) .m1wh4bod{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;gap:var(--fds-spacing-4);visibility:visible;margin-top:var(--fds-spacing-8);}
15
+ .a3rvfgv{width:6rem;margin-left:var(--fds-spacing-32);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}:where(body.fds-breakpoint-md-max) .a3rvfgv{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}:where(body.fds-breakpoint-md-max) .a3rvfgv[data-mobile-layout="loading"]{margin-left:0;margin-top:var(--fds-spacing-16);width:100%;}:where(body.fds-breakpoint-md-max) .a3rvfgv[data-mobile-layout="editable"]{margin-left:0;margin-top:var(--fds-spacing-16);-webkit-align-self:flex-end;-ms-flex-item-align:end;align-self:flex-end;}
16
+ .i5ozu70{width:100%;margin-top:var(--fds-spacing-16);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}
17
+ .ilou5qo{min-width:unset;}.ilou5qo:not(:last-child){margin-right:var(--fds-spacing-8);}}
@@ -1,2 +1,3 @@
1
1
  import type { FileUploadProps } from "./types";
2
- export declare const FileUpload: ({ styleType, fileItems, title, description, maxFiles, warning, className, name, id, "data-testid": testId, accept, capture, multiple, disabled, sortable, fileDescriptionMaxLength, editableFileItems, errorMessage, readOnly, customLabels, onChange, onDelete, onEdit, onSort, }: FileUploadProps) => import("react/jsx-runtime").JSX.Element;
2
+ /** Allows user to upload images via drag-and-drop or a native file dialog. */
3
+ export declare const FileUpload: ({ styleType, fileItems, title, description, maxFiles, warning, className, name, id, "data-testid": testId, accept, capture, multiple, disabled, sortable, fileDescriptionMaxLength, editableFileItems, descriptionRequired, descriptionLabel, errorMessage, readOnly, customLabels, onChange, onDelete, onEdit, onSort, }: FileUploadProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,2 +1,2 @@
1
- import{jsx as e,jsxs as t}from"react/jsx-runtime";import{useRef as r,useState as l}from"react";import{Alert as o}from"../alert/alert.js";import{Button as i}from"../button/button.js";import{Markup as a}from"../markup/markup.js";import{Typography as n}from"../typography/index.js";import{FileUploadContext as s}from"./context.js";import{FileUploadDropzone as d}from"./dropzone.js";import{FileList as c}from"./file-list/file-list.js";import{textContainer as m,warningAlert as p,errorAlert as u,uploadButtonContainer as f,uploadButton as h,uploadButtonText as b,markupContainer as y,description as v}from"./file-upload.styles.js";const g=({styleType:g="bordered",fileItems:N,title:x,description:j,maxFiles:D,warning:I,className:B,name:z,id:M,"data-testid":L,accept:T,capture:F,multiple:S,disabled:k,sortable:w=!1,fileDescriptionMaxLength:C,editableFileItems:O=!1,errorMessage:U,readOnly:A,customLabels:E,onChange:P,onDelete:$,onEdit:q,onSort:G})=>{const H={uploadButton:(null==E?void 0:E.uploadButtonLabel)||"Upload files"},J=r(null),K=r(null),[Q,R]=l(),V=e=>{var t;if(void 0===D)return e;const r=null!==(t=null==N?void 0:N.length)&&void 0!==t?t:0,l=Math.max(D-r,0);return e.slice(0,l)},W=()=>!(!D||!N)&&N.length>=D;return e(s.Provider,{value:{activeId:Q,setActiveId:R},children:t(d,{ref:J,onChange:e=>{var t;const r=V(e);!k&&P&&r.length>0&&(P(r),null===(t=K.current)||void 0===t||t.focus())},id:M?`${M}-dropzone`:"dropzone",accept:T,capture:F,border:"bordered"===g,className:B,"data-testid":L,name:z,multiple:S,disabled:k||W()||A,children:[!(!x&&!j)&&t("div",{className:m,children:[x?"string"==typeof x?e(n.BodyBL,{children:x}):e(a,{className:y,baseTextSize:"body-baseline",children:x}):null,j?"string"==typeof j?e(n.BodyMD,{className:v,children:j}):e(a,{className:y,baseTextSize:"body-md",children:j}):null]}),!!I&&e(o,{className:p,type:"warning",children:I}),e(c,{ref:K,fileItems:N,editableFileItems:O,fileDescriptionMaxLength:C,sortable:w,disabled:k,readOnly:A,onItemDelete:e=>{var t;$&&($(e),null===(t=K.current)||void 0===t||t.focus())},onItemUpdate:e=>{q&&q(e)},onSort:e=>{G&&G(e)}}),U&&e(o,{className:u,type:"error",children:U}),!A&&t("div",{className:f,children:[e(i,{type:"button",sizeType:"small",styleType:"secondary",disabled:!!Q||k||W(),onClick:e=>{k||(e.preventDefault(),J.current&&J.current.openFileDialog())},className:h,children:H.uploadButton}),e(n.BodyMD,{className:b,weight:"semibold",children:"or drop them here"})]})]})})};export{g as FileUpload};
1
+ import{jsx as e,jsxs as t}from"react/jsx-runtime";import{useRef as r,useState as l}from"react";import{Alert as i}from"../alert/alert.js";import{Button as o}from"../button/button.js";import{Markup as a}from"../markup/markup.js";import{Typography as n}from"../typography/index.js";import{FileUploadContext as s}from"./context.js";import{FileUploadDropzone as d}from"./dropzone.js";import{FileList as c}from"./file-list/file-list.js";import{textContainer as m,warningAlert as p,errorAlert as u,uploadButtonContainer as f,uploadButton as b,uploadButtonText as h,markupContainer as y,description as v}from"./file-upload.styles.js";const g=({styleType:g="bordered",fileItems:N,title:x,description:j,maxFiles:D,warning:I,className:B,name:L,id:z,"data-testid":M,accept:T,capture:F,multiple:S,disabled:k,sortable:w=!1,fileDescriptionMaxLength:C,editableFileItems:q=!1,descriptionRequired:O=!0,descriptionLabel:R,errorMessage:U,readOnly:A,customLabels:E,onChange:P,onDelete:$,onEdit:G,onSort:H})=>{const J={uploadButton:(null==E?void 0:E.uploadButtonLabel)||"Upload files"},K=r(null),Q=r(null),[V,W]=l(),X=e=>{var t;if(void 0===D)return e;const r=null!==(t=null==N?void 0:N.length)&&void 0!==t?t:0,l=Math.max(D-r,0);return e.slice(0,l)},Y=()=>!(!D||!N)&&N.length>=D;return e(s.Provider,{value:{activeId:V,setActiveId:W},children:t(d,{ref:K,onChange:e=>{var t;const r=X(e);!k&&P&&r.length>0&&(P(r),null===(t=Q.current)||void 0===t||t.focus())},id:z?`${z}-dropzone`:"dropzone",accept:T,capture:F,border:"bordered"===g,className:B,"data-testid":M,name:L,multiple:S,disabled:k||Y()||A,children:[!(!x&&!j)&&t("div",{className:m,children:[x?"string"==typeof x?e(n.BodyBL,{children:x}):e(a,{className:y,baseTextSize:"body-baseline",children:x}):null,j?"string"==typeof j?e(n.BodyMD,{className:v,children:j}):e(a,{className:y,baseTextSize:"body-md",children:j}):null]}),!!I&&e(i,{className:p,type:"warning",children:I}),e(c,{ref:Q,fileItems:N,editableFileItems:q,descriptionRequired:O,descriptionLabel:R,fileDescriptionMaxLength:C,sortable:w,disabled:k,readOnly:A,onItemDelete:e=>{var t;$&&($(e),null===(t=Q.current)||void 0===t||t.focus())},onItemUpdate:e=>{G&&G(e)},onSort:e=>{H&&H(e)}}),U&&e(i,{className:u,type:"error",children:U}),!A&&t("div",{className:f,children:[e(o,{type:"button",sizeType:"small",styleType:"secondary",disabled:!!V||k||Y(),onClick:e=>{k||(e.preventDefault(),K.current&&K.current.openFileDialog())},className:b,children:J.uploadButton}),e(n.BodyMD,{className:h,weight:"semibold",children:"or drop them here"})]})]})})};export{g as FileUpload};
2
2
  //# sourceMappingURL=file-upload.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-upload.js","sources":["../../src/file-upload/file-upload.tsx"],"sourcesContent":["import { useRef, useState } from \"react\";\n\nimport { Alert } from \"../alert\";\nimport { Button } from \"../button\";\nimport { Markup } from \"../markup\";\nimport { Typography } from \"../typography\";\nimport { FileUploadContext } from \"./context\";\nimport type { DropzoneElement } from \"./dropzone\";\nimport { FileUploadDropzone } from \"./dropzone\";\nimport type { FileListRef } from \"./file-list\";\nimport { FileList } from \"./file-list\";\nimport * as styles from \"./file-upload.styles\";\nimport type { FileItemProps, FileUploadProps } from \"./types\";\n\nexport const FileUpload = ({\n styleType = \"bordered\",\n fileItems,\n title,\n description,\n maxFiles,\n warning,\n className,\n name,\n id,\n \"data-testid\": testId,\n accept,\n capture,\n multiple,\n disabled,\n sortable = false,\n fileDescriptionMaxLength,\n editableFileItems = false,\n errorMessage,\n readOnly,\n customLabels,\n onChange,\n onDelete,\n onEdit,\n onSort,\n}: FileUploadProps) => {\n const labels = {\n uploadButton: customLabels?.uploadButtonLabel || \"Upload files\",\n };\n // =========================================================================\n // CONST, STATE, REFS\n // =========================================================================\n const dropzoneRef = useRef<DropzoneElement>(null);\n const fileListRef = useRef<FileListRef>(null);\n const [activeId, setActiveId] = useState<string>();\n\n // =========================================================================\n // EVENT HANDLERS\n // =========================================================================\n const handleChange = (files: File[]) => {\n const filesToProcess = limitIncomingFiles(files);\n\n if (!disabled && onChange && filesToProcess.length > 0) {\n onChange(filesToProcess);\n fileListRef.current?.focus();\n }\n };\n\n const handleItemDelete = (item: FileItemProps) => {\n if (onDelete) {\n onDelete(item);\n fileListRef.current?.focus();\n }\n };\n\n const handleUploadButtonClick = (\n event: React.MouseEvent<HTMLButtonElement>\n ) => {\n if (!disabled) {\n event.preventDefault();\n if (dropzoneRef.current) {\n dropzoneRef.current.openFileDialog();\n }\n }\n };\n\n const handleItemUpdate = (updatedItem: FileItemProps) => {\n if (onEdit) {\n onEdit(updatedItem);\n }\n };\n\n const handleSort = (updatedItems: FileItemProps[]) => {\n if (onSort) {\n onSort(updatedItems);\n }\n };\n\n // =========================================================================\n // HELPER FUNCTIONS\n // =========================================================================\n const limitIncomingFiles = (files: File[]) => {\n if (maxFiles === undefined) {\n return files;\n }\n\n const existingItemsCount = fileItems?.length ?? 0;\n const remainingSlots = Math.max(maxFiles - existingItemsCount, 0);\n\n return files.slice(0, remainingSlots);\n };\n\n const reachedMaxFiles = () => {\n return maxFiles && fileItems ? fileItems.length >= maxFiles : false;\n };\n\n // =========================================================================\n // RENDER FUNCTIONS\n // =========================================================================\n const renderTitle = () => {\n if (!title) {\n return null;\n }\n\n if (typeof title === \"string\") {\n return <Typography.BodyBL>{title}</Typography.BodyBL>;\n }\n\n return (\n <Markup\n className={styles.markupContainer}\n baseTextSize=\"body-baseline\"\n >\n {title}\n </Markup>\n );\n };\n\n const renderDescription = () => {\n if (!description) {\n return null;\n }\n\n if (typeof description === \"string\") {\n return (\n <Typography.BodyMD className={styles.description}>\n {description}\n </Typography.BodyMD>\n );\n }\n\n return (\n <Markup className={styles.markupContainer} baseTextSize=\"body-md\">\n {description}\n </Markup>\n );\n };\n\n return (\n <FileUploadContext.Provider value={{ activeId, setActiveId }}>\n <FileUploadDropzone\n ref={dropzoneRef}\n onChange={handleChange}\n id={id ? `${id}-dropzone` : \"dropzone\"}\n accept={accept}\n capture={capture}\n border={styleType === \"bordered\"}\n className={className}\n data-testid={testId}\n name={name}\n multiple={multiple}\n disabled={disabled || reachedMaxFiles() || readOnly}\n >\n {!!(title || description) && (\n <div className={styles.textContainer}>\n {renderTitle()}\n {renderDescription()}\n </div>\n )}\n {!!warning && (\n <Alert className={styles.warningAlert} type=\"warning\">\n {warning}\n </Alert>\n )}\n <FileList\n ref={fileListRef}\n fileItems={fileItems}\n editableFileItems={editableFileItems}\n fileDescriptionMaxLength={fileDescriptionMaxLength}\n sortable={sortable}\n disabled={disabled}\n readOnly={readOnly}\n onItemDelete={handleItemDelete}\n onItemUpdate={handleItemUpdate}\n onSort={handleSort}\n />\n {errorMessage && (\n <Alert className={styles.errorAlert} type=\"error\">\n {errorMessage}\n </Alert>\n )}\n {!readOnly && (\n <div className={styles.uploadButtonContainer}>\n <Button\n type=\"button\"\n sizeType=\"small\"\n styleType=\"secondary\"\n disabled={\n !!activeId || disabled || reachedMaxFiles()\n }\n onClick={handleUploadButtonClick}\n className={styles.uploadButton}\n >\n {labels.uploadButton}\n </Button>\n <Typography.BodyMD\n className={styles.uploadButtonText}\n weight=\"semibold\"\n >\n or drop them here\n </Typography.BodyMD>\n </div>\n )}\n </FileUploadDropzone>\n </FileUploadContext.Provider>\n );\n};\n"],"names":["FileUpload","styleType","fileItems","title","description","maxFiles","warning","className","name","id","testId","accept","capture","multiple","disabled","sortable","fileDescriptionMaxLength","editableFileItems","errorMessage","readOnly","customLabels","onChange","onDelete","onEdit","onSort","labels","uploadButton","uploadButtonLabel","dropzoneRef","useRef","fileListRef","activeId","setActiveId","useState","limitIncomingFiles","files","undefined","existingItemsCount","_a","length","remainingSlots","Math","max","slice","reachedMaxFiles","_jsx","FileUploadContext","Provider","value","children","_jsxs","FileUploadDropzone","ref","filesToProcess","current","focus","border","styles.textContainer","Typography","BodyBL","Markup","styles.markupContainer","baseTextSize","BodyMD","styles.description","Alert","styles.warningAlert","type","FileList","onItemDelete","item","onItemUpdate","updatedItem","updatedItems","styles.errorAlert","styles.uploadButtonContainer","Button","sizeType","onClick","event","preventDefault","openFileDialog","styles.uploadButton","styles.uploadButtonText","weight"],"mappings":"knBAcO,MAAMA,EAAa,EACtBC,YAAY,WACZC,YACAC,QAAKC,YACLA,EACAC,WACAC,UACAC,YACAC,OACAC,KACA,cAAeC,EACfC,SACAC,UACAC,WACAC,WACAC,YAAW,EACXC,2BACAC,qBAAoB,EACpBC,eACAC,WACAC,eACAC,WACAC,WACAC,SACAC,aAEA,MAAMC,EAAS,CACXC,cAAcN,eAAAA,EAAcO,oBAAqB,gBAK/CC,EAAcC,EAAwB,MACtCC,EAAcD,EAAoB,OACjCE,EAAUC,GAAeC,IA+C1BC,EAAsBC,UACxB,QAAiBC,IAAb/B,EACA,OAAO8B,EAGX,MAAME,EAAsC,QAAjBC,EAAApC,aAAS,EAATA,EAAWqC,cAAM,IAAAD,EAAAA,EAAI,EAC1CE,EAAiBC,KAAKC,IAAIrC,EAAWgC,EAAoB,GAE/D,OAAOF,EAAMQ,MAAM,EAAGH,EAAe,EAGnCI,EAAkB,OACbvC,IAAYH,IAAYA,EAAUqC,QAAUlC,EA6CvD,OACIwC,EAACC,EAAkBC,SAAQ,CAACC,MAAO,CAAEjB,WAAUC,eAAaiB,SACxDC,EAACC,EAAkB,CACfC,IAAKxB,EACLP,SAvGUc,UAClB,MAAMkB,EAAiBnB,EAAmBC,IAErCrB,GAAYO,GAAYgC,EAAed,OAAS,IACjDlB,EAASgC,GACU,QAAnBf,EAAAR,EAAYwB,eAAO,IAAAhB,GAAAA,EAAEiB,QACzB,EAkGQ9C,GAAIA,EAAK,GAAGA,aAAgB,WAC5BE,OAAQA,EACRC,QAASA,EACT4C,OAAsB,aAAdvD,EACRM,UAAWA,EAAS,cACPG,EACbF,KAAMA,EACNK,SAAUA,EACVC,SAAUA,GAAY8B,KAAqBzB,EAAQ8B,SAAA,IAE/C9C,IAASC,IACT8C,EAAA,MAAA,CAAK3C,UAAWkD,EAAoBR,SAAA,CAtD3C9C,EAIgB,iBAAVA,EACA0C,EAACa,EAAWC,OAAM,CAAAV,SAAE9C,IAI3B0C,EAACe,EAAM,CACHrD,UAAWsD,EACXC,aAAa,yBAEZ3D,IAZE,KAkBNC,EAIsB,iBAAhBA,EAEHyC,EAACa,EAAWK,OAAM,CAACxD,UAAWyD,EAAkBf,SAC3C7C,IAMTyC,EAACe,EAAM,CAACrD,UAAWsD,EAAwBC,aAAa,mBACnD1D,IAbE,UAuCAE,GACCuC,EAACoB,EAAK,CAAC1D,UAAW2D,EAAqBC,KAAK,UAASlB,SAChD3C,IAGTuC,EAACuB,EAAQ,CACLhB,IAAKtB,EACL5B,UAAWA,EACXe,kBAAmBA,EACnBD,yBAA0BA,EAC1BD,SAAUA,EACVD,SAAUA,EACVK,SAAUA,EACVkD,aA5HUC,UAClBhD,IACAA,EAASgD,GACU,QAAnBhC,EAAAR,EAAYwB,eAAO,IAAAhB,GAAAA,EAAEiB,QACzB,EAyHYgB,aA3GUC,IAClBjD,GACAA,EAAOiD,EACX,EAyGYhD,OAtGIiD,IACZjD,GACAA,EAAOiD,EACX,IAqGSvD,GACG2B,EAACoB,EAAK,CAAC1D,UAAWmE,EAAmBP,KAAK,QAAOlB,SAC5C/B,KAGPC,GACE+B,EAAA,MAAA,CAAK3C,UAAWoE,EAA4B1B,SAAA,CACxCJ,EAAC+B,EAAM,CACHT,KAAK,SACLU,SAAS,QACT5E,UAAU,YACVa,WACMiB,GAAYjB,GAAY8B,IAE9BkC,QAtIpBC,IAEKjE,IACDiE,EAAMC,iBACFpD,EAAY0B,SACZ1B,EAAY0B,QAAQ2B,iBAE5B,EAgIoB1E,UAAW2E,EAAmBjC,SAE7BxB,EAAOC,eAEZmB,EAACa,EAAWK,OAAM,CACdxD,UAAW4E,EACXC,OAAO,WAAUnC,SAAA,6BAOR"}
1
+ {"version":3,"file":"file-upload.js","sources":["../../src/file-upload/file-upload.tsx"],"sourcesContent":["import { useRef, useState } from \"react\";\n\nimport { Alert } from \"../alert\";\nimport { Button } from \"../button\";\nimport { Markup } from \"../markup\";\nimport { Typography } from \"../typography\";\nimport { FileUploadContext } from \"./context\";\nimport type { DropzoneElement } from \"./dropzone\";\nimport { FileUploadDropzone } from \"./dropzone\";\nimport type { FileListRef } from \"./file-list\";\nimport { FileList } from \"./file-list\";\nimport * as styles from \"./file-upload.styles\";\nimport type { FileItemProps, FileUploadProps } from \"./types\";\n\n/** Allows user to upload images via drag-and-drop or a native file dialog. */\nexport const FileUpload = ({\n styleType = \"bordered\",\n fileItems,\n title,\n description,\n maxFiles,\n warning,\n className,\n name,\n id,\n \"data-testid\": testId,\n accept,\n capture,\n multiple,\n disabled,\n sortable = false,\n fileDescriptionMaxLength,\n editableFileItems = false,\n descriptionRequired = true,\n descriptionLabel,\n errorMessage,\n readOnly,\n customLabels,\n onChange,\n onDelete,\n onEdit,\n onSort,\n}: FileUploadProps) => {\n const labels = {\n uploadButton: customLabels?.uploadButtonLabel || \"Upload files\",\n };\n // =========================================================================\n // CONST, STATE, REFS\n // =========================================================================\n const dropzoneRef = useRef<DropzoneElement>(null);\n const fileListRef = useRef<FileListRef>(null);\n const [activeId, setActiveId] = useState<string>();\n\n // =========================================================================\n // EVENT HANDLERS\n // =========================================================================\n const handleChange = (files: File[]) => {\n const filesToProcess = limitIncomingFiles(files);\n\n if (!disabled && onChange && filesToProcess.length > 0) {\n onChange(filesToProcess);\n fileListRef.current?.focus();\n }\n };\n\n const handleItemDelete = (item: FileItemProps) => {\n if (onDelete) {\n onDelete(item);\n fileListRef.current?.focus();\n }\n };\n\n const handleUploadButtonClick = (\n event: React.MouseEvent<HTMLButtonElement>\n ) => {\n if (!disabled) {\n event.preventDefault();\n if (dropzoneRef.current) {\n dropzoneRef.current.openFileDialog();\n }\n }\n };\n\n const handleItemUpdate = (updatedItem: FileItemProps) => {\n if (onEdit) {\n onEdit(updatedItem);\n }\n };\n\n const handleSort = (updatedItems: FileItemProps[]) => {\n if (onSort) {\n onSort(updatedItems);\n }\n };\n\n // =========================================================================\n // HELPER FUNCTIONS\n // =========================================================================\n const limitIncomingFiles = (files: File[]) => {\n if (maxFiles === undefined) {\n return files;\n }\n\n const existingItemsCount = fileItems?.length ?? 0;\n const remainingSlots = Math.max(maxFiles - existingItemsCount, 0);\n\n return files.slice(0, remainingSlots);\n };\n\n const reachedMaxFiles = () => {\n return maxFiles && fileItems ? fileItems.length >= maxFiles : false;\n };\n\n // =========================================================================\n // RENDER FUNCTIONS\n // =========================================================================\n const renderTitle = () => {\n if (!title) {\n return null;\n }\n\n if (typeof title === \"string\") {\n return <Typography.BodyBL>{title}</Typography.BodyBL>;\n }\n\n return (\n <Markup\n className={styles.markupContainer}\n baseTextSize=\"body-baseline\"\n >\n {title}\n </Markup>\n );\n };\n\n const renderDescription = () => {\n if (!description) {\n return null;\n }\n\n if (typeof description === \"string\") {\n return (\n <Typography.BodyMD className={styles.description}>\n {description}\n </Typography.BodyMD>\n );\n }\n\n return (\n <Markup className={styles.markupContainer} baseTextSize=\"body-md\">\n {description}\n </Markup>\n );\n };\n\n return (\n <FileUploadContext.Provider value={{ activeId, setActiveId }}>\n <FileUploadDropzone\n ref={dropzoneRef}\n onChange={handleChange}\n id={id ? `${id}-dropzone` : \"dropzone\"}\n accept={accept}\n capture={capture}\n border={styleType === \"bordered\"}\n className={className}\n data-testid={testId}\n name={name}\n multiple={multiple}\n disabled={disabled || reachedMaxFiles() || readOnly}\n >\n {!!(title || description) && (\n <div className={styles.textContainer}>\n {renderTitle()}\n {renderDescription()}\n </div>\n )}\n {!!warning && (\n <Alert className={styles.warningAlert} type=\"warning\">\n {warning}\n </Alert>\n )}\n <FileList\n ref={fileListRef}\n fileItems={fileItems}\n editableFileItems={editableFileItems}\n descriptionRequired={descriptionRequired}\n descriptionLabel={descriptionLabel}\n fileDescriptionMaxLength={fileDescriptionMaxLength}\n sortable={sortable}\n disabled={disabled}\n readOnly={readOnly}\n onItemDelete={handleItemDelete}\n onItemUpdate={handleItemUpdate}\n onSort={handleSort}\n />\n {errorMessage && (\n <Alert className={styles.errorAlert} type=\"error\">\n {errorMessage}\n </Alert>\n )}\n {!readOnly && (\n <div className={styles.uploadButtonContainer}>\n <Button\n type=\"button\"\n sizeType=\"small\"\n styleType=\"secondary\"\n disabled={\n !!activeId || disabled || reachedMaxFiles()\n }\n onClick={handleUploadButtonClick}\n className={styles.uploadButton}\n >\n {labels.uploadButton}\n </Button>\n <Typography.BodyMD\n className={styles.uploadButtonText}\n weight=\"semibold\"\n >\n or drop them here\n </Typography.BodyMD>\n </div>\n )}\n </FileUploadDropzone>\n </FileUploadContext.Provider>\n );\n};\n"],"names":["FileUpload","styleType","fileItems","title","description","maxFiles","warning","className","name","id","testId","accept","capture","multiple","disabled","sortable","fileDescriptionMaxLength","editableFileItems","descriptionRequired","descriptionLabel","errorMessage","readOnly","customLabels","onChange","onDelete","onEdit","onSort","labels","uploadButton","uploadButtonLabel","dropzoneRef","useRef","fileListRef","activeId","setActiveId","useState","limitIncomingFiles","files","undefined","existingItemsCount","_a","length","remainingSlots","Math","max","slice","reachedMaxFiles","_jsx","FileUploadContext","Provider","value","children","_jsxs","FileUploadDropzone","ref","filesToProcess","current","focus","border","styles.textContainer","Typography","BodyBL","Markup","styles.markupContainer","baseTextSize","BodyMD","styles.description","Alert","styles.warningAlert","type","FileList","onItemDelete","item","onItemUpdate","updatedItem","updatedItems","styles.errorAlert","styles.uploadButtonContainer","Button","sizeType","onClick","event","preventDefault","openFileDialog","styles.uploadButton","styles.uploadButtonText","weight"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
- .t9vodht{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;margin-bottom:var(--fds-spacing-32);gap:var(--fds-spacing-8);}
1
+ @layer fds{.t9vodht{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;margin-bottom:var(--fds-spacing-32);gap:var(--fds-spacing-8);}
2
2
  .m7vp3hf{color:var(--fds-colour-text);}
3
3
  .dhybrj2{color:var(--fds-colour-text-subtler);}
4
4
  .wq1el8u{margin-bottom:var(--fds-spacing-32);}
5
5
  .u723luu{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:flex-end;-webkit-box-align:flex-end;-ms-flex-align:flex-end;align-items:flex-end;}:where(body.fds-breakpoint-md-max) .u723luu{-webkit-align-items:flex-start;-webkit-box-align:flex-start;-ms-flex-align:flex-start;align-items:flex-start;}
6
6
  .u7dp799{width:10rem;}:where(body.fds-breakpoint-md-max) .u7dp799{width:100%;}
7
7
  .u1rz06ff{color:var(--fds-colour-text-subtler);margin-top:var(--fds-spacing-8);width:10rem;text-align:center;}:where(body.fds-breakpoint-md-max) .u1rz06ff{display:none;visibility:hidden;}
8
- .emjmrml{margin-bottom:var(--fds-spacing-32);}
8
+ .emjmrml{margin-bottom:var(--fds-spacing-32);}}