@12-apps/ui 6.14.0 → 6.15.1

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 (480) hide show
  1. package/components-catalog.md +8 -1
  2. package/dist/_internal/components/data-display/Badge/Badge.js +2 -2
  3. package/dist/_internal/components/data-display/CardKit/CardKebab.js +3 -3
  4. package/dist/_internal/components/data-display/CardKit/use-remove-confirm.js +7 -7
  5. package/dist/_internal/components/data-display/CardKit/use-row-confirm.js +7 -7
  6. package/dist/_internal/components/data-display/Carousel/Carousel.js +2 -2
  7. package/dist/_internal/components/data-display/Chart/Chart.js +3 -3
  8. package/dist/_internal/components/data-display/Chart/SpecChart.js +6 -6
  9. package/dist/_internal/components/data-display/Chart/chart-renderers.js +2 -2
  10. package/dist/_internal/components/data-display/Chart/chart-spec.js +2 -2
  11. package/dist/_internal/components/data-display/DataGrid/DataGrid.js +3 -3
  12. package/dist/_internal/components/data-display/DataViews/DataViewsGrid.js +55 -54
  13. package/dist/_internal/components/data-display/DataViews/DataViewsTableBase.js +72 -71
  14. package/dist/_internal/components/data-display/DataViews/DeleteViewDialog.js +3 -3
  15. package/dist/_internal/components/data-display/DataViews/ManageViewsDialog.js +7 -7
  16. package/dist/_internal/components/data-display/DataViews/SaveViewModal.js +6 -5
  17. package/dist/_internal/components/data-display/DataViews/base-list-card-geometry.js +4 -4
  18. package/dist/_internal/components/data-display/DataViews/base-list-card-slots.js +3 -3
  19. package/dist/_internal/components/data-display/DataViews/base-list-card.js +6 -6
  20. package/dist/_internal/components/data-display/DataViews/data-views-category-pill.js +16 -15
  21. package/dist/_internal/components/data-display/DataViews/data-views-columns.js +4 -4
  22. package/dist/_internal/components/data-display/DataViews/data-views-display-panel.js +5 -5
  23. package/dist/_internal/components/data-display/DataViews/data-views-empty.js +3 -3
  24. package/dist/_internal/components/data-display/DataViews/data-views-export.js +3 -3
  25. package/dist/_internal/components/data-display/DataViews/data-views-filter-panel.js +22 -21
  26. package/dist/_internal/components/data-display/DataViews/data-views-grid-bodies.js +10 -10
  27. package/dist/_internal/components/data-display/DataViews/data-views-grid-helpers.js +3 -3
  28. package/dist/_internal/components/data-display/DataViews/data-views-grid-parts.js +50 -49
  29. package/dist/_internal/components/data-display/DataViews/data-views-inline-bar.js +24 -23
  30. package/dist/_internal/components/data-display/DataViews/data-views-more-fields.js +6 -6
  31. package/dist/_internal/components/data-display/DataViews/data-views-more-filters.js +9 -9
  32. package/dist/_internal/components/data-display/DataViews/data-views-range-pill.js +2 -2
  33. package/dist/_internal/components/data-display/DataViews/data-views-scope-tabs.js +2 -2
  34. package/dist/_internal/components/data-display/DataViews/data-views-select-all-strip.js +3 -3
  35. package/dist/_internal/components/data-display/DataViews/data-views-shell-toolbar.js +12 -12
  36. package/dist/_internal/components/data-display/DataViews/data-views-table-parts.js +15 -14
  37. package/dist/_internal/components/data-display/DataViews/data-views-toolbar.js +11 -11
  38. package/dist/_internal/components/data-display/DataViews/data-views-view-nav.js +3 -3
  39. package/dist/_internal/components/data-display/DataViews/list-card-rails.js +2 -2
  40. package/dist/_internal/components/data-display/DataViews/use-data-views-state.js +7 -7
  41. package/dist/_internal/components/data-display/HoverCard/HoverCard.js +2 -2
  42. package/dist/_internal/components/data-display/InteractiveTooltip/InteractiveTooltip.js +2 -2
  43. package/dist/_internal/components/data-display/Lightbox/Lightbox.js +6 -6
  44. package/dist/_internal/components/data-display/MapPreview/MapDecorations.js +2 -2
  45. package/dist/_internal/components/data-display/MapPreview/MapLayers.js +3 -3
  46. package/dist/_internal/components/data-display/MapPreview/MapPreview.hooks.js +2 -2
  47. package/dist/_internal/components/data-display/MapPreview/MapPreview.js +11 -11
  48. package/dist/_internal/components/data-display/MapPreview/MapTiles.js +2 -2
  49. package/dist/_internal/components/data-display/MapPreview/StaticMapView.js +4 -4
  50. package/dist/_internal/components/data-display/MapPreview/useMapPreview.js +3 -3
  51. package/dist/_internal/components/data-display/Sheet/Sheet.hooks.js +2 -2
  52. package/dist/_internal/components/data-display/Sheet/Sheet.js +4 -4
  53. package/dist/_internal/components/data-display/Table/Table.js +2 -2
  54. package/dist/_internal/components/data-display/index.js +45 -45
  55. package/dist/_internal/components/feedback/ConfirmAction/ConfirmAction.js +2 -2
  56. package/dist/_internal/components/feedback/ConfirmAction/ConfirmButton.js +5 -5
  57. package/dist/_internal/components/feedback/ConfirmAction/with-confirmation.js +2 -2
  58. package/dist/_internal/components/feedback/StackedModal/StackedModal.js +6 -6
  59. package/dist/_internal/components/feedback/index.js +15 -15
  60. package/dist/_internal/components/form/AddressAutocomplete/AddressAutocomplete.hooks.js +2 -2
  61. package/dist/_internal/components/form/AddressAutocomplete/AddressAutocomplete.js +10 -9
  62. package/dist/_internal/components/form/AddressAutocomplete/AddressAutocompleteField.js +5 -4
  63. package/dist/_internal/components/form/AddressAutocomplete/AddressFallbackField.js +3 -2
  64. package/dist/_internal/components/form/AddressAutocomplete/AddressInputField.js +3 -2
  65. package/dist/_internal/components/form/AddressAutocomplete/AddressTextField.js +2 -1
  66. package/dist/_internal/components/form/Autocomplete/Autocomplete.js +2 -2
  67. package/dist/_internal/components/form/Button/Button.js +2 -2
  68. package/dist/_internal/components/form/Calendar/Calendar.js +4 -4
  69. package/dist/_internal/components/form/Calendar/CalendarDayCell.js +2 -2
  70. package/dist/_internal/components/form/Calendar/CalendarMonth.js +3 -3
  71. package/dist/_internal/components/form/CategorySelect/CategoryPanel.js +8 -7
  72. package/dist/_internal/components/form/CategorySelect/CategoryPanelFoot.js +3 -2
  73. package/dist/_internal/components/form/CategorySelect/CategoryPanelHead.js +3 -2
  74. package/dist/_internal/components/form/CategorySelect/CategoryPanelList.js +5 -4
  75. package/dist/_internal/components/form/CategorySelect/CategoryRows.js +4 -3
  76. package/dist/_internal/components/form/CategorySelect/CategorySelect.js +12 -11
  77. package/dist/_internal/components/form/CategorySelect/CategorySelect.styles.js +2 -1
  78. package/dist/_internal/components/form/CategorySelect/CategoryTrigger.js +3 -2
  79. package/dist/_internal/components/form/CepField/CepField.js +4 -3
  80. package/dist/_internal/components/form/CodeEditor/CodeEditor.js +4 -3
  81. package/dist/_internal/components/form/CreatableSelect/CreatableSelect.js +2 -1
  82. package/dist/_internal/components/form/DateRangePicker/DateRangePicker.js +7 -7
  83. package/dist/_internal/components/form/HeaderActions/HeaderActions.js +11 -0
  84. package/dist/_internal/components/form/HeaderActions/HeaderActions.js.map +1 -0
  85. package/dist/_internal/components/form/HeaderActions/HeaderActions.types.js +1 -0
  86. package/dist/_internal/components/form/HeaderActions/HeaderActions.types.js.map +1 -0
  87. package/dist/_internal/components/form/Input/Input.js +3 -2
  88. package/dist/_internal/components/form/Input/Input.styles.js +2 -1
  89. package/dist/_internal/components/form/InputOTP/InputOTP.js +3 -2
  90. package/dist/_internal/components/form/InputOTP/InputOTP.styles.js +2 -1
  91. package/dist/_internal/components/form/Label/Label.js +2 -2
  92. package/dist/_internal/components/form/PhoneInput/PhoneInput.js +2 -1
  93. package/dist/_internal/components/form/RadioGroup/RadioGroup.js +4 -3
  94. package/dist/_internal/components/form/RadioGroup/RadioGroup.styles.js +2 -1
  95. package/dist/_internal/components/form/RadioGroup/RadioGroup.variants.js +3 -2
  96. package/dist/_internal/components/form/RichTextEditor/RichTextEditor.js +3 -2
  97. package/dist/_internal/components/form/Select/Select.js +2 -1
  98. package/dist/_internal/components/form/Textarea/Textarea.js +3 -2
  99. package/dist/_internal/components/form/Textarea/Textarea.styles.js +2 -1
  100. package/dist/_internal/components/form/Textarea/TextareaRichEditor.js +5 -2
  101. package/dist/_internal/components/form/Textarea/TextareaRichEditor.js.map +1 -1
  102. package/dist/_internal/components/form/Toggle/Toggle.js +3 -2
  103. package/dist/_internal/components/form/Toggle/Toggle.styles.js +2 -1
  104. package/dist/_internal/components/form/index.js +60 -59
  105. package/dist/_internal/components/form/total-form/Fields/CategoryField.js +13 -12
  106. package/dist/_internal/components/form/total-form/Fields/CepField.js +5 -4
  107. package/dist/_internal/components/form/total-form/Fields/SelectField.js +3 -2
  108. package/dist/_internal/components/form/total-form/Fields/TextField.js +4 -3
  109. package/dist/_internal/components/form/total-form/Fields/index.js +25 -24
  110. package/dist/_internal/components/form/total-form/SubmitButton.js +3 -3
  111. package/dist/_internal/components/index.js +160 -157
  112. package/dist/_internal/components/layout/Dashboard/Dashboard.js +4 -2
  113. package/dist/_internal/components/layout/Dashboard/DashboardParts.js +5 -1
  114. package/dist/_internal/components/layout/ScrollArea/ScrollArea.js +3 -3
  115. package/dist/_internal/components/layout/index.js +22 -20
  116. package/dist/_internal/components/navigation/AppHeader/AppHeader.details.js +7 -7
  117. package/dist/_internal/components/navigation/CommandPalette/CommandPalette.js +3 -3
  118. package/dist/_internal/components/navigation/NavigationMenu/NavigationMegaSection.js +3 -3
  119. package/dist/_internal/components/navigation/NavigationMenu/NavigationMenu.js +5 -5
  120. package/dist/_internal/components/navigation/NavigationMenu/NavigationMenuItem.js +2 -2
  121. package/dist/_internal/components/navigation/NavigationMenu/NavigationStandardBody.js +3 -3
  122. package/dist/_internal/components/navigation/index.js +19 -19
  123. package/dist/_internal/components/typography/index.js +3 -3
  124. package/dist/_internal/components/utility/InstallPrompt/InstallPrompt.js +2 -2
  125. package/dist/_internal/components/utility/index.js +7 -7
  126. package/dist/_internal/en-US.data-display.js +2 -2
  127. package/dist/_internal/social-login-button/social-login-button.js +3 -3
  128. package/dist/_internal/tokens/field-edge.js +10 -0
  129. package/dist/_internal/tokens/field-edge.js.map +1 -0
  130. package/dist/_internal/user-avatar/user-avatar.js +3 -3
  131. package/dist/charts.js +11 -11
  132. package/dist/{chunk-WQSL6MCA.js → chunk-23FCBIUN.js} +4 -4
  133. package/dist/{chunk-QIKTIKO6.js → chunk-24LW52EU.js} +2 -2
  134. package/dist/{chunk-4VPCZFF3.js → chunk-2W4CIWTW.js} +7 -4
  135. package/dist/chunk-2W4CIWTW.js.map +1 -0
  136. package/dist/{chunk-75KRWRJA.js → chunk-2ZDTGI5V.js} +7 -7
  137. package/dist/{chunk-XPS7FWZS.js → chunk-3LO5JWTC.js} +3 -3
  138. package/dist/{chunk-MYOFULG4.js → chunk-3ORFVLI3.js} +2 -2
  139. package/dist/{chunk-EIGELK2H.js → chunk-3P4THDBM.js} +4 -4
  140. package/dist/{chunk-SJIBPRPB.js → chunk-3T2I6BYA.js} +4 -4
  141. package/dist/{chunk-J72KWTHC.js → chunk-45N6LXUU.js} +5 -3
  142. package/dist/chunk-45N6LXUU.js.map +1 -0
  143. package/dist/{chunk-ZNGUDGKW.js → chunk-45OIUWGO.js} +9 -9
  144. package/dist/{chunk-4ETQRBZC.js → chunk-46UPILLK.js} +4 -4
  145. package/dist/{chunk-S7CAXRRP.js → chunk-4Y65Q3CR.js} +2 -2
  146. package/dist/{chunk-XN5AYC5S.js → chunk-5SYD23V4.js} +7 -4
  147. package/dist/chunk-5SYD23V4.js.map +1 -0
  148. package/dist/{chunk-2UCJJACD.js → chunk-5VVM2PPV.js} +12 -12
  149. package/dist/{chunk-JE6RZ5L6.js → chunk-5ZOJLYD2.js} +4 -4
  150. package/dist/{chunk-B2324WXJ.js → chunk-64IEKEMQ.js} +7 -4
  151. package/dist/chunk-64IEKEMQ.js.map +1 -0
  152. package/dist/{chunk-AVGTTWTE.js → chunk-65DLYC4S.js} +4 -4
  153. package/dist/{chunk-O6V7KKW7.js → chunk-6CBYPMYQ.js} +5 -5
  154. package/dist/{chunk-BPCYXLWY.js → chunk-6HNEEJES.js} +4 -4
  155. package/dist/{chunk-WXVHZHSJ.js → chunk-6RFL7HGI.js} +3 -3
  156. package/dist/{chunk-UENDC45F.js → chunk-6TYSEAAT.js} +3 -3
  157. package/dist/{chunk-FXMZMX5E.js → chunk-6XPNJLXE.js} +6 -2
  158. package/dist/chunk-6XPNJLXE.js.map +1 -0
  159. package/dist/{chunk-R7MX5KPJ.js → chunk-6YLAVHV4.js} +4 -4
  160. package/dist/{chunk-A43SJQYE.js → chunk-74LYLKO2.js} +4 -2
  161. package/dist/chunk-74LYLKO2.js.map +1 -0
  162. package/dist/{chunk-A2WJMZX5.js → chunk-7DBFEZRC.js} +5 -2
  163. package/dist/chunk-7DBFEZRC.js.map +1 -0
  164. package/dist/{chunk-RXSGHPCR.js → chunk-7FOOLP5H.js} +4 -4
  165. package/dist/{chunk-EICVL6GS.js → chunk-7HPPUO2A.js} +2 -2
  166. package/dist/{chunk-3BR2CLAM.js → chunk-A3KY6NUA.js} +2 -2
  167. package/dist/{chunk-5QQWAIZO.js → chunk-ACDYA5WC.js} +6 -2
  168. package/dist/chunk-ACDYA5WC.js.map +1 -0
  169. package/dist/{chunk-2I5B5NNT.js → chunk-AX7UFG2U.js} +2 -2
  170. package/dist/{chunk-7DNQHMDO.js → chunk-B6IURHSZ.js} +4 -4
  171. package/dist/{chunk-CZJLWCEG.js → chunk-BPYPUEM5.js} +2 -2
  172. package/dist/{chunk-5VZPVDUF.js → chunk-COSJTD6Z.js} +2 -2
  173. package/dist/{chunk-AP3PVR3T.js → chunk-CXA6UNFF.js} +5 -5
  174. package/dist/{chunk-MNZ2NT5A.js → chunk-DCEMUZJQ.js} +6 -2
  175. package/dist/chunk-DCEMUZJQ.js.map +1 -0
  176. package/dist/{chunk-LPNF4YJ7.js → chunk-DGMR3IMM.js} +6 -6
  177. package/dist/{chunk-MUFI3ZXS.js → chunk-DQIQKIEA.js} +2 -2
  178. package/dist/{chunk-LQR2IVSL.js → chunk-DWUMMMLR.js} +4 -4
  179. package/dist/{chunk-56SMIHWE.js → chunk-EE2LBAJH.js} +9 -9
  180. package/dist/{chunk-SHDIZSN5.js → chunk-EGRFMPGD.js} +6 -6
  181. package/dist/{chunk-M6365FGG.js → chunk-ELYLG4F7.js} +7 -7
  182. package/dist/{chunk-PHA3NFZM.js → chunk-ENK4XGKF.js} +4 -4
  183. package/dist/{chunk-XFUNJYFT.js → chunk-EPNUVSNK.js} +7 -7
  184. package/dist/{chunk-FLSSV4TH.js → chunk-EWGVRRUF.js} +23 -2
  185. package/dist/chunk-EWGVRRUF.js.map +1 -0
  186. package/dist/{chunk-QTPKACVO.js → chunk-EY4LPLIR.js} +2 -2
  187. package/dist/{chunk-XCT2ZLA6.js → chunk-FCOEJCUP.js} +6 -2
  188. package/dist/chunk-FCOEJCUP.js.map +1 -0
  189. package/dist/{chunk-GNAAHDCN.js → chunk-FF55LRSV.js} +2 -2
  190. package/dist/{chunk-L6KEVPXN.js → chunk-FH4VARZ7.js} +7 -7
  191. package/dist/{chunk-J4DDXHLB.js → chunk-FJHNNSD3.js} +6 -6
  192. package/dist/{chunk-ONZPM6FP.js → chunk-G7CFUI4I.js} +2 -2
  193. package/dist/{chunk-KDIWFARU.js → chunk-GBB6XQ56.js} +2 -2
  194. package/dist/{chunk-UHXNEXOC.js → chunk-GFBNUWT5.js} +3 -3
  195. package/dist/{chunk-PLOOVF43.js → chunk-GGE7Y53F.js} +2 -2
  196. package/dist/{chunk-R6SBP5M5.js → chunk-GOWBYHYW.js} +4 -4
  197. package/dist/{chunk-HDNK7BAX.js → chunk-GT7C6TSM.js} +3 -3
  198. package/dist/{chunk-7SZ3PFZW.js → chunk-HBAPVB7T.js} +2 -2
  199. package/dist/{chunk-V7TPSQOH.js → chunk-HBZIN6IQ.js} +2 -2
  200. package/dist/{chunk-LS42VJAI.js → chunk-HEDOL2RV.js} +2 -2
  201. package/dist/{chunk-RPWEXIAW.js → chunk-HEG7JIBM.js} +5 -5
  202. package/dist/{chunk-AZUFGKMQ.js → chunk-HJOABXKN.js} +4 -4
  203. package/dist/{chunk-6HLRXICF.js → chunk-IAQFQNBL.js} +4 -4
  204. package/dist/{chunk-PUBPZOQJ.js → chunk-IPE5FFFD.js} +2 -2
  205. package/dist/{chunk-FSMQF5P5.js → chunk-IXZ44HJF.js} +2 -2
  206. package/dist/{chunk-RRO2EOJB.js → chunk-JB67KPGM.js} +4 -4
  207. package/dist/{chunk-PDGAFQ6Z.js → chunk-JPDKRGYI.js} +3 -3
  208. package/dist/{chunk-MNJVOU7T.js → chunk-K2T2CQSZ.js} +4 -4
  209. package/dist/{chunk-LFB4H7Y6.js → chunk-KNNBIXWJ.js} +2 -2
  210. package/dist/{chunk-CKZFYGBY.js → chunk-KSF7TLXH.js} +7 -7
  211. package/dist/{chunk-IIUB4IOH.js → chunk-LKF5KQ2Q.js} +4 -4
  212. package/dist/{chunk-AZSFIQIA.js → chunk-LUWATXU4.js} +13 -13
  213. package/dist/{chunk-CZPU5TW3.js → chunk-LYSSO6WC.js} +4 -4
  214. package/dist/{chunk-J7VY6KNP.js → chunk-M3RIC6JI.js} +2 -2
  215. package/dist/{chunk-5ZZPQ3MT.js → chunk-MHFJBNDP.js} +10 -10
  216. package/dist/chunk-MLOWPVVW.js +44 -0
  217. package/dist/chunk-MLOWPVVW.js.map +1 -0
  218. package/dist/{chunk-V44U7H4M.js → chunk-MUAVYVDJ.js} +6 -6
  219. package/dist/chunk-N4JEQJBL.js +93 -0
  220. package/dist/chunk-N4JEQJBL.js.map +1 -0
  221. package/dist/{chunk-LPYB4Y7C.js → chunk-N4WANJI3.js} +5 -5
  222. package/dist/{chunk-ECIGNYSI.js → chunk-O3OU2PPT.js} +2 -2
  223. package/dist/{chunk-62WEMJV3.js → chunk-PLK7UGO6.js} +3 -3
  224. package/dist/{chunk-U7SO3N42.js → chunk-PMFW55F5.js} +3 -3
  225. package/dist/{chunk-AGYGNNOM.js → chunk-PQECNGDE.js} +2 -2
  226. package/dist/{chunk-GPVB3FQP.js → chunk-PU3AAKRR.js} +2 -2
  227. package/dist/{chunk-KEDI6IRA.js → chunk-QETBO7EC.js} +2 -2
  228. package/dist/{chunk-WBKWIFXA.js → chunk-QYNCPS5W.js} +6 -6
  229. package/dist/{chunk-DFLTUI7W.js → chunk-QZBUGUOY.js} +4 -4
  230. package/dist/{chunk-OLZTGVBT.js → chunk-REMK55JI.js} +4 -4
  231. package/dist/{chunk-3AEY5TYV.js → chunk-RMSH2I3O.js} +8 -4
  232. package/dist/chunk-RMSH2I3O.js.map +1 -0
  233. package/dist/{chunk-CPNSVIIB.js → chunk-RP3W6IQO.js} +5 -5
  234. package/dist/{chunk-4QQVIGRG.js → chunk-RQ4EQ5FJ.js} +2 -2
  235. package/dist/{chunk-BLT5ZBVL.js → chunk-RRX6ZTNX.js} +2 -2
  236. package/dist/{chunk-QL7L6RHR.js → chunk-RX6DWIIW.js} +2 -2
  237. package/dist/{chunk-RGBS6N72.js → chunk-SEH7KOVG.js} +2 -2
  238. package/dist/{chunk-GJQYM3PM.js → chunk-SHQWIDD5.js} +4 -4
  239. package/dist/chunk-SIZOJNB2.js +1 -0
  240. package/dist/chunk-SIZOJNB2.js.map +1 -0
  241. package/dist/{chunk-NQCYVYP3.js → chunk-SLYZMJEL.js} +2 -2
  242. package/dist/{chunk-HKROKM3Z.js → chunk-SM3NRN7L.js} +2 -2
  243. package/dist/{chunk-PMS3H3OO.js → chunk-T53L42XW.js} +10 -10
  244. package/dist/{chunk-LNIVT62P.js → chunk-TPUIIZN2.js} +13 -13
  245. package/dist/{chunk-U5RIDMMV.js → chunk-TUAIPMU7.js} +6 -6
  246. package/dist/{chunk-SQAU5QUY.js → chunk-UMDXGIRZ.js} +6 -3
  247. package/dist/chunk-UMDXGIRZ.js.map +1 -0
  248. package/dist/{chunk-ZYRW7FVY.js → chunk-URWGRPL7.js} +6 -2
  249. package/dist/chunk-URWGRPL7.js.map +1 -0
  250. package/dist/{chunk-7QVYJQN4.js → chunk-VJKRJYZL.js} +3 -3
  251. package/dist/{chunk-Q6HJMJBH.js → chunk-VSLUFBMT.js} +7 -3
  252. package/dist/chunk-VSLUFBMT.js.map +1 -0
  253. package/dist/{chunk-7EGHRNIA.js → chunk-VVXRIPV5.js} +8 -8
  254. package/dist/{chunk-2SWQ6HIK.js → chunk-W3FAKT3D.js} +4 -4
  255. package/dist/{chunk-ZOUWHGV3.js → chunk-WC3W36AM.js} +4 -4
  256. package/dist/{chunk-VJFH2AXT.js → chunk-WEH5TCPE.js} +8 -8
  257. package/dist/{chunk-CESQKLIR.js → chunk-WFX5GASM.js} +2 -2
  258. package/dist/{chunk-O6MZPB64.js → chunk-WR6F6J43.js} +4 -4
  259. package/dist/{chunk-V5P5Q6HM.js → chunk-X24P3ZYW.js} +10 -10
  260. package/dist/{chunk-BVGR7OYA.js → chunk-XULTDO56.js} +4 -4
  261. package/dist/{chunk-OGGHD64H.js → chunk-Y5UCOBQN.js} +4 -4
  262. package/dist/{chunk-2A3OMYCB.js → chunk-YRUCIKPO.js} +4 -4
  263. package/dist/{chunk-K25MT3GZ.js → chunk-YVW7VPK4.js} +2 -2
  264. package/dist/{chunk-XQ2BNVXL.js → chunk-ZBNTFWTG.js} +2 -2
  265. package/dist/{chunk-G5ZVD5IJ.js → chunk-ZDWU52DJ.js} +2 -2
  266. package/dist/data-display/Badge.js +2 -2
  267. package/dist/data-display/CardKit.js +15 -15
  268. package/dist/data-display/Carousel.js +2 -2
  269. package/dist/data-display/Chart.js +11 -11
  270. package/dist/data-display/DataGrid.js +3 -3
  271. package/dist/data-display/DataViews.js +91 -90
  272. package/dist/data-display/HoverCard.js +2 -2
  273. package/dist/data-display/InteractiveTooltip.js +2 -2
  274. package/dist/data-display/Lightbox.js +6 -6
  275. package/dist/data-display/MapPreview.js +11 -11
  276. package/dist/data-display/Sheet.js +4 -4
  277. package/dist/data-display/Table.js +2 -2
  278. package/dist/en-US.js +8 -8
  279. package/dist/feedback/ConfirmAction.js +9 -9
  280. package/dist/feedback/StackedModal.js +6 -6
  281. package/dist/form/AddressAutocomplete.js +10 -9
  282. package/dist/form/Autocomplete.js +2 -2
  283. package/dist/form/Button.js +2 -2
  284. package/dist/form/Calendar.js +4 -4
  285. package/dist/form/CategorySelect.js +12 -11
  286. package/dist/form/CepField.js +4 -3
  287. package/dist/form/CodeEditor.js +4 -3
  288. package/dist/form/CreatableSelect.js +2 -1
  289. package/dist/form/DateRangePicker.js +7 -7
  290. package/dist/form/HeaderActions.js +11 -0
  291. package/dist/form/HeaderActions.js.map +1 -0
  292. package/dist/form/Input.js +3 -2
  293. package/dist/form/InputOTP.js +3 -2
  294. package/dist/form/Label.js +2 -2
  295. package/dist/form/PhoneInput.js +2 -1
  296. package/dist/form/RadioGroup.js +4 -3
  297. package/dist/form/RichTextEditor.js +3 -2
  298. package/dist/form/Select.js +2 -1
  299. package/dist/form/Textarea.js +3 -2
  300. package/dist/form/Toggle.js +3 -2
  301. package/dist/form/total-form.js +31 -30
  302. package/dist/layout/ContentToolbar.js +9 -9
  303. package/dist/layout/Dashboard.js +4 -2
  304. package/dist/layout/ScrollArea.js +3 -3
  305. package/dist/locales.js +11 -11
  306. package/dist/navigation/AppHeader.js +7 -7
  307. package/dist/navigation/CommandPalette.js +3 -3
  308. package/dist/navigation/NavigationMenu.js +5 -5
  309. package/dist/pt-BR.js +4 -4
  310. package/dist/social-login-button.js +3 -3
  311. package/dist/types/components/form/AddressAutocomplete/AddressTextField.d.ts.map +1 -1
  312. package/dist/types/components/form/CategorySelect/CategorySelect.styles.d.ts.map +1 -1
  313. package/dist/types/components/form/CodeEditor/CodeEditor.d.ts.map +1 -1
  314. package/dist/types/components/form/CreatableSelect/CreatableSelect.d.ts.map +1 -1
  315. package/dist/types/components/form/HeaderActions/HeaderActions.d.ts +48 -0
  316. package/dist/types/components/form/HeaderActions/HeaderActions.d.ts.map +1 -0
  317. package/dist/types/components/form/HeaderActions/HeaderActions.types.d.ts +62 -0
  318. package/dist/types/components/form/HeaderActions/HeaderActions.types.d.ts.map +1 -0
  319. package/dist/types/components/form/HeaderActions/index.d.ts +3 -0
  320. package/dist/types/components/form/HeaderActions/index.d.ts.map +1 -0
  321. package/dist/types/components/form/Input/Input.styles.d.ts.map +1 -1
  322. package/dist/types/components/form/InputOTP/InputOTP.styles.d.ts.map +1 -1
  323. package/dist/types/components/form/PhoneInput/PhoneInput.d.ts.map +1 -1
  324. package/dist/types/components/form/RadioGroup/RadioGroup.styles.d.ts.map +1 -1
  325. package/dist/types/components/form/RichTextEditor/RichTextEditor.d.ts.map +1 -1
  326. package/dist/types/components/form/Select/Select.d.ts.map +1 -1
  327. package/dist/types/components/form/Textarea/Textarea.d.ts.map +1 -1
  328. package/dist/types/components/form/Textarea/Textarea.styles.d.ts.map +1 -1
  329. package/dist/types/components/form/Textarea/TextareaRichEditor.d.ts.map +1 -1
  330. package/dist/types/components/form/Toggle/Toggle.styles.d.ts.map +1 -1
  331. package/dist/types/components/layout/Dashboard/Dashboard.d.ts +4 -0
  332. package/dist/types/components/layout/Dashboard/Dashboard.d.ts.map +1 -1
  333. package/dist/types/components/layout/Dashboard/Dashboard.types.d.ts +10 -0
  334. package/dist/types/components/layout/Dashboard/Dashboard.types.d.ts.map +1 -1
  335. package/dist/types/components/layout/Dashboard/DashboardParts.d.ts +22 -1
  336. package/dist/types/components/layout/Dashboard/DashboardParts.d.ts.map +1 -1
  337. package/dist/types/components/layout/Dashboard/index.d.ts +1 -1
  338. package/dist/types/components/layout/Dashboard/index.d.ts.map +1 -1
  339. package/dist/types/tokens/field-edge.d.ts +80 -0
  340. package/dist/types/tokens/field-edge.d.ts.map +1 -0
  341. package/dist/user-avatar.js +3 -3
  342. package/dist/utility/InstallPrompt.js +2 -2
  343. package/package.json +5 -1
  344. package/src/components/form/AddressAutocomplete/AddressTextField.tsx +3 -1
  345. package/src/components/form/CategorySelect/CategorySelect.styles.ts +3 -1
  346. package/src/components/form/CodeEditor/CodeEditor.tsx +3 -1
  347. package/src/components/form/CreatableSelect/CreatableSelect.tsx +4 -2
  348. package/src/components/form/HeaderActions/HeaderActions.md +72 -0
  349. package/src/components/form/HeaderActions/HeaderActions.tsx +134 -0
  350. package/src/components/form/HeaderActions/HeaderActions.types.ts +64 -0
  351. package/src/components/form/HeaderActions/index.ts +2 -0
  352. package/src/components/form/Input/Input.styles.ts +5 -3
  353. package/src/components/form/InputOTP/InputOTP.styles.ts +3 -1
  354. package/src/components/form/PhoneInput/PhoneInput.tsx +3 -1
  355. package/src/components/form/RadioGroup/RadioGroup.styles.ts +4 -2
  356. package/src/components/form/RichTextEditor/RichTextEditor.tsx +3 -1
  357. package/src/components/form/Select/Select.tsx +4 -2
  358. package/src/components/form/Textarea/Textarea.styles.ts +3 -1
  359. package/src/components/form/Textarea/Textarea.tsx +4 -2
  360. package/src/components/form/Textarea/TextareaRichEditor.tsx +3 -1
  361. package/src/components/form/Toggle/Toggle.styles.ts +3 -1
  362. package/src/components/layout/Dashboard/Dashboard.md +9 -2
  363. package/src/components/layout/Dashboard/Dashboard.tsx +2 -0
  364. package/src/components/layout/Dashboard/Dashboard.types.ts +12 -0
  365. package/src/components/layout/Dashboard/DashboardParts.tsx +36 -0
  366. package/src/components/layout/Dashboard/index.ts +1 -0
  367. package/src/tokens/field-edge.ts +141 -0
  368. package/dist/chunk-3AEY5TYV.js.map +0 -1
  369. package/dist/chunk-4VPCZFF3.js.map +0 -1
  370. package/dist/chunk-5QQWAIZO.js.map +0 -1
  371. package/dist/chunk-A2WJMZX5.js.map +0 -1
  372. package/dist/chunk-A43SJQYE.js.map +0 -1
  373. package/dist/chunk-B2324WXJ.js.map +0 -1
  374. package/dist/chunk-FLSSV4TH.js.map +0 -1
  375. package/dist/chunk-FXMZMX5E.js.map +0 -1
  376. package/dist/chunk-J72KWTHC.js.map +0 -1
  377. package/dist/chunk-MNZ2NT5A.js.map +0 -1
  378. package/dist/chunk-Q6HJMJBH.js.map +0 -1
  379. package/dist/chunk-SQAU5QUY.js.map +0 -1
  380. package/dist/chunk-XCT2ZLA6.js.map +0 -1
  381. package/dist/chunk-XN5AYC5S.js.map +0 -1
  382. package/dist/chunk-ZYRW7FVY.js.map +0 -1
  383. /package/dist/{chunk-WQSL6MCA.js.map → chunk-23FCBIUN.js.map} +0 -0
  384. /package/dist/{chunk-QIKTIKO6.js.map → chunk-24LW52EU.js.map} +0 -0
  385. /package/dist/{chunk-75KRWRJA.js.map → chunk-2ZDTGI5V.js.map} +0 -0
  386. /package/dist/{chunk-XPS7FWZS.js.map → chunk-3LO5JWTC.js.map} +0 -0
  387. /package/dist/{chunk-MYOFULG4.js.map → chunk-3ORFVLI3.js.map} +0 -0
  388. /package/dist/{chunk-EIGELK2H.js.map → chunk-3P4THDBM.js.map} +0 -0
  389. /package/dist/{chunk-SJIBPRPB.js.map → chunk-3T2I6BYA.js.map} +0 -0
  390. /package/dist/{chunk-ZNGUDGKW.js.map → chunk-45OIUWGO.js.map} +0 -0
  391. /package/dist/{chunk-4ETQRBZC.js.map → chunk-46UPILLK.js.map} +0 -0
  392. /package/dist/{chunk-S7CAXRRP.js.map → chunk-4Y65Q3CR.js.map} +0 -0
  393. /package/dist/{chunk-2UCJJACD.js.map → chunk-5VVM2PPV.js.map} +0 -0
  394. /package/dist/{chunk-JE6RZ5L6.js.map → chunk-5ZOJLYD2.js.map} +0 -0
  395. /package/dist/{chunk-AVGTTWTE.js.map → chunk-65DLYC4S.js.map} +0 -0
  396. /package/dist/{chunk-O6V7KKW7.js.map → chunk-6CBYPMYQ.js.map} +0 -0
  397. /package/dist/{chunk-BPCYXLWY.js.map → chunk-6HNEEJES.js.map} +0 -0
  398. /package/dist/{chunk-WXVHZHSJ.js.map → chunk-6RFL7HGI.js.map} +0 -0
  399. /package/dist/{chunk-UENDC45F.js.map → chunk-6TYSEAAT.js.map} +0 -0
  400. /package/dist/{chunk-R7MX5KPJ.js.map → chunk-6YLAVHV4.js.map} +0 -0
  401. /package/dist/{chunk-RXSGHPCR.js.map → chunk-7FOOLP5H.js.map} +0 -0
  402. /package/dist/{chunk-EICVL6GS.js.map → chunk-7HPPUO2A.js.map} +0 -0
  403. /package/dist/{chunk-3BR2CLAM.js.map → chunk-A3KY6NUA.js.map} +0 -0
  404. /package/dist/{chunk-2I5B5NNT.js.map → chunk-AX7UFG2U.js.map} +0 -0
  405. /package/dist/{chunk-7DNQHMDO.js.map → chunk-B6IURHSZ.js.map} +0 -0
  406. /package/dist/{chunk-CZJLWCEG.js.map → chunk-BPYPUEM5.js.map} +0 -0
  407. /package/dist/{chunk-5VZPVDUF.js.map → chunk-COSJTD6Z.js.map} +0 -0
  408. /package/dist/{chunk-AP3PVR3T.js.map → chunk-CXA6UNFF.js.map} +0 -0
  409. /package/dist/{chunk-LPNF4YJ7.js.map → chunk-DGMR3IMM.js.map} +0 -0
  410. /package/dist/{chunk-MUFI3ZXS.js.map → chunk-DQIQKIEA.js.map} +0 -0
  411. /package/dist/{chunk-LQR2IVSL.js.map → chunk-DWUMMMLR.js.map} +0 -0
  412. /package/dist/{chunk-56SMIHWE.js.map → chunk-EE2LBAJH.js.map} +0 -0
  413. /package/dist/{chunk-SHDIZSN5.js.map → chunk-EGRFMPGD.js.map} +0 -0
  414. /package/dist/{chunk-M6365FGG.js.map → chunk-ELYLG4F7.js.map} +0 -0
  415. /package/dist/{chunk-PHA3NFZM.js.map → chunk-ENK4XGKF.js.map} +0 -0
  416. /package/dist/{chunk-XFUNJYFT.js.map → chunk-EPNUVSNK.js.map} +0 -0
  417. /package/dist/{chunk-QTPKACVO.js.map → chunk-EY4LPLIR.js.map} +0 -0
  418. /package/dist/{chunk-GNAAHDCN.js.map → chunk-FF55LRSV.js.map} +0 -0
  419. /package/dist/{chunk-L6KEVPXN.js.map → chunk-FH4VARZ7.js.map} +0 -0
  420. /package/dist/{chunk-J4DDXHLB.js.map → chunk-FJHNNSD3.js.map} +0 -0
  421. /package/dist/{chunk-ONZPM6FP.js.map → chunk-G7CFUI4I.js.map} +0 -0
  422. /package/dist/{chunk-KDIWFARU.js.map → chunk-GBB6XQ56.js.map} +0 -0
  423. /package/dist/{chunk-UHXNEXOC.js.map → chunk-GFBNUWT5.js.map} +0 -0
  424. /package/dist/{chunk-PLOOVF43.js.map → chunk-GGE7Y53F.js.map} +0 -0
  425. /package/dist/{chunk-R6SBP5M5.js.map → chunk-GOWBYHYW.js.map} +0 -0
  426. /package/dist/{chunk-HDNK7BAX.js.map → chunk-GT7C6TSM.js.map} +0 -0
  427. /package/dist/{chunk-7SZ3PFZW.js.map → chunk-HBAPVB7T.js.map} +0 -0
  428. /package/dist/{chunk-V7TPSQOH.js.map → chunk-HBZIN6IQ.js.map} +0 -0
  429. /package/dist/{chunk-LS42VJAI.js.map → chunk-HEDOL2RV.js.map} +0 -0
  430. /package/dist/{chunk-RPWEXIAW.js.map → chunk-HEG7JIBM.js.map} +0 -0
  431. /package/dist/{chunk-AZUFGKMQ.js.map → chunk-HJOABXKN.js.map} +0 -0
  432. /package/dist/{chunk-6HLRXICF.js.map → chunk-IAQFQNBL.js.map} +0 -0
  433. /package/dist/{chunk-PUBPZOQJ.js.map → chunk-IPE5FFFD.js.map} +0 -0
  434. /package/dist/{chunk-FSMQF5P5.js.map → chunk-IXZ44HJF.js.map} +0 -0
  435. /package/dist/{chunk-RRO2EOJB.js.map → chunk-JB67KPGM.js.map} +0 -0
  436. /package/dist/{chunk-PDGAFQ6Z.js.map → chunk-JPDKRGYI.js.map} +0 -0
  437. /package/dist/{chunk-MNJVOU7T.js.map → chunk-K2T2CQSZ.js.map} +0 -0
  438. /package/dist/{chunk-LFB4H7Y6.js.map → chunk-KNNBIXWJ.js.map} +0 -0
  439. /package/dist/{chunk-CKZFYGBY.js.map → chunk-KSF7TLXH.js.map} +0 -0
  440. /package/dist/{chunk-IIUB4IOH.js.map → chunk-LKF5KQ2Q.js.map} +0 -0
  441. /package/dist/{chunk-AZSFIQIA.js.map → chunk-LUWATXU4.js.map} +0 -0
  442. /package/dist/{chunk-CZPU5TW3.js.map → chunk-LYSSO6WC.js.map} +0 -0
  443. /package/dist/{chunk-J7VY6KNP.js.map → chunk-M3RIC6JI.js.map} +0 -0
  444. /package/dist/{chunk-5ZZPQ3MT.js.map → chunk-MHFJBNDP.js.map} +0 -0
  445. /package/dist/{chunk-V44U7H4M.js.map → chunk-MUAVYVDJ.js.map} +0 -0
  446. /package/dist/{chunk-LPYB4Y7C.js.map → chunk-N4WANJI3.js.map} +0 -0
  447. /package/dist/{chunk-ECIGNYSI.js.map → chunk-O3OU2PPT.js.map} +0 -0
  448. /package/dist/{chunk-62WEMJV3.js.map → chunk-PLK7UGO6.js.map} +0 -0
  449. /package/dist/{chunk-U7SO3N42.js.map → chunk-PMFW55F5.js.map} +0 -0
  450. /package/dist/{chunk-AGYGNNOM.js.map → chunk-PQECNGDE.js.map} +0 -0
  451. /package/dist/{chunk-GPVB3FQP.js.map → chunk-PU3AAKRR.js.map} +0 -0
  452. /package/dist/{chunk-KEDI6IRA.js.map → chunk-QETBO7EC.js.map} +0 -0
  453. /package/dist/{chunk-WBKWIFXA.js.map → chunk-QYNCPS5W.js.map} +0 -0
  454. /package/dist/{chunk-DFLTUI7W.js.map → chunk-QZBUGUOY.js.map} +0 -0
  455. /package/dist/{chunk-OLZTGVBT.js.map → chunk-REMK55JI.js.map} +0 -0
  456. /package/dist/{chunk-CPNSVIIB.js.map → chunk-RP3W6IQO.js.map} +0 -0
  457. /package/dist/{chunk-4QQVIGRG.js.map → chunk-RQ4EQ5FJ.js.map} +0 -0
  458. /package/dist/{chunk-BLT5ZBVL.js.map → chunk-RRX6ZTNX.js.map} +0 -0
  459. /package/dist/{chunk-QL7L6RHR.js.map → chunk-RX6DWIIW.js.map} +0 -0
  460. /package/dist/{chunk-RGBS6N72.js.map → chunk-SEH7KOVG.js.map} +0 -0
  461. /package/dist/{chunk-GJQYM3PM.js.map → chunk-SHQWIDD5.js.map} +0 -0
  462. /package/dist/{chunk-NQCYVYP3.js.map → chunk-SLYZMJEL.js.map} +0 -0
  463. /package/dist/{chunk-HKROKM3Z.js.map → chunk-SM3NRN7L.js.map} +0 -0
  464. /package/dist/{chunk-PMS3H3OO.js.map → chunk-T53L42XW.js.map} +0 -0
  465. /package/dist/{chunk-LNIVT62P.js.map → chunk-TPUIIZN2.js.map} +0 -0
  466. /package/dist/{chunk-U5RIDMMV.js.map → chunk-TUAIPMU7.js.map} +0 -0
  467. /package/dist/{chunk-7QVYJQN4.js.map → chunk-VJKRJYZL.js.map} +0 -0
  468. /package/dist/{chunk-7EGHRNIA.js.map → chunk-VVXRIPV5.js.map} +0 -0
  469. /package/dist/{chunk-2SWQ6HIK.js.map → chunk-W3FAKT3D.js.map} +0 -0
  470. /package/dist/{chunk-ZOUWHGV3.js.map → chunk-WC3W36AM.js.map} +0 -0
  471. /package/dist/{chunk-VJFH2AXT.js.map → chunk-WEH5TCPE.js.map} +0 -0
  472. /package/dist/{chunk-CESQKLIR.js.map → chunk-WFX5GASM.js.map} +0 -0
  473. /package/dist/{chunk-O6MZPB64.js.map → chunk-WR6F6J43.js.map} +0 -0
  474. /package/dist/{chunk-V5P5Q6HM.js.map → chunk-X24P3ZYW.js.map} +0 -0
  475. /package/dist/{chunk-BVGR7OYA.js.map → chunk-XULTDO56.js.map} +0 -0
  476. /package/dist/{chunk-OGGHD64H.js.map → chunk-Y5UCOBQN.js.map} +0 -0
  477. /package/dist/{chunk-2A3OMYCB.js.map → chunk-YRUCIKPO.js.map} +0 -0
  478. /package/dist/{chunk-K25MT3GZ.js.map → chunk-YVW7VPK4.js.map} +0 -0
  479. /package/dist/{chunk-XQ2BNVXL.js.map → chunk-ZBNTFWTG.js.map} +0 -0
  480. /package/dist/{chunk-G5ZVD5IJ.js.map → chunk-ZDWU52DJ.js.map} +0 -0
@@ -0,0 +1,134 @@
1
+ 'use client';
2
+
3
+ import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
4
+ import MoreHorizIcon from '@mui/icons-material/MoreHoriz';
5
+ import Box from '@mui/material/Box/index.js';
6
+ import ListItemIcon from '@mui/material/ListItemIcon/index.js';
7
+ import ListItemText from '@mui/material/ListItemText/index.js';
8
+ import Menu from '@mui/material/Menu/index.js';
9
+ import MenuItem from '@mui/material/MenuItem/index.js';
10
+ import React, { useState } from 'react';
11
+
12
+ import { HeaderButton } from '../HeaderButton';
13
+ import type { HeaderActionItem, HeaderActionsProps } from './HeaderActions.types';
14
+
15
+ /** Drop the gated-away entries, so everything below can count what is left. */
16
+ function present(
17
+ actions: HeaderActionsProps['actions'],
18
+ ): HeaderActionItem[] {
19
+ return actions.filter(
20
+ (action): action is HeaderActionItem => Boolean(action) && (action as HeaderActionItem).visible !== false,
21
+ );
22
+ }
23
+
24
+ /**
25
+ * The page header's actions, as ONE control that scales with how many there
26
+ * are: nothing, a button, or a button plus an overflow menu.
27
+ *
28
+ * | actions | renders |
29
+ * |---|---|
30
+ * | 0 | nothing at all — not an empty box, and not a menu with no items |
31
+ * | 1 | that action, as an ordinary `HeaderButton` |
32
+ * | n | the FIRST as a button; the other n−1 inside one dropdown |
33
+ *
34
+ * ## Why the first one stays a button
35
+ *
36
+ * A header whose every action lives behind a menu costs two clicks for the
37
+ * thing the page is FOR — "Novo produto" on a catalog, "Nova categoria" on the
38
+ * categories list. Folding it in with the exports and the reorder screens
39
+ * would treat a merchant's daily action as equal to the one they use monthly.
40
+ * So the array is in PRIORITY order and index 0 keeps its button; everything
41
+ * after it is secondary by the caller's own declaration.
42
+ *
43
+ * ## Why this takes a list and not children
44
+ *
45
+ * The 0/1/n decision is only decidable over data. A component handed JSX can
46
+ * count `React.Children`, but it cannot tell a gated-away action from an
47
+ * absent one, cannot read a label to put in a menu row, and cannot re-render
48
+ * a `<Button>` as a `<MenuItem>` without reaching into its props. Every
49
+ * caller in the estate had therefore hand-written the row, which is how four
50
+ * equally-weighted buttons ended up wrapping the line on a catalog page.
51
+ *
52
+ * ## One element, so the spacing is the component's and not the mount's
53
+ *
54
+ * It renders an `inline-flex` box rather than a fragment. A fragment inherits
55
+ * whatever gap its parent happens to set, and the two mounts here set
56
+ * different ones — a `Dashboard.Header` spaces its children, a
57
+ * `Dashboard.Action` slot does not, which is why the pair of buttons in that
58
+ * slot sat flush against each other. The gap belongs to the control.
59
+ *
60
+ * ## The ids survive the move
61
+ *
62
+ * An action that overflows keeps its `dataTestId` on its `MenuItem`. It is a
63
+ * different element in a different place, and it must still answer to the same
64
+ * selector: otherwise adding a fifth action to a header silently breaks the
65
+ * suite of the action that got pushed out, which is the last place anyone
66
+ * would look.
67
+ */
68
+ export function HeaderActions({
69
+ actions,
70
+ moreLabel,
71
+ collapseBelow = 'md',
72
+ testIdPrefix = 'header-actions',
73
+ }: HeaderActionsProps): React.JSX.Element | null {
74
+ const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
75
+ const items = present(actions);
76
+ const open = Boolean(anchorEl);
77
+
78
+ // Before the early return would be a conditional hook; after it is the only
79
+ // legal place. Nothing below runs for an empty list anyway.
80
+ const [primary, ...overflow] = items;
81
+ if (!primary) return null;
82
+
83
+ return (
84
+ <Box sx={{ display: 'inline-flex', alignItems: 'center', gap: 1 }}>
85
+ <HeaderButton
86
+ text={primary.text}
87
+ icon={primary.icon}
88
+ onClick={primary.onClick}
89
+ disabled={primary.disabled}
90
+ variant={primary.variant}
91
+ color={primary.color}
92
+ collapseBelow={collapseBelow}
93
+ dataTestId={primary.dataTestId ?? primary.id}
94
+ />
95
+ {overflow.length > 0 && (
96
+ <>
97
+ <HeaderButton
98
+ text={moreLabel}
99
+ icon={<MoreHorizIcon fontSize="small" />}
100
+ endIcon={<ExpandMoreIcon fontSize="small" />}
101
+ onClick={(event) => setAnchorEl(event.currentTarget)}
102
+ collapseBelow={collapseBelow}
103
+ aria-haspopup="menu"
104
+ aria-expanded={open}
105
+ dataTestId={`${testIdPrefix}-more-trigger`}
106
+ />
107
+ <Menu
108
+ anchorEl={anchorEl}
109
+ open={open}
110
+ onClose={() => setAnchorEl(null)}
111
+ anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
112
+ transformOrigin={{ vertical: 'top', horizontal: 'right' }}
113
+ data-testid={`${testIdPrefix}-more-menu`}
114
+ >
115
+ {overflow.map((action) => (
116
+ <MenuItem
117
+ key={action.id}
118
+ disabled={action.disabled}
119
+ onClick={() => {
120
+ setAnchorEl(null);
121
+ action.onClick?.();
122
+ }}
123
+ data-testid={action.dataTestId ?? action.id}
124
+ >
125
+ <ListItemIcon sx={{ minWidth: 32 }}>{action.icon}</ListItemIcon>
126
+ <ListItemText>{action.text}</ListItemText>
127
+ </MenuItem>
128
+ ))}
129
+ </Menu>
130
+ </>
131
+ )}
132
+ </Box>
133
+ );
134
+ }
@@ -0,0 +1,64 @@
1
+ import type { ReactNode } from 'react';
2
+
3
+ import type { HeaderButtonProps } from '../HeaderButton';
4
+
5
+ /**
6
+ * One page-header action, declared as DATA rather than composed as an element.
7
+ *
8
+ * That is the whole point of the type. A header that composes its buttons as
9
+ * JSX can only ever render all of them, because nothing can count a fragment's
10
+ * children without walking React internals — so "three actions" and "seven
11
+ * actions" produce the same row, and the seventh button is what wraps the line
12
+ * on a laptop. A list can be measured, so the component can decide.
13
+ */
14
+ export interface HeaderActionItem {
15
+ /**
16
+ * Stable identity. Used as the React key, and as the `data-testid` fallback
17
+ * so an action that MOVES into the overflow menu keeps the selector it had
18
+ * as a button — a suite driving it by id must not care where it ended up.
19
+ */
20
+ id: string;
21
+ /** The label. Shown beside the icon as a button; alone in the menu row. */
22
+ text: ReactNode;
23
+ /** Leading icon. Always visible as a button, and in the menu row. */
24
+ icon: ReactNode;
25
+ onClick?: () => void;
26
+ disabled?: boolean;
27
+ /**
28
+ * Drop this action entirely when false. Present so a caller can declare a
29
+ * permission- or plan-gated action inline, instead of building the array
30
+ * conditionally and losing the reason it is missing.
31
+ *
32
+ * @default true
33
+ */
34
+ visible?: boolean;
35
+ /** Overrides the `data-testid`, which otherwise falls back to {@link id}. */
36
+ dataTestId?: string;
37
+ /** MUI variant for the PRIMARY rendering. Ignored inside the menu. */
38
+ variant?: HeaderButtonProps['variant'];
39
+ /** MUI color for the PRIMARY rendering. Ignored inside the menu. */
40
+ color?: HeaderButtonProps['color'];
41
+ }
42
+
43
+ /** Props for {@link HeaderActions}. */
44
+ export interface HeaderActionsProps {
45
+ /**
46
+ * The actions, in priority order — the first is the one that stays a button.
47
+ *
48
+ * `false`/`null`/`undefined` entries are dropped, so a caller can write
49
+ * `[edit, canDelete && del]` without pre-filtering.
50
+ */
51
+ actions: Array<HeaderActionItem | false | null | undefined>;
52
+ /**
53
+ * The overflow trigger's label, which is also its accessible name. REQUIRED:
54
+ * this package ships no copy of its own, in any language.
55
+ */
56
+ moreLabel: string;
57
+ /** Width below which every button collapses to icon-only. @default 'md' */
58
+ collapseBelow?: HeaderButtonProps['collapseBelow'];
59
+ /**
60
+ * Prefix for the overflow trigger's and menu's own test ids. The ACTIONS
61
+ * keep their own ids either way. @default 'header-actions'
62
+ */
63
+ testIdPrefix?: string;
64
+ }
@@ -0,0 +1,2 @@
1
+ export { HeaderActions } from './HeaderActions';
2
+ export type { HeaderActionItem, HeaderActionsProps } from './HeaderActions.types';
@@ -3,6 +3,8 @@ import type { CSSObject, Theme } from '@mui/material/styles/index.js';
3
3
 
4
4
  import type { InputProps } from './Input.types';
5
5
 
6
+ import { fieldEdge } from '../../../tokens/field-edge';
7
+
6
8
  type InputVariant = NonNullable<InputProps['variant']>;
7
9
 
8
10
  // Define pulse animation
@@ -90,7 +92,7 @@ export const inputBaseStyles = (theme: Theme, variant?: InputVariant): CSSObject
90
92
  return {
91
93
  backgroundColor: alpha(theme.palette.background.paper, 0.1),
92
94
  backdropFilter: 'blur(20px)',
93
- border: `1px solid ${alpha(theme.palette.divider, 0.2)}`,
95
+ border: `1px solid ${fieldEdge(theme)}`,
94
96
  '&:hover': {
95
97
  backgroundColor: alpha(theme.palette.background.paper, 0.15),
96
98
  borderColor: alpha(theme.palette.primary.main, 0.3),
@@ -104,7 +106,7 @@ export const inputBaseStyles = (theme: Theme, variant?: InputVariant): CSSObject
104
106
  case 'underline':
105
107
  return {
106
108
  '&:before': {
107
- borderBottomColor: alpha(theme.palette.divider, 0.42),
109
+ borderBottomColor: fieldEdge(theme),
108
110
  },
109
111
  '&:hover:not(.Mui-disabled):before': {
110
112
  borderBottomColor: theme.palette.primary.main,
@@ -155,7 +157,7 @@ const gradientStyles = (theme: Theme): CSSObject => ({
155
157
 
156
158
  export const outlinedStyles = (theme: Theme): CSSObject => ({
157
159
  '& fieldset': {
158
- borderColor: alpha(theme.palette.divider, 0.23),
160
+ borderColor: fieldEdge(theme),
159
161
  },
160
162
  '&:hover fieldset': {
161
163
  borderColor: theme.palette.primary.main,
@@ -1,6 +1,8 @@
1
1
  import { alpha } from '@mui/material/styles/index.js';
2
2
  import type { CSSObject, Theme } from '@mui/material/styles/index.js';
3
3
 
4
+ import { fieldEdge } from '../../../tokens/field-edge';
5
+
4
6
  interface ColorPalette {
5
7
  main: string;
6
8
  dark?: string;
@@ -82,7 +84,7 @@ export const otpSlotSx = (theme: Theme, flags: OtpSlotFlags): CSSObject => {
82
84
  ...(glass && {
83
85
  backgroundColor: alpha(theme.palette.background.paper, 0.1),
84
86
  backdropFilter: 'blur(20px)',
85
- '& fieldset': { border: `1px solid ${alpha(theme.palette.divider, 0.2)}` },
87
+ '& fieldset': { border: `1px solid ${fieldEdge(theme)}` },
86
88
  }),
87
89
  ...(gradient && {
88
90
  '&.Mui-focused fieldset': {
@@ -17,6 +17,8 @@ import { usePhoneInput } from './PhoneInput.hooks';
17
17
  import type { CountryData,PhoneInputProps } from './PhoneInput.types';
18
18
  import type { PhoneInputCopy } from '../../../copy';
19
19
 
20
+ import { fieldEdge } from '../../../tokens/field-edge';
21
+
20
22
  // Country data with expanded support
21
23
 
22
24
  // Styled components
@@ -25,7 +27,7 @@ const GlassTextField = styled(TextField)(({ theme }) => ({
25
27
  background: `linear-gradient(135deg, ${alpha(theme.palette.background.paper, 0.8)} 0%, ${alpha(theme.palette.background.paper, 0.6)} 100%)`,
26
28
  backdropFilter: 'blur(10px)',
27
29
  WebkitBackdropFilter: 'blur(10px)',
28
- border: `1px solid ${alpha(theme.palette.divider, 0.18)}`,
30
+ border: `1px solid ${fieldEdge(theme)}`,
29
31
  transition: theme.transitions.create(['border-color', 'box-shadow', 'background']),
30
32
  '&:hover': {
31
33
  background: `linear-gradient(135deg, ${alpha(theme.palette.background.paper, 0.9)} 0%, ${alpha(theme.palette.background.paper, 0.7)} 100%)`,
@@ -3,6 +3,8 @@ import type { CSSObject, Theme } from '@mui/material/styles/index.js';
3
3
 
4
4
  import { glowAnimation, rippleAnimation, scaleAnimation, slideAnimation } from './RadioGroup.animations';
5
5
 
6
+ import { fieldEdge } from '../../../tokens/field-edge';
7
+
6
8
  interface ColorPalette {
7
9
  main: string;
8
10
  dark?: string;
@@ -119,7 +121,7 @@ const cardBase = (theme: Theme, flags: SurfaceFlags, palette: ColorPalette): CSS
119
121
  return {
120
122
  cursor: 'pointer',
121
123
  transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',
122
- border: `2px solid ${selected ? palette.main : alpha(theme.palette.divider, 0.3)}`,
124
+ border: `2px solid ${selected ? palette.main : fieldEdge(theme)}`,
123
125
  backgroundColor: selected ? alpha(palette.main, 0.05) : theme.palette.background.paper,
124
126
  position: 'relative' as const,
125
127
  overflow: 'hidden' as const,
@@ -183,7 +185,7 @@ const buttonBase = (theme: Theme, flags: SurfaceFlags, palette: ColorPalette): C
183
185
  borderRadius: theme.spacing(1),
184
186
  transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',
185
187
  fontWeight: 500,
186
- border: `2px solid ${selected ? palette.main : alpha(theme.palette.divider, 0.5)}`,
188
+ border: `2px solid ${selected ? palette.main : fieldEdge(theme)}`,
187
189
  backgroundColor: selected ? palette.main : 'transparent',
188
190
  color: selected ? palette.contrastText || '#fff' : theme.palette.text.primary,
189
191
  position: 'relative' as const,
@@ -8,6 +8,8 @@ import { useRichTextEditor } from './RichTextEditor.hooks';
8
8
  import type { RichTextEditorProps, ToolbarConfig } from './RichTextEditor.types';
9
9
  import { RichTextEditorToolbar } from './RichTextEditorToolbar';
10
10
 
11
+ import { fieldEdge } from '../../../tokens/field-edge';
12
+
11
13
  const DEFAULT_TOOLBAR: Required<Omit<ToolbarConfig, 'customItems'>> & Pick<ToolbarConfig, 'customItems'> = {
12
14
  bold: true,
13
15
  italic: true,
@@ -68,7 +70,7 @@ const editorContentSx = (theme: Theme, disabled: boolean, placeholder?: string,
68
70
  '& a': { color: theme.palette.primary.main, textDecoration: 'underline' } });
69
71
 
70
72
  const shellSx = (theme: Theme, isFocused: boolean, disabled: boolean) => ({
71
- border: `1px solid ${alpha(theme.palette.divider, 0.12)}`,
73
+ border: `1px solid ${fieldEdge(theme)}`,
72
74
  borderRadius: 1,
73
75
  overflow: 'hidden',
74
76
  transition: 'border-color 0.2s ease-in-out',
@@ -8,6 +8,8 @@ import React from 'react';
8
8
 
9
9
  import type { SelectProps } from './Select.types';
10
10
 
11
+ import { fieldEdge } from '../../../tokens/field-edge';
12
+
11
13
  // Define pulse animation
12
14
  const pulseAnimation = keyframes`
13
15
  0% {
@@ -57,7 +59,7 @@ const pulseStyles = (theme: Theme): CSSObject => ({
57
59
  const glassVariant = (theme: Theme): CSSObject => ({
58
60
  backgroundColor: alpha(theme.palette.background.paper, 0.1),
59
61
  backdropFilter: 'blur(20px)',
60
- border: `1px solid ${alpha(theme.palette.divider, 0.2)}`,
62
+ border: `1px solid ${fieldEdge(theme)}`,
61
63
  '& fieldset': { border: 'none' },
62
64
  '&:hover': {
63
65
  backgroundColor: alpha(theme.palette.background.paper, 0.15),
@@ -105,7 +107,7 @@ const gradientVariant = (theme: Theme): CSSObject => ({
105
107
 
106
108
  /** `default` variant: standard outlined borders with hover/focus/error states. */
107
109
  const defaultVariant = (theme: Theme): CSSObject => ({
108
- '& fieldset': { borderColor: alpha(theme.palette.divider, 0.23) },
110
+ '& fieldset': { borderColor: fieldEdge(theme) },
109
111
  '&:hover fieldset': { borderColor: theme.palette.primary.main },
110
112
  '&.Mui-focused fieldset': { borderColor: theme.palette.primary.main, borderWidth: 2 },
111
113
  '&.Mui-error fieldset': { borderColor: theme.palette.error.main },
@@ -1,6 +1,8 @@
1
1
  import { alpha, keyframes } from '@mui/material/styles/index.js';
2
2
  import type { CSSObject, Theme } from '@mui/material/styles/index.js';
3
3
 
4
+ import { fieldEdge } from '../../../tokens/field-edge';
5
+
4
6
  const glowAnimation = keyframes`
5
7
  0% {
6
8
  box-shadow: 0 0 5px currentColor;
@@ -107,7 +109,7 @@ const glassStyles = glass
107
109
  ? {
108
110
  backgroundColor: alpha(theme.palette.background.paper, 0.1),
109
111
  backdropFilter: 'blur(20px)',
110
- border: `1px solid ${alpha(theme.palette.divider, 0.2)}`,
112
+ border: `1px solid ${fieldEdge(theme)}`,
111
113
  '&:hover': {
112
114
  backgroundColor: alpha(theme.palette.background.paper, 0.15),
113
115
  backdropFilter: 'blur(25px)',
@@ -30,6 +30,8 @@ const TextareaRichEditor = lazy(async () => ({
30
30
  default: (await import('./TextareaRichEditor')).TextareaRichEditor }));
31
31
  import type { TextareaProps } from './Textarea.types';
32
32
 
33
+ import { fieldEdge } from '../../../tokens/field-edge';
34
+
33
35
  // Interface for styled component props
34
36
  interface StyledTextareaProps {
35
37
  customVariant?: string;
@@ -71,7 +73,7 @@ const StyledTextarea = styled(TextareaAutosize, {
71
73
  width: '100%',
72
74
  fontFamily: theme.typography.fontFamily,
73
75
  borderRadius: theme.spacing(1),
74
- border: `2px solid ${error ? errorColor.main : theme.palette.divider}`,
76
+ border: `2px solid ${error ? errorColor.main : fieldEdge(theme)}`,
75
77
  backgroundColor: theme.palette.background.paper,
76
78
  color: theme.palette.text.primary,
77
79
  transition: 'all 0.3s ease',
@@ -108,7 +110,7 @@ const StyledLabel = styled(InputLabel, {
108
110
  backdropFilter: 'blur(10px)',
109
111
  padding: '4px 8px',
110
112
  borderRadius: '4px',
111
- border: `1px solid ${alpha(theme.palette.divider, 0.2)}`,
113
+ border: `1px solid ${fieldEdge(theme)}`,
112
114
  display: 'inline-block' }) }));
113
115
 
114
116
  // IconWrapper - replaced with inline Box component for better TypeScript compatibility
@@ -19,6 +19,8 @@ import React, { useEffect, useRef, useState } from 'react';
19
19
  import { floatAnimation, getColorFromTheme } from './Textarea.styles';
20
20
  import type { RichEditorToolbarCopy } from '../../../copy';
21
21
 
22
+ import { fieldEdge } from '../../../tokens/field-edge';
23
+
22
24
  const RichToolbar = styled(Box)<{ glass?: boolean }>(({ theme, glass }) => ({
23
25
  display: 'flex',
24
26
  alignItems: 'center',
@@ -104,7 +106,7 @@ const ContentEditableDiv = styled('div')<{
104
106
  minHeight: '120px',
105
107
  padding: theme.spacing(1.5),
106
108
  borderRadius: `0 0 ${theme.spacing(1)} ${theme.spacing(1)}`,
107
- border: `2px solid ${error ? errorColor.main : focused ? colorPalette.main : theme.palette.divider}`,
109
+ border: `2px solid ${error ? errorColor.main : focused ? colorPalette.main : fieldEdge(theme)}`,
108
110
  borderTop: 'none',
109
111
  backgroundColor: glass
110
112
  ? alpha(theme.palette.background.paper, 0.1)
@@ -1,6 +1,8 @@
1
1
  import { alpha, keyframes } from '@mui/material/styles/index.js';
2
2
  import type { CSSObject, PaletteColor, Theme } from '@mui/material/styles/index.js';
3
3
 
4
+ import { fieldEdge } from '../../../tokens/field-edge';
5
+
4
6
  const glowAnimation = keyframes`
5
7
  0% { box-shadow: 0 0 5px currentColor; }
6
8
  50% { box-shadow: 0 0 15px currentColor, 0 0 25px currentColor; }
@@ -74,7 +76,7 @@ export const baseStyles = (
74
76
  fontWeight: 500,
75
77
  borderRadius: theme.spacing(1),
76
78
  transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',
77
- border: `2px solid ${alpha(theme.palette.divider, 0.3)}`,
79
+ border: `2px solid ${fieldEdge(theme)}`,
78
80
  color: theme.palette.text.primary,
79
81
  backgroundColor: 'transparent',
80
82
  position: 'relative',
@@ -27,7 +27,13 @@ import { Dashboard } from '@12-apps/ui/layout/Dashboard';
27
27
  <Dashboard.Settings title="Product settings">In development</Dashboard.Settings>
28
28
  <Dashboard.Spacer />
29
29
  <Dashboard.Export onExport={(id) => exportAs(id)} />
30
- <Dashboard.Action><Button variant="contained">New product</Button></Dashboard.Action>
30
+ <Dashboard.Actions
31
+ moreLabel={copy.moreActions}
32
+ actions={[
33
+ { id: 'new-product', text: 'New product', icon: <AddIcon fontSize="small" />, onClick: onCreate },
34
+ { id: 'import', text: 'Import sheet', icon: <UploadIcon fontSize="small" />, onClick: onImport },
35
+ ]}
36
+ />
31
37
  </Dashboard.Header>
32
38
  <Dashboard.Filters>
33
39
  <SearchInput />
@@ -51,7 +57,8 @@ import { Dashboard } from '@12-apps/ui/layout/Dashboard';
51
57
  | `Dashboard.Settings` | (in header) | Gear icon. Default: opens a dialog with `children`. With `href` (+ optional `linkComponent`): renders as a link to a settings route (e.g. the page's Configuração section) — no dialog. |
52
58
  | `Dashboard.Export` | (in header) | Export dropdown (CSV/Excel/JSON by default); calls `onExport(id)`. |
53
59
  | `Dashboard.Spacer` | (in header) | Pushes following controls to the right edge. |
54
- | `Dashboard.Action` | (in header) | Slot for a primary/secondary button. |
60
+ | `Dashboard.Action` | (in header) | Slot for ONE header control that is not an action — a link, a toggle, a status pill. |
61
+ | `Dashboard.Actions` | (in header) | The header's actions declared as a list. 0 renders nothing, 1 renders a button, n renders the first as a button and the other n−1 in a dropdown. See [HeaderActions](../../form/HeaderActions/HeaderActions.md). |
55
62
  | `Dashboard.Filters` | filters | Collapsible search/filter region; visibility driven by `FilterToggle`. |
56
63
  | `Dashboard.MoreFilters` | (in filters) | Expandable advanced panel for ranges/dates. |
57
64
  | `Dashboard.Body` | body | Main content area (the table/grid). |
@@ -16,6 +16,7 @@ import React, { useMemo, useState } from 'react';
16
16
  import { DashboardContext, useDashboardContext } from './DashboardContext';
17
17
  import {
18
18
  DashboardAction,
19
+ DashboardActions,
19
20
  DashboardExport,
20
21
  DashboardFilterToggle,
21
22
  DashboardInfo,
@@ -309,6 +310,7 @@ Dashboard.FilterToggle = DashboardFilterToggle;
309
310
  Dashboard.Settings = DashboardSettings;
310
311
  Dashboard.Export = DashboardExport;
311
312
  Dashboard.Action = DashboardAction;
313
+ Dashboard.Actions = DashboardActions;
312
314
  Dashboard.Filters = DashboardFilters;
313
315
  Dashboard.MoreFilters = DashboardMoreFilters;
314
316
  Dashboard.Body = DashboardBody;
@@ -1,5 +1,7 @@
1
1
  import type { ElementType, ReactNode } from 'react';
2
2
 
3
+ import type { HeaderActionsProps } from '../../form/HeaderActions';
4
+
3
5
  /** A single breadcrumb entry for `<Dashboard.Breadcrumb>`. */
4
6
  export interface DashboardBreadcrumbItem {
5
7
  /** Visible label. */
@@ -139,6 +141,16 @@ export interface DashboardActionProps {
139
141
  children: ReactNode;
140
142
  }
141
143
 
144
+ /**
145
+ * Props for `<Dashboard.Actions>` — the header's actions DECLARED, rather than
146
+ * composed one `<Dashboard.Action>` at a time.
147
+ *
148
+ * `testIdPrefix` is not among them: the Dashboard already has one, from its
149
+ * root, and letting the part carry a second would give one page two answers to
150
+ * "what is this header called".
151
+ */
152
+ export type DashboardActionsProps = Omit<HeaderActionsProps, 'testIdPrefix'>;
153
+
142
154
  /** Props for `<Dashboard.Filters>` — the collapsible search/filter region. */
143
155
  export interface DashboardFiltersProps {
144
156
  /** Filter controls (search input, pills, `<Dashboard.MoreFilters>`, …). */
@@ -19,10 +19,12 @@ import Tooltip from '@mui/material/Tooltip/index.js';
19
19
  import Typography from '@mui/material/Typography/index.js';
20
20
  import React, { useState } from 'react';
21
21
 
22
+ import { HeaderActions } from '../../form/HeaderActions';
22
23
  import { HeaderButton } from '../../form/HeaderButton';
23
24
  import { useDashboardContext } from './DashboardContext';
24
25
  import type {
25
26
  DashboardActionProps,
27
+ DashboardActionsProps,
26
28
  DashboardExportFormat,
27
29
  DashboardExportProps,
28
30
  DashboardFilterToggleProps,
@@ -206,3 +208,37 @@ export const DashboardAction = ({ children }: DashboardActionProps): React.JSX.E
206
208
  <Box sx={{ display: 'inline-flex' }}>{children}</Box>
207
209
  );
208
210
  DashboardAction.displayName = 'Dashboard.Action';
211
+
212
+ /**
213
+ * The header's actions, declared as a LIST — `<Dashboard.Action>`'s plural.
214
+ *
215
+ * `<Dashboard.Action>` is a slot: it renders whatever you hand it, once per
216
+ * action, and a page with five of them draws five equally-loud buttons. That is
217
+ * the right primitive for one button and the wrong one for five, and the pages
218
+ * here that grew a fifth action all grew it the same way — by adding a fifth
219
+ * slot, because the slot was the only thing on offer.
220
+ *
221
+ * This part answers the question the slot cannot: given N actions, how many
222
+ * belong on the bar? See {@link HeaderActions} for the rule (0 ⇒ nothing,
223
+ * 1 ⇒ a button, n ⇒ a button and a menu of the rest).
224
+ *
225
+ * Both stay. A header still composes `<Dashboard.Action>` for the one control
226
+ * that is not an action at all — a link, a toggle, a status pill — and reaches
227
+ * for this when it has actions to rank.
228
+ */
229
+ export const DashboardActions = ({
230
+ actions,
231
+ moreLabel,
232
+ collapseBelow,
233
+ }: DashboardActionsProps): React.JSX.Element => {
234
+ const { testIdPrefix } = useDashboardContext();
235
+ return (
236
+ <HeaderActions
237
+ actions={actions}
238
+ moreLabel={moreLabel}
239
+ collapseBelow={collapseBelow}
240
+ testIdPrefix={`${testIdPrefix}-actions`}
241
+ />
242
+ );
243
+ };
244
+ DashboardActions.displayName = 'Dashboard.Actions';
@@ -4,6 +4,7 @@ export { DashboardContext, useDashboardContext } from './DashboardContext';
4
4
  export type { DashboardContextValue } from './DashboardContext';
5
5
  export type {
6
6
  DashboardActionProps,
7
+ DashboardActionsProps,
7
8
  DashboardBodyProps,
8
9
  DashboardBreadcrumbItem,
9
10
  DashboardBreadcrumbProps,