@12-apps/ui 6.27.1 → 6.28.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 (583) hide show
  1. package/dist/_internal/components/data-display/Alert/Alert.js +5 -4
  2. package/dist/_internal/components/data-display/Alert/Alert.metrics.js +3 -2
  3. package/dist/_internal/components/data-display/Alert/Alert.styles.js +4 -3
  4. package/dist/_internal/components/data-display/AsyncStateContainer/AsyncStateContainer.js +4 -4
  5. package/dist/_internal/components/data-display/Avatar/Avatar.js +6 -5
  6. package/dist/_internal/components/data-display/Avatar/Avatar.view.js +4 -3
  7. package/dist/_internal/components/data-display/Badge/Badge.animations.js +4 -3
  8. package/dist/_internal/components/data-display/Badge/Badge.js +8 -7
  9. package/dist/_internal/components/data-display/Badge/Badge.metrics.js +3 -2
  10. package/dist/_internal/components/data-display/Badge/Badge.styles.js +6 -5
  11. package/dist/_internal/components/data-display/Badge/Badge.variants.js +4 -3
  12. package/dist/_internal/components/data-display/Badge/BadgeContent.js +7 -6
  13. package/dist/_internal/components/data-display/Banner/Banner.js +5 -4
  14. package/dist/_internal/components/data-display/Banner/Banner.styles.js +4 -3
  15. package/dist/_internal/components/data-display/CardKit/CardKebab.js +5 -4
  16. package/dist/_internal/components/data-display/CardKit/card-actions-context.js +6 -5
  17. package/dist/_internal/components/data-display/CardKit/use-remove-confirm.js +10 -9
  18. package/dist/_internal/components/data-display/CardKit/use-row-confirm.js +5 -4
  19. package/dist/_internal/components/data-display/Carousel/Carousel.chrome.js +2 -1
  20. package/dist/_internal/components/data-display/Carousel/Carousel.js +5 -4
  21. package/dist/_internal/components/data-display/Carousel/Carousel.parts.js +2 -1
  22. package/dist/_internal/components/data-display/Carousel/Carousel.styles.js +2 -1
  23. package/dist/_internal/components/data-display/Chart/Chart.js +5 -4
  24. package/dist/_internal/components/data-display/Chart/SpecChart.js +9 -8
  25. package/dist/_internal/components/data-display/Chart/chart-context.js +2 -1
  26. package/dist/_internal/components/data-display/Chart/chart-internals.js +2 -1
  27. package/dist/_internal/components/data-display/Chart/chart-renderers.js +4 -3
  28. package/dist/_internal/components/data-display/Chart/chart-spec.js +2 -2
  29. package/dist/_internal/components/data-display/DataGrid/DataGrid.body.js +2 -2
  30. package/dist/_internal/components/data-display/DataGrid/DataGrid.cells.js +1 -1
  31. package/dist/_internal/components/data-display/DataGrid/DataGrid.js +3 -3
  32. package/dist/_internal/components/data-display/DataViews/DataViewsBoard.js +5 -4
  33. package/dist/_internal/components/data-display/DataViews/DataViewsGrid.js +49 -47
  34. package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +68 -66
  35. package/dist/_internal/components/data-display/DataViews/DeleteViewDialog.js +9 -8
  36. package/dist/_internal/components/data-display/DataViews/ManageViewsDialog.js +10 -9
  37. package/dist/_internal/components/data-display/DataViews/SaveViewModal.js +15 -14
  38. package/dist/_internal/components/data-display/DataViews/base-card.js +11 -10
  39. package/dist/_internal/components/data-display/DataViews/base-list-card-geometry.js +12 -11
  40. package/dist/_internal/components/data-display/DataViews/base-list-card-gutters.js +4 -3
  41. package/dist/_internal/components/data-display/DataViews/base-list-card-slots.js +8 -7
  42. package/dist/_internal/components/data-display/DataViews/base-list-card.js +17 -16
  43. package/dist/_internal/components/data-display/DataViews/card-surface.js +5 -4
  44. package/dist/_internal/components/data-display/DataViews/data-views-category-pill.js +8 -8
  45. package/dist/_internal/components/data-display/DataViews/data-views-columns-tab.js +5 -4
  46. package/dist/_internal/components/data-display/DataViews/data-views-columns.js +6 -5
  47. package/dist/_internal/components/data-display/DataViews/data-views-display-panel.js +10 -9
  48. package/dist/_internal/components/data-display/DataViews/data-views-display-tabs.js +5 -4
  49. package/dist/_internal/components/data-display/DataViews/data-views-empty.js +7 -6
  50. package/dist/_internal/components/data-display/DataViews/data-views-export.js +7 -6
  51. package/dist/_internal/components/data-display/DataViews/data-views-filter-panel.js +11 -11
  52. package/dist/_internal/components/data-display/DataViews/data-views-grid-bodies.js +16 -14
  53. package/dist/_internal/components/data-display/DataViews/data-views-grid-helpers.js +5 -4
  54. package/dist/_internal/components/data-display/DataViews/data-views-grid-parts.js +45 -43
  55. package/dist/_internal/components/data-display/DataViews/data-views-header-row.js +5 -4
  56. package/dist/_internal/components/data-display/DataViews/data-views-inline-bar.js +19 -18
  57. package/dist/_internal/components/data-display/DataViews/data-views-more-fields.js +8 -7
  58. package/dist/_internal/components/data-display/DataViews/data-views-more-filters.js +11 -10
  59. package/dist/_internal/components/data-display/DataViews/data-views-range-pill.js +2 -2
  60. package/dist/_internal/components/data-display/DataViews/data-views-row-detail.js +8 -0
  61. package/dist/_internal/components/data-display/DataViews/data-views-row-detail.js.map +1 -0
  62. package/dist/_internal/components/data-display/DataViews/data-views-scope-tabs.js +2 -2
  63. package/dist/_internal/components/data-display/DataViews/data-views-select-all-strip.js +7 -6
  64. package/dist/_internal/components/data-display/DataViews/data-views-shell-toolbar.js +15 -14
  65. package/dist/_internal/components/data-display/DataViews/data-views-table-parts.js +22 -21
  66. package/dist/_internal/components/data-display/DataViews/data-views-toolbar.js +14 -13
  67. package/dist/_internal/components/data-display/DataViews/data-views-view-nav.js +7 -6
  68. package/dist/_internal/components/data-display/DataViews/list-card-rails.js +2 -2
  69. package/dist/_internal/components/data-display/DataViews/save-view-preview.js +5 -4
  70. package/dist/_internal/components/data-display/DataViews/use-data-views-state.js +8 -7
  71. package/dist/_internal/components/data-display/DataViews/use-saved-views-controller.js +2 -2
  72. package/dist/_internal/components/data-display/DescriptionItem/DescriptionItem.js +5 -4
  73. package/dist/_internal/components/data-display/FleetMap/FleetBody.js +15 -15
  74. package/dist/_internal/components/data-display/FleetMap/FleetCanvas.js +11 -11
  75. package/dist/_internal/components/data-display/FleetMap/FleetMap.js +18 -17
  76. package/dist/_internal/components/data-display/FleetMap/FleetRoster.js +3 -3
  77. package/dist/_internal/components/data-display/LazyImage/LazyImage.js +3 -3
  78. package/dist/_internal/components/data-display/Lightbox/Lightbox.js +4 -4
  79. package/dist/_internal/components/data-display/LoadingState/LoadingState.js +3 -3
  80. package/dist/_internal/components/data-display/MapPreview/MapDecorations.js +2 -2
  81. package/dist/_internal/components/data-display/MapPreview/MapMarkers.js +2 -2
  82. package/dist/_internal/components/data-display/MapPreview/MapPreview.hooks.js +2 -2
  83. package/dist/_internal/components/data-display/MapPreview/MapPreview.js +10 -10
  84. package/dist/_internal/components/data-display/MapPreview/MapTiles.js +2 -2
  85. package/dist/_internal/components/data-display/MapPreview/StaticMapView.js +4 -4
  86. package/dist/_internal/components/data-display/MapPreview/useMapPreview.js +3 -3
  87. package/dist/_internal/components/data-display/Progress/Progress.js +5 -4
  88. package/dist/_internal/components/data-display/Progress/Progress.metrics.js +3 -2
  89. package/dist/_internal/components/data-display/Progress/Progress.styles.js +4 -3
  90. package/dist/_internal/components/data-display/Sheet/Sheet.body.js +2 -1
  91. package/dist/_internal/components/data-display/Sheet/Sheet.js +4 -3
  92. package/dist/_internal/components/data-display/Sheet/Sheet.styles.js +2 -1
  93. package/dist/_internal/components/data-display/StatCard/StatCard.js +3 -3
  94. package/dist/_internal/components/data-display/Table/Table.js +2 -2
  95. package/dist/_internal/components/data-display/index.js +74 -73
  96. package/dist/_internal/components/feedback/ConfirmAction/ConfirmButton.js +5 -4
  97. package/dist/_internal/components/feedback/Dialog/Dialog.js +2 -2
  98. package/dist/_internal/components/feedback/TutorialOverlay/TutorialOverlay.js +2 -2
  99. package/dist/_internal/components/feedback/index.js +9 -8
  100. package/dist/_internal/components/form/AddressAutocomplete/AddressAutocomplete.hooks.js +4 -4
  101. package/dist/_internal/components/form/AddressAutocomplete/AddressAutocomplete.js +6 -6
  102. package/dist/_internal/components/form/Button/Button.js +4 -3
  103. package/dist/_internal/components/form/Button/Button.styles.js +3 -2
  104. package/dist/_internal/components/form/Calendar/Calendar.js +2 -2
  105. package/dist/_internal/components/form/CategorySelect/CategoryPanel.js +4 -4
  106. package/dist/_internal/components/form/CategorySelect/CategoryPanelList.js +3 -3
  107. package/dist/_internal/components/form/CategorySelect/CategoryRows.js +2 -2
  108. package/dist/_internal/components/form/CategorySelect/CategorySelect.js +6 -6
  109. package/dist/_internal/components/form/CepField/CepField.js +3 -3
  110. package/dist/_internal/components/form/Checkbox/Checkbox.js +3 -2
  111. package/dist/_internal/components/form/CodeEditor/CodeEditor.js +2 -2
  112. package/dist/_internal/components/form/Command/Command.js +4 -3
  113. package/dist/_internal/components/form/Command/Command.styles.js +2 -1
  114. package/dist/_internal/components/form/DateRangePicker/DateRangePicker.js +3 -3
  115. package/dist/_internal/components/form/Input/Input.js +2 -2
  116. package/dist/_internal/components/form/Label/Label.js +2 -1
  117. package/dist/_internal/components/form/Label/Label.styles.js +2 -1
  118. package/dist/_internal/components/form/Menubar/Menubar.item.js +2 -1
  119. package/dist/_internal/components/form/Menubar/Menubar.js +2 -1
  120. package/dist/_internal/components/form/Menubar/Menubar.styles.js +2 -1
  121. package/dist/_internal/components/form/Menubar/Menubar.toolbar.js +2 -1
  122. package/dist/_internal/components/form/Switch/Switch.js +5 -4
  123. package/dist/_internal/components/form/Switch/Switch.parts.js +4 -3
  124. package/dist/_internal/components/form/Switch/Switch.styles.js +3 -2
  125. package/dist/_internal/components/form/index.js +24 -23
  126. package/dist/_internal/components/form/total-form/Fields/CategoryField.js +7 -7
  127. package/dist/_internal/components/form/total-form/Fields/CepField.js +4 -4
  128. package/dist/_internal/components/form/total-form/Fields/TextField.js +3 -3
  129. package/dist/_internal/components/form/total-form/Fields/index.js +15 -15
  130. package/dist/_internal/components/form/total-form/SubmitButton.js +5 -4
  131. package/dist/_internal/components/index.js +122 -121
  132. package/dist/_internal/components/layout/Box/Box.js +5 -4
  133. package/dist/_internal/components/layout/Card/Card.js +2 -2
  134. package/dist/_internal/components/layout/ScrollArea/ScrollArea.js +2 -2
  135. package/dist/_internal/components/layout/SettingsLayout/SettingsLayout.js +4 -4
  136. package/dist/_internal/components/layout/SettingsLayout/SettingsPanel.js +2 -2
  137. package/dist/_internal/components/layout/Skeleton/Skeleton.js +2 -2
  138. package/dist/_internal/components/layout/Stack/Stack.js +6 -5
  139. package/dist/_internal/components/layout/index.js +9 -9
  140. package/dist/_internal/components/navigation/AppHeader/AppHeader.details.js +9 -8
  141. package/dist/_internal/components/navigation/AppHeader/AppHeader.identity.js +2 -1
  142. package/dist/_internal/components/navigation/NavigationMenu/NavigationMegaSection.js +3 -3
  143. package/dist/_internal/components/navigation/NavigationMenu/NavigationMenu.js +5 -5
  144. package/dist/_internal/components/navigation/NavigationMenu/NavigationMenuItem.js +2 -2
  145. package/dist/_internal/components/navigation/NavigationMenu/NavigationStandardBody.js +3 -3
  146. package/dist/_internal/components/navigation/Tabs/Tabs.js +2 -2
  147. package/dist/_internal/components/navigation/index.js +18 -17
  148. package/dist/_internal/components/typography/Heading/Heading.js +5 -4
  149. package/dist/_internal/components/typography/Heading/Heading.metrics.js +3 -2
  150. package/dist/_internal/components/typography/Heading/Heading.styles.js +4 -3
  151. package/dist/_internal/components/typography/Paragraph/Paragraph.js +3 -2
  152. package/dist/_internal/components/typography/Text/Text.js +4 -3
  153. package/dist/_internal/components/typography/Text/Text.metrics.js +3 -2
  154. package/dist/_internal/components/typography/index.js +8 -7
  155. package/dist/_internal/icons/Icon.js +5 -4
  156. package/dist/_internal/provider/UiProvider.js +4 -3
  157. package/dist/_internal/provider/mui-bridge.js +3 -2
  158. package/dist/_internal/provider/use-ui-theme.js +4 -3
  159. package/dist/_internal/social-login-button/social-login-button.js +12 -11
  160. package/dist/_internal/tokens/ink-over.js +17 -0
  161. package/dist/_internal/tokens/ink-over.js.map +1 -0
  162. package/dist/_internal/tokens/theme.js +5 -3
  163. package/dist/_internal/user-avatar/user-avatar.js +13 -12
  164. package/dist/charts.js +19 -18
  165. package/dist/{chunk-Q3GSDSK2.js → chunk-236QP424.js} +2 -2
  166. package/dist/{chunk-JFRKBSWI.js → chunk-237NDIT2.js} +2 -2
  167. package/dist/chunk-2BYKTBDL.js +33 -0
  168. package/dist/chunk-2BYKTBDL.js.map +1 -0
  169. package/dist/{chunk-TQOPF7LD.js → chunk-2L2NWXWJ.js} +2 -2
  170. package/dist/{chunk-M4NFXC5R.js → chunk-2WSU6OGE.js} +5 -5
  171. package/dist/{chunk-72T5PAW7.js → chunk-3BPDHWVF.js} +9 -9
  172. package/dist/{chunk-EOHKZGOZ.js → chunk-3PUOLOEP.js} +2 -2
  173. package/dist/{chunk-ECMJ5VPW.js → chunk-3TFUAKWJ.js} +2 -2
  174. package/dist/{chunk-4ETQRBZC.js → chunk-46UPILLK.js} +4 -4
  175. package/dist/{chunk-6VHCSPKK.js → chunk-4H4Y2SX3.js} +3 -3
  176. package/dist/{chunk-L7S6N67X.js → chunk-4OSGKO7E.js} +2 -2
  177. package/dist/{chunk-UG76BO5K.js → chunk-5KFZGB5U.js} +2 -2
  178. package/dist/{chunk-FF3R67WD.js → chunk-5UC2RNOY.js} +4 -4
  179. package/dist/{chunk-EMNGIYH6.js → chunk-7TZ6OC5T.js} +5 -5
  180. package/dist/{chunk-G2JPUHEJ.js → chunk-AIBNBWQU.js} +2 -2
  181. package/dist/{chunk-QE2C35TO.js → chunk-ALAJBLBE.js} +5 -5
  182. package/dist/{chunk-E5LWJDI3.js → chunk-AROBXRC5.js} +11 -5
  183. package/dist/chunk-AROBXRC5.js.map +1 -0
  184. package/dist/{chunk-AIRWM7KK.js → chunk-AVI3XHRQ.js} +4 -4
  185. package/dist/{chunk-IE7ISTLQ.js → chunk-B443IIQG.js} +4 -4
  186. package/dist/{chunk-CKJI7JO5.js → chunk-BEWD734I.js} +2 -2
  187. package/dist/{chunk-RRX6ZTNX.js → chunk-BLT5ZBVL.js} +2 -2
  188. package/dist/{chunk-MDTSMJ7C.js → chunk-BYMWW65P.js} +3 -3
  189. package/dist/{chunk-Q3OFOOO7.js → chunk-C5EFVSBN.js} +2 -2
  190. package/dist/{chunk-Y55ILY2F.js → chunk-C5YBXQTK.js} +3 -3
  191. package/dist/{chunk-YANLN6HP.js → chunk-D6HDJVQW.js} +5 -5
  192. package/dist/{chunk-DIHVWBQV.js → chunk-DEE6IPGI.js} +32 -6
  193. package/dist/chunk-DEE6IPGI.js.map +1 -0
  194. package/dist/{chunk-ZA4U5GDU.js → chunk-DORPR2YP.js} +2 -2
  195. package/dist/{chunk-6YLAVHV4.js → chunk-DTKMBI7B.js} +4 -4
  196. package/dist/{chunk-5QUSX3TC.js → chunk-DVE53B2L.js} +7 -7
  197. package/dist/chunk-DVE53B2L.js.map +1 -0
  198. package/dist/{chunk-JXNT5TUP.js → chunk-DVEYD27F.js} +2 -2
  199. package/dist/{chunk-WZUNBSS7.js → chunk-DVUPIVI2.js} +4 -4
  200. package/dist/{chunk-CMN26J5Y.js → chunk-E6D2Y5EK.js} +2 -2
  201. package/dist/{chunk-HKB5C2KY.js → chunk-EMAX7RPN.js} +5 -5
  202. package/dist/{chunk-ZAJO2B75.js → chunk-EPRA5QLB.js} +2 -2
  203. package/dist/{chunk-ERX4XIYC.js → chunk-EUKYQXYU.js} +2 -2
  204. package/dist/{chunk-C3CMEDSO.js → chunk-EVXFEXBS.js} +2 -2
  205. package/dist/{chunk-O7HLQTB7.js → chunk-EYC6ERJJ.js} +3 -3
  206. package/dist/chunk-EYC6ERJJ.js.map +1 -0
  207. package/dist/{chunk-DYESJJ3Q.js → chunk-EZNTM6PT.js} +4 -4
  208. package/dist/{chunk-67ALTEWH.js → chunk-FGKKLHKY.js} +2 -2
  209. package/dist/{chunk-OXYR2HVK.js → chunk-FOKBP6HR.js} +10 -10
  210. package/dist/{chunk-22X7TT6Z.js → chunk-FR6AJSMT.js} +5 -5
  211. package/dist/{chunk-TUO47RL2.js → chunk-FVPN4YKW.js} +4 -4
  212. package/dist/{chunk-ZDWU52DJ.js → chunk-G5ZVD5IJ.js} +2 -2
  213. package/dist/{chunk-NPN7JTRM.js → chunk-GH2DC7PS.js} +4 -4
  214. package/dist/{chunk-77DF5LKI.js → chunk-GJUIZ5FN.js} +2 -2
  215. package/dist/{chunk-YJ4HM25H.js → chunk-GLWW2XCP.js} +2 -2
  216. package/dist/{chunk-7AIHK2XM.js → chunk-H53YNR23.js} +6 -6
  217. package/dist/{chunk-GT7C6TSM.js → chunk-HDNK7BAX.js} +3 -3
  218. package/dist/{chunk-7NEUPEV5.js → chunk-HQB5XNK5.js} +2 -2
  219. package/dist/{chunk-SZETT7QV.js → chunk-HS2OJI6L.js} +8 -8
  220. package/dist/{chunk-KZLLTOB2.js → chunk-HTZNB6IV.js} +2 -2
  221. package/dist/{chunk-NNXZ5RK5.js → chunk-IQ7WZ3RN.js} +4 -4
  222. package/dist/{chunk-7KEGJH3Q.js → chunk-IVVOIDE5.js} +3 -3
  223. package/dist/{chunk-45OHGD2B.js → chunk-J2K65BQQ.js} +4 -4
  224. package/dist/{chunk-SSWZHR46.js → chunk-J3ZP6EUS.js} +5 -5
  225. package/dist/{chunk-YPILHGEO.js → chunk-J6CSPDC7.js} +2 -2
  226. package/dist/{chunk-RRO2EOJB.js → chunk-JB67KPGM.js} +4 -4
  227. package/dist/{chunk-V5P5Q6HM.js → chunk-JOXBCXVL.js} +8 -8
  228. package/dist/{chunk-LO2B7FDQ.js → chunk-JPVDZXXX.js} +2 -2
  229. package/dist/{chunk-P7FQUGED.js → chunk-JRWPI4XF.js} +5 -5
  230. package/dist/{chunk-OVGASVPW.js → chunk-JVVTSSS4.js} +2 -2
  231. package/dist/{chunk-IASDP44E.js → chunk-K4N3V7YE.js} +4 -4
  232. package/dist/{chunk-L7LCSZ3H.js → chunk-K7DCYV5Q.js} +3 -3
  233. package/dist/{chunk-B5SW7I5W.js → chunk-L4D6YLLU.js} +2 -2
  234. package/dist/{chunk-FOF2RAVQ.js → chunk-L6TCIZFR.js} +4 -4
  235. package/dist/{chunk-7Z2AQEC5.js → chunk-LCXXPIG3.js} +2 -2
  236. package/dist/{chunk-MQPT254A.js → chunk-LSJY4LWZ.js} +4 -4
  237. package/dist/{chunk-CA7TA36R.js → chunk-MGPA6KTM.js} +2 -2
  238. package/dist/{chunk-OGHW7RQC.js → chunk-MHSTG7FF.js} +3 -3
  239. package/dist/{chunk-GQJ4NCZ6.js → chunk-MNSW33DU.js} +4 -4
  240. package/dist/{chunk-WETAIIKC.js → chunk-MRMNVGNX.js} +2 -2
  241. package/dist/{chunk-MYH7VISV.js → chunk-MSUSZLRE.js} +5 -5
  242. package/dist/{chunk-WKF54CCK.js → chunk-MVJYIHPH.js} +5 -5
  243. package/dist/{chunk-EQA4VQEO.js → chunk-NGM5XKAS.js} +2 -2
  244. package/dist/{chunk-PKFFJAQ6.js → chunk-NGVGTMHT.js} +2 -2
  245. package/dist/{chunk-3GB6KWHH.js → chunk-NUB4T3RQ.js} +2 -2
  246. package/dist/{chunk-GTLJYAEG.js → chunk-NWQWUYOV.js} +2 -2
  247. package/dist/{chunk-QXFPTRHB.js → chunk-NY2Y2SHA.js} +4 -4
  248. package/dist/{chunk-4A2Q22HO.js → chunk-O42ZA3TW.js} +3 -3
  249. package/dist/chunk-O5UGAL2V.js +15 -0
  250. package/dist/chunk-O5UGAL2V.js.map +1 -0
  251. package/dist/{chunk-DTIB5KWP.js → chunk-OJCK5RNJ.js} +3 -3
  252. package/dist/{chunk-OAWEUKUC.js → chunk-OLQDB346.js} +2 -2
  253. package/dist/{chunk-4IVOHL32.js → chunk-OP6F3NXX.js} +2 -2
  254. package/dist/{chunk-DWJBOR47.js → chunk-P3NRT6GV.js} +4 -4
  255. package/dist/{chunk-GBX5ACPF.js → chunk-PCYGUOWJ.js} +4 -4
  256. package/dist/{chunk-3PJLT5FX.js → chunk-PFZAUMJA.js} +5 -3
  257. package/dist/{chunk-3PJLT5FX.js.map → chunk-PFZAUMJA.js.map} +1 -1
  258. package/dist/{chunk-N5PY7IXI.js → chunk-PJTSGHTY.js} +2 -2
  259. package/dist/{chunk-AGYGNNOM.js → chunk-PQECNGDE.js} +2 -2
  260. package/dist/{chunk-XNOSTV5F.js → chunk-PTP3CZL4.js} +2 -2
  261. package/dist/{chunk-LGJ2H4AH.js → chunk-PVIAHB7D.js} +10 -10
  262. package/dist/{chunk-SC72DRTX.js → chunk-QGAYEBMU.js} +14 -8
  263. package/dist/chunk-QGAYEBMU.js.map +1 -0
  264. package/dist/{chunk-X5RDHO6G.js → chunk-QPDDS6DQ.js} +2 -2
  265. package/dist/{chunk-6SK3MTYJ.js → chunk-QSKJLMNS.js} +4 -4
  266. package/dist/{chunk-GYQT47YZ.js → chunk-QTZ7I6QS.js} +2 -2
  267. package/dist/{chunk-WBKWIFXA.js → chunk-QYNCPS5W.js} +6 -6
  268. package/dist/{chunk-DFLTUI7W.js → chunk-QZBUGUOY.js} +4 -4
  269. package/dist/{chunk-GOWBYHYW.js → chunk-R6SBP5M5.js} +4 -4
  270. package/dist/{chunk-FGK2C7JR.js → chunk-RVGG5YJY.js} +2 -2
  271. package/dist/{chunk-7FOOLP5H.js → chunk-RXSGHPCR.js} +4 -4
  272. package/dist/{chunk-LUMF63BM.js → chunk-SFAP5EH5.js} +4 -4
  273. package/dist/{chunk-DW6GBMLQ.js → chunk-SLMA4UQS.js} +3 -3
  274. package/dist/{chunk-QRX5BYUQ.js → chunk-SOCKK67R.js} +7 -7
  275. package/dist/{chunk-QLI7ES7Z.js → chunk-SONWG2RT.js} +5 -18
  276. package/dist/chunk-SONWG2RT.js.map +1 -0
  277. package/dist/{chunk-G76H5PEM.js → chunk-SQV3HPTZ.js} +4 -4
  278. package/dist/{chunk-IV5QQLCS.js → chunk-T2VO32Z2.js} +2 -2
  279. package/dist/{chunk-VK4ULJFH.js → chunk-T5WNNEP5.js} +2 -2
  280. package/dist/{chunk-FRW4SYZD.js → chunk-TEE6HNHS.js} +4 -4
  281. package/dist/{chunk-JD3D6Y4U.js → chunk-THOPGHTY.js} +7 -7
  282. package/dist/{chunk-2LSCK45B.js → chunk-TSEWUY4V.js} +5 -3
  283. package/dist/{chunk-2LSCK45B.js.map → chunk-TSEWUY4V.js.map} +1 -1
  284. package/dist/{chunk-65METCKT.js → chunk-TSFFZ3AH.js} +20 -19
  285. package/dist/chunk-TSFFZ3AH.js.map +1 -0
  286. package/dist/{chunk-EZ5Z5UFI.js → chunk-TTW4MAOJ.js} +5 -5
  287. package/dist/{chunk-DTC224UJ.js → chunk-TX3ZHO5R.js} +5 -5
  288. package/dist/{chunk-H3BQFEN5.js → chunk-UC6A6ASM.js} +2 -2
  289. package/dist/{chunk-GSTRPZS4.js → chunk-UKPZVX3J.js} +2 -2
  290. package/dist/{chunk-EPNCYUQ7.js → chunk-UN5INW6K.js} +4 -4
  291. package/dist/{chunk-UGL6SJN6.js → chunk-UQNB2W2I.js} +3 -3
  292. package/dist/{chunk-P7IVAMAU.js → chunk-V7F53GEO.js} +7 -7
  293. package/dist/{chunk-ZC7RQDZ5.js → chunk-VESIQYBF.js} +5 -5
  294. package/dist/{chunk-2KVQIGVE.js → chunk-VKH7AENA.js} +2 -2
  295. package/dist/{chunk-S7HRED4D.js → chunk-VLHGBFR6.js} +3 -3
  296. package/dist/{chunk-SMZBGHR2.js → chunk-VRKS5K4N.js} +5 -5
  297. package/dist/{chunk-PW2WLDX3.js → chunk-VVXA7T2M.js} +2 -2
  298. package/dist/{chunk-2SWQ6HIK.js → chunk-W3FAKT3D.js} +4 -4
  299. package/dist/{chunk-QQLGSMGE.js → chunk-W5CW7JFZ.js} +2 -2
  300. package/dist/{chunk-HOJL2GKW.js → chunk-WC3W36AM.js} +4 -4
  301. package/dist/{chunk-3VZT2FAI.js → chunk-WC5XYWTE.js} +3 -3
  302. package/dist/{chunk-RFZU5BTG.js → chunk-WYDGPJ3Z.js} +4 -4
  303. package/dist/{chunk-27BL3DNT.js → chunk-XBZ43VIV.js} +9 -9
  304. package/dist/{chunk-KOFO6QZY.js → chunk-XGOWREVV.js} +2 -2
  305. package/dist/{chunk-KAV63FBG.js → chunk-XOCLWQON.js} +3 -3
  306. package/dist/{chunk-DF2FFYZ7.js → chunk-XSJWN3WH.js} +7 -7
  307. package/dist/{chunk-DB2MAYPK.js → chunk-XV2TDULR.js} +2 -2
  308. package/dist/{chunk-4OHRZW7U.js → chunk-XXE6NTJB.js} +4 -4
  309. package/dist/{chunk-4G3FGCWX.js → chunk-XXJRT6BP.js} +2 -2
  310. package/dist/{chunk-LV4UTYAD.js → chunk-XYDW5RQB.js} +2 -2
  311. package/dist/{chunk-7VN7LFBA.js → chunk-YD77RANW.js} +5 -5
  312. package/dist/{chunk-77OXG6DH.js → chunk-YFY3YVV6.js} +7 -7
  313. package/dist/{chunk-PENJBKPH.js → chunk-YTYROOLY.js} +3 -3
  314. package/dist/data-display/Alert.js +5 -4
  315. package/dist/data-display/AsyncStateContainer.js +4 -4
  316. package/dist/data-display/Avatar.js +6 -5
  317. package/dist/data-display/Badge.js +8 -7
  318. package/dist/data-display/Banner.js +5 -4
  319. package/dist/data-display/CardKit.js +13 -12
  320. package/dist/data-display/Carousel.js +5 -4
  321. package/dist/data-display/Chart.js +19 -18
  322. package/dist/data-display/DataGrid.js +3 -3
  323. package/dist/data-display/DataViews.js +87 -85
  324. package/dist/data-display/DescriptionItem.js +5 -4
  325. package/dist/data-display/FleetMap.js +18 -17
  326. package/dist/data-display/LazyImage.js +3 -3
  327. package/dist/data-display/Lightbox.js +4 -4
  328. package/dist/data-display/LoadingState.js +3 -3
  329. package/dist/data-display/MapPreview.js +10 -10
  330. package/dist/data-display/Progress.js +5 -4
  331. package/dist/data-display/Sheet.js +4 -3
  332. package/dist/data-display/StatCard.js +3 -3
  333. package/dist/data-display/Table.js +2 -2
  334. package/dist/feedback/ConfirmAction.js +5 -4
  335. package/dist/feedback/Dialog.js +2 -2
  336. package/dist/feedback/TutorialOverlay.js +2 -2
  337. package/dist/form/AddressAutocomplete.js +6 -6
  338. package/dist/form/Button.js +4 -3
  339. package/dist/form/Calendar.js +2 -2
  340. package/dist/form/CategorySelect.js +8 -8
  341. package/dist/form/CepField.js +3 -3
  342. package/dist/form/Checkbox.js +3 -2
  343. package/dist/form/CodeEditor.js +2 -2
  344. package/dist/form/Command.js +4 -3
  345. package/dist/form/DateRangePicker.js +3 -3
  346. package/dist/form/Input.js +2 -2
  347. package/dist/form/Label.js +2 -1
  348. package/dist/form/Menubar.js +2 -1
  349. package/dist/form/Switch.js +5 -4
  350. package/dist/form/total-form.js +20 -19
  351. package/dist/icons.js +5 -4
  352. package/dist/layout/Box.js +5 -4
  353. package/dist/layout/Card.js +2 -2
  354. package/dist/layout/ContentToolbar.js +3 -3
  355. package/dist/layout/ScrollArea.js +2 -2
  356. package/dist/layout/SettingsLayout.js +6 -6
  357. package/dist/layout/Skeleton.js +2 -2
  358. package/dist/layout/Stack.js +6 -5
  359. package/dist/native/chunks/{chunk-XI7HTAVN.js → chunk-2HLEFYJ5.js} +2 -2
  360. package/dist/native/chunks/{chunk-UYREIOEM.js → chunk-6XDMYJBW.js} +2 -2
  361. package/dist/native/chunks/{chunk-6L4UZBQP.js → chunk-BEPOBULQ.js} +3 -3
  362. package/dist/native/chunks/{chunk-ZOP7UAZK.js → chunk-CO47ZRXO.js} +2 -2
  363. package/dist/native/chunks/{chunk-UII3IFLP.js → chunk-NVPXIJ2O.js} +2 -2
  364. package/dist/native/chunks/{chunk-2SBTJSQE.js → chunk-SOQVMWLQ.js} +5 -5
  365. package/dist/native/chunks/{chunk-MP3UDWTT.js → chunk-YQDDM6ZW.js} +24 -17
  366. package/dist/native/chunks/chunk-YQDDM6ZW.js.map +1 -0
  367. package/dist/native/chunks/{chunk-QEQZ5AF6.js → chunk-YXM4NR2B.js} +3 -3
  368. package/dist/native/data-display/Alert.js +3 -3
  369. package/dist/native/data-display/Avatar.js +3 -3
  370. package/dist/native/data-display/Badge.js +3 -3
  371. package/dist/native/data-display/Chip.js +3 -3
  372. package/dist/native/data-display/EmptyState.js +5 -5
  373. package/dist/native/data-display/ErrorState.js +4 -4
  374. package/dist/native/data-display/FleetMap.js +6 -6
  375. package/dist/native/data-display/LoadingState.js +2 -2
  376. package/dist/native/data-display/Progress.js +2 -2
  377. package/dist/native/feedback/Dialog.js +3 -3
  378. package/dist/native/form/Button.js +3 -3
  379. package/dist/native/form/Checkbox.js +3 -3
  380. package/dist/native/form/Input.js +3 -3
  381. package/dist/native/form/Select.js +4 -4
  382. package/dist/native/form/Switch.js +2 -2
  383. package/dist/native/icons.js +3 -3
  384. package/dist/native/layout/Box.js +3 -3
  385. package/dist/native/layout/Card.js +2 -2
  386. package/dist/native/layout/Container.js +2 -2
  387. package/dist/native/layout/Skeleton.js +3 -3
  388. package/dist/native/layout/Spacer.js +2 -2
  389. package/dist/native/layout/Stack.js +3 -3
  390. package/dist/native/provider.js +2 -2
  391. package/dist/native/tokens.js +1 -1
  392. package/dist/native/typography/Heading.js +2 -2
  393. package/dist/native/typography/Paragraph.js +2 -2
  394. package/dist/native/typography/Text.js +2 -2
  395. package/dist/navigation/AppHeader.js +11 -10
  396. package/dist/navigation/NavigationMenu.js +5 -5
  397. package/dist/navigation/Tabs.js +2 -2
  398. package/dist/provider.js +5 -4
  399. package/dist/social-login-button.js +12 -11
  400. package/dist/tokens.js +5 -3
  401. package/dist/types/components/data-display/DataGrid/DataGrid.cells.d.ts.map +1 -1
  402. package/dist/types/components/data-display/DataGrid/DataGrid.types.d.ts +10 -0
  403. package/dist/types/components/data-display/DataGrid/DataGrid.types.d.ts.map +1 -1
  404. package/dist/types/components/data-display/DataViews/DataViewsGrid.d.ts +6 -0
  405. package/dist/types/components/data-display/DataViews/DataViewsGrid.d.ts.map +1 -1
  406. package/dist/types/components/data-display/DataViews/DataViewsTableBase.d.ts +3 -0
  407. package/dist/types/components/data-display/DataViews/DataViewsTableBase.d.ts.map +1 -1
  408. package/dist/types/components/data-display/DataViews/data-views-grid-bodies.d.ts +3 -0
  409. package/dist/types/components/data-display/DataViews/data-views-grid-bodies.d.ts.map +1 -1
  410. package/dist/types/components/data-display/DataViews/data-views-grid-parts.d.ts +3 -0
  411. package/dist/types/components/data-display/DataViews/data-views-grid-parts.d.ts.map +1 -1
  412. package/dist/types/components/data-display/DataViews/data-views-row-detail.d.ts +27 -0
  413. package/dist/types/components/data-display/DataViews/data-views-row-detail.d.ts.map +1 -0
  414. package/dist/types/components/data-display/DataViews/index.d.ts +1 -0
  415. package/dist/types/components/data-display/DataViews/index.d.ts.map +1 -1
  416. package/dist/types/components/form/Switch/Switch.styles.d.ts.map +1 -1
  417. package/dist/types/tokens/ink-over.d.ts +12 -0
  418. package/dist/types/tokens/ink-over.d.ts.map +1 -0
  419. package/dist/types/tokens/theme.d.ts +2 -44
  420. package/dist/types/tokens/theme.d.ts.map +1 -1
  421. package/dist/types-native/tokens/ink-over.d.ts +12 -0
  422. package/dist/types-native/tokens/ink-over.d.ts.map +1 -0
  423. package/dist/types-native/tokens/theme.d.ts +2 -44
  424. package/dist/types-native/tokens/theme.d.ts.map +1 -1
  425. package/dist/typography/Heading.js +5 -4
  426. package/dist/typography/Paragraph.js +3 -2
  427. package/dist/typography/Text.js +4 -3
  428. package/dist/user-avatar.js +13 -12
  429. package/package.json +1 -1
  430. package/src/components/data-display/DataGrid/DataGrid.cells.tsx +23 -9
  431. package/src/components/data-display/DataGrid/DataGrid.md +8 -0
  432. package/src/components/data-display/DataGrid/DataGrid.types.ts +10 -0
  433. package/src/components/data-display/DataViews/DataViewsGrid.tsx +6 -0
  434. package/src/components/data-display/DataViews/DataViewsTableBase.tsx +3 -0
  435. package/src/components/data-display/DataViews/data-views-grid-bodies.tsx +7 -0
  436. package/src/components/data-display/DataViews/data-views-grid-parts.tsx +4 -0
  437. package/src/components/data-display/DataViews/data-views-row-detail.ts +40 -0
  438. package/src/components/data-display/DataViews/index.ts +1 -0
  439. package/src/components/form/Switch/Switch.styles.ts +29 -3
  440. package/src/tokens/ink-over.ts +142 -0
  441. package/src/tokens/theme.ts +10 -65
  442. package/dist/chunk-5QUSX3TC.js.map +0 -1
  443. package/dist/chunk-65METCKT.js.map +0 -1
  444. package/dist/chunk-DIHVWBQV.js.map +0 -1
  445. package/dist/chunk-E5LWJDI3.js.map +0 -1
  446. package/dist/chunk-O7HLQTB7.js.map +0 -1
  447. package/dist/chunk-QLI7ES7Z.js.map +0 -1
  448. package/dist/chunk-SC72DRTX.js.map +0 -1
  449. package/dist/native/chunks/chunk-MP3UDWTT.js.map +0 -1
  450. /package/dist/{chunk-Q3GSDSK2.js.map → chunk-236QP424.js.map} +0 -0
  451. /package/dist/{chunk-JFRKBSWI.js.map → chunk-237NDIT2.js.map} +0 -0
  452. /package/dist/{chunk-TQOPF7LD.js.map → chunk-2L2NWXWJ.js.map} +0 -0
  453. /package/dist/{chunk-M4NFXC5R.js.map → chunk-2WSU6OGE.js.map} +0 -0
  454. /package/dist/{chunk-72T5PAW7.js.map → chunk-3BPDHWVF.js.map} +0 -0
  455. /package/dist/{chunk-EOHKZGOZ.js.map → chunk-3PUOLOEP.js.map} +0 -0
  456. /package/dist/{chunk-ECMJ5VPW.js.map → chunk-3TFUAKWJ.js.map} +0 -0
  457. /package/dist/{chunk-4ETQRBZC.js.map → chunk-46UPILLK.js.map} +0 -0
  458. /package/dist/{chunk-6VHCSPKK.js.map → chunk-4H4Y2SX3.js.map} +0 -0
  459. /package/dist/{chunk-L7S6N67X.js.map → chunk-4OSGKO7E.js.map} +0 -0
  460. /package/dist/{chunk-UG76BO5K.js.map → chunk-5KFZGB5U.js.map} +0 -0
  461. /package/dist/{chunk-FF3R67WD.js.map → chunk-5UC2RNOY.js.map} +0 -0
  462. /package/dist/{chunk-EMNGIYH6.js.map → chunk-7TZ6OC5T.js.map} +0 -0
  463. /package/dist/{chunk-G2JPUHEJ.js.map → chunk-AIBNBWQU.js.map} +0 -0
  464. /package/dist/{chunk-QE2C35TO.js.map → chunk-ALAJBLBE.js.map} +0 -0
  465. /package/dist/{chunk-AIRWM7KK.js.map → chunk-AVI3XHRQ.js.map} +0 -0
  466. /package/dist/{chunk-IE7ISTLQ.js.map → chunk-B443IIQG.js.map} +0 -0
  467. /package/dist/{chunk-CKJI7JO5.js.map → chunk-BEWD734I.js.map} +0 -0
  468. /package/dist/{chunk-RRX6ZTNX.js.map → chunk-BLT5ZBVL.js.map} +0 -0
  469. /package/dist/{chunk-MDTSMJ7C.js.map → chunk-BYMWW65P.js.map} +0 -0
  470. /package/dist/{chunk-Q3OFOOO7.js.map → chunk-C5EFVSBN.js.map} +0 -0
  471. /package/dist/{chunk-Y55ILY2F.js.map → chunk-C5YBXQTK.js.map} +0 -0
  472. /package/dist/{chunk-YANLN6HP.js.map → chunk-D6HDJVQW.js.map} +0 -0
  473. /package/dist/{chunk-ZA4U5GDU.js.map → chunk-DORPR2YP.js.map} +0 -0
  474. /package/dist/{chunk-6YLAVHV4.js.map → chunk-DTKMBI7B.js.map} +0 -0
  475. /package/dist/{chunk-JXNT5TUP.js.map → chunk-DVEYD27F.js.map} +0 -0
  476. /package/dist/{chunk-WZUNBSS7.js.map → chunk-DVUPIVI2.js.map} +0 -0
  477. /package/dist/{chunk-CMN26J5Y.js.map → chunk-E6D2Y5EK.js.map} +0 -0
  478. /package/dist/{chunk-HKB5C2KY.js.map → chunk-EMAX7RPN.js.map} +0 -0
  479. /package/dist/{chunk-ZAJO2B75.js.map → chunk-EPRA5QLB.js.map} +0 -0
  480. /package/dist/{chunk-ERX4XIYC.js.map → chunk-EUKYQXYU.js.map} +0 -0
  481. /package/dist/{chunk-C3CMEDSO.js.map → chunk-EVXFEXBS.js.map} +0 -0
  482. /package/dist/{chunk-DYESJJ3Q.js.map → chunk-EZNTM6PT.js.map} +0 -0
  483. /package/dist/{chunk-67ALTEWH.js.map → chunk-FGKKLHKY.js.map} +0 -0
  484. /package/dist/{chunk-OXYR2HVK.js.map → chunk-FOKBP6HR.js.map} +0 -0
  485. /package/dist/{chunk-22X7TT6Z.js.map → chunk-FR6AJSMT.js.map} +0 -0
  486. /package/dist/{chunk-TUO47RL2.js.map → chunk-FVPN4YKW.js.map} +0 -0
  487. /package/dist/{chunk-ZDWU52DJ.js.map → chunk-G5ZVD5IJ.js.map} +0 -0
  488. /package/dist/{chunk-NPN7JTRM.js.map → chunk-GH2DC7PS.js.map} +0 -0
  489. /package/dist/{chunk-77DF5LKI.js.map → chunk-GJUIZ5FN.js.map} +0 -0
  490. /package/dist/{chunk-YJ4HM25H.js.map → chunk-GLWW2XCP.js.map} +0 -0
  491. /package/dist/{chunk-7AIHK2XM.js.map → chunk-H53YNR23.js.map} +0 -0
  492. /package/dist/{chunk-GT7C6TSM.js.map → chunk-HDNK7BAX.js.map} +0 -0
  493. /package/dist/{chunk-7NEUPEV5.js.map → chunk-HQB5XNK5.js.map} +0 -0
  494. /package/dist/{chunk-SZETT7QV.js.map → chunk-HS2OJI6L.js.map} +0 -0
  495. /package/dist/{chunk-KZLLTOB2.js.map → chunk-HTZNB6IV.js.map} +0 -0
  496. /package/dist/{chunk-NNXZ5RK5.js.map → chunk-IQ7WZ3RN.js.map} +0 -0
  497. /package/dist/{chunk-7KEGJH3Q.js.map → chunk-IVVOIDE5.js.map} +0 -0
  498. /package/dist/{chunk-45OHGD2B.js.map → chunk-J2K65BQQ.js.map} +0 -0
  499. /package/dist/{chunk-SSWZHR46.js.map → chunk-J3ZP6EUS.js.map} +0 -0
  500. /package/dist/{chunk-YPILHGEO.js.map → chunk-J6CSPDC7.js.map} +0 -0
  501. /package/dist/{chunk-RRO2EOJB.js.map → chunk-JB67KPGM.js.map} +0 -0
  502. /package/dist/{chunk-V5P5Q6HM.js.map → chunk-JOXBCXVL.js.map} +0 -0
  503. /package/dist/{chunk-LO2B7FDQ.js.map → chunk-JPVDZXXX.js.map} +0 -0
  504. /package/dist/{chunk-P7FQUGED.js.map → chunk-JRWPI4XF.js.map} +0 -0
  505. /package/dist/{chunk-OVGASVPW.js.map → chunk-JVVTSSS4.js.map} +0 -0
  506. /package/dist/{chunk-IASDP44E.js.map → chunk-K4N3V7YE.js.map} +0 -0
  507. /package/dist/{chunk-L7LCSZ3H.js.map → chunk-K7DCYV5Q.js.map} +0 -0
  508. /package/dist/{chunk-B5SW7I5W.js.map → chunk-L4D6YLLU.js.map} +0 -0
  509. /package/dist/{chunk-FOF2RAVQ.js.map → chunk-L6TCIZFR.js.map} +0 -0
  510. /package/dist/{chunk-7Z2AQEC5.js.map → chunk-LCXXPIG3.js.map} +0 -0
  511. /package/dist/{chunk-MQPT254A.js.map → chunk-LSJY4LWZ.js.map} +0 -0
  512. /package/dist/{chunk-CA7TA36R.js.map → chunk-MGPA6KTM.js.map} +0 -0
  513. /package/dist/{chunk-OGHW7RQC.js.map → chunk-MHSTG7FF.js.map} +0 -0
  514. /package/dist/{chunk-GQJ4NCZ6.js.map → chunk-MNSW33DU.js.map} +0 -0
  515. /package/dist/{chunk-WETAIIKC.js.map → chunk-MRMNVGNX.js.map} +0 -0
  516. /package/dist/{chunk-MYH7VISV.js.map → chunk-MSUSZLRE.js.map} +0 -0
  517. /package/dist/{chunk-WKF54CCK.js.map → chunk-MVJYIHPH.js.map} +0 -0
  518. /package/dist/{chunk-EQA4VQEO.js.map → chunk-NGM5XKAS.js.map} +0 -0
  519. /package/dist/{chunk-PKFFJAQ6.js.map → chunk-NGVGTMHT.js.map} +0 -0
  520. /package/dist/{chunk-3GB6KWHH.js.map → chunk-NUB4T3RQ.js.map} +0 -0
  521. /package/dist/{chunk-GTLJYAEG.js.map → chunk-NWQWUYOV.js.map} +0 -0
  522. /package/dist/{chunk-QXFPTRHB.js.map → chunk-NY2Y2SHA.js.map} +0 -0
  523. /package/dist/{chunk-4A2Q22HO.js.map → chunk-O42ZA3TW.js.map} +0 -0
  524. /package/dist/{chunk-DTIB5KWP.js.map → chunk-OJCK5RNJ.js.map} +0 -0
  525. /package/dist/{chunk-OAWEUKUC.js.map → chunk-OLQDB346.js.map} +0 -0
  526. /package/dist/{chunk-4IVOHL32.js.map → chunk-OP6F3NXX.js.map} +0 -0
  527. /package/dist/{chunk-DWJBOR47.js.map → chunk-P3NRT6GV.js.map} +0 -0
  528. /package/dist/{chunk-GBX5ACPF.js.map → chunk-PCYGUOWJ.js.map} +0 -0
  529. /package/dist/{chunk-N5PY7IXI.js.map → chunk-PJTSGHTY.js.map} +0 -0
  530. /package/dist/{chunk-AGYGNNOM.js.map → chunk-PQECNGDE.js.map} +0 -0
  531. /package/dist/{chunk-XNOSTV5F.js.map → chunk-PTP3CZL4.js.map} +0 -0
  532. /package/dist/{chunk-LGJ2H4AH.js.map → chunk-PVIAHB7D.js.map} +0 -0
  533. /package/dist/{chunk-X5RDHO6G.js.map → chunk-QPDDS6DQ.js.map} +0 -0
  534. /package/dist/{chunk-6SK3MTYJ.js.map → chunk-QSKJLMNS.js.map} +0 -0
  535. /package/dist/{chunk-GYQT47YZ.js.map → chunk-QTZ7I6QS.js.map} +0 -0
  536. /package/dist/{chunk-WBKWIFXA.js.map → chunk-QYNCPS5W.js.map} +0 -0
  537. /package/dist/{chunk-DFLTUI7W.js.map → chunk-QZBUGUOY.js.map} +0 -0
  538. /package/dist/{chunk-GOWBYHYW.js.map → chunk-R6SBP5M5.js.map} +0 -0
  539. /package/dist/{chunk-FGK2C7JR.js.map → chunk-RVGG5YJY.js.map} +0 -0
  540. /package/dist/{chunk-7FOOLP5H.js.map → chunk-RXSGHPCR.js.map} +0 -0
  541. /package/dist/{chunk-LUMF63BM.js.map → chunk-SFAP5EH5.js.map} +0 -0
  542. /package/dist/{chunk-DW6GBMLQ.js.map → chunk-SLMA4UQS.js.map} +0 -0
  543. /package/dist/{chunk-QRX5BYUQ.js.map → chunk-SOCKK67R.js.map} +0 -0
  544. /package/dist/{chunk-G76H5PEM.js.map → chunk-SQV3HPTZ.js.map} +0 -0
  545. /package/dist/{chunk-IV5QQLCS.js.map → chunk-T2VO32Z2.js.map} +0 -0
  546. /package/dist/{chunk-VK4ULJFH.js.map → chunk-T5WNNEP5.js.map} +0 -0
  547. /package/dist/{chunk-FRW4SYZD.js.map → chunk-TEE6HNHS.js.map} +0 -0
  548. /package/dist/{chunk-JD3D6Y4U.js.map → chunk-THOPGHTY.js.map} +0 -0
  549. /package/dist/{chunk-EZ5Z5UFI.js.map → chunk-TTW4MAOJ.js.map} +0 -0
  550. /package/dist/{chunk-DTC224UJ.js.map → chunk-TX3ZHO5R.js.map} +0 -0
  551. /package/dist/{chunk-H3BQFEN5.js.map → chunk-UC6A6ASM.js.map} +0 -0
  552. /package/dist/{chunk-GSTRPZS4.js.map → chunk-UKPZVX3J.js.map} +0 -0
  553. /package/dist/{chunk-EPNCYUQ7.js.map → chunk-UN5INW6K.js.map} +0 -0
  554. /package/dist/{chunk-UGL6SJN6.js.map → chunk-UQNB2W2I.js.map} +0 -0
  555. /package/dist/{chunk-P7IVAMAU.js.map → chunk-V7F53GEO.js.map} +0 -0
  556. /package/dist/{chunk-ZC7RQDZ5.js.map → chunk-VESIQYBF.js.map} +0 -0
  557. /package/dist/{chunk-2KVQIGVE.js.map → chunk-VKH7AENA.js.map} +0 -0
  558. /package/dist/{chunk-S7HRED4D.js.map → chunk-VLHGBFR6.js.map} +0 -0
  559. /package/dist/{chunk-SMZBGHR2.js.map → chunk-VRKS5K4N.js.map} +0 -0
  560. /package/dist/{chunk-PW2WLDX3.js.map → chunk-VVXA7T2M.js.map} +0 -0
  561. /package/dist/{chunk-2SWQ6HIK.js.map → chunk-W3FAKT3D.js.map} +0 -0
  562. /package/dist/{chunk-QQLGSMGE.js.map → chunk-W5CW7JFZ.js.map} +0 -0
  563. /package/dist/{chunk-HOJL2GKW.js.map → chunk-WC3W36AM.js.map} +0 -0
  564. /package/dist/{chunk-3VZT2FAI.js.map → chunk-WC5XYWTE.js.map} +0 -0
  565. /package/dist/{chunk-RFZU5BTG.js.map → chunk-WYDGPJ3Z.js.map} +0 -0
  566. /package/dist/{chunk-27BL3DNT.js.map → chunk-XBZ43VIV.js.map} +0 -0
  567. /package/dist/{chunk-KOFO6QZY.js.map → chunk-XGOWREVV.js.map} +0 -0
  568. /package/dist/{chunk-KAV63FBG.js.map → chunk-XOCLWQON.js.map} +0 -0
  569. /package/dist/{chunk-DF2FFYZ7.js.map → chunk-XSJWN3WH.js.map} +0 -0
  570. /package/dist/{chunk-DB2MAYPK.js.map → chunk-XV2TDULR.js.map} +0 -0
  571. /package/dist/{chunk-4OHRZW7U.js.map → chunk-XXE6NTJB.js.map} +0 -0
  572. /package/dist/{chunk-4G3FGCWX.js.map → chunk-XXJRT6BP.js.map} +0 -0
  573. /package/dist/{chunk-LV4UTYAD.js.map → chunk-XYDW5RQB.js.map} +0 -0
  574. /package/dist/{chunk-7VN7LFBA.js.map → chunk-YD77RANW.js.map} +0 -0
  575. /package/dist/{chunk-77OXG6DH.js.map → chunk-YFY3YVV6.js.map} +0 -0
  576. /package/dist/{chunk-PENJBKPH.js.map → chunk-YTYROOLY.js.map} +0 -0
  577. /package/dist/native/chunks/{chunk-XI7HTAVN.js.map → chunk-2HLEFYJ5.js.map} +0 -0
  578. /package/dist/native/chunks/{chunk-UYREIOEM.js.map → chunk-6XDMYJBW.js.map} +0 -0
  579. /package/dist/native/chunks/{chunk-6L4UZBQP.js.map → chunk-BEPOBULQ.js.map} +0 -0
  580. /package/dist/native/chunks/{chunk-ZOP7UAZK.js.map → chunk-CO47ZRXO.js.map} +0 -0
  581. /package/dist/native/chunks/{chunk-UII3IFLP.js.map → chunk-NVPXIJ2O.js.map} +0 -0
  582. /package/dist/native/chunks/{chunk-2SBTJSQE.js.map → chunk-SOQVMWLQ.js.map} +0 -0
  583. /package/dist/native/chunks/{chunk-QEQZ5AF6.js.map → chunk-YXM4NR2B.js.map} +0 -0
@@ -1,4 +1,12 @@
1
- import { darken, getContrastRatio, lighten } from './color';
1
+ import { darken, lighten } from './color';
2
+ import { contrastText, DARK_TEXT_PRIMARY, inkOver } from './ink-over';
3
+
4
+ /*
5
+ RE-EXPORTED rather than moved out of the public surface. Both were published
6
+ from here, and `ink-over.ts` exists because this file reached the 400-line cap
7
+ — a caller should not have to learn that.
8
+ */
9
+ export { contrastText, inkOver };
2
10
  import { cssLengthToPx, cssTrackingToEm } from './css-units';
3
11
  import { HEADING_SCALE, type HeadingLevel } from './heading-scale';
4
12
 
@@ -127,11 +135,8 @@ const ROOT_FONT_PX = 16;
127
135
  /** The px value as the rem string the web components write. */
128
136
  export const px = (value: number): string => `${value / ROOT_FONT_PX}rem`;
129
137
 
130
- /** MUI's `createPalette` defaults, exactly. */
138
+ /** MUI's `createPalette` default tonal offset, exactly. */
131
139
  const TONAL_OFFSET = 0.2;
132
- const CONTRAST_THRESHOLD = 3;
133
- const DARK_TEXT_PRIMARY = 'rgba(0, 0, 0, 0.87)';
134
- const LIGHT_TEXT_PRIMARY = '#fff';
135
140
 
136
141
  export const GREY: Record<UiGreyStep, string> = {
137
142
  50: '#fafafa',
@@ -207,66 +212,6 @@ const MODE_DEFAULTS: Record<
207
212
  },
208
213
  };
209
214
 
210
- /**
211
- * MUI's `getContrastText`: white where white reads at 3:1 on the colour, the
212
- * light mode's dark ink otherwise. (MUI's source spells the white as the DARK
213
- * palette's `text.primary`, which is what made it easy to read backwards.)
214
- */
215
- export function contrastText(background: string): string {
216
- return getContrastRatio(background, LIGHT_TEXT_PRIMARY) >= CONTRAST_THRESHOLD
217
- ? LIGHT_TEXT_PRIMARY
218
- : DARK_TEXT_PRIMARY;
219
- }
220
-
221
- /**
222
- * The ink that reads on EVERY one of these fills (FUT-1924).
223
- *
224
- * {@link contrastText} answers for one fill, which is all MUI's `augmentColor`
225
- * ever needs: a solid button is a single flat colour. Two components paint the
226
- * label over something that is not one colour — `Button`'s `gradient` variant
227
- * runs between two stops, and `Switch`'s thumb travels the whole length of a
228
- * checked track — and both of them stated `#fff` outright instead, which is
229
- * white-on-pale the moment a white-labelled host hands the library a pale
230
- * brand. Audited across the library, those two were the only places a hardcoded
231
- * white sat over a surface the TENANT chooses.
232
- *
233
- * **This deliberately does not follow `contrastText`'s rule.** MUI's is a
234
- * threshold that PREFERS white — white wherever white clears 3:1 — which is a
235
- * brand-feel decision, and it is kept for every existing caller so nothing
236
- * already legible moves. Here the fills can disagree: over MUI's own success
237
- * pair white is 2.78:1 on `#4caf50` and dark ink 2.66:1 on `#1b5e20`, so
238
- * neither meets any threshold and asking whether one does is the wrong
239
- * question. The answer is whichever ink has the better WORST case across the
240
- * fills — which is also not what either fill says on its own, since
241
- * `contrastText('#4caf50')` is dark ink.
242
- *
243
- * A gradient wide enough that neither ink clears 4.5:1 anywhere is a palette
244
- * problem this cannot fix — it returns the less bad ink and does not pretend
245
- * otherwise.
246
- *
247
- * `Math.min` is the claim, and it is worth knowing that no test can prove it
248
- * against `Math.max` today: the two candidate inks sit at opposite ends of the
249
- * luminance range, so ranking them by their best fill and by their worst gives
250
- * the same winner for every possible pair (checked exhaustively). Worst case is
251
- * still what this MEANS, and the moment a third ink or one that is not an
252
- * extreme is offered, the two stop agreeing.
253
- *
254
- * `fallback` is returned when a fill cannot be decomposed: {@link getContrastRatio}
255
- * throws on a format it does not know, and a throw inside an emotion style
256
- * function takes the render down with it.
257
- */
258
- export function inkOver(fills: readonly string[], fallback: string): string {
259
- try {
260
- const worstCase = (ink: string): number =>
261
- Math.min(...fills.map((fill) => getContrastRatio(ink, fill)));
262
-
263
- return worstCase(LIGHT_TEXT_PRIMARY) >= worstCase(DARK_TEXT_PRIMARY)
264
- ? LIGHT_TEXT_PRIMARY
265
- : DARK_TEXT_PRIMARY;
266
- } catch {
267
- return fallback;
268
- }
269
- }
270
215
 
271
216
  /**
272
217
  * MUI's `augmentColor` for a custom colour: derive whatever shade the seed
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/data-display/DataViews/DataViewsTableBase.tsx"],"sourcesContent":["\"use client\";\n\nimport type { SortFieldDefinition } from \"../../layout/ContentToolbar\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { DataViewsGrid } from \"./DataViewsGrid\";\nimport type { SelectionExtraRender } from \"./data-views-selection-extra\";\nimport type { ListGroupConfig } from \"./list-card-rails\";\nimport type { DisplayPanelView } from \"./data-views-display-panel\";\nimport { viewStateKey } from \"./data-views-dirty\";\nimport { DeleteViewDialog } from \"./DeleteViewDialog\";\nimport type { BoardConfig } from \"./DataViewsBoard\";\nimport type { DataViewExport } from \"./data-views-export\";\nimport type { ScopeConfig } from \"./data-views-scopes\";\nimport { ViewDialogs, ViewMutationErrorAlert } from \"./data-views-table-parts\";\nimport {\n useSavedViewsController,\n type SavedViewsController,\n} from \"./use-saved-views-controller\";\nimport {\n type DataViewColumn,\n type DataViewsLayout,\n type DataViewServer,\n type DataViewState,\n type DataViewSyncState,\n type DataViewPersistence,\n type DataViewRouter,\n type FilterFieldConfig,\n type RangeFieldConfig,\n type DataViewCardSelection,\n type RowAction,\n type SavedViewSummary,\n} from \"./data-views-types\";\n\nexport interface DataViewsTableBaseProps<T extends Record<string, unknown>> {\n /** The applied-view id read from the URL (`?view=`) on load, or null. */\n initialViewId?: string | null;\n /** Injected saved-view persistence (create/update/delete). */\n persistence: DataViewPersistence;\n /** Injected router side-effects (URL sync + refresh). */\n router: DataViewRouter;\n rows: T[];\n columns: DataViewColumn<T>[];\n fields: FilterFieldConfig<T>[];\n /** Optional numeric min/max range filters (advanced \"filter by amount\"). */\n rangeFields?: RangeFieldConfig<T>[];\n getRowId: (row: T) => string | number;\n onRowClick?: (row: T) => void;\n emptyState?: React.ReactNode;\n dataTestId?: string;\n testIdPrefix?: string;\n /** The user's + shared views for this table (from the server). */\n views: SavedViewSummary[];\n /** Big page title in the table header, beside the funnel + gear (GTA layout). */\n title?: string;\n /** Primary page actions (e.g. \"Novo produto\") rendered at the header's right. */\n headerActions?: React.ReactNode;\n /** Sort options for the toolbar's \"Sort By\" dropdown (defaults to sortable columns). */\n sortFields?: SortFieldDefinition[];\n /**\n * Per-sort-field VALUE KIND (`\"currency\" | \"number\" | \"date\" | \"text\"`), so the\n * Exibir panel phrases the direction in that column's own terms. \"Crescente\"\n * on a currency column is a puzzle; \"Menor → maior\" is not. Defaults to text.\n */\n sortKinds?: Record<string, string>;\n /**\n * Opt-in \"Exportar\" control. The grid hands the host the current query,\n * UNPAGINATED, and the host re-queries — the grid never fetches, and an\n * export therefore follows the filters rather than the loaded page.\n */\n exportConfig?: DataViewExport;\n /** Notified with the currently-visible (filtered) rows, so Export matches the view. */\n onVisibleRowsChange?: (rows: T[]) => void;\n /** Reusable row actions driving both the row \"⋮\" kebab and the bulk menu. */\n rowActions?: RowAction<T>[];\n /** Leading control in the auto kebab column (e.g. a favourite star). */\n rowActionsLeading?: (row: T) => React.ReactNode;\n /** Low-level bulk-action override; prefer `rowActions`. */\n bulkActions?: (selectedRows: T[], clearSelection: () => void) => React.ReactNode;\n /** A selection-widening control beside the count (e.g. \"select all matching\"). */\n selectionExtra?: SelectionExtraRender<T>;\n /** Bespoke per-row menu (an entity's self-contained 3-dots menu) instead of the auto kebab. */\n renderRowMenu?: (row: T) => React.ReactNode;\n /** Opt-in \"Grade\" (cards) layout — a card renderer per row; adds a Grade/Tabela toggle. */\n renderCard?: (row: T, selection: DataViewCardSelection) => React.ReactNode;\n /** Opt-in \"Quadro\" (board) layout — the loaded page as columns of one field. Needs `renderCard`. */\n board?: BoardConfig<T>;\n /** Opt-in \"Lista\" layout — one full-width, entity-rendered row per record (FUT-733). */\n renderListRow?: (row: T, selection: DataViewCardSelection) => React.ReactNode;\n /** The Lista's shared columns, so its rows line up by construction not convention. */\n listGroup?: ListGroupConfig<T>;\n /** The page-level partition rendered as tabs under the toolbar (server mode only). */\n scopes?: ScopeConfig[];\n /** The row field the scopes partition by — used only to reject a pill over the same field. */\n scopeFieldId?: string;\n /** Which layout to show first when the user has expressed no preference (default \"table\"). */\n defaultLayout?: DataViewsLayout;\n /**\n * Ignore the remembered cross-screen layout preference and pin to\n * `defaultLayout`. For tables that exist to SHOW a layout — stories, docs,\n * screenshots — not for real screens.\n */\n ignoreStoredLayout?: boolean;\n /** Opt into the responsive inline filter UX (collapsible row / modal). Default keeps the panel. */\n inlineFilters?: boolean;\n /** Keep the inline search visible with no filter fields and no active search. */\n alwaysShowSearch?: boolean;\n /** Server-mode wiring (FUT-180): backend-driven rows/total + re-fetch. Omit for client mode. */\n server?: DataViewServer;\n /** Seed the initial view state (search/pills/ranges/sort) from the URL when no saved view applies. */\n initialState?: DataViewState;\n}\n\n/**\n * Derive the grid's reactive `syncState` from the URL-seeded `initialState` in\n * server mode so browser back/forward RE-APPLIES the search/pills/sort controls\n * (merging over live state, preserving hidden columns — see {@link DataViewSyncState}).\n * Client-mode tables (no `server`) get `undefined`. Callers memoize `initialState`\n * on the URL, so this reference only changes on genuine navigations.\n */\nfunction useUrlSyncState(\n server: DataViewServer | undefined,\n initialState: DataViewState | undefined,\n): DataViewSyncState | undefined {\n const isServerMode = server !== undefined;\n return useMemo<DataViewSyncState | undefined>(\n () =>\n isServerMode && initialState\n ? {\n search: initialState.search,\n pills: initialState.pills,\n ranges: initialState.ranges,\n sortBy: initialState.sortBy,\n // The scope belongs in the URL-driven slice alongside them: a\n // `?view=recusados`-style deep link and browser back/forward must\n // move the tab strip, and they must do it WITHOUT resetting the\n // user's hidden columns — which is the whole reason this is a\n // merging `syncState` and not a replacing `appliedState`.\n scope: initialState.scope,\n }\n : undefined,\n [isServerMode, initialState],\n );\n}\n\n/**\n * Resolve the initial applied view: a `?view=<id>` shortcut (FUT-90) wins, else\n * the user's default view, else none. Drives the seed state + trigger label.\n */\nfunction resolveInitialView(\n views: SavedViewSummary[],\n requestedId: string | null,\n): SavedViewSummary | undefined {\n const requested = requestedId ? views.find((view) => view.id === requestedId) : undefined;\n return requested ?? views.find((view) => view.isDefault);\n}\n\n/**\n * The Exibir panel's view chrome, assembled from the saved-views controller.\n * Extracted so {@link DataViewsTableBase} stays inside its size budget.\n */\nfunction buildDisplayView({\n ctl,\n views,\n activeView,\n dirty,\n onRequestDelete,\n}: {\n ctl: SavedViewsController;\n views: SavedViewSummary[];\n activeView: SavedViewSummary | undefined;\n dirty: boolean;\n /** Opens the confirmation; the delete itself happens on confirm. */\n onRequestDelete: (view: SavedViewSummary) => void;\n}): DisplayPanelView {\n return {\n activeViewName: ctl.activeViewName,\n dirty,\n onReset: () => (activeView ? ctl.applyView(activeView) : ctl.selectMain()),\n // Only offer \"Atualizar\" when there IS a view to update — otherwise the\n // single footer button is a plain \"Salvar visão\".\n onUpdate: activeView ? () => ctl.openEdit(activeView) : undefined,\n onSaveAs: ctl.openCreate,\n // The views themselves, not a dropdown: the panel renders them in its own\n // body (see `data-views-view-nav`), so there is no second popover to clip\n // the row actions.\n nav: {\n views,\n activeViewId: activeView?.id ?? null,\n onSelectView: (id) => {\n const next = id === null ? null : views.find((view) => view.id === id);\n if (next) ctl.applyView(next);\n else ctl.selectMain();\n },\n onEditView: ctl.openEdit,\n onPatchView: (view, changes) => void ctl.patchView(view, changes),\n onDeleteView: onRequestDelete,\n },\n };\n}\n\n/**\n * \"Are there unsaved changes?\" — the dot on Exibir, and whether Redefinir and\n * Salvar visão are live.\n *\n * Two things it gets right that the inline version did not. It compares\n * NORMALISED states (`viewStateKey`), so a filter applied and then removed is\n * clean again rather than clean-looking but flagged; and it re-baselines after\n * a SAVE, because the state just written is the clean one from that point.\n *\n * The baseline is the first state the grid emits for a view, not the view\n * itself: the grid normalises what it is handed — resolving visible columns,\n * filling in layout — so the applied view is never byte-identical to the state\n * it produces.\n */\nfunction useDirtyTracking(ctl: SavedViewsController): {\n dirty: boolean;\n noteState: (state: DataViewState) => void;\n markSaved: () => void;\n} {\n const [dirty, setDirty] = useState(false);\n const [savedAt, setSavedAt] = useState(0);\n const baseline = useRef<string | null>(null);\n const appliedKey = JSON.stringify(ctl.applied ?? null);\n\n useEffect(() => {\n baseline.current = null;\n setDirty(false);\n }, [appliedKey, savedAt]);\n\n return {\n dirty,\n noteState: (state) => {\n ctl.currentRef.current = state;\n const key = viewStateKey(state);\n if (baseline.current === null) {\n baseline.current = key;\n setDirty(false);\n return;\n }\n const next = key !== baseline.current;\n setDirty((prev) => (prev === next ? prev : next));\n },\n markSaved: () => setSavedAt((tick) => tick + 1),\n };\n}\n\n/**\n * The reusable admin table (FUT-89): the DataViews grid plus the full saved-views\n * experience — a views dropdown, a save/edit modal (with preview), and a manage\n * dialog. Framework-agnostic: saved-view persistence and router side-effects are\n * INJECTED (`persistence`, `router`, `initialViewId`) so the host app wires them\n * to its backend + framework router. A default view auto-applies on load; applying\n * a view restores its filters + columns + sort. Each table supplies its own columns\n * + filter fields; everything else is shared.\n */\nexport function DataViewsTableBase<T extends Record<string, unknown>>(\n props: DataViewsTableBaseProps<T>,\n): React.JSX.Element {\n // Forwarded as a whole rather than restated name-by-name twice (as in\n // DataViewsGrid): this component only ADDS the saved-views chrome, and a\n // 30-name destructure repeated in the JSX is exactly where a newly added prop\n // silently stops being passed on.\n const {\n initialViewId = null,\n persistence,\n router,\n columns,\n fields,\n testIdPrefix = \"table\",\n views,\n server,\n initialState,\n } = props;\n const initialView = resolveInitialView(views, initialViewId);\n const columnIds = columns.map((col) => col.id);\n const ctl = useSavedViewsController(persistence, router, columnIds, views, initialView, initialState);\n // Unsaved-changes flag for the Exibir panel. Set from `onStateChange` rather\n // than derived in render because the live state lives in a REF (the grid owns\n // it); the equality bail-out in `setDirty` is what stops the update loop.\n const { dirty, noteState, markSaved } = useDirtyTracking(ctl);\n // Deleting a saved view is confirmed, not immediate — see `DeleteViewDialog`.\n const [pendingDelete, setPendingDelete] = useState<SavedViewSummary | null>(null);\n // The view the panel's \"Redefinir\" restores: the applied one, or the built-in\n // \"Visão principal\" when none is.\n const activeView = views.find((view) => view.name === ctl.activeViewName);\n const displayView = buildDisplayView({\n ctl,\n views,\n activeView,\n dirty,\n onRequestDelete: setPendingDelete,\n });\n // Server-mode lists re-apply URL-derived controls on back/forward (not just the mount seed).\n const syncState = useUrlSyncState(server, initialState);\n\n return (\n <>\n <ViewMutationErrorAlert error={ctl.mutationError} onClose={ctl.clearMutationError} testIdPrefix={testIdPrefix} />\n <DataViewsGrid<T>\n {...props}\n testIdPrefix={testIdPrefix}\n appliedState={ctl.applied}\n syncState={syncState}\n onStateChange={noteState}\n // The saved-views menu is NOT a toolbar control any more: it lives in\n // the Exibir panel's VISÃO header, passed through `displayView`.\n displayView={displayView}\n />\n {renderViewDialogs(ctl, fields, columns, views, testIdPrefix, markSaved)}\n <DeleteViewDialog\n view={pendingDelete}\n onClose={() => setPendingDelete(null)}\n onConfirm={(view) => {\n void ctl.handleDelete(view);\n setPendingDelete(null);\n }}\n testIdPrefix={testIdPrefix}\n />\n </>\n );\n}\n\n/** The save + manage saved-view dialogs, split out to keep the base thin. */\nfunction renderViewDialogs<T extends Record<string, unknown>>(\n ctl: SavedViewsController,\n fields: DataViewsTableBaseProps<T>[\"fields\"],\n columns: DataViewsTableBaseProps<T>[\"columns\"],\n views: SavedViewSummary[],\n testIdPrefix: string,\n onSaved: () => void,\n): React.JSX.Element {\n return (\n <ViewDialogs<T>\n saveOpen={ctl.saveOpen}\n onCloseSave={ctl.closeSave}\n currentState={ctl.editing ? ctl.editing.state : ctl.currentRef.current}\n fields={fields}\n columns={columns}\n editing={ctl.editing}\n onSave={async (payload) => {\n await ctl.handleSave(payload);\n // The saved state is the clean one from here on.\n onSaved();\n }}\n manageOpen={ctl.manageOpen}\n onCloseManage={() => ctl.setManageOpen(false)}\n views={views}\n onEditFromManage={ctl.editFromManage}\n onDelete={(view) => void ctl.handleDelete(view)}\n testIdPrefix={testIdPrefix}\n />\n );\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/data-display/DataViews/data-views-grid-parts.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nimport { TableFilter } from \"../../layout/TableFilter\";\nimport { Stack } from \"../../../mui/Stack\";\n\nimport {\n DataViewsLayoutProvider,\n useDataViewsLayout,\n type DataViewsLayout,\n} from \"./data-views-layout-context\";\nimport { FilterDialog, GridFilterPanel } from \"./data-views-filter-panel\";\nimport { GridMain } from \"./data-views-grid-bodies\";\nimport type { ListGroupConfig } from \"./list-card-rails\";\nimport { InlineFilterControls } from \"./data-views-inline-bar\";\nimport { toOverflowFields, useFilterOverflow, type OverflowSplit } from \"./data-views-overflow\";\nimport { GridHeaderRow } from \"./data-views-header-row\";\nimport { resolveSelectionExtra, type SelectionExtraRender } from \"./data-views-selection-extra\";\nimport { ShellToolbar } from \"./data-views-shell-toolbar\";\nimport type { DisplayPanelView } from \"./data-views-display-panel\";\nimport type { DataViewExport } from \"./data-views-export\";\nimport { useDataViewsCopy } from \"./data-views-copy-context\";\nimport { DataViewsEmpty } from \"./data-views-empty\";\nimport { DataViewsPagination } from \"./data-views-pagination\";\nimport type { BoardConfig } from \"./DataViewsBoard\";\nimport { type ScopeConfig } from \"./data-views-scopes\";\nimport { ScopeTabsSlot } from \"./data-views-scope-tabs\";\nimport { togglePillValues } from \"./data-views-grid-helpers\";\nimport type {\n DataViewCardSelection,\n FilterFieldConfig,\n RangeFieldConfig,\n RangeValue,\n RowAction,\n} from \"./data-views-types\";\nimport type { DataViewsController } from \"./use-data-views-state\";\n\n/* ── Layout ⇄ view-state mirror ──────────────────────────────────────────── */\n\n/**\n * Mirrors the LIVE layout back into the view state, so saving a view captures\n * the layout the user is actually looking at.\n *\n * A component rather than a callback prop because only something INSIDE the\n * provider can read the layout, and only the controller can write the state.\n * The `stored !== layout` guard is what makes it idempotent: `c` is rebuilt on\n * every render, so an unguarded effect here would patch → re-render → patch.\n *\n * It re-fires when `stored` changes too, which is the case that matters after\n * applying a saved view: `appliedState` REPLACES the state, so a view saved\n * before layouts were captured clears `state.layout`, and the mirror puts the\n * current one back rather than leaving the next save with nothing to store.\n */\nfunction LayoutStateSync<T extends Record<string, unknown>>({\n c,\n}: {\n c: DataViewsController<T>;\n}): null {\n const { layout } = useDataViewsLayout();\n const stored = c.state.layout;\n useEffect(() => {\n if (stored !== layout) c.patch({ layout });\n // `c` is intentionally out of the deps — see the guard above.\n }, [layout, stored]);\n return null;\n}\n\n/* ── Shell (composes toolbar + body + panel) ─────────────────────────────── */\n\n/** The shared filter-surface props consumed by the inline bar, panel, and modal. */\ninterface FilterSurfaceProps<T extends Record<string, unknown>> {\n testIdPrefix: string;\n search: string;\n fields: FilterFieldConfig<T>[];\n rangeFields: RangeFieldConfig<T>[];\n pills: Record<string, string[]>;\n ranges: Record<string, RangeValue>;\n onSearchChange: (value: string) => void;\n onTogglePill: (fieldId: string, value: string, checked: boolean) => void;\n onChangeRange: (fieldId: string, range: RangeValue) => void;\n onClearField: (fieldId: string) => void;\n onClearAll: () => void;\n}\n\n/**\n * Derives the responsive filter state (which surface to show at this width) and\n * the filter-mutation handlers from the controller — pulled out of `GridShell`\n * so the component body stays under the size/complexity budget.\n */\n/** Grouped rather than positional: the list had grown past readability. */\ninterface GridShellFiltersArgs<T extends Record<string, unknown>> {\n c: DataViewsController<T>;\n inlineFilters: boolean;\n fields: FilterFieldConfig<T>[];\n rangeFields: RangeFieldConfig<T>[];\n testIdPrefix: string;\n alwaysShowSearch: boolean;\n /** Is \"Exportar\" on the bar? Half the right cluster's cost when it is not. */\n hasExport: boolean;\n}\n\nfunction useGridShellFilters<T extends Record<string, unknown>>({\n c,\n inlineFilters,\n fields,\n rangeFields,\n testIdPrefix,\n alwaysShowSearch,\n hasExport,\n}: GridShellFiltersArgs<T>): {\n showInline: boolean;\n useModal: boolean;\n inlineVisible: boolean;\n filterProps: FilterSurfaceProps<T>;\n split: OverflowSplit<T>;\n onControlOpenChange: (open: boolean) => void;\n} {\n const { state } = c;\n // How many filter controls are open. A COUNT, not a flag: closing one popover\n // by opening another overlaps, and a boolean would unfreeze mid-handover.\n const [openControls, setOpenControls] = useState(0);\n // ONE measurement for the whole shell: the filter row decides which controls\n // it can keep, and the TOOLBAR needs the same answer to drop its labels.\n // Measuring twice would let the two disagree at the crossover width.\n const split = useFilterOverflow(\n toOverflowFields(fields, rangeFields),\n state.pills,\n c.ranges,\n openControls > 0,\n hasExport,\n );\n // THE BAR RENDERS AT EVERY WIDTH. It used to be swapped for a full-screen\n // filter MODAL below `lg`, which was the responsive strategy before the\n // measured ladder existed — and the two now do the same job, badly together:\n // the modal took the bar away at 1199px, and with it the very degradation\n // (labels off, search collapsed, filters into \"Mais\") that exists to make a\n // narrow bar work. So a 900px window got no bar and no ladder, and the\n // operator lost the search entirely rather than gaining a compact one.\n //\n // The ladder is measured, so it already covers every width the modal did.\n const showInline = inlineFilters;\n const useModal = false;\n const inlineVisible =\n showInline &&\n (alwaysShowSearch || fields.length > 0 || rangeFields.length > 0 || state.search !== \"\");\n const filterProps: FilterSurfaceProps<T> = {\n testIdPrefix,\n search: state.search,\n fields,\n rangeFields,\n pills: state.pills,\n ranges: c.ranges,\n onSearchChange: (value) => c.patch({ search: value }),\n // Updater, never the render's `state` — see {@link DataViewStatePatch}.\n onTogglePill: (fieldId, value, checked) =>\n c.patch(({ pills }) => ({ pills: { ...pills, [fieldId]: togglePillValues(pills[fieldId], value, checked) } })),\n onChangeRange: (fieldId, range) => c.patch({ ranges: { ...c.ranges, [fieldId]: range } }),\n onClearField: (fieldId) => c.patch({ pills: { ...state.pills, [fieldId]: [] } }),\n onClearAll: () => c.patch({ search: \"\", pills: {}, ranges: {} }),\n };\n return {\n showInline,\n useModal,\n inlineVisible,\n filterProps,\n split,\n onControlOpenChange: (open) =>\n setOpenControls((count) => Math.max(0, count + (open ? 1 : -1))),\n };\n}\n\ninterface GridShellProps<T extends Record<string, unknown>> {\n c: DataViewsController<T>;\n rows: T[];\n fields: FilterFieldConfig<T>[];\n rangeFields: RangeFieldConfig<T>[];\n getRowId: (row: T) => string | number;\n testIdPrefix: string;\n dataTestId?: string;\n emptyState?: React.ReactNode;\n toolbarRightSlot?: React.ReactNode;\n rowActions?: RowAction<T>[];\n bulkActions?: (selectedRows: T[], clearSelection: () => void) => React.ReactNode;\n /** A widening control beside the selection count — see `resolveSelectionExtra`. */\n selectionExtra?: SelectionExtraRender<T>;\n /** Opt-in \"Grade\" (cards) layout: renders each row as an entity-supplied card.\n * Omit ⇒ table only (no layout toggle). */\n renderCard?: (row: T, selection: DataViewCardSelection) => React.ReactNode;\n /**\n * Opt-in \"Quadro\" (board) layout. Needs `renderCard` too — the board reuses\n * the entity's card, so a board config without one simply offers no board\n * rather than failing: that is a config gap, not a runtime error.\n */\n board?: BoardConfig<T>;\n /** Opt-in \"Lista\" layout: one full-width, entity-rendered row per record. */\n renderListRow?: (row: T, selection: DataViewCardSelection) => React.ReactNode;\n /** The Lista's shared columns, so its rows line up by construction. */\n listGroup?: ListGroupConfig<T>;\n /** The page-level partition rendered as tabs under the toolbar. */\n scopes?: ScopeConfig[];\n /**\n * The row field the scopes partition by. Compared against the board's\n * `groupBy` so the two are not shown as the same partition twice.\n */\n scopeFieldId?: string;\n /** Per-sort-field value kind, so directions read in the column's own terms. */\n sortKinds?: Record<string, string>;\n /** The saved-view chrome bracketing the Exibir panel. */\n displayView?: DisplayPanelView;\n /** Injected export — the host re-queries; the grid never fetches. */\n exportConfig?: DataViewExport;\n /** Page title in the grid's own header row, above the scopes + toolbar. */\n title?: string;\n /** Primary page actions rendered at the header row's right. */\n headerActions?: React.ReactNode;\n /** Which layout to show first when the user has expressed no preference (default \"table\"). */\n defaultLayout?: DataViewsLayout;\n /** Pin to `defaultLayout`, ignoring the remembered preference (stories/docs). */\n ignoreStoredLayout?: boolean;\n /**\n * Opt into the responsive inline filter UX: a collapsible filter row below the\n * toolbar on wide screens and a modal on narrow ones. When false (default),\n * keep the classic slide-in filter panel opened by the \"Filtros\" button.\n */\n inlineFilters?: boolean;\n /**\n * Keep the inline search box on screen even with no filter fields and no\n * active search. Without it a grid whose only filter IS the search (`fields`\n * empty) can never OFFER one: the row renders only once a search exists, so\n * the operator would have to hand-edit the URL to start one. Default false —\n * every grid that ships filter fields already shows the row.\n */\n alwaysShowSearch?: boolean;\n}\n\n/** The scrollable content region: scope tabs, toolbar, filter bar, body, pager. */\nfunction ShellStack<T extends Record<string, unknown>>({\n props,\n filters,\n}: {\n props: GridShellProps<T>;\n filters: ReturnType<typeof useGridShellFilters<T>>;\n}): React.JSX.Element {\n const copy = useDataViewsCopy();\n const { c, testIdPrefix, dataTestId, scopes = [], emptyState, inlineFilters = false } = props;\n const { showInline, useModal, inlineVisible, filterProps, split, onControlOpenChange } = filters;\n // The grid renders the FILTERED empty state itself — it is the only party\n // that knows a filter is applied. See {@link DataViewsEmpty}.\n const body = (\n <DataViewsEmpty\n filtered={c.activeFilterCount > 0 || c.state.search !== \"\"}\n onClearFilters={() => c.patch({ search: \"\", pills: {}, ranges: {} })}\n emptyState={emptyState}\n testIdPrefix={testIdPrefix}\n />\n );\n return (\n <TableFilter\n copy={copy.tableFilter} open={c.filterOpen} onOpenChange={c.setFilterOpen}\n hasActiveFilters={c.activeFilterCount > 0}\n >\n <Stack spacing={0} data-testid={dataTestId ? `${dataTestId}-container` : undefined}>\n <GridHeaderRow title={props.title} headerActions={props.headerActions} testIdPrefix={testIdPrefix} />\n <ShellToolbar\n c={c}\n rows={props.rows}\n sortKinds={props.sortKinds}\n displayView={props.displayView}\n exportConfig={props.exportConfig}\n filterControls={\n inlineVisible ? (\n <InlineFilterControls\n {...filterProps} split={split} activeFilterCount={c.activeFilterCount}\n onControlOpenChange={onControlOpenChange}\n />\n ) : undefined\n }\n barRef={split.barRef}\n testIdPrefix={testIdPrefix}\n rowActions={props.rowActions}\n bulkActions={props.bulkActions}\n selectionExtra={resolveSelectionExtra(props)}\n toolbarRightSlot={props.toolbarRightSlot}\n compactControls={showInline && split.compactControls}\n counterHidden={showInline && split.counterHidden}\n showInline={showInline}\n />\n <ScopeTabsSlot\n scopes={scopes} scopeFieldId={props.scopeFieldId} board={props.board}\n value={c.scope} onChange={c.setScope} counts={c.scopeCounts}\n testIdPrefix={testIdPrefix}\n />\n <TableFilter.Layout>\n <TableFilter.Main>\n <GridMain\n c={c}\n getRowId={props.getRowId}\n renderCard={props.renderCard}\n renderListRow={props.renderListRow}\n listGroup={props.listGroup}\n board={props.board}\n dataTestId={dataTestId}\n testIdPrefix={testIdPrefix}\n emptyState={body}\n />\n <DataViewsPagination c={c} testIdPrefix={testIdPrefix} />\n </TableFilter.Main>\n {inlineFilters ? null : <GridFilterPanel {...filterProps} />}\n </TableFilter.Layout>\n {useModal && <FilterDialog open={c.filterOpen} onClose={() => c.setFilterOpen(false)} {...filterProps} />}\n </Stack>\n </TableFilter>\n );\n}\n\nexport function GridShell<T extends Record<string, unknown>>(props: GridShellProps<T>): React.JSX.Element {\n const {\n c,\n fields,\n rangeFields,\n testIdPrefix,\n renderCard,\n renderListRow,\n board,\n defaultLayout,\n ignoreStoredLayout,\n inlineFilters = false,\n alwaysShowSearch = false,\n } = props;\n const filters = useGridShellFilters({\n c,\n inlineFilters,\n fields,\n rangeFields,\n testIdPrefix,\n alwaysShowSearch,\n hasExport: props.exportConfig !== undefined,\n });\n return (\n <DataViewsLayoutProvider\n canUseCards={Boolean(renderCard)}\n canUseList={Boolean(renderListRow)}\n // The board reuses the entity's card, so it needs BOTH — a `board` with no\n // `renderCard` offers no board rather than throwing.\n canUseBoard={Boolean(board && renderCard)}\n defaultLayout={defaultLayout}\n ignoreStoredLayout={ignoreStoredLayout}\n viewLayout={c.state.layout}\n >\n <LayoutStateSync c={c} />\n <ShellStack props={props} filters={filters} />\n </DataViewsLayoutProvider>\n );\n}\n"],"mappings":"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","names":["default"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/form/Switch/Switch.styles.ts"],"sourcesContent":["import { alpha } from '@mui/material/styles/index.js';\nimport type { CSSObject, Theme } from '@mui/material/styles/index.js';\n\nimport {\n bounceAnimation,\n glowAnimation,\n pulseAnimation,\n rippleAnimation,\n shimmerAnimation,\n spinAnimation,\n} from './Switch.animations';\nimport {\n DISABLED,\n IOS_BASE_OFFSET,\n IOS_THUMB_SHADOW,\n IOS_TRAVEL_INSET,\n SWITCH_GLASS,\n SWITCH_GLOW,\n NEUTRAL_CONTRAST,\n NEUTRAL_FALLBACK,\n NEUTRAL_GREY,\n SWITCH_FOCUS_RING,\n SWITCH_GRADIENT,\n SWITCH_HOVER,\n SWITCH_PULSE,\n SWITCH_RIPPLE,\n SWITCH_SPINNER,\n SWITCH_TRANSITION,\n RESTING_THUMB,\n THUMB_ELEVATION,\n THUMB_RADIUS,\n TRACK_LABEL,\n TRACK_RADIUS,\n geometryOf,\n iosTrackShadow,\n lookOf,\n seconds,\n showsTrackLabels,\n trackColor,\n type SwitchGeometry,\n type SwitchLook,\n} from './Switch.metrics';\nimport type { SwitchVariant } from './Switch.base';\n\nimport { inkOver, px } from '../../../tokens/theme';\nimport type { ColorValue, SizeValue } from '../../../tokens/vocabulary';\n\n// Every number below comes from `./Switch.metrics`, which the native renderer\n// reads too — see its header. The palette and the shadows stay on the MUI\n// theme so a host that re-themes either keeps moving the web.\ninterface ColorPalette {\n main: string;\n dark?: string;\n light?: string;\n contrastText?: string;\n}\n\n/** `neutral` is not a MUI palette entry, so it is built from the grey ramp. */\nconst neutralPalette = (theme: Theme): ColorPalette => ({\n main: theme.palette.grey?.[NEUTRAL_GREY.main] || NEUTRAL_FALLBACK.main,\n dark: theme.palette.grey?.[NEUTRAL_GREY.dark] || NEUTRAL_FALLBACK.dark,\n light: theme.palette.grey?.[NEUTRAL_GREY.light] || NEUTRAL_FALLBACK.light,\n contrastText: NEUTRAL_CONTRAST,\n});\n\n/**\n * Resolves a colour name to a full palette, filling any step the theme leaves\n * out from `main` and then from the primary palette. `danger` is this\n * component's name for the error palette; the rest map straight through.\n */\nconst getColorFromTheme = (theme: Theme, color: string): ColorPalette => {\n if (color === 'neutral') {\n return neutralPalette(theme);\n }\n\n const colorMap: Record<string, ColorPalette | undefined> = {\n primary: theme.palette.primary,\n secondary: theme.palette.secondary,\n success: theme.palette.success,\n warning: theme.palette.warning,\n info: theme.palette.info,\n danger: theme.palette.error,\n };\n const palette = colorMap[color] ?? theme.palette.primary;\n const { primary } = theme.palette;\n\n return {\n main: palette.main || primary.main,\n dark: palette.dark || palette.main || primary.dark,\n light: palette.light || palette.main || primary.light,\n contrastText: palette.contrastText || NEUTRAL_CONTRAST,\n };\n};\n\nexport interface SwitchFlags {\n customVariant?: SwitchVariant;\n customColor?: ColorValue;\n customSize?: SizeValue;\n glow?: boolean;\n glass?: boolean;\n gradient?: boolean;\n trackWidth?: number;\n trackHeight?: number;\n onText?: string;\n offText?: string;\n loading?: boolean;\n ripple?: boolean;\n pulse?: boolean;\n}\n\nconst thumbShadow = (theme: Theme, look: SwitchLook): string =>\n look === 'ios' ? IOS_THUMB_SHADOW : (theme.shadows[THUMB_ELEVATION[look]] ?? 'none');\n\n/** The ripple that expands from the thumb on hover. */\nconst rippleOverlay = (palette: ColorPalette): CSSObject => ({\n content: '\"\"',\n position: 'absolute',\n top: '50%',\n left: '50%',\n width: '100%',\n height: '100%',\n borderRadius: '50%',\n background: alpha(palette.main, SWITCH_RIPPLE.alpha),\n animation: `${rippleAnimation} ${seconds(SWITCH_RIPPLE.ms)} ease-out`,\n transform: 'translate(-50%, -50%)',\n pointerEvents: 'none',\n});\n\n/**\n * The ink on the CHECKED track — the thumb, the `on` wording and any on-icon\n * (FUT-1924).\n *\n * All three stated `#fff`, and the checked track is `palette.main`: the one\n * surface in this component the TENANT picks. A store with a pale brand got a\n * white thumb on a pale green bar, which does not read as a knob at all — the\n * switch looks OFF while it is on, so this is a state a user misreads rather\n * than a colour they dislike.\n *\n * The `gradient` flag paints the track `light → main → dark`, so the fills the\n * thumb travels over are handed over together and {@link inkOver} takes the\n * worst of them.\n *\n * The RESTING track is not here on purpose: it is `theme.palette.action.disabled`\n * washed over the page, which no tenant chooses, and a white thumb on it is the\n * conventional look in both modes.\n */\nconst checkedInk = (flags: SwitchFlags, palette: ColorPalette): string => {\n const fills = flags.gradient\n ? [palette.light || palette.main, palette.main, palette.dark || palette.main]\n : [palette.main];\n\n return inkOver(fills, palette.contrastText || NEUTRAL_CONTRAST);\n};\n\n/** The checked track: the filled bar behind the thumb once the switch is on. */\nconst checkedTrack = (flags: SwitchFlags, palette: ColorPalette): CSSObject => ({\n backgroundColor: palette.main,\n opacity: 1,\n border: 0,\n position: 'relative',\n overflow: 'hidden',\n ...(flags.glow && {\n animation: `${glowAnimation} ${seconds(SWITCH_GLOW.ms)} ease-in-out infinite`,\n boxShadow: `0 0 ${SWITCH_GLOW.blur}px ${alpha(palette.main, SWITCH_GLOW.alpha)}, inset 0 0 ${SWITCH_GLOW.insetBlur}px ${alpha(palette.main, SWITCH_GLOW.insetAlpha)}`,\n }),\n ...(flags.gradient && {\n background: `linear-gradient(${SWITCH_GRADIENT.checked.angleDeg}deg, ${palette.light || palette.main} ${SWITCH_GRADIENT.checked.stops[0]}%, ${palette.main} ${SWITCH_GRADIENT.checked.stops[1]}%, ${palette.dark || palette.main} ${SWITCH_GRADIENT.checked.stops[2]}%)`,\n backgroundSize: '200% 100%',\n animation: `${shimmerAnimation} ${seconds(SWITCH_GRADIENT.shimmerMs)} ease infinite`,\n }),\n});\n\nconst switchBaseSx = (\n theme: Theme,\n flags: SwitchFlags,\n palette: ColorPalette,\n geometry: SwitchGeometry,\n look: SwitchLook,\n): CSSObject => {\n const { width, thumbSize, padding } = geometry;\n const isIos = look === 'ios';\n\n return {\n padding,\n margin: 0,\n transitionDuration: `${SWITCH_TRANSITION.ms}ms`,\n transitionTimingFunction: SWITCH_TRANSITION.easing,\n ...(isIos && { transform: `translateX(${IOS_BASE_OFFSET}px)` }),\n '&:hover': {\n '& .MuiSwitch-thumb': {\n transform: flags.loading ? 'none' : `scale(${SWITCH_HOVER.thumbScale})`,\n boxShadow: `${theme.shadows[SWITCH_HOVER.elevation]}, 0 0 ${SWITCH_HOVER.blur}px ${alpha(palette.main, SWITCH_HOVER.alpha)}`,\n },\n ...(flags.ripple && { '&::after': rippleOverlay(palette) }),\n },\n '&.Mui-checked': {\n // The thumb travels the track minus its own width and both paddings; the\n // iOS look insets differently, so it gets its own distance.\n transform: `translateX(${width - thumbSize - padding * 2}px)`,\n color: checkedInk(flags, palette),\n '& .MuiSwitch-thumb': {\n animation: flags.loading ? 'none' : `${bounceAnimation} ${seconds(SWITCH_TRANSITION.ms)} ease-out`,\n // `glass` draws its own translucent thumb and means to show the track\n // through it, so it keeps the fill it chose.\n ...(flags.glass ? {} : { backgroundColor: checkedInk(flags, palette) }),\n },\n '& + .MuiSwitch-track': checkedTrack(flags, palette),\n '&.Mui-disabled + .MuiSwitch-track': { opacity: DISABLED.checkedTrackOpacity },\n ...(isIos && { transform: `translateX(${width - thumbSize - IOS_TRAVEL_INSET}px)` }),\n },\n '&.Mui-focusVisible .MuiSwitch-thumb': {\n color: palette.main,\n border: `${SWITCH_FOCUS_RING.width}px solid ${alpha(palette.main, SWITCH_FOCUS_RING.alpha)}`,\n },\n '&.Mui-disabled .MuiSwitch-thumb': { color: theme.palette.grey[DISABLED.thumbGrey] },\n '&.Mui-disabled + .MuiSwitch-track': { opacity: DISABLED.trackOpacity },\n };\n};\n\nconst thumbSx = (\n theme: Theme,\n flags: SwitchFlags,\n palette: ColorPalette,\n thumbSize: number,\n look: SwitchLook,\n): CSSObject => ({\n width: thumbSize,\n height: thumbSize,\n borderRadius: THUMB_RADIUS[look](thumbSize),\n // `.Mui-checked` above replaces this for the brand-filled track; see\n // {@link RESTING_THUMB} for why the resting one stays white.\n backgroundColor: RESTING_THUMB,\n boxShadow: thumbShadow(theme, look),\n transition: `all ${seconds(SWITCH_TRANSITION.ms)} ${SWITCH_TRANSITION.easing}`,\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n ...(flags.glass && {\n backgroundColor: alpha(theme.palette.background.paper, SWITCH_GLASS.thumbAlpha),\n backdropFilter: `blur(${SWITCH_GLASS.thumbBlur}px)`,\n border: `1px solid ${alpha(theme.palette.divider, SWITCH_GLASS.borderAlpha)}`,\n }),\n ...(flags.pulse && { animation: `${pulseAnimation} ${seconds(SWITCH_PULSE.ms)} ease-in-out infinite` }),\n ...(flags.loading && {\n // A spinner drawn inside the thumb rather than over the whole control.\n '&::after': {\n content: '\"\"',\n position: 'absolute',\n width: thumbSize * SWITCH_SPINNER.sizeRatio,\n height: thumbSize * SWITCH_SPINNER.sizeRatio,\n border: `${SWITCH_SPINNER.borderWidth}px solid ${palette.main}`,\n borderTop: `${SWITCH_SPINNER.borderWidth}px solid transparent`,\n borderRadius: '50%',\n animation: `${spinAnimation} ${seconds(SWITCH_SPINNER.ms)} linear infinite`,\n },\n }),\n ...(look === 'material' && {\n '&::before': {\n content: '\"\"',\n position: 'absolute',\n width: '100%',\n height: '100%',\n borderRadius: 'inherit',\n backgroundColor: palette.main,\n opacity: 0,\n transform: 'scale(0)',\n transition: 'all 0.3s ease',\n },\n }),\n});\n\n/** The on/off wording the `label` variant prints inside the track. */\nconst trackLabels = (\n theme: Theme,\n flags: SwitchFlags,\n palette: ColorPalette,\n onText?: string,\n offText?: string,\n): CSSObject => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingLeft: theme.spacing(TRACK_LABEL.insetUnits),\n paddingRight: theme.spacing(TRACK_LABEL.insetUnits),\n fontSize: px(TRACK_LABEL.fontSize),\n fontWeight: TRACK_LABEL.fontWeight,\n color: theme.palette.text.secondary,\n '&::before, &::after': {\n content: '\"\"',\n position: 'absolute',\n fontSize: px(TRACK_LABEL.fontSize),\n fontWeight: TRACK_LABEL.fontWeight,\n top: '50%',\n transform: 'translateY(-50%)',\n zIndex: 1,\n },\n ...(onText && {\n '&::before': {\n content: `\"${onText}\"`,\n left: theme.spacing(TRACK_LABEL.insetUnits),\n // The `on` word sits at the end the thumb travels TO, which is the\n // filled half of the track once checked.\n color: checkedInk(flags, palette),\n },\n }),\n ...(offText && {\n '&::after': {\n content: `\"${offText}\"`,\n right: theme.spacing(TRACK_LABEL.insetUnits),\n color: theme.palette.text.secondary,\n },\n }),\n});\n\nconst trackSx = (\n theme: Theme,\n flags: SwitchFlags,\n palette: ColorPalette,\n height: number,\n look: SwitchLook,\n): CSSObject => {\n const { glass, gradient, onText, offText, customVariant } = flags;\n\n return {\n borderRadius: TRACK_RADIUS[look](height),\n backgroundColor: trackColor(\n { black: theme.palette.common.black, disabled: theme.palette.action.disabled },\n look,\n ),\n opacity: 1,\n transition: `all ${seconds(SWITCH_TRANSITION.ms)} ${SWITCH_TRANSITION.easing}`,\n position: 'relative',\n boxShadow: look === 'ios' ? iosTrackShadow() : 'none',\n ...(glass && {\n backgroundColor: alpha(theme.palette.background.paper, SWITCH_GLASS.trackAlpha),\n backdropFilter: `blur(${SWITCH_GLASS.trackBlur}px)`,\n border: `1px solid ${alpha(theme.palette.divider, SWITCH_GLASS.borderAlpha)}`,\n }),\n ...(gradient &&\n !glass && {\n background: `linear-gradient(${SWITCH_GRADIENT.resting.angleDeg}deg, ${alpha(palette.light || palette.main, SWITCH_GRADIENT.resting.lightAlpha)}, ${alpha(palette.main, SWITCH_GRADIENT.resting.mainAlpha)})`,\n }),\n ...(showsTrackLabels(customVariant, onText, offText) &&\n trackLabels(theme, flags, palette, onText, offText)),\n };\n};\n\n/**\n * The same checked-track ink, for the two ICONS the control overlays on the\n * track — which are drawn as components rather than styles, so they cannot\n * reach {@link checkedInk} directly.\n */\nexport const onTrackInk = (theme: Theme, flags: SwitchFlags): string =>\n checkedInk(flags, getColorFromTheme(theme, flags.customColor ?? 'primary'));\n\nexport const switchSx = (theme: Theme, flags: SwitchFlags): CSSObject => {\n const palette = getColorFromTheme(theme, flags.customColor ?? 'primary');\n const geometry = geometryOf(flags.customSize, flags.trackWidth, flags.trackHeight);\n const look = lookOf(flags.customVariant);\n\n return {\n width: geometry.width,\n height: geometry.height,\n padding: 0,\n overflow: 'visible',\n '& .MuiSwitch-switchBase': switchBaseSx(theme, flags, palette, geometry, look),\n '& .MuiSwitch-thumb': thumbSx(theme, flags, palette, geometry.thumbSize, look),\n '& .MuiSwitch-track': trackSx(theme, flags, palette, geometry.height, look),\n };\n};\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/data-display/DataGrid/DataGrid.cells.tsx"],"sourcesContent":["/**\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 from '@mui/material/Button/index.js';\nimport Checkbox from '@mui/material/Checkbox/index.js';\nimport IconButton from '@mui/material/IconButton/index.js';\nimport TableCell from '@mui/material/TableCell/index.js';\nimport TableRow from '@mui/material/TableRow/index.js';\nimport Typography from '@mui/material/Typography/index.js';\nimport { useTheme } from '@mui/material/styles/index.js';\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"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/data-display/DataViews/DataViewsGrid.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef } from \"react\";\n\nimport { type SortFieldDefinition } from \"../../layout/ContentToolbar\";\n\nimport { GridShell } from \"./data-views-grid-parts\";\nimport type { SelectionExtraRender } from \"./data-views-selection-extra\";\nimport type { ListGroupConfig } from \"./list-card-rails\";\nimport type { DisplayPanelView } from \"./data-views-display-panel\";\nimport type { BoardConfig } from \"./DataViewsBoard\";\nimport type { DataViewExport } from \"./data-views-export\";\nimport type { ScopeConfig } from \"./data-views-scopes\";\nimport type { DataViewCardSelection } from \"./data-views-types\";\nimport {\n type DataViewColumn,\n type DataViewsLayout,\n type DataViewServer,\n type DataViewState,\n type DataViewSyncState,\n type FilterFieldConfig,\n type RangeFieldConfig,\n type RowAction,\n} from \"./data-views-types\";\nimport { useDataViewsState } from \"./use-data-views-state\";\n\ninterface DataViewsGridProps<T extends Record<string, unknown>> {\n rows: T[];\n columns: DataViewColumn<T>[];\n fields: FilterFieldConfig<T>[];\n /** Optional numeric min/max range filters (advanced \"filter by amount\"). */\n rangeFields?: RangeFieldConfig<T>[];\n getRowId: (row: T) => string | number;\n /** Row click opens the row; clicks in the actions column are ignored. */\n onRowClick?: (row: T) => void;\n emptyState?: React.ReactNode;\n dataTestId?: string;\n testIdPrefix?: string;\n /** Seed/replace the view state. A NEW reference re-applies (used to apply a saved view). */\n appliedState?: DataViewState;\n /**\n * URL-driven controls (search/pills/ranges/sort) that RE-APPLY on reference\n * change while preserving column visibility — for server-mode lists that keep\n * their filter/sort/page in the address bar (see {@link DataViewSyncState}).\n */\n syncState?: DataViewSyncState;\n /** Notified on every view-state change (so a save-view modal can read it). */\n onStateChange?: (state: DataViewState) => void;\n /**\n * Notified with the currently-visible (search + filter matched) rows whenever\n * they change — so a page-level Export exports what the user sees, not the\n * full dataset.\n */\n onVisibleRowsChange?: (rows: T[]) => void;\n /** Saved-views UI injected into the toolbar (FUT-89). */\n toolbarRightSlot?: React.ReactNode;\n /**\n * The saved-view chrome for the Exibir panel: its VISÃO header (with the\n * views dropdown) and its Redefinir / Salvar visão footer. Supplied by\n * `DataViewsTableBase`; without it the panel is tabs only.\n */\n displayView?: DisplayPanelView;\n /** Big page title in the header row (next to the funnel + gear). */\n title?: string;\n /** Primary page actions rendered at the header's right. */\n headerActions?: React.ReactNode;\n /**\n * Sort options for the toolbar's \"Sort By\" dropdown. Defaults to the sortable\n * columns (asc/desc each) when omitted.\n */\n sortFields?: SortFieldDefinition[];\n /**\n * Per-sort-field VALUE KIND (`\"currency\" | \"number\" | \"date\" | \"text\"`), so the\n * Exibir panel phrases the direction in that column's own terms. \"Crescente\"\n * on a currency column is a puzzle; \"Menor → maior\" is not. Defaults to text.\n */\n sortKinds?: Record<string, string>;\n /**\n * Opt-in \"Exportar\" control. The grid hands the host the current query,\n * UNPAGINATED, and the host re-queries — the grid never fetches, and an\n * export therefore follows the filters rather than the loaded page.\n */\n exportConfig?: DataViewExport;\n /**\n * A single, reusable list of row actions that drives BOTH the per-row \"⋮\"\n * kebab AND the bulk-actions menu (tabwoah model). When provided, the grid\n * appends a kebab actions column automatically (unless the page already\n * defines one) and shows an \"Ações\" bulk menu when rows are selected.\n */\n rowActions?: RowAction<T>[];\n /**\n * Extra leading control rendered in the auto kebab column, before the \"⋮\"\n * (e.g. a favourite star). Only used when `rowActions` is set.\n */\n rowActionsLeading?: (row: T) => React.ReactNode;\n /**\n * Low-level override for the selection bulk control. Prefer `rowActions`.\n * Receives the selected rows + a `clearSelection` callback.\n */\n bulkActions?: (selectedRows: T[], clearSelection: () => void) => React.ReactNode;\n /**\n * A control rendered beside the \"N selected\" count, for changing WHAT is\n * selected rather than what happens to it — a \"select all N matching the\n * filter\" widening, above all.\n *\n * Called only while something is selected, and handed\n * {@link SelectionExtraContext.allOnPageSelected} so the control can follow\n * the convention operators already know: the widening appears once the whole\n * page is ticked, and not before.\n */\n selectionExtra?: SelectionExtraRender<T>;\n /**\n * Render a bespoke per-row menu in the actions column instead of the auto\n * kebab — typically an entity's self-contained 3-dots menu that owns its own\n * popups, so the SAME menu component drives both the table row and the card.\n * `rowActions`/`bulkActions` still drive the multi-row bulk menu.\n */\n renderRowMenu?: (row: T) => React.ReactNode;\n /**\n * Opt-in \"Grade\" (cards) layout. When provided, a Grade/Tabela toggle appears in\n * the toolbar and the cards body renders each visible row via this function\n * (reusing the same search/filter/sort). Omit ⇒ table only (unchanged).\n */\n renderCard?: (row: T, selection: DataViewCardSelection) => React.ReactNode;\n /**\n * Opt-in \"Quadro\" (board) layout: the loaded page laid out as columns of one\n * grouping field. Reuses `renderCard`, so supplying a board WITHOUT one simply\n * offers no board. Best when the groups are states in a state machine — derive\n * these groups and `scopes` from ONE definition so the two cannot drift.\n */\n board?: BoardConfig<T>;\n /**\n * Opt-in \"Lista\" layout (FUT-733): one FULL-WIDTH row per record, rendered by\n * the entity — a marker, a title, a subtitle and a value on the right. Sits\n * between the table (compare columns) and the cards (browse); omit ⇒ not\n * offered, exactly as `renderCard` gates the cards.\n */\n renderListRow?: (row: T, selection: DataViewCardSelection) => React.ReactNode;\n /**\n * The Lista's SHARED COLUMNS — declared once for the list, obeyed by every row.\n *\n * This is what makes a list line up by construction rather than by convention.\n * Omit it and each row still resolves its own tracks from its own config,\n * which agrees with its neighbours right up until one row carries an unusually\n * wide value.\n */\n listGroup?: ListGroupConfig<T>;\n /**\n * The page-level partition rendered as an exclusive tab strip above the\n * toolbar, with server-supplied counts. Requires `server`: a scope is applied\n * at the backend, never in the browser.\n */\n scopes?: ScopeConfig[];\n /** The row field the scopes partition by — used only to reject a pill over the same field. */\n scopeFieldId?: string;\n /** Which layout to show first when the user has expressed no preference (default \"table\"). */\n defaultLayout?: DataViewsLayout;\n /**\n * Ignore the remembered cross-screen layout preference and pin to\n * `defaultLayout`. For tables that exist to SHOW a layout — stories, docs,\n * screenshots — not for real screens.\n */\n ignoreStoredLayout?: boolean;\n /**\n * Opt into the responsive inline filter UX (collapsible filter row on wide\n * screens, modal on narrow). Default `false` keeps the classic slide-in panel.\n */\n inlineFilters?: boolean;\n /** Keep the inline search visible with no filter fields and no active search. */\n alwaysShowSearch?: boolean;\n /** Server-mode wiring; when set the grid is backend-driven (no client filter/sort/paginate). */\n server?: DataViewServer;\n}\n\n/**\n * Surface the visible (filtered) rows so a page-level Export matches the view.\n *\n * Pages pass inline column/field arrays, so `matched` is a fresh reference on\n * every render even when its contents are unchanged. The guard is a signature\n * over the rows' *contents* (not just their ids), so the callback — and the\n * parent `useState` it usually drives — fires only when the visible data\n * actually changes. Ids alone are not enough: a server refresh can change a\n * visible row's values while keeping its id, and the export must reflect them.\n * Content-equal renders keep the same signature, so this never loops.\n */\nfunction useVisibleRowsNotifier<T>(matched: T[], onVisibleRowsChange?: (rows: T[]) => void): void {\n const visibleSignature = JSON.stringify(matched);\n const lastSignature = useRef<string | null>(null);\n useEffect(() => {\n if (lastSignature.current === visibleSignature) return;\n lastSignature.current = visibleSignature;\n onVisibleRowsChange?.(matched);\n }, [visibleSignature, matched, onVisibleRowsChange]);\n}\n\n/**\n * The reusable admin DataViews table (FUT-88): the shared ContentToolbar +\n * TableFilter panel over `@12-apps/ui` DataGrid. State + derived data live in\n * {@link useDataViewsState}; the render lives in `GridShell`. This component just\n * connects the two. Reused across every admin list page.\n */\nexport function DataViewsGrid<T extends Record<string, unknown>>(\n props: DataViewsGridProps<T>,\n): React.JSX.Element {\n // Forwarded as a whole rather than restated name-by-name twice: this component\n // only ADDS the controller, and a 25-name destructure repeated in the JSX is\n // where a newly added prop silently stops being passed on.\n const { rangeFields = [], testIdPrefix = \"table\" } = props;\n const controller = useDataViewsState({ ...props, rangeFields, testIdPrefix });\n useVisibleRowsNotifier(controller.matched, props.onVisibleRowsChange);\n return <GridShell {...props} c={controller} rangeFields={rangeFields} testIdPrefix={testIdPrefix} />;\n}\n"],"mappings":";;;;;;;;AAEA,SAAS,WAAW,cAAc;AAgNzB;AAzBT,SAAS,uBAA0B,SAAc,qBAAiD;AAChG,QAAM,mBAAmB,KAAK,UAAU,OAAO;AAC/C,QAAM,gBAAgB,OAAsB,IAAI;AAChD,YAAU,MAAM;AACd,QAAI,cAAc,YAAY,iBAAkB;AAChD,kBAAc,UAAU;AACxB,0BAAsB,OAAO;AAAA,EAC/B,GAAG,CAAC,kBAAkB,SAAS,mBAAmB,CAAC;AACrD;AAQO,SAAS,cACd,OACmB;AAInB,QAAM,EAAE,cAAc,CAAC,GAAG,eAAe,QAAQ,IAAI;AACrD,QAAM,aAAa,kBAAkB,EAAE,GAAG,OAAO,aAAa,aAAa,CAAC;AAC5E,yBAAuB,WAAW,SAAS,MAAM,mBAAmB;AACpE,SAAO,oBAAC,aAAW,GAAG,OAAO,GAAG,YAAY,aAA0B,cAA4B;AACpG;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/tokens/theme.ts"],"sourcesContent":["import { darken, getContrastRatio, lighten } from './color';\nimport { cssLengthToPx, cssTrackingToEm } from './css-units';\nimport { HEADING_SCALE, type HeadingLevel } from './heading-scale';\n\nimport type { SizeValue } from './vocabulary';\n\n/**\n * THE THEME BOTH RENDERERS READ.\n *\n * On the web every component styles itself from MUI's `Theme`, which is built\n * by the host (`@12-apps/app-shell`'s `createAppTheme` in the origin apps) and\n * reaches a component through emotion's context. React Native has no emotion,\n * no CSS and no MUI, so a native `Button` needs the same decisions — the\n * palette, the spacing unit, the radius, the type scale — from somewhere that\n * does not import a renderer.\n *\n * This is that somewhere. `UiTheme` is a plain object of numbers and colour\n * strings. `createUiTheme` derives it the way MUI's `createPalette` derives its\n * own: a `light` shade is `lighten(main, 0.2)`, a `dark` shade `darken(main,\n * 0.3)`, `contrastText` flips at a 3:1 ratio against `rgba(0, 0, 0, 0.87)`.\n * Same seeds in, same shades out, on both sides — that is the whole basis for\n * a native button being the web button's colour and not a near miss.\n *\n * Numbers are in px on the web and dp on native; both are the CSS-pixel unit\n * a design is drawn in, so a `fontSize: 16` here IS `1rem` in a web style\n * and `16` in a `StyleSheet`. The web components keep their `rem` strings and\n * derive them from these numbers where the two meet (see `px()` below and the\n * `*.metrics.ts` file beside each ported component).\n *\n * `danger` and `neutral` are this package's names (see `./scales`); `danger`\n * is MUI's `error` and `neutral` is drawn from the grey ramp the way\n * `Button.styles.ts` has always drawn it.\n */\n\nexport type UiThemeMode = 'light' | 'dark';\n\nexport interface UiPaletteColor {\n main: string;\n light: string;\n dark: string;\n contrastText: string;\n}\n\nexport type UiGreyStep = 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900;\n\nexport interface UiPalette {\n mode: UiThemeMode;\n primary: UiPaletteColor;\n secondary: UiPaletteColor;\n success: UiPaletteColor;\n warning: UiPaletteColor;\n info: UiPaletteColor;\n danger: UiPaletteColor;\n neutral: UiPaletteColor;\n text: { primary: string; secondary: string; disabled: string };\n background: { default: string; paper: string };\n divider: string;\n action: {\n active: string;\n hover: string;\n selected: string;\n disabled: string;\n disabledBackground: string;\n focus: string;\n };\n grey: Record<UiGreyStep, string>;\n}\n\n/** One step of the body scale: `fontSize` in px, `lineHeight` as a ratio. */\nexport interface UiTypeStep {\n fontSize: number;\n lineHeight: number;\n}\n\nexport type UiFontWeight = 'light' | 'normal' | 'medium' | 'semibold' | 'bold';\n\nexport interface UiHeadingStep extends UiTypeStep {\n /** In em, so it scales with the step. `undefined` is \"normal\". */\n letterSpacing?: number;\n normalWeight: number;\n}\n\nexport interface UiTypography {\n /**\n * Native has no fallback stacks: a font is either installed and named, or\n * `undefined` and the platform's own. The web default is MUI's Roboto stack.\n */\n fontFamily: string | undefined;\n monospaceFontFamily: string | undefined;\n sizes: Record<SizeValue, UiTypeStep>;\n weights: Record<UiFontWeight, number>;\n heading: Record<HeadingLevel, UiHeadingStep>;\n}\n\nexport interface UiTheme {\n mode: UiThemeMode;\n palette: UiPalette;\n /** MUI's `theme.spacing(n)`: `n` units of {@link UiTheme.spacingUnit}, in px. */\n spacing: (units: number) => number;\n spacingUnit: number;\n /** `md` is MUI's `shape.borderRadius`; the others are its halves and doubles. */\n radius: { sm: number; md: number; lg: number; xl: number; full: number };\n typography: UiTypography;\n zIndex: { appBar: number; drawer: number; modal: number; snackbar: number; tooltip: number };\n}\n\n/** A seed for one palette slot: a hex `main`, or any subset of the four shades. */\nexport type UiPaletteSeed = string | Partial<UiPaletteColor>;\n\nexport interface UiThemeOptions {\n mode?: UiThemeMode;\n palette?: Partial<{\n primary: UiPaletteSeed;\n secondary: UiPaletteSeed;\n success: UiPaletteSeed;\n warning: UiPaletteSeed;\n info: UiPaletteSeed;\n danger: UiPaletteSeed;\n background: Partial<UiPalette['background']>;\n }>;\n typography?: Partial<Pick<UiTypography, 'fontFamily' | 'monospaceFontFamily'>>;\n spacingUnit?: number;\n}\n\nconst ROOT_FONT_PX = 16;\n\n/** The px value as the rem string the web components write. */\nexport const px = (value: number): string => `${value / ROOT_FONT_PX}rem`;\n\n/** MUI's `createPalette` defaults, exactly. */\nconst TONAL_OFFSET = 0.2;\nconst CONTRAST_THRESHOLD = 3;\nconst DARK_TEXT_PRIMARY = 'rgba(0, 0, 0, 0.87)';\nconst LIGHT_TEXT_PRIMARY = '#fff';\n\nexport const GREY: Record<UiGreyStep, string> = {\n 50: '#fafafa',\n 100: '#f5f5f5',\n 200: '#eeeeee',\n 300: '#e0e0e0',\n 400: '#bdbdbd',\n 500: '#9e9e9e',\n 600: '#757575',\n 700: '#616161',\n 800: '#424242',\n 900: '#212121',\n};\n\n/**\n * The platform's own seeds. The pair `@12-apps/ui`'s Storybook preview and\n * `@12-apps/app-shell`'s `DEFAULT_THEME_TOKENS` both carry — keep the three in\n * step if the design tokens change.\n */\nexport const DEFAULT_BRAND: Record<UiThemeMode, { primary: string; secondary: string }> = {\n light: { primary: '#6366F1', secondary: '#8B5CF6' },\n dark: { primary: '#818CF8', secondary: '#A78BFA' },\n};\n\n/** MUI's semantic defaults per mode. These are declared shades, not derived. */\nconst SEMANTIC_DEFAULTS: Record<\n UiThemeMode,\n Record<'success' | 'warning' | 'info' | 'danger', UiPaletteColor>\n> = {\n light: {\n success: { main: '#2e7d32', light: '#4caf50', dark: '#1b5e20', contrastText: '#fff' },\n warning: { main: '#ed6c02', light: '#ff9800', dark: '#e65100', contrastText: '#fff' },\n info: { main: '#0288d1', light: '#03a9f4', dark: '#01579b', contrastText: '#fff' },\n danger: { main: '#d32f2f', light: '#ef5350', dark: '#c62828', contrastText: '#fff' },\n },\n dark: {\n success: { main: '#66bb6a', light: '#81c784', dark: '#388e3c', contrastText: DARK_TEXT_PRIMARY },\n warning: { main: '#ffa726', light: '#ffb74d', dark: '#f57c00', contrastText: DARK_TEXT_PRIMARY },\n info: { main: '#29b6f6', light: '#4fc3f7', dark: '#0288d1', contrastText: DARK_TEXT_PRIMARY },\n danger: { main: '#f44336', light: '#e57373', dark: '#d32f2f', contrastText: '#fff' },\n },\n};\n\nconst MODE_DEFAULTS: Record<\n UiThemeMode,\n Pick<UiPalette, 'text' | 'background' | 'divider' | 'action'>\n> = {\n light: {\n text: { primary: DARK_TEXT_PRIMARY, secondary: 'rgba(0, 0, 0, 0.6)', disabled: 'rgba(0, 0, 0, 0.38)' },\n background: { default: '#fff', paper: '#fff' },\n divider: 'rgba(0, 0, 0, 0.12)',\n action: {\n active: 'rgba(0, 0, 0, 0.54)',\n hover: 'rgba(0, 0, 0, 0.04)',\n selected: 'rgba(0, 0, 0, 0.08)',\n disabled: 'rgba(0, 0, 0, 0.26)',\n disabledBackground: 'rgba(0, 0, 0, 0.12)',\n focus: 'rgba(0, 0, 0, 0.12)',\n },\n },\n dark: {\n text: { primary: '#fff', secondary: 'rgba(255, 255, 255, 0.7)', disabled: 'rgba(255, 255, 255, 0.5)' },\n background: { default: '#121212', paper: '#121212' },\n divider: 'rgba(255, 255, 255, 0.12)',\n action: {\n active: '#fff',\n hover: 'rgba(255, 255, 255, 0.08)',\n selected: 'rgba(255, 255, 255, 0.16)',\n disabled: 'rgba(255, 255, 255, 0.3)',\n disabledBackground: 'rgba(255, 255, 255, 0.12)',\n focus: 'rgba(255, 255, 255, 0.12)',\n },\n },\n};\n\n/**\n * MUI's `getContrastText`: white where white reads at 3:1 on the colour, the\n * light mode's dark ink otherwise. (MUI's source spells the white as the DARK\n * palette's `text.primary`, which is what made it easy to read backwards.)\n */\nexport function contrastText(background: string): string {\n return getContrastRatio(background, LIGHT_TEXT_PRIMARY) >= CONTRAST_THRESHOLD\n ? LIGHT_TEXT_PRIMARY\n : DARK_TEXT_PRIMARY;\n}\n\n/**\n * The ink that reads on EVERY one of these fills (FUT-1924).\n *\n * {@link contrastText} answers for one fill, which is all MUI's `augmentColor`\n * ever needs: a solid button is a single flat colour. Two components paint the\n * label over something that is not one colour — `Button`'s `gradient` variant\n * runs between two stops, and `Switch`'s thumb travels the whole length of a\n * checked track — and both of them stated `#fff` outright instead, which is\n * white-on-pale the moment a white-labelled host hands the library a pale\n * brand. Audited across the library, those two were the only places a hardcoded\n * white sat over a surface the TENANT chooses.\n *\n * **This deliberately does not follow `contrastText`'s rule.** MUI's is a\n * threshold that PREFERS white — white wherever white clears 3:1 — which is a\n * brand-feel decision, and it is kept for every existing caller so nothing\n * already legible moves. Here the fills can disagree: over MUI's own success\n * pair white is 2.78:1 on `#4caf50` and dark ink 2.66:1 on `#1b5e20`, so\n * neither meets any threshold and asking whether one does is the wrong\n * question. The answer is whichever ink has the better WORST case across the\n * fills — which is also not what either fill says on its own, since\n * `contrastText('#4caf50')` is dark ink.\n *\n * A gradient wide enough that neither ink clears 4.5:1 anywhere is a palette\n * problem this cannot fix — it returns the less bad ink and does not pretend\n * otherwise.\n *\n * `Math.min` is the claim, and it is worth knowing that no test can prove it\n * against `Math.max` today: the two candidate inks sit at opposite ends of the\n * luminance range, so ranking them by their best fill and by their worst gives\n * the same winner for every possible pair (checked exhaustively). Worst case is\n * still what this MEANS, and the moment a third ink or one that is not an\n * extreme is offered, the two stop agreeing.\n *\n * `fallback` is returned when a fill cannot be decomposed: {@link getContrastRatio}\n * throws on a format it does not know, and a throw inside an emotion style\n * function takes the render down with it.\n */\nexport function inkOver(fills: readonly string[], fallback: string): string {\n try {\n const worstCase = (ink: string): number =>\n Math.min(...fills.map((fill) => getContrastRatio(ink, fill)));\n\n return worstCase(LIGHT_TEXT_PRIMARY) >= worstCase(DARK_TEXT_PRIMARY)\n ? LIGHT_TEXT_PRIMARY\n : DARK_TEXT_PRIMARY;\n } catch {\n return fallback;\n }\n}\n\n/**\n * MUI's `augmentColor` for a custom colour: derive whatever shade the seed\n * left out. `light` is one tonal offset up, `dark` one and a half down.\n */\nexport function augmentColor(seed: UiPaletteSeed): UiPaletteColor {\n const partial = typeof seed === 'string' ? { main: seed } : seed;\n const main = partial.main ?? partial.light ?? partial.dark;\n if (!main) {\n throw new Error('@12-apps/ui: a palette seed needs at least a `main` colour.');\n }\n return {\n main,\n light: partial.light ?? lighten(main, TONAL_OFFSET),\n dark: partial.dark ?? darken(main, TONAL_OFFSET * 1.5),\n contrastText: partial.contrastText ?? contrastText(main),\n };\n}\n\nconst semantic = (\n mode: UiThemeMode,\n key: 'success' | 'warning' | 'info' | 'danger',\n seed: UiPaletteSeed | undefined,\n): UiPaletteColor => (seed === undefined ? SEMANTIC_DEFAULTS[mode][key] : augmentColor(seed));\n\n/** `neutral` as `accentFor` in `./scales` has always drawn it: three greys and white. */\nexport const NEUTRAL: UiPaletteColor = {\n main: GREY[600],\n light: GREY[400],\n dark: GREY[800],\n contrastText: '#fff',\n};\n\n/** The body scale `Text` renders, in px. `Text.tsx`'s rem map is this, divided by 16. */\nexport const TYPE_SIZES: Record<SizeValue, UiTypeStep> = {\n xs: { fontSize: 12, lineHeight: 1.2 },\n sm: { fontSize: 14, lineHeight: 1.3 },\n md: { fontSize: 16, lineHeight: 1.5 },\n lg: { fontSize: 18, lineHeight: 1.4 },\n xl: { fontSize: 20, lineHeight: 1.3 },\n};\n\nexport const FONT_WEIGHTS: Record<UiFontWeight, number> = {\n light: 300,\n normal: 400,\n medium: 500,\n semibold: 600,\n bold: 700,\n};\n\n// `HEADING_SCALE` speaks CSS, this theme speaks numbers; `./css-units` is the\n// one place that conversion is written.\nconst HEADING_STEPS = Object.fromEntries(\n Object.entries(HEADING_SCALE).map(([level, metrics]) => [\n level,\n {\n fontSize: cssLengthToPx(metrics.fontSize, ROOT_FONT_PX),\n lineHeight: metrics.lineHeight,\n letterSpacing: cssTrackingToEm(metrics.letterSpacing),\n normalWeight: metrics.normalWeight,\n },\n ]),\n) as Record<HeadingLevel, UiHeadingStep>;\n\nexport const WEB_FONT_FAMILY = '\"Roboto\", \"Helvetica\", \"Arial\", sans-serif';\nexport const WEB_MONOSPACE_FONT_FAMILY = 'Monaco, Menlo, \"Ubuntu Mono\", \"Courier New\", monospace';\n\n/**\n * Build the theme. Every field is derived here so a host that changes one\n * seed gets every dependent shade recomputed, on both renderers, identically.\n */\nexport function createUiTheme(options: UiThemeOptions = {}): UiTheme {\n const mode = options.mode ?? 'light';\n const seeds = options.palette ?? {};\n const brand = DEFAULT_BRAND[mode];\n const defaults = MODE_DEFAULTS[mode];\n const spacingUnit = options.spacingUnit ?? 8;\n\n const palette: UiPalette = {\n mode,\n primary: augmentColor(seeds.primary ?? brand.primary),\n secondary: augmentColor(seeds.secondary ?? brand.secondary),\n success: semantic(mode, 'success', seeds.success),\n warning: semantic(mode, 'warning', seeds.warning),\n info: semantic(mode, 'info', seeds.info),\n danger: semantic(mode, 'danger', seeds.danger),\n neutral: NEUTRAL,\n text: defaults.text,\n background: { ...defaults.background, ...seeds.background },\n divider: defaults.divider,\n action: defaults.action,\n grey: GREY,\n };\n\n return {\n mode,\n palette,\n spacing: (units: number) => units * spacingUnit,\n spacingUnit,\n radius: { sm: 2, md: 4, lg: 8, xl: 16, full: 9999 },\n typography: {\n fontFamily: options.typography?.fontFamily,\n monospaceFontFamily: options.typography?.monospaceFontFamily,\n sizes: TYPE_SIZES,\n weights: FONT_WEIGHTS,\n heading: HEADING_STEPS,\n },\n zIndex: { appBar: 1100, drawer: 1200, modal: 1300, snackbar: 1400, tooltip: 1500 },\n };\n}\n\n/** The palette slot a house colour name resolves to. */\nexport type UiPaletteKey = 'primary' | 'secondary' | 'success' | 'warning' | 'info' | 'danger' | 'neutral';\n\nexport const DEFAULT_UI_THEME: UiTheme = createUiTheme();\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/data-display/DataViews/data-views-grid-bodies.tsx"],"sourcesContent":["\"use client\";\n\nimport React from \"react\";\n\nimport { DataGrid, type GridColumn, type GridSort } from \"../DataGrid\";\nimport { Box } from \"../../../mui/Box\";\n\nimport {\n cardTargetWidthFor,\n cardScaleForZoom,\n DENSITY_BOARD_SCALE,\n DENSITY_ROW_PADDING,\n useDataViewsLayout,\n type DataViewsDensity,\n} from \"./data-views-layout-context\";\nimport { cardGridTracks } from \"./data-views-grid-helpers\";\nimport { DataViewsBoard, type BoardConfig } from \"./DataViewsBoard\";\nimport { SelectAllStrip } from \"./data-views-select-all-strip\";\nimport { ListCardGroup, type ListGroupConfig } from \"./list-card-rails\";\nimport type { DataViewCardSelection } from \"./data-views-types\";\nimport type { DataViewsController } from \"./use-data-views-state\";\nimport { useDataViewsCopy } from \"./data-views-copy-context\";\n\n/* ── Body (grid) ─────────────────────────────────────────────────────────── */\n\ninterface GridBodyProps<T extends Record<string, unknown>> {\n rows: T[];\n columns: GridColumn<T>[];\n getRowId: (row: T) => string | number;\n selectedIds: Array<string | number>;\n onChangeSelected: (ids: Array<string | number>) => void;\n sortBy: GridSort[];\n onChangeSortBy: (next: GridSort[]) => void;\n /** \"server\" defers ordering to the backend (rows render as-is); \"client\" sorts in-grid. */\n sortMode: \"client\" | \"server\";\n /** Vertical cell padding, from the density preference. */\n rowPadding: number;\n dataTestId?: string;\n emptyState?: React.ReactNode;\n}\n\n/** The dense DataGrid with multi-select, wrapped in the scrollable table region. */\nfunction GridBody<T extends Record<string, unknown>>({\n rows,\n columns,\n getRowId,\n selectedIds,\n onChangeSelected,\n sortBy,\n onChangeSortBy,\n sortMode,\n rowPadding,\n dataTestId,\n emptyState,\n}: GridBodyProps<T>): React.JSX.Element {\n const copy = useDataViewsCopy();\n return (\n <Box\n sx={{\n width: \"100%\",\n overflowX: \"auto\",\n mt: 1.5,\n // Tabwoah-style dense rows: MUI's default TableCell padding keeps rows\n // tall regardless of rowHeight, so the DENSITY preference is applied\n // here rather than through `rowHeight`, which it would fight.\n \"& .MuiTableCell-root\": { py: rowPadding, fontSize: \"0.8125rem\" },\n \"& .MuiTableCell-head\": { py: 0.5, fontSize: \"0.75rem\" },\n }}\n >\n <DataGrid<T>\n rows={rows}\n columns={columns}\n getRowId={(row) => getRowId(row)}\n virtualizeRows={false}\n density=\"compact\"\n rowHeight={36}\n headerHeight={36}\n selection={{ mode: \"multi\", selectedRowIds: selectedIds, onChangeSelected }}\n sorting={{ mode: sortMode, sortBy, onChangeSortBy }}\n data-testid={dataTestId}\n emptyState={emptyState}\n emptyText={copy.grid.emptyFilteredTitle}\n />\n </Box>\n );\n}\n\n/* ── Body (cards) ────────────────────────────────────────────────────────── */\n\ninterface CardBodyProps<T extends Record<string, unknown>> {\n rows: T[];\n renderCard: (row: T, selection: DataViewCardSelection) => React.ReactNode;\n getRowId: (row: T) => string | number;\n selectedIds: Set<string | number>;\n onToggleId: (id: string | number) => void;\n /** The width each card asks for; `auto-fill` turns it into a column count. */\n targetCardWidth: number;\n /** Content scale (padding + type) handed to each card, from the zoom slider. */\n cardScale: number;\n dataTestId?: string;\n emptyState?: React.ReactNode;\n}\n\n/**\n * The \"Grade\" layout: the filtered/sorted rows rendered as an auto-filling grid\n * of entity-supplied cards. Reuses `rows` (= `c.matched`), so search/filter/sort\n * apply; the column width comes from the zoom slider, and each card is handed its\n * selection state so it can drive its own checkbox (BaseCard) — the same\n * selection model as the table.\n */\nfunction CardBody<T extends Record<string, unknown>>({\n rows,\n renderCard,\n getRowId,\n selectedIds,\n onToggleId,\n targetCardWidth,\n cardScale,\n dataTestId,\n emptyState,\n}: CardBodyProps<T>): React.JSX.Element {\n if (rows.length === 0) {\n return <Box sx={{ mt: 1.5 }}>{emptyState}</Box>;\n }\n return (\n <Box\n sx={{\n mt: 1.5,\n display: \"grid\",\n // Fixed inter-card gap — deliberately NOT scaled by the zoom slider, so\n // only the cards grow while the space between them stays constant.\n gap: 1.5,\n ...cardGridTracks(targetCardWidth),\n }}\n data-testid={dataTestId ? `${dataTestId}-cards` : \"data-views-cards\"}\n >\n {rows.map((row) => {\n const id = getRowId(row);\n return (\n <Box key={id}>\n {renderCard(row, {\n selected: selectedIds.has(id),\n onToggleSelect: () => onToggleId(id),\n scale: cardScale,\n })}\n </Box>\n );\n })}\n </Box>\n );\n}\n\n/* ── Body (list) ─────────────────────────────────────────────────────────── */\n\ninterface ListBodyProps<T extends Record<string, unknown>> {\n rows: T[];\n renderListRow: (row: T, selection: DataViewCardSelection) => React.ReactNode;\n getRowId: (row: T) => string | number;\n selectedIds: Set<string | number>;\n onToggleId: (id: string | number) => void;\n /** Gap between rows, from the density preference. */\n rowGap: number;\n /** The list's shared column config. See {@link ListGroupConfig}. */\n group?: ListGroupConfig<T>;\n /** The density every row answers, handed to the group when there is one. */\n density: DataViewsDensity;\n dataTestId?: string;\n emptyState?: React.ReactNode;\n}\n\n/**\n * The \"Lista\" layout: one FULL-WIDTH row per record, rendered by the entity — a\n * marker, a title, a subtitle and a value on the right is the shape it was\n * designed for (FUT-733).\n *\n * It sits between the table and the cards rather than replacing either: the\n * table is for comparing many columns, the cards are for browsing, and the list\n * is for scanning a queue on a narrow screen. Selection is the SAME model as\n * both — each row receives its selection state, so it can drive its own\n * checkbox and the bulk menu behaves identically in every layout.\n *\n * `scale` is handed over as 1 rather than the zoom multiplier, and the zoom\n * slider is hidden in this layout: a full-width row has no card size to\n * multiply. See {@link DataViewsZoomSlider}.\n */\nfunction ListBody<T extends Record<string, unknown>>({\n rows,\n renderListRow,\n getRowId,\n selectedIds,\n onToggleId,\n rowGap,\n group,\n density,\n dataTestId,\n emptyState,\n}: ListBodyProps<T>): React.JSX.Element {\n if (rows.length === 0) {\n return <Box sx={{ mt: 1.5 }}>{emptyState}</Box>;\n }\n const testId = dataTestId ? `${dataTestId}-list` : \"data-views-list\";\n const selectionFor = (id: string | number): DataViewCardSelection => ({\n selected: selectedIds.has(id),\n onToggleSelect: () => onToggleId(id),\n scale: 1,\n });\n\n if (group) {\n return (\n <Box sx={{ mt: 1.5 }}>\n <ListCardGroup\n cells={group.cells}\n metaColumns={group.metaColumns}\n rails={group.rails}\n reserveGutters={group.reserveGutters}\n density={density}\n gap={rowGap}\n dataTestId={testId}\n >\n {rows.map((row) => {\n const id = getRowId(row);\n // A FRAGMENT, NOT A BOX. The row is subgrid over the group's tracks\n // (`gridColumn: span railCount`), which only resolves while the card\n // is a DIRECT child of the group's grid. One wrapper element and the\n // span is measured against a grid that isn't there, so every rail\n // collapses — the exact failure the group exists to prevent.\n return (\n <React.Fragment key={id}>\n {renderListRow(row, selectionFor(id))}\n </React.Fragment>\n );\n })}\n </ListCardGroup>\n </Box>\n );\n }\n\n return (\n <Box\n sx={{ mt: 1.5, display: \"flex\", flexDirection: \"column\", gap: rowGap }}\n data-testid={testId}\n >\n {rows.map((row) => {\n const id = getRowId(row);\n return <Box key={id}>{renderListRow(row, selectionFor(id))}</Box>;\n })}\n </Box>\n );\n}\n\n/* ── Body selector (board vs list vs cards vs table, from context) ───────── */\n\ninterface GridMainProps<T extends Record<string, unknown>> {\n c: DataViewsController<T>;\n getRowId: (row: T) => string | number;\n renderCard?: (row: T, selection: DataViewCardSelection) => React.ReactNode;\n /** Opt-in \"Lista\" layout — one full-width row per record. */\n renderListRow?: (row: T, selection: DataViewCardSelection) => React.ReactNode;\n /** The Lista's shared columns. Omitted, each row resolves its own tracks. */\n listGroup?: ListGroupConfig<T>;\n /** Opt-in \"Quadro\" (board) layout — needs `renderCard`, since it reuses the card. */\n board?: BoardConfig<T>;\n dataTestId?: string;\n emptyState?: React.ReactNode;\n testIdPrefix: string;\n}\n\n/**\n * The headerless layouts, each preceded by its own select-all.\n *\n * The strip is rendered HERE rather than inside each body so all three agree on\n * where it sits and what it says — and so the table, which already has one in\n * its `<thead>`, never gets a second.\n */\nfunction Headerless<T extends Record<string, unknown>>({\n c,\n getRowId,\n testIdPrefix,\n children,\n}: {\n c: DataViewsController<T>;\n getRowId: (row: T) => string | number;\n testIdPrefix: string;\n children: React.ReactNode;\n}): React.JSX.Element {\n return (\n <>\n <SelectAllStrip\n rows={c.matched}\n getRowId={getRowId}\n selectedIds={c.selectedIds}\n onChange={(next) => c.setSelectedIds(next)}\n testIdPrefix={testIdPrefix}\n />\n {children}\n </>\n );\n}\n\n/**\n * The body for one of the three HEADERLESS layouts, or `null` for the table.\n *\n * Split out from {@link GridMain} so the select-all strip is wrapped around the\n * result exactly once instead of being repeated identically in every branch —\n * which is also what keeps either function inside the line budget.\n */\nfunction headerlessBody<T extends Record<string, unknown>>(\n { c, getRowId, renderCard, renderListRow, listGroup, board, dataTestId, emptyState }: GridMainProps<T>,\n { layout, zoom, density }: ReturnType<typeof useDataViewsLayout>,\n): React.ReactNode | null {\n if (layout === \"list\" && renderListRow) {\n return (\n <ListBody\n rows={c.matched}\n renderListRow={renderListRow}\n getRowId={getRowId}\n selectedIds={c.selectedIds}\n onToggleId={c.toggleId}\n rowGap={DENSITY_ROW_PADDING[density]}\n group={listGroup}\n density={density}\n dataTestId={dataTestId}\n emptyState={emptyState}\n />\n );\n }\n if (layout === \"board\" && board && renderCard) {\n return (\n <DataViewsBoard\n rows={c.matched}\n board={board}\n getRowId={getRowId}\n renderCard={renderCard}\n selectedIds={c.selectedIds}\n onToggleId={c.toggleId}\n // DENSITY, not zoom: the board's own knob in the Exibição tab is how\n // wide its columns are, and it is the only sizing control the board\n // has since the zoom slider was removed.\n cardScale={DENSITY_BOARD_SCALE[density]}\n dataTestId={dataTestId}\n />\n );\n }\n if (layout === \"cards\" && renderCard) {\n return (\n <CardBody\n rows={c.matched}\n renderCard={renderCard}\n getRowId={getRowId}\n selectedIds={c.selectedIds}\n onToggleId={c.toggleId}\n targetCardWidth={cardTargetWidthFor(zoom, density)}\n cardScale={cardScaleForZoom(zoom)}\n dataTestId={dataTestId}\n emptyState={emptyState}\n />\n );\n }\n return null;\n}\n\n/** Picks the body from the layout context: board, list, cards, or the dense grid. */\nexport function GridMain<T extends Record<string, unknown>>(props: GridMainProps<T>): React.JSX.Element {\n const { c, getRowId, dataTestId, emptyState, testIdPrefix } = props;\n const layoutState = useDataViewsLayout();\n const body = headerlessBody(props, layoutState);\n if (body) {\n return (\n <Headerless c={c} getRowId={getRowId} testIdPrefix={testIdPrefix}>\n {body}\n </Headerless>\n );\n }\n return (\n <GridBody\n rows={c.matched}\n columns={c.gridColumns}\n getRowId={getRowId}\n selectedIds={[...c.selectedIds]}\n onChangeSelected={(ids) => c.setSelectedIds(new Set(ids))}\n sortBy={c.state.sortBy}\n onChangeSortBy={(next: GridSort[]) => c.patch({ sortBy: next })}\n sortMode={c.serverMode ? \"server\" : \"client\"}\n rowPadding={DENSITY_ROW_PADDING[layoutState.density]}\n dataTestId={dataTestId}\n emptyState={emptyState}\n />\n );\n}\n\n"],"mappings":"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","names":["default"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/tokens/color.ts","../../../src/tokens/heading-scale.ts","../../../src/tokens/css-units.ts","../../../src/tokens/theme.ts"],"sourcesContent":["/**\n * COLOUR ARITHMETIC WITH NO RENDERER BEHIND IT.\n *\n * Every shade the web components paint comes out of MUI's colour manipulator:\n * `lighten(main, 0.2)` is a palette's `light`, `darken(main, 0.3)` its `dark`,\n * `alpha(main, 0.1)` the hover wash on an outline button. A native component\n * that wants the SAME pixel has to run the SAME arithmetic, and it cannot\n * import it — `@mui/material/styles` drags emotion and the DOM in behind it.\n *\n * So the arithmetic lives here, once, with nothing behind it. It is a faithful\n * port of `@mui/system/colorManipulator` (MIT), down to the truncation:\n * `lighten('#6366F1', 0.2)` is `rgb(130, 132, 243)` on both sides because both\n * TRUNCATE 132.6 rather than round it. A port that rounded would be one pixel\n * of tint away from the web on every button, forever, and nothing would flag it.\n *\n * `color()` space strings are deliberately unsupported: nothing in this package\n * emits one, and a smaller surface is a smaller thing to keep identical.\n */\n\nexport type ColorFormat = 'rgb' | 'rgba' | 'hsl' | 'hsla';\n\nexport interface DecomposedColor {\n type: ColorFormat;\n values: number[];\n}\n\nconst FORMATS: readonly ColorFormat[] = ['rgb', 'rgba', 'hsl', 'hsla'];\n\nconst clamp = (value: number, min = 0, max = 1): number => Math.min(Math.max(min, value), max);\n\n/** `#rgb`, `#rgba`, `#rrggbb` or `#rrggbbaa` to its `rgb()` / `rgba()` string. */\nexport function hexToRgb(color: string): string {\n const hex = color.slice(1);\n const pair = new RegExp(`.{1,${hex.length >= 6 ? 2 : 1}}`, 'g');\n let channels: string[] | null = hex.match(pair);\n if (channels && channels[0]?.length === 1) {\n channels = channels.map((channel) => channel + channel);\n }\n if (!channels) return '';\n\n const parts = channels.map((channel, index) =>\n index < 3 ? parseInt(channel, 16) : Math.round((parseInt(channel, 16) / 255) * 1000) / 1000,\n );\n return `rgb${channels.length === 4 ? 'a' : ''}(${parts.join(', ')})`;\n}\n\n/** Any supported colour string to its type and numeric channels. */\nexport function decomposeColor(color: string): DecomposedColor {\n if (color.charAt(0) === '#') {\n return decomposeColor(hexToRgb(color));\n }\n\n const marker = color.indexOf('(');\n const type = color.substring(0, marker) as ColorFormat;\n if (!FORMATS.includes(type)) {\n throw new Error(\n `@12-apps/ui: unsupported colour \"${color}\". Use #nnn, #nnnnnn, rgb(), rgba(), hsl() or hsla().`,\n );\n }\n\n const values = color\n .substring(marker + 1, color.length - 1)\n .split(',')\n .map((value) => parseFloat(value));\n\n return { type, values };\n}\n\n/** The inverse of {@link decomposeColor}, with MUI's channel truncation. */\nexport function recomposeColor({ type, values }: DecomposedColor): string {\n const parts: Array<number | string> = type.startsWith('rgb')\n ? values.map((value, index) => (index < 3 ? Math.trunc(value) : value))\n : [values[0] ?? 0, `${values[1] ?? 0}%`, `${values[2] ?? 0}%`, ...values.slice(3)];\n\n return `${type}(${parts.join(', ')})`;\n}\n\n/** An `hsl()` / `hsla()` string to its `rgb()` / `rgba()` equivalent. */\nexport function hslToRgb(color: string): string {\n const { type, values } = decomposeColor(color);\n const h = values[0] ?? 0;\n const s = (values[1] ?? 0) / 100;\n const l = (values[2] ?? 0) / 100;\n const a = s * Math.min(l, 1 - l);\n const f = (n: number, k = (n + h / 30) % 12): number =>\n l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);\n\n const rgb = [Math.round(f(0) * 255), Math.round(f(8) * 255), Math.round(f(4) * 255)];\n if (type === 'hsla') {\n return recomposeColor({ type: 'rgba', values: [...rgb, values[3] ?? 1] });\n }\n return recomposeColor({ type: 'rgb', values: rgb });\n}\n\n/** Relative luminance (WCAG 2.0), to three decimals like MUI. */\nexport function getLuminance(color: string): number {\n const decomposed = decomposeColor(color);\n const channels = decomposed.type.startsWith('hsl')\n ? decomposeColor(hslToRgb(color)).values\n : decomposed.values;\n\n const [r, g, b] = channels.slice(0, 3).map((value) => {\n const c = value / 255;\n return c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;\n });\n\n return Number((0.2126 * (r ?? 0) + 0.7152 * (g ?? 0) + 0.0722 * (b ?? 0)).toFixed(3));\n}\n\n/** WCAG contrast ratio between two colours, 1 to 21. */\nexport function getContrastRatio(foreground: string, background: string): number {\n const lumA = getLuminance(foreground);\n const lumB = getLuminance(background);\n return (Math.max(lumA, lumB) + 0.05) / (Math.min(lumA, lumB) + 0.05);\n}\n\n/** The colour with its alpha channel set to `value` (0 to 1). */\nexport function alpha(color: string, value: number): string {\n const decomposed = decomposeColor(color);\n const type: ColorFormat = decomposed.type.endsWith('a')\n ? decomposed.type\n : (`${decomposed.type}a` as ColorFormat);\n const values = decomposed.values.slice(0, 3);\n values[3] = clamp(value);\n return recomposeColor({ type, values });\n}\n\n/** The colour moved `coefficient` (0 to 1) of the way towards black. */\nexport function darken(color: string, coefficient: number): string {\n const decomposed = decomposeColor(color);\n const amount = clamp(coefficient);\n const values = [...decomposed.values];\n\n if (decomposed.type.startsWith('hsl')) {\n values[2] = (values[2] ?? 0) * (1 - amount);\n } else {\n for (let index = 0; index < 3; index += 1) {\n values[index] = (values[index] ?? 0) * (1 - amount);\n }\n }\n return recomposeColor({ type: decomposed.type, values });\n}\n\n/** The colour moved `coefficient` (0 to 1) of the way towards white. */\nexport function lighten(color: string, coefficient: number): string {\n const decomposed = decomposeColor(color);\n const amount = clamp(coefficient);\n const values = [...decomposed.values];\n\n if (decomposed.type.startsWith('hsl')) {\n values[2] = (values[2] ?? 0) + (100 - (values[2] ?? 0)) * amount;\n } else {\n for (let index = 0; index < 3; index += 1) {\n values[index] = (values[index] ?? 0) + (255 - (values[index] ?? 0)) * amount;\n }\n }\n return recomposeColor({ type: decomposed.type, values });\n}\n\n/** Darken a light colour or lighten a dark one, by `coefficient`. */\nexport function emphasize(color: string, coefficient = 0.15): string {\n return getLuminance(color) > 0.5 ? darken(color, coefficient) : lighten(color, coefficient);\n}\n","\n/**\n * THE THIRD VOCABULARY: the type scale.\n *\n * `scales.ts` opens by saying the package had both halves of every argument at\n * once until the size and colour vocabularies were declared in one place and\n * every component derived from them. The type scale was the one that never got\n * that treatment — it lived as a private `LEVELS` table inside\n * `Heading.styles.ts`, which is exactly the shape that file exists to refuse.\n *\n * Two things follow from it being private, and the second is the expensive one.\n *\n * **It could not be re-themed.** `Heading` read `theme.typography.h1.fontFamily`\n * from the theme and then ignored the theme for every other metric, so a host\n * calling `createTheme({ typography: { h1: { fontSize: '2rem' } } })` changed\n * `<Typography variant=\"h1\">` and left `<Heading level=\"h1\">` at 48px. A design\n * system whose type scale cannot be set by the design is not a system.\n *\n * **And the numbers were a landing page's.** `h1` at 3rem and `h2` at 2.5rem are\n * hero metrics. Dropped into an operations console they put a 48px title\n * directly above 14px body copy — a 3.4x jump with nothing in between — so\n * product teams stopped reaching for the component. Measured in one consuming\n * repo: `<Heading>` appeared four times in the entire codebase while raw\n * `fontSize` appeared in dozens of files. The component was not disliked, it was\n * unusable at app scale, and every host paid for that in hand-rolled CSS.\n *\n * So the defaults below are an APP scale, and `display` keeps the hero size for\n * the screens that actually want one. A marketing page asks for `display`; a\n * console asks for `h1` and gets something it can put on a page.\n */\n\n/**\n * A step on the scale.\n *\n * `display` is a SIZE, not a rank — see `Heading`, which renders it as `h1` so\n * the document still gets exactly one level-one heading.\n */\nexport type HeadingLevel = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'display';\n\n/**\n * The runtime list, declared beside the union for the reason `SIZE_VALUES`\n * gives: a story's `argTypes.options` spelled by hand drifts from the type, and\n * the direction it drifts is \"documents less than the component accepts\".\n */\nexport const HEADING_LEVELS = [\n 'display',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n] as const satisfies readonly HeadingLevel[];\n\n/** Everything one step of the scale decides. */\nexport interface HeadingMetrics {\n fontSize: string;\n lineHeight: number;\n letterSpacing?: string;\n /**\n * The weight this step carries when the caller asks for `normal`. A heading's\n * \"normal\" is not body text's 400 — it is the weight the step is meant to\n * carry, which gets heavier as the step gets larger.\n */\n normalWeight: number;\n}\n\n/**\n * The house default, in CODE rather than in a component.\n *\n * ~1.15x per step from a 1rem `h6`, which keeps six distinguishable ranks inside\n * the range an application actually uses. The old table ran 1.125rem → 4rem and\n * spent its top three steps above anything a product screen wants.\n */\nexport const HEADING_SCALE: Record<HeadingLevel, HeadingMetrics> = {\n // The hero size the old `h1` was really offering, under the name that says so.\n display: { fontSize: '3rem', lineHeight: 1.05, letterSpacing: '-0.03em', normalWeight: 800 },\n h1: { fontSize: '2rem', lineHeight: 1.2, letterSpacing: '-0.02em', normalWeight: 700 },\n h2: { fontSize: '1.75rem', lineHeight: 1.25, letterSpacing: '-0.015em', normalWeight: 700 },\n h3: { fontSize: '1.5rem', lineHeight: 1.3, letterSpacing: '-0.01em', normalWeight: 600 },\n h4: { fontSize: '1.25rem', lineHeight: 1.35, letterSpacing: '-0.005em', normalWeight: 600 },\n h5: { fontSize: '1.125rem', lineHeight: 1.4, normalWeight: 600 },\n h6: { fontSize: '1rem', lineHeight: 1.5, normalWeight: 600 },\n};\n\n/** A host's overrides: any subset of the steps, any subset of each step's metrics. */\nexport type HeadingScaleOverrides = Partial<Record<HeadingLevel, Partial<HeadingMetrics>>>;\n","/**\n * THE ONE READER OF CSS LENGTHS.\n *\n * `HEADING_SCALE` and a host's MUI overrides speak CSS — `'2rem'`, `'-0.02em'`\n * — and both `tokens/theme.ts` and `provider/mui-bridge.ts` need them as\n * numbers. Two private parsers drifted (one multiplied `em` by 16, one did\n * not), so there is one, here, with the rule spelled out: a length becomes px\n * against a 16px root, a tracking value becomes em.\n */\n\nconst ROOT_PX = 16;\n\n/** `'1.5rem'` → 24, `'1.5em'` → 24, `'20px'` → 20, `20` → 20, unparseable → `fallback`. */\nexport function cssLengthToPx(value: string | number | undefined, fallback: number): number {\n if (typeof value === 'number') return value;\n if (value === undefined) return fallback;\n const parsed = Number.parseFloat(value);\n if (Number.isNaN(parsed)) return fallback;\n return value.endsWith('rem') || value.endsWith('em') ? parsed * ROOT_PX : parsed;\n}\n\n/** `'-0.02em'` → -0.02, `'0.5px'` → 0.5 / 16, `undefined` → `undefined` (\"normal\"). */\nexport function cssTrackingToEm(value: string | undefined): number | undefined {\n if (value === undefined) return undefined;\n const parsed = Number.parseFloat(value);\n if (Number.isNaN(parsed)) return undefined;\n return value.endsWith('px') ? parsed / ROOT_PX : parsed;\n}\n","import { darken, getContrastRatio, lighten } from './color';\nimport { cssLengthToPx, cssTrackingToEm } from './css-units';\nimport { HEADING_SCALE, type HeadingLevel } from './heading-scale';\n\nimport type { SizeValue } from './vocabulary';\n\n/**\n * THE THEME BOTH RENDERERS READ.\n *\n * On the web every component styles itself from MUI's `Theme`, which is built\n * by the host (`@12-apps/app-shell`'s `createAppTheme` in the origin apps) and\n * reaches a component through emotion's context. React Native has no emotion,\n * no CSS and no MUI, so a native `Button` needs the same decisions — the\n * palette, the spacing unit, the radius, the type scale — from somewhere that\n * does not import a renderer.\n *\n * This is that somewhere. `UiTheme` is a plain object of numbers and colour\n * strings. `createUiTheme` derives it the way MUI's `createPalette` derives its\n * own: a `light` shade is `lighten(main, 0.2)`, a `dark` shade `darken(main,\n * 0.3)`, `contrastText` flips at a 3:1 ratio against `rgba(0, 0, 0, 0.87)`.\n * Same seeds in, same shades out, on both sides — that is the whole basis for\n * a native button being the web button's colour and not a near miss.\n *\n * Numbers are in px on the web and dp on native; both are the CSS-pixel unit\n * a design is drawn in, so a `fontSize: 16` here IS `1rem` in a web style\n * and `16` in a `StyleSheet`. The web components keep their `rem` strings and\n * derive them from these numbers where the two meet (see `px()` below and the\n * `*.metrics.ts` file beside each ported component).\n *\n * `danger` and `neutral` are this package's names (see `./scales`); `danger`\n * is MUI's `error` and `neutral` is drawn from the grey ramp the way\n * `Button.styles.ts` has always drawn it.\n */\n\nexport type UiThemeMode = 'light' | 'dark';\n\nexport interface UiPaletteColor {\n main: string;\n light: string;\n dark: string;\n contrastText: string;\n}\n\nexport type UiGreyStep = 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900;\n\nexport interface UiPalette {\n mode: UiThemeMode;\n primary: UiPaletteColor;\n secondary: UiPaletteColor;\n success: UiPaletteColor;\n warning: UiPaletteColor;\n info: UiPaletteColor;\n danger: UiPaletteColor;\n neutral: UiPaletteColor;\n text: { primary: string; secondary: string; disabled: string };\n background: { default: string; paper: string };\n divider: string;\n action: {\n active: string;\n hover: string;\n selected: string;\n disabled: string;\n disabledBackground: string;\n focus: string;\n };\n grey: Record<UiGreyStep, string>;\n}\n\n/** One step of the body scale: `fontSize` in px, `lineHeight` as a ratio. */\nexport interface UiTypeStep {\n fontSize: number;\n lineHeight: number;\n}\n\nexport type UiFontWeight = 'light' | 'normal' | 'medium' | 'semibold' | 'bold';\n\nexport interface UiHeadingStep extends UiTypeStep {\n /** In em, so it scales with the step. `undefined` is \"normal\". */\n letterSpacing?: number;\n normalWeight: number;\n}\n\nexport interface UiTypography {\n /**\n * Native has no fallback stacks: a font is either installed and named, or\n * `undefined` and the platform's own. The web default is MUI's Roboto stack.\n */\n fontFamily: string | undefined;\n monospaceFontFamily: string | undefined;\n sizes: Record<SizeValue, UiTypeStep>;\n weights: Record<UiFontWeight, number>;\n heading: Record<HeadingLevel, UiHeadingStep>;\n}\n\nexport interface UiTheme {\n mode: UiThemeMode;\n palette: UiPalette;\n /** MUI's `theme.spacing(n)`: `n` units of {@link UiTheme.spacingUnit}, in px. */\n spacing: (units: number) => number;\n spacingUnit: number;\n /** `md` is MUI's `shape.borderRadius`; the others are its halves and doubles. */\n radius: { sm: number; md: number; lg: number; xl: number; full: number };\n typography: UiTypography;\n zIndex: { appBar: number; drawer: number; modal: number; snackbar: number; tooltip: number };\n}\n\n/** A seed for one palette slot: a hex `main`, or any subset of the four shades. */\nexport type UiPaletteSeed = string | Partial<UiPaletteColor>;\n\nexport interface UiThemeOptions {\n mode?: UiThemeMode;\n palette?: Partial<{\n primary: UiPaletteSeed;\n secondary: UiPaletteSeed;\n success: UiPaletteSeed;\n warning: UiPaletteSeed;\n info: UiPaletteSeed;\n danger: UiPaletteSeed;\n background: Partial<UiPalette['background']>;\n }>;\n typography?: Partial<Pick<UiTypography, 'fontFamily' | 'monospaceFontFamily'>>;\n spacingUnit?: number;\n}\n\nconst ROOT_FONT_PX = 16;\n\n/** The px value as the rem string the web components write. */\nexport const px = (value: number): string => `${value / ROOT_FONT_PX}rem`;\n\n/** MUI's `createPalette` defaults, exactly. */\nconst TONAL_OFFSET = 0.2;\nconst CONTRAST_THRESHOLD = 3;\nconst DARK_TEXT_PRIMARY = 'rgba(0, 0, 0, 0.87)';\nconst LIGHT_TEXT_PRIMARY = '#fff';\n\nexport const GREY: Record<UiGreyStep, string> = {\n 50: '#fafafa',\n 100: '#f5f5f5',\n 200: '#eeeeee',\n 300: '#e0e0e0',\n 400: '#bdbdbd',\n 500: '#9e9e9e',\n 600: '#757575',\n 700: '#616161',\n 800: '#424242',\n 900: '#212121',\n};\n\n/**\n * The platform's own seeds. The pair `@12-apps/ui`'s Storybook preview and\n * `@12-apps/app-shell`'s `DEFAULT_THEME_TOKENS` both carry — keep the three in\n * step if the design tokens change.\n */\nexport const DEFAULT_BRAND: Record<UiThemeMode, { primary: string; secondary: string }> = {\n light: { primary: '#6366F1', secondary: '#8B5CF6' },\n dark: { primary: '#818CF8', secondary: '#A78BFA' },\n};\n\n/** MUI's semantic defaults per mode. These are declared shades, not derived. */\nconst SEMANTIC_DEFAULTS: Record<\n UiThemeMode,\n Record<'success' | 'warning' | 'info' | 'danger', UiPaletteColor>\n> = {\n light: {\n success: { main: '#2e7d32', light: '#4caf50', dark: '#1b5e20', contrastText: '#fff' },\n warning: { main: '#ed6c02', light: '#ff9800', dark: '#e65100', contrastText: '#fff' },\n info: { main: '#0288d1', light: '#03a9f4', dark: '#01579b', contrastText: '#fff' },\n danger: { main: '#d32f2f', light: '#ef5350', dark: '#c62828', contrastText: '#fff' },\n },\n dark: {\n success: { main: '#66bb6a', light: '#81c784', dark: '#388e3c', contrastText: DARK_TEXT_PRIMARY },\n warning: { main: '#ffa726', light: '#ffb74d', dark: '#f57c00', contrastText: DARK_TEXT_PRIMARY },\n info: { main: '#29b6f6', light: '#4fc3f7', dark: '#0288d1', contrastText: DARK_TEXT_PRIMARY },\n danger: { main: '#f44336', light: '#e57373', dark: '#d32f2f', contrastText: '#fff' },\n },\n};\n\nconst MODE_DEFAULTS: Record<\n UiThemeMode,\n Pick<UiPalette, 'text' | 'background' | 'divider' | 'action'>\n> = {\n light: {\n text: { primary: DARK_TEXT_PRIMARY, secondary: 'rgba(0, 0, 0, 0.6)', disabled: 'rgba(0, 0, 0, 0.38)' },\n background: { default: '#fff', paper: '#fff' },\n divider: 'rgba(0, 0, 0, 0.12)',\n action: {\n active: 'rgba(0, 0, 0, 0.54)',\n hover: 'rgba(0, 0, 0, 0.04)',\n selected: 'rgba(0, 0, 0, 0.08)',\n disabled: 'rgba(0, 0, 0, 0.26)',\n disabledBackground: 'rgba(0, 0, 0, 0.12)',\n focus: 'rgba(0, 0, 0, 0.12)',\n },\n },\n dark: {\n text: { primary: '#fff', secondary: 'rgba(255, 255, 255, 0.7)', disabled: 'rgba(255, 255, 255, 0.5)' },\n background: { default: '#121212', paper: '#121212' },\n divider: 'rgba(255, 255, 255, 0.12)',\n action: {\n active: '#fff',\n hover: 'rgba(255, 255, 255, 0.08)',\n selected: 'rgba(255, 255, 255, 0.16)',\n disabled: 'rgba(255, 255, 255, 0.3)',\n disabledBackground: 'rgba(255, 255, 255, 0.12)',\n focus: 'rgba(255, 255, 255, 0.12)',\n },\n },\n};\n\n/**\n * MUI's `getContrastText`: white where white reads at 3:1 on the colour, the\n * light mode's dark ink otherwise. (MUI's source spells the white as the DARK\n * palette's `text.primary`, which is what made it easy to read backwards.)\n */\nexport function contrastText(background: string): string {\n return getContrastRatio(background, LIGHT_TEXT_PRIMARY) >= CONTRAST_THRESHOLD\n ? LIGHT_TEXT_PRIMARY\n : DARK_TEXT_PRIMARY;\n}\n\n/**\n * The ink that reads on EVERY one of these fills (FUT-1924).\n *\n * {@link contrastText} answers for one fill, which is all MUI's `augmentColor`\n * ever needs: a solid button is a single flat colour. Two components paint the\n * label over something that is not one colour — `Button`'s `gradient` variant\n * runs between two stops, and `Switch`'s thumb travels the whole length of a\n * checked track — and both of them stated `#fff` outright instead, which is\n * white-on-pale the moment a white-labelled host hands the library a pale\n * brand. Audited across the library, those two were the only places a hardcoded\n * white sat over a surface the TENANT chooses.\n *\n * **This deliberately does not follow `contrastText`'s rule.** MUI's is a\n * threshold that PREFERS white — white wherever white clears 3:1 — which is a\n * brand-feel decision, and it is kept for every existing caller so nothing\n * already legible moves. Here the fills can disagree: over MUI's own success\n * pair white is 2.78:1 on `#4caf50` and dark ink 2.66:1 on `#1b5e20`, so\n * neither meets any threshold and asking whether one does is the wrong\n * question. The answer is whichever ink has the better WORST case across the\n * fills — which is also not what either fill says on its own, since\n * `contrastText('#4caf50')` is dark ink.\n *\n * A gradient wide enough that neither ink clears 4.5:1 anywhere is a palette\n * problem this cannot fix — it returns the less bad ink and does not pretend\n * otherwise.\n *\n * `Math.min` is the claim, and it is worth knowing that no test can prove it\n * against `Math.max` today: the two candidate inks sit at opposite ends of the\n * luminance range, so ranking them by their best fill and by their worst gives\n * the same winner for every possible pair (checked exhaustively). Worst case is\n * still what this MEANS, and the moment a third ink or one that is not an\n * extreme is offered, the two stop agreeing.\n *\n * `fallback` is returned when a fill cannot be decomposed: {@link getContrastRatio}\n * throws on a format it does not know, and a throw inside an emotion style\n * function takes the render down with it.\n */\nexport function inkOver(fills: readonly string[], fallback: string): string {\n try {\n const worstCase = (ink: string): number =>\n Math.min(...fills.map((fill) => getContrastRatio(ink, fill)));\n\n return worstCase(LIGHT_TEXT_PRIMARY) >= worstCase(DARK_TEXT_PRIMARY)\n ? LIGHT_TEXT_PRIMARY\n : DARK_TEXT_PRIMARY;\n } catch {\n return fallback;\n }\n}\n\n/**\n * MUI's `augmentColor` for a custom colour: derive whatever shade the seed\n * left out. `light` is one tonal offset up, `dark` one and a half down.\n */\nexport function augmentColor(seed: UiPaletteSeed): UiPaletteColor {\n const partial = typeof seed === 'string' ? { main: seed } : seed;\n const main = partial.main ?? partial.light ?? partial.dark;\n if (!main) {\n throw new Error('@12-apps/ui: a palette seed needs at least a `main` colour.');\n }\n return {\n main,\n light: partial.light ?? lighten(main, TONAL_OFFSET),\n dark: partial.dark ?? darken(main, TONAL_OFFSET * 1.5),\n contrastText: partial.contrastText ?? contrastText(main),\n };\n}\n\nconst semantic = (\n mode: UiThemeMode,\n key: 'success' | 'warning' | 'info' | 'danger',\n seed: UiPaletteSeed | undefined,\n): UiPaletteColor => (seed === undefined ? SEMANTIC_DEFAULTS[mode][key] : augmentColor(seed));\n\n/** `neutral` as `accentFor` in `./scales` has always drawn it: three greys and white. */\nexport const NEUTRAL: UiPaletteColor = {\n main: GREY[600],\n light: GREY[400],\n dark: GREY[800],\n contrastText: '#fff',\n};\n\n/** The body scale `Text` renders, in px. `Text.tsx`'s rem map is this, divided by 16. */\nexport const TYPE_SIZES: Record<SizeValue, UiTypeStep> = {\n xs: { fontSize: 12, lineHeight: 1.2 },\n sm: { fontSize: 14, lineHeight: 1.3 },\n md: { fontSize: 16, lineHeight: 1.5 },\n lg: { fontSize: 18, lineHeight: 1.4 },\n xl: { fontSize: 20, lineHeight: 1.3 },\n};\n\nexport const FONT_WEIGHTS: Record<UiFontWeight, number> = {\n light: 300,\n normal: 400,\n medium: 500,\n semibold: 600,\n bold: 700,\n};\n\n// `HEADING_SCALE` speaks CSS, this theme speaks numbers; `./css-units` is the\n// one place that conversion is written.\nconst HEADING_STEPS = Object.fromEntries(\n Object.entries(HEADING_SCALE).map(([level, metrics]) => [\n level,\n {\n fontSize: cssLengthToPx(metrics.fontSize, ROOT_FONT_PX),\n lineHeight: metrics.lineHeight,\n letterSpacing: cssTrackingToEm(metrics.letterSpacing),\n normalWeight: metrics.normalWeight,\n },\n ]),\n) as Record<HeadingLevel, UiHeadingStep>;\n\nexport const WEB_FONT_FAMILY = '\"Roboto\", \"Helvetica\", \"Arial\", sans-serif';\nexport const WEB_MONOSPACE_FONT_FAMILY = 'Monaco, Menlo, \"Ubuntu Mono\", \"Courier New\", monospace';\n\n/**\n * Build the theme. Every field is derived here so a host that changes one\n * seed gets every dependent shade recomputed, on both renderers, identically.\n */\nexport function createUiTheme(options: UiThemeOptions = {}): UiTheme {\n const mode = options.mode ?? 'light';\n const seeds = options.palette ?? {};\n const brand = DEFAULT_BRAND[mode];\n const defaults = MODE_DEFAULTS[mode];\n const spacingUnit = options.spacingUnit ?? 8;\n\n const palette: UiPalette = {\n mode,\n primary: augmentColor(seeds.primary ?? brand.primary),\n secondary: augmentColor(seeds.secondary ?? brand.secondary),\n success: semantic(mode, 'success', seeds.success),\n warning: semantic(mode, 'warning', seeds.warning),\n info: semantic(mode, 'info', seeds.info),\n danger: semantic(mode, 'danger', seeds.danger),\n neutral: NEUTRAL,\n text: defaults.text,\n background: { ...defaults.background, ...seeds.background },\n divider: defaults.divider,\n action: defaults.action,\n grey: GREY,\n };\n\n return {\n mode,\n palette,\n spacing: (units: number) => units * spacingUnit,\n spacingUnit,\n radius: { sm: 2, md: 4, lg: 8, xl: 16, full: 9999 },\n typography: {\n fontFamily: options.typography?.fontFamily,\n monospaceFontFamily: options.typography?.monospaceFontFamily,\n sizes: TYPE_SIZES,\n weights: FONT_WEIGHTS,\n heading: HEADING_STEPS,\n },\n zIndex: { appBar: 1100, drawer: 1200, modal: 1300, snackbar: 1400, tooltip: 1500 },\n };\n}\n\n/** The palette slot a house colour name resolves to. */\nexport type UiPaletteKey = 'primary' | 'secondary' | 'success' | 'warning' | 'info' | 'danger' | 'neutral';\n\nexport const DEFAULT_UI_THEME: UiTheme = createUiTheme();\n"],"mappings":"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","names":[]}