@12-apps/ui 6.7.0 → 6.9.0

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 (405) hide show
  1. package/dist/chunk-3X3JVF6E.js +438 -0
  2. package/dist/chunk-3X3JVF6E.js.map +1 -0
  3. package/dist/chunk-AL3W7TXN.js +465 -0
  4. package/dist/chunk-AL3W7TXN.js.map +1 -0
  5. package/dist/{chunk-QLBYAYUG.js → chunk-KR2BP7NK.js} +4 -4
  6. package/dist/chunk-KR2BP7NK.js.map +1 -0
  7. package/dist/{chunk-DFVRZ3UK.js → chunk-KXARS46L.js} +3 -3
  8. package/dist/chunk-KXARS46L.js.map +1 -0
  9. package/dist/{chunk-JP55QWVR.js → chunk-L7L6SX64.js} +5 -2
  10. package/dist/chunk-L7L6SX64.js.map +1 -0
  11. package/dist/{chunk-QZZVHY6U.js → chunk-PVLDKXKR.js} +7 -3
  12. package/dist/chunk-PVLDKXKR.js.map +1 -0
  13. package/dist/{chunk-H7UAGTVW.js → chunk-TSG5C7MP.js} +4 -3
  14. package/dist/chunk-TSG5C7MP.js.map +1 -0
  15. package/dist/{chunk-NUCLEOHF.js → chunk-UNM7KFDX.js} +44 -14
  16. package/dist/chunk-UNM7KFDX.js.map +1 -0
  17. package/dist/{chunk-CEKPLUQV.js → chunk-UY7UF7IN.js} +19 -13
  18. package/dist/chunk-UY7UF7IN.js.map +1 -0
  19. package/dist/data-display/DataGrid.js +1 -1
  20. package/dist/data-display/DataViews.js +88 -65
  21. package/dist/data-display/DataViews.js.map +1 -1
  22. package/dist/data-display/HoverCard.js +4 -1
  23. package/dist/data-display/HoverCard.js.map +1 -1
  24. package/dist/data-display/Table.js +4 -2
  25. package/dist/data-display/Table.js.map +1 -1
  26. package/dist/data-display/TimingDiagram.js +3 -2
  27. package/dist/data-display/TimingDiagram.js.map +1 -1
  28. package/dist/en-US.js +56 -0
  29. package/dist/en-US.js.map +1 -0
  30. package/dist/feedback/Sonner.js +5 -4
  31. package/dist/feedback/Sonner.js.map +1 -1
  32. package/dist/feedback/StackedModal.js +1 -1
  33. package/dist/feedback/TutorialOverlay.js +19 -5
  34. package/dist/feedback/TutorialOverlay.js.map +1 -1
  35. package/dist/form/AddressAutocomplete.js +16 -8
  36. package/dist/form/AddressAutocomplete.js.map +1 -1
  37. package/dist/form/Autocomplete.js +9 -7
  38. package/dist/form/Autocomplete.js.map +1 -1
  39. package/dist/form/Calendar.js +1 -1
  40. package/dist/form/CodeEditor.js +14 -9
  41. package/dist/form/CodeEditor.js.map +1 -1
  42. package/dist/form/DateRangePicker.js +10 -3
  43. package/dist/form/DateRangePicker.js.map +1 -1
  44. package/dist/form/Menubar.js +4 -1
  45. package/dist/form/Menubar.js.map +1 -1
  46. package/dist/form/PasswordStrength.js +48 -28
  47. package/dist/form/PasswordStrength.js.map +1 -1
  48. package/dist/form/PhoneInput.js +11 -5
  49. package/dist/form/PhoneInput.js.map +1 -1
  50. package/dist/form/SearchPalette.js +4 -1
  51. package/dist/form/SearchPalette.js.map +1 -1
  52. package/dist/form/Textarea.js +21 -19
  53. package/dist/form/Textarea.js.map +1 -1
  54. package/dist/form/UploadButton.js +16 -11
  55. package/dist/form/UploadButton.js.map +1 -1
  56. package/dist/layout/ContentToolbar.js +1 -1
  57. package/dist/layout/Dashboard.js +2 -1
  58. package/dist/layout/Dashboard.js.map +1 -1
  59. package/dist/layout/ScrollArea.js +9 -3
  60. package/dist/layout/ScrollArea.js.map +1 -1
  61. package/dist/layout/TableFilter.js +1 -1
  62. package/dist/locales.js +171 -0
  63. package/dist/locales.js.map +1 -0
  64. package/dist/navigation/Breadcrumbs.js +9 -3
  65. package/dist/navigation/Breadcrumbs.js.map +1 -1
  66. package/dist/navigation/CommandPalette.js +20 -7
  67. package/dist/navigation/CommandPalette.js.map +1 -1
  68. package/dist/navigation/Pagination.js +1 -1
  69. package/dist/navigation/Tabs.js +7 -3
  70. package/dist/navigation/Tabs.js.map +1 -1
  71. package/dist/pt-BR.js +42 -274
  72. package/dist/pt-BR.js.map +1 -1
  73. package/dist/types/components/data-display/DataGrid/DataGrid.states.d.ts +1 -0
  74. package/dist/types/components/data-display/DataGrid/DataGrid.states.d.ts.map +1 -1
  75. package/dist/types/components/data-display/DataGrid/DataGrid.types.d.ts +5 -0
  76. package/dist/types/components/data-display/DataGrid/DataGrid.types.d.ts.map +1 -1
  77. package/dist/types/components/data-display/DataViews/data-views-category-pill.d.ts.map +1 -1
  78. package/dist/types/components/data-display/DataViews/data-views-copy.d.ts +27 -1
  79. package/dist/types/components/data-display/DataViews/data-views-copy.d.ts.map +1 -1
  80. package/dist/types/components/data-display/DataViews/data-views-day-input.d.ts +12 -1
  81. package/dist/types/components/data-display/DataViews/data-views-day-input.d.ts.map +1 -1
  82. package/dist/types/components/data-display/DataViews/data-views-filter-panel.d.ts.map +1 -1
  83. package/dist/types/components/data-display/DataViews/data-views-grid-bodies.d.ts.map +1 -1
  84. package/dist/types/components/data-display/DataViews/data-views-grid-parts.d.ts.map +1 -1
  85. package/dist/types/components/data-display/DataViews/data-views-more-fields.d.ts.map +1 -1
  86. package/dist/types/components/data-display/DataViews/data-views-pagination.d.ts.map +1 -1
  87. package/dist/types/components/data-display/DataViews/data-views-range-pill.d.ts.map +1 -1
  88. package/dist/types/components/data-display/DataViews/data-views-toolbar.d.ts.map +1 -1
  89. package/dist/types/components/data-display/HoverCard/HoverCard.content.d.ts +1 -1
  90. package/dist/types/components/data-display/HoverCard/HoverCard.content.d.ts.map +1 -1
  91. package/dist/types/components/data-display/HoverCard/HoverCard.d.ts.map +1 -1
  92. package/dist/types/components/data-display/HoverCard/HoverCard.types.d.ts +2 -0
  93. package/dist/types/components/data-display/HoverCard/HoverCard.types.d.ts.map +1 -1
  94. package/dist/types/components/data-display/Table/Table.d.ts.map +1 -1
  95. package/dist/types/components/data-display/Table/Table.types.d.ts +5 -0
  96. package/dist/types/components/data-display/Table/Table.types.d.ts.map +1 -1
  97. package/dist/types/components/data-display/Table/TableStates.d.ts +3 -1
  98. package/dist/types/components/data-display/Table/TableStates.d.ts.map +1 -1
  99. package/dist/types/components/data-display/TimingDiagram/TimingDiagram.d.ts.map +1 -1
  100. package/dist/types/components/data-display/TimingDiagram/TimingDiagram.types.d.ts +3 -0
  101. package/dist/types/components/data-display/TimingDiagram/TimingDiagram.types.d.ts.map +1 -1
  102. package/dist/types/components/feedback/Sonner/Sonner.d.ts +8 -0
  103. package/dist/types/components/feedback/Sonner/Sonner.d.ts.map +1 -1
  104. package/dist/types/components/feedback/Sonner/Sonner.types.d.ts +2 -0
  105. package/dist/types/components/feedback/Sonner/Sonner.types.d.ts.map +1 -1
  106. package/dist/types/components/feedback/Sonner/SonnerToast.d.ts.map +1 -1
  107. package/dist/types/components/feedback/StackedModal/StackedModal.d.ts.map +1 -1
  108. package/dist/types/components/feedback/StackedModal/StackedModal.parts.d.ts +2 -0
  109. package/dist/types/components/feedback/StackedModal/StackedModal.parts.d.ts.map +1 -1
  110. package/dist/types/components/feedback/StackedModal/StackedModal.types.d.ts +2 -0
  111. package/dist/types/components/feedback/StackedModal/StackedModal.types.d.ts.map +1 -1
  112. package/dist/types/components/feedback/TutorialOverlay/TutorialOverlay.d.ts.map +1 -1
  113. package/dist/types/components/feedback/TutorialOverlay/TutorialOverlay.types.d.ts +3 -0
  114. package/dist/types/components/feedback/TutorialOverlay/TutorialOverlay.types.d.ts.map +1 -1
  115. package/dist/types/components/feedback/TutorialOverlay/TutorialStepBody.d.ts +2 -0
  116. package/dist/types/components/feedback/TutorialOverlay/TutorialStepBody.d.ts.map +1 -1
  117. package/dist/types/components/form/AddressAutocomplete/AddressAutocomplete.types.d.ts +7 -0
  118. package/dist/types/components/form/AddressAutocomplete/AddressAutocomplete.types.d.ts.map +1 -1
  119. package/dist/types/components/form/AddressAutocomplete/AddressAutocompleteField.d.ts.map +1 -1
  120. package/dist/types/components/form/AddressAutocomplete/AddressFallbackField.d.ts +1 -0
  121. package/dist/types/components/form/AddressAutocomplete/AddressFallbackField.d.ts.map +1 -1
  122. package/dist/types/components/form/AddressAutocomplete/AddressInputField.d.ts +1 -0
  123. package/dist/types/components/form/AddressAutocomplete/AddressInputField.d.ts.map +1 -1
  124. package/dist/types/components/form/Autocomplete/Autocomplete.d.ts.map +1 -1
  125. package/dist/types/components/form/Autocomplete/Autocomplete.parts.d.ts +9 -3
  126. package/dist/types/components/form/Autocomplete/Autocomplete.parts.d.ts.map +1 -1
  127. package/dist/types/components/form/Autocomplete/Autocomplete.types.d.ts +7 -0
  128. package/dist/types/components/form/Autocomplete/Autocomplete.types.d.ts.map +1 -1
  129. package/dist/types/components/form/Calendar/Calendar.types.d.ts +6 -0
  130. package/dist/types/components/form/Calendar/Calendar.types.d.ts.map +1 -1
  131. package/dist/types/components/form/CodeEditor/CodeEditor.d.ts.map +1 -1
  132. package/dist/types/components/form/CodeEditor/CodeEditor.types.d.ts +7 -0
  133. package/dist/types/components/form/CodeEditor/CodeEditor.types.d.ts.map +1 -1
  134. package/dist/types/components/form/CodeEditor/CodeEditorToolbar.d.ts +2 -0
  135. package/dist/types/components/form/CodeEditor/CodeEditorToolbar.d.ts.map +1 -1
  136. package/dist/types/components/form/DateRangePicker/DateRangePicker.d.ts.map +1 -1
  137. package/dist/types/components/form/DateRangePicker/DateRangePicker.range.d.ts.map +1 -1
  138. package/dist/types/components/form/DateRangePicker/DateRangePicker.types.d.ts +11 -0
  139. package/dist/types/components/form/DateRangePicker/DateRangePicker.types.d.ts.map +1 -1
  140. package/dist/types/components/form/DateRangePicker/DateRangePickerFields.d.ts.map +1 -1
  141. package/dist/types/components/form/Menubar/Menubar.d.ts.map +1 -1
  142. package/dist/types/components/form/Menubar/Menubar.toolbar.d.ts +1 -0
  143. package/dist/types/components/form/Menubar/Menubar.toolbar.d.ts.map +1 -1
  144. package/dist/types/components/form/Menubar/Menubar.types.d.ts +5 -0
  145. package/dist/types/components/form/Menubar/Menubar.types.d.ts.map +1 -1
  146. package/dist/types/components/form/PasswordStrength/PasswordStrength.d.ts.map +1 -1
  147. package/dist/types/components/form/PasswordStrength/PasswordStrength.helpers.d.ts +4 -2
  148. package/dist/types/components/form/PasswordStrength/PasswordStrength.helpers.d.ts.map +1 -1
  149. package/dist/types/components/form/PasswordStrength/PasswordStrength.types.d.ts +8 -0
  150. package/dist/types/components/form/PasswordStrength/PasswordStrength.types.d.ts.map +1 -1
  151. package/dist/types/components/form/PhoneInput/PhoneInput.d.ts.map +1 -1
  152. package/dist/types/components/form/PhoneInput/PhoneInput.types.d.ts +7 -0
  153. package/dist/types/components/form/PhoneInput/PhoneInput.types.d.ts.map +1 -1
  154. package/dist/types/components/form/SearchPalette/SearchPalette.d.ts.map +1 -1
  155. package/dist/types/components/form/SearchPalette/SearchPalette.parts.d.ts +2 -0
  156. package/dist/types/components/form/SearchPalette/SearchPalette.parts.d.ts.map +1 -1
  157. package/dist/types/components/form/SearchPalette/SearchPalette.types.d.ts +6 -0
  158. package/dist/types/components/form/SearchPalette/SearchPalette.types.d.ts.map +1 -1
  159. package/dist/types/components/form/Textarea/Textarea.d.ts.map +1 -1
  160. package/dist/types/components/form/Textarea/Textarea.types.d.ts +16 -1
  161. package/dist/types/components/form/Textarea/Textarea.types.d.ts.map +1 -1
  162. package/dist/types/components/form/Textarea/TextareaRichEditor.d.ts +7 -0
  163. package/dist/types/components/form/Textarea/TextareaRichEditor.d.ts.map +1 -1
  164. package/dist/types/components/form/UploadButton/UploadButton.d.ts.map +1 -1
  165. package/dist/types/components/form/UploadButton/UploadButton.parts.d.ts +6 -3
  166. package/dist/types/components/form/UploadButton/UploadButton.parts.d.ts.map +1 -1
  167. package/dist/types/components/form/UploadButton/UploadButton.types.d.ts +7 -0
  168. package/dist/types/components/form/UploadButton/UploadButton.types.d.ts.map +1 -1
  169. package/dist/types/components/layout/ContentToolbar/ContentToolbar.d.ts +1 -1
  170. package/dist/types/components/layout/ContentToolbar/ContentToolbar.d.ts.map +1 -1
  171. package/dist/types/components/layout/ContentToolbar/ContentToolbar.types.d.ts +12 -0
  172. package/dist/types/components/layout/ContentToolbar/ContentToolbar.types.d.ts.map +1 -1
  173. package/dist/types/components/layout/ContentToolbar/MultiSelectDropdown.d.ts +1 -1
  174. package/dist/types/components/layout/ContentToolbar/MultiSelectDropdown.d.ts.map +1 -1
  175. package/dist/types/components/layout/ContentToolbar/SortByDropdown.d.ts +1 -1
  176. package/dist/types/components/layout/ContentToolbar/SortByDropdown.d.ts.map +1 -1
  177. package/dist/types/components/layout/ContentToolbar/ViewSelector.d.ts +1 -1
  178. package/dist/types/components/layout/ContentToolbar/ViewSelector.d.ts.map +1 -1
  179. package/dist/types/components/layout/Dashboard/Dashboard.d.ts +1 -1
  180. package/dist/types/components/layout/Dashboard/Dashboard.types.d.ts +4 -0
  181. package/dist/types/components/layout/Dashboard/Dashboard.types.d.ts.map +1 -1
  182. package/dist/types/components/layout/Dashboard/DashboardParts.d.ts +1 -1
  183. package/dist/types/components/layout/Dashboard/DashboardParts.d.ts.map +1 -1
  184. package/dist/types/components/layout/ScrollArea/ScrollArea.d.ts.map +1 -1
  185. package/dist/types/components/layout/ScrollArea/ScrollArea.types.d.ts +21 -3
  186. package/dist/types/components/layout/ScrollArea/ScrollArea.types.d.ts.map +1 -1
  187. package/dist/types/components/layout/ScrollArea/ScrollViewport.d.ts +2 -0
  188. package/dist/types/components/layout/ScrollArea/ScrollViewport.d.ts.map +1 -1
  189. package/dist/types/components/layout/TableFilter/TableFilter.d.ts +1 -1
  190. package/dist/types/components/layout/TableFilter/TableFilter.d.ts.map +1 -1
  191. package/dist/types/components/layout/TableFilter/TableFilter.types.d.ts +7 -0
  192. package/dist/types/components/layout/TableFilter/TableFilter.types.d.ts.map +1 -1
  193. package/dist/types/components/layout/TableFilter/TableFilterContext.d.ts +9 -0
  194. package/dist/types/components/layout/TableFilter/TableFilterContext.d.ts.map +1 -1
  195. package/dist/types/components/navigation/Breadcrumbs/BreadcrumbEntry.d.ts +2 -0
  196. package/dist/types/components/navigation/Breadcrumbs/BreadcrumbEntry.d.ts.map +1 -1
  197. package/dist/types/components/navigation/Breadcrumbs/Breadcrumbs.d.ts.map +1 -1
  198. package/dist/types/components/navigation/Breadcrumbs/Breadcrumbs.types.d.ts +3 -0
  199. package/dist/types/components/navigation/Breadcrumbs/Breadcrumbs.types.d.ts.map +1 -1
  200. package/dist/types/components/navigation/CommandPalette/CommandPalette.d.ts.map +1 -1
  201. package/dist/types/components/navigation/CommandPalette/CommandPalette.types.d.ts +3 -0
  202. package/dist/types/components/navigation/CommandPalette/CommandPalette.types.d.ts.map +1 -1
  203. package/dist/types/components/navigation/CommandPalette/CommandPaletteResults.d.ts +2 -0
  204. package/dist/types/components/navigation/CommandPalette/CommandPaletteResults.d.ts.map +1 -1
  205. package/dist/types/components/navigation/Pagination/Pagination.d.ts.map +1 -1
  206. package/dist/types/components/navigation/Pagination/Pagination.types.d.ts +2 -0
  207. package/dist/types/components/navigation/Pagination/Pagination.types.d.ts.map +1 -1
  208. package/dist/types/components/navigation/Pagination/PaginationParts.d.ts +2 -0
  209. package/dist/types/components/navigation/Pagination/PaginationParts.d.ts.map +1 -1
  210. package/dist/types/components/navigation/Tabs/Tabs.d.ts.map +1 -1
  211. package/dist/types/components/navigation/Tabs/Tabs.types.d.ts +2 -0
  212. package/dist/types/components/navigation/Tabs/Tabs.types.d.ts.map +1 -1
  213. package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.d.ts.map +1 -1
  214. package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.parts.d.ts +6 -2
  215. package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.parts.d.ts.map +1 -1
  216. package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.types.d.ts +6 -0
  217. package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.types.d.ts.map +1 -1
  218. package/dist/types/components/utility/InstallPrompt/InstallPrompt.d.ts +4 -2
  219. package/dist/types/components/utility/InstallPrompt/InstallPrompt.d.ts.map +1 -1
  220. package/dist/types/components/utility/InstallPrompt/InstallPrompt.types.d.ts +8 -7
  221. package/dist/types/components/utility/InstallPrompt/InstallPrompt.types.d.ts.map +1 -1
  222. package/dist/types/copy/data-display.d.ts +56 -0
  223. package/dist/types/copy/data-display.d.ts.map +1 -0
  224. package/dist/types/copy/feedback.d.ts +38 -0
  225. package/dist/types/copy/feedback.d.ts.map +1 -0
  226. package/dist/types/copy/form.d.ts +146 -0
  227. package/dist/types/copy/form.d.ts.map +1 -0
  228. package/dist/types/copy/layout.d.ts +18 -0
  229. package/dist/types/copy/layout.d.ts.map +1 -0
  230. package/dist/types/copy/navigation.d.ts +24 -0
  231. package/dist/types/copy/navigation.d.ts.map +1 -0
  232. package/dist/types/copy/shared.d.ts +119 -0
  233. package/dist/types/copy/shared.d.ts.map +1 -0
  234. package/dist/types/copy/utility.d.ts +35 -0
  235. package/dist/types/copy/utility.d.ts.map +1 -0
  236. package/dist/types/copy.d.ts +12 -165
  237. package/dist/types/copy.d.ts.map +1 -1
  238. package/dist/types/en-US.d.ts +24 -0
  239. package/dist/types/en-US.d.ts.map +1 -0
  240. package/dist/types/en-US.data-display.d.ts +13 -0
  241. package/dist/types/en-US.data-display.d.ts.map +1 -0
  242. package/dist/types/en-US.feedback.d.ts +8 -0
  243. package/dist/types/en-US.feedback.d.ts.map +1 -0
  244. package/dist/types/en-US.form.d.ts +13 -0
  245. package/dist/types/en-US.form.d.ts.map +1 -0
  246. package/dist/types/en-US.layout.d.ts +7 -0
  247. package/dist/types/en-US.layout.d.ts.map +1 -0
  248. package/dist/types/en-US.navigation.d.ts +8 -0
  249. package/dist/types/en-US.navigation.d.ts.map +1 -0
  250. package/dist/types/en-US.shared.d.ts +26 -0
  251. package/dist/types/en-US.shared.d.ts.map +1 -0
  252. package/dist/types/en-US.utility.d.ts +8 -0
  253. package/dist/types/en-US.utility.d.ts.map +1 -0
  254. package/dist/types/locales.d.ts +53 -0
  255. package/dist/types/locales.d.ts.map +1 -0
  256. package/dist/types/pt-BR.d.ts +15 -22
  257. package/dist/types/pt-BR.d.ts.map +1 -1
  258. package/dist/types/pt-BR.data-display.d.ts +13 -0
  259. package/dist/types/pt-BR.data-display.d.ts.map +1 -0
  260. package/dist/types/pt-BR.feedback.d.ts +8 -0
  261. package/dist/types/pt-BR.feedback.d.ts.map +1 -0
  262. package/dist/types/pt-BR.form.d.ts +13 -0
  263. package/dist/types/pt-BR.form.d.ts.map +1 -0
  264. package/dist/types/pt-BR.layout.d.ts +7 -0
  265. package/dist/types/pt-BR.layout.d.ts.map +1 -0
  266. package/dist/types/pt-BR.navigation.d.ts +8 -0
  267. package/dist/types/pt-BR.navigation.d.ts.map +1 -0
  268. package/dist/types/pt-BR.shared.d.ts +21 -0
  269. package/dist/types/pt-BR.shared.d.ts.map +1 -0
  270. package/dist/types/pt-BR.utility.d.ts +8 -0
  271. package/dist/types/pt-BR.utility.d.ts.map +1 -0
  272. package/dist/types/user-avatar/user-avatar.d.ts +7 -1
  273. package/dist/types/user-avatar/user-avatar.d.ts.map +1 -1
  274. package/dist/user-avatar.js +2 -2
  275. package/dist/user-avatar.js.map +1 -1
  276. package/dist/utility/InfiniteScroll.js +7 -5
  277. package/dist/utility/InfiniteScroll.js.map +1 -1
  278. package/dist/utility/InstallPrompt.js +14 -13
  279. package/dist/utility/InstallPrompt.js.map +1 -1
  280. package/package.json +10 -1
  281. package/src/components/data-display/DataGrid/DataGrid.states.tsx +3 -3
  282. package/src/components/data-display/DataGrid/DataGrid.tsx +1 -1
  283. package/src/components/data-display/DataGrid/DataGrid.types.ts +5 -0
  284. package/src/components/data-display/DataViews/data-views-category-pill.tsx +2 -0
  285. package/src/components/data-display/DataViews/data-views-copy.ts +27 -1
  286. package/src/components/data-display/DataViews/data-views-day-input.tsx +14 -3
  287. package/src/components/data-display/DataViews/data-views-filter-panel.tsx +2 -1
  288. package/src/components/data-display/DataViews/data-views-grid-bodies.tsx +3 -0
  289. package/src/components/data-display/DataViews/data-views-grid-parts.tsx +9 -10
  290. package/src/components/data-display/DataViews/data-views-more-fields.tsx +3 -1
  291. package/src/components/data-display/DataViews/data-views-pagination.tsx +3 -0
  292. package/src/components/data-display/DataViews/data-views-range-pill.tsx +3 -1
  293. package/src/components/data-display/DataViews/data-views-toolbar.tsx +2 -0
  294. package/src/components/data-display/HoverCard/HoverCard.content.tsx +10 -2
  295. package/src/components/data-display/HoverCard/HoverCard.tsx +2 -3
  296. package/src/components/data-display/HoverCard/HoverCard.types.ts +2 -0
  297. package/src/components/data-display/Table/Table.tsx +7 -2
  298. package/src/components/data-display/Table/Table.types.ts +5 -0
  299. package/src/components/data-display/Table/TableStates.tsx +2 -2
  300. package/src/components/data-display/TimingDiagram/TimingDiagram.tsx +3 -2
  301. package/src/components/data-display/TimingDiagram/TimingDiagram.types.ts +3 -0
  302. package/src/components/feedback/Sonner/Sonner.tsx +15 -3
  303. package/src/components/feedback/Sonner/Sonner.types.ts +2 -0
  304. package/src/components/feedback/Sonner/SonnerToast.tsx +2 -1
  305. package/src/components/feedback/StackedModal/StackedModal.parts.tsx +10 -3
  306. package/src/components/feedback/StackedModal/StackedModal.tsx +2 -1
  307. package/src/components/feedback/StackedModal/StackedModal.types.ts +2 -0
  308. package/src/components/feedback/TutorialOverlay/TutorialOverlay.tsx +13 -1
  309. package/src/components/feedback/TutorialOverlay/TutorialOverlay.types.ts +3 -0
  310. package/src/components/feedback/TutorialOverlay/TutorialStepBody.tsx +10 -4
  311. package/src/components/form/AddressAutocomplete/AddressAutocomplete.types.ts +7 -0
  312. package/src/components/form/AddressAutocomplete/AddressAutocompleteField.tsx +2 -0
  313. package/src/components/form/AddressAutocomplete/AddressFallbackField.tsx +4 -2
  314. package/src/components/form/AddressAutocomplete/AddressInputField.tsx +13 -6
  315. package/src/components/form/Autocomplete/Autocomplete.parts.tsx +9 -6
  316. package/src/components/form/Autocomplete/Autocomplete.tsx +2 -1
  317. package/src/components/form/Autocomplete/Autocomplete.types.ts +7 -0
  318. package/src/components/form/Calendar/Calendar.tsx +2 -2
  319. package/src/components/form/Calendar/Calendar.types.ts +7 -0
  320. package/src/components/form/CodeEditor/CodeEditor.tsx +6 -4
  321. package/src/components/form/CodeEditor/CodeEditor.types.ts +7 -0
  322. package/src/components/form/CodeEditor/CodeEditorToolbar.tsx +12 -5
  323. package/src/components/form/DateRangePicker/DateRangePicker.range.ts +2 -0
  324. package/src/components/form/DateRangePicker/DateRangePicker.tsx +4 -0
  325. package/src/components/form/DateRangePicker/DateRangePicker.types.ts +11 -0
  326. package/src/components/form/DateRangePicker/DateRangePickerFields.tsx +2 -0
  327. package/src/components/form/Menubar/Menubar.toolbar.tsx +3 -1
  328. package/src/components/form/Menubar/Menubar.tsx +2 -1
  329. package/src/components/form/Menubar/Menubar.types.ts +5 -0
  330. package/src/components/form/PasswordStrength/PasswordStrength.helpers.tsx +33 -17
  331. package/src/components/form/PasswordStrength/PasswordStrength.tsx +29 -13
  332. package/src/components/form/PasswordStrength/PasswordStrength.types.ts +9 -0
  333. package/src/components/form/PhoneInput/PhoneInput.tsx +15 -5
  334. package/src/components/form/PhoneInput/PhoneInput.types.ts +7 -0
  335. package/src/components/form/SearchPalette/SearchPalette.parts.tsx +4 -1
  336. package/src/components/form/SearchPalette/SearchPalette.tsx +4 -1
  337. package/src/components/form/SearchPalette/SearchPalette.types.ts +6 -0
  338. package/src/components/form/Textarea/Textarea.tsx +6 -1
  339. package/src/components/form/Textarea/Textarea.types.ts +14 -1
  340. package/src/components/form/Textarea/TextareaRichEditor.tsx +28 -18
  341. package/src/components/form/UploadButton/UploadButton.parts.tsx +16 -7
  342. package/src/components/form/UploadButton/UploadButton.tsx +4 -1
  343. package/src/components/form/UploadButton/UploadButton.types.ts +8 -0
  344. package/src/components/layout/ContentToolbar/ContentToolbar.tsx +10 -2
  345. package/src/components/layout/ContentToolbar/ContentToolbar.types.ts +12 -0
  346. package/src/components/layout/ContentToolbar/MultiSelectDropdown.tsx +15 -4
  347. package/src/components/layout/ContentToolbar/SortByDropdown.tsx +12 -3
  348. package/src/components/layout/ContentToolbar/ViewSelector.tsx +2 -1
  349. package/src/components/layout/Dashboard/Dashboard.types.ts +4 -0
  350. package/src/components/layout/Dashboard/DashboardParts.tsx +2 -1
  351. package/src/components/layout/ScrollArea/ScrollArea.tsx +16 -3
  352. package/src/components/layout/ScrollArea/ScrollArea.types.ts +19 -4
  353. package/src/components/layout/ScrollArea/ScrollViewport.tsx +4 -1
  354. package/src/components/layout/TableFilter/TableFilter.tsx +19 -11
  355. package/src/components/layout/TableFilter/TableFilter.types.ts +8 -0
  356. package/src/components/layout/TableFilter/TableFilterContext.tsx +10 -0
  357. package/src/components/navigation/Breadcrumbs/BreadcrumbEntry.tsx +11 -4
  358. package/src/components/navigation/Breadcrumbs/Breadcrumbs.tsx +2 -0
  359. package/src/components/navigation/Breadcrumbs/Breadcrumbs.types.ts +3 -0
  360. package/src/components/navigation/CommandPalette/CommandPalette.tsx +15 -5
  361. package/src/components/navigation/CommandPalette/CommandPalette.types.ts +3 -0
  362. package/src/components/navigation/CommandPalette/CommandPaletteResults.tsx +5 -2
  363. package/src/components/navigation/Pagination/Pagination.tsx +2 -0
  364. package/src/components/navigation/Pagination/Pagination.types.ts +2 -0
  365. package/src/components/navigation/Pagination/PaginationParts.tsx +4 -1
  366. package/src/components/navigation/Tabs/Tabs.tsx +8 -3
  367. package/src/components/navigation/Tabs/Tabs.types.ts +2 -0
  368. package/src/components/utility/InfiniteScroll/InfiniteScroll.parts.tsx +4 -4
  369. package/src/components/utility/InfiniteScroll/InfiniteScroll.tsx +4 -2
  370. package/src/components/utility/InfiniteScroll/InfiniteScroll.types.ts +6 -0
  371. package/src/components/utility/InstallPrompt/InstallPrompt.tsx +18 -13
  372. package/src/components/utility/InstallPrompt/InstallPrompt.types.ts +9 -7
  373. package/src/copy/data-display.ts +60 -0
  374. package/src/copy/feedback.ts +39 -0
  375. package/src/copy/form.ts +154 -0
  376. package/src/copy/layout.ts +18 -0
  377. package/src/copy/navigation.ts +25 -0
  378. package/src/copy/shared.ts +122 -0
  379. package/src/copy/utility.ts +36 -0
  380. package/src/copy.ts +12 -173
  381. package/src/en-US.data-display.ts +244 -0
  382. package/src/en-US.feedback.ts +25 -0
  383. package/src/en-US.form.ts +103 -0
  384. package/src/en-US.layout.ts +15 -0
  385. package/src/en-US.navigation.ts +23 -0
  386. package/src/en-US.shared.ts +105 -0
  387. package/src/en-US.ts +24 -0
  388. package/src/en-US.utility.ts +24 -0
  389. package/src/locales.ts +151 -0
  390. package/src/pt-BR.data-display.ts +236 -0
  391. package/src/pt-BR.feedback.ts +25 -0
  392. package/src/pt-BR.form.ts +96 -0
  393. package/src/pt-BR.layout.ts +15 -0
  394. package/src/pt-BR.navigation.ts +21 -0
  395. package/src/pt-BR.shared.ts +94 -0
  396. package/src/pt-BR.ts +15 -307
  397. package/src/pt-BR.utility.ts +21 -0
  398. package/src/user-avatar/user-avatar.tsx +8 -2
  399. package/dist/chunk-CEKPLUQV.js.map +0 -1
  400. package/dist/chunk-DFVRZ3UK.js.map +0 -1
  401. package/dist/chunk-H7UAGTVW.js.map +0 -1
  402. package/dist/chunk-JP55QWVR.js.map +0 -1
  403. package/dist/chunk-NUCLEOHF.js.map +0 -1
  404. package/dist/chunk-QLBYAYUG.js.map +0 -1
  405. package/dist/chunk-QZZVHY6U.js.map +0 -1
@@ -282,8 +282,8 @@ var useRichEditorState = ({
282
282
  updateActiveFormats
283
283
  };
284
284
  };
285
- var InlineFormatButtons = ({ activeFormats, onCommand }) => /* @__PURE__ */ jsxs(Fragment, { children: [
286
- /* @__PURE__ */ jsx(Tooltip, { title: "Bold", arrow: true, children: /* @__PURE__ */ jsx(
285
+ var InlineFormatButtons = ({ copy, activeFormats, onCommand }) => /* @__PURE__ */ jsxs(Fragment, { children: [
286
+ /* @__PURE__ */ jsx(Tooltip, { title: copy.bold, arrow: true, children: /* @__PURE__ */ jsx(
287
287
  ToolbarButton,
288
288
  {
289
289
  size: "small",
@@ -292,7 +292,7 @@ var InlineFormatButtons = ({ activeFormats, onCommand }) => /* @__PURE__ */ jsxs
292
292
  children: /* @__PURE__ */ jsx(FormatBold, { fontSize: "small" })
293
293
  }
294
294
  ) }),
295
- /* @__PURE__ */ jsx(Tooltip, { title: "Italic", arrow: true, children: /* @__PURE__ */ jsx(
295
+ /* @__PURE__ */ jsx(Tooltip, { title: copy.italic, arrow: true, children: /* @__PURE__ */ jsx(
296
296
  ToolbarButton,
297
297
  {
298
298
  size: "small",
@@ -301,7 +301,7 @@ var InlineFormatButtons = ({ activeFormats, onCommand }) => /* @__PURE__ */ jsxs
301
301
  children: /* @__PURE__ */ jsx(FormatItalic, { fontSize: "small" })
302
302
  }
303
303
  ) }),
304
- /* @__PURE__ */ jsx(Tooltip, { title: "Underline", arrow: true, children: /* @__PURE__ */ jsx(
304
+ /* @__PURE__ */ jsx(Tooltip, { title: copy.underline, arrow: true, children: /* @__PURE__ */ jsx(
305
305
  ToolbarButton,
306
306
  {
307
307
  size: "small",
@@ -311,9 +311,9 @@ var InlineFormatButtons = ({ activeFormats, onCommand }) => /* @__PURE__ */ jsxs
311
311
  }
312
312
  ) })
313
313
  ] });
314
- var BlockFormatButtons = ({ activeFormats, onCommand }) => /* @__PURE__ */ jsxs(Fragment, { children: [
314
+ var BlockFormatButtons = ({ copy, activeFormats, onCommand }) => /* @__PURE__ */ jsxs(Fragment, { children: [
315
315
  /* @__PURE__ */ jsx(Divider, { orientation: "vertical", flexItem: true }),
316
- /* @__PURE__ */ jsx(Tooltip, { title: "Bullet List", arrow: true, children: /* @__PURE__ */ jsx(
316
+ /* @__PURE__ */ jsx(Tooltip, { title: copy.bulletList, arrow: true, children: /* @__PURE__ */ jsx(
317
317
  ToolbarButton,
318
318
  {
319
319
  size: "small",
@@ -322,7 +322,7 @@ var BlockFormatButtons = ({ activeFormats, onCommand }) => /* @__PURE__ */ jsxs(
322
322
  children: /* @__PURE__ */ jsx(FormatListBulleted, { fontSize: "small" })
323
323
  }
324
324
  ) }),
325
- /* @__PURE__ */ jsx(Tooltip, { title: "Numbered List", arrow: true, children: /* @__PURE__ */ jsx(
325
+ /* @__PURE__ */ jsx(Tooltip, { title: copy.numberedList, arrow: true, children: /* @__PURE__ */ jsx(
326
326
  ToolbarButton,
327
327
  {
328
328
  size: "small",
@@ -332,28 +332,28 @@ var BlockFormatButtons = ({ activeFormats, onCommand }) => /* @__PURE__ */ jsxs(
332
332
  }
333
333
  ) }),
334
334
  /* @__PURE__ */ jsx(Divider, { orientation: "vertical", flexItem: true }),
335
- /* @__PURE__ */ jsx(Tooltip, { title: "Quote", arrow: true, children: /* @__PURE__ */ jsx(ToolbarButton, { size: "small", onClick: () => onCommand("formatBlock", "blockquote"), children: /* @__PURE__ */ jsx(FormatQuote, { fontSize: "small" }) }) }),
336
- /* @__PURE__ */ jsx(Tooltip, { title: "Code", arrow: true, children: /* @__PURE__ */ jsx(ToolbarButton, { size: "small", onClick: () => onCommand("formatBlock", "pre"), children: /* @__PURE__ */ jsx(Code, { fontSize: "small" }) }) }),
335
+ /* @__PURE__ */ jsx(Tooltip, { title: copy.quote, arrow: true, children: /* @__PURE__ */ jsx(ToolbarButton, { size: "small", onClick: () => onCommand("formatBlock", "blockquote"), children: /* @__PURE__ */ jsx(FormatQuote, { fontSize: "small" }) }) }),
336
+ /* @__PURE__ */ jsx(Tooltip, { title: copy.code, arrow: true, children: /* @__PURE__ */ jsx(ToolbarButton, { size: "small", onClick: () => onCommand("formatBlock", "pre"), children: /* @__PURE__ */ jsx(Code, { fontSize: "small" }) }) }),
337
337
  /* @__PURE__ */ jsx(Divider, { orientation: "vertical", flexItem: true }),
338
- /* @__PURE__ */ jsx(Tooltip, { title: "Insert Link", arrow: true, children: /* @__PURE__ */ jsx(
338
+ /* @__PURE__ */ jsx(Tooltip, { title: copy.insertLink, arrow: true, children: /* @__PURE__ */ jsx(
339
339
  ToolbarButton,
340
340
  {
341
341
  size: "small",
342
342
  onClick: () => {
343
- const url = window.prompt("Enter URL:");
343
+ const url = window.prompt(copy.linkPrompt);
344
344
  if (url) onCommand("createLink", url);
345
345
  },
346
346
  children: /* @__PURE__ */ jsx(Link, { fontSize: "small" })
347
347
  }
348
348
  ) }),
349
- /* @__PURE__ */ jsx(Tooltip, { title: "Text Color", arrow: true, children: /* @__PURE__ */ jsx(ToolbarButton, { size: "small", children: /* @__PURE__ */ jsx(FormatColorText, { fontSize: "small" }) }) }),
350
- /* @__PURE__ */ jsx(Tooltip, { title: "Background Color", arrow: true, children: /* @__PURE__ */ jsx(ToolbarButton, { size: "small", children: /* @__PURE__ */ jsx(FormatColorFill, { fontSize: "small" }) }) })
349
+ /* @__PURE__ */ jsx(Tooltip, { title: copy.textColor, arrow: true, children: /* @__PURE__ */ jsx(ToolbarButton, { size: "small", children: /* @__PURE__ */ jsx(FormatColorText, { fontSize: "small" }) }) }),
350
+ /* @__PURE__ */ jsx(Tooltip, { title: copy.backgroundColor, arrow: true, children: /* @__PURE__ */ jsx(ToolbarButton, { size: "small", children: /* @__PURE__ */ jsx(FormatColorFill, { fontSize: "small" }) }) })
351
351
  ] });
352
- var EditorToolbar = ({ glass, activeFormats, onCommand }) => /* @__PURE__ */ jsxs(RichToolbar, { glass, children: [
353
- /* @__PURE__ */ jsx(InlineFormatButtons, { activeFormats, onCommand }),
354
- /* @__PURE__ */ jsx(BlockFormatButtons, { activeFormats, onCommand })
352
+ var EditorToolbar = ({ copy, glass, activeFormats, onCommand }) => /* @__PURE__ */ jsxs(RichToolbar, { glass, children: [
353
+ /* @__PURE__ */ jsx(InlineFormatButtons, { copy, activeFormats, onCommand }),
354
+ /* @__PURE__ */ jsx(BlockFormatButtons, { copy, activeFormats, onCommand })
355
355
  ] });
356
- var TextareaRichEditor = ({ value, onChange, placeholder, error, glass, color, characterLimit }) => {
356
+ var TextareaRichEditor = ({ copy, value, onChange, placeholder, error, glass, color, characterLimit }) => {
357
357
  const {
358
358
  focused,
359
359
  setFocused,
@@ -365,7 +365,7 @@ var TextareaRichEditor = ({ value, onChange, placeholder, error, glass, color, c
365
365
  updateActiveFormats
366
366
  } = useRichEditorState({ value, onChange });
367
367
  return /* @__PURE__ */ jsxs(Box, { sx: { position: "relative" }, children: [
368
- /* @__PURE__ */ jsx(EditorToolbar, { glass, activeFormats, onCommand: handleFormat }),
368
+ /* @__PURE__ */ jsx(EditorToolbar, { copy, glass, activeFormats, onCommand: handleFormat }),
369
369
  /* @__PURE__ */ jsx(
370
370
  ContentEditableDiv,
371
371
  {
@@ -527,6 +527,7 @@ var Textarea = (textareaProps) => {
527
527
  dataTestId: dataTestIdCamelCase,
528
528
  ...props
529
529
  } = { ...TEXTAREA_DEFAULTS, ...definedProps(textareaProps) };
530
+ const { richEditorCopy } = textareaProps;
530
531
  const [richTextValue, setRichTextValue] = useState2("");
531
532
  const hasIcon = Boolean(icon);
532
533
  const testId = dataTestId || dataTestIdCamelCase;
@@ -539,10 +540,11 @@ var Textarea = (textareaProps) => {
539
540
  [iconPosition === "start" ? "paddingLeft" : "paddingRight"]: ICON_GUTTER
540
541
  }
541
542
  };
542
- if (variant === "rich") {
543
+ if (variant === "rich" && richEditorCopy) {
543
544
  return /* @__PURE__ */ jsx2(TextareaShell, { testId, label, glassLabel, error, helperText, children: /* @__PURE__ */ jsx2(
544
545
  TextareaRichEditor,
545
546
  {
547
+ copy: richEditorCopy,
546
548
  value: richTextValue,
547
549
  onChange: setRichTextValue,
548
550
  placeholder: props.placeholder,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/form/Textarea/Textarea.tsx","../../src/components/form/Textarea/Textarea.styles.ts","../../src/components/form/Textarea/TextareaRichEditor.tsx"],"sourcesContent":["import {\n alpha,\n Box,\n FormHelperText,\n InputLabel,\n TextareaAutosize } from '@mui/material';\nimport type { Theme } from '@mui/material';\nimport { styled } from '@mui/material';\nimport React, { useState } from 'react';\n\nimport {\n getColorFromTheme,\n textareaEmphasisStyles } from './Textarea.styles';\nimport { TextareaRichEditor } from './TextareaRichEditor';\nimport type { TextareaProps } from './Textarea.types';\n\n// Interface for styled component props\ninterface StyledTextareaProps {\n customVariant?: string;\n customColor?: string;\n customSize?: string;\n glow?: boolean;\n glass?: boolean;\n gradient?: boolean;\n error?: boolean;\n theme?: Theme;\n}\n\n// Glow animation for enhanced visual effects\nconst StyledTextarea = styled(TextareaAutosize, {\n shouldForwardProp: (prop) =>\n !['customVariant', 'customColor', 'customSize', 'glow', 'glass', 'gradient', 'error'].includes(\n prop as string,\n ) })<StyledTextareaProps>(({\n theme,\n customVariant,\n customColor = 'primary',\n customSize = 'md',\n glow,\n glass,\n gradient,\n error }) => {\n if (!theme) return {};\n const colorPalette = getColorFromTheme(theme, customColor);\n const errorColor = theme.palette.error;\n\n const sizeMap = {\n xs: { padding: '6px 8px', fontSize: '0.75rem', minHeight: '60px' },\n sm: { padding: '8px 10px', fontSize: '0.875rem', minHeight: '80px' },\n md: { padding: '10px 12px', fontSize: '1rem', minHeight: '100px' },\n lg: { padding: '12px 14px', fontSize: '1.125rem', minHeight: '120px' },\n xl: { padding: '14px 16px', fontSize: '1.25rem', minHeight: '140px' } };\n\n const baseStyles = {\n width: '100%',\n fontFamily: theme.typography.fontFamily,\n borderRadius: theme.spacing(1),\n border: `2px solid ${error ? errorColor.main : theme.palette.divider}`,\n backgroundColor: theme.palette.background.paper,\n color: theme.palette.text.primary,\n transition: 'all 0.3s ease',\n resize: customVariant === 'resizable' ? 'vertical' : 'none',\n outline: 'none',\n ...sizeMap[customSize as keyof typeof sizeMap],\n\n '&::placeholder': {\n color: theme.palette.text.secondary,\n opacity: 0.7 },\n\n '&:hover': {\n borderColor: error ? errorColor.dark : colorPalette.main,\n backgroundColor: alpha(theme.palette.background.paper, 0.8) },\n\n '&:focus': {\n borderColor: error ? errorColor.main : colorPalette.main,\n backgroundColor: theme.palette.background.paper,\n boxShadow: `0 0 0 3px ${alpha(error ? errorColor.main : colorPalette.main, 0.1)}` } };\n\n // Glass morphism effect\n return {\n ...baseStyles,\n ...textareaEmphasisStyles({ theme, colorPalette, glass, gradient, glow }) };\n});\n\nconst StyledLabel = styled(InputLabel, {\n shouldForwardProp: (prop) => !['glass', 'error'].includes(prop as string) })<{ glass?: boolean; error?: boolean }>(({ theme, glass, error }) => ({\n marginBottom: theme.spacing(1),\n fontWeight: 500,\n color: error ? theme.palette.error.main : theme.palette.text.primary,\n ...(glass && {\n backgroundColor: alpha(theme.palette.background.paper, 0.1),\n backdropFilter: 'blur(10px)',\n padding: '4px 8px',\n borderRadius: '4px',\n border: `1px solid ${alpha(theme.palette.divider, 0.2)}`,\n display: 'inline-block' }) }));\n\n// IconWrapper - replaced with inline Box component for better TypeScript compatibility\n// const IconWrapper = styled(Box)<{ position: 'start' | 'end' }>(({ theme, position }) => {\n// const positionStyles = position === 'start' ? { left: '12px' } : { right: '12px' };\n// return {\n// position: 'absolute' as const,\n// top: '12px',\n// ...positionStyles,\n// color: theme.palette.text.secondary,\n// pointerEvents: 'none' as const,\n// zIndex: 1,\n// };\n// });\n\n// Rich text toolbar styling\n\nconst ICON_GUTTER = '40px';\n\nconst TEXTAREA_DEFAULTS = {\n variant: 'default',\n color: 'primary',\n size: 'md',\n error: false,\n glassLabel: false,\n glow: false,\n glass: false,\n gradient: false,\n iconPosition: 'start',\n minRows: 3 } satisfies Partial<TextareaProps>;\n\n// Strips explicitly-undefined props before the merge, so `prop={undefined}`\n// still falls back to the default as a destructuring default would.\nconst definedProps = (props: TextareaProps): Partial<TextareaProps> =>\n Object.fromEntries(\n Object.entries(props).filter(([, value]) => value !== undefined),\n ) as Partial<TextareaProps>;\n\n// Label above, helper text below — identical for the plain and rich variants,\n// which previously duplicated both.\nconst TextareaShell: React.FC<{\n testId?: string;\n label?: React.ReactNode;\n glassLabel: boolean;\n error: boolean;\n helperText?: React.ReactNode;\n children: React.ReactNode;\n}> = ({ testId, label, glassLabel, error, helperText, children }) => (\n <Box\n sx={{ position: 'relative', width: '100%' }}\n data-testid={testId ? `${testId}-wrapper` : undefined}\n >\n {label && (\n <StyledLabel glass={glassLabel} error={error}>\n {label}\n </StyledLabel>\n )}\n\n {children}\n\n {helperText && (\n <FormHelperText error={error} sx={{ mt: 1 }}>\n {helperText}\n </FormHelperText>\n )}\n </Box>\n);\n\nconst TextareaIcon: React.FC<{\n icon?: React.ReactNode;\n iconPosition: 'start' | 'end';\n}> = ({ icon, iconPosition }) => (\n <Box\n sx={{\n position: 'absolute',\n top: '12px',\n ...(iconPosition === 'start' ? { left: '12px' } : { right: '12px' }),\n color: 'text.secondary',\n pointerEvents: 'none',\n zIndex: 1 }}\n >\n {icon}\n </Box>\n);\n\nexport const Textarea: React.FC<TextareaProps> = (textareaProps) => {\n const {\n variant,\n color,\n size,\n error,\n helperText,\n label,\n glassLabel,\n glow,\n glass,\n gradient,\n icon,\n iconPosition,\n minRows,\n maxRows,\n style,\n 'data-testid': dataTestId,\n dataTestId: dataTestIdCamelCase,\n ...props\n } = { ...TEXTAREA_DEFAULTS, ...definedProps(textareaProps) };\n\n const [richTextValue, setRichTextValue] = useState('');\n const hasIcon = Boolean(icon);\n const testId = dataTestId || dataTestIdCamelCase;\n\n const textareaStyle = {\n ...style,\n // Same gap either side; only which side it applies to changes. The previous\n // version had `iconPosition === 'start' ? '40px' : '40px'`, a ternary whose\n // two branches were identical.\n ...(hasIcon && {\n [iconPosition === 'start' ? 'paddingLeft' : 'paddingRight']: ICON_GUTTER }) };\n\n // If rich text variant, use the rich text editor\n if (variant === 'rich') {\n return (\n <TextareaShell testId={testId} label={label} glassLabel={glassLabel} error={error} helperText={helperText}>\n <TextareaRichEditor\n value={richTextValue}\n onChange={setRichTextValue}\n placeholder={props.placeholder}\n error={error}\n glass={glass}\n color={color}\n characterLimit={props.maxLength}\n />\n </TextareaShell>\n );\n }\n\n return (\n <TextareaShell testId={testId} label={label} glassLabel={glassLabel} error={error} helperText={helperText}>\n <Box sx={{ position: 'relative' }}>\n {hasIcon && <TextareaIcon icon={icon} iconPosition={iconPosition} />}\n\n <StyledTextarea\n customVariant={variant}\n customColor={color}\n customSize={size}\n glow={glow}\n glass={glass}\n gradient={gradient}\n error={error}\n minRows={variant === 'autosize' ? minRows : undefined}\n maxRows={variant === 'autosize' ? maxRows : undefined}\n style={textareaStyle}\n aria-label={label || props['aria-label']}\n data-testid={testId}\n {...props}\n />\n </Box>\n </TextareaShell>\n );\n};\n\nTextarea.displayName = 'Textarea';\n","import { alpha, keyframes } from '@mui/material';\nimport type { CSSObject, Theme } from '@mui/material';\n\nconst glowAnimation = keyframes`\n 0% {\n box-shadow: 0 0 5px currentColor;\n }\n 50% {\n box-shadow: 0 0 20px currentColor, 0 0 30px currentColor;\n }\n 100% {\n box-shadow: 0 0 5px currentColor;\n }\n`;\n\n// Ripple animation for buttons (commented out - not currently used)\n// const rippleAnimation = keyframes`\n// 0% {\n// transform: scale(0);\n// opacity: 1;\n// }\n// 100% {\n// transform: scale(4);\n// opacity: 0;\n// }\n// `;\n\n// Float animation for rich text toolbar\nexport const floatAnimation = keyframes`\n 0% {\n transform: translateY(0px);\n }\n 50% {\n transform: translateY(-3px);\n }\n 100% {\n transform: translateY(0px);\n }\n`;\n\ntype ResolvedPalette = {\n main: string;\n dark: string;\n light: string;\n contrastText: string;\n};\n\ntype PartialPalette = { main: string; dark?: string; light?: string; contrastText?: string };\n\n// grey is indexed by weight rather than main/dark/light, so neutral is built by\n// hand. The literals are the MUI grey values, used if the theme omits a weight.\nconst neutralPalette = (theme: Theme): ResolvedPalette => {\n const grey = theme.palette.grey as unknown as Record<number, string>;\n\n return {\n main: grey?.[700] || '#616161',\n dark: grey?.[800] || '#424242',\n light: grey?.[500] || '#9e9e9e',\n contrastText: '#fff',\n };\n};\n\n// Each slot falls back to the palette's own main, then to primary — a custom\n// theme can define main without dark or light.\nconst pick = (...candidates: Array<string | undefined>): string =>\n candidates.find(Boolean) ?? '';\n\nconst withFallbacks = (theme: Theme, palette: PartialPalette): ResolvedPalette => ({\n main: pick(palette?.main, theme.palette.primary.main),\n dark: pick(palette?.dark, palette?.main, theme.palette.primary.dark),\n light: pick(palette?.light, palette?.main, theme.palette.primary.light),\n contrastText: pick(palette?.contrastText, '#fff'),\n});\n\nexport const getColorFromTheme = (theme: Theme, color: string): ResolvedPalette => {\n if (color === 'neutral') return neutralPalette(theme);\n\n const colorMap: Record<string, PartialPalette> = {\n primary: theme.palette.primary,\n secondary: theme.palette.secondary,\n success: theme.palette.success,\n warning: theme.palette.warning,\n info: theme.palette.info,\n danger: theme.palette.error,\n };\n\n return withFallbacks(theme, colorMap[color] || theme.palette.primary);\n};\n\n// glass, gradient and glow are independent flags that each layer styles onto the\n// base. Spelled out here rather than inline so the styled() callback keeps one\n// branch instead of three.\nexport const textareaEmphasisStyles = ({\n theme,\n colorPalette,\n glass,\n gradient,\n glow,\n}: {\n theme: Theme;\n colorPalette: { main: string; light?: string; dark?: string };\n glass?: boolean;\n gradient?: boolean;\n glow?: boolean;\n}): CSSObject => {\nconst glassStyles = glass\n ? {\n backgroundColor: alpha(theme.palette.background.paper, 0.1),\n backdropFilter: 'blur(20px)',\n border: `1px solid ${alpha(theme.palette.divider, 0.2)}`,\n '&:hover': {\n backgroundColor: alpha(theme.palette.background.paper, 0.15),\n backdropFilter: 'blur(25px)',\n },\n '&:focus': {\n backgroundColor: alpha(theme.palette.background.paper, 0.2),\n backdropFilter: 'blur(30px)',\n },\n }\n : {};\n\n// Gradient border effect\nconst gradientStyles = gradient\n ? {\n background: `linear-gradient(${theme.palette.background.paper}, ${theme.palette.background.paper}) padding-box,\n linear-gradient(135deg, ${colorPalette.main}, ${colorPalette.light}) border-box`,\n border: '2px solid transparent',\n '&:focus': {\n background: `linear-gradient(${theme.palette.background.paper}, ${theme.palette.background.paper}) padding-box,\n linear-gradient(135deg, ${colorPalette.main}, ${colorPalette.dark}) border-box`,\n },\n }\n : {};\n\n// Glow effect\nconst glowStyles = glow\n ? {\n animation: `${glowAnimation} 2s ease-in-out infinite`,\n boxShadow: `0 0 10px ${alpha(colorPalette.main, 0.3)}`,\n }\n : {};\n\n return { ...glassStyles, ...gradientStyles, ...glowStyles };\n};\n","import Code from '@mui/icons-material/Code';\nimport FormatBold from '@mui/icons-material/FormatBold';\nimport FormatColorFill from '@mui/icons-material/FormatColorFill';\nimport FormatColorText from '@mui/icons-material/FormatColorText';\nimport FormatItalic from '@mui/icons-material/FormatItalic';\nimport FormatListBulleted from '@mui/icons-material/FormatListBulleted';\nimport FormatListNumbered from '@mui/icons-material/FormatListNumbered';\nimport FormatQuote from '@mui/icons-material/FormatQuote';\nimport FormatUnderlined from '@mui/icons-material/FormatUnderlined';\nimport Link from '@mui/icons-material/Link';\nimport { alpha, Box, Divider, IconButton, Tooltip } from '@mui/material';\nimport type { Theme } from '@mui/material';\nimport { styled } from '@mui/material';\nimport React, { useEffect, useRef, useState } from 'react';\n\nimport { floatAnimation, getColorFromTheme } from './Textarea.styles';\n\nconst RichToolbar = styled(Box)<{ glass?: boolean }>(({ theme, glass }) => ({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(0.5),\n padding: theme.spacing(1),\n borderRadius: `${theme.spacing(1)} ${theme.spacing(1)} 0 0`,\n borderBottom: `1px solid ${theme.palette.divider}`,\n background: glass ? alpha(theme.palette.background.paper, 0.1) : theme.palette.background.paper,\n ...(glass && {\n backdropFilter: 'blur(15px)' }),\n '& .MuiDivider-root': {\n height: 24,\n margin: `0 ${theme.spacing(1)}` } }));\n\nconst ToolbarButton = styled(IconButton, {\n shouldForwardProp: (prop) => prop !== 'active' })<{ active?: boolean }>(({ theme, active }) => ({\n padding: theme.spacing(0.75),\n borderRadius: theme.spacing(0.5),\n color: active ? theme.palette.primary.main : theme.palette.text.secondary,\n backgroundColor: active ? alpha(theme.palette.primary.main, 0.1) : 'transparent',\n transition: 'all 0.2s ease',\n position: 'relative',\n overflow: 'hidden',\n\n '&::before': {\n content: '\"\"',\n position: 'absolute',\n top: '50%',\n left: '50%',\n width: 0,\n height: 0,\n borderRadius: '50%',\n backgroundColor: alpha(theme.palette.primary.main, 0.3),\n transform: 'translate(-50%, -50%)',\n transition: 'width 0.3s, height 0.3s' },\n\n '&:hover': {\n color: theme.palette.primary.main,\n backgroundColor: alpha(theme.palette.primary.main, 0.15),\n transform: 'translateY(-1px)',\n animation: `${floatAnimation} 1.5s ease-in-out infinite`,\n\n '&::before': {\n width: '100%',\n height: '100%' } },\n\n '&:active': {\n transform: 'scale(0.95)' } }));\n\nconst CharacterCount = styled(Box)<{ limit?: number; count: number }>(({ theme, limit, count }) => {\n const isWarning = limit && count > limit * 0.8;\n const isError = limit && count > limit;\n\n return {\n position: 'absolute',\n bottom: theme.spacing(1),\n right: theme.spacing(1),\n fontSize: '0.75rem',\n color: isError\n ? theme.palette.error.main\n : isWarning\n ? theme.palette.warning.main\n : theme.palette.text.secondary,\n padding: '2px 6px',\n borderRadius: theme.spacing(0.5),\n backgroundColor: alpha(theme.palette.background.paper, 0.8),\n backdropFilter: 'blur(10px)',\n transition: 'all 0.3s ease' };\n});\n\nconst ContentEditableDiv = styled('div')<{\n error?: boolean;\n focused?: boolean;\n glass?: boolean;\n customColor?: string;\n theme?: Theme;\n}>(({ theme, error, focused, glass, customColor = 'primary' }) => {\n if (!theme) return {};\n const colorPalette = getColorFromTheme(theme, customColor);\n const errorColor = theme.palette.error;\n\n return {\n minHeight: '120px',\n padding: theme.spacing(1.5),\n borderRadius: `0 0 ${theme.spacing(1)} ${theme.spacing(1)}`,\n border: `2px solid ${error ? errorColor.main : focused ? colorPalette.main : theme.palette.divider}`,\n borderTop: 'none',\n backgroundColor: glass\n ? alpha(theme.palette.background.paper, 0.1)\n : theme.palette.background.paper,\n color: theme.palette.text.primary,\n fontFamily: theme.typography.fontFamily,\n fontSize: '1rem',\n lineHeight: 1.5,\n outline: 'none',\n transition: 'all 0.3s ease',\n cursor: 'text',\n\n ...(glass && {\n backdropFilter: 'blur(20px)' }),\n\n '&:hover': {\n backgroundColor: glass\n ? alpha(theme.palette.background.paper, 0.15)\n : alpha(theme.palette.background.paper, 0.9) },\n\n '&:focus': {\n borderColor: error ? errorColor.main : colorPalette.main,\n boxShadow: `0 0 0 3px ${alpha(error ? errorColor.main : colorPalette.main, 0.1)}` },\n\n '& > *': {\n margin: '0.5em 0' },\n\n '&[contenteditable=\"true\"]:empty::before': {\n content: 'attr(data-placeholder)',\n color: theme.palette.text.secondary,\n opacity: 0.6 } };\n});\n\n// Rich text formatting functions\nconst formatText = (command: string, value?: string) => {\n document.execCommand(command, false, value);\n};\n\n// Editable state: what is typed, how long it is, and which formats apply at the\n// caret. Kept apart from the markup below.\nconst useRichEditorState = ({\n value,\n onChange }: {\n value?: string;\n onChange?: (html: string) => void;\n}) => {\n const [focused, setFocused] = useState(false);\n const [characterCount, setCharacterCount] = useState(0);\n const [activeFormats, setActiveFormats] = useState({\n bold: false,\n italic: false,\n underline: false,\n list: false,\n orderedList: false,\n quote: false,\n code: false });\n const contentRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (contentRef.current && value !== undefined) {\n if (contentRef.current.innerHTML !== value) {\n contentRef.current.innerHTML = value;\n }\n setCharacterCount(contentRef.current.innerText.length);\n }\n }, [value]);\n\n const handleInput = () => {\n if (contentRef.current) {\n const html = contentRef.current.innerHTML;\n onChange?.(html);\n setCharacterCount(contentRef.current.innerText.length);\n updateActiveFormats();\n }\n };\n\n const updateActiveFormats = () => {\n setActiveFormats({\n bold: document.queryCommandState('bold'),\n italic: document.queryCommandState('italic'),\n underline: document.queryCommandState('underline'),\n list: document.queryCommandState('insertUnorderedList'),\n orderedList: document.queryCommandState('insertOrderedList'),\n quote: false,\n code: false });\n };\n\n const handleFormat = (command: string, value?: string) => {\n formatText(command, value);\n updateActiveFormats();\n contentRef.current?.focus();\n };\n\n return {\n focused,\n setFocused,\n characterCount,\n activeFormats,\n contentRef,\n handleInput,\n handleFormat,\n updateActiveFormats };\n};\n\nconst InlineFormatButtons: React.FC<{\n activeFormats: Record<string, boolean>;\n onCommand: (command: string, value?: string) => void;\n}> = ({ activeFormats, onCommand }) => (\n <>\n <Tooltip title=\"Bold\" arrow>\n <ToolbarButton\n size=\"small\"\n active={activeFormats.bold}\n onClick={() => onCommand('bold')}\n >\n <FormatBold fontSize=\"small\" />\n </ToolbarButton>\n </Tooltip>\n\n <Tooltip title=\"Italic\" arrow>\n <ToolbarButton\n size=\"small\"\n active={activeFormats.italic}\n onClick={() => onCommand('italic')}\n >\n <FormatItalic fontSize=\"small\" />\n </ToolbarButton>\n </Tooltip>\n\n <Tooltip title=\"Underline\" arrow>\n <ToolbarButton\n size=\"small\"\n active={activeFormats.underline}\n onClick={() => onCommand('underline')}\n >\n <FormatUnderlined fontSize=\"small\" />\n </ToolbarButton>\n </Tooltip>\n\n </>\n);\n\nconst BlockFormatButtons: React.FC<{\n activeFormats: Record<string, boolean>;\n onCommand: (command: string, value?: string) => void;\n}> = ({ activeFormats, onCommand }) => (\n <>\n <Divider orientation=\"vertical\" flexItem />\n\n <Tooltip title=\"Bullet List\" arrow>\n <ToolbarButton\n size=\"small\"\n active={activeFormats.list}\n onClick={() => onCommand('insertUnorderedList')}\n >\n <FormatListBulleted fontSize=\"small\" />\n </ToolbarButton>\n </Tooltip>\n\n <Tooltip title=\"Numbered List\" arrow>\n <ToolbarButton\n size=\"small\"\n active={activeFormats.orderedList}\n onClick={() => onCommand('insertOrderedList')}\n >\n <FormatListNumbered fontSize=\"small\" />\n </ToolbarButton>\n </Tooltip>\n\n <Divider orientation=\"vertical\" flexItem />\n\n <Tooltip title=\"Quote\" arrow>\n <ToolbarButton size=\"small\" onClick={() => onCommand('formatBlock', 'blockquote')}>\n <FormatQuote fontSize=\"small\" />\n </ToolbarButton>\n </Tooltip>\n\n <Tooltip title=\"Code\" arrow>\n <ToolbarButton size=\"small\" onClick={() => onCommand('formatBlock', 'pre')}>\n <Code fontSize=\"small\" />\n </ToolbarButton>\n </Tooltip>\n\n <Divider orientation=\"vertical\" flexItem />\n\n <Tooltip title=\"Insert Link\" arrow>\n <ToolbarButton\n size=\"small\"\n onClick={() => {\n const url = window.prompt('Enter URL:');\n if (url) onCommand('createLink', url);\n }}\n >\n <Link fontSize=\"small\" />\n </ToolbarButton>\n </Tooltip>\n\n <Tooltip title=\"Text Color\" arrow>\n <ToolbarButton size=\"small\">\n <FormatColorText fontSize=\"small\" />\n </ToolbarButton>\n </Tooltip>\n\n <Tooltip title=\"Background Color\" arrow>\n <ToolbarButton size=\"small\">\n <FormatColorFill fontSize=\"small\" />\n </ToolbarButton>\n </Tooltip>\n </>\n);\n\n// The formatting buttons. Split out so the editor body is state, handlers and\n// the editable region.\nconst EditorToolbar: React.FC<{\n glass?: boolean;\n activeFormats: Record<string, boolean>;\n onCommand: (command: string, value?: string) => void;\n}> = ({ glass, activeFormats, onCommand }) => (\n <RichToolbar glass={glass}>\n <InlineFormatButtons activeFormats={activeFormats} onCommand={onCommand} />\n <BlockFormatButtons activeFormats={activeFormats} onCommand={onCommand} />\n </RichToolbar>\n);\n\nexport const TextareaRichEditor: React.FC<{\n value?: string;\n onChange?: (html: string) => void;\n placeholder?: string;\n error?: boolean;\n glass?: boolean;\n color?: string;\n characterLimit?: number;\n}> = ({ value, onChange, placeholder, error, glass, color, characterLimit }) => {\n const {\n focused,\n setFocused,\n characterCount,\n activeFormats,\n contentRef,\n handleInput,\n handleFormat,\n updateActiveFormats } = useRichEditorState({ value, onChange });\n\n return (\n <Box sx={{ position: 'relative' }}>\n <EditorToolbar glass={glass} activeFormats={activeFormats} onCommand={handleFormat} />\n\n <ContentEditableDiv\n ref={contentRef}\n contentEditable\n data-placeholder={placeholder}\n error={error}\n focused={focused}\n glass={glass}\n customColor={color}\n onFocus={() => setFocused(true)}\n onBlur={() => setFocused(false)}\n onInput={handleInput}\n onKeyUp={updateActiveFormats}\n onMouseUp={updateActiveFormats}\n role=\"textbox\"\n aria-multiline=\"true\"\n aria-label={placeholder || 'Rich text editor'}\n />\n\n {characterLimit && (\n <CharacterCount limit={characterLimit} count={characterCount}>\n {characterCount}\n {characterLimit ? `/${characterLimit}` : ''}\n </CharacterCount>\n )}\n </Box>\n );\n};\n"],"mappings":"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","names":["alpha","Box","styled","useState","alpha","alpha","value","jsx","jsxs","styled","alpha","Box","useState"]}
1
+ {"version":3,"sources":["../../src/components/form/Textarea/Textarea.tsx","../../src/components/form/Textarea/Textarea.styles.ts","../../src/components/form/Textarea/TextareaRichEditor.tsx"],"sourcesContent":["import {\n alpha,\n Box,\n FormHelperText,\n InputLabel,\n TextareaAutosize } from '@mui/material';\nimport type { Theme } from '@mui/material';\nimport { styled } from '@mui/material';\nimport React, { useState } from 'react';\n\nimport {\n getColorFromTheme,\n textareaEmphasisStyles } from './Textarea.styles';\nimport { TextareaRichEditor } from './TextareaRichEditor';\nimport type { TextareaProps } from './Textarea.types';\n\n// Interface for styled component props\ninterface StyledTextareaProps {\n customVariant?: string;\n customColor?: string;\n customSize?: string;\n glow?: boolean;\n glass?: boolean;\n gradient?: boolean;\n error?: boolean;\n theme?: Theme;\n}\n\n// Glow animation for enhanced visual effects\nconst StyledTextarea = styled(TextareaAutosize, {\n shouldForwardProp: (prop) =>\n !['customVariant', 'customColor', 'customSize', 'glow', 'glass', 'gradient', 'error'].includes(\n prop as string,\n ) })<StyledTextareaProps>(({\n theme,\n customVariant,\n customColor = 'primary',\n customSize = 'md',\n glow,\n glass,\n gradient,\n error }) => {\n if (!theme) return {};\n const colorPalette = getColorFromTheme(theme, customColor);\n const errorColor = theme.palette.error;\n\n const sizeMap = {\n xs: { padding: '6px 8px', fontSize: '0.75rem', minHeight: '60px' },\n sm: { padding: '8px 10px', fontSize: '0.875rem', minHeight: '80px' },\n md: { padding: '10px 12px', fontSize: '1rem', minHeight: '100px' },\n lg: { padding: '12px 14px', fontSize: '1.125rem', minHeight: '120px' },\n xl: { padding: '14px 16px', fontSize: '1.25rem', minHeight: '140px' } };\n\n const baseStyles = {\n width: '100%',\n fontFamily: theme.typography.fontFamily,\n borderRadius: theme.spacing(1),\n border: `2px solid ${error ? errorColor.main : theme.palette.divider}`,\n backgroundColor: theme.palette.background.paper,\n color: theme.palette.text.primary,\n transition: 'all 0.3s ease',\n resize: customVariant === 'resizable' ? 'vertical' : 'none',\n outline: 'none',\n ...sizeMap[customSize as keyof typeof sizeMap],\n\n '&::placeholder': {\n color: theme.palette.text.secondary,\n opacity: 0.7 },\n\n '&:hover': {\n borderColor: error ? errorColor.dark : colorPalette.main,\n backgroundColor: alpha(theme.palette.background.paper, 0.8) },\n\n '&:focus': {\n borderColor: error ? errorColor.main : colorPalette.main,\n backgroundColor: theme.palette.background.paper,\n boxShadow: `0 0 0 3px ${alpha(error ? errorColor.main : colorPalette.main, 0.1)}` } };\n\n // Glass morphism effect\n return {\n ...baseStyles,\n ...textareaEmphasisStyles({ theme, colorPalette, glass, gradient, glow }) };\n});\n\nconst StyledLabel = styled(InputLabel, {\n shouldForwardProp: (prop) => !['glass', 'error'].includes(prop as string) })<{ glass?: boolean; error?: boolean }>(({ theme, glass, error }) => ({\n marginBottom: theme.spacing(1),\n fontWeight: 500,\n color: error ? theme.palette.error.main : theme.palette.text.primary,\n ...(glass && {\n backgroundColor: alpha(theme.palette.background.paper, 0.1),\n backdropFilter: 'blur(10px)',\n padding: '4px 8px',\n borderRadius: '4px',\n border: `1px solid ${alpha(theme.palette.divider, 0.2)}`,\n display: 'inline-block' }) }));\n\n// IconWrapper - replaced with inline Box component for better TypeScript compatibility\n// const IconWrapper = styled(Box)<{ position: 'start' | 'end' }>(({ theme, position }) => {\n// const positionStyles = position === 'start' ? { left: '12px' } : { right: '12px' };\n// return {\n// position: 'absolute' as const,\n// top: '12px',\n// ...positionStyles,\n// color: theme.palette.text.secondary,\n// pointerEvents: 'none' as const,\n// zIndex: 1,\n// };\n// });\n\n// Rich text toolbar styling\n\nconst ICON_GUTTER = '40px';\n\nconst TEXTAREA_DEFAULTS = {\n variant: 'default',\n color: 'primary',\n size: 'md',\n error: false,\n glassLabel: false,\n glow: false,\n glass: false,\n gradient: false,\n iconPosition: 'start',\n minRows: 3 } satisfies Partial<TextareaProps>;\n\n// Strips explicitly-undefined props before the merge, so `prop={undefined}`\n// still falls back to the default as a destructuring default would.\nconst definedProps = (props: TextareaProps): Partial<TextareaProps> =>\n Object.fromEntries(\n Object.entries(props).filter(([, value]) => value !== undefined),\n ) as Partial<TextareaProps>;\n\n// Label above, helper text below — identical for the plain and rich variants,\n// which previously duplicated both.\nconst TextareaShell: React.FC<{\n testId?: string;\n label?: React.ReactNode;\n glassLabel: boolean;\n error: boolean;\n helperText?: React.ReactNode;\n children: React.ReactNode;\n}> = ({ testId, label, glassLabel, error, helperText, children }) => (\n <Box\n sx={{ position: 'relative', width: '100%' }}\n data-testid={testId ? `${testId}-wrapper` : undefined}\n >\n {label && (\n <StyledLabel glass={glassLabel} error={error}>\n {label}\n </StyledLabel>\n )}\n\n {children}\n\n {helperText && (\n <FormHelperText error={error} sx={{ mt: 1 }}>\n {helperText}\n </FormHelperText>\n )}\n </Box>\n);\n\nconst TextareaIcon: React.FC<{\n icon?: React.ReactNode;\n iconPosition: 'start' | 'end';\n}> = ({ icon, iconPosition }) => (\n <Box\n sx={{\n position: 'absolute',\n top: '12px',\n ...(iconPosition === 'start' ? { left: '12px' } : { right: '12px' }),\n color: 'text.secondary',\n pointerEvents: 'none',\n zIndex: 1 }}\n >\n {icon}\n </Box>\n);\n\nexport const Textarea: React.FC<TextareaProps> = (textareaProps) => {\n const {\n variant,\n color,\n size,\n error,\n helperText,\n label,\n glassLabel,\n glow,\n glass,\n gradient,\n icon,\n iconPosition,\n minRows,\n maxRows,\n style,\n 'data-testid': dataTestId,\n dataTestId: dataTestIdCamelCase,\n ...props\n } = { ...TEXTAREA_DEFAULTS, ...definedProps(textareaProps) };\n\n // Read off the props rather than the merged object: the spread widens every\n // key to optional, which would lose what the variant union already proved.\n const { richEditorCopy } = textareaProps;\n\n const [richTextValue, setRichTextValue] = useState('');\n const hasIcon = Boolean(icon);\n const testId = dataTestId || dataTestIdCamelCase;\n\n const textareaStyle = {\n ...style,\n // Same gap either side; only which side it applies to changes. The previous\n // version had `iconPosition === 'start' ? '40px' : '40px'`, a ternary whose\n // two branches were identical.\n ...(hasIcon && {\n [iconPosition === 'start' ? 'paddingLeft' : 'paddingRight']: ICON_GUTTER }) };\n\n // If rich text variant, use the rich text editor\n if (variant === 'rich' && richEditorCopy) {\n return (\n <TextareaShell testId={testId} label={label} glassLabel={glassLabel} error={error} helperText={helperText}>\n <TextareaRichEditor\n copy={richEditorCopy}\n value={richTextValue}\n onChange={setRichTextValue}\n placeholder={props.placeholder}\n error={error}\n glass={glass}\n color={color}\n characterLimit={props.maxLength}\n />\n </TextareaShell>\n );\n }\n\n return (\n <TextareaShell testId={testId} label={label} glassLabel={glassLabel} error={error} helperText={helperText}>\n <Box sx={{ position: 'relative' }}>\n {hasIcon && <TextareaIcon icon={icon} iconPosition={iconPosition} />}\n\n <StyledTextarea\n customVariant={variant}\n customColor={color}\n customSize={size}\n glow={glow}\n glass={glass}\n gradient={gradient}\n error={error}\n minRows={variant === 'autosize' ? minRows : undefined}\n maxRows={variant === 'autosize' ? maxRows : undefined}\n style={textareaStyle}\n aria-label={label || props['aria-label']}\n data-testid={testId}\n {...props}\n />\n </Box>\n </TextareaShell>\n );\n};\n\nTextarea.displayName = 'Textarea';\n","import { alpha, keyframes } from '@mui/material';\nimport type { CSSObject, Theme } from '@mui/material';\n\nconst glowAnimation = keyframes`\n 0% {\n box-shadow: 0 0 5px currentColor;\n }\n 50% {\n box-shadow: 0 0 20px currentColor, 0 0 30px currentColor;\n }\n 100% {\n box-shadow: 0 0 5px currentColor;\n }\n`;\n\n// Ripple animation for buttons (commented out - not currently used)\n// const rippleAnimation = keyframes`\n// 0% {\n// transform: scale(0);\n// opacity: 1;\n// }\n// 100% {\n// transform: scale(4);\n// opacity: 0;\n// }\n// `;\n\n// Float animation for rich text toolbar\nexport const floatAnimation = keyframes`\n 0% {\n transform: translateY(0px);\n }\n 50% {\n transform: translateY(-3px);\n }\n 100% {\n transform: translateY(0px);\n }\n`;\n\ntype ResolvedPalette = {\n main: string;\n dark: string;\n light: string;\n contrastText: string;\n};\n\ntype PartialPalette = { main: string; dark?: string; light?: string; contrastText?: string };\n\n// grey is indexed by weight rather than main/dark/light, so neutral is built by\n// hand. The literals are the MUI grey values, used if the theme omits a weight.\nconst neutralPalette = (theme: Theme): ResolvedPalette => {\n const grey = theme.palette.grey as unknown as Record<number, string>;\n\n return {\n main: grey?.[700] || '#616161',\n dark: grey?.[800] || '#424242',\n light: grey?.[500] || '#9e9e9e',\n contrastText: '#fff',\n };\n};\n\n// Each slot falls back to the palette's own main, then to primary — a custom\n// theme can define main without dark or light.\nconst pick = (...candidates: Array<string | undefined>): string =>\n candidates.find(Boolean) ?? '';\n\nconst withFallbacks = (theme: Theme, palette: PartialPalette): ResolvedPalette => ({\n main: pick(palette?.main, theme.palette.primary.main),\n dark: pick(palette?.dark, palette?.main, theme.palette.primary.dark),\n light: pick(palette?.light, palette?.main, theme.palette.primary.light),\n contrastText: pick(palette?.contrastText, '#fff'),\n});\n\nexport const getColorFromTheme = (theme: Theme, color: string): ResolvedPalette => {\n if (color === 'neutral') return neutralPalette(theme);\n\n const colorMap: Record<string, PartialPalette> = {\n primary: theme.palette.primary,\n secondary: theme.palette.secondary,\n success: theme.palette.success,\n warning: theme.palette.warning,\n info: theme.palette.info,\n danger: theme.palette.error,\n };\n\n return withFallbacks(theme, colorMap[color] || theme.palette.primary);\n};\n\n// glass, gradient and glow are independent flags that each layer styles onto the\n// base. Spelled out here rather than inline so the styled() callback keeps one\n// branch instead of three.\nexport const textareaEmphasisStyles = ({\n theme,\n colorPalette,\n glass,\n gradient,\n glow,\n}: {\n theme: Theme;\n colorPalette: { main: string; light?: string; dark?: string };\n glass?: boolean;\n gradient?: boolean;\n glow?: boolean;\n}): CSSObject => {\nconst glassStyles = glass\n ? {\n backgroundColor: alpha(theme.palette.background.paper, 0.1),\n backdropFilter: 'blur(20px)',\n border: `1px solid ${alpha(theme.palette.divider, 0.2)}`,\n '&:hover': {\n backgroundColor: alpha(theme.palette.background.paper, 0.15),\n backdropFilter: 'blur(25px)',\n },\n '&:focus': {\n backgroundColor: alpha(theme.palette.background.paper, 0.2),\n backdropFilter: 'blur(30px)',\n },\n }\n : {};\n\n// Gradient border effect\nconst gradientStyles = gradient\n ? {\n background: `linear-gradient(${theme.palette.background.paper}, ${theme.palette.background.paper}) padding-box,\n linear-gradient(135deg, ${colorPalette.main}, ${colorPalette.light}) border-box`,\n border: '2px solid transparent',\n '&:focus': {\n background: `linear-gradient(${theme.palette.background.paper}, ${theme.palette.background.paper}) padding-box,\n linear-gradient(135deg, ${colorPalette.main}, ${colorPalette.dark}) border-box`,\n },\n }\n : {};\n\n// Glow effect\nconst glowStyles = glow\n ? {\n animation: `${glowAnimation} 2s ease-in-out infinite`,\n boxShadow: `0 0 10px ${alpha(colorPalette.main, 0.3)}`,\n }\n : {};\n\n return { ...glassStyles, ...gradientStyles, ...glowStyles };\n};\n","import Code from '@mui/icons-material/Code';\nimport FormatBold from '@mui/icons-material/FormatBold';\nimport FormatColorFill from '@mui/icons-material/FormatColorFill';\nimport FormatColorText from '@mui/icons-material/FormatColorText';\nimport FormatItalic from '@mui/icons-material/FormatItalic';\nimport FormatListBulleted from '@mui/icons-material/FormatListBulleted';\nimport FormatListNumbered from '@mui/icons-material/FormatListNumbered';\nimport FormatQuote from '@mui/icons-material/FormatQuote';\nimport FormatUnderlined from '@mui/icons-material/FormatUnderlined';\nimport Link from '@mui/icons-material/Link';\nimport { alpha, Box, Divider, IconButton, Tooltip } from '@mui/material';\nimport type { Theme } from '@mui/material';\nimport { styled } from '@mui/material';\nimport React, { useEffect, useRef, useState } from 'react';\n\nimport { floatAnimation, getColorFromTheme } from './Textarea.styles';\nimport type { RichEditorToolbarCopy } from '../../../copy';\n\nconst RichToolbar = styled(Box)<{ glass?: boolean }>(({ theme, glass }) => ({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(0.5),\n padding: theme.spacing(1),\n borderRadius: `${theme.spacing(1)} ${theme.spacing(1)} 0 0`,\n borderBottom: `1px solid ${theme.palette.divider}`,\n background: glass ? alpha(theme.palette.background.paper, 0.1) : theme.palette.background.paper,\n ...(glass && {\n backdropFilter: 'blur(15px)' }),\n '& .MuiDivider-root': {\n height: 24,\n margin: `0 ${theme.spacing(1)}` } }));\n\nconst ToolbarButton = styled(IconButton, {\n shouldForwardProp: (prop) => prop !== 'active' })<{ active?: boolean }>(({ theme, active }) => ({\n padding: theme.spacing(0.75),\n borderRadius: theme.spacing(0.5),\n color: active ? theme.palette.primary.main : theme.palette.text.secondary,\n backgroundColor: active ? alpha(theme.palette.primary.main, 0.1) : 'transparent',\n transition: 'all 0.2s ease',\n position: 'relative',\n overflow: 'hidden',\n\n '&::before': {\n content: '\"\"',\n position: 'absolute',\n top: '50%',\n left: '50%',\n width: 0,\n height: 0,\n borderRadius: '50%',\n backgroundColor: alpha(theme.palette.primary.main, 0.3),\n transform: 'translate(-50%, -50%)',\n transition: 'width 0.3s, height 0.3s' },\n\n '&:hover': {\n color: theme.palette.primary.main,\n backgroundColor: alpha(theme.palette.primary.main, 0.15),\n transform: 'translateY(-1px)',\n animation: `${floatAnimation} 1.5s ease-in-out infinite`,\n\n '&::before': {\n width: '100%',\n height: '100%' } },\n\n '&:active': {\n transform: 'scale(0.95)' } }));\n\nconst CharacterCount = styled(Box)<{ limit?: number; count: number }>(({ theme, limit, count }) => {\n const isWarning = limit && count > limit * 0.8;\n const isError = limit && count > limit;\n\n return {\n position: 'absolute',\n bottom: theme.spacing(1),\n right: theme.spacing(1),\n fontSize: '0.75rem',\n color: isError\n ? theme.palette.error.main\n : isWarning\n ? theme.palette.warning.main\n : theme.palette.text.secondary,\n padding: '2px 6px',\n borderRadius: theme.spacing(0.5),\n backgroundColor: alpha(theme.palette.background.paper, 0.8),\n backdropFilter: 'blur(10px)',\n transition: 'all 0.3s ease' };\n});\n\nconst ContentEditableDiv = styled('div')<{\n error?: boolean;\n focused?: boolean;\n glass?: boolean;\n customColor?: string;\n theme?: Theme;\n}>(({ theme, error, focused, glass, customColor = 'primary' }) => {\n if (!theme) return {};\n const colorPalette = getColorFromTheme(theme, customColor);\n const errorColor = theme.palette.error;\n\n return {\n minHeight: '120px',\n padding: theme.spacing(1.5),\n borderRadius: `0 0 ${theme.spacing(1)} ${theme.spacing(1)}`,\n border: `2px solid ${error ? errorColor.main : focused ? colorPalette.main : theme.palette.divider}`,\n borderTop: 'none',\n backgroundColor: glass\n ? alpha(theme.palette.background.paper, 0.1)\n : theme.palette.background.paper,\n color: theme.palette.text.primary,\n fontFamily: theme.typography.fontFamily,\n fontSize: '1rem',\n lineHeight: 1.5,\n outline: 'none',\n transition: 'all 0.3s ease',\n cursor: 'text',\n\n ...(glass && {\n backdropFilter: 'blur(20px)' }),\n\n '&:hover': {\n backgroundColor: glass\n ? alpha(theme.palette.background.paper, 0.15)\n : alpha(theme.palette.background.paper, 0.9) },\n\n '&:focus': {\n borderColor: error ? errorColor.main : colorPalette.main,\n boxShadow: `0 0 0 3px ${alpha(error ? errorColor.main : colorPalette.main, 0.1)}` },\n\n '& > *': {\n margin: '0.5em 0' },\n\n '&[contenteditable=\"true\"]:empty::before': {\n content: 'attr(data-placeholder)',\n color: theme.palette.text.secondary,\n opacity: 0.6 } };\n});\n\n// Rich text formatting functions\nconst formatText = (command: string, value?: string) => {\n document.execCommand(command, false, value);\n};\n\n// Editable state: what is typed, how long it is, and which formats apply at the\n// caret. Kept apart from the markup below.\nconst useRichEditorState = ({\n value,\n onChange }: {\n value?: string;\n onChange?: (html: string) => void;\n}) => {\n const [focused, setFocused] = useState(false);\n const [characterCount, setCharacterCount] = useState(0);\n const [activeFormats, setActiveFormats] = useState({\n bold: false,\n italic: false,\n underline: false,\n list: false,\n orderedList: false,\n quote: false,\n code: false });\n const contentRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (contentRef.current && value !== undefined) {\n if (contentRef.current.innerHTML !== value) {\n contentRef.current.innerHTML = value;\n }\n setCharacterCount(contentRef.current.innerText.length);\n }\n }, [value]);\n\n const handleInput = () => {\n if (contentRef.current) {\n const html = contentRef.current.innerHTML;\n onChange?.(html);\n setCharacterCount(contentRef.current.innerText.length);\n updateActiveFormats();\n }\n };\n\n const updateActiveFormats = () => {\n setActiveFormats({\n bold: document.queryCommandState('bold'),\n italic: document.queryCommandState('italic'),\n underline: document.queryCommandState('underline'),\n list: document.queryCommandState('insertUnorderedList'),\n orderedList: document.queryCommandState('insertOrderedList'),\n quote: false,\n code: false });\n };\n\n const handleFormat = (command: string, value?: string) => {\n formatText(command, value);\n updateActiveFormats();\n contentRef.current?.focus();\n };\n\n return {\n focused,\n setFocused,\n characterCount,\n activeFormats,\n contentRef,\n handleInput,\n handleFormat,\n updateActiveFormats };\n};\n\nconst InlineFormatButtons: React.FC<{\n copy: RichEditorToolbarCopy;\n activeFormats: Record<string, boolean>;\n onCommand: (command: string, value?: string) => void;\n}> = ({ copy, activeFormats, onCommand }) => (\n <>\n <Tooltip title={copy.bold} arrow>\n <ToolbarButton\n size=\"small\"\n active={activeFormats.bold}\n onClick={() => onCommand('bold')}\n >\n <FormatBold fontSize=\"small\" />\n </ToolbarButton>\n </Tooltip>\n\n <Tooltip title={copy.italic} arrow>\n <ToolbarButton\n size=\"small\"\n active={activeFormats.italic}\n onClick={() => onCommand('italic')}\n >\n <FormatItalic fontSize=\"small\" />\n </ToolbarButton>\n </Tooltip>\n\n <Tooltip title={copy.underline} arrow>\n <ToolbarButton\n size=\"small\"\n active={activeFormats.underline}\n onClick={() => onCommand('underline')}\n >\n <FormatUnderlined fontSize=\"small\" />\n </ToolbarButton>\n </Tooltip>\n\n </>\n);\n\nconst BlockFormatButtons: React.FC<{\n copy: RichEditorToolbarCopy;\n activeFormats: Record<string, boolean>;\n onCommand: (command: string, value?: string) => void;\n}> = ({ copy, activeFormats, onCommand }) => (\n <>\n <Divider orientation=\"vertical\" flexItem />\n\n <Tooltip title={copy.bulletList} arrow>\n <ToolbarButton\n size=\"small\"\n active={activeFormats.list}\n onClick={() => onCommand('insertUnorderedList')}\n >\n <FormatListBulleted fontSize=\"small\" />\n </ToolbarButton>\n </Tooltip>\n\n <Tooltip title={copy.numberedList} arrow>\n <ToolbarButton\n size=\"small\"\n active={activeFormats.orderedList}\n onClick={() => onCommand('insertOrderedList')}\n >\n <FormatListNumbered fontSize=\"small\" />\n </ToolbarButton>\n </Tooltip>\n\n <Divider orientation=\"vertical\" flexItem />\n\n <Tooltip title={copy.quote} arrow>\n <ToolbarButton size=\"small\" onClick={() => onCommand('formatBlock', 'blockquote')}>\n <FormatQuote fontSize=\"small\" />\n </ToolbarButton>\n </Tooltip>\n\n <Tooltip title={copy.code} arrow>\n <ToolbarButton size=\"small\" onClick={() => onCommand('formatBlock', 'pre')}>\n <Code fontSize=\"small\" />\n </ToolbarButton>\n </Tooltip>\n\n <Divider orientation=\"vertical\" flexItem />\n\n <Tooltip title={copy.insertLink} arrow>\n <ToolbarButton\n size=\"small\"\n onClick={() => {\n const url = window.prompt(copy.linkPrompt);\n if (url) onCommand('createLink', url);\n }}\n >\n <Link fontSize=\"small\" />\n </ToolbarButton>\n </Tooltip>\n\n <Tooltip title={copy.textColor} arrow>\n <ToolbarButton size=\"small\">\n <FormatColorText fontSize=\"small\" />\n </ToolbarButton>\n </Tooltip>\n\n <Tooltip title={copy.backgroundColor} arrow>\n <ToolbarButton size=\"small\">\n <FormatColorFill fontSize=\"small\" />\n </ToolbarButton>\n </Tooltip>\n </>\n);\n\n// The formatting buttons. Split out so the editor body is state, handlers and\n// the editable region.\nconst EditorToolbar: React.FC<{\n copy: RichEditorToolbarCopy;\n glass?: boolean;\n activeFormats: Record<string, boolean>;\n onCommand: (command: string, value?: string) => void;\n}> = ({ copy, glass, activeFormats, onCommand }) => (\n <RichToolbar glass={glass}>\n <InlineFormatButtons copy={copy} activeFormats={activeFormats} onCommand={onCommand} />\n <BlockFormatButtons copy={copy} activeFormats={activeFormats} onCommand={onCommand} />\n </RichToolbar>\n);\n\nexport const TextareaRichEditor: React.FC<{\n /**\n * The ten toolbar buttons' tooltips — which are also their accessible names,\n * since every one of them is a glyph — plus the link prompt. REQUIRED: this\n * package ships no default copy.\n */\n copy: RichEditorToolbarCopy;\n value?: string;\n onChange?: (html: string) => void;\n placeholder?: string;\n error?: boolean;\n glass?: boolean;\n color?: string;\n characterLimit?: number;\n}> = ({ copy, value, onChange, placeholder, error, glass, color, characterLimit }) => {\n const {\n focused,\n setFocused,\n characterCount,\n activeFormats,\n contentRef,\n handleInput,\n handleFormat,\n updateActiveFormats } = useRichEditorState({ value, onChange });\n\n return (\n <Box sx={{ position: 'relative' }}>\n <EditorToolbar copy={copy} glass={glass} activeFormats={activeFormats} onCommand={handleFormat} />\n\n <ContentEditableDiv\n ref={contentRef}\n contentEditable\n data-placeholder={placeholder}\n error={error}\n focused={focused}\n glass={glass}\n customColor={color}\n onFocus={() => setFocused(true)}\n onBlur={() => setFocused(false)}\n onInput={handleInput}\n onKeyUp={updateActiveFormats}\n onMouseUp={updateActiveFormats}\n role=\"textbox\"\n aria-multiline=\"true\"\n aria-label={placeholder || 'Rich text editor'}\n />\n\n {characterLimit && (\n <CharacterCount limit={characterLimit} count={characterCount}>\n {characterCount}\n {characterLimit ? `/${characterLimit}` : ''}\n </CharacterCount>\n )}\n </Box>\n );\n};\n"],"mappings":";;;AAAA;AAAA,EACE,SAAAA;AAAA,EACA,OAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAAwB;AAE1B,SAAS,UAAAC,eAAc;AACvB,SAAgB,YAAAC,iBAAgB;;;ACRhC,SAAS,OAAO,iBAAiB;AAGjC,IAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyBf,IAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuB9B,IAAM,iBAAiB,CAAC,UAAkC;AACxD,QAAM,OAAO,MAAM,QAAQ;AAE3B,SAAO;AAAA,IACL,MAAM,OAAO,GAAG,KAAK;AAAA,IACrB,MAAM,OAAO,GAAG,KAAK;AAAA,IACrB,OAAO,OAAO,GAAG,KAAK;AAAA,IACtB,cAAc;AAAA,EAChB;AACF;AAIA,IAAM,OAAO,IAAI,eACf,WAAW,KAAK,OAAO,KAAK;AAE9B,IAAM,gBAAgB,CAAC,OAAc,aAA8C;AAAA,EACjF,MAAM,KAAK,SAAS,MAAM,MAAM,QAAQ,QAAQ,IAAI;AAAA,EACpD,MAAM,KAAK,SAAS,MAAM,SAAS,MAAM,MAAM,QAAQ,QAAQ,IAAI;AAAA,EACnE,OAAO,KAAK,SAAS,OAAO,SAAS,MAAM,MAAM,QAAQ,QAAQ,KAAK;AAAA,EACtE,cAAc,KAAK,SAAS,cAAc,MAAM;AAClD;AAEO,IAAM,oBAAoB,CAAC,OAAc,UAAmC;AACjF,MAAI,UAAU,UAAW,QAAO,eAAe,KAAK;AAEpD,QAAM,WAA2C;AAAA,IAC/C,SAAS,MAAM,QAAQ;AAAA,IACvB,WAAW,MAAM,QAAQ;AAAA,IACzB,SAAS,MAAM,QAAQ;AAAA,IACvB,SAAS,MAAM,QAAQ;AAAA,IACvB,MAAM,MAAM,QAAQ;AAAA,IACpB,QAAQ,MAAM,QAAQ;AAAA,EACxB;AAEA,SAAO,cAAc,OAAO,SAAS,KAAK,KAAK,MAAM,QAAQ,OAAO;AACtE;AAKO,IAAM,yBAAyB,CAAC;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAMiB;AACjB,QAAM,cAAc,QAChB;AAAA,IACE,iBAAiB,MAAM,MAAM,QAAQ,WAAW,OAAO,GAAG;AAAA,IAC1D,gBAAgB;AAAA,IAChB,QAAQ,aAAa,MAAM,MAAM,QAAQ,SAAS,GAAG,CAAC;AAAA,IACtD,WAAW;AAAA,MACT,iBAAiB,MAAM,MAAM,QAAQ,WAAW,OAAO,IAAI;AAAA,MAC3D,gBAAgB;AAAA,IAClB;AAAA,IACA,WAAW;AAAA,MACT,iBAAiB,MAAM,MAAM,QAAQ,WAAW,OAAO,GAAG;AAAA,MAC1D,gBAAgB;AAAA,IAClB;AAAA,EACF,IACA,CAAC;AAGL,QAAM,iBAAiB,WACnB;AAAA,IACE,YAAY,mBAAmB,MAAM,QAAQ,WAAW,KAAK,KAAK,MAAM,QAAQ,WAAW,KAAK;AAAA,yCAC7D,aAAa,IAAI,KAAK,aAAa,KAAK;AAAA,IAC3E,QAAQ;AAAA,IACR,WAAW;AAAA,MACT,YAAY,mBAAmB,MAAM,QAAQ,WAAW,KAAK,KAAK,MAAM,QAAQ,WAAW,KAAK;AAAA,2CAC7D,aAAa,IAAI,KAAK,aAAa,IAAI;AAAA,IAC5E;AAAA,EACF,IACA,CAAC;AAGL,QAAM,aAAa,OACf;AAAA,IACE,WAAW,GAAG,aAAa;AAAA,IAC3B,WAAW,YAAY,MAAM,aAAa,MAAM,GAAG,CAAC;AAAA,EACtD,IACA,CAAC;AAEH,SAAO,EAAE,GAAG,aAAa,GAAG,gBAAgB,GAAG,WAAW;AAC5D;;;AC/IA,OAAO,UAAU;AACjB,OAAO,gBAAgB;AACvB,OAAO,qBAAqB;AAC5B,OAAO,qBAAqB;AAC5B,OAAO,kBAAkB;AACzB,OAAO,wBAAwB;AAC/B,OAAO,wBAAwB;AAC/B,OAAO,iBAAiB;AACxB,OAAO,sBAAsB;AAC7B,OAAO,UAAU;AACjB,SAAS,SAAAC,QAAO,KAAK,SAAS,YAAY,eAAe;AAEzD,SAAS,cAAc;AACvB,SAAgB,WAAW,QAAQ,gBAAgB;AAwMjD,mBAOM,KAPN;AAnMF,IAAM,cAAc,OAAO,GAAG,EAAuB,CAAC,EAAE,OAAO,MAAM,OAAO;AAAA,EAC1E,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,KAAK,MAAM,QAAQ,GAAG;AAAA,EACtB,SAAS,MAAM,QAAQ,CAAC;AAAA,EACxB,cAAc,GAAG,MAAM,QAAQ,CAAC,CAAC,IAAI,MAAM,QAAQ,CAAC,CAAC;AAAA,EACrD,cAAc,aAAa,MAAM,QAAQ,OAAO;AAAA,EAChD,YAAY,QAAQC,OAAM,MAAM,QAAQ,WAAW,OAAO,GAAG,IAAI,MAAM,QAAQ,WAAW;AAAA,EAC1F,GAAI,SAAS;AAAA,IACX,gBAAgB;AAAA,EAAa;AAAA,EAC/B,sBAAsB;AAAA,IACpB,QAAQ;AAAA,IACR,QAAQ,KAAK,MAAM,QAAQ,CAAC,CAAC;AAAA,EAAG;AAAE,EAAE;AAExC,IAAM,gBAAgB,OAAO,YAAY;AAAA,EACvC,mBAAmB,CAAC,SAAS,SAAS;AAAS,CAAC,EAAwB,CAAC,EAAE,OAAO,OAAO,OAAO;AAAA,EAChG,SAAS,MAAM,QAAQ,IAAI;AAAA,EAC3B,cAAc,MAAM,QAAQ,GAAG;AAAA,EAC/B,OAAO,SAAS,MAAM,QAAQ,QAAQ,OAAO,MAAM,QAAQ,KAAK;AAAA,EAChE,iBAAiB,SAASA,OAAM,MAAM,QAAQ,QAAQ,MAAM,GAAG,IAAI;AAAA,EACnE,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,UAAU;AAAA,EAEV,aAAa;AAAA,IACX,SAAS;AAAA,IACT,UAAU;AAAA,IACV,KAAK;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,iBAAiBA,OAAM,MAAM,QAAQ,QAAQ,MAAM,GAAG;AAAA,IACtD,WAAW;AAAA,IACX,YAAY;AAAA,EAA0B;AAAA,EAExC,WAAW;AAAA,IACT,OAAO,MAAM,QAAQ,QAAQ;AAAA,IAC7B,iBAAiBA,OAAM,MAAM,QAAQ,QAAQ,MAAM,IAAI;AAAA,IACvD,WAAW;AAAA,IACX,WAAW,GAAG,cAAc;AAAA,IAE5B,aAAa;AAAA,MACX,OAAO;AAAA,MACP,QAAQ;AAAA,IAAO;AAAA,EAAE;AAAA,EAErB,YAAY;AAAA,IACV,WAAW;AAAA,EAAc;AAAE,EAAE;AAEjC,IAAM,iBAAiB,OAAO,GAAG,EAAqC,CAAC,EAAE,OAAO,OAAO,MAAM,MAAM;AACjG,QAAM,YAAY,SAAS,QAAQ,QAAQ;AAC3C,QAAM,UAAU,SAAS,QAAQ;AAEjC,SAAO;AAAA,IACL,UAAU;AAAA,IACV,QAAQ,MAAM,QAAQ,CAAC;AAAA,IACvB,OAAO,MAAM,QAAQ,CAAC;AAAA,IACtB,UAAU;AAAA,IACV,OAAO,UACH,MAAM,QAAQ,MAAM,OACpB,YACE,MAAM,QAAQ,QAAQ,OACtB,MAAM,QAAQ,KAAK;AAAA,IACzB,SAAS;AAAA,IACT,cAAc,MAAM,QAAQ,GAAG;AAAA,IAC/B,iBAAiBA,OAAM,MAAM,QAAQ,WAAW,OAAO,GAAG;AAAA,IAC1D,gBAAgB;AAAA,IAChB,YAAY;AAAA,EAAgB;AAChC,CAAC;AAED,IAAM,qBAAqB,OAAO,KAAK,EAMpC,CAAC,EAAE,OAAO,OAAO,SAAS,OAAO,cAAc,UAAU,MAAM;AAChE,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,QAAM,eAAe,kBAAkB,OAAO,WAAW;AACzD,QAAM,aAAa,MAAM,QAAQ;AAEjC,SAAO;AAAA,IACL,WAAW;AAAA,IACX,SAAS,MAAM,QAAQ,GAAG;AAAA,IAC1B,cAAc,OAAO,MAAM,QAAQ,CAAC,CAAC,IAAI,MAAM,QAAQ,CAAC,CAAC;AAAA,IACzD,QAAQ,aAAa,QAAQ,WAAW,OAAO,UAAU,aAAa,OAAO,MAAM,QAAQ,OAAO;AAAA,IAClG,WAAW;AAAA,IACX,iBAAiB,QACbA,OAAM,MAAM,QAAQ,WAAW,OAAO,GAAG,IACzC,MAAM,QAAQ,WAAW;AAAA,IAC7B,OAAO,MAAM,QAAQ,KAAK;AAAA,IAC1B,YAAY,MAAM,WAAW;AAAA,IAC7B,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,QAAQ;AAAA,IAER,GAAI,SAAS;AAAA,MACX,gBAAgB;AAAA,IAAa;AAAA,IAE/B,WAAW;AAAA,MACT,iBAAiB,QACbA,OAAM,MAAM,QAAQ,WAAW,OAAO,IAAI,IAC1CA,OAAM,MAAM,QAAQ,WAAW,OAAO,GAAG;AAAA,IAAE;AAAA,IAEjD,WAAW;AAAA,MACT,aAAa,QAAQ,WAAW,OAAO,aAAa;AAAA,MACpD,WAAW,aAAaA,OAAM,QAAQ,WAAW,OAAO,aAAa,MAAM,GAAG,CAAC;AAAA,IAAG;AAAA,IAEpF,SAAS;AAAA,MACP,QAAQ;AAAA,IAAU;AAAA,IAEpB,2CAA2C;AAAA,MACzC,SAAS;AAAA,MACT,OAAO,MAAM,QAAQ,KAAK;AAAA,MAC1B,SAAS;AAAA,IAAI;AAAA,EAAE;AACrB,CAAC;AAGD,IAAM,aAAa,CAAC,SAAiB,UAAmB;AACtD,WAAS,YAAY,SAAS,OAAO,KAAK;AAC5C;AAIA,IAAM,qBAAqB,CAAC;AAAA,EAC1B;AAAA,EACA;AAAS,MAGL;AACJ,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAC5C,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAAS,CAAC;AACtD,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAS;AAAA,IACjD,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO;AAAA,IACP,MAAM;AAAA,EAAM,CAAC;AACf,QAAM,aAAa,OAAuB,IAAI;AAE9C,YAAU,MAAM;AACd,QAAI,WAAW,WAAW,UAAU,QAAW;AAC7C,UAAI,WAAW,QAAQ,cAAc,OAAO;AAC1C,mBAAW,QAAQ,YAAY;AAAA,MACjC;AACA,wBAAkB,WAAW,QAAQ,UAAU,MAAM;AAAA,IACvD;AAAA,EACF,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,cAAc,MAAM;AACxB,QAAI,WAAW,SAAS;AACtB,YAAM,OAAO,WAAW,QAAQ;AAChC,iBAAW,IAAI;AACf,wBAAkB,WAAW,QAAQ,UAAU,MAAM;AACrD,0BAAoB;AAAA,IACtB;AAAA,EACF;AAEA,QAAM,sBAAsB,MAAM;AAChC,qBAAiB;AAAA,MACf,MAAM,SAAS,kBAAkB,MAAM;AAAA,MACvC,QAAQ,SAAS,kBAAkB,QAAQ;AAAA,MAC3C,WAAW,SAAS,kBAAkB,WAAW;AAAA,MACjD,MAAM,SAAS,kBAAkB,qBAAqB;AAAA,MACtD,aAAa,SAAS,kBAAkB,mBAAmB;AAAA,MAC3D,OAAO;AAAA,MACP,MAAM;AAAA,IAAM,CAAC;AAAA,EACjB;AAEA,QAAM,eAAe,CAAC,SAAiBC,WAAmB;AACxD,eAAW,SAASA,MAAK;AACzB,wBAAoB;AACpB,eAAW,SAAS,MAAM;AAAA,EAC5B;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAoB;AACxB;AAEA,IAAM,sBAID,CAAC,EAAE,MAAM,eAAe,UAAU,MACrC,iCACE;AAAA,sBAAC,WAAQ,OAAO,KAAK,MAAM,OAAK,MAC9B;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,QAAQ,cAAc;AAAA,MACtB,SAAS,MAAM,UAAU,MAAM;AAAA,MAE/B,8BAAC,cAAW,UAAS,SAAQ;AAAA;AAAA,EAC/B,GACF;AAAA,EAEA,oBAAC,WAAQ,OAAO,KAAK,QAAQ,OAAK,MAChC;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,QAAQ,cAAc;AAAA,MACtB,SAAS,MAAM,UAAU,QAAQ;AAAA,MAEjC,8BAAC,gBAAa,UAAS,SAAQ;AAAA;AAAA,EACjC,GACF;AAAA,EAEA,oBAAC,WAAQ,OAAO,KAAK,WAAW,OAAK,MACnC;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,QAAQ,cAAc;AAAA,MACtB,SAAS,MAAM,UAAU,WAAW;AAAA,MAEpC,8BAAC,oBAAiB,UAAS,SAAQ;AAAA;AAAA,EACrC,GACF;AAAA,GAEF;AAGF,IAAM,qBAID,CAAC,EAAE,MAAM,eAAe,UAAU,MACrC,iCACE;AAAA,sBAAC,WAAQ,aAAY,YAAW,UAAQ,MAAC;AAAA,EAEzC,oBAAC,WAAQ,OAAO,KAAK,YAAY,OAAK,MACpC;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,QAAQ,cAAc;AAAA,MACtB,SAAS,MAAM,UAAU,qBAAqB;AAAA,MAE9C,8BAAC,sBAAmB,UAAS,SAAQ;AAAA;AAAA,EACvC,GACF;AAAA,EAEA,oBAAC,WAAQ,OAAO,KAAK,cAAc,OAAK,MACtC;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,QAAQ,cAAc;AAAA,MACtB,SAAS,MAAM,UAAU,mBAAmB;AAAA,MAE5C,8BAAC,sBAAmB,UAAS,SAAQ;AAAA;AAAA,EACvC,GACF;AAAA,EAEA,oBAAC,WAAQ,aAAY,YAAW,UAAQ,MAAC;AAAA,EAEzC,oBAAC,WAAQ,OAAO,KAAK,OAAO,OAAK,MAC/B,8BAAC,iBAAc,MAAK,SAAQ,SAAS,MAAM,UAAU,eAAe,YAAY,GAC9E,8BAAC,eAAY,UAAS,SAAQ,GAChC,GACF;AAAA,EAEA,oBAAC,WAAQ,OAAO,KAAK,MAAM,OAAK,MAC9B,8BAAC,iBAAc,MAAK,SAAQ,SAAS,MAAM,UAAU,eAAe,KAAK,GACvE,8BAAC,QAAK,UAAS,SAAQ,GACzB,GACF;AAAA,EAEA,oBAAC,WAAQ,aAAY,YAAW,UAAQ,MAAC;AAAA,EAEzC,oBAAC,WAAQ,OAAO,KAAK,YAAY,OAAK,MACpC;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,SAAS,MAAM;AACb,cAAM,MAAM,OAAO,OAAO,KAAK,UAAU;AACzC,YAAI,IAAK,WAAU,cAAc,GAAG;AAAA,MACtC;AAAA,MAEA,8BAAC,QAAK,UAAS,SAAQ;AAAA;AAAA,EACzB,GACF;AAAA,EAEA,oBAAC,WAAQ,OAAO,KAAK,WAAW,OAAK,MACnC,8BAAC,iBAAc,MAAK,SAClB,8BAAC,mBAAgB,UAAS,SAAQ,GACpC,GACF;AAAA,EAEA,oBAAC,WAAQ,OAAO,KAAK,iBAAiB,OAAK,MACzC,8BAAC,iBAAc,MAAK,SAClB,8BAAC,mBAAgB,UAAS,SAAQ,GACpC,GACF;AAAA,GACF;AAKF,IAAM,gBAKD,CAAC,EAAE,MAAM,OAAO,eAAe,UAAU,MAC5C,qBAAC,eAAY,OACX;AAAA,sBAAC,uBAAoB,MAAY,eAA8B,WAAsB;AAAA,EACrF,oBAAC,sBAAmB,MAAY,eAA8B,WAAsB;AAAA,GACtF;AAGK,IAAM,qBAcR,CAAC,EAAE,MAAM,OAAO,UAAU,aAAa,OAAO,OAAO,OAAO,eAAe,MAAM;AACpF,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAoB,IAAI,mBAAmB,EAAE,OAAO,SAAS,CAAC;AAEhE,SACE,qBAAC,OAAI,IAAI,EAAE,UAAU,WAAW,GAC9B;AAAA,wBAAC,iBAAc,MAAY,OAAc,eAA8B,WAAW,cAAc;AAAA,IAEhG;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,iBAAe;AAAA,QACf,oBAAkB;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,QACA,aAAa;AAAA,QACb,SAAS,MAAM,WAAW,IAAI;AAAA,QAC9B,QAAQ,MAAM,WAAW,KAAK;AAAA,QAC9B,SAAS;AAAA,QACT,SAAS;AAAA,QACT,WAAW;AAAA,QACX,MAAK;AAAA,QACL,kBAAe;AAAA,QACf,cAAY,eAAe;AAAA;AAAA,IAC7B;AAAA,IAEC,kBACC,qBAAC,kBAAe,OAAO,gBAAgB,OAAO,gBAC3C;AAAA;AAAA,MACA,iBAAiB,IAAI,cAAc,KAAK;AAAA,OAC3C;AAAA,KAEJ;AAEJ;;;AFnPE,SAKI,OAAAC,MALJ,QAAAC,aAAA;AAlHF,IAAM,iBAAiBC,QAAO,kBAAkB;AAAA,EAC9C,mBAAmB,CAAC,SAClB,CAAC,CAAC,iBAAiB,eAAe,cAAc,QAAQ,SAAS,YAAY,OAAO,EAAE;AAAA,IACpF;AAAA,EACF;AAAE,CAAC,EAAuB,CAAC;AAAA,EAC7B;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAM,MAAM;AACZ,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,QAAM,eAAe,kBAAkB,OAAO,WAAW;AACzD,QAAM,aAAa,MAAM,QAAQ;AAEjC,QAAM,UAAU;AAAA,IACd,IAAI,EAAE,SAAS,WAAW,UAAU,WAAW,WAAW,OAAO;AAAA,IACjE,IAAI,EAAE,SAAS,YAAY,UAAU,YAAY,WAAW,OAAO;AAAA,IACnE,IAAI,EAAE,SAAS,aAAa,UAAU,QAAQ,WAAW,QAAQ;AAAA,IACjE,IAAI,EAAE,SAAS,aAAa,UAAU,YAAY,WAAW,QAAQ;AAAA,IACrE,IAAI,EAAE,SAAS,aAAa,UAAU,WAAW,WAAW,QAAQ;AAAA,EAAE;AAExE,QAAM,aAAa;AAAA,IACjB,OAAO;AAAA,IACP,YAAY,MAAM,WAAW;AAAA,IAC7B,cAAc,MAAM,QAAQ,CAAC;AAAA,IAC7B,QAAQ,aAAa,QAAQ,WAAW,OAAO,MAAM,QAAQ,OAAO;AAAA,IACpE,iBAAiB,MAAM,QAAQ,WAAW;AAAA,IAC1C,OAAO,MAAM,QAAQ,KAAK;AAAA,IAC1B,YAAY;AAAA,IACZ,QAAQ,kBAAkB,cAAc,aAAa;AAAA,IACrD,SAAS;AAAA,IACT,GAAG,QAAQ,UAAkC;AAAA,IAE7C,kBAAkB;AAAA,MAChB,OAAO,MAAM,QAAQ,KAAK;AAAA,MAC1B,SAAS;AAAA,IAAI;AAAA,IAEf,WAAW;AAAA,MACT,aAAa,QAAQ,WAAW,OAAO,aAAa;AAAA,MACpD,iBAAiBC,OAAM,MAAM,QAAQ,WAAW,OAAO,GAAG;AAAA,IAAE;AAAA,IAE9D,WAAW;AAAA,MACT,aAAa,QAAQ,WAAW,OAAO,aAAa;AAAA,MACpD,iBAAiB,MAAM,QAAQ,WAAW;AAAA,MAC1C,WAAW,aAAaA,OAAM,QAAQ,WAAW,OAAO,aAAa,MAAM,GAAG,CAAC;AAAA,IAAG;AAAA,EAAE;AAGxF,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG,uBAAuB,EAAE,OAAO,cAAc,OAAO,UAAU,KAAK,CAAC;AAAA,EAAE;AAC9E,CAAC;AAED,IAAM,cAAcD,QAAO,YAAY;AAAA,EACrC,mBAAmB,CAAC,SAAS,CAAC,CAAC,SAAS,OAAO,EAAE,SAAS,IAAc;AAAE,CAAC,EAAwC,CAAC,EAAE,OAAO,OAAO,MAAM,OAAO;AAAA,EACjJ,cAAc,MAAM,QAAQ,CAAC;AAAA,EAC7B,YAAY;AAAA,EACZ,OAAO,QAAQ,MAAM,QAAQ,MAAM,OAAO,MAAM,QAAQ,KAAK;AAAA,EAC7D,GAAI,SAAS;AAAA,IACX,iBAAiBC,OAAM,MAAM,QAAQ,WAAW,OAAO,GAAG;AAAA,IAC1D,gBAAgB;AAAA,IAChB,SAAS;AAAA,IACT,cAAc;AAAA,IACd,QAAQ,aAAaA,OAAM,MAAM,QAAQ,SAAS,GAAG,CAAC;AAAA,IACtD,SAAS;AAAA,EAAe;AAAG,EAAE;AAiBjC,IAAM,cAAc;AAEpB,IAAM,oBAAoB;AAAA,EACxB,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AAAA,EACN,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,OAAO;AAAA,EACP,UAAU;AAAA,EACV,cAAc;AAAA,EACd,SAAS;AAAE;AAIb,IAAM,eAAe,CAAC,UACpB,OAAO;AAAA,EACL,OAAO,QAAQ,KAAK,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,MAAM,UAAU,MAAS;AACjE;AAIF,IAAM,gBAOD,CAAC,EAAE,QAAQ,OAAO,YAAY,OAAO,YAAY,SAAS,MAC7D,gBAAAF;AAAA,EAACG;AAAA,EAAA;AAAA,IACC,IAAI,EAAE,UAAU,YAAY,OAAO,OAAO;AAAA,IAC1C,eAAa,SAAS,GAAG,MAAM,aAAa;AAAA,IAE3C;AAAA,eACC,gBAAAJ,KAAC,eAAY,OAAO,YAAY,OAC7B,iBACH;AAAA,MAGD;AAAA,MAEA,cACC,gBAAAA,KAAC,kBAAe,OAAc,IAAI,EAAE,IAAI,EAAE,GACvC,sBACH;AAAA;AAAA;AAEJ;AAGF,IAAM,eAGD,CAAC,EAAE,MAAM,aAAa,MACzB,gBAAAA;AAAA,EAACI;AAAA,EAAA;AAAA,IACC,IAAI;AAAA,MACF,UAAU;AAAA,MACV,KAAK;AAAA,MACL,GAAI,iBAAiB,UAAU,EAAE,MAAM,OAAO,IAAI,EAAE,OAAO,OAAO;AAAA,MAClE,OAAO;AAAA,MACP,eAAe;AAAA,MACf,QAAQ;AAAA,IAAE;AAAA,IAEX;AAAA;AACH;AAGK,IAAM,WAAoC,CAAC,kBAAkB;AAClE,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,GAAG;AAAA,EACL,IAAI,EAAE,GAAG,mBAAmB,GAAG,aAAa,aAAa,EAAE;AAI3D,QAAM,EAAE,eAAe,IAAI;AAE3B,QAAM,CAAC,eAAe,gBAAgB,IAAIC,UAAS,EAAE;AACrD,QAAM,UAAU,QAAQ,IAAI;AAC5B,QAAM,SAAS,cAAc;AAE7B,QAAM,gBAAgB;AAAA,IACpB,GAAG;AAAA;AAAA;AAAA;AAAA,IAIH,GAAI,WAAW;AAAA,MACb,CAAC,iBAAiB,UAAU,gBAAgB,cAAc,GAAG;AAAA,IAAY;AAAA,EAAG;AAGhF,MAAI,YAAY,UAAU,gBAAgB;AACxC,WACE,gBAAAL,KAAC,iBAAc,QAAgB,OAAc,YAAwB,OAAc,YACjF,0BAAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN,OAAO;AAAA,QACP,UAAU;AAAA,QACV,aAAa,MAAM;AAAA,QACnB;AAAA,QACA;AAAA,QACA;AAAA,QACA,gBAAgB,MAAM;AAAA;AAAA,IACxB,GACF;AAAA,EAEJ;AAEA,SACE,gBAAAA,KAAC,iBAAc,QAAgB,OAAc,YAAwB,OAAc,YACjF,0BAAAC,MAACG,MAAA,EAAI,IAAI,EAAE,UAAU,WAAW,GAC7B;AAAA,eAAW,gBAAAJ,KAAC,gBAAa,MAAY,cAA4B;AAAA,IAElE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,eAAe;AAAA,QACf,aAAa;AAAA,QACb,YAAY;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAS,YAAY,aAAa,UAAU;AAAA,QAC5C,SAAS,YAAY,aAAa,UAAU;AAAA,QAC5C,OAAO;AAAA,QACP,cAAY,SAAS,MAAM,YAAY;AAAA,QACvC,eAAa;AAAA,QACZ,GAAG;AAAA;AAAA,IACN;AAAA,KACF,GACF;AAEJ;AAEA,SAAS,cAAc;","names":["alpha","Box","styled","useState","alpha","alpha","value","jsx","jsxs","styled","alpha","Box","useState"]}
@@ -205,6 +205,7 @@ import CloudUploadOutlined from "@mui/icons-material/CloudUploadOutlined";
205
205
  import { Box, Button, LinearProgress, Typography, useTheme } from "@mui/material";
206
206
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
207
207
  function UploadDropzone({
208
+ copy,
208
209
  label,
209
210
  icon,
210
211
  disabled,
@@ -248,17 +249,18 @@ function UploadDropzone({
248
249
  onOpen();
249
250
  },
250
251
  "aria-describedby": describedBy,
251
- "aria-label": `Upload file dropzone. ${label}`,
252
+ "aria-label": copy.dropzoneRole(label),
252
253
  children: [
253
254
  /* @__PURE__ */ jsx(Box, { sx: { mb: 2 }, children: icon || /* @__PURE__ */ jsx(CloudUploadOutlined, { sx: { fontSize: 48, color: "text.secondary" } }) }),
254
255
  /* @__PURE__ */ jsx(Typography, { variant: "body1", sx: { mb: 1 }, children: label }),
255
- /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", children: "Drop your file here or click to browse" })
256
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", children: copy.dropzoneHint })
256
257
  ]
257
258
  }
258
259
  );
259
260
  }
260
261
  var MUI_VARIANT = { outline: "outlined", ghost: "text" };
261
262
  function UploadTrigger({
263
+ copy,
262
264
  label,
263
265
  icon,
264
266
  disabled,
@@ -285,11 +287,12 @@ function UploadTrigger({
285
287
  "&:hover": { backgroundColor: `${theme.palette.primary.main}08` }
286
288
  }
287
289
  },
288
- children: isUploading ? "Uploading..." : label
290
+ children: isUploading ? copy.uploading : label
289
291
  }
290
292
  );
291
293
  }
292
294
  function UploadAnnouncer({
295
+ copy,
293
296
  announceDragOver,
294
297
  isUploading,
295
298
  progress,
@@ -309,14 +312,15 @@ function UploadAnnouncer({
309
312
  overflow: "hidden"
310
313
  },
311
314
  children: [
312
- announceDragOver && "File ready to drop",
313
- isUploading && `Upload in progress: ${Math.round(progress)}%`,
314
- error && `Error: ${error}`
315
+ announceDragOver && copy.dropReady,
316
+ isUploading && copy.uploadInProgress(Math.round(progress)),
317
+ error && copy.errorAnnouncement(error)
315
318
  ]
316
319
  }
317
320
  );
318
321
  }
319
322
  function UploadFeedback({
323
+ copy,
320
324
  isUploading,
321
325
  progress,
322
326
  helperText,
@@ -328,10 +332,7 @@ function UploadFeedback({
328
332
  return /* @__PURE__ */ jsxs(Fragment, { children: [
329
333
  isUploading && progress > 0 && /* @__PURE__ */ jsxs(Box, { sx: { mt: 1 }, children: [
330
334
  /* @__PURE__ */ jsx(LinearProgress, { variant: "determinate", value: progress, sx: { borderRadius: 1 } }),
331
- /* @__PURE__ */ jsxs(Typography, { variant: "caption", sx: { mt: 0.5, display: "block" }, children: [
332
- Math.round(progress),
333
- "% uploaded"
334
- ] })
335
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", sx: { mt: 0.5, display: "block" }, children: copy.percentUploaded(Math.round(progress)) })
335
336
  ] }),
336
337
  helperText && !error && /* @__PURE__ */ jsx(
337
338
  Typography,
@@ -357,6 +358,7 @@ function UploadFeedback({
357
358
  /* @__PURE__ */ jsx(
358
359
  UploadAnnouncer,
359
360
  {
361
+ copy,
360
362
  announceDragOver,
361
363
  isUploading,
362
364
  progress,
@@ -370,8 +372,9 @@ function UploadFeedback({
370
372
  import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
371
373
  var UploadButton = React.forwardRef((props, ref) => {
372
374
  const {
375
+ copy,
373
376
  variant = "default",
374
- label = "Upload File",
377
+ label = props.copy.buttonLabel,
375
378
  disabled = false,
376
379
  multiple = false,
377
380
  accept,
@@ -383,6 +386,7 @@ var UploadButton = React.forwardRef((props, ref) => {
383
386
  } = props;
384
387
  const { inputRef, inputId, state, drag, derived, openPicker, handleInputChange } = useUploadButton(props);
385
388
  const trigger = {
389
+ copy,
386
390
  label,
387
391
  icon,
388
392
  disabled,
@@ -411,6 +415,7 @@ var UploadButton = React.forwardRef((props, ref) => {
411
415
  /* @__PURE__ */ jsx2(
412
416
  UploadFeedback,
413
417
  {
418
+ copy,
414
419
  isUploading: derived.isUploading,
415
420
  progress: derived.progress,
416
421
  helperText,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/form/UploadButton/UploadButton.tsx","../../src/components/form/UploadButton/UploadButton.hooks.ts","../../src/components/form/UploadButton/UploadButton.parts.tsx"],"sourcesContent":["import { Box } from '@mui/material';\nimport React from 'react';\n\nimport { useUploadButton } from './UploadButton.hooks';\nimport {\n UploadDropzone,\n UploadFeedback,\n UploadTrigger,\n type TriggerProps,\n} from './UploadButton.parts';\nimport type { UploadButtonProps, UploadButtonState } from './UploadButton.types';\n\n/**\n * A file picker with an optional drag-and-drop surface.\n *\n * The body here is deliberately thin: selection rules live in\n * `UploadButton.hooks`, appearance in `UploadButton.parts`. What remains is the\n * wiring — the hidden input, which trigger to render, and the feedback beneath.\n */\nconst UploadButton = React.forwardRef<HTMLInputElement, UploadButtonProps>((props, ref) => {\n const {\n variant = 'default',\n label = 'Upload File',\n disabled = false,\n multiple = false,\n accept,\n capture,\n helperText,\n icon,\n className,\n 'data-testid': dataTestId,\n } = props;\n const { inputRef, inputId, state, drag, derived, openPicker, handleInputChange } =\n useUploadButton(props);\n\n const trigger: TriggerProps = {\n label,\n icon,\n disabled,\n className,\n dataTestId,\n describedBy: derived.describedBy,\n onOpen: openPicker,\n };\n\n return (\n <Box>\n <input\n ref={ref || inputRef}\n id={inputId}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n capture={capture}\n onChange={handleInputChange}\n style={{ display: 'none' }}\n disabled={disabled}\n aria-hidden=\"true\"\n />\n\n {variant === 'dropzone' ? (\n <UploadDropzone {...trigger} isDragOver={state.isDragOver} drag={drag} />\n ) : (\n <UploadTrigger {...trigger} variant={variant} isUploading={derived.isUploading} />\n )}\n\n <UploadFeedback\n isUploading={derived.isUploading}\n progress={derived.progress}\n helperText={helperText}\n helperId={derived.helperId}\n error={derived.error}\n errorId={derived.errorId}\n announceDragOver={variant === 'dropzone' && state.isDragOver}\n />\n </Box>\n );\n});\n\nUploadButton.displayName = 'UploadButton';\n\nexport { UploadButton };\nexport type { UploadButtonProps, UploadButtonState };\n","import { useCallback, useId, useMemo, useRef, useState } from 'react';\nimport type React from 'react';\n\nimport type { UploadButtonProps, UploadButtonState } from './UploadButton.types';\n\n/** The props {@link useUploadButton} reads — the component's own props. */\ntype UploadButtonHookProps = UploadButtonProps;\n\n/** Percent the simulated progress creeps to while waiting on `onUpload`. */\nconst SIMULATED_PROGRESS_CEILING = 90;\nconst SIMULATED_PROGRESS_STEP = 10;\nconst SIMULATED_PROGRESS_INTERVAL_MS = 100;\nconst PROGRESS_RESET_DELAY_MS = 1000;\nconst BYTES_PER_MB = 1024 * 1024;\n\nconst INITIAL_STATE: UploadButtonState = {\n isDragOver: false,\n isUploading: false,\n uploadProgress: 0,\n error: null,\n};\n\n/** Narrowed `setState` for the pieces below. */\ntype SetState = React.Dispatch<React.SetStateAction<UploadButtonState>>;\n\n/** The size/custom validation applied to every file, in both modes. */\nfunction useFileValidator(\n maxSizeMB: number | undefined,\n validate: ((file: globalThis.File) => string | null) | undefined,\n): (file: globalThis.File) => string | null {\n return useCallback(\n (file: globalThis.File): string | null => {\n if (maxSizeMB && file.size > maxSizeMB * BYTES_PER_MB) {\n return `File size must be less than ${maxSizeMB}MB`;\n }\n return validate ? validate(file) : null;\n },\n [maxSizeMB, validate],\n );\n}\n\n/**\n * The built-in upload path, reachable from BOTH selection modes.\n *\n * Kept apart from selection because it is the only asynchronous part: left\n * inline it was single-file only, which made `onUpload` a silent no-op for a\n * multi-file caller — the worst kind of contract, since nothing fails.\n */\nfunction useUploadRunner(\n onUpload: ((file: globalThis.File) => Promise<void>) | undefined,\n externalUploading: boolean,\n setState: SetState,\n): (file: globalThis.File) => Promise<void> {\n return useCallback(\n async (file: globalThis.File) => {\n if (!onUpload || externalUploading) return;\n try {\n setState((prev) => ({ ...prev, isUploading: true, uploadProgress: 0 }));\n // The real percentage is unknowable through a bare promise, so the bar\n // creeps to a ceiling and only completes when the promise does.\n const timer = globalThis.setInterval(() => {\n setState((prev) => {\n if (prev.uploadProgress >= SIMULATED_PROGRESS_CEILING) {\n globalThis.clearInterval(timer);\n return prev;\n }\n return { ...prev, uploadProgress: prev.uploadProgress + SIMULATED_PROGRESS_STEP };\n });\n }, SIMULATED_PROGRESS_INTERVAL_MS);\n\n await onUpload(file);\n\n globalThis.clearInterval(timer);\n setState((prev) => ({ ...prev, isUploading: false, uploadProgress: 100 }));\n globalThis.setTimeout(() => {\n setState((prev) => ({ ...prev, uploadProgress: 0 }));\n }, PROGRESS_RESET_DELAY_MS);\n } catch (error) {\n setState((prev) => ({\n ...prev,\n isUploading: false,\n uploadProgress: 0,\n error: error instanceof Error ? error.message : 'Upload failed',\n }));\n }\n },\n [onUpload, externalUploading, setState],\n );\n}\n\n/**\n * What {@link useUploadSelection} hands back. Module-private: the published\n * surface is {@link useUploadButton}, not the shape of its internals.\n */\ninterface UploadSelection {\n state: UploadButtonState;\n setDragOver: (isDragOver: boolean) => void;\n /** Route a picked/dropped selection through validation and the callbacks. */\n handleFiles: (files: globalThis.File[]) => void;\n}\n\ninterface UploadSelectionOptions {\n onSelect: (file: globalThis.File) => void;\n multiple: boolean;\n onSelectMany?: (files: globalThis.File[]) => void;\n onUpload?: (file: globalThis.File) => Promise<void>;\n externalUploading: boolean;\n validateFile: (file: globalThis.File) => string | null;\n}\n\n/**\n * Selection, validation and the optional built-in upload.\n *\n * The rendering layer only reads `state` and calls `handleFiles`; every rule\n * about what a selection means lives here.\n */\nfunction useUploadSelection({\n onSelect,\n multiple,\n onSelectMany,\n onUpload,\n externalUploading,\n validateFile,\n}: UploadSelectionOptions): UploadSelection {\n const [state, setState] = useState<UploadButtonState>(INITIAL_STATE);\n const runUpload = useUploadRunner(onUpload, externalUploading, setState);\n\n const selectOne = useCallback(\n (file: globalThis.File) => {\n const error = validateFile(file);\n setState((prev) => ({ ...prev, error }));\n if (error) return;\n onSelect(file);\n void runUpload(file);\n },\n [onSelect, runUpload, validateFile],\n );\n\n /**\n * Multi-file mode is deliberately forgiving: the valid files are handed over\n * and the first rejection is reported alongside them, so dropping a folder\n * that also contains a PDF imports the rest instead of refusing the lot.\n */\n const selectMany = useCallback(\n (files: globalThis.File[], accept: (files: globalThis.File[]) => void) => {\n const accepted: globalThis.File[] = [];\n let rejection: string | null = null;\n for (const file of files) {\n const error = validateFile(file);\n if (error) rejection ??= error;\n else accepted.push(file);\n }\n setState((prev) => ({ ...prev, error: rejection }));\n if (accepted.length === 0) return;\n accept(accepted);\n // `onUpload` applies here too, one file after another, so the prop means\n // the same thing in both modes. Sequential because the progress bar is a\n // single indicator — overlapping uploads would report nonsense.\n void (async () => {\n for (const file of accepted) await runUpload(file);\n })();\n },\n [runUpload, validateFile],\n );\n\n const handleFiles = useCallback(\n (files: globalThis.File[]) => {\n if (files.length === 0) return;\n if (multiple && onSelectMany) selectMany(files, onSelectMany);\n else selectOne(files[0] as globalThis.File);\n },\n [multiple, onSelectMany, selectMany, selectOne],\n );\n\n const setDragOver = useCallback((isDragOver: boolean) => {\n setState((prev) => ({ ...prev, isDragOver }));\n }, []);\n\n return useMemo(() => ({ state, setDragOver, handleFiles }), [state, setDragOver, handleFiles]);\n}\n\n/** Drag-and-drop wiring for the dropzone variant. */\nexport interface DragHandlers {\n onDragEnter: (event: React.DragEvent) => void;\n onDragLeave: (event: React.DragEvent) => void;\n onDragOver: (event: React.DragEvent) => void;\n onDrop: (event: React.DragEvent) => void;\n}\n\nconst swallow = (event: React.DragEvent): void => {\n event.preventDefault();\n event.stopPropagation();\n};\n\nfunction useDragHandlers(\n disabled: boolean,\n setDragOver: (isDragOver: boolean) => void,\n handleFiles: (files: globalThis.File[]) => void,\n): DragHandlers {\n return {\n onDragEnter: (event) => {\n swallow(event);\n if (!disabled) setDragOver(true);\n },\n onDragLeave: (event) => {\n swallow(event);\n setDragOver(false);\n },\n onDragOver: swallow,\n onDrop: (event) => {\n swallow(event);\n setDragOver(false);\n if (!disabled) handleFiles(Array.from(event.dataTransfer.files));\n },\n };\n}\n\n/** Everything the component needs, assembled from its props in one call. */\ninterface UploadButtonKit {\n inputRef: React.RefObject<HTMLInputElement | null>;\n inputId: string;\n state: UploadButtonState;\n drag: DragHandlers;\n derived: DerivedUploadState;\n openPicker: () => void;\n handleInputChange: (event: React.ChangeEvent<HTMLInputElement>) => void;\n}\n\n/**\n * The component's whole behaviour in one hook, so the render body stays a thin\n * piece of wiring rather than a place where rules accumulate.\n */\nexport function useUploadButton(props: UploadButtonHookProps): UploadButtonKit {\n const {\n onSelect,\n multiple = false,\n onSelectMany,\n onUpload,\n uploading: externalUploading = false,\n progress: externalProgress = 0,\n maxSizeMB,\n validate,\n helperText,\n errorText,\n disabled = false,\n } = props;\n\n const inputRef = useRef<HTMLInputElement>(null);\n const inputId = `upload-button-${useId()}`;\n const validateFile = useFileValidator(maxSizeMB, validate);\n const { state, setDragOver, handleFiles } = useUploadSelection({\n onSelect,\n multiple,\n onSelectMany,\n onUpload,\n externalUploading,\n validateFile,\n });\n const drag = useDragHandlers(disabled, setDragOver, handleFiles);\n const derived = useDerivedUploadState({\n state,\n inputId,\n externalUploading,\n externalProgress,\n errorText,\n helperText,\n });\n\n const openPicker = useCallback(() => inputRef.current?.click(), []);\n const handleInputChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n handleFiles(Array.from(event.target.files ?? []));\n // Let the same file be picked twice in a row — without this the input\n // holds the old value and re-selecting it fires no change event.\n event.target.value = '';\n },\n [handleFiles],\n );\n\n return { inputRef, inputId, state, drag, derived, openPicker, handleInputChange };\n}\n\n/** The values the render derives from props + internal state. */\ninterface DerivedUploadState {\n isUploading: boolean;\n progress: number;\n error: string | null;\n helperId?: string;\n errorId?: string;\n describedBy?: string;\n}\n\n/**\n * Fold props and internal state into what the render actually shows. External\n * state wins whenever the caller drives it.\n */\nfunction useDerivedUploadState({\n state,\n inputId,\n externalUploading,\n externalProgress,\n errorText,\n helperText,\n}: {\n state: UploadButtonState;\n inputId: string;\n externalUploading: boolean;\n externalProgress: number;\n errorText?: string;\n helperText?: string;\n}): DerivedUploadState {\n const error = errorText || state.error;\n const helperId = helperText ? `${inputId}-helper` : undefined;\n const errorId = error ? `${inputId}-error` : undefined;\n return {\n isUploading: externalUploading || state.isUploading,\n progress: externalUploading ? externalProgress : state.uploadProgress,\n error,\n helperId,\n errorId,\n describedBy: [helperId, errorId].filter(Boolean).join(' ') || undefined,\n };\n}\n","import AttachFileOutlined from '@mui/icons-material/AttachFileOutlined';\nimport CloudUploadOutlined from '@mui/icons-material/CloudUploadOutlined';\nimport { Box, Button, LinearProgress, Typography, useTheme } from '@mui/material';\nimport type React from 'react';\n\nimport type { DragHandlers } from './UploadButton.hooks';\nimport type { UploadButtonProps } from './UploadButton.types';\n\n/** Shared shape for the two trigger variants. */\nexport interface TriggerProps {\n label: string;\n icon?: React.ReactNode;\n disabled: boolean;\n className?: string;\n dataTestId?: string;\n describedBy?: string;\n onOpen: () => void;\n}\n\n/** The drag-and-drop surface. */\nexport function UploadDropzone({\n label,\n icon,\n disabled,\n className,\n dataTestId,\n describedBy,\n onOpen,\n isDragOver,\n drag,\n}: TriggerProps & { isDragOver: boolean; drag: DragHandlers }): React.ReactElement {\n const theme = useTheme();\n return (\n <Box\n component=\"div\"\n {...drag}\n onClick={onOpen}\n sx={{\n border: `2px dashed ${isDragOver ? theme.palette.primary.main : theme.palette.divider}`,\n borderRadius: 2,\n padding: 3,\n textAlign: 'center',\n cursor: disabled ? 'not-allowed' : 'pointer',\n backgroundColor: isDragOver ? `${theme.palette.primary.main}0A` : 'transparent',\n transition: 'all 0.2s ease-in-out',\n ...(!disabled && {\n '&:hover': {\n borderColor: theme.palette.primary.main,\n backgroundColor: `${theme.palette.primary.main}05`,\n },\n }),\n opacity: disabled ? 0.6 : 1,\n }}\n className={className}\n data-testid={dataTestId}\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n onKeyDown={(event) => {\n if (event.key !== 'Enter' && event.key !== ' ') return;\n event.preventDefault();\n onOpen();\n }}\n aria-describedby={describedBy}\n aria-label={`Upload file dropzone. ${label}`}\n >\n <Box sx={{ mb: 2 }}>\n {icon || <CloudUploadOutlined sx={{ fontSize: 48, color: 'text.secondary' }} />}\n </Box>\n <Typography variant=\"body1\" sx={{ mb: 1 }}>\n {label}\n </Typography>\n <Typography variant=\"body2\" color=\"text.secondary\">\n Drop your file here or click to browse\n </Typography>\n </Box>\n );\n}\n\n/** MUI variant for each non-dropzone appearance. */\nconst MUI_VARIANT = { outline: 'outlined', ghost: 'text' } as const;\n\n/** The plain-button trigger. */\nexport function UploadTrigger({\n label,\n icon,\n disabled,\n className,\n dataTestId,\n describedBy,\n onOpen,\n variant,\n isUploading,\n}: TriggerProps & {\n variant: NonNullable<UploadButtonProps['variant']>;\n isUploading: boolean;\n}): React.ReactElement {\n const theme = useTheme();\n return (\n <Button\n variant={MUI_VARIANT[variant as keyof typeof MUI_VARIANT] ?? 'contained'}\n disabled={disabled || isUploading}\n onClick={onOpen}\n startIcon={icon || <AttachFileOutlined />}\n className={className}\n data-testid={dataTestId}\n aria-describedby={describedBy}\n sx={{\n ...(variant === 'ghost' && {\n '&:hover': { backgroundColor: `${theme.palette.primary.main}08` },\n }),\n }}\n >\n {isUploading ? 'Uploading...' : label}\n </Button>\n );\n}\n\n/** The screen-reader live region — drag, progress and error announcements. */\nfunction UploadAnnouncer({\n announceDragOver,\n isUploading,\n progress,\n error,\n}: {\n announceDragOver: boolean;\n isUploading: boolean;\n progress: number;\n error: string | null;\n}): React.ReactElement {\n return (\n <div\n aria-live=\"polite\"\n aria-atomic=\"true\"\n className=\"sr-only\"\n style={{\n position: 'absolute',\n left: '-10000px',\n width: '1px',\n height: '1px',\n overflow: 'hidden',\n }}\n >\n {announceDragOver && 'File ready to drop'}\n {isUploading && `Upload in progress: ${Math.round(progress)}%`}\n {error && `Error: ${error}`}\n </div>\n );\n}\n\n/** Progress bar, helper text, error text and the live region. */\nexport function UploadFeedback({\n isUploading,\n progress,\n helperText,\n helperId,\n error,\n errorId,\n announceDragOver,\n}: {\n isUploading: boolean;\n progress: number;\n helperText?: string;\n helperId?: string;\n error: string | null;\n errorId?: string;\n announceDragOver: boolean;\n}): React.ReactElement {\n return (\n <>\n {isUploading && progress > 0 && (\n <Box sx={{ mt: 1 }}>\n <LinearProgress variant=\"determinate\" value={progress} sx={{ borderRadius: 1 }} />\n <Typography variant=\"caption\" sx={{ mt: 0.5, display: 'block' }}>\n {Math.round(progress)}% uploaded\n </Typography>\n </Box>\n )}\n\n {helperText && !error && (\n <Typography\n id={helperId}\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ display: 'block', mt: 0.5 }}\n >\n {helperText}\n </Typography>\n )}\n\n {error && (\n <Typography\n id={errorId}\n variant=\"caption\"\n color=\"error\"\n sx={{ display: 'block', mt: 0.5 }}\n role=\"alert\"\n >\n {error}\n </Typography>\n )}\n\n <UploadAnnouncer\n announceDragOver={announceDragOver}\n isUploading={isUploading}\n progress={progress}\n error={error}\n />\n </>\n );\n}\n"],"mappings":";;;AAAA,SAAS,OAAAA,YAAW;AACpB,OAAO,WAAW;;;ACDlB,SAAS,aAAa,OAAO,SAAS,QAAQ,gBAAgB;AAS9D,IAAM,6BAA6B;AACnC,IAAM,0BAA0B;AAChC,IAAM,iCAAiC;AACvC,IAAM,0BAA0B;AAChC,IAAM,eAAe,OAAO;AAE5B,IAAM,gBAAmC;AAAA,EACvC,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,OAAO;AACT;AAMA,SAAS,iBACP,WACA,UAC0C;AAC1C,SAAO;AAAA,IACL,CAAC,SAAyC;AACxC,UAAI,aAAa,KAAK,OAAO,YAAY,cAAc;AACrD,eAAO,+BAA+B,SAAS;AAAA,MACjD;AACA,aAAO,WAAW,SAAS,IAAI,IAAI;AAAA,IACrC;AAAA,IACA,CAAC,WAAW,QAAQ;AAAA,EACtB;AACF;AASA,SAAS,gBACP,UACA,mBACA,UAC0C;AAC1C,SAAO;AAAA,IACL,OAAO,SAA0B;AAC/B,UAAI,CAAC,YAAY,kBAAmB;AACpC,UAAI;AACF,iBAAS,CAAC,UAAU,EAAE,GAAG,MAAM,aAAa,MAAM,gBAAgB,EAAE,EAAE;AAGtE,cAAM,QAAQ,WAAW,YAAY,MAAM;AACzC,mBAAS,CAAC,SAAS;AACjB,gBAAI,KAAK,kBAAkB,4BAA4B;AACrD,yBAAW,cAAc,KAAK;AAC9B,qBAAO;AAAA,YACT;AACA,mBAAO,EAAE,GAAG,MAAM,gBAAgB,KAAK,iBAAiB,wBAAwB;AAAA,UAClF,CAAC;AAAA,QACH,GAAG,8BAA8B;AAEjC,cAAM,SAAS,IAAI;AAEnB,mBAAW,cAAc,KAAK;AAC9B,iBAAS,CAAC,UAAU,EAAE,GAAG,MAAM,aAAa,OAAO,gBAAgB,IAAI,EAAE;AACzE,mBAAW,WAAW,MAAM;AAC1B,mBAAS,CAAC,UAAU,EAAE,GAAG,MAAM,gBAAgB,EAAE,EAAE;AAAA,QACrD,GAAG,uBAAuB;AAAA,MAC5B,SAAS,OAAO;AACd,iBAAS,CAAC,UAAU;AAAA,UAClB,GAAG;AAAA,UACH,aAAa;AAAA,UACb,gBAAgB;AAAA,UAChB,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAAA,QAClD,EAAE;AAAA,MACJ;AAAA,IACF;AAAA,IACA,CAAC,UAAU,mBAAmB,QAAQ;AAAA,EACxC;AACF;AA4BA,SAAS,mBAAmB;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4C;AAC1C,QAAM,CAAC,OAAO,QAAQ,IAAI,SAA4B,aAAa;AACnE,QAAM,YAAY,gBAAgB,UAAU,mBAAmB,QAAQ;AAEvE,QAAM,YAAY;AAAA,IAChB,CAAC,SAA0B;AACzB,YAAM,QAAQ,aAAa,IAAI;AAC/B,eAAS,CAAC,UAAU,EAAE,GAAG,MAAM,MAAM,EAAE;AACvC,UAAI,MAAO;AACX,eAAS,IAAI;AACb,WAAK,UAAU,IAAI;AAAA,IACrB;AAAA,IACA,CAAC,UAAU,WAAW,YAAY;AAAA,EACpC;AAOA,QAAM,aAAa;AAAA,IACjB,CAAC,OAA0B,WAA+C;AACxE,YAAM,WAA8B,CAAC;AACrC,UAAI,YAA2B;AAC/B,iBAAW,QAAQ,OAAO;AACxB,cAAM,QAAQ,aAAa,IAAI;AAC/B,YAAI,MAAO,2BAAc;AAAA,YACpB,UAAS,KAAK,IAAI;AAAA,MACzB;AACA,eAAS,CAAC,UAAU,EAAE,GAAG,MAAM,OAAO,UAAU,EAAE;AAClD,UAAI,SAAS,WAAW,EAAG;AAC3B,aAAO,QAAQ;AAIf,YAAM,YAAY;AAChB,mBAAW,QAAQ,SAAU,OAAM,UAAU,IAAI;AAAA,MACnD,GAAG;AAAA,IACL;AAAA,IACA,CAAC,WAAW,YAAY;AAAA,EAC1B;AAEA,QAAM,cAAc;AAAA,IAClB,CAAC,UAA6B;AAC5B,UAAI,MAAM,WAAW,EAAG;AACxB,UAAI,YAAY,aAAc,YAAW,OAAO,YAAY;AAAA,UACvD,WAAU,MAAM,CAAC,CAAoB;AAAA,IAC5C;AAAA,IACA,CAAC,UAAU,cAAc,YAAY,SAAS;AAAA,EAChD;AAEA,QAAM,cAAc,YAAY,CAAC,eAAwB;AACvD,aAAS,CAAC,UAAU,EAAE,GAAG,MAAM,WAAW,EAAE;AAAA,EAC9C,GAAG,CAAC,CAAC;AAEL,SAAO,QAAQ,OAAO,EAAE,OAAO,aAAa,YAAY,IAAI,CAAC,OAAO,aAAa,WAAW,CAAC;AAC/F;AAUA,IAAM,UAAU,CAAC,UAAiC;AAChD,QAAM,eAAe;AACrB,QAAM,gBAAgB;AACxB;AAEA,SAAS,gBACP,UACA,aACA,aACc;AACd,SAAO;AAAA,IACL,aAAa,CAAC,UAAU;AACtB,cAAQ,KAAK;AACb,UAAI,CAAC,SAAU,aAAY,IAAI;AAAA,IACjC;AAAA,IACA,aAAa,CAAC,UAAU;AACtB,cAAQ,KAAK;AACb,kBAAY,KAAK;AAAA,IACnB;AAAA,IACA,YAAY;AAAA,IACZ,QAAQ,CAAC,UAAU;AACjB,cAAQ,KAAK;AACb,kBAAY,KAAK;AACjB,UAAI,CAAC,SAAU,aAAY,MAAM,KAAK,MAAM,aAAa,KAAK,CAAC;AAAA,IACjE;AAAA,EACF;AACF;AAiBO,SAAS,gBAAgB,OAA+C;AAC7E,QAAM;AAAA,IACJ;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA,WAAW,oBAAoB;AAAA,IAC/B,UAAU,mBAAmB;AAAA,IAC7B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,EACb,IAAI;AAEJ,QAAM,WAAW,OAAyB,IAAI;AAC9C,QAAM,UAAU,iBAAiB,MAAM,CAAC;AACxC,QAAM,eAAe,iBAAiB,WAAW,QAAQ;AACzD,QAAM,EAAE,OAAO,aAAa,YAAY,IAAI,mBAAmB;AAAA,IAC7D;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,OAAO,gBAAgB,UAAU,aAAa,WAAW;AAC/D,QAAM,UAAU,sBAAsB;AAAA,IACpC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,aAAa,YAAY,MAAM,SAAS,SAAS,MAAM,GAAG,CAAC,CAAC;AAClE,QAAM,oBAAoB;AAAA,IACxB,CAAC,UAA+C;AAC9C,kBAAY,MAAM,KAAK,MAAM,OAAO,SAAS,CAAC,CAAC,CAAC;AAGhD,YAAM,OAAO,QAAQ;AAAA,IACvB;AAAA,IACA,CAAC,WAAW;AAAA,EACd;AAEA,SAAO,EAAE,UAAU,SAAS,OAAO,MAAM,SAAS,YAAY,kBAAkB;AAClF;AAgBA,SAAS,sBAAsB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAOuB;AACrB,QAAM,QAAQ,aAAa,MAAM;AACjC,QAAM,WAAW,aAAa,GAAG,OAAO,YAAY;AACpD,QAAM,UAAU,QAAQ,GAAG,OAAO,WAAW;AAC7C,SAAO;AAAA,IACL,aAAa,qBAAqB,MAAM;AAAA,IACxC,UAAU,oBAAoB,mBAAmB,MAAM;AAAA,IACvD;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,CAAC,UAAU,OAAO,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,KAAK;AAAA,EAChE;AACF;;;AClUA,OAAO,wBAAwB;AAC/B,OAAO,yBAAyB;AAChC,SAAS,KAAK,QAAQ,gBAAgB,YAAY,gBAAgB;AA+B9D,SAuIA,UAtGa,KAjCb;AAbG,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAmF;AACjF,QAAM,QAAQ,SAAS;AACvB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACT,GAAG;AAAA,MACJ,SAAS;AAAA,MACT,IAAI;AAAA,QACF,QAAQ,cAAc,aAAa,MAAM,QAAQ,QAAQ,OAAO,MAAM,QAAQ,OAAO;AAAA,QACrF,cAAc;AAAA,QACd,SAAS;AAAA,QACT,WAAW;AAAA,QACX,QAAQ,WAAW,gBAAgB;AAAA,QACnC,iBAAiB,aAAa,GAAG,MAAM,QAAQ,QAAQ,IAAI,OAAO;AAAA,QAClE,YAAY;AAAA,QACZ,GAAI,CAAC,YAAY;AAAA,UACf,WAAW;AAAA,YACT,aAAa,MAAM,QAAQ,QAAQ;AAAA,YACnC,iBAAiB,GAAG,MAAM,QAAQ,QAAQ,IAAI;AAAA,UAChD;AAAA,QACF;AAAA,QACA,SAAS,WAAW,MAAM;AAAA,MAC5B;AAAA,MACA;AAAA,MACA,eAAa;AAAA,MACb,MAAK;AAAA,MACL,UAAU,WAAW,KAAK;AAAA,MAC1B,WAAW,CAAC,UAAU;AACpB,YAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,IAAK;AAChD,cAAM,eAAe;AACrB,eAAO;AAAA,MACT;AAAA,MACA,oBAAkB;AAAA,MAClB,cAAY,yBAAyB,KAAK;AAAA,MAE1C;AAAA,4BAAC,OAAI,IAAI,EAAE,IAAI,EAAE,GACd,kBAAQ,oBAAC,uBAAoB,IAAI,EAAE,UAAU,IAAI,OAAO,iBAAiB,GAAG,GAC/E;AAAA,QACA,oBAAC,cAAW,SAAQ,SAAQ,IAAI,EAAE,IAAI,EAAE,GACrC,iBACH;AAAA,QACA,oBAAC,cAAW,SAAQ,SAAQ,OAAM,kBAAiB,oDAEnD;AAAA;AAAA;AAAA,EACF;AAEJ;AAGA,IAAM,cAAc,EAAE,SAAS,YAAY,OAAO,OAAO;AAGlD,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAGuB;AACrB,QAAM,QAAQ,SAAS;AACvB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,SAAS,YAAY,OAAmC,KAAK;AAAA,MAC7D,UAAU,YAAY;AAAA,MACtB,SAAS;AAAA,MACT,WAAW,QAAQ,oBAAC,sBAAmB;AAAA,MACvC;AAAA,MACA,eAAa;AAAA,MACb,oBAAkB;AAAA,MAClB,IAAI;AAAA,QACF,GAAI,YAAY,WAAW;AAAA,UACzB,WAAW,EAAE,iBAAiB,GAAG,MAAM,QAAQ,QAAQ,IAAI,KAAK;AAAA,QAClE;AAAA,MACF;AAAA,MAEC,wBAAc,iBAAiB;AAAA;AAAA,EAClC;AAEJ;AAGA,SAAS,gBAAgB;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKuB;AACrB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,eAAY;AAAA,MACZ,WAAU;AAAA,MACV,OAAO;AAAA,QACL,UAAU;AAAA,QACV,MAAM;AAAA,QACN,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,UAAU;AAAA,MACZ;AAAA,MAEC;AAAA,4BAAoB;AAAA,QACpB,eAAe,uBAAuB,KAAK,MAAM,QAAQ,CAAC;AAAA,QAC1D,SAAS,UAAU,KAAK;AAAA;AAAA;AAAA,EAC3B;AAEJ;AAGO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAQuB;AACrB,SACE,iCACG;AAAA,mBAAe,WAAW,KACzB,qBAAC,OAAI,IAAI,EAAE,IAAI,EAAE,GACf;AAAA,0BAAC,kBAAe,SAAQ,eAAc,OAAO,UAAU,IAAI,EAAE,cAAc,EAAE,GAAG;AAAA,MAChF,qBAAC,cAAW,SAAQ,WAAU,IAAI,EAAE,IAAI,KAAK,SAAS,QAAQ,GAC3D;AAAA,aAAK,MAAM,QAAQ;AAAA,QAAE;AAAA,SACxB;AAAA,OACF;AAAA,IAGD,cAAc,CAAC,SACd;AAAA,MAAC;AAAA;AAAA,QACC,IAAI;AAAA,QACJ,SAAQ;AAAA,QACR,OAAM;AAAA,QACN,IAAI,EAAE,SAAS,SAAS,IAAI,IAAI;AAAA,QAE/B;AAAA;AAAA,IACH;AAAA,IAGD,SACC;AAAA,MAAC;AAAA;AAAA,QACC,IAAI;AAAA,QACJ,SAAQ;AAAA,QACR,OAAM;AAAA,QACN,IAAI,EAAE,SAAS,SAAS,IAAI,IAAI;AAAA,QAChC,MAAK;AAAA,QAEJ;AAAA;AAAA,IACH;AAAA,IAGF;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,IACF;AAAA,KACF;AAEJ;;;AFnKI,SACE,OAAAC,MADF,QAAAC,aAAA;AA3BJ,IAAM,eAAe,MAAM,WAAgD,CAAC,OAAO,QAAQ;AACzF,QAAM;AAAA,IACJ,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,eAAe;AAAA,EACjB,IAAI;AACJ,QAAM,EAAE,UAAU,SAAS,OAAO,MAAM,SAAS,YAAY,kBAAkB,IAC7E,gBAAgB,KAAK;AAEvB,QAAM,UAAwB;AAAA,IAC5B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,QAAQ;AAAA,IACrB,QAAQ;AAAA,EACV;AAEA,SACE,gBAAAA,MAACC,MAAA,EACC;AAAA,oBAAAF;AAAA,MAAC;AAAA;AAAA,QACC,KAAK,OAAO;AAAA,QACZ,IAAI;AAAA,QACJ,MAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA,UAAU;AAAA,QACV,OAAO,EAAE,SAAS,OAAO;AAAA,QACzB;AAAA,QACA,eAAY;AAAA;AAAA,IACd;AAAA,IAEC,YAAY,aACX,gBAAAA,KAAC,kBAAgB,GAAG,SAAS,YAAY,MAAM,YAAY,MAAY,IAEvE,gBAAAA,KAAC,iBAAe,GAAG,SAAS,SAAkB,aAAa,QAAQ,aAAa;AAAA,IAGlF,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,aAAa,QAAQ;AAAA,QACrB,UAAU,QAAQ;AAAA,QAClB;AAAA,QACA,UAAU,QAAQ;AAAA,QAClB,OAAO,QAAQ;AAAA,QACf,SAAS,QAAQ;AAAA,QACjB,kBAAkB,YAAY,cAAc,MAAM;AAAA;AAAA,IACpD;AAAA,KACF;AAEJ,CAAC;AAED,aAAa,cAAc;","names":["Box","jsx","jsxs","Box"]}
1
+ {"version":3,"sources":["../../src/components/form/UploadButton/UploadButton.tsx","../../src/components/form/UploadButton/UploadButton.hooks.ts","../../src/components/form/UploadButton/UploadButton.parts.tsx"],"sourcesContent":["import { Box } from '@mui/material';\nimport React from 'react';\n\nimport { useUploadButton } from './UploadButton.hooks';\nimport {\n UploadDropzone,\n UploadFeedback,\n UploadTrigger,\n type TriggerProps,\n} from './UploadButton.parts';\nimport type { UploadButtonProps, UploadButtonState } from './UploadButton.types';\n\n/**\n * A file picker with an optional drag-and-drop surface.\n *\n * The body here is deliberately thin: selection rules live in\n * `UploadButton.hooks`, appearance in `UploadButton.parts`. What remains is the\n * wiring — the hidden input, which trigger to render, and the feedback beneath.\n */\nconst UploadButton = React.forwardRef<HTMLInputElement, UploadButtonProps>((props, ref) => {\n const {\n copy,\n variant = 'default',\n label = props.copy.buttonLabel,\n disabled = false,\n multiple = false,\n accept,\n capture,\n helperText,\n icon,\n className,\n 'data-testid': dataTestId,\n } = props;\n const { inputRef, inputId, state, drag, derived, openPicker, handleInputChange } =\n useUploadButton(props);\n\n const trigger: TriggerProps = {\n copy,\n label,\n icon,\n disabled,\n className,\n dataTestId,\n describedBy: derived.describedBy,\n onOpen: openPicker,\n };\n\n return (\n <Box>\n <input\n ref={ref || inputRef}\n id={inputId}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n capture={capture}\n onChange={handleInputChange}\n style={{ display: 'none' }}\n disabled={disabled}\n aria-hidden=\"true\"\n />\n\n {variant === 'dropzone' ? (\n <UploadDropzone {...trigger} isDragOver={state.isDragOver} drag={drag} />\n ) : (\n <UploadTrigger {...trigger} variant={variant} isUploading={derived.isUploading} />\n )}\n\n <UploadFeedback\n copy={copy}\n isUploading={derived.isUploading}\n progress={derived.progress}\n helperText={helperText}\n helperId={derived.helperId}\n error={derived.error}\n errorId={derived.errorId}\n announceDragOver={variant === 'dropzone' && state.isDragOver}\n />\n </Box>\n );\n});\n\nUploadButton.displayName = 'UploadButton';\n\nexport { UploadButton };\nexport type { UploadButtonProps, UploadButtonState };\n","import { useCallback, useId, useMemo, useRef, useState } from 'react';\nimport type React from 'react';\n\nimport type { UploadButtonProps, UploadButtonState } from './UploadButton.types';\n\n/** The props {@link useUploadButton} reads — the component's own props. */\ntype UploadButtonHookProps = UploadButtonProps;\n\n/** Percent the simulated progress creeps to while waiting on `onUpload`. */\nconst SIMULATED_PROGRESS_CEILING = 90;\nconst SIMULATED_PROGRESS_STEP = 10;\nconst SIMULATED_PROGRESS_INTERVAL_MS = 100;\nconst PROGRESS_RESET_DELAY_MS = 1000;\nconst BYTES_PER_MB = 1024 * 1024;\n\nconst INITIAL_STATE: UploadButtonState = {\n isDragOver: false,\n isUploading: false,\n uploadProgress: 0,\n error: null,\n};\n\n/** Narrowed `setState` for the pieces below. */\ntype SetState = React.Dispatch<React.SetStateAction<UploadButtonState>>;\n\n/** The size/custom validation applied to every file, in both modes. */\nfunction useFileValidator(\n maxSizeMB: number | undefined,\n validate: ((file: globalThis.File) => string | null) | undefined,\n): (file: globalThis.File) => string | null {\n return useCallback(\n (file: globalThis.File): string | null => {\n if (maxSizeMB && file.size > maxSizeMB * BYTES_PER_MB) {\n return `File size must be less than ${maxSizeMB}MB`;\n }\n return validate ? validate(file) : null;\n },\n [maxSizeMB, validate],\n );\n}\n\n/**\n * The built-in upload path, reachable from BOTH selection modes.\n *\n * Kept apart from selection because it is the only asynchronous part: left\n * inline it was single-file only, which made `onUpload` a silent no-op for a\n * multi-file caller — the worst kind of contract, since nothing fails.\n */\nfunction useUploadRunner(\n onUpload: ((file: globalThis.File) => Promise<void>) | undefined,\n externalUploading: boolean,\n setState: SetState,\n): (file: globalThis.File) => Promise<void> {\n return useCallback(\n async (file: globalThis.File) => {\n if (!onUpload || externalUploading) return;\n try {\n setState((prev) => ({ ...prev, isUploading: true, uploadProgress: 0 }));\n // The real percentage is unknowable through a bare promise, so the bar\n // creeps to a ceiling and only completes when the promise does.\n const timer = globalThis.setInterval(() => {\n setState((prev) => {\n if (prev.uploadProgress >= SIMULATED_PROGRESS_CEILING) {\n globalThis.clearInterval(timer);\n return prev;\n }\n return { ...prev, uploadProgress: prev.uploadProgress + SIMULATED_PROGRESS_STEP };\n });\n }, SIMULATED_PROGRESS_INTERVAL_MS);\n\n await onUpload(file);\n\n globalThis.clearInterval(timer);\n setState((prev) => ({ ...prev, isUploading: false, uploadProgress: 100 }));\n globalThis.setTimeout(() => {\n setState((prev) => ({ ...prev, uploadProgress: 0 }));\n }, PROGRESS_RESET_DELAY_MS);\n } catch (error) {\n setState((prev) => ({\n ...prev,\n isUploading: false,\n uploadProgress: 0,\n error: error instanceof Error ? error.message : 'Upload failed',\n }));\n }\n },\n [onUpload, externalUploading, setState],\n );\n}\n\n/**\n * What {@link useUploadSelection} hands back. Module-private: the published\n * surface is {@link useUploadButton}, not the shape of its internals.\n */\ninterface UploadSelection {\n state: UploadButtonState;\n setDragOver: (isDragOver: boolean) => void;\n /** Route a picked/dropped selection through validation and the callbacks. */\n handleFiles: (files: globalThis.File[]) => void;\n}\n\ninterface UploadSelectionOptions {\n onSelect: (file: globalThis.File) => void;\n multiple: boolean;\n onSelectMany?: (files: globalThis.File[]) => void;\n onUpload?: (file: globalThis.File) => Promise<void>;\n externalUploading: boolean;\n validateFile: (file: globalThis.File) => string | null;\n}\n\n/**\n * Selection, validation and the optional built-in upload.\n *\n * The rendering layer only reads `state` and calls `handleFiles`; every rule\n * about what a selection means lives here.\n */\nfunction useUploadSelection({\n onSelect,\n multiple,\n onSelectMany,\n onUpload,\n externalUploading,\n validateFile,\n}: UploadSelectionOptions): UploadSelection {\n const [state, setState] = useState<UploadButtonState>(INITIAL_STATE);\n const runUpload = useUploadRunner(onUpload, externalUploading, setState);\n\n const selectOne = useCallback(\n (file: globalThis.File) => {\n const error = validateFile(file);\n setState((prev) => ({ ...prev, error }));\n if (error) return;\n onSelect(file);\n void runUpload(file);\n },\n [onSelect, runUpload, validateFile],\n );\n\n /**\n * Multi-file mode is deliberately forgiving: the valid files are handed over\n * and the first rejection is reported alongside them, so dropping a folder\n * that also contains a PDF imports the rest instead of refusing the lot.\n */\n const selectMany = useCallback(\n (files: globalThis.File[], accept: (files: globalThis.File[]) => void) => {\n const accepted: globalThis.File[] = [];\n let rejection: string | null = null;\n for (const file of files) {\n const error = validateFile(file);\n if (error) rejection ??= error;\n else accepted.push(file);\n }\n setState((prev) => ({ ...prev, error: rejection }));\n if (accepted.length === 0) return;\n accept(accepted);\n // `onUpload` applies here too, one file after another, so the prop means\n // the same thing in both modes. Sequential because the progress bar is a\n // single indicator — overlapping uploads would report nonsense.\n void (async () => {\n for (const file of accepted) await runUpload(file);\n })();\n },\n [runUpload, validateFile],\n );\n\n const handleFiles = useCallback(\n (files: globalThis.File[]) => {\n if (files.length === 0) return;\n if (multiple && onSelectMany) selectMany(files, onSelectMany);\n else selectOne(files[0] as globalThis.File);\n },\n [multiple, onSelectMany, selectMany, selectOne],\n );\n\n const setDragOver = useCallback((isDragOver: boolean) => {\n setState((prev) => ({ ...prev, isDragOver }));\n }, []);\n\n return useMemo(() => ({ state, setDragOver, handleFiles }), [state, setDragOver, handleFiles]);\n}\n\n/** Drag-and-drop wiring for the dropzone variant. */\nexport interface DragHandlers {\n onDragEnter: (event: React.DragEvent) => void;\n onDragLeave: (event: React.DragEvent) => void;\n onDragOver: (event: React.DragEvent) => void;\n onDrop: (event: React.DragEvent) => void;\n}\n\nconst swallow = (event: React.DragEvent): void => {\n event.preventDefault();\n event.stopPropagation();\n};\n\nfunction useDragHandlers(\n disabled: boolean,\n setDragOver: (isDragOver: boolean) => void,\n handleFiles: (files: globalThis.File[]) => void,\n): DragHandlers {\n return {\n onDragEnter: (event) => {\n swallow(event);\n if (!disabled) setDragOver(true);\n },\n onDragLeave: (event) => {\n swallow(event);\n setDragOver(false);\n },\n onDragOver: swallow,\n onDrop: (event) => {\n swallow(event);\n setDragOver(false);\n if (!disabled) handleFiles(Array.from(event.dataTransfer.files));\n },\n };\n}\n\n/** Everything the component needs, assembled from its props in one call. */\ninterface UploadButtonKit {\n inputRef: React.RefObject<HTMLInputElement | null>;\n inputId: string;\n state: UploadButtonState;\n drag: DragHandlers;\n derived: DerivedUploadState;\n openPicker: () => void;\n handleInputChange: (event: React.ChangeEvent<HTMLInputElement>) => void;\n}\n\n/**\n * The component's whole behaviour in one hook, so the render body stays a thin\n * piece of wiring rather than a place where rules accumulate.\n */\nexport function useUploadButton(props: UploadButtonHookProps): UploadButtonKit {\n const {\n onSelect,\n multiple = false,\n onSelectMany,\n onUpload,\n uploading: externalUploading = false,\n progress: externalProgress = 0,\n maxSizeMB,\n validate,\n helperText,\n errorText,\n disabled = false,\n } = props;\n\n const inputRef = useRef<HTMLInputElement>(null);\n const inputId = `upload-button-${useId()}`;\n const validateFile = useFileValidator(maxSizeMB, validate);\n const { state, setDragOver, handleFiles } = useUploadSelection({\n onSelect,\n multiple,\n onSelectMany,\n onUpload,\n externalUploading,\n validateFile,\n });\n const drag = useDragHandlers(disabled, setDragOver, handleFiles);\n const derived = useDerivedUploadState({\n state,\n inputId,\n externalUploading,\n externalProgress,\n errorText,\n helperText,\n });\n\n const openPicker = useCallback(() => inputRef.current?.click(), []);\n const handleInputChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n handleFiles(Array.from(event.target.files ?? []));\n // Let the same file be picked twice in a row — without this the input\n // holds the old value and re-selecting it fires no change event.\n event.target.value = '';\n },\n [handleFiles],\n );\n\n return { inputRef, inputId, state, drag, derived, openPicker, handleInputChange };\n}\n\n/** The values the render derives from props + internal state. */\ninterface DerivedUploadState {\n isUploading: boolean;\n progress: number;\n error: string | null;\n helperId?: string;\n errorId?: string;\n describedBy?: string;\n}\n\n/**\n * Fold props and internal state into what the render actually shows. External\n * state wins whenever the caller drives it.\n */\nfunction useDerivedUploadState({\n state,\n inputId,\n externalUploading,\n externalProgress,\n errorText,\n helperText,\n}: {\n state: UploadButtonState;\n inputId: string;\n externalUploading: boolean;\n externalProgress: number;\n errorText?: string;\n helperText?: string;\n}): DerivedUploadState {\n const error = errorText || state.error;\n const helperId = helperText ? `${inputId}-helper` : undefined;\n const errorId = error ? `${inputId}-error` : undefined;\n return {\n isUploading: externalUploading || state.isUploading,\n progress: externalUploading ? externalProgress : state.uploadProgress,\n error,\n helperId,\n errorId,\n describedBy: [helperId, errorId].filter(Boolean).join(' ') || undefined,\n };\n}\n","import AttachFileOutlined from '@mui/icons-material/AttachFileOutlined';\nimport CloudUploadOutlined from '@mui/icons-material/CloudUploadOutlined';\nimport { Box, Button, LinearProgress, Typography, useTheme } from '@mui/material';\nimport type React from 'react';\n\nimport type { DragHandlers } from './UploadButton.hooks';\nimport type { UploadButtonCopy } from '../../../copy';\nimport type { UploadButtonProps } from './UploadButton.types';\n\n/** Shared shape for the two trigger variants. */\nexport interface TriggerProps {\n copy: UploadButtonCopy;\n label: string;\n icon?: React.ReactNode;\n disabled: boolean;\n className?: string;\n dataTestId?: string;\n describedBy?: string;\n onOpen: () => void;\n}\n\n/** The drag-and-drop surface. */\nexport function UploadDropzone({\n copy,\n label,\n icon,\n disabled,\n className,\n dataTestId,\n describedBy,\n onOpen,\n isDragOver,\n drag,\n}: TriggerProps & { isDragOver: boolean; drag: DragHandlers }): React.ReactElement {\n const theme = useTheme();\n return (\n <Box\n component=\"div\"\n {...drag}\n onClick={onOpen}\n sx={{\n border: `2px dashed ${isDragOver ? theme.palette.primary.main : theme.palette.divider}`,\n borderRadius: 2,\n padding: 3,\n textAlign: 'center',\n cursor: disabled ? 'not-allowed' : 'pointer',\n backgroundColor: isDragOver ? `${theme.palette.primary.main}0A` : 'transparent',\n transition: 'all 0.2s ease-in-out',\n ...(!disabled && {\n '&:hover': {\n borderColor: theme.palette.primary.main,\n backgroundColor: `${theme.palette.primary.main}05`,\n },\n }),\n opacity: disabled ? 0.6 : 1,\n }}\n className={className}\n data-testid={dataTestId}\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n onKeyDown={(event) => {\n if (event.key !== 'Enter' && event.key !== ' ') return;\n event.preventDefault();\n onOpen();\n }}\n aria-describedby={describedBy}\n aria-label={copy.dropzoneRole(label)}\n >\n <Box sx={{ mb: 2 }}>\n {icon || <CloudUploadOutlined sx={{ fontSize: 48, color: 'text.secondary' }} />}\n </Box>\n <Typography variant=\"body1\" sx={{ mb: 1 }}>\n {label}\n </Typography>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {copy.dropzoneHint}\n </Typography>\n </Box>\n );\n}\n\n/** MUI variant for each non-dropzone appearance. */\nconst MUI_VARIANT = { outline: 'outlined', ghost: 'text' } as const;\n\n/** The plain-button trigger. */\nexport function UploadTrigger({\n copy,\n label,\n icon,\n disabled,\n className,\n dataTestId,\n describedBy,\n onOpen,\n variant,\n isUploading,\n}: TriggerProps & {\n variant: NonNullable<UploadButtonProps['variant']>;\n isUploading: boolean;\n}): React.ReactElement {\n const theme = useTheme();\n return (\n <Button\n variant={MUI_VARIANT[variant as keyof typeof MUI_VARIANT] ?? 'contained'}\n disabled={disabled || isUploading}\n onClick={onOpen}\n startIcon={icon || <AttachFileOutlined />}\n className={className}\n data-testid={dataTestId}\n aria-describedby={describedBy}\n sx={{\n ...(variant === 'ghost' && {\n '&:hover': { backgroundColor: `${theme.palette.primary.main}08` },\n }),\n }}\n >\n {isUploading ? copy.uploading : label}\n </Button>\n );\n}\n\n/** The screen-reader live region — drag, progress and error announcements. */\nfunction UploadAnnouncer({\n copy,\n announceDragOver,\n isUploading,\n progress,\n error,\n}: {\n copy: UploadButtonCopy;\n announceDragOver: boolean;\n isUploading: boolean;\n progress: number;\n error: string | null;\n}): React.ReactElement {\n return (\n <div\n aria-live=\"polite\"\n aria-atomic=\"true\"\n className=\"sr-only\"\n style={{\n position: 'absolute',\n left: '-10000px',\n width: '1px',\n height: '1px',\n overflow: 'hidden',\n }}\n >\n {announceDragOver && copy.dropReady}\n {isUploading && copy.uploadInProgress(Math.round(progress))}\n {error && copy.errorAnnouncement(error)}\n </div>\n );\n}\n\n/** Progress bar, helper text, error text and the live region. */\nexport function UploadFeedback({\n copy,\n isUploading,\n progress,\n helperText,\n helperId,\n error,\n errorId,\n announceDragOver,\n}: {\n copy: UploadButtonCopy;\n isUploading: boolean;\n progress: number;\n helperText?: string;\n helperId?: string;\n error: string | null;\n errorId?: string;\n announceDragOver: boolean;\n}): React.ReactElement {\n return (\n <>\n {isUploading && progress > 0 && (\n <Box sx={{ mt: 1 }}>\n <LinearProgress variant=\"determinate\" value={progress} sx={{ borderRadius: 1 }} />\n <Typography variant=\"caption\" sx={{ mt: 0.5, display: 'block' }}>\n {copy.percentUploaded(Math.round(progress))}\n </Typography>\n </Box>\n )}\n\n {helperText && !error && (\n <Typography\n id={helperId}\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ display: 'block', mt: 0.5 }}\n >\n {helperText}\n </Typography>\n )}\n\n {error && (\n <Typography\n id={errorId}\n variant=\"caption\"\n color=\"error\"\n sx={{ display: 'block', mt: 0.5 }}\n role=\"alert\"\n >\n {error}\n </Typography>\n )}\n\n <UploadAnnouncer\n copy={copy}\n announceDragOver={announceDragOver}\n isUploading={isUploading}\n progress={progress}\n error={error}\n />\n </>\n );\n}\n"],"mappings":"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","names":["Box","jsx","jsxs","Box"]}
@@ -6,7 +6,7 @@ import {
6
6
  SavedViewsMenu,
7
7
  SortByDropdown,
8
8
  ViewSelector
9
- } from "../chunk-NUCLEOHF.js";
9
+ } from "../chunk-UNM7KFDX.js";
10
10
  import "../chunk-PZ5AY32C.js";
11
11
  export {
12
12
  ColumnsMenu,
@@ -115,6 +115,7 @@ var DashboardFilterToggle = ({ ariaLabel }) => {
115
115
  DashboardFilterToggle.displayName = "Dashboard.FilterToggle";
116
116
  var DashboardSettings = ({
117
117
  title = "Settings",
118
+ closeLabel,
118
119
  children,
119
120
  ariaLabel = "Settings",
120
121
  href,
@@ -153,7 +154,7 @@ var DashboardSettings = ({
153
154
  /* @__PURE__ */ jsxs(Dialog, { open, onClose: () => setOpen(false), maxWidth: "sm", fullWidth: true, "data-testid": `${testIdPrefix}-settings-dialog`, children: [
154
155
  /* @__PURE__ */ jsxs(DialogTitle, { sx: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
155
156
  title,
156
- /* @__PURE__ */ jsx(IconButton, { "aria-label": "Close", size: "small", onClick: () => setOpen(false), children: /* @__PURE__ */ jsx(CloseIcon, { fontSize: "small" }) })
157
+ /* @__PURE__ */ jsx(IconButton, { "aria-label": closeLabel, size: "small", onClick: () => setOpen(false), children: /* @__PURE__ */ jsx(CloseIcon, { fontSize: "small" }) })
157
158
  ] }),
158
159
  /* @__PURE__ */ jsx(DialogContent, { dividers: true, children })
159
160
  ] })