@12-apps/ui 6.6.0 → 6.8.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 (436) hide show
  1. package/dist/{chunk-QLBYAYUG.js → chunk-KR2BP7NK.js} +4 -4
  2. package/dist/chunk-KR2BP7NK.js.map +1 -0
  3. package/dist/{chunk-DFVRZ3UK.js → chunk-KXARS46L.js} +3 -3
  4. package/dist/chunk-KXARS46L.js.map +1 -0
  5. package/dist/{chunk-JP55QWVR.js → chunk-L7L6SX64.js} +5 -2
  6. package/dist/chunk-L7L6SX64.js.map +1 -0
  7. package/dist/{chunk-QZZVHY6U.js → chunk-PVLDKXKR.js} +7 -3
  8. package/dist/chunk-PVLDKXKR.js.map +1 -0
  9. package/dist/{chunk-3KWD5Y5O.js → chunk-RXE5CUUE.js} +8 -4
  10. package/dist/chunk-RXE5CUUE.js.map +1 -0
  11. package/dist/{chunk-H7UAGTVW.js → chunk-TSG5C7MP.js} +4 -3
  12. package/dist/chunk-TSG5C7MP.js.map +1 -0
  13. package/dist/{chunk-NUCLEOHF.js → chunk-UNM7KFDX.js} +44 -14
  14. package/dist/chunk-UNM7KFDX.js.map +1 -0
  15. package/dist/{chunk-CEKPLUQV.js → chunk-UY7UF7IN.js} +19 -13
  16. package/dist/chunk-UY7UF7IN.js.map +1 -0
  17. package/dist/data-display/Alert.js +1 -1
  18. package/dist/data-display/AsyncStateContainer.js +2 -1
  19. package/dist/data-display/AsyncStateContainer.js.map +1 -1
  20. package/dist/data-display/Banner.js +4 -2
  21. package/dist/data-display/Banner.js.map +1 -1
  22. package/dist/data-display/CardKit.js +3 -1
  23. package/dist/data-display/CardKit.js.map +1 -1
  24. package/dist/data-display/Carousel.js +5 -2
  25. package/dist/data-display/Carousel.js.map +1 -1
  26. package/dist/data-display/DataGrid.js +1 -1
  27. package/dist/data-display/DataViews.js +90 -66
  28. package/dist/data-display/DataViews.js.map +1 -1
  29. package/dist/data-display/HoverCard.js +4 -1
  30. package/dist/data-display/HoverCard.js.map +1 -1
  31. package/dist/data-display/Lightbox.js +147 -117
  32. package/dist/data-display/Lightbox.js.map +1 -1
  33. package/dist/data-display/MapPreview.js +14 -10
  34. package/dist/data-display/MapPreview.js.map +1 -1
  35. package/dist/data-display/Table.js +4 -2
  36. package/dist/data-display/Table.js.map +1 -1
  37. package/dist/data-display/TimingDiagram.js +3 -2
  38. package/dist/data-display/TimingDiagram.js.map +1 -1
  39. package/dist/feedback/Sonner.js +5 -4
  40. package/dist/feedback/Sonner.js.map +1 -1
  41. package/dist/feedback/StackedModal.js +1 -1
  42. package/dist/feedback/TutorialOverlay.js +19 -5
  43. package/dist/feedback/TutorialOverlay.js.map +1 -1
  44. package/dist/form/AddressAutocomplete.js +16 -8
  45. package/dist/form/AddressAutocomplete.js.map +1 -1
  46. package/dist/form/Autocomplete.js +9 -7
  47. package/dist/form/Autocomplete.js.map +1 -1
  48. package/dist/form/Calendar.js +1 -1
  49. package/dist/form/CodeEditor.js +14 -9
  50. package/dist/form/CodeEditor.js.map +1 -1
  51. package/dist/form/DateRangePicker.js +10 -3
  52. package/dist/form/DateRangePicker.js.map +1 -1
  53. package/dist/form/Menubar.js +4 -1
  54. package/dist/form/Menubar.js.map +1 -1
  55. package/dist/form/PasswordStrength.js +48 -28
  56. package/dist/form/PasswordStrength.js.map +1 -1
  57. package/dist/form/PhoneInput.js +11 -5
  58. package/dist/form/PhoneInput.js.map +1 -1
  59. package/dist/form/SearchPalette.js +4 -1
  60. package/dist/form/SearchPalette.js.map +1 -1
  61. package/dist/form/Textarea.js +21 -19
  62. package/dist/form/Textarea.js.map +1 -1
  63. package/dist/form/UploadButton.js +16 -11
  64. package/dist/form/UploadButton.js.map +1 -1
  65. package/dist/layout/ContentToolbar.js +1 -1
  66. package/dist/layout/Dashboard.js +2 -1
  67. package/dist/layout/Dashboard.js.map +1 -1
  68. package/dist/layout/ScrollArea.js +9 -3
  69. package/dist/layout/ScrollArea.js.map +1 -1
  70. package/dist/layout/TableFilter.js +1 -1
  71. package/dist/navigation/Breadcrumbs.js +9 -3
  72. package/dist/navigation/Breadcrumbs.js.map +1 -1
  73. package/dist/navigation/CommandPalette.js +20 -7
  74. package/dist/navigation/CommandPalette.js.map +1 -1
  75. package/dist/navigation/Pagination.js +1 -1
  76. package/dist/navigation/Tabs.js +7 -3
  77. package/dist/navigation/Tabs.js.map +1 -1
  78. package/dist/pt-BR.js +192 -5
  79. package/dist/pt-BR.js.map +1 -1
  80. package/dist/types/components/data-display/Alert/Alert.d.ts +9 -2
  81. package/dist/types/components/data-display/Alert/Alert.d.ts.map +1 -1
  82. package/dist/types/components/data-display/Alert/Alert.types.d.ts +25 -9
  83. package/dist/types/components/data-display/Alert/Alert.types.d.ts.map +1 -1
  84. package/dist/types/components/data-display/AsyncStateContainer/AsyncStateContainer.d.ts.map +1 -1
  85. package/dist/types/components/data-display/AsyncStateContainer/AsyncStateContainer.types.d.ts +6 -0
  86. package/dist/types/components/data-display/AsyncStateContainer/AsyncStateContainer.types.d.ts.map +1 -1
  87. package/dist/types/components/data-display/Banner/Banner.d.ts.map +1 -1
  88. package/dist/types/components/data-display/Banner/Banner.types.d.ts +2 -0
  89. package/dist/types/components/data-display/Banner/Banner.types.d.ts.map +1 -1
  90. package/dist/types/components/data-display/CardKit/card-actions-context.d.ts +3 -1
  91. package/dist/types/components/data-display/CardKit/card-actions-context.d.ts.map +1 -1
  92. package/dist/types/components/data-display/Carousel/Carousel.chrome.d.ts +3 -0
  93. package/dist/types/components/data-display/Carousel/Carousel.chrome.d.ts.map +1 -1
  94. package/dist/types/components/data-display/Carousel/Carousel.parts.d.ts.map +1 -1
  95. package/dist/types/components/data-display/Carousel/Carousel.types.d.ts +7 -0
  96. package/dist/types/components/data-display/Carousel/Carousel.types.d.ts.map +1 -1
  97. package/dist/types/components/data-display/DataGrid/DataGrid.states.d.ts +1 -0
  98. package/dist/types/components/data-display/DataGrid/DataGrid.states.d.ts.map +1 -1
  99. package/dist/types/components/data-display/DataGrid/DataGrid.types.d.ts +5 -0
  100. package/dist/types/components/data-display/DataGrid/DataGrid.types.d.ts.map +1 -1
  101. package/dist/types/components/data-display/DataViews/data-views-category-pill.d.ts.map +1 -1
  102. package/dist/types/components/data-display/DataViews/data-views-copy.d.ts +29 -1
  103. package/dist/types/components/data-display/DataViews/data-views-copy.d.ts.map +1 -1
  104. package/dist/types/components/data-display/DataViews/data-views-day-input.d.ts +12 -1
  105. package/dist/types/components/data-display/DataViews/data-views-day-input.d.ts.map +1 -1
  106. package/dist/types/components/data-display/DataViews/data-views-filter-panel.d.ts.map +1 -1
  107. package/dist/types/components/data-display/DataViews/data-views-grid-bodies.d.ts.map +1 -1
  108. package/dist/types/components/data-display/DataViews/data-views-grid-parts.d.ts.map +1 -1
  109. package/dist/types/components/data-display/DataViews/data-views-more-fields.d.ts.map +1 -1
  110. package/dist/types/components/data-display/DataViews/data-views-pagination.d.ts.map +1 -1
  111. package/dist/types/components/data-display/DataViews/data-views-range-pill.d.ts.map +1 -1
  112. package/dist/types/components/data-display/DataViews/data-views-table-parts.d.ts.map +1 -1
  113. package/dist/types/components/data-display/DataViews/data-views-toolbar.d.ts.map +1 -1
  114. package/dist/types/components/data-display/HoverCard/HoverCard.content.d.ts +1 -1
  115. package/dist/types/components/data-display/HoverCard/HoverCard.content.d.ts.map +1 -1
  116. package/dist/types/components/data-display/HoverCard/HoverCard.d.ts.map +1 -1
  117. package/dist/types/components/data-display/HoverCard/HoverCard.types.d.ts +2 -0
  118. package/dist/types/components/data-display/HoverCard/HoverCard.types.d.ts.map +1 -1
  119. package/dist/types/components/data-display/Lightbox/Lightbox.d.ts.map +1 -1
  120. package/dist/types/components/data-display/Lightbox/Lightbox.types.d.ts +9 -0
  121. package/dist/types/components/data-display/Lightbox/Lightbox.types.d.ts.map +1 -1
  122. package/dist/types/components/data-display/Lightbox/LightboxControls.d.ts.map +1 -1
  123. package/dist/types/components/data-display/Lightbox/lightbox-copy-context.d.ts +17 -0
  124. package/dist/types/components/data-display/Lightbox/lightbox-copy-context.d.ts.map +1 -0
  125. package/dist/types/components/data-display/MapPreview/MapControlBar.d.ts +7 -0
  126. package/dist/types/components/data-display/MapPreview/MapControlBar.d.ts.map +1 -1
  127. package/dist/types/components/data-display/MapPreview/MapLayers.d.ts.map +1 -1
  128. package/dist/types/components/data-display/MapPreview/MapPreview.types.d.ts +9 -0
  129. package/dist/types/components/data-display/MapPreview/MapPreview.types.d.ts.map +1 -1
  130. package/dist/types/components/data-display/MapPreview/MapSearchBar.d.ts +2 -0
  131. package/dist/types/components/data-display/MapPreview/MapSearchBar.d.ts.map +1 -1
  132. package/dist/types/components/data-display/Table/Table.d.ts.map +1 -1
  133. package/dist/types/components/data-display/Table/Table.types.d.ts +5 -0
  134. package/dist/types/components/data-display/Table/Table.types.d.ts.map +1 -1
  135. package/dist/types/components/data-display/Table/TableStates.d.ts +3 -1
  136. package/dist/types/components/data-display/Table/TableStates.d.ts.map +1 -1
  137. package/dist/types/components/data-display/TimingDiagram/TimingDiagram.d.ts.map +1 -1
  138. package/dist/types/components/data-display/TimingDiagram/TimingDiagram.types.d.ts +3 -0
  139. package/dist/types/components/data-display/TimingDiagram/TimingDiagram.types.d.ts.map +1 -1
  140. package/dist/types/components/feedback/Sonner/Sonner.d.ts +8 -0
  141. package/dist/types/components/feedback/Sonner/Sonner.d.ts.map +1 -1
  142. package/dist/types/components/feedback/Sonner/Sonner.types.d.ts +2 -0
  143. package/dist/types/components/feedback/Sonner/Sonner.types.d.ts.map +1 -1
  144. package/dist/types/components/feedback/Sonner/SonnerToast.d.ts.map +1 -1
  145. package/dist/types/components/feedback/StackedModal/StackedModal.d.ts.map +1 -1
  146. package/dist/types/components/feedback/StackedModal/StackedModal.parts.d.ts +2 -0
  147. package/dist/types/components/feedback/StackedModal/StackedModal.parts.d.ts.map +1 -1
  148. package/dist/types/components/feedback/StackedModal/StackedModal.types.d.ts +2 -0
  149. package/dist/types/components/feedback/StackedModal/StackedModal.types.d.ts.map +1 -1
  150. package/dist/types/components/feedback/TutorialOverlay/TutorialOverlay.d.ts.map +1 -1
  151. package/dist/types/components/feedback/TutorialOverlay/TutorialOverlay.types.d.ts +3 -0
  152. package/dist/types/components/feedback/TutorialOverlay/TutorialOverlay.types.d.ts.map +1 -1
  153. package/dist/types/components/feedback/TutorialOverlay/TutorialStepBody.d.ts +2 -0
  154. package/dist/types/components/feedback/TutorialOverlay/TutorialStepBody.d.ts.map +1 -1
  155. package/dist/types/components/form/AddressAutocomplete/AddressAutocomplete.types.d.ts +7 -0
  156. package/dist/types/components/form/AddressAutocomplete/AddressAutocomplete.types.d.ts.map +1 -1
  157. package/dist/types/components/form/AddressAutocomplete/AddressAutocompleteField.d.ts.map +1 -1
  158. package/dist/types/components/form/AddressAutocomplete/AddressFallbackField.d.ts +1 -0
  159. package/dist/types/components/form/AddressAutocomplete/AddressFallbackField.d.ts.map +1 -1
  160. package/dist/types/components/form/AddressAutocomplete/AddressInputField.d.ts +1 -0
  161. package/dist/types/components/form/AddressAutocomplete/AddressInputField.d.ts.map +1 -1
  162. package/dist/types/components/form/Autocomplete/Autocomplete.d.ts.map +1 -1
  163. package/dist/types/components/form/Autocomplete/Autocomplete.parts.d.ts +9 -3
  164. package/dist/types/components/form/Autocomplete/Autocomplete.parts.d.ts.map +1 -1
  165. package/dist/types/components/form/Autocomplete/Autocomplete.types.d.ts +7 -0
  166. package/dist/types/components/form/Autocomplete/Autocomplete.types.d.ts.map +1 -1
  167. package/dist/types/components/form/Calendar/Calendar.types.d.ts +6 -0
  168. package/dist/types/components/form/Calendar/Calendar.types.d.ts.map +1 -1
  169. package/dist/types/components/form/CodeEditor/CodeEditor.d.ts.map +1 -1
  170. package/dist/types/components/form/CodeEditor/CodeEditor.types.d.ts +7 -0
  171. package/dist/types/components/form/CodeEditor/CodeEditor.types.d.ts.map +1 -1
  172. package/dist/types/components/form/CodeEditor/CodeEditorToolbar.d.ts +2 -0
  173. package/dist/types/components/form/CodeEditor/CodeEditorToolbar.d.ts.map +1 -1
  174. package/dist/types/components/form/DateRangePicker/DateRangePicker.d.ts.map +1 -1
  175. package/dist/types/components/form/DateRangePicker/DateRangePicker.range.d.ts.map +1 -1
  176. package/dist/types/components/form/DateRangePicker/DateRangePicker.types.d.ts +11 -0
  177. package/dist/types/components/form/DateRangePicker/DateRangePicker.types.d.ts.map +1 -1
  178. package/dist/types/components/form/DateRangePicker/DateRangePickerFields.d.ts.map +1 -1
  179. package/dist/types/components/form/Menubar/Menubar.d.ts.map +1 -1
  180. package/dist/types/components/form/Menubar/Menubar.toolbar.d.ts +1 -0
  181. package/dist/types/components/form/Menubar/Menubar.toolbar.d.ts.map +1 -1
  182. package/dist/types/components/form/Menubar/Menubar.types.d.ts +5 -0
  183. package/dist/types/components/form/Menubar/Menubar.types.d.ts.map +1 -1
  184. package/dist/types/components/form/PasswordStrength/PasswordStrength.d.ts.map +1 -1
  185. package/dist/types/components/form/PasswordStrength/PasswordStrength.helpers.d.ts +4 -2
  186. package/dist/types/components/form/PasswordStrength/PasswordStrength.helpers.d.ts.map +1 -1
  187. package/dist/types/components/form/PasswordStrength/PasswordStrength.types.d.ts +8 -0
  188. package/dist/types/components/form/PasswordStrength/PasswordStrength.types.d.ts.map +1 -1
  189. package/dist/types/components/form/PhoneInput/PhoneInput.d.ts.map +1 -1
  190. package/dist/types/components/form/PhoneInput/PhoneInput.types.d.ts +7 -0
  191. package/dist/types/components/form/PhoneInput/PhoneInput.types.d.ts.map +1 -1
  192. package/dist/types/components/form/SearchPalette/SearchPalette.d.ts.map +1 -1
  193. package/dist/types/components/form/SearchPalette/SearchPalette.parts.d.ts +2 -0
  194. package/dist/types/components/form/SearchPalette/SearchPalette.parts.d.ts.map +1 -1
  195. package/dist/types/components/form/SearchPalette/SearchPalette.types.d.ts +6 -0
  196. package/dist/types/components/form/SearchPalette/SearchPalette.types.d.ts.map +1 -1
  197. package/dist/types/components/form/Textarea/Textarea.d.ts.map +1 -1
  198. package/dist/types/components/form/Textarea/Textarea.types.d.ts +16 -1
  199. package/dist/types/components/form/Textarea/Textarea.types.d.ts.map +1 -1
  200. package/dist/types/components/form/Textarea/TextareaRichEditor.d.ts +7 -0
  201. package/dist/types/components/form/Textarea/TextareaRichEditor.d.ts.map +1 -1
  202. package/dist/types/components/form/UploadButton/UploadButton.d.ts.map +1 -1
  203. package/dist/types/components/form/UploadButton/UploadButton.parts.d.ts +6 -3
  204. package/dist/types/components/form/UploadButton/UploadButton.parts.d.ts.map +1 -1
  205. package/dist/types/components/form/UploadButton/UploadButton.types.d.ts +7 -0
  206. package/dist/types/components/form/UploadButton/UploadButton.types.d.ts.map +1 -1
  207. package/dist/types/components/layout/ContentToolbar/ContentToolbar.d.ts +1 -1
  208. package/dist/types/components/layout/ContentToolbar/ContentToolbar.d.ts.map +1 -1
  209. package/dist/types/components/layout/ContentToolbar/ContentToolbar.types.d.ts +12 -0
  210. package/dist/types/components/layout/ContentToolbar/ContentToolbar.types.d.ts.map +1 -1
  211. package/dist/types/components/layout/ContentToolbar/MultiSelectDropdown.d.ts +1 -1
  212. package/dist/types/components/layout/ContentToolbar/MultiSelectDropdown.d.ts.map +1 -1
  213. package/dist/types/components/layout/ContentToolbar/SortByDropdown.d.ts +1 -1
  214. package/dist/types/components/layout/ContentToolbar/SortByDropdown.d.ts.map +1 -1
  215. package/dist/types/components/layout/ContentToolbar/ViewSelector.d.ts +1 -1
  216. package/dist/types/components/layout/ContentToolbar/ViewSelector.d.ts.map +1 -1
  217. package/dist/types/components/layout/Dashboard/Dashboard.d.ts +1 -1
  218. package/dist/types/components/layout/Dashboard/Dashboard.types.d.ts +4 -0
  219. package/dist/types/components/layout/Dashboard/Dashboard.types.d.ts.map +1 -1
  220. package/dist/types/components/layout/Dashboard/DashboardParts.d.ts +1 -1
  221. package/dist/types/components/layout/Dashboard/DashboardParts.d.ts.map +1 -1
  222. package/dist/types/components/layout/ScrollArea/ScrollArea.d.ts.map +1 -1
  223. package/dist/types/components/layout/ScrollArea/ScrollArea.types.d.ts +21 -3
  224. package/dist/types/components/layout/ScrollArea/ScrollArea.types.d.ts.map +1 -1
  225. package/dist/types/components/layout/ScrollArea/ScrollViewport.d.ts +2 -0
  226. package/dist/types/components/layout/ScrollArea/ScrollViewport.d.ts.map +1 -1
  227. package/dist/types/components/layout/TableFilter/TableFilter.d.ts +1 -1
  228. package/dist/types/components/layout/TableFilter/TableFilter.d.ts.map +1 -1
  229. package/dist/types/components/layout/TableFilter/TableFilter.types.d.ts +7 -0
  230. package/dist/types/components/layout/TableFilter/TableFilter.types.d.ts.map +1 -1
  231. package/dist/types/components/layout/TableFilter/TableFilterContext.d.ts +9 -0
  232. package/dist/types/components/layout/TableFilter/TableFilterContext.d.ts.map +1 -1
  233. package/dist/types/components/navigation/Breadcrumbs/BreadcrumbEntry.d.ts +2 -0
  234. package/dist/types/components/navigation/Breadcrumbs/BreadcrumbEntry.d.ts.map +1 -1
  235. package/dist/types/components/navigation/Breadcrumbs/Breadcrumbs.d.ts.map +1 -1
  236. package/dist/types/components/navigation/Breadcrumbs/Breadcrumbs.types.d.ts +3 -0
  237. package/dist/types/components/navigation/Breadcrumbs/Breadcrumbs.types.d.ts.map +1 -1
  238. package/dist/types/components/navigation/CommandPalette/CommandPalette.d.ts.map +1 -1
  239. package/dist/types/components/navigation/CommandPalette/CommandPalette.types.d.ts +3 -0
  240. package/dist/types/components/navigation/CommandPalette/CommandPalette.types.d.ts.map +1 -1
  241. package/dist/types/components/navigation/CommandPalette/CommandPaletteResults.d.ts +2 -0
  242. package/dist/types/components/navigation/CommandPalette/CommandPaletteResults.d.ts.map +1 -1
  243. package/dist/types/components/navigation/Pagination/Pagination.d.ts.map +1 -1
  244. package/dist/types/components/navigation/Pagination/Pagination.types.d.ts +2 -0
  245. package/dist/types/components/navigation/Pagination/Pagination.types.d.ts.map +1 -1
  246. package/dist/types/components/navigation/Pagination/PaginationParts.d.ts +2 -0
  247. package/dist/types/components/navigation/Pagination/PaginationParts.d.ts.map +1 -1
  248. package/dist/types/components/navigation/Tabs/Tabs.d.ts.map +1 -1
  249. package/dist/types/components/navigation/Tabs/Tabs.types.d.ts +2 -0
  250. package/dist/types/components/navigation/Tabs/Tabs.types.d.ts.map +1 -1
  251. package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.d.ts.map +1 -1
  252. package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.parts.d.ts +6 -2
  253. package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.parts.d.ts.map +1 -1
  254. package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.types.d.ts +6 -0
  255. package/dist/types/components/utility/InfiniteScroll/InfiniteScroll.types.d.ts.map +1 -1
  256. package/dist/types/components/utility/InstallPrompt/InstallPrompt.d.ts +4 -2
  257. package/dist/types/components/utility/InstallPrompt/InstallPrompt.d.ts.map +1 -1
  258. package/dist/types/components/utility/InstallPrompt/InstallPrompt.types.d.ts +8 -7
  259. package/dist/types/components/utility/InstallPrompt/InstallPrompt.types.d.ts.map +1 -1
  260. package/dist/types/copy/data-display.d.ts +56 -0
  261. package/dist/types/copy/data-display.d.ts.map +1 -0
  262. package/dist/types/copy/feedback.d.ts +38 -0
  263. package/dist/types/copy/feedback.d.ts.map +1 -0
  264. package/dist/types/copy/form.d.ts +146 -0
  265. package/dist/types/copy/form.d.ts.map +1 -0
  266. package/dist/types/copy/layout.d.ts +18 -0
  267. package/dist/types/copy/layout.d.ts.map +1 -0
  268. package/dist/types/copy/navigation.d.ts +24 -0
  269. package/dist/types/copy/navigation.d.ts.map +1 -0
  270. package/dist/types/copy/shared.d.ts +119 -0
  271. package/dist/types/copy/shared.d.ts.map +1 -0
  272. package/dist/types/copy/utility.d.ts +35 -0
  273. package/dist/types/copy/utility.d.ts.map +1 -0
  274. package/dist/types/copy.d.ts +13 -113
  275. package/dist/types/copy.d.ts.map +1 -1
  276. package/dist/types/pt-BR.d.ts +15 -18
  277. package/dist/types/pt-BR.d.ts.map +1 -1
  278. package/dist/types/pt-BR.data-display.d.ts +13 -0
  279. package/dist/types/pt-BR.data-display.d.ts.map +1 -0
  280. package/dist/types/pt-BR.feedback.d.ts +8 -0
  281. package/dist/types/pt-BR.feedback.d.ts.map +1 -0
  282. package/dist/types/pt-BR.form.d.ts +13 -0
  283. package/dist/types/pt-BR.form.d.ts.map +1 -0
  284. package/dist/types/pt-BR.layout.d.ts +7 -0
  285. package/dist/types/pt-BR.layout.d.ts.map +1 -0
  286. package/dist/types/pt-BR.navigation.d.ts +8 -0
  287. package/dist/types/pt-BR.navigation.d.ts.map +1 -0
  288. package/dist/types/pt-BR.shared.d.ts +21 -0
  289. package/dist/types/pt-BR.shared.d.ts.map +1 -0
  290. package/dist/types/pt-BR.utility.d.ts +8 -0
  291. package/dist/types/pt-BR.utility.d.ts.map +1 -0
  292. package/dist/types/user-avatar/user-avatar.d.ts +7 -1
  293. package/dist/types/user-avatar/user-avatar.d.ts.map +1 -1
  294. package/dist/user-avatar.js +2 -2
  295. package/dist/user-avatar.js.map +1 -1
  296. package/dist/utility/InfiniteScroll.js +7 -5
  297. package/dist/utility/InfiniteScroll.js.map +1 -1
  298. package/dist/utility/InstallPrompt.js +14 -13
  299. package/dist/utility/InstallPrompt.js.map +1 -1
  300. package/package.json +1 -1
  301. package/src/components/data-display/Alert/Alert.tsx +22 -5
  302. package/src/components/data-display/Alert/Alert.types.ts +20 -10
  303. package/src/components/data-display/AsyncStateContainer/AsyncStateContainer.tsx +2 -1
  304. package/src/components/data-display/AsyncStateContainer/AsyncStateContainer.types.ts +6 -0
  305. package/src/components/data-display/Banner/Banner.tsx +5 -2
  306. package/src/components/data-display/Banner/Banner.types.ts +2 -0
  307. package/src/components/data-display/CardKit/card-actions-context.tsx +4 -0
  308. package/src/components/data-display/Carousel/Carousel.chrome.tsx +5 -0
  309. package/src/components/data-display/Carousel/Carousel.parts.tsx +4 -3
  310. package/src/components/data-display/Carousel/Carousel.types.ts +7 -0
  311. package/src/components/data-display/DataGrid/DataGrid.states.tsx +3 -3
  312. package/src/components/data-display/DataGrid/DataGrid.tsx +1 -1
  313. package/src/components/data-display/DataGrid/DataGrid.types.ts +5 -0
  314. package/src/components/data-display/DataViews/data-views-category-pill.tsx +2 -0
  315. package/src/components/data-display/DataViews/data-views-copy.ts +29 -1
  316. package/src/components/data-display/DataViews/data-views-day-input.tsx +14 -3
  317. package/src/components/data-display/DataViews/data-views-filter-panel.tsx +2 -1
  318. package/src/components/data-display/DataViews/data-views-grid-bodies.tsx +3 -0
  319. package/src/components/data-display/DataViews/data-views-grid-parts.tsx +9 -10
  320. package/src/components/data-display/DataViews/data-views-more-fields.tsx +3 -1
  321. package/src/components/data-display/DataViews/data-views-pagination.tsx +3 -0
  322. package/src/components/data-display/DataViews/data-views-range-pill.tsx +3 -1
  323. package/src/components/data-display/DataViews/data-views-table-parts.tsx +1 -0
  324. package/src/components/data-display/DataViews/data-views-toolbar.tsx +2 -0
  325. package/src/components/data-display/HoverCard/HoverCard.content.tsx +10 -2
  326. package/src/components/data-display/HoverCard/HoverCard.tsx +2 -3
  327. package/src/components/data-display/HoverCard/HoverCard.types.ts +2 -0
  328. package/src/components/data-display/Lightbox/Lightbox.tsx +3 -0
  329. package/src/components/data-display/Lightbox/Lightbox.types.ts +9 -0
  330. package/src/components/data-display/Lightbox/LightboxControls.tsx +28 -15
  331. package/src/components/data-display/Lightbox/lightbox-copy-context.tsx +42 -0
  332. package/src/components/data-display/MapPreview/MapControlBar.tsx +17 -9
  333. package/src/components/data-display/MapPreview/MapLayers.tsx +2 -0
  334. package/src/components/data-display/MapPreview/MapPreview.types.ts +10 -0
  335. package/src/components/data-display/MapPreview/MapSearchBar.tsx +4 -1
  336. package/src/components/data-display/Table/Table.tsx +7 -2
  337. package/src/components/data-display/Table/Table.types.ts +5 -0
  338. package/src/components/data-display/Table/TableStates.tsx +2 -2
  339. package/src/components/data-display/TimingDiagram/TimingDiagram.tsx +3 -2
  340. package/src/components/data-display/TimingDiagram/TimingDiagram.types.ts +3 -0
  341. package/src/components/feedback/Sonner/Sonner.tsx +15 -3
  342. package/src/components/feedback/Sonner/Sonner.types.ts +2 -0
  343. package/src/components/feedback/Sonner/SonnerToast.tsx +2 -1
  344. package/src/components/feedback/StackedModal/StackedModal.parts.tsx +10 -3
  345. package/src/components/feedback/StackedModal/StackedModal.tsx +2 -1
  346. package/src/components/feedback/StackedModal/StackedModal.types.ts +2 -0
  347. package/src/components/feedback/TutorialOverlay/TutorialOverlay.tsx +13 -1
  348. package/src/components/feedback/TutorialOverlay/TutorialOverlay.types.ts +3 -0
  349. package/src/components/feedback/TutorialOverlay/TutorialStepBody.tsx +10 -4
  350. package/src/components/form/AddressAutocomplete/AddressAutocomplete.types.ts +7 -0
  351. package/src/components/form/AddressAutocomplete/AddressAutocompleteField.tsx +2 -0
  352. package/src/components/form/AddressAutocomplete/AddressFallbackField.tsx +4 -2
  353. package/src/components/form/AddressAutocomplete/AddressInputField.tsx +13 -6
  354. package/src/components/form/Autocomplete/Autocomplete.parts.tsx +9 -6
  355. package/src/components/form/Autocomplete/Autocomplete.tsx +2 -1
  356. package/src/components/form/Autocomplete/Autocomplete.types.ts +7 -0
  357. package/src/components/form/Calendar/Calendar.tsx +2 -2
  358. package/src/components/form/Calendar/Calendar.types.ts +7 -0
  359. package/src/components/form/CodeEditor/CodeEditor.tsx +6 -4
  360. package/src/components/form/CodeEditor/CodeEditor.types.ts +7 -0
  361. package/src/components/form/CodeEditor/CodeEditorToolbar.tsx +12 -5
  362. package/src/components/form/DateRangePicker/DateRangePicker.range.ts +2 -0
  363. package/src/components/form/DateRangePicker/DateRangePicker.tsx +4 -0
  364. package/src/components/form/DateRangePicker/DateRangePicker.types.ts +11 -0
  365. package/src/components/form/DateRangePicker/DateRangePickerFields.tsx +2 -0
  366. package/src/components/form/Menubar/Menubar.toolbar.tsx +3 -1
  367. package/src/components/form/Menubar/Menubar.tsx +2 -1
  368. package/src/components/form/Menubar/Menubar.types.ts +5 -0
  369. package/src/components/form/PasswordStrength/PasswordStrength.helpers.tsx +33 -17
  370. package/src/components/form/PasswordStrength/PasswordStrength.tsx +29 -13
  371. package/src/components/form/PasswordStrength/PasswordStrength.types.ts +9 -0
  372. package/src/components/form/PhoneInput/PhoneInput.tsx +15 -5
  373. package/src/components/form/PhoneInput/PhoneInput.types.ts +7 -0
  374. package/src/components/form/SearchPalette/SearchPalette.parts.tsx +4 -1
  375. package/src/components/form/SearchPalette/SearchPalette.tsx +4 -1
  376. package/src/components/form/SearchPalette/SearchPalette.types.ts +6 -0
  377. package/src/components/form/Textarea/Textarea.tsx +6 -1
  378. package/src/components/form/Textarea/Textarea.types.ts +14 -1
  379. package/src/components/form/Textarea/TextareaRichEditor.tsx +28 -18
  380. package/src/components/form/UploadButton/UploadButton.parts.tsx +16 -7
  381. package/src/components/form/UploadButton/UploadButton.tsx +4 -1
  382. package/src/components/form/UploadButton/UploadButton.types.ts +8 -0
  383. package/src/components/layout/ContentToolbar/ContentToolbar.tsx +10 -2
  384. package/src/components/layout/ContentToolbar/ContentToolbar.types.ts +12 -0
  385. package/src/components/layout/ContentToolbar/MultiSelectDropdown.tsx +15 -4
  386. package/src/components/layout/ContentToolbar/SortByDropdown.tsx +12 -3
  387. package/src/components/layout/ContentToolbar/ViewSelector.tsx +2 -1
  388. package/src/components/layout/Dashboard/Dashboard.types.ts +4 -0
  389. package/src/components/layout/Dashboard/DashboardParts.tsx +2 -1
  390. package/src/components/layout/ScrollArea/ScrollArea.tsx +16 -3
  391. package/src/components/layout/ScrollArea/ScrollArea.types.ts +19 -4
  392. package/src/components/layout/ScrollArea/ScrollViewport.tsx +4 -1
  393. package/src/components/layout/TableFilter/TableFilter.tsx +19 -11
  394. package/src/components/layout/TableFilter/TableFilter.types.ts +8 -0
  395. package/src/components/layout/TableFilter/TableFilterContext.tsx +10 -0
  396. package/src/components/navigation/Breadcrumbs/BreadcrumbEntry.tsx +11 -4
  397. package/src/components/navigation/Breadcrumbs/Breadcrumbs.tsx +2 -0
  398. package/src/components/navigation/Breadcrumbs/Breadcrumbs.types.ts +3 -0
  399. package/src/components/navigation/CommandPalette/CommandPalette.tsx +15 -5
  400. package/src/components/navigation/CommandPalette/CommandPalette.types.ts +3 -0
  401. package/src/components/navigation/CommandPalette/CommandPaletteResults.tsx +5 -2
  402. package/src/components/navigation/Pagination/Pagination.tsx +2 -0
  403. package/src/components/navigation/Pagination/Pagination.types.ts +2 -0
  404. package/src/components/navigation/Pagination/PaginationParts.tsx +4 -1
  405. package/src/components/navigation/Tabs/Tabs.tsx +8 -3
  406. package/src/components/navigation/Tabs/Tabs.types.ts +2 -0
  407. package/src/components/utility/InfiniteScroll/InfiniteScroll.parts.tsx +4 -4
  408. package/src/components/utility/InfiniteScroll/InfiniteScroll.tsx +4 -2
  409. package/src/components/utility/InfiniteScroll/InfiniteScroll.types.ts +6 -0
  410. package/src/components/utility/InstallPrompt/InstallPrompt.tsx +18 -13
  411. package/src/components/utility/InstallPrompt/InstallPrompt.types.ts +9 -7
  412. package/src/copy/data-display.ts +60 -0
  413. package/src/copy/feedback.ts +39 -0
  414. package/src/copy/form.ts +154 -0
  415. package/src/copy/layout.ts +18 -0
  416. package/src/copy/navigation.ts +25 -0
  417. package/src/copy/shared.ts +122 -0
  418. package/src/copy/utility.ts +36 -0
  419. package/src/copy.ts +13 -117
  420. package/src/pt-BR.data-display.ts +236 -0
  421. package/src/pt-BR.feedback.ts +25 -0
  422. package/src/pt-BR.form.ts +96 -0
  423. package/src/pt-BR.layout.ts +15 -0
  424. package/src/pt-BR.navigation.ts +21 -0
  425. package/src/pt-BR.shared.ts +94 -0
  426. package/src/pt-BR.ts +15 -267
  427. package/src/pt-BR.utility.ts +21 -0
  428. package/src/user-avatar/user-avatar.tsx +8 -2
  429. package/dist/chunk-3KWD5Y5O.js.map +0 -1
  430. package/dist/chunk-CEKPLUQV.js.map +0 -1
  431. package/dist/chunk-DFVRZ3UK.js.map +0 -1
  432. package/dist/chunk-H7UAGTVW.js.map +0 -1
  433. package/dist/chunk-JP55QWVR.js.map +0 -1
  434. package/dist/chunk-NUCLEOHF.js.map +0 -1
  435. package/dist/chunk-QLBYAYUG.js.map +0 -1
  436. package/dist/chunk-QZZVHY6U.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/navigation/Pagination/Pagination.tsx","../src/components/navigation/Pagination/Pagination.helpers.tsx","../src/components/navigation/Pagination/Pagination.styles.ts","../src/components/navigation/Pagination/PaginationParts.tsx"],"sourcesContent":["import FirstPage from '@mui/icons-material/FirstPage';\nimport LastPage from '@mui/icons-material/LastPage';\nimport NavigateBefore from '@mui/icons-material/NavigateBefore';\nimport NavigateNext from '@mui/icons-material/NavigateNext';\nimport type { PaginationRenderItemParams } from '@mui/material';\nimport {\n Box,\n Pagination as MuiPagination,\n PaginationItem } from '@mui/material';\nimport { styled } from '@mui/material';\nimport React from 'react';\n\nimport type { ResolvedPaginationProps } from './Pagination.helpers';\nimport { makeTestId, muiSizeFor, resolvePaginationProps } from './Pagination.helpers';\nimport { paginationStyles } from './Pagination.styles';\nimport type { PaginationProps } from './Pagination.types';\nimport { ItemsPerPageSelect, PageInfo } from './PaginationParts';\n\nconst StyledPagination = styled(MuiPagination, {\n shouldForwardProp: (prop) => !['customVariant', 'customSize'].includes(prop as string) })<{ customVariant?: string; customSize?: string }>(({ theme, customVariant, customSize }) => ({\n ...paginationStyles({ theme, customVariant, customSize }) }));\n\nconst PaginationContainer = styled(Box)(({ theme }) => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexWrap: 'wrap',\n gap: theme.spacing(1) }));\n\n// Arrow items get a short suffix, pages carry their number. This was two\n// parallel switch statements that differed only in whether the prefix came from\n// dataTestId or the literal 'pagination'.\nconst ITEM_TEST_SUFFIX: Record<string, string> = {\n first: 'first',\n last: 'last',\n previous: 'prev',\n next: 'next' };\n\nconst paginationItemTestId = (\n base: string | undefined,\n item: PaginationRenderItemParams,\n): string | undefined => {\n const prefix = base ?? 'pagination';\n\n if (item.type === 'page') return `${prefix}-page-${item.page}`;\n\n const suffix = ITEM_TEST_SUFFIX[item.type];\n return suffix ? `${prefix}-${suffix}` : undefined;\n};\n\n// A dots-variant page renders as a bare dot; everything else uses MUI's item\n// with our own arrow icons.\nconst renderPaginationItem = ({\n item,\n variant,\n size: _size,\n dataTestId,\n icons }: {\n item: PaginationRenderItemParams;\n variant: string;\n size: string;\n dataTestId?: string;\n icons: {\n firstIcon?: React.ReactNode;\n lastIcon?: React.ReactNode;\n previousIcon?: React.ReactNode;\n nextIcon?: React.ReactNode;\n };\n}) => {\n const { firstIcon, lastIcon, previousIcon, nextIcon } = icons;\n\n const itemTestId = paginationItemTestId(dataTestId, item);\n\n if (variant === 'dots') {\n if (item.type === 'page') {\n return (\n <PaginationItem\n {...item}\n data-testid={itemTestId}\n sx={{\n '&.MuiPaginationItem-page': {\n fontSize: 0,\n overflow: 'hidden',\n textIndent: '-9999px' } }}\n />\n );\n }\n return null; // Hide navigation buttons for dots\n }\n\n // Map custom icons to components\n const iconMap: Record<string, React.ReactElement> = {\n first: firstIcon as React.ReactElement,\n last: lastIcon as React.ReactElement,\n previous: previousIcon as React.ReactElement,\n next: nextIcon as React.ReactElement };\n\n return (\n <PaginationItem\n {...item}\n data-testid={itemTestId}\n components={{\n first: () => iconMap.first || <FirstPage />,\n last: () => iconMap.last || <LastPage />,\n previous: () => iconMap.previous || <NavigateBefore />,\n next: () => iconMap.next || <NavigateNext /> }}\n />\n );\n \n};\n\n// The control itself. Local because StyledPagination cannot cross a module\n// boundary (TS2742).\nconst PaginationControl: React.FC<\n ResolvedPaginationProps & {\n innerRef: React.Ref<HTMLElement>;\n renderItem: (item: PaginationRenderItemParams) => React.ReactNode;\n rest: Record<string, unknown>;\n }\n> = ({ innerRef, renderItem, rest, ...p }) => {\n // The dots variant is a position indicator, not a control: no page numbers\n // around the current one, and no step buttons.\n const isDots = p.variant === 'dots';\n\n return (\n <StyledPagination\n ref={innerRef}\n page={p.page}\n count={p.count}\n onChange={p.onChange}\n customVariant={p.variant}\n customSize={p.size}\n variant=\"outlined\"\n size={muiSizeFor(p.size)}\n boundaryCount={isDots ? 0 : p.boundaryCount}\n siblingCount={isDots ? 0 : p.siblingCount}\n hideNextButton={p.hideNextButton || isDots}\n hidePrevButton={p.hidePrevButton || isDots}\n showFirstButton={p.showFirstButton && !isDots}\n showLastButton={p.showLastButton && !isDots}\n disabled={p.disabled}\n // MUI spells the unaccented pagination colour `standard`; ours is\n // `neutral`, translated here rather than carried as a second name.\n color={p.color === undefined ? undefined : p.color === 'neutral' ? 'standard' : p.color}\n renderItem={renderItem}\n {...rest}\n />\n );\n};\n\nexport const Pagination = React.forwardRef<HTMLElement, PaginationProps>(\n (componentProps, ref) => {\n const resolved = resolvePaginationProps(componentProps);\n const {\n variant,\n size,\n page,\n count,\n onChange: _onChange,\n boundaryCount: _boundaryCount,\n siblingCount: _siblingCount,\n hideNextButton: _hideNextButton,\n hidePrevButton: _hidePrevButton,\n showFirstButton: _showFirstButton,\n showLastButton: _showLastButton,\n firstIcon,\n lastIcon,\n previousIcon,\n nextIcon,\n disabled,\n color: _color,\n showPageInfo,\n pageInfoFormat,\n showItemsPerPage,\n itemsPerPageOptions,\n itemsPerPage,\n onItemsPerPageChange,\n className,\n dataTestId,\n ...props\n } = resolved;\n\n const testId = makeTestId(dataTestId);\n\n const renderItem = (item: PaginationRenderItemParams) =>\n renderPaginationItem({\n item,\n variant,\n size,\n dataTestId,\n icons: { firstIcon, lastIcon, previousIcon, nextIcon } });\n\n return (\n <PaginationContainer className={className} data-testid={dataTestId || 'pagination'}>\n {showItemsPerPage && onItemsPerPageChange && (\n <ItemsPerPageSelect\n value={itemsPerPage}\n options={itemsPerPageOptions}\n size={size}\n disabled={disabled}\n testId={testId('items-per-page')}\n onChange={onItemsPerPageChange}\n />\n )}\n\n <PaginationControl\n {...resolved}\n innerRef={ref}\n renderItem={renderItem}\n rest={props as unknown as Record<string, unknown>}\n />\n\n {showPageInfo && (\n <PageInfo size={size} testId={testId('info')}>\n {pageInfoFormat(page, count)}\n </PageInfo>\n )}\n </PaginationContainer>\n );\n },\n);\n\nPagination.displayName = 'Pagination';\n","import FirstPage from '@mui/icons-material/FirstPage';\nimport LastPage from '@mui/icons-material/LastPage';\nimport NavigateBefore from '@mui/icons-material/NavigateBefore';\nimport NavigateNext from '@mui/icons-material/NavigateNext';\nimport React from 'react';\n\nimport type { PaginationProps } from './Pagination.types';\n\ntype PaginationDefaultedKeys =\n | 'variant'\n | 'size'\n | 'boundaryCount'\n | 'siblingCount'\n | 'hideNextButton'\n | 'hidePrevButton'\n | 'showFirstButton'\n | 'showLastButton'\n | 'firstIcon'\n | 'lastIcon'\n | 'previousIcon'\n | 'nextIcon'\n | 'disabled'\n | 'color'\n | 'showPageInfo'\n | 'pageInfoFormat'\n | 'showItemsPerPage'\n | 'itemsPerPageOptions'\n | 'itemsPerPage';\n\nexport type ResolvedPaginationProps = PaginationProps &\n Required<Pick<PaginationProps, PaginationDefaultedKeys>>;\n\nconst PAGINATION_DEFAULTS: Pick<PaginationProps, PaginationDefaultedKeys> = {\n variant: 'default',\n size: 'md',\n boundaryCount: 1,\n siblingCount: 1,\n hideNextButton: false,\n hidePrevButton: false,\n showFirstButton: false,\n showLastButton: false,\n firstIcon: <FirstPage />,\n lastIcon: <LastPage />,\n previousIcon: <NavigateBefore />,\n nextIcon: <NavigateNext />,\n disabled: false,\n color: 'primary',\n showPageInfo: false,\n pageInfoFormat: (page: number, count: number) => `Page ${page} of ${count}`,\n showItemsPerPage: false,\n itemsPerPageOptions: [10, 25, 50, 100],\n itemsPerPage: 10,\n};\n\n// Strips explicitly-undefined props before the merge, so `prop={undefined}` still\n// falls back to the default exactly as a destructuring default would. Applied as\n// a merge rather than destructuring defaults, which would otherwise put nineteen\n// branches into the component's own complexity budget.\nexport const resolvePaginationProps = (props: PaginationProps): ResolvedPaginationProps =>\n ({\n ...PAGINATION_DEFAULTS,\n ...(Object.fromEntries(\n Object.entries(props).filter(([, value]) => value !== undefined),\n ) as Partial<PaginationProps>),\n }) as ResolvedPaginationProps;\n\nexport const makeTestId =\n (dataTestId?: string) =>\n (suffix: string): string =>\n dataTestId ? `${dataTestId}-${suffix}` : `pagination-${suffix}`;\n\n// Our three sizes map onto MUI's own scale.\nexport const muiSizeFor = (size: string): 'small' | 'medium' | 'large' => {\n if (size === 'sm') return 'small';\n if (size === 'lg') return 'large';\n return 'medium';\n};\n\n// One scale for every place that sizes something off the same prop. Kept\n// generic so spacing values stay in MUI units rather than being converted.\nexport const scaleFor = <T,>(size: string, scale: [T, T, T]): T => {\n if (size === 'sm') return scale[0];\n if (size === 'lg') return scale[2];\n return scale[1];\n};\n","import { alpha } from '@mui/material';\nimport type { CSSObject, Theme } from '@mui/material';\n\nconst ITEM_SIZE_STYLES: Record<string, (theme: Theme) => CSSObject> = {\n sm: (theme) => ({\n fontSize: '0.875rem',\n minWidth: 28,\n height: 28,\n padding: theme.spacing(0.25, 0.5) }),\n lg: (theme) => ({\n fontSize: '1.125rem',\n minWidth: 44,\n height: 44,\n padding: theme.spacing(1, 1.5) }) };\n\n// One variant applies at a time, so a lookup replaces the mutually exclusive\n// spreads.\nconst ITEM_VARIANTS: Record<string, (theme: Theme, customSize?: string) => CSSObject> = {\n default: (theme, _customSize) => ({\n borderRadius: theme.spacing(1),\n '&:hover': {\n backgroundColor: alpha(theme.palette.primary.main, 0.08),\n transform: 'translateY(-1px)',\n boxShadow: `0 2px 8px ${alpha(theme.palette.primary.main, 0.15)}` },\n '&.Mui-selected': {\n backgroundColor: theme.palette.primary.main,\n color: theme.palette.primary.contrastText,\n boxShadow: `0 4px 12px ${alpha(theme.palette.primary.main, 0.3)}`,\n '&:hover': {\n backgroundColor: theme.palette.primary.dark,\n transform: 'translateY(-2px)' } } }),\n rounded: (theme, customSize) => ({\n borderRadius: '50%',\n minWidth: customSize === 'sm' ? 28 : customSize === 'lg' ? 44 : 36,\n width: customSize === 'sm' ? 28 : customSize === 'lg' ? 44 : 36,\n '&:hover': {\n backgroundColor: alpha(theme.palette.primary.main, 0.08),\n transform: 'scale(1.1)',\n boxShadow: `0 4px 16px ${alpha(theme.palette.primary.main, 0.2)}` },\n '&.Mui-selected': {\n backgroundColor: theme.palette.primary.main,\n color: theme.palette.primary.contrastText,\n transform: 'scale(1.05)',\n boxShadow: `0 6px 20px ${alpha(theme.palette.primary.main, 0.3)}`,\n '&:hover': {\n backgroundColor: theme.palette.primary.dark,\n transform: 'scale(1.15)' } } }),\n dots: (theme, customSize) => ({\n borderRadius: '50%',\n minWidth: customSize === 'sm' ? 8 : customSize === 'lg' ? 12 : 10,\n width: customSize === 'sm' ? 8 : customSize === 'lg' ? 12 : 10,\n height: customSize === 'sm' ? 8 : customSize === 'lg' ? 12 : 10,\n fontSize: 0,\n backgroundColor: alpha(theme.palette.text.secondary, 0.3),\n '&:hover': {\n backgroundColor: alpha(theme.palette.primary.main, 0.5),\n transform: 'scale(1.3)' },\n '&.Mui-selected': {\n backgroundColor: theme.palette.primary.main,\n transform: 'scale(1.2)',\n '&:hover': {\n backgroundColor: theme.palette.primary.dark,\n transform: 'scale(1.4)' } },\n '&.MuiPaginationItem-previousNext, &.MuiPaginationItem-firstLast': {\n display: 'none' } }),\n minimal: (theme, _customSize) => ({\n borderRadius: theme.spacing(0.5),\n backgroundColor: 'transparent',\n color: theme.palette.text.secondary,\n padding: theme.spacing(0.5, 1),\n '&:hover': {\n backgroundColor: alpha(theme.palette.primary.main, 0.04),\n color: theme.palette.primary.main },\n '&.Mui-selected': {\n backgroundColor: 'transparent',\n color: theme.palette.primary.main,\n fontWeight: 600,\n position: 'relative',\n '&::after': {\n content: '\"\"',\n position: 'absolute',\n bottom: 0,\n left: '50%',\n transform: 'translateX(-50%)',\n width: '60%',\n height: 2,\n backgroundColor: theme.palette.primary.main,\n borderRadius: 1 } } }) };\n\nconst itemSizeStyles = (theme: Theme, customSize?: string): CSSObject =>\n customSize ? (ITEM_SIZE_STYLES[customSize]?.(theme) ?? {}) : {};\n\nconst itemVariantStyles = (theme: Theme, customVariant?: string, customSize?: string): CSSObject =>\n customVariant ? (ITEM_VARIANTS[customVariant]?.(theme, customSize) ?? {}) : {};\n\n// The pagination list's own styling, lifted out so the styled() callback is a\n// single spread.\nexport const paginationStyles = ({\n theme,\n customVariant,\n customSize }: {\n theme: Theme;\n customVariant?: string;\n customSize?: string;\n}): CSSObject => ({\n '& .MuiPagination-ul': {\n gap: customVariant === 'minimal' ? theme.spacing(0.5) : theme.spacing(1) },\n\n '& .MuiPaginationItem-root': {\n ...itemSizeStyles(theme, customSize),\n ...itemVariantStyles(theme, customVariant, customSize),\n transition: 'all 0.2s ease',\n fontWeight: 500,\n\n\n\n\n\n // Default variant (flat design)\n\n\n // Rounded variant\n\n\n // Dots variant (minimal circular dots)\n\n\n // Minimal variant (text-only)\n\n },\n\n // Hide ellipsis for dots variant\n ...(customVariant === 'dots' && {\n '& .MuiPaginationItem-ellipsis': {\n display: 'none' } }) });\n","import { Box, FormControl, MenuItem, Select, Typography } from '@mui/material';\nimport { styled } from '@mui/material';\nimport type { FC } from 'react';\nimport React from 'react';\n\nimport { scaleFor } from './Pagination.helpers';\n\n// Kept module-local: styled() components cannot be exported across a module\n// boundary here without tripping TS2742.\nconst ItemsPerPageContainer = styled(Box)(({ theme }) => ({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n}));\n\nconst PageInfoContainer = styled(Box)(({ theme }) => ({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n}));\n\nexport interface ItemsPerPageSelectProps {\n value: number;\n options: number[];\n size: string;\n disabled: boolean;\n testId: string;\n onChange: (value: number) => void;\n}\n\nexport const ItemsPerPageSelect: FC<ItemsPerPageSelectProps> = ({\n value,\n options,\n size,\n disabled,\n testId,\n onChange,\n}) => (\n <ItemsPerPageContainer>\n <Typography variant=\"body2\" color=\"text.secondary\">\n Show:\n </Typography>\n <FormControl size=\"small\" sx={{ minWidth: 80 }}>\n <Select\n value={value}\n onChange={(event) => onChange(event.target.value as number)}\n disabled={disabled}\n data-testid={testId}\n sx={{\n '& .MuiSelect-select': {\n fontSize: scaleFor(size, ['0.875rem', '1rem', '1.125rem']),\n py: scaleFor(size, [0.5, 1, 1.5]),\n },\n }}\n >\n {options.map((option) => (\n <MenuItem key={option} value={option}>\n {option}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n </ItemsPerPageContainer>\n);\n\nexport const PageInfo: FC<{ size: string; testId: string; children: React.ReactNode }> = ({\n size,\n testId,\n children,\n}) => (\n <PageInfoContainer>\n <Typography\n variant=\"body2\"\n color=\"text.secondary\"\n fontSize={scaleFor(size, ['0.75rem', '0.875rem', '1rem'])}\n data-testid={testId}\n >\n {children}\n </Typography>\n </PageInfoContainer>\n);\n"],"mappings":"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","names":["FirstPage","LastPage","NavigateBefore","NavigateNext","Box","styled","jsx","jsx","jsxs","styled","Box","FirstPage","LastPage","NavigateBefore","NavigateNext"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/layout/ContentToolbar/ContentToolbar.tsx","../src/components/layout/ContentToolbar/ViewSelector.tsx","../src/components/layout/ContentToolbar/SortByDropdown.tsx","../src/components/layout/ContentToolbar/MultiSelectDropdown.tsx","../src/components/layout/ContentToolbar/MultiSelectTriggers.tsx","../src/components/layout/ContentToolbar/FilterTrigger.tsx","../src/components/layout/ContentToolbar/ColumnsMenu.tsx","../src/components/layout/ContentToolbar/SavedViewsMenu.tsx"],"sourcesContent":["'use client';\n\nimport { Box, Button, Checkbox, Divider, Typography } from '@mui/material';\nimport React from 'react';\n\nimport type { ContentToolbarProps } from './ContentToolbar.types';\n\nconst selectionButtonSx = {\n minWidth: 0,\n height: 'auto',\n borderRadius: 0.5,\n fontWeight: 600,\n py: 0.5,\n px: 1.5,\n fontSize: '0.75rem',\n textTransform: 'none',\n color: 'text.primary',\n} as const;\n\ntype SelectionClusterProps = Pick<\n ContentToolbarProps,\n | 'hasSelection'\n | 'selectedCount'\n | 'selectAll'\n | 'clearSelection'\n | 'actions'\n | 'selectAllTestId'\n | 'clearAllTestId'\n | 'edgeAlign'\n | 'selectAllLabel'\n>;\n\n/** The left cluster: Select All + (when selecting) Clear All / count / actions. */\nfunction SelectionCluster({\n hasSelection,\n selectedCount,\n selectAll,\n clearSelection,\n actions,\n selectAllTestId,\n clearAllTestId,\n edgeAlign = false,\n selectAllLabel,\n}: SelectionClusterProps): React.JSX.Element {\n const actionsSlot = actions !== undefined && (\n <Box sx={{ ml: 0.5, display: 'flex', flexShrink: 0, alignItems: 'center' }}>{actions}</Box>\n );\n return (\n <Box\n sx={{\n display: 'flex',\n minWidth: 0,\n // Mobile: don't grow, so the controls sit on the SAME line as the checkbox\n // (no orphaned selection row). Desktop: grow to push controls right.\n flex: { xs: '0 0 auto', md: 1 },\n alignItems: 'center',\n gap: 1.5,\n ml: edgeAlign ? -1.5 : 0,\n }}\n >\n {/* Desktop: a \"Select All\" text button (md+). Mobile: a compact checkbox\n that toggles select-all/clear — the text would eat the tight row. */}\n <Button\n variant=\"text\"\n size=\"small\"\n color=\"inherit\"\n onClick={selectAll}\n data-testid={selectAllTestId}\n sx={{ ...selectionButtonSx, display: { xs: 'none', md: 'inline-flex' } }}\n >\n Select All\n </Button>\n <Checkbox\n size=\"small\"\n checked={hasSelection}\n onChange={(event) => (event.target.checked ? selectAll() : clearSelection())}\n data-testid={`${selectAllTestId}-checkbox`}\n inputProps={{ 'aria-label': selectAllLabel }}\n sx={{ p: 0.5, display: { xs: 'inline-flex', md: 'none' } }}\n />\n {hasSelection ? (\n <>\n <Button\n variant=\"text\"\n size=\"small\"\n color=\"inherit\"\n onClick={clearSelection}\n data-testid={clearAllTestId}\n sx={selectionButtonSx}\n >\n Clear All\n </Button>\n <Divider orientation=\"vertical\" flexItem sx={{ height: 16, alignSelf: 'center' }} />\n <Typography\n component=\"span\"\n data-testid=\"selected-count-indicator\"\n sx={{ fontSize: '0.875rem', color: 'text.secondary', whiteSpace: 'nowrap', flexShrink: 0 }}\n >\n {selectedCount} {selectedCount === 1 ? 'item' : 'items'} selected\n </Typography>\n {actionsSlot}\n </>\n ) : (\n actionsSlot\n )}\n </Box>\n );\n}\n\n/**\n * The BROWSING half of the toolbar: search + filters on the left, the page's\n * own controls on the right. Split out of {@link ContentToolbar} so that\n * function stays inside the complexity gate — it is layout only, and the\n * decision of whether to show it at all is made by the caller.\n */\nfunction BrowsingClusters({\n leadingControls,\n rightControls,\n hasSelection,\n edgeAlign,\n}: {\n leadingControls?: React.ReactNode;\n rightControls: React.ReactNode;\n hasSelection: boolean;\n edgeAlign: boolean;\n}): React.JSX.Element {\n return (\n <>\n {/* minWidth:0 lets this cluster be the one that gives up width as the row\n * tightens, which is what the filter overflow measures against. */}\n {leadingControls !== undefined && (\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n flexGrow: 1,\n minWidth: 0,\n // The collapse ladder has a FLOOR — below roughly 400px even the\n // fully-collapsed row does not fit, and its controls cannot shrink\n // (they are flexShrink:0 so an over-packed row sheds instead of\n // squeezing). Past that point this scrolls rather than letting them\n // paint outside the toolbar, which is what a narrow phone did.\n overflowX: 'auto',\n // No scrollbar gutter stealing height on the common case.\n scrollbarWidth: 'thin',\n }}\n >\n {leadingControls}\n </Box>\n )}\n {/* ml:auto keeps the controls right-aligned even when the cluster wraps to\n * its own row (where justify-content:space-between would otherwise snap a\n * lone item to the left); it's a no-op on a shared row. */}\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n // Same single-line rule as the row itself: this cluster wrapping\n // INTERNALLY buys a second line just as surely as the row wrapping\n // does. It bit at exactly 900px, the `md` breakpoint where the \"N de\n // N\" counter appears and pushes Exibir/Exportar over the edge.\n flexWrap: leadingControls === undefined ? 'wrap' : 'nowrap',\n // Tight (5px) when browsing so the controls fit one line beside the\n // checkbox; roomier (14px) in selection mode where they get their own row.\n gap: hasSelection ? '14px' : '5px',\n ml: 'auto',\n mr: edgeAlign ? -1.5 : 0,\n '& > *': { flexShrink: 0 },\n }}\n >\n {rightControls}\n </Box>\n </>\n );\n}\n\n/**\n * Shared toolbar for content pages (Favorites, Personal Space, Recents, …). The\n * left cluster owns selection chrome — **Select All**, and once items are\n * selected, **Clear All** + an \"N items selected\" count + an optional `actions`\n * slot. The right cluster is a free `rightControls` slot for page-specific\n * controls (ViewSelector, SortByDropdown, MultiSelectDropdown, FilterTrigger).\n *\n * Faithful, generic MUI port of the reference `ContentPageToolbar` — the\n * domain-specific default actions are intentionally left to the consumer via\n * the `actions` slot so this stays agnostic and reusable across projects.\n *\n * @example\n * ```tsx\n * <ContentToolbar\n * hasSelection={selected.size > 0}\n * selectedCount={selected.size}\n * selectAll={selectAll}\n * clearSelection={clear}\n * rightControls={\n * <>\n * <ViewSelector viewMode={view} onViewModeChange={setView} zoom={zoom} onZoomChange={setZoom} />\n * <SortByDropdown fields={FIELDS} activeField={field} onFieldChange={setField} />\n * <MultiSelectDropdown label=\"Content Type\" options={types} selected={typeSet} onToggle={toggle} onClear={clear} />\n * <FilterTrigger open={panelOpen} onOpenChange={setPanelOpen} hasActiveFilters={hasFilters} />\n * </>\n * }\n * />\n * ```\n */\nexport function ContentToolbar({\n hasSelection,\n selectedCount,\n selectAll,\n clearSelection,\n rightControls,\n leadingControls,\n actions,\n selectAllTestId,\n clearAllTestId,\n edgeAlign = false,\n exclusiveSelection = false,\n selectAllLabel,\n}: ContentToolbarProps): React.JSX.Element {\n // Under `exclusiveSelection` the two states are alternatives, not neighbours:\n // browsing shows the controls and no checkbox, selecting shows the checkbox\n // and no controls. Anything else double-books the row.\n const showSelection = !exclusiveSelection || hasSelection;\n const showControls = !exclusiveSelection || !hasSelection;\n return (\n // Two clusters on one line. They may wrap onto separate rows ONLY for a\n // toolbar without `leadingControls` — one carrying search + filters is\n // driven by a measured collapse ladder (see `useFilterOverflow`), and a\n // wrap there is the ladder having failed: it would silently buy a second\n // row instead of shedding a control into \"Mais\", which is the one outcome\n // the ladder exists to prevent.\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 2,\n flexWrap: leadingControls === undefined ? 'wrap' : 'nowrap',\n rowGap: 1,\n }}\n >\n {showSelection && (\n <SelectionCluster\n hasSelection={hasSelection}\n selectedCount={selectedCount}\n selectAll={selectAll}\n clearSelection={clearSelection}\n actions={actions}\n selectAllTestId={selectAllTestId}\n clearAllTestId={clearAllTestId}\n selectAllLabel={selectAllLabel}\n edgeAlign={edgeAlign}\n />\n )}\n\n {showControls && (\n <BrowsingClusters\n leadingControls={leadingControls}\n rightControls={rightControls}\n hasSelection={hasSelection}\n edgeAlign={edgeAlign}\n />\n )}\n </Box>\n );\n}\n","'use client';\n\nimport CheckIcon from '@mui/icons-material/Check';\nimport ChevronDownIcon from '@mui/icons-material/KeyboardArrowDown';\nimport GridIcon from '@mui/icons-material/GridViewOutlined';\nimport ListIcon from '@mui/icons-material/FormatListBulletedRounded';\nimport { Box, Button, ListItemIcon, ListItemText, Menu, MenuItem, Slider } from '@mui/material';\n// Type-only, so it is erased at build time and costs no barrel transform.\nimport type { SvgIconComponent } from '@mui/icons-material';\nimport React, { useState } from 'react';\n\nimport type { ViewMode, ViewSelectorProps } from './ContentToolbar.types';\n\nconst VIEW_OPTIONS: { value: ViewMode; label: string; icon: SvgIconComponent }[] = [\n { value: 'grid', label: 'Grid View', icon: GridIcon },\n { value: 'list', label: 'List View', icon: ListIcon },\n];\n\n/**\n * View selector: a grid/list dropdown plus a card-size zoom slider (grid mode\n * only). Faithful MUI port of the reference toolbar's view control.\n */\nexport function ViewSelector({\n viewMode,\n onViewModeChange,\n zoom,\n onZoomChange,\n}: ViewSelectorProps): React.JSX.Element {\n const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);\n const open = Boolean(anchorEl);\n const activeOption = VIEW_OPTIONS.find((option) => option.value === viewMode) ?? VIEW_OPTIONS[0]!;\n const ActiveIcon = activeOption.icon;\n\n return (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5 }}>\n {viewMode === 'grid' && (\n <Box sx={{ width: 96, display: 'flex', alignItems: 'center' }}>\n <Slider\n data-testid=\"resize-card-slider\"\n aria-label=\"Card size\"\n value={zoom[0] ?? 0}\n onChange={(_, value) => onZoomChange([value as number])}\n min={0}\n max={100}\n step={1}\n size=\"small\"\n />\n </Box>\n )}\n\n <Button\n data-testid=\"view-mode-btn\"\n variant=\"text\"\n size=\"small\"\n color=\"inherit\"\n aria-label={activeOption.label}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n onClick={(event) => setAnchorEl(event.currentTarget)}\n sx={{ minWidth: 0, height: 32, px: 1, gap: 1, color: 'text.secondary' }}\n >\n <ActiveIcon sx={{ fontSize: 16 }} />\n <ChevronDownIcon sx={{ fontSize: 14 }} />\n </Button>\n <Menu\n anchorEl={anchorEl}\n open={open}\n onClose={() => setAnchorEl(null)}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n transformOrigin={{ vertical: 'top', horizontal: 'right' }}\n slotProps={{ paper: { sx: { minWidth: 180 } } }}\n >\n {VIEW_OPTIONS.map((option) => {\n const OptionIcon = option.icon;\n const selected = viewMode === option.value;\n return (\n <MenuItem\n key={option.value}\n data-testid={`view-mode-${option.value}`}\n onClick={() => {\n onViewModeChange(option.value);\n setAnchorEl(null);\n }}\n sx={{ gap: 1.5 }}\n >\n <ListItemText>{option.label}</ListItemText>\n <OptionIcon sx={{ fontSize: 16, color: 'text.secondary' }} />\n <ListItemIcon sx={{ minWidth: 'auto !important' }}>\n <CheckIcon sx={{ fontSize: 16, color: selected ? 'text.primary' : 'transparent' }} />\n </ListItemIcon>\n </MenuItem>\n );\n })}\n </Menu>\n </Box>\n );\n}\n","'use client';\n\nimport CheckIcon from '@mui/icons-material/Check';\nimport ChevronDownIcon from '@mui/icons-material/KeyboardArrowDown';\nimport { Box, Button, Divider, ListSubheader, Menu, MenuItem, Typography } from '@mui/material';\nimport React, { useState } from 'react';\n\nimport type {\n SortByDropdownProps,\n SortFieldDefinition,\n SortOrderOption,\n} from './ContentToolbar.types';\n\nfunction findActiveField<TField extends string>(\n fields: SortFieldDefinition<TField>[] | undefined,\n activeField: TField,\n): SortFieldDefinition<TField> | undefined {\n return fields?.find((field) => field.value === activeField);\n}\n\nfunction findActiveOrder(\n fieldDef: SortFieldDefinition | undefined,\n activeOrder: string | undefined,\n): SortOrderOption | undefined {\n const options = fieldDef?.orderOptions;\n if (!options?.length) return undefined;\n return options.find((option) => option.value === activeOrder) ?? options[0];\n}\n\nfunction resolveArrowDirection(option: SortOrderOption | undefined, indexInList: number): 'up' | 'down' {\n if (option?.arrowDirection) return option.arrowDirection;\n // A missing (<0) or first index sorts \"down\"; any later option sorts \"up\".\n return indexInList <= 0 ? 'down' : 'up';\n}\n\nfunction buildTriggerLabel(\n fieldDef: SortFieldDefinition | undefined,\n orderOption: SortOrderOption | undefined,\n): string {\n if (!fieldDef) return '';\n if (fieldDef.showOrderInTrigger === false || !orderOption) return fieldDef.label;\n if (fieldDef.triggerLabelStyle === 'range' && fieldDef.orderOptions?.length === 2) {\n const other = fieldDef.orderOptions.find((option) => option.value !== orderOption.value);\n if (other) return `${fieldDef.label} (${orderOption.label.toLowerCase()}-${other.label.toLowerCase()})`;\n }\n return `${fieldDef.label} (${orderOption.label.toLowerCase()})`;\n}\n\n/** The trigger's full label (md+), short label (mobile), and direction arrow. */\nfunction resolveTriggerParts(\n fieldDef: SortFieldDefinition | undefined,\n orderOption: SortOrderOption | undefined,\n orderOptions: SortOrderOption[],\n): { full: string; short: string; arrowSuffix: string } {\n const useRangeLabel = fieldDef?.triggerLabelStyle === 'range' && orderOptions.length === 2;\n const orderIndex = orderOptions.findIndex((option) => option.value === orderOption?.value);\n const arrow = resolveArrowDirection(orderOption, orderIndex);\n const arrowSuffix = orderOptions.length > 0 && !useRangeLabel ? ` ${arrow === 'down' ? '↓' : '↑'}` : '';\n const full = buildTriggerLabel(fieldDef, orderOption);\n return { full, short: fieldDef?.label ?? full, arrowSuffix };\n}\n\nconst sectionLabelSx = { px: 1, py: 0.75, fontSize: '0.75rem', fontWeight: 600, color: 'text.primary', lineHeight: 1.5 } as const;\n\n/** A fixed-width check slot (empty when unchecked) so labels align. */\nfunction SortCheck({ checked }: { checked: boolean }): React.JSX.Element {\n return (\n <Box component=\"span\" sx={{ display: 'flex', width: 16, flexShrink: 0, alignItems: 'center', justifyContent: 'center' }} aria-hidden>\n {checked ? <CheckIcon sx={{ fontSize: 14 }} /> : null}\n </Box>\n );\n}\n\n/** One `id`/`label` menu row with a leading check + testid. */\nfunction SortRow({\n value,\n label,\n checked,\n onSelect,\n}: {\n value: string;\n label: string;\n checked: boolean;\n onSelect: () => void;\n}): React.JSX.Element {\n return (\n <MenuItem data-testid={`sort-${value}-option`} onClick={onSelect} sx={{ gap: 1 }}>\n <SortCheck checked={checked} />\n <Box component=\"span\" sx={{ flex: 1, minWidth: 0, textAlign: 'left' }}>\n {label}\n </Box>\n </MenuItem>\n );\n}\n\ninterface SortMenuProps<TField extends string> {\n anchorEl: HTMLElement | null;\n open: boolean;\n close: () => void;\n orderOptions: SortOrderOption[];\n activeOrderValue: string | undefined;\n onOrderSelect: (value: string) => void;\n fields: SortFieldDefinition<TField>[];\n activeField: TField;\n onFieldSelect: (field: TField) => void;\n}\n\n/** The Order + Sort sections of the dropdown menu. */\nfunction SortMenu<TField extends string>({\n anchorEl,\n open,\n close,\n orderOptions,\n activeOrderValue,\n onOrderSelect,\n fields,\n activeField,\n onFieldSelect,\n}: SortMenuProps<TField>): React.JSX.Element {\n return (\n <Menu\n anchorEl={anchorEl}\n open={open}\n onClose={close}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}\n transformOrigin={{ vertical: 'top', horizontal: 'left' }}\n slotProps={{ paper: { sx: { minWidth: 180 } } }}\n >\n {orderOptions.length > 0 && [\n <ListSubheader key=\"order-label\" sx={sectionLabelSx}>\n Order\n </ListSubheader>,\n ...orderOptions.map((option) => (\n <SortRow\n key={`order-${option.value}`}\n value={option.value}\n label={option.label}\n checked={activeOrderValue === option.value}\n onSelect={() => onOrderSelect(option.value)}\n />\n )),\n <Divider key=\"order-divider\" />,\n ]}\n <ListSubheader sx={sectionLabelSx}>Sort</ListSubheader>\n {fields.map((field) => (\n <SortRow\n key={field.value}\n value={field.value}\n label={field.label}\n checked={activeField === field.value}\n onSelect={() => onFieldSelect(field.value)}\n />\n ))}\n </Menu>\n );\n}\n\n/**\n * Generic \"Sort By\" dropdown: a \"Sort By:\" label + a trigger whose menu has an\n * **Order** section (direction within the active field) and a **Sort** section\n * (which field). The Order section is hidden when the field defines no order\n * options. Faithful MUI port of the reference control.\n */\nexport function SortByDropdown<TField extends string = string>({\n fields,\n activeField,\n activeOrder,\n onFieldChange,\n onOrderChange,\n 'data-testid': testId,\n}: SortByDropdownProps<TField>): React.JSX.Element {\n const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);\n const open = Boolean(anchorEl);\n const close = (): void => setAnchorEl(null);\n\n const safeFields = fields ?? [];\n const activeFieldDef = findActiveField(fields, activeField);\n const orderOptions = activeFieldDef?.orderOptions ?? [];\n const activeOrderOption = findActiveOrder(activeFieldDef, activeOrder);\n const trigger = resolveTriggerParts(activeFieldDef, activeOrderOption, orderOptions);\n\n function handleFieldChange(field: TField): void {\n // Switch field in ONE callback. Previously this also fired `onOrderChange`\n // to reset the order, but a consumer whose `onOrderChange` derives the field\n // from its own (now-stale) prop would re-apply the OLD field — silently\n // reverting the field change (e.g. picking \"E-mail\" snapped back to \"Nome\").\n // The field-change consumer owns the resulting order.\n onFieldChange(field);\n close();\n }\n\n return (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, fontSize: '0.875rem' }}>\n <Typography\n component=\"span\"\n sx={{ display: { xs: 'none', md: 'inline' }, color: 'text.secondary', fontSize: '0.875rem' }}\n >\n Sort By:\n </Typography>\n <Button\n variant=\"text\"\n size=\"small\"\n color=\"inherit\"\n data-testid={testId}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n onClick={(event) => setAnchorEl(event.currentTarget)}\n sx={{ minWidth: 0, height: 32, px: 1, gap: 0.5, color: 'text.primary', textTransform: 'none', fontWeight: 600 }}\n >\n {/* Full \"Nome (crescente)\" on md+; just the field name on mobile — the\n arrow already conveys the direction, so the parenthetical is dropped. */}\n <Box component=\"span\" sx={{ display: { xs: 'none', md: 'inline' } }}>\n {trigger.full}\n </Box>\n <Box component=\"span\" sx={{ display: { xs: 'inline', md: 'none' } }}>\n {trigger.short}\n </Box>\n {trigger.arrowSuffix}\n <ChevronDownIcon sx={{ fontSize: 14 }} />\n </Button>\n <SortMenu\n anchorEl={anchorEl}\n open={open}\n close={close}\n orderOptions={orderOptions}\n activeOrderValue={activeOrderOption?.value}\n onOrderSelect={(value) => {\n onOrderChange?.(value);\n close();\n }}\n fields={safeFields}\n activeField={activeField}\n onFieldSelect={handleFieldChange}\n />\n </Box>\n );\n}\n","'use client';\n\nimport SearchIcon from '@mui/icons-material/Search';\nimport {\n Box,\n Button,\n Checkbox,\n Divider,\n InputAdornment,\n ListSubheader,\n Menu,\n MenuItem,\n TextField,\n} from '@mui/material';\nimport React, { useMemo, useState } from 'react';\n\nimport type {\n MultiSelectDropdownProps,\n MultiSelectExtraOption,\n MultiSelectOption,\n} from './ContentToolbar.types';\nimport { buildTriggerLabel, InlineTrigger, PillTrigger, StackedTrigger } from './MultiSelectTriggers';\n\n/** One checkbox menu row with an optional trailing count. */\nfunction CheckboxRow({\n label,\n count,\n checked,\n onToggle,\n}: {\n label: string;\n count?: number;\n checked: boolean;\n onToggle: (next: boolean) => void;\n}): React.JSX.Element {\n return (\n <MenuItem onClick={() => onToggle(!checked)} sx={{ gap: 1 }}>\n <Checkbox checked={checked} size=\"small\" disableRipple sx={{ p: 0, pointerEvents: 'none' }} tabIndex={-1} />\n <Box component=\"span\" sx={{ flex: 1, minWidth: 0, textAlign: 'left' }}>\n {label}\n {count != null && (\n <Box component=\"span\" sx={{ color: 'text.secondary' }}>\n {' '}\n ({count})\n </Box>\n )}\n </Box>\n </MenuItem>\n );\n}\n\n/**\n * Generic multi-select dropdown with checkboxes, counts, an optional \"Options\"\n * section, and a \"Clear\" action. Faithful MUI port of the reference toolbar's\n * \"Content Type\" control. The menu stays open while toggling options.\n */\nexport function MultiSelectDropdown<TValue extends string = string>({\n label,\n options,\n selected,\n onToggle,\n onClear,\n allLabel = 'All',\n clearLabel,\n extraOptions,\n searchable,\n searchPlaceholder = 'Search…',\n noResultsLabel = 'No results',\n layout = 'inline',\n 'data-testid': testId,\n onOpenChange,\n}: MultiSelectDropdownProps<TValue>): React.JSX.Element {\n const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);\n const [query, setQuery] = useState('');\n const open = Boolean(anchorEl);\n const stacked = layout === 'stacked';\n // Reset the query each time the menu closes so it reopens showing everything.\n const close = (): void => {\n setAnchorEl(null);\n setQuery('');\n onOpenChange?.(false);\n };\n const triggerLabel = buildTriggerLabel(selected, options, allLabel);\n // Auto-enable search for long lists (e.g. many categories) unless overridden.\n const showSearch = searchable ?? options.length > 8;\n const anyExtraChecked = extraOptions?.some((option) => option.checked) ?? false;\n const clearDisabled = selected.size === 0 && !anyExtraChecked;\n\n const openMenu = (event: React.MouseEvent<HTMLElement>): void => {\n setAnchorEl(event.currentTarget);\n onOpenChange?.(true);\n };\n const triggerProps = { triggerLabel, open, onOpen: openMenu, testId };\n\n const renderTrigger = (): React.JSX.Element => {\n if (stacked) return <StackedTrigger label={label} {...triggerProps} />;\n if (layout === 'pill')\n return (\n <PillTrigger\n clearLabel={clearLabel}\n label={label}\n selectedCount={selected.size}\n onClear={onClear}\n {...triggerProps}\n />\n );\n return <InlineTrigger label={label} {...triggerProps} />;\n };\n\n return (\n <>\n {renderTrigger()}\n <MultiSelectMenu\n anchorEl={anchorEl}\n open={open}\n close={close}\n options={options}\n selected={selected}\n onToggle={onToggle}\n extraOptions={extraOptions}\n clearDisabled={clearDisabled}\n onClear={onClear}\n showSearch={showSearch}\n query={query}\n onQueryChange={setQuery}\n searchPlaceholder={searchPlaceholder}\n noResultsLabel={noResultsLabel}\n matchAnchorWidth={stacked}\n testId={testId}\n />\n </>\n );\n}\n\n/** Sticky search box at the top of the menu; keydowns don't reach the Menu's typeahead. */\nfunction MenuSearchField({\n query,\n onQueryChange,\n placeholder,\n testId,\n}: {\n query: string;\n onQueryChange: (value: string) => void;\n placeholder: string;\n testId?: string;\n}): React.JSX.Element {\n return (\n <Box\n sx={{ position: 'sticky', top: 0, zIndex: 1, bgcolor: 'background.paper', px: 1, py: 0.75 }}\n onKeyDown={(event) => event.stopPropagation()}\n >\n <TextField\n autoFocus\n size=\"small\"\n fullWidth\n value={query}\n onChange={(event) => onQueryChange(event.target.value)}\n placeholder={placeholder}\n inputProps={{ 'aria-label': placeholder, 'data-testid': testId ? `${testId}-search` : undefined }}\n InputProps={{\n startAdornment: (\n <InputAdornment position=\"start\">\n <SearchIcon sx={{ fontSize: 16 }} />\n </InputAdornment>\n ),\n }}\n />\n </Box>\n );\n}\n\ninterface MultiSelectMenuProps<TValue extends string> {\n anchorEl: HTMLElement | null;\n open: boolean;\n close: () => void;\n options: MultiSelectOption<TValue>[];\n selected: ReadonlySet<TValue>;\n onToggle: (value: TValue, checked: boolean) => void;\n extraOptions?: MultiSelectExtraOption[];\n clearDisabled: boolean;\n onClear: () => void;\n showSearch: boolean;\n query: string;\n onQueryChange: (value: string) => void;\n searchPlaceholder: string;\n noResultsLabel: string;\n /** Match the menu width to the trigger and left-align it (stacked select). */\n matchAnchorWidth?: boolean;\n testId?: string;\n}\n\n/**\n * Menu placement. Default: anchored to the trigger's right (toolbar). When\n * `matchAnchorWidth` (stacked select), match the trigger width and left-align so\n * the menu sits flush under the full-width control.\n */\nfunction resolveMenuPlacement(\n matchAnchorWidth: boolean | undefined,\n anchorEl: HTMLElement | null,\n): { anchorWidth: number | undefined; align: 'left' | 'right' } {\n if (!matchAnchorWidth) return { anchorWidth: undefined, align: 'right' };\n return { anchorWidth: anchorEl?.offsetWidth, align: 'left' };\n}\n\n/** The (optional) search box + checkbox list + optional \"Options\" section + a \"Clear\" footer. */\nfunction MultiSelectMenu<TValue extends string>({\n anchorEl,\n open,\n close,\n options,\n selected,\n onToggle,\n extraOptions,\n clearDisabled,\n onClear,\n showSearch,\n query,\n onQueryChange,\n searchPlaceholder,\n noResultsLabel,\n matchAnchorWidth,\n testId,\n}: MultiSelectMenuProps<TValue>): React.JSX.Element {\n const trimmed = query.trim().toLowerCase();\n const visibleOptions = useMemo(\n () => (trimmed ? options.filter((option) => option.label.toLowerCase().includes(trimmed)) : options),\n [options, trimmed],\n );\n const { anchorWidth, align } = resolveMenuPlacement(matchAnchorWidth, anchorEl);\n return (\n <Menu\n anchorEl={anchorEl}\n open={open}\n onClose={close}\n anchorOrigin={{ vertical: 'bottom', horizontal: align }}\n transformOrigin={{ vertical: 'top', horizontal: align }}\n // Keep focus on the search box (don't let the Menu grab the first item),\n // and stop MUI's typeahead from swallowing keystrokes meant for the input.\n autoFocus={!showSearch}\n disableAutoFocusItem\n slotProps={{\n // Cap the height so a long list (e.g. many categories) scrolls instead\n // of running off-screen; the sticky search box stays pinned on top.\n paper: { sx: { minWidth: anchorWidth ?? 180, width: anchorWidth, maxHeight: 360 } },\n list: { sx: { pt: showSearch ? 0 : undefined, pb: 0 } },\n }}\n >\n {showSearch && (\n <MenuSearchField query={query} onQueryChange={onQueryChange} placeholder={searchPlaceholder} testId={testId} />\n )}\n {visibleOptions.length === 0 && showSearch ? (\n <MenuItem disabled data-testid={testId ? `${testId}-no-results` : undefined} sx={{ fontSize: '0.8125rem' }}>\n {noResultsLabel}\n </MenuItem>\n ) : (\n visibleOptions.map((option) => (\n <CheckboxRow\n key={option.value}\n label={option.label}\n count={option.count}\n checked={selected.has(option.value)}\n onToggle={(next) => onToggle(option.value, next)}\n />\n ))\n )}\n {extraOptions && extraOptions.length > 0\n ? [\n <Divider key=\"extra-divider\" />,\n <ListSubheader key=\"extra-label\" sx={{ px: 1, py: 0.75, fontSize: '0.75rem', fontWeight: 600 }}>\n Options\n </ListSubheader>,\n ...extraOptions.map((extra) => (\n <CheckboxRow key={extra.id} label={extra.label} checked={extra.checked} onToggle={(next) => extra.onCheckedChange(next)} />\n )),\n ]\n : null}\n <MenuClearFooter clearDisabled={clearDisabled} onClear={onClear} close={close} testId={testId} />\n </Menu>\n );\n}\n\n/** The bottom \"Clear\" footer that resets the selection and closes the menu. */\nfunction MenuClearFooter({\n clearDisabled,\n onClear,\n close,\n testId,\n}: {\n clearDisabled: boolean;\n onClear: () => void;\n close: () => void;\n testId?: string;\n}): React.JSX.Element {\n return (\n <Box\n sx={{\n // Pin to the bottom of the scroll viewport so it stays visible while the\n // options list scrolls (mirrors the sticky search box on top).\n position: 'sticky',\n bottom: 0,\n zIndex: 1,\n display: 'flex',\n justifyContent: 'flex-end',\n borderTop: 1,\n borderColor: 'divider',\n bgcolor: 'background.paper',\n px: 1,\n py: 0.75,\n }}\n >\n <Button\n variant=\"text\"\n size=\"small\"\n color=\"inherit\"\n data-testid={testId ? `${testId}-clear` : undefined}\n disabled={clearDisabled}\n onClick={() => {\n onClear();\n close();\n }}\n sx={{ minWidth: 0, px: 1, py: 0.25, fontSize: '0.75rem', fontWeight: 400, textTransform: 'none', color: 'text.secondary' }}\n >\n Clear\n </Button>\n </Box>\n );\n}\n","'use client';\n\nimport CloseIcon from '@mui/icons-material/Close';\nimport ChevronDownIcon from '@mui/icons-material/KeyboardArrowDown';\nimport { Box, Button, Typography } from '@mui/material';\nimport React, { useId } from 'react';\n\nimport type { MultiSelectOption } from './ContentToolbar.types';\n\n/**\n * Trigger label from the current selection: `allLabel` when none/all are\n * selected, the single label when one, else \"first (+N)\". Uses Set iteration\n * order so the label reflects the first-clicked option.\n */\nexport function buildTriggerLabel<TValue extends string>(\n selected: ReadonlySet<TValue>,\n options: MultiSelectOption<TValue>[],\n allLabel: string,\n): string {\n const size = selected.size;\n if (size === 0 || size === options.length) return allLabel;\n const labelMap = new Map(options.map((option) => [option.value, option.label]));\n const firstValue = selected.values().next().value as TValue;\n const firstLabel = labelMap.get(firstValue) ?? allLabel;\n if (size === 1) return firstLabel;\n return `${firstLabel} (+${size - 1})`;\n}\n\nexport interface TriggerProps {\n label: string;\n triggerLabel: string;\n open: boolean;\n onOpen: (event: React.MouseEvent<HTMLElement>) => void;\n testId?: string;\n}\n\n/** Compact `Label:` text button for a horizontal toolbar (the default layout). */\nexport function InlineTrigger({ label, triggerLabel, open, onOpen, testId }: TriggerProps): React.JSX.Element {\n return (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, fontSize: '0.875rem' }}>\n <Typography component=\"span\" sx={{ color: 'text.secondary', fontSize: '0.875rem' }}>\n {label}:\n </Typography>\n <Button\n variant=\"text\"\n size=\"small\"\n color=\"inherit\"\n data-testid={testId}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n onClick={onOpen}\n sx={{ minWidth: 0, height: 32, px: 1, gap: 0.5, color: 'text.primary', textTransform: 'none', fontWeight: 600 }}\n >\n {triggerLabel}\n <ChevronDownIcon sx={{ fontSize: 14 }} />\n </Button>\n </Box>\n );\n}\n\n/** Full-width, outlined select-style control with the label above (stacked layout). */\nexport function StackedTrigger({ label, triggerLabel, open, onOpen, testId }: TriggerProps): React.JSX.Element {\n // Name the button by label + value (aria-labelledby): a <button> isn't labelable.\n const baseId = useId();\n return (\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>\n <Typography id={`${baseId}-label`} component=\"label\" sx={{ fontSize: '0.75rem', fontWeight: 500, color: 'text.secondary' }}>\n {label}\n </Typography>\n <Button\n variant=\"outlined\"\n color=\"inherit\"\n fullWidth\n data-testid={testId}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-labelledby={`${baseId}-label ${baseId}-value`}\n onClick={onOpen}\n endIcon={<ChevronDownIcon sx={{ fontSize: 18, color: 'text.secondary' }} />}\n sx={{\n justifyContent: 'space-between',\n height: 40,\n px: 1.5,\n color: 'text.primary',\n textTransform: 'none',\n fontWeight: 400,\n fontSize: '0.875rem',\n borderColor: 'divider',\n bgcolor: 'background.paper',\n '&:hover': { borderColor: 'text.primary', bgcolor: 'background.paper' },\n }}\n >\n <Box\n component=\"span\" id={`${baseId}-value`}\n sx={{ flex: 1, minWidth: 0, textAlign: 'left', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}\n >\n {triggerLabel}\n </Box>\n </Button>\n </Box>\n );\n}\n\n/** Rounded outlined chip (`Label ▾`, `Label (N) ▾` when selected) for a filter row. */\n/** The pill's own props, above the component so the signature stays short. */\nexport type PillTriggerProps = TriggerProps & {\n selectedCount: number;\n onClear?: () => void;\n /**\n * The clear affordance's accessible name — the pill's own label is already\n * on screen, so this is the only thing a screen reader gets for the little\n * cross. REQUIRED: this package ships no default copy.\n */\n clearLabel: string;\n};\n\nexport function PillTrigger({\n label,\n open,\n onOpen,\n testId,\n selectedCount,\n onClear,\n clearLabel,\n}: PillTriggerProps): React.JSX.Element {\n const active = selectedCount > 0;\n return (\n <Button\n variant=\"outlined\"\n color=\"inherit\"\n size=\"small\"\n data-testid={testId}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n onClick={onOpen}\n // Clearing lives ON the pill: the filter and the way to remove it are one\n // control, so removing one does not mean finding it again in a second\n // list somewhere else on the page.\n startIcon={\n active && onClear ? (\n <Box\n component=\"span\"\n role=\"button\"\n tabIndex={0}\n aria-label={clearLabel}\n data-testid={testId ? `${testId}-clear` : undefined}\n onClick={(event: React.MouseEvent) => {\n // The pill's own click opens the menu; clearing must not.\n event.stopPropagation();\n onClear();\n }}\n onKeyDown={(event: React.KeyboardEvent) => {\n if (event.key !== 'Enter' && event.key !== ' ') return;\n event.preventDefault();\n event.stopPropagation();\n onClear();\n }}\n sx={{\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: '50%',\n cursor: 'pointer',\n color: 'primary.main',\n '&:hover': { bgcolor: 'primary.main', color: 'primary.contrastText' },\n }}\n >\n <CloseIcon sx={{ fontSize: 14 }} />\n </Box>\n ) : undefined\n }\n endIcon={<ChevronDownIcon sx={{ fontSize: 16 }} />}\n sx={{\n borderRadius: 999,\n height: 34,\n px: 1.5,\n color: 'text.primary',\n fontWeight: 600,\n fontSize: '0.8125rem',\n textTransform: 'none',\n borderColor: active ? 'primary.main' : 'divider',\n bgcolor: active ? 'action.selected' : 'background.paper',\n '&:hover': { borderColor: active ? 'primary.main' : 'text.primary', bgcolor: active ? 'action.selected' : 'action.hover' },\n }}\n >\n {label}\n {active ? ` (${selectedCount})` : ''}\n </Button>\n );\n}\n","'use client';\n\nimport FilterIcon from '@mui/icons-material/FilterListRounded';\nimport { Box, Button } from '@mui/material';\nimport React from 'react';\n\nimport type { FilterTriggerProps } from './ContentToolbar.types';\n\n/**\n * Labeled filter toggle: a \"Filtros\" button (styled like the sibling toolbar\n * controls) with a funnel icon and, when filters are active, a count badge — so\n * it's obvious that the list is filtered and by how many facets. The panel itself\n * is supplied by the consumer.\n */\nexport function FilterTrigger({\n open,\n onOpenChange,\n hasActiveFilters = false,\n activeCount = 0,\n label = 'Filtros',\n 'data-testid': testId = 'toggle-filters-btn',\n}: FilterTriggerProps): React.JSX.Element {\n const active = activeCount > 0 || hasActiveFilters;\n return (\n <Button\n variant=\"text\"\n size=\"small\"\n color=\"inherit\"\n data-testid={testId}\n aria-expanded={open}\n aria-label={open ? 'Close filters' : 'Open filters'}\n onClick={() => onOpenChange(!open)}\n startIcon={<FilterIcon sx={{ fontSize: 16 }} />}\n sx={{\n minWidth: 0,\n height: 32,\n px: 1,\n gap: 0.25,\n textTransform: 'none',\n fontWeight: 600,\n color: active ? 'primary.main' : 'text.primary',\n bgcolor: open ? 'action.selected' : 'transparent',\n }}\n >\n {label}\n {activeCount > 0 && (\n <Box\n component=\"span\"\n data-testid={`${testId}-count`}\n sx={{\n ml: 0.5,\n minWidth: 18,\n height: 18,\n px: 0.5,\n borderRadius: 999,\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '0.7rem',\n fontWeight: 700,\n lineHeight: 1,\n bgcolor: 'primary.main',\n color: 'primary.contrastText',\n }}\n >\n {activeCount}\n </Box>\n )}\n </Button>\n );\n}\n","'use client';\n\nimport ColumnsIcon from '@mui/icons-material/ViewColumnRounded';\nimport { Box, Checkbox, IconButton, ListSubheader, Menu, MenuItem } from '@mui/material';\nimport React, { useState } from 'react';\n\nimport type { ColumnVisibilityOption, ColumnsMenuProps } from './ContentToolbar.types';\n\n/** One column checkbox row; toggling never closes the menu. */\nfunction ColumnRow({\n option,\n onToggle,\n testId,\n}: {\n option: ColumnVisibilityOption;\n onToggle: (id: string, visible: boolean) => void;\n testId?: string;\n}): React.JSX.Element {\n return (\n <MenuItem\n data-testid={testId}\n onClick={() => onToggle(option.id, !option.visible)}\n disabled={option.locked}\n sx={{ gap: 1 }}\n >\n <Checkbox\n checked={option.visible}\n size=\"small\"\n disableRipple\n sx={{ p: 0, pointerEvents: 'none' }}\n tabIndex={-1}\n />\n <Box component=\"span\" sx={{ flex: 1, minWidth: 0, textAlign: 'left' }}>\n {option.label}\n </Box>\n </MenuItem>\n );\n}\n\n/**\n * Stateless column-visibility selector: a neutral icon button (matching\n * {@link FilterTrigger}/{@link SortByDropdown}) opening a checkbox list of the\n * hideable columns. Purely presentational — the caller owns the visibility state\n * and is notified via `onToggle`. The menu stays open while toggling so several\n * columns can be flipped at once.\n */\nexport function ColumnsMenu({\n columns,\n onToggle,\n title = 'Columns',\n ariaLabel = 'Toggle columns',\n 'data-testid': testId,\n}: ColumnsMenuProps): React.JSX.Element {\n const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);\n const open = Boolean(anchorEl);\n const close = (): void => setAnchorEl(null);\n\n return (\n <>\n <IconButton\n size=\"small\"\n data-testid={testId}\n aria-label={ariaLabel}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n onClick={(event) => setAnchorEl(event.currentTarget)}\n sx={{\n width: 32,\n height: 32,\n borderRadius: 1,\n color: 'text.secondary',\n bgcolor: open ? 'action.selected' : 'transparent',\n }}\n >\n <ColumnsIcon sx={{ fontSize: 16 }} />\n </IconButton>\n <Menu\n anchorEl={anchorEl}\n open={open}\n onClose={close}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n transformOrigin={{ vertical: 'top', horizontal: 'right' }}\n slotProps={{ paper: { sx: { minWidth: 200 } } }}\n >\n <ListSubheader sx={{ px: 1.5, py: 0.75, fontSize: '0.75rem', fontWeight: 600, color: 'text.primary', lineHeight: 1.5 }}>\n {title}\n </ListSubheader>\n {columns.map((option) => (\n <ColumnRow\n key={option.id}\n option={option}\n onToggle={onToggle}\n testId={testId ? `${testId}-${option.id}` : undefined}\n />\n ))}\n </Menu>\n </>\n );\n}\n","'use client';\n\nimport CheckIcon from '@mui/icons-material/Check';\nimport ChevronDownIcon from '@mui/icons-material/KeyboardArrowDown';\nimport KebabIcon from '@mui/icons-material/MoreVert';\nimport ViewIcon from '@mui/icons-material/Visibility';\nimport { Box, Button, IconButton, Menu, MenuItem, Popover, Stack, Typography } from '@mui/material';\nimport React, { useState } from 'react';\n\nimport type {\n SavedViewLike,\n SavedViewsLabels,\n SavedViewsMenuProps,\n} from './ContentToolbar.types';\n\n/** How many non-pinned views show under \"Recentes\". */\nconst RECENT_LIMIT = 5;\n\ninterface RowHandlers<V extends SavedViewLike> {\n apply: (view: V) => void;\n onEdit: (view: V) => void;\n onDelete: (view: V) => void;\n onSetDefault: (view: V) => void;\n onTogglePin: (view: V) => void;\n onToggleShare: (view: V) => void;\n}\n\nfunction DefaultTag({ label, testId }: { label: string; testId: string }): React.JSX.Element {\n return (\n <Box\n component=\"span\"\n data-testid={testId}\n sx={{ px: 0.75, py: 0.125, borderRadius: 1, fontSize: '0.7rem', bgcolor: 'primary.main', color: 'primary.contrastText' }}\n >\n {label}\n </Box>\n );\n}\n\ninterface KebabAction {\n id: string;\n label: string;\n danger?: boolean;\n run: () => void;\n}\n\n/** Build the per-view ⋮ actions; owner-only mutations follow \"Apply\". */\nfunction buildActions<V extends SavedViewLike>(\n view: V,\n handlers: RowHandlers<V>,\n labels: SavedViewsLabels,\n): KebabAction[] {\n const actions: KebabAction[] = [{ id: 'apply', label: labels.apply, run: () => handlers.apply(view) }];\n if (!view.isOwner) return actions;\n if (!view.isDefault) {\n actions.push({ id: 'default', label: labels.setDefault, run: () => handlers.onSetDefault(view) });\n }\n actions.push({ id: 'pin', label: view.pinned ? labels.unpin : labels.pin, run: () => handlers.onTogglePin(view) });\n actions.push({ id: 'share', label: view.shared ? labels.unshare : labels.share, run: () => handlers.onToggleShare(view) });\n actions.push({ id: 'edit', label: labels.edit, run: () => handlers.onEdit(view) });\n actions.push({ id: 'delete', label: labels.remove, danger: true, run: () => handlers.onDelete(view) });\n return actions;\n}\n\nfunction ViewKebab<V extends SavedViewLike>({\n view,\n handlers,\n labels,\n testIdPrefix,\n}: {\n view: V;\n handlers: RowHandlers<V>;\n labels: SavedViewsLabels;\n testIdPrefix: string;\n}): React.JSX.Element {\n const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);\n const close = (): void => setAnchorEl(null);\n return (\n <>\n <IconButton\n size=\"small\"\n aria-label={`${labels.apply} ${view.name}`}\n data-testid={`${testIdPrefix}-kebab-${view.id}`}\n onClick={(event) => setAnchorEl(event.currentTarget)}\n sx={{ width: 28, height: 28, color: 'text.secondary' }}\n >\n <KebabIcon sx={{ fontSize: 16 }} />\n </IconButton>\n <Menu anchorEl={anchorEl} open={Boolean(anchorEl)} onClose={close}>\n {buildActions(view, handlers, labels).map((action) => (\n <MenuItem\n key={action.id}\n data-testid={`${testIdPrefix}-item-${action.id}-${view.id}`}\n onClick={() => {\n action.run();\n close();\n }}\n sx={action.danger ? { color: 'error.main' } : undefined}\n >\n {action.label}\n </MenuItem>\n ))}\n </Menu>\n </>\n );\n}\n\nfunction ViewRow<V extends SavedViewLike>({\n view,\n handlers,\n labels,\n testIdPrefix,\n}: {\n view: V;\n handlers: RowHandlers<V>;\n labels: SavedViewsLabels;\n testIdPrefix: string;\n}): React.JSX.Element {\n return (\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }} data-testid={`${testIdPrefix}-row-${view.id}`}>\n <Box\n onClick={() => handlers.apply(view)}\n sx={{ flex: 1, minWidth: 0, cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 0.75 }}\n data-testid={`${testIdPrefix}-apply-${view.id}`}\n >\n <Typography component=\"span\" sx={{ fontSize: '0.875rem' }}>\n {view.name}\n </Typography>\n {view.isDefault && <DefaultTag label={labels.defaultTag} testId={`${testIdPrefix}-default-${view.id}`} />}\n </Box>\n <ViewKebab view={view} handlers={handlers} labels={labels} testIdPrefix={testIdPrefix} />\n </Stack>\n );\n}\n\nfunction ViewSection<V extends SavedViewLike>({\n title,\n list,\n sectionKey,\n handlers,\n labels,\n testIdPrefix,\n}: {\n title: string;\n list: V[];\n sectionKey: string;\n handlers: RowHandlers<V>;\n labels: SavedViewsLabels;\n testIdPrefix: string;\n}): React.JSX.Element | null {\n if (list.length === 0) return null;\n return (\n <Box data-testid={`${testIdPrefix}-section-${sectionKey}`}>\n <Typography component=\"span\" sx={{ fontSize: '0.75rem', fontWeight: 600, color: 'text.secondary' }}>\n {title}\n </Typography>\n <Stack spacing={0.5} sx={{ mt: 0.5 }}>\n {list.map((view) => (\n <ViewRow key={view.id} view={view} handlers={handlers} labels={labels} testIdPrefix={testIdPrefix} />\n ))}\n </Stack>\n </Box>\n );\n}\n\n/** A borderless footer text button (Save current / Manage all). */\nfunction FooterButton({\n label,\n testId,\n onClick,\n}: {\n label: string;\n testId: string;\n onClick: () => void;\n}): React.JSX.Element {\n return (\n <Button variant=\"text\" size=\"small\" color=\"inherit\" onClick={onClick} data-testid={testId} sx={{ textTransform: 'none' }}>\n {label}\n </Button>\n );\n}\n\n/** The popover contents: the built-in Main vision default, saved-view sections, and footer. */\nfunction PopoverBody<V extends SavedViewLike>({\n views,\n pinned,\n recent,\n activeViewName,\n labels,\n handlers,\n onSelectMain,\n onSaveCurrent,\n onManageAll,\n testIdPrefix,\n}: {\n views: V[];\n pinned: V[];\n recent: V[];\n activeViewName?: string;\n labels: SavedViewsLabels;\n handlers: RowHandlers<V>;\n onSelectMain: () => void;\n onSaveCurrent: () => void;\n onManageAll: () => void;\n testIdPrefix: string;\n}): React.JSX.Element {\n return (\n <Stack spacing={1.5} sx={{ p: 1.5, width: 300 }} data-testid={`${testIdPrefix}-popover`}>\n {/* Built-in no-filter default, always available above the saved views. */}\n <MenuItem data-testid={`${testIdPrefix}-main`} selected={!activeViewName} onClick={onSelectMain} sx={{ borderRadius: 1, px: 1, gap: 1 }}>\n <Box component=\"span\" sx={{ flex: 1, minWidth: 0, fontSize: '0.875rem' }}>\n {labels.mainView}\n </Box>\n {!activeViewName && <CheckIcon sx={{ fontSize: 16, color: 'primary.main' }} />}\n </MenuItem>\n {views.length === 0 ? (\n <Typography sx={{ fontSize: '0.75rem', color: 'text.secondary' }}>{labels.empty}</Typography>\n ) : (\n <>\n <ViewSection title={labels.pinned} list={pinned} sectionKey=\"pinned\" handlers={handlers} labels={labels} testIdPrefix={testIdPrefix} />\n <ViewSection title={labels.recent} list={recent} sectionKey=\"recent\" handlers={handlers} labels={labels} testIdPrefix={testIdPrefix} />\n </>\n )}\n <Box sx={{ borderTop: 1, borderColor: 'divider', pt: 1 }}>\n <Stack spacing={0.5} sx={{ alignItems: 'flex-start' }}>\n <FooterButton label={labels.saveCurrent} testId={`${testIdPrefix}-save-current`} onClick={onSaveCurrent} />\n <FooterButton label={labels.manageAll} testId={`${testIdPrefix}-manage-all`} onClick={onManageAll} />\n </Stack>\n </Box>\n </Stack>\n );\n}\n\n/**\n * Stateless saved-views dropdown: a neutral trigger (styled like the sibling\n * toolbar controls) that shows `activeViewName` when a view is applied, else the\n * built-in \"Main vision\" label. The popover lists the Main vision default plus\n * pinned + recent views; a per-view ⋮ exposes owner-only mutations. This\n * component owns NO data — every action is a callback, so a page-level Connector\n * wires it to the backend.\n */\nexport function SavedViewsMenu<V extends SavedViewLike = SavedViewLike>({\n views,\n activeViewName,\n onApply,\n onSelectMain,\n onSaveCurrent,\n onEdit,\n onDelete,\n onSetDefault,\n onTogglePin,\n onToggleShare,\n onManageAll,\n labels: labelOverrides,\n testIdPrefix = 'views',\n}: SavedViewsMenuProps<V>): React.JSX.Element {\n const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);\n const close = (): void => setAnchorEl(null);\n const runAndClose = (action: () => void) => (): void => {\n action();\n close();\n };\n const labels = labelOverrides;\n const pinned = views.filter((view) => view.pinned);\n const recent = views.filter((view) => !view.pinned).slice(0, RECENT_LIMIT);\n\n const handlers: RowHandlers<V> = {\n apply: (view) => {\n onApply(view);\n close();\n },\n onEdit,\n onDelete,\n onSetDefault,\n onTogglePin,\n onToggleShare,\n };\n\n return (\n <>\n <Button\n variant=\"text\"\n size=\"small\"\n color=\"inherit\"\n onClick={(event) => setAnchorEl(event.currentTarget)}\n data-testid={`${testIdPrefix}-button`}\n aria-haspopup=\"menu\"\n aria-expanded={Boolean(anchorEl)}\n aria-label={activeViewName ?? labels.mainView}\n sx={{ minWidth: 0, height: 32, px: 1, gap: 0.5, color: 'text.primary', textTransform: 'none', fontWeight: 600 }}\n >\n {/* Mobile: an eye icon stands in for the view name to keep the toolbar one line. */}\n <ViewIcon sx={{ fontSize: 18, display: { xs: 'inline-flex', md: 'none' } }} />\n <Box component=\"span\" sx={{ display: { xs: 'none', md: 'inline' } }}>\n {activeViewName ?? labels.mainView}\n </Box>\n <ChevronDownIcon sx={{ fontSize: 14 }} />\n </Button>\n <Popover\n open={Boolean(anchorEl)}\n anchorEl={anchorEl}\n onClose={close}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n transformOrigin={{ vertical: 'top', horizontal: 'right' }}\n >\n <PopoverBody\n views={views}\n pinned={pinned}\n recent={recent}\n activeViewName={activeViewName}\n labels={labels}\n handlers={handlers}\n onSelectMain={runAndClose(onSelectMain)}\n onSaveCurrent={runAndClose(onSaveCurrent)}\n onManageAll={runAndClose(onManageAll)}\n testIdPrefix={testIdPrefix}\n />\n </Popover>\n </>\n );\n}\n"],"mappings":"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","names":["Box","Button","jsx","jsxs","CheckIcon","ChevronDownIcon","Box","Button","Divider","Menu","MenuItem","Typography","useState","jsx","jsxs","Box","Button","Checkbox","Divider","ListSubheader","Menu","MenuItem","useState","ChevronDownIcon","Box","Button","Typography","jsx","jsxs","buildTriggerLabel","Fragment","jsx","jsxs","MenuItem","Checkbox","Box","useState","buildTriggerLabel","Menu","Divider","ListSubheader","Button","Box","Button","jsx","jsxs","Box","Checkbox","ListSubheader","Menu","MenuItem","useState","Fragment","jsx","jsxs","CheckIcon","ChevronDownIcon","Box","Button","IconButton","Menu","MenuItem","Typography","useState","Fragment","jsx","jsxs"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/data-display/DataGrid/DataGrid.tsx","../src/components/data-display/DataGrid/DataGrid.body.tsx","../src/components/data-display/DataGrid/DataGrid.cells.tsx","../src/components/data-display/DataGrid/DataGrid.rows.ts","../src/components/data-display/DataGrid/DataGrid.model.ts","../src/components/data-display/DataGrid/DataGrid.states.tsx"],"sourcesContent":["/**\n * `DataGrid` — the shell.\n *\n * Everything that is not \"which of the four renders is this, and what wraps the\n * table\" lives beside it: the state in `DataGrid.model.ts`, the client-mode row\n * pipeline in `DataGrid.rows.ts`, the cells and rows in `DataGrid.cells.tsx`,\n * the head/body in `DataGrid.body.tsx`, and the loading/error/empty renders in\n * `DataGrid.states.tsx`.\n *\n * All FOUR renders carry the caller's `data-testid`. It used to be applied only\n * on the populated one, so a grid whose first paint had no rows could not be\n * found by a test at all — see `DataGrid.states.tsx` for the full story.\n */\nimport { Paper, Table, TableContainer } from '@mui/material';\nimport type React from 'react';\n\nimport { GridBody, GridHeader } from './DataGrid.body';\nimport { useDataGridModel } from './DataGrid.model';\nimport { DataGridEmpty, DataGridError, DataGridLoading } from './DataGrid.states';\nimport type { DataGridProps } from './DataGrid.types';\n\n/**\n * The chrome every render needs, with the defaults resolved ONCE.\n *\n * Extracted from the component body because a dozen destructuring defaults are\n * a dozen branches: the gate counted them, correctly, as complexity the render\n * did not need to carry.\n */\nfunction resolveChrome<T extends Record<string, unknown>>(props: DataGridProps<T>): {\n dataAttrs: Record<string, unknown>;\n placeholder: {\n dataTestId?: string;\n ariaLabel: string;\n className?: string;\n style?: React.CSSProperties;\n htmlProps: React.HTMLAttributes<HTMLElement>;\n };\n} {\n const { className, style, 'data-testid': dataTestId, ...rest } = props;\n const stickyHeader = props.stickyHeader ?? true;\n return {\n dataAttrs: {\n 'data-ui': 'datagrid',\n 'data-density': props.density ?? 'comfortable',\n 'data-size-mode': props.sizeMode ?? 'auto',\n 'data-virtual-rows': props.virtualizeRows ?? true,\n 'data-virtual-cols': props.virtualizeColumns ?? false,\n 'data-sticky-header': stickyHeader,\n },\n placeholder: {\n dataTestId,\n ariaLabel: props.ariaLabel ?? 'Data grid',\n className,\n style,\n // Only the DOM-safe leftovers reach the element: every grid-specific prop\n // is named in `GRID_ONLY_PROPS`, so this cannot smuggle `rows` onto a div.\n htmlProps: omitGridProps(rest as Record<string, unknown>),\n },\n };\n}\n\nexport const DataGrid = <T extends Record<string, unknown> = Record<string, unknown>>(\n props: DataGridProps<T>,\n): React.JSX.Element => {\n const model = useDataGridModel(props);\n const { dataAttrs, placeholder } = resolveChrome(props);\n\n if (props.loading) return <DataGridLoading {...placeholder} />;\n if (props.error) return <DataGridError {...placeholder} error={props.error} />;\n if (model.processedRows.length === 0) {\n return <DataGridEmpty {...placeholder} emptyState={props.emptyState} />;\n }\n\n const leadingColumns = (props.selection?.mode ?? 'none') !== 'none' ? 1 : 0;\n const totalColumns =\n model.visibleColumns.length + leadingColumns + (props.expansion ? 1 : 0);\n const section = { model, props, totalColumns };\n\n return (\n <Paper\n ref={model.containerRef}\n {...dataAttrs}\n data-testid={placeholder.dataTestId}\n className={placeholder.className}\n style={placeholder.style}\n role=\"grid\"\n aria-label={placeholder.ariaLabel}\n aria-description={props.ariaDescription}\n aria-rowcount={model.processedRows.length + 1} // +1 for the header row\n aria-colcount={totalColumns}\n sx={{ height: '100%', overflow: 'hidden', display: 'flex', flexDirection: 'column' }}\n {...placeholder.htmlProps}\n >\n <TableContainer\n sx={{ flex: 1, overflow: 'auto', position: 'relative' }}\n onScroll={model.onScroll}\n >\n <Table stickyHeader={props.stickyHeader ?? true}>\n <GridHeader {...section} />\n <GridBody {...section} />\n </Table>\n </TableContainer>\n </Paper>\n );\n};\n\n/**\n * The grid props that are NOT HTML attributes.\n *\n * `DataGridProps` extends `HTMLAttributes`, so the rest-spread carries the\n * grid's own configuration too. React would warn (or worse, serialize an array\n * of rows into an attribute) if any of it reached the DOM.\n */\nconst GRID_ONLY_PROPS = [\n 'rows',\n 'columns',\n 'getRowId',\n 'sizeMode',\n 'density',\n 'rowHeight',\n 'headerHeight',\n 'footerHeight',\n 'selection',\n 'pagination',\n 'sorting',\n 'filtering',\n 'expansion',\n 'editing',\n 'virtualizeRows',\n 'virtualizeColumns',\n 'stickyHeader',\n 'stickyFooter',\n 'loading',\n 'error',\n 'emptyState',\n 'onRequestData',\n 'ariaLabel',\n 'ariaDescription',\n] as const;\n\nfunction omitGridProps(rest: Record<string, unknown>): React.HTMLAttributes<HTMLElement> {\n const html: Record<string, unknown> = { ...rest };\n for (const key of GRID_ONLY_PROPS) delete html[key];\n return html as React.HTMLAttributes<HTMLElement>;\n}\n\nDataGrid.displayName = 'DataGrid';\n","/**\n * The DataGrid's `<thead>` and `<tbody>`.\n *\n * Split from the shell so each stays inside the size budget and so the\n * virtualization spacers — which are pure layout, not data — sit next to the\n * rows they pad rather than in the middle of the component that owns the paper.\n */\nimport { Checkbox, TableBody, TableCell, TableHead, TableRow, useTheme } from '@mui/material';\nimport type React from 'react';\n\nimport { GridRow, HeaderCell } from './DataGrid.cells';\nimport type { DataGridModel } from './DataGrid.model';\nimport type { DataGridProps } from './DataGrid.types';\n\nexport interface GridSectionProps<T extends Record<string, unknown>> {\n model: DataGridModel<T>;\n props: DataGridProps<T>;\n totalColumns: number;\n}\n\n/** The leading header cells for the selection / expansion columns. */\nfunction HeaderControls<T extends Record<string, unknown>>({\n model,\n props,\n}: GridSectionProps<T>): React.JSX.Element {\n const theme = useTheme();\n const { selection = { mode: 'none' }, expansion, stickyHeader = true } = props;\n const sticky = {\n position: stickyHeader ? ('sticky' as const) : ('static' as const),\n top: 0,\n zIndex: 1,\n backgroundColor: theme.palette.background.paper,\n };\n const total = model.processedRows.length;\n const picked = model.selectedRowIds.length;\n return (\n <>\n {selection.mode !== 'none' && (\n <TableCell padding=\"checkbox\" sx={sticky}>\n {selection.mode === 'multi' && (\n <Checkbox\n indeterminate={picked > 0 && picked < total}\n checked={total > 0 && picked === total}\n onChange={(event) =>\n model.setSelectedRowIds(\n event.target.checked\n ? model.processedRows.map((row, index) => rowIdOf(props, row, index))\n : [],\n )\n }\n inputProps={{ 'aria-label': 'Select all rows' }}\n />\n )}\n </TableCell>\n )}\n {expansion && <TableCell padding=\"checkbox\" sx={sticky} />}\n </>\n );\n}\n\n/** The caller's `getRowId`, or the row's own `id`, or its index. */\nexport function rowIdOf<T extends Record<string, unknown>>(\n props: DataGridProps<T>,\n row: T,\n index: number,\n): string | number {\n if (props.getRowId) return props.getRowId(row, index);\n const candidate = (row as { id?: string | number }).id;\n return candidate ?? index;\n}\n\nexport function GridHeader<T extends Record<string, unknown>>(\n section: GridSectionProps<T>,\n): React.JSX.Element {\n const { model, props } = section;\n const { sorting = {}, stickyHeader = true, headerHeight = 56 } = props;\n const sortable = sorting.mode === 'client' || sorting.mode === 'server';\n return (\n <TableHead data-slot=\"header\">\n <TableRow data-slot=\"header-row\" role=\"row\">\n <HeaderControls {...section} />\n {model.visibleColumns.map((column) => (\n <HeaderCell\n key={column.id}\n column={column}\n sort={model.sortBy.find((entry) => entry.id === column.id)}\n sortable={column.enableSort !== false && sortable}\n stickyHeader={stickyHeader}\n headerHeight={headerHeight}\n onSort={model.onSort}\n />\n ))}\n </TableRow>\n </TableHead>\n );\n}\n\n/** An invisible row standing in for the rows the window is not rendering. */\nfunction Spacer({ height, colSpan }: { height: number; colSpan: number }): React.JSX.Element | null {\n if (height <= 0) return null;\n return (\n <TableRow>\n <TableCell colSpan={colSpan} sx={{ height, border: 'none', p: 0 }} />\n </TableRow>\n );\n}\n\nexport function GridBody<T extends Record<string, unknown>>(\n section: GridSectionProps<T>,\n): React.JSX.Element {\n const { model, props, totalColumns } = section;\n const { start, end } = model.visibleRange;\n const trailing = model.virtualized ? model.processedRows.length - end : 0;\n return (\n <TableBody data-slot=\"body\">\n {model.virtualized ? (\n <Spacer height={start * model.rowHeight} colSpan={totalColumns} />\n ) : null}\n {model.visibleRows.map((row, offset) => {\n const index = model.virtualized ? start + offset : offset;\n const rowId = rowIdOf(props, row, index);\n return (\n <GridRow\n key={rowId}\n row={row}\n index={index}\n rowId={rowId}\n isSelected={model.selectedRowIdsSet.has(rowId)}\n isExpanded={model.expandedRowIdsSet.has(rowId)}\n totalColumns={totalColumns}\n model={model}\n props={props}\n />\n );\n })}\n {model.virtualized ? (\n <Spacer height={trailing * model.rowHeight} colSpan={totalColumns} />\n ) : null}\n </TableBody>\n );\n}\n","/**\n * The DataGrid's cell and row renderers.\n *\n * Components rather than closures over the grid's scope: as inline `render*`\n * functions they could reach every piece of the component's state, which is how\n * the body grew past 700 lines. Each one now states exactly what it needs.\n */\nimport ArrowDownward from '@mui/icons-material/ArrowDownward';\nimport ArrowUpward from '@mui/icons-material/ArrowUpward';\nimport ExpandLess from '@mui/icons-material/ExpandLess';\nimport ExpandMore from '@mui/icons-material/ExpandMore';\nimport UnfoldMore from '@mui/icons-material/UnfoldMore';\nimport { Button, Checkbox, IconButton, TableCell, TableRow, Typography, useTheme } from '@mui/material';\nimport React from 'react';\n\nimport { cellValue } from './DataGrid.rows';\nimport type { DataGridModel } from './DataGrid.model';\nimport type { DataGridProps, GridColumn, GridSort } from './DataGrid.types';\n\n/** The glyph for a column's current sort state — unsorted included. */\nfunction SortIcon({ dir }: { dir: GridSort['dir'] | undefined }): React.JSX.Element {\n if (!dir) return <UnfoldMore fontSize=\"small\" sx={{ opacity: 0.5 }} />;\n return dir === 'asc' ? <ArrowUpward fontSize=\"small\" /> : <ArrowDownward fontSize=\"small\" />;\n}\n\n/** `aria-sort`'s three values, which are not the same words as `SortDirection`. */\nfunction ariaSort(dir: GridSort['dir'] | undefined): 'none' | 'ascending' | 'descending' {\n if (!dir) return 'none';\n return dir === 'asc' ? 'ascending' : 'descending';\n}\n\nexport interface HeaderCellProps<T extends Record<string, unknown>> {\n column: GridColumn<T>;\n sort: GridSort | undefined;\n sortable: boolean;\n stickyHeader: boolean;\n headerHeight: number;\n onSort: (columnId: string) => void;\n}\n\nexport function HeaderCell<T extends Record<string, unknown>>({\n column,\n sort,\n sortable,\n stickyHeader,\n headerHeight,\n onSort,\n}: HeaderCellProps<T>): React.JSX.Element {\n const theme = useTheme();\n const content = column.headerCell ? column.headerCell(column) : column.header;\n return (\n <TableCell\n data-slot=\"header-cell\"\n data-sort={sort?.dir ?? 'none'}\n sx={{\n position: stickyHeader ? 'sticky' : 'static',\n top: 0,\n zIndex: 1,\n backgroundColor: theme.palette.background.paper,\n borderBottom: `1px solid ${theme.palette.divider}`,\n height: headerHeight,\n minWidth: column.minWidth,\n maxWidth: column.maxWidth,\n width: column.width,\n }}\n role=\"columnheader\"\n aria-sort={ariaSort(sort?.dir)}\n >\n {sortable ? (\n <Button\n onClick={() => onSort(column.id)}\n sx={{\n justifyContent: 'flex-start',\n textTransform: 'none',\n fontWeight: 500,\n color: 'inherit',\n p: 0,\n minWidth: 0,\n '&:hover': { backgroundColor: 'transparent', opacity: 0.8 },\n }}\n endIcon={<SortIcon dir={sort?.dir} />}\n aria-label={column.ariaLabel ?? `Sort by ${String(column.header)}`}\n >\n {content}\n </Button>\n ) : (\n <Typography variant=\"subtitle2\" fontWeight={500}>\n {content}\n </Typography>\n )}\n </TableCell>\n );\n}\n\nexport interface DataCellProps<T extends Record<string, unknown>> {\n row: T;\n rowIndex: number;\n rowId: string | number;\n column: GridColumn<T>;\n rowHeight: number;\n editing: NonNullable<DataGridProps<T>['editing']>;\n model: Pick<DataGridModel<T>, 'editingCell' | 'setEditingCell'>;\n}\n\nexport function DataCell<T extends Record<string, unknown>>({\n row,\n rowIndex,\n rowId,\n column,\n rowHeight,\n editing,\n model,\n}: DataCellProps<T>): React.JSX.Element {\n const value = cellValue(row, column);\n const isEditing =\n model.editingCell?.rowId === rowId && model.editingCell?.colId === column.id;\n const content = column.cell\n ? column.cell({ value, row, rowIndex, col: column })\n : String(value ?? '');\n return (\n <TableCell\n data-slot=\"cell\"\n data-col-id={column.id}\n data-editing={isEditing}\n sx={{\n minWidth: column.minWidth,\n maxWidth: column.maxWidth,\n width: column.width,\n height: rowHeight,\n }}\n role=\"gridcell\"\n tabIndex={-1}\n >\n {isEditing && column.editor\n ? column.editor({\n value,\n row,\n onChange: () => undefined,\n commit: () => {\n editing.onEditCommit?.({ rowId, colId: column.id, value, row });\n model.setEditingCell(null);\n },\n cancel: () => model.setEditingCell(null),\n })\n : content}\n </TableCell>\n );\n}\n\nexport interface GridRowProps<T extends Record<string, unknown>> {\n row: T;\n index: number;\n rowId: string | number;\n isSelected: boolean;\n isExpanded: boolean;\n totalColumns: number;\n model: DataGridModel<T>;\n props: DataGridProps<T>;\n}\n\n/** The leading checkbox / chevron cells, which exist only for enabled features. */\nfunction RowControls<T extends Record<string, unknown>>({\n index,\n rowId,\n isSelected,\n isExpanded,\n model,\n props,\n}: GridRowProps<T>): React.JSX.Element {\n const { selection = { mode: 'none' }, expansion } = props;\n return (\n <>\n {selection.mode !== 'none' && (\n <TableCell padding=\"checkbox\">\n <Checkbox\n checked={isSelected}\n onChange={(event) => model.onToggleRow(rowId, event.target.checked)}\n inputProps={{ 'aria-label': `Select row ${index + 1}` }}\n />\n </TableCell>\n )}\n {expansion && (\n <TableCell padding=\"checkbox\">\n <IconButton\n size=\"small\"\n onClick={() => model.onToggleExpansion(rowId)}\n aria-label={isExpanded ? 'Collapse row' : 'Expand row'}\n >\n {isExpanded ? <ExpandLess /> : <ExpandMore />}\n </IconButton>\n </TableCell>\n )}\n </>\n );\n}\n\nexport function GridRow<T extends Record<string, unknown>>(\n rowProps: GridRowProps<T>,\n): React.JSX.Element {\n const { row, index, rowId, isSelected, isExpanded, totalColumns, model, props } = rowProps;\n const theme = useTheme();\n const expansion = props.expansion;\n return (\n <React.Fragment>\n <TableRow\n data-slot=\"row\"\n data-selected={isSelected}\n data-expanded={isExpanded}\n sx={{\n '&:hover': { backgroundColor: theme.palette.action.hover },\n ...(isSelected && { backgroundColor: theme.palette.action.selected }),\n height: model.rowHeight,\n }}\n role=\"row\"\n aria-selected={isSelected}\n >\n <RowControls {...rowProps} />\n {model.visibleColumns.map((column) => (\n <DataCell\n key={column.id}\n row={row}\n rowIndex={index}\n rowId={rowId}\n column={column}\n rowHeight={model.rowHeight}\n editing={props.editing ?? { mode: 'none' }}\n model={model}\n />\n ))}\n </TableRow>\n {expansion && isExpanded && (\n <TableRow>\n <TableCell colSpan={totalColumns}>{expansion.render(row, index)}</TableCell>\n </TableRow>\n )}\n </React.Fragment>\n );\n}\n","/**\n * The DataGrid's CLIENT-MODE row pipeline: filter, sort, paginate.\n *\n * Lifted out of the component so it is a pure function of its inputs — no\n * hooks, no theme, no refs — which is the only way the comparator can be read\n * (and tested) at all. Server modes skip every step here: the rows arrived\n * already filtered, sorted and paged, and re-doing any of it locally would make\n * the grid disagree with the page count the server just sent.\n */\nimport type { GridColumn, GridFilter, GridSort } from './DataGrid.types';\n\n/** The value a column reads out of a row: accessor fn, accessor key, or id. */\nexport function cellValue<T extends Record<string, unknown>>(\n row: T,\n column: GridColumn<T>,\n): unknown {\n const { accessor } = column;\n if (typeof accessor === 'function') return accessor(row);\n if (accessor !== undefined) return row[accessor];\n return row[column.id];\n}\n\n/**\n * Order two cell values, with absent ones sorting first.\n *\n * Numbers compare as numbers and everything else as a string — the grid has no\n * per-column comparator, and stringifying a number would sort 10 before 9.\n */\nfunction compareValues(a: unknown, b: unknown): number {\n if (a == null && b == null) return 0;\n if (a == null) return -1;\n if (b == null) return 1;\n const left = typeof a === 'number' ? a : String(a);\n const right = typeof b === 'number' ? b : String(b);\n if (left < right) return -1;\n return left > right ? 1 : 0;\n}\n\n/**\n * A comparator over the whole `sortBy` list — earlier entries win, later ones\n * break their ties. A sort entry naming an unknown column, or carrying a `null`\n * direction, is skipped rather than treated as ascending.\n */\nfunction makeComparator<T extends Record<string, unknown>>(\n sortBy: readonly GridSort[],\n columnMap: ReadonlyMap<string, GridColumn<T>>,\n): (a: T, b: T) => number {\n return (a, b) => {\n for (const sort of sortBy) {\n const column = columnMap.get(sort.id);\n if (!column || !sort.dir) continue;\n const comparison = compareValues(cellValue(a, column), cellValue(b, column));\n if (comparison !== 0) return sort.dir === 'desc' ? -comparison : comparison;\n }\n return 0;\n };\n}\n\n/** Does `row` satisfy one filter? An unknown column or empty value matches all. */\nfunction matchesFilter<T extends Record<string, unknown>>(\n row: T,\n filter: GridFilter,\n columnMap: ReadonlyMap<string, GridColumn<T>>,\n): boolean {\n const column = columnMap.get(filter.id);\n if (!column || !filter.value) return true;\n const value = cellValue(row, column);\n if (column.filterPredicate) return column.filterPredicate(value, filter.value, row);\n return String(value ?? '')\n .toLowerCase()\n .includes(String(filter.value).toLowerCase());\n}\n\n/** Which client-mode steps this render actually needs. */\ninterface RowPipeline<T extends Record<string, unknown>> {\n rows: T[];\n columnMap: ReadonlyMap<string, GridColumn<T>>;\n filters: readonly GridFilter[];\n sortBy: readonly GridSort[];\n needsFiltering: boolean;\n needsSorting: boolean;\n needsPagination: boolean;\n pageIndex: number;\n pageSize: number;\n}\n\n/**\n * Run the pipeline, copying the array only when a step actually has to modify\n * it. The identity of the untouched array is load-bearing: the grid's memos and\n * every consumer's `rows === prev` check depend on a no-op pipeline returning\n * exactly what it was given.\n */\nexport function processRows<T extends Record<string, unknown>>(pipeline: RowPipeline<T>): T[] {\n const { rows, columnMap, needsFiltering, needsSorting, needsPagination } = pipeline;\n if (!needsFiltering && !needsSorting && !needsPagination) return rows;\n\n let result = rows;\n if (needsFiltering) {\n result = result.filter((row) =>\n pipeline.filters.every((filter) => matchesFilter(row, filter, columnMap)),\n );\n }\n if (needsSorting) {\n // Copy only here: `Array#sort` is in-place and the caller owns `rows`.\n result = [...result].sort(makeComparator(pipeline.sortBy, columnMap));\n }\n if (needsPagination) {\n const start = pipeline.pageIndex * pipeline.pageSize;\n result = result.slice(start, start + pipeline.pageSize);\n }\n return result;\n}\n","/**\n * The DataGrid's STATE, in one hook.\n *\n * The component used to hold all of it inline, which made its body 700 lines\n * long and put the row pipeline, the virtualization window and the JSX in one\n * scope where any of them could reach any other. Split out, each piece is a\n * hook with named inputs and the render is left with nothing to do but render.\n *\n * Controlled/uncontrolled is resolved in ONE place per feature: a caller that\n * passes `sorting.sortBy` owns the sort, and a caller that does not gets the\n * internal state — the component never holds a second, divergent copy.\n */\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type React from 'react';\n\nimport { processRows } from './DataGrid.rows';\nimport type {\n DataGridProps,\n GridColumn,\n GridFilter,\n GridSort,\n SortDirection,\n} from './DataGrid.types';\n\nconst DEFAULT_ROW_HEIGHT = 52;\nconst DEFAULT_PAGE_SIZE = 50;\n/** Rows rendered on either side of the window, so a fast scroll stays filled. */\nconst OVERSCAN_COUNT = 20;\n/** Below this many rows, virtualization costs more than it saves. */\nconst VIRTUALIZATION_THRESHOLD = 100;\n/** The initial (and reset) window size, before a scroll has measured anything. */\nconst INITIAL_WINDOW = 50;\n/** Re-window only past this much drift, so a scroll is not one setState per pixel. */\nconst WINDOW_DRIFT = 5;\n\n/** Which id is being edited, or `null`. */\nexport interface EditingCell {\n rowId: string | number;\n colId: string;\n}\n\n/** The visible slice of a virtualized body. */\nexport interface VisibleRange {\n start: number;\n end: number;\n}\n\n/** Everything the render needs, and nothing it has to derive. */\nexport interface DataGridModel<T extends Record<string, unknown>> {\n containerRef: React.RefObject<HTMLDivElement | null>;\n rowHeight: number;\n visibleColumns: GridColumn<T>[];\n processedRows: T[];\n visibleRows: T[];\n visibleRange: VisibleRange;\n virtualized: boolean;\n sortBy: readonly GridSort[];\n selectedRowIds: Array<string | number>;\n selectedRowIdsSet: ReadonlySet<string | number>;\n expandedRowIdsSet: ReadonlySet<string | number>;\n editingCell: EditingCell | null;\n setEditingCell: (cell: EditingCell | null) => void;\n setSelectedRowIds: (ids: Array<string | number>) => void;\n onSort: (columnId: string) => void;\n onToggleRow: (rowId: string | number, isSelected: boolean) => void;\n onToggleExpansion: (rowId: string | number) => void;\n onScroll: (event: React.UIEvent<HTMLDivElement>) => void;\n}\n\n/** The row height a density implies. */\nfunction densityHeight(base: number, density: DataGridProps['density']): number {\n if (density === 'compact') return Math.max(base * 0.8, 32);\n if (density === 'spacious') return base * 1.2;\n return base;\n}\n\n/** The rows this render should show, with every client-mode step resolved. */\nfunction useProcessedRows<T extends Record<string, unknown>>(\n props: DataGridProps<T>,\n columnMap: ReadonlyMap<string, GridColumn<T>>,\n sortBy: readonly GridSort[],\n filters: readonly GridFilter[],\n): T[] {\n const { rows, filtering = {}, sorting = {}, pagination, virtualizeRows = true } = props;\n const pageIndex = pagination?.pageIndex ?? 0;\n const pageSize = pagination?.pageSize ?? DEFAULT_PAGE_SIZE;\n return useMemo(\n () =>\n processRows({\n rows,\n columnMap,\n filters,\n sortBy,\n needsFiltering: filtering.mode === 'client' && filters.length > 0,\n needsSorting: sorting.mode === 'client' && sortBy.length > 0,\n // Virtualization already slices; doing both would page a page.\n needsPagination: pagination?.mode === 'client' && !virtualizeRows,\n pageIndex,\n pageSize,\n }),\n [\n rows,\n columnMap,\n filters,\n sortBy,\n filtering.mode,\n sorting.mode,\n pagination?.mode,\n virtualizeRows,\n pageIndex,\n pageSize,\n ],\n );\n}\n\n/**\n * The virtualization window and the scroll handler that moves it.\n *\n * Throttled through `requestAnimationFrame`, and only committed once the window\n * has drifted meaningfully — a `setState` per scroll event re-renders every\n * visible row for a movement the eye cannot see.\n */\nfunction useRowWindow(\n rowCount: number,\n rowHeight: number,\n enabled: boolean,\n): { range: VisibleRange; onScroll: (event: React.UIEvent<HTMLDivElement>) => void } {\n const [range, setRange] = useState<VisibleRange>({ start: 0, end: INITIAL_WINDOW });\n const rafRef = useRef<number | null>(null);\n\n useEffect(() => {\n if (rowCount < range.end) setRange({ start: 0, end: Math.min(INITIAL_WINDOW, rowCount) });\n }, [rowCount, range.end]);\n\n useEffect(\n () => () => {\n if (rafRef.current !== null) window.cancelAnimationFrame(rafRef.current);\n },\n [],\n );\n\n const onScroll = useCallback(\n (event: React.UIEvent<HTMLDivElement>) => {\n if (!enabled) return;\n const { scrollTop, clientHeight } = event.currentTarget;\n if (rafRef.current !== null) window.cancelAnimationFrame(rafRef.current);\n rafRef.current = window.requestAnimationFrame(() => {\n const first = Math.floor(scrollTop / rowHeight);\n const visible = Math.ceil(clientHeight / rowHeight);\n const start = Math.max(0, first - OVERSCAN_COUNT);\n const end = Math.min(first + visible + OVERSCAN_COUNT, rowCount);\n setRange((current) =>\n Math.abs(start - current.start) > WINDOW_DRIFT ||\n Math.abs(end - current.end) > WINDOW_DRIFT\n ? { start, end }\n : current,\n );\n rafRef.current = null;\n });\n },\n [enabled, rowHeight, rowCount],\n );\n\n return { range, onScroll };\n}\n\n/** The next `sortBy` for a header press: asc → desc → unsorted. */\nfunction nextSortBy(current: readonly GridSort[], columnId: string): GridSort[] {\n const existing = current.find((sort) => sort.id === columnId);\n let dir: SortDirection = 'asc';\n if (existing?.dir === 'asc') dir = 'desc';\n else if (existing?.dir === 'desc') dir = null;\n return dir ? [{ id: columnId, dir }] : current.filter((sort) => sort.id !== columnId);\n}\n\n/** Selection + expansion, each resolved once against its controlled prop. */\nfunction useRowFlags<T extends Record<string, unknown>>(\n props: DataGridProps<T>,\n): Pick<\n DataGridModel<T>,\n | 'selectedRowIds'\n | 'selectedRowIdsSet'\n | 'expandedRowIdsSet'\n | 'setSelectedRowIds'\n | 'onToggleRow'\n | 'onToggleExpansion'\n> {\n const { selection = { mode: 'none' }, expansion } = props;\n const [internalSelected, setInternalSelected] = useState(selection.defaultSelectedRowIds ?? []);\n const [internalExpanded, setInternalExpanded] = useState(expansion?.defaultExpandedRowIds ?? []);\n const selectedRowIds = selection.selectedRowIds ?? internalSelected;\n const expandedRowIds = expansion?.expandedRowIds ?? internalExpanded;\n\n const commitSelected = useCallback(\n (ids: Array<string | number>) => {\n if (selection.onChangeSelected) selection.onChangeSelected(ids);\n else setInternalSelected(ids);\n },\n [selection],\n );\n\n return {\n selectedRowIds,\n selectedRowIdsSet: useMemo(() => new Set(selectedRowIds), [selectedRowIds]),\n expandedRowIdsSet: useMemo(() => new Set(expandedRowIds), [expandedRowIds]),\n setSelectedRowIds: commitSelected,\n onToggleRow: (rowId, isSelected) => {\n if (selection.mode === 'single') commitSelected(isSelected ? [rowId] : []);\n else if (selection.mode === 'multi') {\n commitSelected(\n isSelected\n ? [...selectedRowIds, rowId]\n : selectedRowIds.filter((id) => id !== rowId),\n );\n }\n },\n onToggleExpansion: (rowId) => {\n if (!expansion) return;\n const next = expandedRowIds.includes(rowId)\n ? expandedRowIds.filter((id) => id !== rowId)\n : [...expandedRowIds, rowId];\n if (expansion.onChangeExpanded) expansion.onChangeExpanded(next);\n else setInternalExpanded(next);\n },\n };\n}\n\n/**\n * A header press, routed to whoever owns the sort: the server (which must\n * re-query — sorting the current page locally would reorder one page of a\n * dataset and call it sorted), the caller's `onChangeSortBy`, or internal state.\n */\nfunction useSortHandler<T extends Record<string, unknown>>(\n props: DataGridProps<T>,\n sortBy: readonly GridSort[],\n filters: readonly GridFilter[],\n setInternalSortBy: (next: GridSort[]) => void,\n): (columnId: string) => void {\n const { sorting = {}, pagination, onRequestData } = props;\n return useCallback(\n (columnId: string) => {\n const next = nextSortBy(sortBy, columnId);\n if (sorting.mode === 'server' && onRequestData) {\n onRequestData({\n pageIndex: pagination?.pageIndex ?? 0,\n pageSize: pagination?.pageSize ?? DEFAULT_PAGE_SIZE,\n sortBy: next,\n filters: [...filters],\n });\n return;\n }\n if (sorting.onChangeSortBy) sorting.onChangeSortBy(next);\n else setInternalSortBy(next);\n },\n [sortBy, sorting, onRequestData, pagination, filters, setInternalSortBy],\n );\n}\n\n/**\n * Sort and filter, each resolved ONCE against its controlled prop: a caller\n * that passes `sorting.sortBy` owns the sort, and one that does not gets the\n * internal state. The grid never holds a second, divergent copy.\n */\nfunction useSortAndFilter<T extends Record<string, unknown>>(\n props: DataGridProps<T>,\n): {\n sortBy: readonly GridSort[];\n filters: readonly GridFilter[];\n setInternalSortBy: (next: GridSort[]) => void;\n} {\n const { sorting = {}, filtering = {} } = props;\n const [internalSortBy, setInternalSortBy] = useState<GridSort[]>(sorting.defaultSortBy ?? []);\n const [internalFilters] = useState<GridFilter[]>(filtering.defaultFilters ?? []);\n return {\n sortBy: sorting.sortBy ?? internalSortBy,\n filters: filtering.filters ?? internalFilters,\n setInternalSortBy,\n };\n}\n\nexport function useDataGridModel<T extends Record<string, unknown>>(\n props: DataGridProps<T>,\n): DataGridModel<T> {\n const { columns } = props;\n const containerRef = useRef<HTMLDivElement>(null);\n const [editingCell, setEditingCell] = useState<EditingCell | null>(null);\n const { sortBy, filters, setInternalSortBy } = useSortAndFilter(props);\n const rowHeight = densityHeight(props.rowHeight ?? DEFAULT_ROW_HEIGHT, props.density);\n const columnMap = useMemo(\n () => new Map(columns.map((column) => [column.id, column])),\n [columns],\n );\n const visibleColumns = useMemo(() => columns.filter((column) => !column.hidden), [columns]);\n const processedRows = useProcessedRows(props, columnMap, sortBy, filters);\n const virtualized =\n (props.virtualizeRows ?? true) && processedRows.length > VIRTUALIZATION_THRESHOLD;\n const { range, onScroll } = useRowWindow(processedRows.length, rowHeight, virtualized);\n const onSort = useSortHandler(props, sortBy, filters, setInternalSortBy);\n\n return {\n containerRef,\n rowHeight,\n visibleColumns,\n processedRows,\n visibleRows: virtualized ? processedRows.slice(range.start, range.end) : processedRows,\n visibleRange: range,\n virtualized,\n sortBy,\n editingCell,\n setEditingCell,\n onSort,\n onScroll,\n ...useRowFlags(props),\n };\n}\n","/**\n * The DataGrid's three PLACEHOLDER states: loading, error, and empty.\n *\n * ## Why they carry `data-testid`\n *\n * They used to not, and it was invisible: `data-testid` is destructured out of\n * the props and was re-applied only on the populated render, so a grid whose\n * first paint was any of these three states rendered with NO test id at all.\n * The grid had booted perfectly and simply could not be found — every spec that\n * landed on a screen with no rows yet waited out its whole budget on an element\n * that would only appear once somebody created a row. `stations.e2e.ts` carries\n * a paragraph about working around exactly this.\n *\n * So all four renders now agree: the id names the GRID, not the grid's data.\n * A test that asks \"did the grid mount\" gets the same answer in every state,\n * and `data-loading` / `data-error` / `data-empty` say WHICH state it is.\n */\nimport { Box, CircularProgress, Typography } from '@mui/material';\nimport type React from 'react';\n\n/** Shared by all three: the same box, the same role, the same id. */\ninterface PlaceholderProps {\n dataTestId?: string;\n ariaLabel?: string;\n className?: string;\n style?: React.CSSProperties;\n htmlProps: React.HTMLAttributes<HTMLElement>;\n children: React.ReactNode;\n /** The single state flag this placeholder sets (`data-loading` etc.). */\n flag: 'data-loading' | 'data-error' | 'data-empty';\n}\n\nfunction Placeholder({\n dataTestId,\n ariaLabel,\n className,\n style,\n htmlProps,\n children,\n flag,\n}: PlaceholderProps): React.JSX.Element {\n return (\n <Box\n data-ui=\"datagrid\"\n {...{ [flag]: 'true' }}\n data-testid={dataTestId}\n className={className}\n style={style}\n sx={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n flexDirection: 'column',\n gap: 2,\n height: 200,\n }}\n aria-label={ariaLabel}\n role=\"grid\"\n {...htmlProps}\n >\n {children}\n </Box>\n );\n}\n\ntype StateProps = Omit<PlaceholderProps, 'children' | 'flag'>;\n\nexport function DataGridLoading(props: StateProps): React.JSX.Element {\n return (\n <Placeholder {...props} flag=\"data-loading\">\n <CircularProgress />\n </Placeholder>\n );\n}\n\nexport function DataGridError(\n props: StateProps & { error: React.ReactNode },\n): React.JSX.Element {\n const { error, ...rest } = props;\n return (\n <Placeholder {...rest} flag=\"data-error\">\n <Typography color=\"error\" variant=\"body1\">\n {error}\n </Typography>\n </Placeholder>\n );\n}\n\nexport function DataGridEmpty(\n props: StateProps & { emptyState?: React.ReactNode },\n): React.JSX.Element {\n const { emptyState, ...rest } = props;\n return (\n <Placeholder {...rest} flag=\"data-empty\">\n {emptyState ?? (\n <Typography variant=\"body1\" color=\"text.secondary\">\n No data available\n </Typography>\n )}\n </Placeholder>\n );\n}\n"],"mappings":"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","names":["Checkbox","TableCell","TableRow","useTheme","Fragment","jsx","jsxs","useTheme","TableCell","Checkbox","TableRow","Typography","jsx","jsx","jsxs"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/feedback/StackedModal/StackedModal.tsx","../src/components/feedback/StackedModal/StackedModal.hooks.ts","../src/components/feedback/StackedModal/modal-stack.tsx","../src/components/feedback/StackedModal/StackedModal.parts.tsx","../src/components/feedback/StackedModal/StackedModal.styles.ts"],"sourcesContent":["import { Dialog, Slide, styled } from '@mui/material';\nimport type { TransitionProps } from '@mui/material/transitions';\nimport type { FC } from 'react';\nimport React, { forwardRef, useId } from 'react';\nimport { usePanelChrome } from './StackedModal.hooks';\nimport { modalAriaIds, ModalPanelContents, resolveModalContent } from './StackedModal.parts';\nimport type { PanelStyleProps } from './StackedModal.styles';\nimport { dialogRootStyles, STYLE_ONLY_PROPS } from './StackedModal.styles';\nimport type { StackedModalProps } from './StackedModal.types';\n\nconst StyledDialog = styled(Dialog, {\n shouldForwardProp: (prop) => !STYLE_ONLY_PROPS.includes(prop as string),\n})<PanelStyleProps>(({ theme, ...props }) => dialogRootStyles(theme, props));\n\n/** Panels slide in from the right on every device. */\nconst SlideTransition = forwardRef<HTMLDivElement, TransitionProps>(\n function SlideTransition(props, ref) {\n return (\n <Slide direction=\"left\" ref={ref} {...props}>\n {props.children as React.ReactElement}\n </Slide>\n );\n },\n);\n\nconst DEFAULTS: Partial<StackedModalProps> = {\n open: false,\n glass: false,\n navigationTitle: '',\n closeOnClickOutside: true,\n closeOnEsc: true,\n loading: false,\n loadingText: 'Loading...',\n maxWidth: false,\n disableBackdrop: false,\n disableFocusTrap: false,\n keepMounted: false,\n rtl: false,\n};\n\n/**\n * Fills in the defaults for props the caller left `undefined`. A table plus one\n * loop, rather than a default per destructured prop — each of those is a branch,\n * and fifteen of them put the component over the complexity bar on their own.\n */\nconst withDefaults = (props: StackedModalProps): StackedModalProps => {\n const resolved = { ...props };\n for (const [key, value] of Object.entries(DEFAULTS)) {\n const prop = key as keyof StackedModalProps;\n if (resolved[prop] === undefined) {\n Object.assign(resolved, { [prop]: value });\n }\n }\n return resolved;\n};\n\n/** The modal's props once defaults are applied and its stack identity is settled. */\ntype ResolvedProps = StackedModalProps & { modalId: string };\n\nconst StackedModalPanel: FC<ResolvedProps> = (props) => {\n const {\n open, onClose, glass, navigationTitle, hideClose, children, actions, modalId,\n closeOnClickOutside, closeOnEsc, loading, loadingText, fullScreen, maxWidth, disableBackdrop,\n disableFocusTrap, keepMounted, rtl, dataTestId,\n 'aria-labelledby': ariaLabelledBy, 'aria-describedby': ariaDescribedBy, ...otherProps\n } = props;\n\n const {\n dialogRef, modalRole, isAnimating, showSkeleton, zIndex, isMobile, canGoBack,\n handleBack, handleClose,\n } = usePanelChrome({\n open, modalId, loading, closeOnEsc, closeOnClickOutside, disableFocusTrap, onClose,\n });\n\n // Don't render if in background (performance optimization)\n if (modalRole === 'background' && !keepMounted) return null;\n\n const { content, modalActions, headerActions, hasMobileActions } = resolveModalContent(\n children,\n actions,\n isMobile,\n );\n const { titleId, descId } = modalAriaIds(modalId, ariaLabelledBy, ariaDescribedBy);\n\n return (\n <StyledDialog\n ref={dialogRef}\n open={Boolean(open)}\n onClose={handleClose}\n fullScreen={fullScreen ?? isMobile}\n modalRole={modalRole}\n isAnimating={isAnimating}\n glass={glass}\n rtl={rtl}\n customMaxWidth={maxWidth}\n TransitionComponent={SlideTransition}\n maxWidth={maxWidth}\n disableEscapeKeyDown={!closeOnEsc}\n hideBackdrop={disableBackdrop}\n keepMounted={keepMounted}\n aria-labelledby={titleId}\n aria-describedby={descId}\n data-testid={dataTestId}\n sx={{ zIndex }}\n {...otherProps}\n >\n <ModalPanelContents\n showSkeleton={showSkeleton}\n loadingText={loadingText}\n titleId={titleId}\n descId={descId}\n navigationTitle={navigationTitle}\n hideClose={hideClose}\n canGoBack={canGoBack}\n onBack={handleBack}\n onClose={onClose}\n headerActions={headerActions}\n content={content}\n modalActions={modalActions}\n hasMobileActions={hasMobileActions}\n rtl={rtl}\n dataTestId={dataTestId}\n />\n </StyledDialog>\n );\n};\n\nexport const StackedModal: FC<StackedModalProps> = (props) => {\n // A modal with no caller-supplied id still needs a STABLE one — it keys this\n // panel's entry in the stack, so a value that changed per render (as a\n // `Math.random()` default does) would re-register it on every pass.\n const fallbackId = useId();\n const resolved = withDefaults(props);\n return <StackedModalPanel {...resolved} modalId={resolved.modalId ?? fallbackId} />;\n};\n\n// Re-exported so `./StackedModal` stays the single public entry point for the\n// component and its stack primitives, as the barrel and existing imports expect.\nexport {\n ModalStackProvider,\n ModalStackProvider as StackedModalProvider,\n useModalStack,\n useModalStack as useStackedModal,\n} from './modal-stack';\nexport { StackedModalActions, StackedModalContent } from './StackedModal.parts';\n","import { useMediaQuery, useTheme } from '@mui/material';\nimport type { RefObject } from 'react';\nimport { useEffect, useRef, useState } from 'react';\nimport { useModalStack } from './modal-stack';\nimport type { ModalPanelRole } from './StackedModal.types';\n\nconst FOCUSABLE = 'a[href], button, textarea, input, select, [tabindex]:not([tabindex=\"-1\"])';\n/** MUI Dialog's own default, used when the modal isn't registered in the stack yet. */\nconst FALLBACK_Z_INDEX = 1300;\n/** Matches the panel's slide duration, so role swaps animate rather than jump. */\nconst ROLE_TRANSITION_MS = 300;\n\n/** Keeps Tab cycling inside the open panel instead of escaping to the page behind. */\nconst useFocusTrap = (\n ref: RefObject<HTMLElement | null>,\n isActive: boolean,\n disabled?: boolean,\n): void => {\n useEffect(() => {\n if (!isActive || disabled || !ref.current) return;\n\n const element = ref.current;\n const focusable = element.querySelectorAll(FOCUSABLE);\n const first = focusable[0] as HTMLElement | undefined;\n const last = focusable[focusable.length - 1] as HTMLElement | undefined;\n\n window.setTimeout(() => first?.focus(), 100);\n\n const handleTabKey = (e: globalThis.KeyboardEvent): void => {\n if (e.key !== 'Tab') return;\n const atEdge = e.shiftKey ? first : last;\n if (document.activeElement !== atEdge) return;\n e.preventDefault();\n (e.shiftKey ? last : first)?.focus();\n };\n\n element.addEventListener('keydown', handleTabKey);\n return () => element.removeEventListener('keydown', handleTabKey);\n }, [ref, isActive, disabled]);\n};\n\n/** Closes the panel on Escape — only while it is the top one. */\nconst useEscapeToClose = (active: boolean, onClose: () => void): void => {\n useEffect(() => {\n if (!active) return;\n\n const handleEsc = (e: globalThis.KeyboardEvent): void => {\n if (e.key !== 'Escape') return;\n e.preventDefault();\n onClose();\n };\n\n window.addEventListener('keydown', handleEsc);\n return () => window.removeEventListener('keydown', handleEsc);\n }, [active, onClose]);\n};\n\n/** Holds the skeleton a beat past `loading` so the swap to content isn't a flash. */\nconst useSkeleton = (loading: boolean): boolean => {\n const [showSkeleton, setShowSkeleton] = useState(loading);\n\n useEffect(() => {\n if (loading) {\n setShowSkeleton(true);\n return;\n }\n const timer = window.setTimeout(() => setShowSkeleton(false), 200);\n return () => window.clearTimeout(timer);\n }, [loading]);\n\n return showSkeleton;\n};\n\n/** Registers the modal in the stack while open, and unregisters it after it slides out. */\nconst useStackRegistration = (open: boolean, modalId: string): void => {\n const { pushModal, popModal, isModalInStack } = useModalStack();\n const hasRegisteredRef = useRef(false);\n\n useEffect(() => {\n if (open && !hasRegisteredRef.current) {\n pushModal(modalId);\n hasRegisteredRef.current = true;\n } else if (!open) {\n hasRegisteredRef.current = false;\n }\n }, [open, modalId, pushModal]);\n\n useEffect(() => {\n if (open || !isModalInStack(modalId)) return;\n const timer = window.setTimeout(() => popModal(modalId), ROLE_TRANSITION_MS);\n return () => window.clearTimeout(timer);\n }, [open, modalId, popModal, isModalInStack]);\n};\n\ninterface PanelChromeOptions {\n open?: boolean;\n modalId: string;\n loading?: boolean;\n closeOnEsc?: boolean;\n closeOnClickOutside?: boolean;\n disableFocusTrap?: boolean;\n onClose: () => void;\n}\n\ninterface PanelChrome {\n dialogRef: RefObject<HTMLDivElement | null>;\n modalRole: ModalPanelRole;\n isAnimating: boolean;\n showSkeleton: boolean;\n zIndex: number;\n isMobile: boolean;\n canGoBack: boolean;\n handleBack: () => void;\n handleClose: (event: object, reason: 'backdropClick' | 'escapeKeyDown') => void;\n}\n\n/**\n * Everything the panel needs to render itself: its place in the stack, the\n * viewport it is on, and the handlers that dismiss it. Bundled into one hook so\n * the component stays a description of the markup.\n */\nexport const usePanelChrome = (options: PanelChromeOptions): PanelChrome => {\n const { open, modalId, loading, closeOnEsc, closeOnClickOutside, disableFocusTrap, onClose } =\n options;\n\n const dialogRef = useRef<HTMLDivElement>(null);\n const { currentDepth } = useModalStack();\n const { modalRole, isAnimating } = useModalRole(Boolean(open), modalId);\n const showSkeleton = useSkeleton(Boolean(loading));\n const zIndex = usePanelZIndex(modalId, FALLBACK_Z_INDEX);\n\n const theme = useTheme();\n const isMobile = useMediaQuery(theme.breakpoints.down('sm'));\n const isPrimary = modalRole === 'primary';\n const canGoBack = currentDepth > 1;\n\n useFocusTrap(dialogRef, Boolean(open) && isPrimary, disableFocusTrap);\n useEscapeToClose(Boolean(open && closeOnEsc) && isPrimary, onClose);\n\n const { handleBack, handleClose } = useCloseHandlers({\n isPrimary,\n closeOnClickOutside,\n closeOnEsc,\n canGoBack,\n onClose,\n });\n\n return {\n dialogRef,\n modalRole,\n isAnimating,\n showSkeleton,\n zIndex,\n isMobile,\n canGoBack,\n handleBack,\n handleClose,\n };\n};\n\ninterface CloseHandlerOptions {\n /** Only the top panel responds to a backdrop click or Escape. */\n isPrimary: boolean;\n closeOnClickOutside?: boolean;\n closeOnEsc?: boolean;\n /** Deeper than one panel, so the leading control goes back rather than closing. */\n canGoBack: boolean;\n onClose: () => void;\n}\n\n/** The panel's dismissal handlers, honouring which gestures the caller allows. */\nconst useCloseHandlers = ({\n isPrimary,\n closeOnClickOutside,\n closeOnEsc,\n canGoBack,\n onClose,\n}: CloseHandlerOptions): {\n handleBack: () => void;\n handleClose: (event: object, reason: 'backdropClick' | 'escapeKeyDown') => void;\n} => ({\n handleBack: () => {\n if (canGoBack) onClose();\n },\n handleClose: (_event, reason) => {\n if (!isPrimary) return;\n if (reason === 'backdropClick' && !closeOnClickOutside) return;\n if (reason === 'escapeKeyDown' && !closeOnEsc) return;\n onClose();\n },\n});\n\n/** The z-index this panel was assigned when it joined the stack. */\nconst usePanelZIndex = (modalId: string, fallback: number): number => {\n const { stack } = useModalStack();\n return stack.find((m) => m.id === modalId)?.zIndex ?? fallback;\n};\n\n/**\n * This modal's role in the stack, plus whether it is mid-transition between two\n * roles (which drives the expand/contract animation).\n */\nconst useModalRole = (\n open: boolean,\n modalId: string,\n): { modalRole: ModalPanelRole; isAnimating: boolean } => {\n const { stack } = useModalStack();\n const [modalRole, setModalRole] = useState<ModalPanelRole>('primary');\n const [isAnimating, setIsAnimating] = useState(false);\n\n useStackRegistration(open, modalId);\n\n useEffect(() => {\n if (!open) return;\n\n const newRole = stack.find((m) => m.id === modalId)?.role;\n if (!newRole || newRole === modalRole) return;\n\n setIsAnimating(true);\n setModalRole(newRole);\n const timer = window.setTimeout(() => setIsAnimating(false), ROLE_TRANSITION_MS);\n return () => window.clearTimeout(timer);\n }, [stack, modalId, open, modalRole]);\n\n return { modalRole, isAnimating };\n};\n","import type { FC, ReactNode } from 'react';\nimport { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';\nimport { MODAL_STACK_BASE_Z_INDEX, MODAL_STACK_Z_INDEX_STEP } from '../../../tokens/layers';\nimport type { ModalInfo, ModalPanelRole, ModalStackContextValue } from './StackedModal.types';\n\n/**\n * MUI Dialog default z-index; each panel in the stack sits 10 above the last.\n *\n * Imported rather than declared here: anything that portals out of a panel has\n * to clear this ladder, so the numbers are shared with the token that tells it\n * how — see `tokens/layers`.\n */\nconst BASE_Z_INDEX = MODAL_STACK_BASE_Z_INDEX;\nconst Z_INDEX_STEP = MODAL_STACK_Z_INDEX_STEP;\n\nconst noop = (): void => {\n /** do nothing */\n};\n\nconst ModalStackContext = createContext<ModalStackContextValue>({\n stack: [],\n pushModal: noop,\n popModal: noop,\n clearStack: noop,\n currentDepth: 0,\n isModalInStack: () => false,\n getModalRole: () => null,\n});\n\nexport const useModalStack = (): ModalStackContextValue => {\n const context = useContext(ModalStackContext);\n if (!context) {\n throw new Error('useModalStack must be used within a ModalStackProvider');\n }\n return context;\n};\n\n/** Top of the stack drives the view; the one behind it recedes; the rest are hidden. */\nconst roleAt = (index: number, depth: number): ModalPanelRole => {\n if (index === depth - 1) return 'primary';\n if (index === depth - 2) return 'secondary';\n return 'background';\n};\n\n/** Re-derive every role from stack position — the one place roles are assigned. */\nconst withRoles = (stack: ModalInfo[]): ModalInfo[] =>\n stack.map((modal, index) => ({ ...modal, role: roleAt(index, stack.length) }));\n\n/**\n * Locks body scroll while any modal is open, restoring whatever the page had\n * before. Owned by the provider rather than each modal, so nested panels can't\n * fight over the same style.\n */\nconst useBodyScrollLock = (locked: boolean): void => {\n const originalOverflow = useRef<string>('');\n\n useEffect(() => {\n const restore = (): void => {\n if (!originalOverflow.current) return;\n document.body.style.overflow = originalOverflow.current;\n originalOverflow.current = '';\n };\n\n if (locked) {\n if (!originalOverflow.current) {\n originalOverflow.current = document.body.style.overflow || '';\n }\n document.body.style.overflow = 'hidden';\n } else {\n restore();\n }\n\n return restore;\n }, [locked]);\n};\n\nexport const ModalStackProvider: FC<{ children: ReactNode }> = ({ children }) => {\n const [stack, setStack] = useState<ModalInfo[]>([]);\n\n useBodyScrollLock(stack.length > 0);\n\n const pushModal = useCallback((modalId: string) => {\n setStack((prev) => {\n if (prev.some((m) => m.id === modalId)) return prev;\n const entry: ModalInfo = {\n id: modalId,\n zIndex: BASE_Z_INDEX + prev.length * Z_INDEX_STEP,\n role: 'primary',\n };\n return withRoles([...prev, entry]);\n });\n }, []);\n\n const popModal = useCallback((modalId?: string) => {\n setStack((prev) =>\n withRoles(modalId ? prev.filter((m) => m.id !== modalId) : prev.slice(0, -1)),\n );\n }, []);\n\n const clearStack = useCallback(() => setStack([]), []);\n\n const isModalInStack = useCallback(\n (modalId: string) => stack.some((m) => m.id === modalId),\n [stack],\n );\n\n const getModalRole = useCallback(\n (modalId: string) => stack.find((m) => m.id === modalId)?.role ?? null,\n [stack],\n );\n\n const value = useMemo(\n () => ({\n stack,\n pushModal,\n popModal,\n clearStack,\n currentDepth: stack.length,\n isModalInStack,\n getModalRole,\n }),\n [stack, pushModal, popModal, clearStack, isModalInStack, getModalRole],\n );\n\n return <ModalStackContext.Provider value={value}>{children}</ModalStackContext.Provider>;\n};\n","import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';\nimport CloseIcon from '@mui/icons-material/Close';\nimport {\n Box,\n CircularProgress,\n DialogActions,\n DialogContent,\n DialogTitle,\n IconButton,\n Skeleton,\n styled,\n Typography,\n} from '@mui/material';\nimport type { FC, ReactNode } from 'react';\nimport React from 'react';\nimport { safeAreaBottom } from '../../../utils/viewport';\nimport {\n loadingOverlayStyles,\n modalContentStyles,\n titleLeftStyles,\n titleRightStyles,\n titleStyles,\n} from './StackedModal.styles';\n\nconst StyledDialogTitle = styled(DialogTitle, {\n shouldForwardProp: (prop) => prop !== 'rtl',\n})<{ rtl?: boolean }>(({ theme, rtl }) => titleStyles(theme, rtl));\n\nconst DialogTitleLeft = styled(Box)(({ theme }) => titleLeftStyles(theme));\nconst DialogTitleRight = styled(Box)(({ theme }) => titleRightStyles(theme));\nconst LoadingOverlay = styled(Box)(({ theme }) => loadingOverlayStyles(theme));\n\n/**\n * The padded content wrapper callers put inside a StackedModal. The explicit\n * `typeof DialogContent` annotation keeps its type nameable across package\n * boundaries (TS2742) now that it is re-exported from the barrel.\n */\nexport const StackedModalContent: typeof DialogContent = styled(DialogContent)(({ theme }) =>\n modalContentStyles(theme),\n) as typeof DialogContent;\n\n/** Sub-element test IDs derive from the modal's own, or stay off when it has none. */\nexport const testId = (base: string | undefined, suffix: string): string | undefined =>\n base ? `${base}-${suffix}` : undefined;\n\n/**\n * A wrapper marking the subtree that should render as modal actions — the\n * StackedModal pulls it out of `children` and places it by device.\n */\nexport const StackedModalActions: FC<{ children?: ReactNode }> = ({ children }) => <>{children}</>;\n\n/** Separates the `StackedModalActions` subtree from the rest of the content. */\nconst splitModalChildren = (children: ReactNode): { content: ReactNode; actions: ReactNode } => {\n let actions: ReactNode = null;\n\n React.Children.forEach(children, (child) => {\n if (React.isValidElement<{ children?: ReactNode }>(child) && child.type === StackedModalActions) {\n actions = child.props.children;\n }\n });\n\n const content = React.Children.toArray(children).filter(\n (child) => !(React.isValidElement(child) && child.type === StackedModalActions),\n );\n\n return { content, actions };\n};\n\n/**\n * Works out what renders where: a `StackedModalActions` child wins over the\n * `actions` prop, and on phones those actions move out of the header into a\n * pinned bottom bar.\n */\nexport const resolveModalContent = (\n children: ReactNode,\n actions: ReactNode,\n isMobile: boolean,\n): {\n content: ReactNode;\n modalActions: ReactNode;\n headerActions: ReactNode;\n hasMobileActions: boolean;\n} => {\n const { content, actions: childActions } = splitModalChildren(children);\n const modalActions = childActions ?? actions;\n return {\n content,\n modalActions,\n headerActions: isMobile ? null : modalActions,\n hasMobileActions: Boolean(isMobile && modalActions),\n };\n};\n\n/** The panel's own ARIA ids, unless the caller wired it to its own labels. */\nexport const modalAriaIds = (\n modalId: string,\n ariaLabelledBy?: string,\n ariaDescribedBy?: string,\n): { titleId: string; descId: string } => ({\n titleId: ariaLabelledBy || `modal-title-${modalId}`,\n descId: ariaDescribedBy || `modal-desc-${modalId}`,\n});\n\nexport const ModalLoadingOverlay: FC<{ loadingText?: string; dataTestId?: string }> = ({\n loadingText,\n dataTestId,\n}) => (\n <LoadingOverlay data-testid={testId(dataTestId, 'loading-overlay')}>\n <CircularProgress size={40} data-testid={testId(dataTestId, 'loading-spinner')} />\n {loadingText && (\n <Typography variant=\"body2\" sx={{ mt: 2 }} data-testid={testId(dataTestId, 'loading-text')}>\n {loadingText}\n </Typography>\n )}\n </LoadingOverlay>\n);\n\ninterface ModalHeaderProps {\n titleId: string;\n navigationTitle?: ReactNode;\n /** Deeper than the first panel, so the leading button goes back instead of closing. */\n canGoBack: boolean;\n onBack: () => void;\n onClose: () => void;\n /** Renders the bar without its ✕ — the panel's content owns the dismiss. */\n hideClose?: boolean;\n /** Header actions — desktop only; on phones they move to the footer. */\n headerActions?: ReactNode;\n rtl?: boolean;\n dataTestId?: string;\n}\n\n/**\n * The bar's leading control: back at depth ≥2, otherwise close — and nothing at\n * all when the panel's content carries its own ✕ (`hideClose`).\n */\nconst HeaderLeadingButton: FC<\n Pick<ModalHeaderProps, 'canGoBack' | 'onBack' | 'onClose' | 'hideClose' | 'rtl' | 'dataTestId'>\n> = ({ canGoBack, onBack, onClose, hideClose, rtl, dataTestId }) => {\n if (canGoBack) {\n return (\n <IconButton\n edge=\"start\"\n color=\"inherit\"\n onClick={onBack}\n aria-label=\"go back\"\n size=\"small\"\n sx={{ transform: rtl ? 'rotate(180deg)' : 'none' }}\n data-testid={testId(dataTestId, 'back-button')}\n >\n <ChevronLeftIcon />\n </IconButton>\n );\n }\n if (hideClose) return null;\n return (\n <IconButton\n edge=\"start\"\n color=\"inherit\"\n onClick={onClose}\n aria-label=\"close\"\n size=\"small\"\n data-testid={testId(dataTestId, 'close-button')}\n >\n <CloseIcon />\n </IconButton>\n );\n};\n\nexport const ModalHeader: FC<ModalHeaderProps> = ({\n titleId,\n navigationTitle,\n canGoBack,\n onBack,\n onClose,\n hideClose,\n headerActions,\n rtl,\n dataTestId,\n}) => (\n <StyledDialogTitle id={titleId} rtl={rtl} data-testid={testId(dataTestId, 'header')}>\n <DialogTitleLeft>\n <HeaderLeadingButton\n canGoBack={canGoBack}\n onBack={onBack}\n onClose={onClose}\n hideClose={hideClose}\n rtl={rtl}\n dataTestId={dataTestId}\n />\n {navigationTitle && (\n <Typography\n variant=\"h6\"\n component=\"h2\"\n noWrap\n sx={{ ml: canGoBack || !hideClose ? 1 : 0 }}\n data-testid={testId(dataTestId, 'title')}\n >\n {navigationTitle}\n </Typography>\n )}\n </DialogTitleLeft>\n <DialogTitleRight data-testid={testId(dataTestId, 'header-actions')}>\n {headerActions}\n </DialogTitleRight>\n </StyledDialogTitle>\n);\n\nconst ContentSkeleton: FC = () => (\n <Box sx={{ p: 3 }}>\n <Skeleton variant=\"text\" width=\"60%\" height={32} />\n <Skeleton variant=\"text\" width=\"100%\" />\n <Skeleton variant=\"text\" width=\"100%\" />\n <Skeleton variant=\"rectangular\" height={200} sx={{ mt: 2 }} />\n </Box>\n);\n\ninterface ModalBodyProps {\n descId: string;\n showSkeleton: boolean;\n /** When there is no action bar, the body is what reaches the bottom of the panel. */\n endsPanel: boolean;\n dataTestId?: string;\n children?: ReactNode;\n}\n\nexport const ModalBody: FC<ModalBodyProps> = ({\n descId,\n showSkeleton,\n endsPanel,\n dataTestId,\n children,\n}) => (\n <Box\n id={descId}\n sx={{\n position: 'relative',\n flex: 1,\n overflow: 'auto',\n // iOS momentum scrolling, and no scroll-chaining to the page behind —\n // without `contain`, an overscroll at the end of the list rubber-bands the\n // whole panel and springs back before the last row can be tapped.\n WebkitOverflowScrolling: 'touch',\n overscrollBehavior: 'contain',\n // The content itself ends the panel when there is no action bar, so it has\n // to clear the home indicator on its own.\n ...(endsPanel ? safeAreaBottom(0) : {}),\n }}\n data-testid={testId(dataTestId, 'content')}\n >\n {showSkeleton ? <ContentSkeleton /> : children}\n </Box>\n);\n\n/** The phone-only pinned action bar; on desktop the actions live in the header. */\nexport const ModalFooter: FC<{ dataTestId?: string; children?: ReactNode }> = ({\n dataTestId,\n children,\n}) => (\n <DialogActions\n sx={{\n borderTop: (theme) => `1px solid ${theme.palette.divider}`,\n padding: 2,\n // Never let the action row sit under the iOS home indicator.\n flexShrink: 0,\n ...safeAreaBottom(16),\n }}\n data-testid={testId(dataTestId, 'footer')}\n >\n {children}\n </DialogActions>\n);\n\ninterface PanelContentsProps extends ModalHeaderProps {\n showSkeleton: boolean;\n loadingText?: string;\n descId: string;\n content: ReactNode;\n /** The resolved actions, already placed in the header or destined for the footer. */\n modalActions: ReactNode;\n hasMobileActions: boolean;\n}\n\n/** Everything inside the sliding panel: the loading veil, header, body and action bar. */\nexport const ModalPanelContents: FC<PanelContentsProps> = ({\n showSkeleton,\n loadingText,\n descId,\n content,\n modalActions,\n hasMobileActions,\n ...header\n}) => (\n <>\n {showSkeleton && (\n <ModalLoadingOverlay loadingText={loadingText} dataTestId={header.dataTestId} />\n )}\n <ModalHeader {...header} />\n <ModalBody\n descId={descId}\n showSkeleton={showSkeleton}\n endsPanel={!hasMobileActions}\n dataTestId={header.dataTestId}\n >\n {content}\n </ModalBody>\n {hasMobileActions && (\n <ModalFooter dataTestId={header.dataTestId}>{modalActions}</ModalFooter>\n )}\n </>\n);\n","import { alpha } from '@mui/material';\nimport type { CSSObject, Theme } from '@mui/material';\nimport { dynamicViewportHeight } from '../../../utils/viewport';\nimport type { ModalPanelRole, PanelMaxWidth } from './StackedModal.types';\n\n/** Props that drive the panel's look but must not reach the DOM. */\nexport interface PanelStyleProps {\n modalRole?: ModalPanelRole;\n isAnimating?: boolean;\n glass?: boolean;\n rtl?: boolean;\n customMaxWidth?: PanelMaxWidth;\n}\n\n/** Style-only props, filtered out before they can land on a DOM node. */\nexport const STYLE_ONLY_PROPS = ['modalRole', 'isAnimating', 'glass', 'rtl', 'customMaxWidth'];\n\n/** MUI breakpoint names mapped to the pixel width they cap the panel at. */\nconst MAX_WIDTH_PX: Record<Exclude<PanelMaxWidth, false>, number> = {\n xs: 444,\n sm: 600,\n md: 960,\n lg: 1280,\n xl: 1920,\n};\n\nconst BACKDROP_BY_ROLE: Partial<Record<ModalPanelRole, string>> = {\n secondary: 'rgba(0, 0, 0, 0.3)',\n background: 'rgba(0, 0, 0, 0.1)',\n};\n\nconst ANIMATION_BY_ROLE: Partial<Record<ModalPanelRole, string>> = {\n secondary: 'expandModal 300ms ease-in-out forwards',\n primary: 'contractModal 300ms ease-in-out forwards',\n};\n\n// Animation endpoints use the common lg width (60vw); the role styles set the\n// exact per-breakpoint width once the animation settles.\nconst KEYFRAMES: CSSObject = {\n '@keyframes expandModal': {\n from: { width: '60vw', transform: 'translateX(0)' },\n to: { width: '100vw', transform: 'translateX(0)' },\n },\n '@keyframes contractModal': {\n from: { width: '100vw', transform: 'translateX(0)' },\n to: { width: '60vw', transform: 'translateX(0)' },\n },\n};\n\nconst cap = (customMaxWidth?: PanelMaxWidth): number | null =>\n customMaxWidth ? MAX_WIDTH_PX[customMaxWidth] : null;\n\n/** One breakpoint's width: the viewport share, held under the optional px cap. */\nconst panelWidth = (share: string, capPx: number | null): CSSObject =>\n capPx\n ? { width: `min(${share}, ${capPx}px)`, maxWidth: `${capPx}px` }\n : { width: share, maxWidth: share };\n\nconst backdropStyles = (modalRole?: ModalPanelRole): CSSObject => ({\n backgroundColor: (modalRole && BACKDROP_BY_ROLE[modalRole]) ?? 'rgba(0, 0, 0, 0.5)',\n backdropFilter: modalRole === 'primary' ? 'blur(4px)' : 'none',\n});\n\n/**\n * The top panel is viewport-aware and narrows as the screen grows: full width on\n * mobile, 80vw on tablet/small desktop, 60vw on regular desktops (lg up —\n * including ~1080p/1440p/1080-wide), and 40vw only on ultra-wide screens\n * (≥2200px) so the receding panel stays visible on huge monitors. A `maxWidth`\n * prop, when given, caps it further.\n */\nconst primaryPanelStyles = (theme: Theme, capPx: number | null): CSSObject => ({\n [theme.breakpoints.down('sm')]: panelWidth('100%', capPx),\n [theme.breakpoints.between('sm', 'lg')]: panelWidth('80vw', capPx),\n [theme.breakpoints.up('lg')]: panelWidth('60vw', capPx),\n '@media (min-width:2200px)': panelWidth('40vw', capPx),\n});\n\n/** Panels below the top one expand to full width, producing the GTM stacking effect. */\nconst secondaryPanelStyles = (): CSSObject => ({\n width: '100vw !important',\n maxWidth: '100vw !important',\n right: '0 !important',\n top: '0 !important',\n ...dynamicViewportHeight('height', 'maxHeight'),\n borderRadius: '0 !important',\n opacity: 0.95,\n transform: 'scale(1)',\n});\n\nconst rolePanelStyles = (theme: Theme, role: ModalPanelRole | undefined, capPx: number | null): CSSObject => {\n if (role === 'primary') return primaryPanelStyles(theme, capPx);\n if (role === 'secondary') return secondaryPanelStyles();\n // Background modals stay mounted but hidden, for performance.\n if (role === 'background') return { display: 'none' };\n return {};\n};\n\nconst glassStyles = (theme: Theme, glass?: boolean, role?: ModalPanelRole): CSSObject =>\n glass && role === 'primary'\n ? {\n backgroundColor: alpha(theme.palette.background.paper, 0.85),\n backdropFilter: 'blur(10px)',\n WebkitBackdropFilter: 'blur(10px)',\n border: `1px solid ${alpha(theme.palette.divider, 0.18)}`,\n }\n : {};\n\nconst animationStyles = (isAnimating?: boolean, role?: ModalPanelRole): CSSObject =>\n isAnimating ? { animation: (role && ANIMATION_BY_ROLE[role]) ?? 'none' } : {};\n\nconst panelBaseStyles = (theme: Theme): CSSObject => ({\n margin: 0,\n position: 'fixed',\n right: 0,\n top: 0,\n // Pinned to the DYNAMIC viewport: on iOS a `100vh` panel runs underneath the\n // browser toolbar, which parks the tail of the scroll area (the submit row)\n // out of reach. See `dynamicViewportHeight`.\n ...dynamicViewportHeight('height', 'maxHeight'),\n borderRadius: 0,\n willChange: 'transform, width, border-radius',\n transition: theme.transitions.create(\n ['width', 'max-width', 'border-radius', 'transform', 'opacity'],\n { duration: 300, easing: theme.transitions.easing.easeInOut },\n ),\n});\n\nconst panelStyles = (theme: Theme, props: PanelStyleProps): CSSObject => {\n const capPx = cap(props.customMaxWidth);\n return {\n ...panelBaseStyles(theme),\n ...rolePanelStyles(theme, props.modalRole, capPx),\n ...glassStyles(theme, props.glass, props.modalRole),\n ...animationStyles(props.isAnimating, props.modalRole),\n };\n};\n\n/** The full rule set for the sliding panel's Dialog root. */\nexport const dialogRootStyles = (theme: Theme, props: PanelStyleProps): CSSObject => ({\n direction: props.rtl ? 'rtl' : 'ltr',\n '& .MuiBackdrop-root': backdropStyles(props.modalRole),\n '& .MuiDialog-container': { alignItems: 'flex-start', justifyContent: 'flex-end' },\n '& .MuiDialog-paper': panelStyles(theme, props),\n ...KEYFRAMES,\n});\n\nexport const titleStyles = (theme: Theme, rtl?: boolean): CSSObject => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: theme.spacing(2, 2.5),\n borderBottom: `1px solid ${theme.palette.divider}`,\n direction: rtl ? 'rtl' : 'ltr',\n});\n\nexport const titleLeftStyles = (theme: Theme): CSSObject => ({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1.5),\n flex: 1,\n});\n\nexport const titleRightStyles = (theme: Theme): CSSObject => ({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n});\n\nexport const loadingOverlayStyles = (theme: Theme): CSSObject => ({\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: alpha(theme.palette.background.paper, 0.8),\n zIndex: 9999,\n});\n\nexport const modalContentStyles = (theme: Theme): CSSObject => ({\n padding: theme.spacing(3),\n // MUI's DialogContent defaults to `overflow-y: auto`, but inside a panel it is\n // NOT the element that scrolls — ModalBody above it is, and this box always\n // ends up exactly as tall as its own content. A scroll container that never\n // scrolls is still the containing block for every `position: sticky`\n // descendant, so a sticky header anchored here gets zero travel and rides the\n // content out of view: sticky, and pinned to nothing. Handing the overflow\n // back to ModalBody makes the panel's own scroller the anchor.\n overflowY: 'visible',\n});\n"],"mappings":"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","names":["styled","useEffect","useRef","useState","useEffect","useState","useRef","jsx","jsx","styled","SlideTransition"]}