material-plus-ui 1.3.1 → 1.5.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 (261) hide show
  1. package/.fix.py +92 -0
  2. package/README.md +2 -2
  3. package/dist/components/alert/MPAlert.d.ts +26 -0
  4. package/dist/components/alert/MPAlert.js +1 -1
  5. package/dist/components/alert/index.d.ts +1 -1
  6. package/dist/components/animate-marquee/MPAnimateMarquee.js +1 -1
  7. package/dist/components/avatar/MPAvatar.js +1 -1
  8. package/dist/components/avatar-group/MPAvatarGroup.d.ts +74 -0
  9. package/dist/components/avatar-group/MPAvatarGroup.js +2 -0
  10. package/dist/components/avatar-group/index.d.ts +2 -0
  11. package/dist/components/avatar-group/index.js +1 -0
  12. package/dist/components/breadcrumb/MPBreadcrumb.d.ts +10 -4
  13. package/dist/components/breadcrumb/MPBreadcrumb.js +1 -1
  14. package/dist/components/button/MPButton.js +1 -1
  15. package/dist/components/button-group/MPButtonGroup.d.ts +9 -0
  16. package/dist/components/button-group/MPButtonGroup.js +1 -1
  17. package/dist/components/carousel/MPCarousel.d.ts +12 -7
  18. package/dist/components/carousel/MPCarousel.js +1 -1
  19. package/dist/components/chat-bubble/MPChatBubble.d.ts +15 -2
  20. package/dist/components/chat-bubble/MPChatBubble.js +1 -1
  21. package/dist/components/checkbox/MPCheckbox.d.ts +6 -0
  22. package/dist/components/checkbox/MPCheckbox.js +1 -1
  23. package/dist/components/color-picker/MPColorPicker.d.ts +20 -17
  24. package/dist/components/color-picker/MPColorPicker.js +1 -1
  25. package/dist/components/combobox/MPCombobox.d.ts +22 -4
  26. package/dist/components/combobox/MPCombobox.js +1 -1
  27. package/dist/components/command-palette/MPCommandPalette.d.ts +132 -0
  28. package/dist/components/command-palette/MPCommandPalette.js +2 -0
  29. package/dist/components/command-palette/index.d.ts +2 -0
  30. package/dist/components/command-palette/index.js +1 -0
  31. package/dist/components/container/MPContainer.js +1 -1
  32. package/dist/components/date-time-picker/MPDateTimePicker.d.ts +5 -0
  33. package/dist/components/dialog/MPDialog.js +1 -1
  34. package/dist/components/divider/MPDivider.js +1 -1
  35. package/dist/components/drawer/MPDrawer.js +1 -1
  36. package/dist/components/fieldset/MPFieldset.d.ts +52 -0
  37. package/dist/components/fieldset/MPFieldset.js +2 -0
  38. package/dist/components/fieldset/index.d.ts +2 -0
  39. package/dist/components/fieldset/index.js +1 -0
  40. package/dist/components/file-picker/MPFilePicker.d.ts +10 -3
  41. package/dist/components/file-picker/MPFilePicker.js +1 -1
  42. package/dist/components/floating-action-button/MPFloatingActionButton.js +1 -1
  43. package/dist/components/footer/MPFooter.d.ts +94 -0
  44. package/dist/components/footer/MPFooter.js +2 -0
  45. package/dist/components/footer/index.d.ts +2 -0
  46. package/dist/components/footer/index.js +1 -0
  47. package/dist/components/form/MPForm.d.ts +73 -0
  48. package/dist/components/form/MPForm.js +2 -0
  49. package/dist/components/form/index.d.ts +2 -0
  50. package/dist/components/form/index.js +1 -0
  51. package/dist/components/header/MPHeader.d.ts +122 -0
  52. package/dist/components/header/MPHeader.js +2 -0
  53. package/dist/components/header/index.d.ts +2 -0
  54. package/dist/components/header/index.js +1 -0
  55. package/dist/components/highlight/MPHighlight.d.ts +7 -0
  56. package/dist/components/menu/MPMenu.d.ts +4 -2
  57. package/dist/components/menu/MPMenu.js +1 -1
  58. package/dist/components/menubar/MPMenubar.d.ts +89 -0
  59. package/dist/components/menubar/MPMenubar.js +2 -0
  60. package/dist/components/menubar/index.d.ts +2 -0
  61. package/dist/components/menubar/index.js +1 -0
  62. package/dist/components/navigation-menu/MPNavigationMenu.d.ts +158 -0
  63. package/dist/components/navigation-menu/MPNavigationMenu.js +2 -0
  64. package/dist/components/navigation-menu/index.d.ts +2 -0
  65. package/dist/components/navigation-menu/index.js +1 -0
  66. package/dist/components/number-field/MPNumberField.d.ts +19 -4
  67. package/dist/components/number-field/MPNumberField.js +1 -1
  68. package/dist/components/overlay/MPOverlay.d.ts +8 -2
  69. package/dist/components/overlay/MPOverlay.js +1 -1
  70. package/dist/components/page-layout/MPPageLayout.d.ts +145 -0
  71. package/dist/components/page-layout/MPPageLayout.js +2 -0
  72. package/dist/components/page-layout/index.d.ts +2 -0
  73. package/dist/components/page-layout/index.js +1 -0
  74. package/dist/components/panes/MPPanes.js +1 -1
  75. package/dist/components/popover/MPPopover.js +1 -1
  76. package/dist/components/progress-box/MPProgressBox.js +1 -1
  77. package/dist/components/progress-circular/MPProgressCircular.js +1 -1
  78. package/dist/components/progress-linear/MPProgressLinear.js +1 -1
  79. package/dist/components/radio-group/MPRadioGroup.d.ts +12 -0
  80. package/dist/components/radio-group/MPRadioGroup.js +1 -1
  81. package/dist/components/segmented-button/MPSegmentedButton.d.ts +7 -0
  82. package/dist/components/segmented-button/MPSegmentedButton.js +1 -1
  83. package/dist/components/select/MPSelect.d.ts +19 -1
  84. package/dist/components/select/MPSelect.js +1 -1
  85. package/dist/components/shortcut/MPShortcut.js +1 -1
  86. package/dist/components/sidebar/MPSidebar.d.ts +160 -0
  87. package/dist/components/sidebar/MPSidebar.js +2 -0
  88. package/dist/components/sidebar/MPSidebarTrigger.d.ts +45 -0
  89. package/dist/components/sidebar/MPSidebarTrigger.js +2 -0
  90. package/dist/components/sidebar/index.d.ts +4 -0
  91. package/dist/components/sidebar/index.js +1 -0
  92. package/dist/components/skeleton/MPSkeleton.js +1 -1
  93. package/dist/components/slider/MPSlider.d.ts +6 -0
  94. package/dist/components/slider/MPSlider.js +1 -1
  95. package/dist/components/snackbar/MPSnackbar.js +1 -1
  96. package/dist/components/switch/MPSwitch.d.ts +6 -0
  97. package/dist/components/switch/MPSwitch.js +1 -1
  98. package/dist/components/table/MPTable.d.ts +27 -5
  99. package/dist/components/table/MPTable.js +1 -1
  100. package/dist/components/text-field/MPTextField.d.ts +21 -2
  101. package/dist/components/text-field/MPTextField.js +1 -1
  102. package/dist/components/text-link/MPTextLink.d.ts +7 -1
  103. package/dist/components/text-link/MPTextLink.js +1 -1
  104. package/dist/components/time-picker/MPTimePicker.d.ts +4 -0
  105. package/dist/components/toggle/MPToggle.d.ts +72 -0
  106. package/dist/components/toggle/MPToggle.js +2 -0
  107. package/dist/components/toggle/index.d.ts +2 -0
  108. package/dist/components/toggle/index.js +1 -0
  109. package/dist/components/toggle-group/MPToggleGroup.d.ts +74 -0
  110. package/dist/components/toggle-group/MPToggleGroup.js +2 -0
  111. package/dist/components/toggle-group/index.d.ts +2 -0
  112. package/dist/components/toggle-group/index.js +1 -0
  113. package/dist/components/tooltip/MPTooltip.js +1 -1
  114. package/dist/components/transfer/MPTransfer.d.ts +98 -0
  115. package/dist/components/transfer/MPTransfer.js +2 -0
  116. package/dist/components/transfer/index.d.ts +2 -0
  117. package/dist/components/transfer/index.js +1 -0
  118. package/dist/constants/glyphs.d.ts +10 -0
  119. package/dist/constants/glyphs.js +1 -1
  120. package/dist/constants/icons.d.ts +1 -0
  121. package/dist/constants/icons.js +1 -1
  122. package/dist/index.d.ts +13 -0
  123. package/dist/index.js +1 -1
  124. package/dist/internal/Calendar.js +1 -1
  125. package/dist/internal/FieldOutline.js +1 -1
  126. package/dist/internal/SupportingText.d.ts +1 -1
  127. package/dist/internal/SupportingText.js +1 -1
  128. package/dist/internal/animate.d.ts +0 -17
  129. package/dist/internal/animate.js +1 -1
  130. package/dist/internal/avatar-group.d.ts +22 -0
  131. package/dist/internal/avatar-group.js +2 -0
  132. package/dist/internal/button-group.d.ts +20 -1
  133. package/dist/internal/button-group.js +1 -1
  134. package/dist/internal/color.d.ts +0 -5
  135. package/dist/internal/color.js +1 -1
  136. package/dist/internal/date.js +1 -1
  137. package/dist/internal/i18n.d.ts +201 -4
  138. package/dist/internal/keys.d.ts +72 -0
  139. package/dist/internal/keys.js +2 -0
  140. package/dist/internal/length.d.ts +42 -0
  141. package/dist/internal/length.js +1 -0
  142. package/dist/internal/link.d.ts +44 -0
  143. package/dist/internal/link.js +1 -0
  144. package/dist/internal/locale.d.ts +20 -1
  145. package/dist/internal/locale.js +1 -1
  146. package/dist/internal/messages/breadcrumb.d.ts +3 -0
  147. package/dist/internal/messages/breadcrumb.js +1 -0
  148. package/dist/internal/messages/carousel.d.ts +3 -0
  149. package/dist/internal/messages/carousel.js +1 -0
  150. package/dist/internal/messages/color-picker.d.ts +3 -0
  151. package/dist/internal/messages/color-picker.js +1 -0
  152. package/dist/internal/messages/combobox.d.ts +3 -0
  153. package/dist/internal/messages/combobox.js +1 -0
  154. package/dist/internal/messages/command.d.ts +3 -0
  155. package/dist/internal/messages/command.js +1 -0
  156. package/dist/internal/messages/file-picker.d.ts +3 -0
  157. package/dist/internal/messages/file-picker.js +1 -0
  158. package/dist/internal/messages/layout.d.ts +3 -0
  159. package/dist/internal/messages/layout.js +1 -0
  160. package/dist/internal/messages/number-field.d.ts +3 -0
  161. package/dist/internal/messages/number-field.js +1 -0
  162. package/dist/internal/messages/overlay.d.ts +3 -0
  163. package/dist/internal/messages/overlay.js +1 -0
  164. package/dist/internal/messages/table.d.ts +3 -0
  165. package/dist/internal/messages/table.js +1 -0
  166. package/dist/internal/messages/text-link.d.ts +3 -0
  167. package/dist/internal/messages/text-link.js +1 -0
  168. package/dist/internal/messages/transfer.d.ts +3 -0
  169. package/dist/internal/messages/transfer.js +1 -0
  170. package/dist/internal/page-layout.d.ts +182 -0
  171. package/dist/internal/page-layout.js +2 -0
  172. package/dist/internal/scale.d.ts +17 -0
  173. package/dist/internal/scale.js +1 -1
  174. package/dist/locales/ar.js +1 -1
  175. package/dist/locales/de.js +1 -1
  176. package/dist/locales/es.js +1 -1
  177. package/dist/locales/fr.js +1 -1
  178. package/dist/locales/hi.js +1 -1
  179. package/dist/locales/id.js +1 -1
  180. package/dist/locales/it.js +1 -1
  181. package/dist/locales/ja.js +1 -1
  182. package/dist/locales/ko.js +1 -1
  183. package/dist/locales/nl.js +1 -1
  184. package/dist/locales/pl.js +1 -1
  185. package/dist/locales/pt.js +1 -1
  186. package/dist/locales/ru.js +1 -1
  187. package/dist/locales/th.js +1 -1
  188. package/dist/locales/tr.js +1 -1
  189. package/dist/locales/vi.js +1 -1
  190. package/dist/locales/zh-hans.js +1 -1
  191. package/dist/locales/zh-hant.js +1 -1
  192. package/dist/styles/accordion.css +1 -1
  193. package/dist/styles/alert.css +1 -1
  194. package/dist/styles/avatar-group.css +2 -0
  195. package/dist/styles/avatar.css +1 -1
  196. package/dist/styles/badge.css +1 -1
  197. package/dist/styles/blockquote.css +1 -1
  198. package/dist/styles/bottom-navigation.css +1 -1
  199. package/dist/styles/box.css +1 -1
  200. package/dist/styles/breadcrumb.css +1 -1
  201. package/dist/styles/button-group.css +1 -1
  202. package/dist/styles/button.css +1 -1
  203. package/dist/styles/card.css +1 -1
  204. package/dist/styles/carousel.css +1 -1
  205. package/dist/styles/chat-bubble.css +1 -1
  206. package/dist/styles/checkbox.css +1 -1
  207. package/dist/styles/chip.css +1 -1
  208. package/dist/styles/collapsible.css +1 -1
  209. package/dist/styles/color-picker.css +1 -1
  210. package/dist/styles/combobox.css +1 -1
  211. package/dist/styles/command-palette.css +2 -0
  212. package/dist/styles/date-picker.css +1 -1
  213. package/dist/styles/date-range-picker.css +1 -1
  214. package/dist/styles/date-time-picker.css +1 -1
  215. package/dist/styles/dialog.css +1 -1
  216. package/dist/styles/divider.css +1 -1
  217. package/dist/styles/drawer.css +1 -1
  218. package/dist/styles/empty.css +1 -1
  219. package/dist/styles/fieldset.css +2 -0
  220. package/dist/styles/file-picker.css +1 -1
  221. package/dist/styles/floating-action-button.css +1 -1
  222. package/dist/styles/footer.css +2 -0
  223. package/dist/styles/form.css +2 -0
  224. package/dist/styles/header.css +2 -0
  225. package/dist/styles/highlight.css +1 -1
  226. package/dist/styles/icon-button.css +1 -1
  227. package/dist/styles/list.css +1 -1
  228. package/dist/styles/locale.css +1 -1
  229. package/dist/styles/menu.css +1 -1
  230. package/dist/styles/menubar.css +2 -0
  231. package/dist/styles/navigation-menu.css +2 -0
  232. package/dist/styles/number-field.css +1 -1
  233. package/dist/styles/otp-field.css +1 -1
  234. package/dist/styles/overlay.css +1 -1
  235. package/dist/styles/page-layout.css +2 -0
  236. package/dist/styles/pagination.css +1 -1
  237. package/dist/styles/panes.css +1 -1
  238. package/dist/styles/pill.css +1 -1
  239. package/dist/styles/popover.css +1 -1
  240. package/dist/styles/progress-box.css +1 -1
  241. package/dist/styles/progress-circular.css +1 -1
  242. package/dist/styles/progress-linear.css +1 -1
  243. package/dist/styles/radio-group.css +1 -1
  244. package/dist/styles/segmented-button.css +1 -1
  245. package/dist/styles/select.css +1 -1
  246. package/dist/styles/sidebar.css +2 -0
  247. package/dist/styles/skeleton.css +1 -1
  248. package/dist/styles/slider.css +1 -1
  249. package/dist/styles/spoiler.css +1 -1
  250. package/dist/styles/switch.css +1 -1
  251. package/dist/styles/table.css +1 -1
  252. package/dist/styles/tabs.css +1 -1
  253. package/dist/styles/text-field.css +1 -1
  254. package/dist/styles/text-link.css +1 -1
  255. package/dist/styles/time-picker.css +1 -1
  256. package/dist/styles/timeline.css +1 -1
  257. package/dist/styles/toggle-group.css +2 -0
  258. package/dist/styles/toggle.css +2 -0
  259. package/dist/styles/transfer.css +2 -0
  260. package/dist/styles.css +1 -1
  261. package/package.json +2 -2
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{jsx as t,jsxs as e}from"react/jsx-runtime";import*as a from"react";import{Button as o}from"@base-ui/react/button";import{accentSlots as n}from"../../internal/accent.js";import{MPStateLayer as i}from"../../internal/StateLayer.js";import{hasContent as s}from"../../internal/scale.js";const r={filled:"bg-(--_mp-accent) text-(--_mp-on-accent)",tonal:"bg-(--_mp-accent-container) text-(--_mp-on-accent-container)",elevated:"bg-mp-surface-container-high text-(--_mp-accent)"},m={xs:"h-10",sm:"h-12",md:"h-14",lg:"h-18",xl:"h-24"},l={xs:"min-w-10 gap-0 px-0",sm:"min-w-12 gap-0 px-0",md:"min-w-14 gap-0 px-0",lg:"min-w-18 gap-0 px-0",xl:"min-w-24 gap-0 px-0"},p={xs:"rounded-mp-md",sm:"rounded-mp-lg",md:"rounded-mp-lg",lg:"rounded-mp-xl",xl:"rounded-mp-xl"},d={xs:24,sm:24,md:24,lg:30,xl:36},f={xs:"text-mp-label-large",sm:"text-mp-label-large",md:"text-mp-label-large",lg:"text-mp-title-medium",xl:"text-mp-title-medium"},c={xs:"min-w-16 gap-1.5 px-3",sm:"min-w-18 gap-2 px-4",md:"min-w-20 gap-2 px-4",lg:"min-w-24 gap-2.5 px-5",xl:"min-w-28 gap-3 px-6"},x={absolute:"absolute z-30",sticky:"sticky z-30",fixed:"fixed z-40"},u={"top-start":"top-(--_mp-fab-offset) start-(--_mp-fab-offset)","top-end":"top-(--_mp-fab-offset) end-(--_mp-fab-offset)","bottom-start":"bottom-(--_mp-fab-offset) start-(--_mp-fab-offset)","bottom-end":"bottom-(--_mp-fab-offset) end-(--_mp-fab-offset)"};export const MPFloatingActionButton=/*@__PURE__*/a.forwardRef(function({icon:a,label:b,extended:g=!1,variant:h="tonal",color:w="primary",size:y="md",position:_="fixed",corner:j="bottom-end",offset:v=16,disabled:k=!1,type:z="button",className:N,style:$,...B},A){return e(o,{ref:A,type:z,disabled:k,"aria-label":b,"data-mp-size":y,"data-mp-variant":h,className:["mp-fab group inline-flex shrink-0 items-center justify-center","box-border overflow-hidden align-middle whitespace-nowrap select-none","cursor-pointer appearance-none font-[inherit]","outline-mp-secondary focus-visible:outline-2 focus-visible:outline-offset-2","focus-visible:outline-solid outline-none","transition-[background-color,box-shadow,color,min-width,padding,gap]","duration-(--mp-sys-motion-duration-short4) ease-mp-standard",p[y],m[y],f[y],g?c[y]:l[y],k?"bg-mp-on-surface/12 text-mp-on-surface/38 cursor-default shadow-none":`${r[h]} shadow-mp-3`,"static"===_?"relative":`${x[_]} ${u[j]}`,N??""].filter(Boolean).join(" "),style:{...n(w),"--_mp-fab-offset":"number"==typeof v?`${v}px`:v,...$},...B,children:[k?null:t(i,{}),s(a)?t("span",{className:"relative flex shrink-0 items-center justify-center",style:{width:d[y],height:d[y]},children:a}):null,t("span",{className:["relative grid transition-[grid-template-columns]","duration-(--mp-sys-motion-duration-short4) ease-mp-standard",g?"grid-cols-[1fr]":"grid-cols-[0fr]"].join(" "),children:t("span",{className:"min-w-0 truncate",children:b})})]})});
2
+ import{jsx as t,jsxs as e}from"react/jsx-runtime";import*as a from"react";import{Button as n}from"@base-ui/react/button";import{accentSlots as o}from"../../internal/accent.js";import{cssLength as i}from"../../internal/length.js";import{MPStateLayer as s}from"../../internal/StateLayer.js";import{hasContent as r}from"../../internal/scale.js";const m={filled:"bg-(--_mp-accent) text-(--_mp-on-accent)",tonal:"bg-(--_mp-accent-container) text-(--_mp-on-accent-container)",elevated:"bg-mp-surface-container-high text-(--_mp-accent)"},l={xs:"h-10",sm:"h-12",md:"h-14",lg:"h-18",xl:"h-24"},p={xs:"min-w-10 gap-0 px-0",sm:"min-w-12 gap-0 px-0",md:"min-w-14 gap-0 px-0",lg:"min-w-18 gap-0 px-0",xl:"min-w-24 gap-0 px-0"},d={xs:"rounded-mp-md",sm:"rounded-mp-lg",md:"rounded-mp-lg",lg:"rounded-mp-xl",xl:"rounded-mp-xl"},f={xs:24,sm:24,md:24,lg:30,xl:36},c={xs:"text-mp-label-large",sm:"text-mp-label-large",md:"text-mp-label-large",lg:"text-mp-title-medium",xl:"text-mp-title-medium"},x={xs:"min-w-16 gap-1.5 px-3",sm:"min-w-18 gap-2 px-4",md:"min-w-20 gap-2 px-4",lg:"min-w-24 gap-2.5 px-5",xl:"min-w-28 gap-3 px-6"},u={absolute:"absolute z-30",sticky:"sticky z-30",fixed:"fixed z-40"},b={"top-start":"top-(--_mp-fab-offset) start-(--_mp-fab-offset)","top-end":"top-(--_mp-fab-offset) end-(--_mp-fab-offset)","bottom-start":"bottom-(--_mp-fab-offset) start-(--_mp-fab-offset)","bottom-end":"bottom-(--_mp-fab-offset) end-(--_mp-fab-offset)"};export const MPFloatingActionButton=/*@__PURE__*/a.forwardRef(function({icon:a,label:g,extended:h=!1,variant:w="tonal",color:y="primary",size:_="md",position:j="fixed",corner:v="bottom-end",offset:k=16,disabled:z=!1,type:N="button",className:B,style:$,...A},F){return e(n,{ref:F,type:N,disabled:z,"aria-label":g,"data-mp-size":_,"data-mp-variant":w,className:["mp-fab group inline-flex shrink-0 items-center justify-center","box-border overflow-hidden align-middle whitespace-nowrap select-none","cursor-pointer appearance-none font-[inherit]","outline-mp-secondary focus-visible:outline-2 focus-visible:outline-offset-2","focus-visible:outline-solid outline-none","transition-[background-color,box-shadow,color,min-width,padding,gap]","duration-(--mp-sys-motion-duration-short4) ease-mp-standard",d[_],l[_],c[_],h?x[_]:p[_],z?"bg-mp-on-surface/12 text-mp-on-surface/38 cursor-default shadow-none":`${m[w]} shadow-mp-3`,"static"===j?"relative":`${u[j]} ${b[v]}`,B??""].filter(Boolean).join(" "),style:{...o(y),"--_mp-fab-offset":i(k),...$},...A,children:[z?null:t(s,{}),r(a)?t("span",{className:"relative flex shrink-0 items-center justify-center",style:{width:f[_],height:f[_]},children:a}):null,t("span",{className:["relative grid transition-[grid-template-columns]","duration-(--mp-sys-motion-duration-short4) ease-mp-standard",h?"grid-cols-[1fr]":"grid-cols-[0fr]"].join(" "),children:t("span",{className:"min-w-0 truncate",children:g})})]})});
@@ -0,0 +1,94 @@
1
+ import * as React from 'react';
2
+ import { useRender } from '@base-ui/react/use-render';
3
+ import type { MPPosition, MPSize, MPVariant } from '../../types.js';
4
+ export interface MPFooterProps extends Omit<React.ComponentPropsWithoutRef<'footer'>, 'title'> {
5
+ /**
6
+ * How the sheet sits in the page's scroll.
7
+ *
8
+ * `static` — the default, and the opposite of [MPHeader](./header)'s — is what
9
+ * a footer *is*: the thing at the end of the document, reached by scrolling to
10
+ * it. `sticky` and `fixed` are for the bar that has to stay in reach — a
11
+ * form's save row, a cookie notice — and an [MPPageLayout](./page-layout)
12
+ * reserves the height a `fixed` one takes out of the flow.
13
+ * @default 'static'
14
+ */
15
+ position?: MPPosition;
16
+ /**
17
+ * How much surface the sheet paints, on the **container** ladder — a footer is
18
+ * never dyed, because what sits on it arrives with colours of its own.
19
+ *
20
+ * `outlined` is the default here and `tonal` is [MPHeader](./header)'s,
21
+ * because the two sit against different things. A header is over content that
22
+ * is passing underneath it and needs a tone of its own to stay legible; a
23
+ * footer has the end of the document above it and nothing below, so the
24
+ * hairline is the whole of what says the document ended.
25
+ * @default 'outlined'
26
+ */
27
+ variant?: MPVariant;
28
+ /**
29
+ * The sheet's scale — its gutter and the air above and below its content. As
30
+ * on [MPBox](./box), `size` here is the size of the *sheet*: it sets no height
31
+ * and no type scale.
32
+ * @default 'md'
33
+ */
34
+ size?: MPSize;
35
+ /**
36
+ * Holds the content to a measure and centres it while the sheet itself still
37
+ * spans the window. The same ladder [MPContainer](./container)'s `maxWidth`
38
+ * uses.
39
+ * @default 'none'
40
+ */
41
+ maxWidth?: MPSize | 'none';
42
+ /**
43
+ * The gutter, and the air above and below.
44
+ * @default true
45
+ */
46
+ padded?: boolean;
47
+ /**
48
+ * The name the region is announced by. Worth writing when a page has more than
49
+ * one `<footer>` in it — an article's own and the site's.
50
+ */
51
+ label?: string;
52
+ /**
53
+ * Renders something other than a `<footer>`. Base UI's own escape hatch, and
54
+ * rarely what you want: at the top level of a document that tag is the
55
+ * `contentinfo` landmark, and it is what says "this is the site's own
56
+ * information" rather than "this is more of the article".
57
+ */
58
+ render?: useRender.RenderProp;
59
+ /**
60
+ * Everything in it.
61
+ *
62
+ * A footer's content is four columns of links on one site and a single line on
63
+ * the next, all of it the caller's — which is why this component has slots for
64
+ * nothing and room for anything.
65
+ */
66
+ children?: React.ReactNode;
67
+ }
68
+ /**
69
+ * The sheet at the end of a page.
70
+ *
71
+ * A real `<footer>`, which is the whole reason it is a component rather than a
72
+ * div: at the top level of a document that tag is the `contentinfo` landmark —
73
+ * the region a screen reader offers as "the site's own information", and the one
74
+ * a search engine reads the copyright, the address and the site map out of.
75
+ *
76
+ * ## Why it has no slots, and [MPHeader](./header) does
77
+ *
78
+ * Because a header's three regions are a fixed arrangement worth writing once,
79
+ * and a footer's content is not an arrangement at all. Four columns of links on
80
+ * one site, a copyright line on the next, a language picker and a row of logos
81
+ * on the third. A component that guessed would be a component every second site
82
+ * had to fight.
83
+ *
84
+ * What it decides instead is the **sheet**: the surface, the gutter, the measure,
85
+ * and whether it stays in reach. Everything above that is an
86
+ * [MPGrid](./grid) or an [MPContainer](./container) the caller puts inside it.
87
+ *
88
+ * ## Inside a layout, and outside one
89
+ *
90
+ * Inside an [MPPageLayout](./page-layout) it registers itself, so a `fixed`
91
+ * footer's height is reserved rather than sitting on top of the last paragraph.
92
+ * Outside one it is simply a sheet.
93
+ */
94
+ export declare const MPFooter: React.ForwardRefExoticComponent<MPFooterProps & React.RefAttributes<HTMLElement>>;
@@ -0,0 +1,2 @@
1
+ "use client";
2
+ import{jsx as e}from"react/jsx-runtime";import*as t from"react";import{useRender as o}from"@base-ui/react/use-render";import{BAR_SURFACE as r,MPPageLayoutContext as a}from"../../internal/page-layout.js";import{MEASURE as i,SHEET_PAD_X as n,SHEET_PAD_Y as s}from"../../internal/scale.js";const l={static:"",absolute:"absolute inset-x-0 bottom-0 z-30",sticky:"sticky bottom-0 z-30",fixed:"fixed inset-x-0 bottom-0 z-40"};export const MPFooter=/*@__PURE__*/t.forwardRef(function({position:m="static",variant:c="outlined",size:d="md",maxWidth:f="none",padded:u=!0,label:p,render:b,className:x,children:j,...z},h){const{register:v}=t.useContext(a),w=t.useCallback(e=>{v("footer",e),"function"==typeof h?h(e):h&&(h.current=e)},[v,h]);return o({render:b??e("footer",{}),ref:w,props:{"aria-label":p,"data-mp-size":d,"data-mp-variant":c,className:["mp-footer text-mp-on-surface box-border w-full min-w-0",r[c],"outlined"===c?"border-mp-outline-variant border-t":"",l[m],x??""].filter(Boolean).join(" "),children:e("div",{className:["mp-footer__inner w-full",u?`${n[d]} ${s[d]}`:"","none"===f?"":`${i[f]} mx-auto`].filter(Boolean).join(" "),children:j}),...z}})});
@@ -0,0 +1,2 @@
1
+ export { MPFooter } from './MPFooter.js';
2
+ export type { MPFooterProps } from './MPFooter.js';
@@ -0,0 +1 @@
1
+ export{MPFooter}from"./MPFooter.js";
@@ -0,0 +1,73 @@
1
+ import * as React from 'react';
2
+ import type { MPSize } from '../../types.js';
3
+ /**
4
+ * When a field decides whether it is valid.
5
+ *
6
+ * Base UI's own three, under Base UI's own spelling. This is one of the few
7
+ * places the library does *not* invent a word of its own: `validationMode` is
8
+ * what a caller will read everywhere else, and a nicer synonym would only be a
9
+ * word they had to translate back.
10
+ */
11
+ export type MPFormValidationMode = 'onSubmit' | 'onBlur' | 'onChange';
12
+ /** Errors that came from somewhere else, keyed by the field's `name`. */
13
+ export type MPFormErrors = Record<string, string | string[]>;
14
+ export interface MPFormProps extends Omit<React.ComponentPropsWithoutRef<'form'>, 'onSubmit'> {
15
+ /**
16
+ * When a field validates.
17
+ *
18
+ * - `onSubmit` — on submit, and on every change afterwards. The default, and
19
+ * the only one that does not tell somebody their email address is wrong
20
+ * while they are still typing it.
21
+ * - `onBlur` — when a field loses focus.
22
+ * - `onChange` — on every keystroke.
23
+ * @default 'onSubmit'
24
+ */
25
+ validationMode?: MPFormValidationMode;
26
+ /**
27
+ * Errors from outside the browser's own validation — a server, a form action,
28
+ * a schema — keyed by the `name` of the field each belongs to.
29
+ *
30
+ * They are shown **on the field**, and cleared as soon as that field changes.
31
+ */
32
+ errors?: MPFormErrors;
33
+ /**
34
+ * Called on a valid submit, with the form's values. The native submit event is
35
+ * prevented, so nothing navigates.
36
+ */
37
+ onSubmit?: (values: Record<string, unknown>) => void;
38
+ /**
39
+ * The gap between the form's children. A form is a stack, and this is which
40
+ * rung of the [ladder](../../design/prop-conventions#size) it stacks on.
41
+ * @default 'md'
42
+ */
43
+ size?: MPSize;
44
+ children?: React.ReactNode;
45
+ }
46
+ /**
47
+ * A `<form>` that knows which of its fields is wrong.
48
+ *
49
+ * On its own, a page of [MPTextField](./text-field)s validates one field at a
50
+ * time, and a failed submit leaves the reader to go and find the red one. What
51
+ * this adds is the part that has to be owned **above** the fields: a submit
52
+ * collects every field's validity at once, focus lands on the first one that
53
+ * failed, and `errors` puts a server's answer back on the field it belongs to
54
+ * rather than in a banner at the top of the page.
55
+ *
56
+ * ## It is not a form library
57
+ *
58
+ * There is no schema here, no resolver and no field array. A project that wants
59
+ * those keeps the one it already has and hands the result to `errors`, which is
60
+ * the seam this is built around — and it is a seam rather than an integration
61
+ * precisely because every one of those libraries can produce
62
+ * `{ [name]: message }`.
63
+ *
64
+ * ## Why it lays its children out at all
65
+ *
66
+ * Because a form is a **stack**, and a stack with no gap is a stack of fields
67
+ * touching. The gap is the only visual decision here: no surface, no padding, no
68
+ * measure. Those belong to an [MPCard](../layout/card) or an
69
+ * [MPContainer](../layout/container) around it, for the reason a container gives
70
+ * — the thing that decides the shape of a page should not also be the thing that
71
+ * submits it.
72
+ */
73
+ export declare const MPForm: React.ForwardRefExoticComponent<MPFormProps & React.RefAttributes<HTMLFormElement>>;
@@ -0,0 +1,2 @@
1
+ "use client";
2
+ import{jsx as r}from"react/jsx-runtime";import*as o from"react";import{Form as e}from"@base-ui/react/form";import{SHEET_GAP as i}from"../../internal/scale.js";export const MPForm=/*@__PURE__*/o.forwardRef(function({validationMode:o="onSubmit",errors:m,onSubmit:a,size:t="md",className:n,children:s,...f},l){return r(e,{ref:l,validationMode:o,errors:m,onFormSubmit:r=>a?.(r),"data-mp-size":t,className:["mp-form flex flex-col",i[t],n??""].filter(Boolean).join(" "),...f,children:s})});
@@ -0,0 +1,2 @@
1
+ export { MPForm } from './MPForm.js';
2
+ export type { MPFormErrors, MPFormProps, MPFormValidationMode } from './MPForm.js';
@@ -0,0 +1 @@
1
+ export{MPForm}from"./MPForm.js";
@@ -0,0 +1,122 @@
1
+ import * as React from 'react';
2
+ import { useRender } from '@base-ui/react/use-render';
3
+ import type { MPAlign, MPPosition, MPSize, MPVariant } from '../../types.js';
4
+ export interface MPHeaderProps extends Omit<React.ComponentPropsWithoutRef<'header'>, 'title'> {
5
+ /**
6
+ * The leading slot: the mark, the product's name, the thing that is the same
7
+ * on every page — and, on a narrow window, the
8
+ * [MPSidebarTrigger](./sidebar#mpsidebartrigger) that goes ahead of it.
9
+ *
10
+ * A slot rather than the first of `children` because the three regions of a
11
+ * bar are laid out *against each other* — the middle can only be centred on
12
+ * the bar if the two ends are the component's to measure — and a caller
13
+ * writing three wrappers by hand is a caller whose header drifts from the next
14
+ * one.
15
+ */
16
+ brand?: React.ReactNode;
17
+ /**
18
+ * The trailing slot: the account menu, the theme switch, the call to action.
19
+ * Laid out end-aligned, so a row of icon buttons needs no wrapper of its own.
20
+ */
21
+ actions?: React.ReactNode;
22
+ /**
23
+ * Where the middle slot sits.
24
+ *
25
+ * `center` is MD3's own **center-aligned top app bar**, and it is centred on
26
+ * the *bar* rather than in the space left over: both ends are given equal
27
+ * shares, so the middle stays on the bar's midline however long the brand is.
28
+ * @default 'start'
29
+ */
30
+ align?: MPAlign;
31
+ /**
32
+ * How the bar sits in the page's scroll, spelled the way CSS spells it.
33
+ *
34
+ * `sticky` — the default — holds it against the top of the window once the
35
+ * page has scrolled to it, while leaving it in the flow so nothing has to be
36
+ * padded out of its way. `fixed` takes it out of the flow entirely, which an
37
+ * [MPPageLayout](./page-layout) answers by reserving its height. `static` lets
38
+ * it scroll away.
39
+ * @default 'sticky'
40
+ */
41
+ position?: MPPosition;
42
+ /**
43
+ * How much surface the bar paints, on the **container** ladder — the bar is
44
+ * never dyed, because what sits on it arrives with colours of its own.
45
+ *
46
+ * `tonal` is the default and is MD3's own scrolled top app bar:
47
+ * `surface-container` against the page's `surface`. `outlined` is the flat one
48
+ * — the page's own surface with a hairline where it ends — and `text` paints
49
+ * nothing at all, which is what a bar over a hero image wants.
50
+ * @default 'tonal'
51
+ */
52
+ variant?: MPVariant;
53
+ /**
54
+ * The bar's height floor, its gutter and the air between its slots.
55
+ *
56
+ * `md` is 64px, which is MD3's own small top app bar. It is a floor rather
57
+ * than a height: a bar whose middle slot wrapped onto a second line would
58
+ * otherwise clip it.
59
+ * @default 'md'
60
+ */
61
+ size?: MPSize;
62
+ /**
63
+ * Holds the row of slots to a measure and centres it while the sheet itself
64
+ * still spans the window. The same ladder [MPContainer](./container)'s
65
+ * `maxWidth` uses, so a header and the container under it line up on one edge.
66
+ * @default 'none'
67
+ */
68
+ maxWidth?: MPSize | 'none';
69
+ /**
70
+ * The gutter down each side of the row.
71
+ * @default true
72
+ */
73
+ padded?: boolean;
74
+ /**
75
+ * The name the bar is announced by. Worth writing when a page has more than
76
+ * one `<header>` in it — an article's own and the site's — because "banner"
77
+ * twice tells a reader which is which not at all.
78
+ */
79
+ label?: string;
80
+ /**
81
+ * Renders something other than a `<header>`. Base UI's own escape hatch, and
82
+ * rarely what you want: at the top level of a document that tag *is* the
83
+ * `banner` landmark, and it is what says so to a screen reader's landmark
84
+ * list, to a reader mode and to a crawler.
85
+ */
86
+ render?: useRender.RenderProp;
87
+ /** The middle slot: a row of navigation links, a search field, a headline. */
88
+ children?: React.ReactNode;
89
+ }
90
+ /**
91
+ * The bar across the top of a page. **MD3's top app bar**, with the site's own
92
+ * three regions on it.
93
+ *
94
+ * A real `<header>`, which is the whole reason it is a component rather than a
95
+ * row of divs: at the top level of a document that tag is the `banner` landmark,
96
+ * and it is what a screen reader's landmark list, a reader mode and a search
97
+ * engine's understanding of the page are built out of.
98
+ *
99
+ * The slots are props rather than compound sub-components, for
100
+ * [MPCard](./card)'s reason: the arrangement is fixed — brand, middle, actions —
101
+ * and what a caller wants to decide is what goes in each. That the middle can be
102
+ * centred on the bar's own midline is only possible *because* the ends are the
103
+ * component's to measure.
104
+ *
105
+ * ## Why there is no `divider`
106
+ *
107
+ * [MPBottomNavigation](./bottom-navigation) has one and this does not, and the
108
+ * difference is that this takes a `variant`. MD3 separates a bar from the
109
+ * content by **tone** — `surface-container` against `surface` — and the case a
110
+ * hairline exists for is the bar that paints the page's own surface. That bar is
111
+ * `variant="outlined"`, and the rule is what `outlined` *means* here: a
112
+ * container's outline is a hairline all the way round, and a bar has exactly one
113
+ * edge with anything on the other side of it.
114
+ *
115
+ * ## Inside a layout, and outside one
116
+ *
117
+ * Inside an [MPPageLayout](./page-layout) the bar registers itself, so a column
118
+ * that holds its place knows how far down the window to start and a `fixed` bar
119
+ * has its height reserved. Outside one it is simply a bar, and everything above
120
+ * still holds.
121
+ */
122
+ export declare const MPHeader: React.ForwardRefExoticComponent<MPHeaderProps & React.RefAttributes<HTMLElement>>;
@@ -0,0 +1,2 @@
1
+ "use client";
2
+ import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as a from"react";import{useRender as i}from"@base-ui/react/use-render";import{BAR_SURFACE as n,MPPageLayoutContext as r}from"../../internal/page-layout.js";import{hasContent as s,MEASURE as l,SHEET_PAD_X as m}from"../../internal/scale.js";const d={xs:"min-h-12",sm:"min-h-14",md:"min-h-16",lg:"min-h-20",xl:"min-h-24"},o={xs:"text-mp-title-small",sm:"text-mp-title-medium",md:"text-mp-title-large",lg:"text-mp-headline-small",xl:"text-mp-headline-medium"},c={xs:"gap-1.5",sm:"gap-2",md:"gap-3",lg:"gap-4",xl:"gap-5"},p={xs:"gap-3",sm:"gap-4",md:"gap-6",lg:"gap-8",xl:"gap-10"},x={static:"",absolute:"absolute inset-x-0 top-0 z-30",sticky:"sticky top-0 z-30",fixed:"fixed inset-x-0 top-0 z-40"},f={start:"shrink-0",center:"flex-1 basis-0",end:"shrink-0"},u={start:"flex min-w-0 flex-1 items-center justify-start",center:"flex min-w-0 shrink items-center justify-center",end:"flex min-w-0 flex-1 items-center justify-end"};export const MPHeader=/*@__PURE__*/a.forwardRef(function({brand:h,actions:g,align:b="start",position:j="sticky",variant:v="tonal",size:w="md",maxWidth:y="none",padded:N=!0,label:k,render:_,className:z,children:$,...B},C){const{register:H}=a.useContext(r),M=a.useCallback(e=>{H("header",e),"function"==typeof C?C(e):C&&(C.current=e)},[H,C]);return i({render:_??e("header",{}),ref:M,props:{"aria-label":k,"data-mp-size":w,"data-mp-variant":v,className:["mp-header text-mp-on-surface box-border w-full min-w-0",n[v],"outlined"===v?"border-mp-outline-variant border-b":"",x[j],z??""].filter(Boolean).join(" "),children:t("div",{className:["flex w-full items-center",d[w],p[w],N?m[w]:"","none"===y?"":`${l[y]} mx-auto`].filter(Boolean).join(" "),children:[s(h)?e("div",{className:["mp-header__brand flex min-w-0 items-center",f[b],c[w],o[w]].join(" "),children:h}):"center"===b?e("div",{"aria-hidden":"true",className:f[b]}):null,s($)?e("div",{className:`mp-header__middle ${u[b]} ${c[w]}`,children:$}):null,s(g)?e("div",{className:["mp-header__actions flex min-w-0 items-center justify-end",f[b],c[w]].join(" "),children:g}):"center"===b?e("div",{"aria-hidden":"true",className:f[b]}):null]}),...B}})});
@@ -0,0 +1,2 @@
1
+ export { MPHeader } from './MPHeader.js';
2
+ export type { MPHeaderProps } from './MPHeader.js';
@@ -0,0 +1 @@
1
+ export{MPHeader}from"./MPHeader.js";
@@ -19,6 +19,13 @@ export interface MPHighlightProps extends Omit<React.ComponentPropsWithoutRef<'s
19
19
  * letters of it. A `RegExp` is used as written, with the global flag forced on;
20
20
  * `caseSensitive` and `wholeWord` are ignored for it, because a regular
21
21
  * expression already says both of those things itself.
22
+ *
23
+ * Strings are escaped, so a search box's contents are safe to pass straight
24
+ * through however they are spelled. A `RegExp` is **not** — it is run as
25
+ * written, which is the point of accepting one. Building one out of text
26
+ * somebody else typed is a denial of service waiting for the input that
27
+ * backtracks; escape it into a string term instead, or keep the expression a
28
+ * literal in your own source.
22
29
  */
23
30
  query: string | string[] | RegExp;
24
31
  /**
@@ -133,6 +133,7 @@ export interface MPMenuGroupProps {
133
133
  label?: React.ReactNode;
134
134
  children?: React.ReactNode;
135
135
  className?: string;
136
+ style?: React.CSSProperties;
136
137
  }
137
138
  export interface MPMenuCheckboxItemProps extends Omit<MPMenuItemProps, 'href' | 'target' | 'startIcon' | 'onClick'> {
138
139
  checked?: boolean;
@@ -153,6 +154,7 @@ export interface MPMenuRadioGroupProps {
153
154
  disabled?: boolean;
154
155
  children?: React.ReactNode;
155
156
  className?: string;
157
+ style?: React.CSSProperties;
156
158
  }
157
159
  export interface MPMenuRadioItemProps extends Omit<MPMenuItemProps, 'href' | 'target' | 'startIcon' | 'onClick'> {
158
160
  /** What this row sets the group to. */
@@ -173,7 +175,7 @@ export declare function MPMenuItem({ onClick, href, target, rel, startIcon, endI
173
175
  /** A row that ticks. The tick lands in the column a `startIcon` would. */
174
176
  export declare function MPMenuCheckboxItem({ checked, defaultChecked, onCheckedChange, endIcon, shortcut, description, color, closeOnClick, disabled, label, children, className, style }: MPMenuCheckboxItemProps): React.JSX.Element;
175
177
  /** One choice out of a set. Wraps the rows that make up the set. */
176
- export declare function MPMenuRadioGroup({ value, defaultValue, onValueChange, disabled, children, className }: MPMenuRadioGroupProps): React.JSX.Element;
178
+ export declare function MPMenuRadioGroup({ value, defaultValue, onValueChange, disabled, children, className, style }: MPMenuRadioGroupProps): React.JSX.Element;
177
179
  /**
178
180
  * A row inside an `MPMenuRadioGroup`.
179
181
  *
@@ -183,7 +185,7 @@ export declare function MPMenuRadioGroup({ value, defaultValue, onValueChange, d
183
185
  */
184
186
  export declare function MPMenuRadioItem({ value, endIcon, shortcut, description, color, closeOnClick, disabled, label, children, className, style }: MPMenuRadioItemProps): React.JSX.Element;
185
187
  /** A named run of rows. The label is a heading, not a row — it cannot be picked. */
186
- export declare function MPMenuGroup({ label, children, className }: MPMenuGroupProps): React.JSX.Element;
188
+ export declare function MPMenuGroup({ label, children, className, style }: MPMenuGroupProps): React.JSX.Element;
187
189
  /** The hairline between two runs of rows. `outline-variant`, as MD3 draws it. */
188
190
  export declare function MPMenuSeparator({ className, ...props }: MPMenuSeparatorProps): React.JSX.Element;
189
191
  /**
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{jsx as e,jsxs as n}from"react/jsx-runtime";import*as t from"react";import{Menu as a}from"@base-ui/react/menu";import{ContextMenu as l}from"@base-ui/react/context-menu";import{MPIcon as r}from"../icon/MPIcon.js";import{CheckIcon as o,ChevronRightIcon as s}from"../../constants/icons.js";import{MPMenuContext as i}from"../../internal/menu.js";import{accentSlots as c}from"../../internal/accent.js";import{MPStateLayer as d}from"../../internal/StateLayer.js";import{CONTROL_ICON as m,META_TEXT as u,hasContent as p}from"../../internal/scale.js";import{FADE as h,PORTAL_LAYER as f}from"../../internal/surface.js";const x=/*@__PURE__*/["mp-menu__popup rounded-mp-xs shadow-mp-2 bg-mp-surface-container text-mp-on-surface","max-h-[min(24rem,var(--available-height))] min-w-[112px] max-w-[280px]","overflow-y-auto overscroll-contain py-2 outline-none",h].join(" "),b={xs:"min-h-8",sm:"min-h-10",md:"min-h-12",lg:"min-h-14",xl:"min-h-16"},g={xs:"px-2",sm:"px-2.5",md:"px-3",lg:"px-4",xl:"px-5"},N={xs:"gap-2",sm:"gap-2.5",md:"gap-3",lg:"gap-3",xl:"gap-4"},v={xs:"text-mp-label-medium",sm:"text-mp-label-large",md:"text-mp-label-large",lg:"text-mp-title-medium",xl:"text-mp-title-medium"};function C(e,n,t){return["group relative flex w-full cursor-pointer items-center select-none",n?"text-(--_mp-accent)":"text-mp-on-surface",b[e],g[e],N[e],v[e],"data-disabled:text-mp-on-surface/38 data-disabled:cursor-default","outline-none",t??""].filter(Boolean).join(" ")}function y(){return e(d,{layer:"inset-0 bg-current",className:"group-data-highlighted:opacity-8 group-data-popup-open:opacity-8 group-data-disabled:opacity-0"})}const k="relative flex shrink-0 items-center justify-center";function M({children:t,description:a}){return p(a)?n("span",{className:"relative flex min-w-0 flex-1 flex-col py-1.5 text-start",children:[e("span",{className:"truncate",children:t}),e("span",{className:`text-mp-on-surface-variant truncate ${u}`,children:a})]}):e("span",{className:"relative min-w-0 flex-1 truncate text-start",children:t})}function O({shortcut:n}){return p(n)?e("span",{className:`text-mp-on-surface-variant relative ms-2 shrink-0 ${u}`,children:n}):null}export function MPMenuItem({onClick:l,href:r,target:o,rel:s,startIcon:c,endIcon:d,shortcut:m,description:u,color:h,closeOnClick:f=!0,disabled:x=!1,label:b,children:g,className:N,style:v}){const{size:P}=t.useContext(i),j=n(t.Fragment,{children:[e(y,{}),p(c)?e("span",{className:`${k} text-mp-on-surface-variant`,children:c}):null,e(M,{description:u,children:g}),p(d)?e("span",{className:`${k} text-mp-on-surface-variant`,children:d}):null,e(O,{shortcut:m})]}),I=h?{"--_mp-accent":`var(--_mp-color-${h})`}:void 0,$=I||v?{...I,...v}:void 0;return void 0===r||x?e(a.Item,{disabled:x,label:b,closeOnClick:f,onClick:l,className:C(P,Boolean(h),N),style:$,children:j}):e(a.LinkItem,{href:r,target:o,rel:s??("_blank"===o?"noopener noreferrer":void 0),label:b,closeOnClick:f,onClick:l,className:C(P,Boolean(h),N),style:$,children:j})}export function MPMenuCheckboxItem({checked:l,defaultChecked:s,onCheckedChange:c,endIcon:d,shortcut:u,description:h,color:f,closeOnClick:x=!1,disabled:b=!1,label:g,children:N,className:v,style:P}){const{size:j}=t.useContext(i),I=f?{"--_mp-accent":`var(--_mp-color-${f})`}:void 0;return n(a.CheckboxItem,{checked:l,defaultChecked:s,onCheckedChange:e=>c?.(e),disabled:b,label:g,closeOnClick:x,className:C(j,Boolean(f),v),style:I||P?{...I,...P}:void 0,children:[e(y,{}),e("span",{className:`${k} text-(--_mp-accent)`,style:{width:m[j]},children:e(a.CheckboxItemIndicator,{className:"flex items-center justify-center",children:e(r,{icon:o,size:m[j]})})}),e(M,{description:h,children:N}),p(d)?e("span",{className:`${k} text-mp-on-surface-variant`,children:d}):null,e(O,{shortcut:u})]})}export function MPMenuRadioGroup({value:n,defaultValue:t,onValueChange:l,disabled:r=!1,children:o,className:s}){return e(a.RadioGroup,{value:n,defaultValue:t,onValueChange:e=>l?.(e),disabled:r,className:s,children:o})}export function MPMenuRadioItem({value:l,endIcon:r,shortcut:o,description:s,color:c,closeOnClick:d=!1,disabled:u=!1,label:h,children:f,className:x,style:b}){const{size:g}=t.useContext(i),N=c?{"--_mp-accent":`var(--_mp-color-${c})`}:void 0;return n(a.RadioItem,{value:l,disabled:u,label:h,closeOnClick:d,className:C(g,Boolean(c),x),style:N||b?{...N,...b}:void 0,children:[e(y,{}),e("span",{className:`${k} text-(--_mp-accent)`,style:{width:m[g]},children:e(a.RadioItemIndicator,{className:"flex items-center justify-center",children:e("span",{className:"block size-2.5 rounded-full bg-current"})})}),e(M,{description:s,children:f}),p(r)?e("span",{className:`${k} text-mp-on-surface-variant`,children:r}):null,e(O,{shortcut:o})]})}export function MPMenuGroup({label:l,children:r,className:o}){const{size:s}=t.useContext(i);return n(a.Group,{className:o,children:[p(l)?e(a.GroupLabel,{className:`text-mp-on-surface-variant pt-2 pb-1 ${g[s]} ${u}`,children:l}):null,r]})}export function MPMenuSeparator({className:n,...t}){return e(a.Separator,{className:["bg-mp-outline-variant my-2 h-px",n??""].filter(Boolean).join(" "),...t})}export function MPMenuSubmenu({label:l,startIcon:o,disabled:d=!1,side:u="right",sideOffset:h=0,children:b,className:g,style:N}){const{size:v,color:M}=t.useContext(i);return n(a.SubmenuRoot,{children:[n(a.SubmenuTrigger,{disabled:d,className:C(v,!1),children:[e(y,{}),p(o)?e("span",{className:`${k} text-mp-on-surface-variant`,children:o}):null,e("span",{className:"relative min-w-0 flex-1 truncate text-start",children:l}),e("span",{className:`${k} text-mp-on-surface-variant rtl:rotate-180`,children:e(r,{icon:s,size:m[v]})})]}),e(a.Portal,{children:e(a.Positioner,{className:f,side:u,sideOffset:h,align:"start",children:e(a.Popup,{className:[x,g??""].filter(Boolean).join(" "),style:{...c(M),...N},children:b})})})]})}export function MPMenu({size:l="md",color:r="primary",trigger:o,open:s,defaultOpen:d,onOpenChange:m,side:u="bottom",align:p="start",sideOffset:h=4,modal:b=!0,openOnHover:g=!1,loopFocus:N=!0,disabled:v=!1,className:C,style:y,children:k}){const M=t.useMemo(()=>({size:l,color:r}),[l,r]);return e(i.Provider,{value:M,children:n(a.Root,{open:s,defaultOpen:d,onOpenChange:e=>m?.(e),modal:b,loopFocus:N,disabled:v,children:[o?e(a.Trigger,{render:o,openOnHover:g,disabled:v}):null,e(a.Portal,{children:e(a.Positioner,{className:f,side:u,align:p,sideOffset:h,children:e(a.Popup,{"data-mp-size":l,className:[x,C??""].filter(Boolean).join(" "),style:{...c(r),...y},children:k})})})]})})}export function MPContextMenu({size:a="md",color:r="primary",content:o,children:s,open:d,defaultOpen:m,onOpenChange:u,loopFocus:p=!0,disabled:h=!1,className:b,style:g}){const N=t.useMemo(()=>({size:a,color:r}),[a,r]);return e(i.Provider,{value:N,children:n(l.Root,{open:d,defaultOpen:m,onOpenChange:e=>u?.(e),loopFocus:p,disabled:h,children:[e(l.Trigger,{children:s}),e(l.Portal,{children:e(l.Positioner,{className:f,children:e(l.Popup,{"data-mp-size":a,className:[x,b??""].filter(Boolean).join(" "),style:{...c(r),...g},children:o})})})]})})}
2
+ import{jsx as e,jsxs as n}from"react/jsx-runtime";import*as t from"react";import{Menu as a}from"@base-ui/react/menu";import{ContextMenu as l}from"@base-ui/react/context-menu";import{MPIcon as r}from"../icon/MPIcon.js";import{CheckIcon as s,ChevronRightIcon as o}from"../../constants/icons.js";import{linkRel as i}from"../../internal/link.js";import{MPMenuContext as c}from"../../internal/menu.js";import{accentSlots as d}from"../../internal/accent.js";import{MPStateLayer as m}from"../../internal/StateLayer.js";import{CONTROL_ICON as u,META_TEXT as p,hasContent as h}from"../../internal/scale.js";import{FADE as f,PORTAL_LAYER as x}from"../../internal/surface.js";const b=/*@__PURE__*/["mp-menu__popup rounded-mp-xs shadow-mp-2 bg-mp-surface-container text-mp-on-surface","max-h-[min(24rem,var(--available-height))] min-w-[112px] max-w-[280px]","overflow-y-auto overscroll-contain py-2 outline-none",f].join(" "),g={xs:"min-h-8",sm:"min-h-10",md:"min-h-12",lg:"min-h-14",xl:"min-h-16"},N={xs:"px-2",sm:"px-2.5",md:"px-3",lg:"px-4",xl:"px-5"},v={xs:"gap-2",sm:"gap-2.5",md:"gap-3",lg:"gap-3",xl:"gap-4"},y={xs:"text-mp-label-medium",sm:"text-mp-label-large",md:"text-mp-label-large",lg:"text-mp-title-medium",xl:"text-mp-title-medium"};function C(e,n,t){return["group relative flex w-full cursor-pointer items-center select-none",n?"text-(--_mp-accent)":"text-mp-on-surface",g[e],N[e],v[e],y[e],"data-disabled:text-mp-on-surface/38 data-disabled:cursor-default","outline-none",t??""].filter(Boolean).join(" ")}function k(){return e(m,{layer:"inset-0 bg-current",className:"group-data-highlighted:opacity-8 group-data-popup-open:opacity-8 group-data-disabled:opacity-0"})}const M="relative flex shrink-0 items-center justify-center";function O({children:t,description:a}){return h(a)?n("span",{className:"relative flex min-w-0 flex-1 flex-col py-1.5 text-start",children:[e("span",{className:"truncate",children:t}),e("span",{className:`text-mp-on-surface-variant truncate ${p}`,children:a})]}):e("span",{className:"relative min-w-0 flex-1 truncate text-start",children:t})}function P({shortcut:n}){return h(n)?e("span",{className:`text-mp-on-surface-variant relative ms-2 shrink-0 ${p}`,children:n}):null}export function MPMenuItem({onClick:l,href:r,target:s,rel:o,startIcon:d,endIcon:m,shortcut:u,description:p,color:f,closeOnClick:x=!0,disabled:b=!1,label:g,children:N,className:v,style:y}){const{size:j}=t.useContext(c),I=n(t.Fragment,{children:[e(k,{}),h(d)?e("span",{className:`${M} text-mp-on-surface-variant`,children:d}):null,e(O,{description:p,children:N}),h(m)?e("span",{className:`${M} text-mp-on-surface-variant`,children:m}):null,e(P,{shortcut:u})]}),$=f?{"--_mp-accent":`var(--_mp-color-${f})`}:void 0,z=$||y?{...$,...y}:void 0;return void 0===r||b?e(a.Item,{disabled:b,label:g,closeOnClick:x,onClick:l,className:C(j,Boolean(f),v),style:z,children:I}):e(a.LinkItem,{href:r,target:s,rel:i(s,o),label:g,closeOnClick:x,onClick:l,className:C(j,Boolean(f),v),style:z,children:I})}export function MPMenuCheckboxItem({checked:l,defaultChecked:o,onCheckedChange:i,endIcon:d,shortcut:m,description:p,color:f,closeOnClick:x=!1,disabled:b=!1,label:g,children:N,className:v,style:y}){const{size:j}=t.useContext(c),I=f?{"--_mp-accent":`var(--_mp-color-${f})`}:void 0;return n(a.CheckboxItem,{checked:l,defaultChecked:o,onCheckedChange:e=>i?.(e),disabled:b,label:g,closeOnClick:x,className:C(j,Boolean(f),v),style:I||y?{...I,...y}:void 0,children:[e(k,{}),e("span",{className:`${M} text-(--_mp-accent)`,style:{width:u[j]},children:e(a.CheckboxItemIndicator,{className:"flex items-center justify-center",children:e(r,{icon:s,size:u[j]})})}),e(O,{description:p,children:N}),h(d)?e("span",{className:`${M} text-mp-on-surface-variant`,children:d}):null,e(P,{shortcut:m})]})}export function MPMenuRadioGroup({value:n,defaultValue:t,onValueChange:l,disabled:r=!1,children:s,className:o,style:i}){return e(a.RadioGroup,{value:n,defaultValue:t,onValueChange:e=>l?.(e),disabled:r,className:o,style:i,children:s})}export function MPMenuRadioItem({value:l,endIcon:r,shortcut:s,description:o,color:i,closeOnClick:d=!1,disabled:m=!1,label:p,children:f,className:x,style:b}){const{size:g}=t.useContext(c),N=i?{"--_mp-accent":`var(--_mp-color-${i})`}:void 0;return n(a.RadioItem,{value:l,disabled:m,label:p,closeOnClick:d,className:C(g,Boolean(i),x),style:N||b?{...N,...b}:void 0,children:[e(k,{}),e("span",{className:`${M} text-(--_mp-accent)`,style:{width:u[g]},children:e(a.RadioItemIndicator,{className:"flex items-center justify-center",children:e("span",{className:"block size-2.5 rounded-full bg-current"})})}),e(O,{description:o,children:f}),h(r)?e("span",{className:`${M} text-mp-on-surface-variant`,children:r}):null,e(P,{shortcut:s})]})}export function MPMenuGroup({label:l,children:r,className:s,style:o}){const{size:i}=t.useContext(c);return n(a.Group,{className:s,style:o,children:[h(l)?e(a.GroupLabel,{className:`text-mp-on-surface-variant pt-2 pb-1 ${N[i]} ${p}`,children:l}):null,r]})}export function MPMenuSeparator({className:n,...t}){return e(a.Separator,{className:["bg-mp-outline-variant my-2 h-px",n??""].filter(Boolean).join(" "),...t})}export function MPMenuSubmenu({label:l,startIcon:s,disabled:i=!1,side:m="right",sideOffset:p=0,children:f,className:g,style:N}){const{size:v,color:y}=t.useContext(c);return n(a.SubmenuRoot,{children:[n(a.SubmenuTrigger,{disabled:i,className:C(v,!1),children:[e(k,{}),h(s)?e("span",{className:`${M} text-mp-on-surface-variant`,children:s}):null,e("span",{className:"relative min-w-0 flex-1 truncate text-start",children:l}),e("span",{className:`${M} text-mp-on-surface-variant rtl:rotate-180`,children:e(r,{icon:o,size:u[v]})})]}),e(a.Portal,{children:e(a.Positioner,{className:x,side:m,sideOffset:p,align:"start",children:e(a.Popup,{className:[b,g??""].filter(Boolean).join(" "),style:{...d(y),...N},children:f})})})]})}export function MPMenu({size:l="md",color:r="primary",trigger:s,open:o,defaultOpen:i,onOpenChange:m,side:u="bottom",align:p="start",sideOffset:h=4,modal:f,openOnHover:g=!1,loopFocus:N=!0,disabled:v=!1,className:y,style:C,children:k}){const M=t.useMemo(()=>({size:l,color:r}),[l,r]);return e(c.Provider,{value:M,children:n(a.Root,{open:o,defaultOpen:i,onOpenChange:e=>m?.(e),modal:f,loopFocus:N,disabled:v,children:[s?e(a.Trigger,{render:s,openOnHover:g,disabled:v}):null,e(a.Portal,{children:e(a.Positioner,{className:x,side:u,align:p,sideOffset:h,children:e(a.Popup,{"data-mp-size":l,className:[b,y??""].filter(Boolean).join(" "),style:{...d(r),...C},children:k})})})]})})}export function MPContextMenu({size:a="md",color:r="primary",content:s,children:o,open:i,defaultOpen:m,onOpenChange:u,loopFocus:p=!0,disabled:h=!1,className:f,style:g}){const N=t.useMemo(()=>({size:a,color:r}),[a,r]);return e(c.Provider,{value:N,children:n(l.Root,{open:i,defaultOpen:m,onOpenChange:e=>u?.(e),loopFocus:p,disabled:h,children:[e(l.Trigger,{children:o}),e(l.Portal,{children:e(l.Positioner,{className:x,children:e(l.Popup,{"data-mp-size":a,className:[b,f??""].filter(Boolean).join(" "),style:{...d(r),...g},children:s})})})]})})}
@@ -0,0 +1,89 @@
1
+ import * as React from 'react';
2
+ import type { MPColor, MPOrientation, MPSize } from '../../types.js';
3
+ export interface MPMenubarProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'color'> {
4
+ /**
5
+ * Which way the bar runs. `vertical` is the shape a side rail of menus takes;
6
+ * the arrow keys follow it either way.
7
+ * @default 'horizontal'
8
+ */
9
+ orientation?: MPOrientation;
10
+ /**
11
+ * Whether an open menu takes the page away.
12
+ * @default true
13
+ */
14
+ modal?: boolean;
15
+ /**
16
+ * Whether the arrow keys wrap around at the ends of the bar.
17
+ * @default true
18
+ */
19
+ loopFocus?: boolean;
20
+ /** Disables every menu on the bar at once. */
21
+ disabled?: boolean;
22
+ /**
23
+ * The row height and type scale, passed to every menu on the bar.
24
+ * @default 'md'
25
+ */
26
+ size?: MPSize;
27
+ /**
28
+ * Which accent family an open menu's word reads, and which a chosen row inside
29
+ * it reads.
30
+ * @default 'primary'
31
+ */
32
+ color?: MPColor;
33
+ /** The `MPMenubarMenu`s. */
34
+ children?: React.ReactNode;
35
+ }
36
+ export interface MPMenubarMenuProps {
37
+ /** The word on the bar. */
38
+ label: React.ReactNode;
39
+ /** A glyph before the label. */
40
+ startIcon?: React.ReactNode;
41
+ /** Unavailable. The word stays on the bar and opens nothing. */
42
+ disabled?: boolean;
43
+ /** The rows, written exactly as they are inside an [MPMenu](./menu). */
44
+ children?: React.ReactNode;
45
+ /**
46
+ * Added to the word on the bar — the button that opens the menu — rather than
47
+ * to the menu it opens. That one takes its own `className` on
48
+ * [MPMenu](./menu).
49
+ */
50
+ className?: string;
51
+ style?: React.CSSProperties;
52
+ }
53
+ /**
54
+ * One menu on the bar: the word, and the rows behind it.
55
+ *
56
+ * It has no `size` and no `color` of its own — both belong to the bar, which is
57
+ * the only place they can be set once and hold for every menu on it. The rows
58
+ * inside are the same [MPMenuItem](./menu), `MPMenuSeparator`, `MPMenuGroup` and
59
+ * `MPMenuSubmenu` an [MPMenu](./menu) takes, because it *is* the same menu.
60
+ */
61
+ export declare function MPMenubarMenu({ label, startIcon, disabled, children, className, style }: MPMenubarMenuProps): React.JSX.Element;
62
+ /**
63
+ * The strip of words at the top of an application — File, Edit, View — each of
64
+ * which opens a menu.
65
+ *
66
+ * ## What makes it a bar rather than a row of menus
67
+ *
68
+ * What happens once one of them is **open**: moving along the strip walks
69
+ * through the others instead of closing the one you left, and the arrow keys
70
+ * move between the menus as well as inside them. Base UI owns all of that, along
71
+ * with the `menubar` role — which is what tells a screen reader that the strip
72
+ * is one widget with one tab stop rather than six unrelated buttons.
73
+ *
74
+ * ## Why it draws no surface
75
+ *
76
+ * A menu bar sits **on** something: an [MPHeader](../layout/header), a title
77
+ * bar, a toolbar. A sheet under a strip that is already on a sheet is two
78
+ * sheets, and the second one has nothing to say. It is the same refusal
79
+ * [MPContainer](../layout/container#why-it-draws-no-surface) makes, one level
80
+ * down.
81
+ *
82
+ * ## When this is the wrong component
83
+ *
84
+ * When there are more actions than a strip can hold. A menu bar's whole
85
+ * advantage is that every heading is visible before you go looking for one, and
86
+ * a bar of twelve words has already lost it — that is an
87
+ * [MPCommandPalette](./command-palette).
88
+ */
89
+ export declare const MPMenubar: React.ForwardRefExoticComponent<MPMenubarProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,2 @@
1
+ "use client";
2
+ import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as o from"react";import{Menubar as r}from"@base-ui/react/menubar";import{MPMenu as n}from"../menu/MPMenu.js";import{accentSlots as s}from"../../internal/accent.js";import{MPMenuContext as l}from"../../internal/menu.js";import{MPStateLayer as a}from"../../internal/StateLayer.js";import{CONTROL_GAP as i,hasContent as m}from"../../internal/scale.js";const c={xs:"h-6",sm:"h-7",md:"h-8",lg:"h-10",xl:"h-12"},p={xs:"px-1.5",sm:"px-2",md:"px-2.5",lg:"px-3",xl:"px-4"},u={xs:"text-mp-label-medium",sm:"text-mp-label-large",md:"text-mp-label-large",lg:"text-mp-title-medium",xl:"text-mp-title-medium"};export function MPMenubarMenu({label:r,startIcon:s,disabled:d=!1,children:f,className:x,style:b}){const{size:h,color:j}=o.useContext(l);return e(n,{size:h,color:j,disabled:d,openOnHover:!0,sideOffset:4,trigger:t("button",{type:"button",disabled:d,className:["mp-menubar__menu group text-mp-on-surface relative inline-flex shrink-0","rounded-mp-xs cursor-pointer items-center justify-center bg-transparent","appearance-none font-[inherit] whitespace-nowrap select-none","transition-colors duration-(--mp-sys-motion-duration-short4)","data-popup-open:text-(--_mp-accent)","disabled:text-mp-on-surface/38 disabled:cursor-default","outline-mp-secondary focus-visible:outline-2 focus-visible:-outline-offset-2","focus-visible:outline-solid outline-none",c[h],p[h],u[h],i[h],x??""].filter(Boolean).join(" "),style:b,children:[d?null:e(a,{className:"group-data-popup-open:opacity-8"}),m(s)?e("span",{className:"relative flex",children:s}):null,e("span",{className:"relative",children:r})]}),children:f})}export const MPMenubar=/*@__PURE__*/o.forwardRef(function({orientation:t="horizontal",modal:n=!0,loopFocus:a=!0,disabled:m=!1,size:c="md",color:p="primary",className:u,style:d,children:f,...x},b){const h=o.useMemo(()=>({size:c,color:p}),[c,p]);return e(l.Provider,{value:h,children:e(r,{ref:b,orientation:t,modal:n,loopFocus:a,disabled:m,"data-mp-size":c,"data-mp-orientation":t,className:["mp-menubar flex items-center","vertical"===t?"flex-col items-stretch":"flex-row",i[c],u??""].filter(Boolean).join(" "),style:{...s(p),...d},...x,children:f})})});
@@ -0,0 +1,2 @@
1
+ export { MPMenubar, MPMenubarMenu } from './MPMenubar.js';
2
+ export type { MPMenubarMenuProps, MPMenubarProps } from './MPMenubar.js';
@@ -0,0 +1 @@
1
+ export{MPMenubar,MPMenubarMenu}from"./MPMenubar.js";