material-plus-ui 1.0.0 → 1.2.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 (151) hide show
  1. package/dist/components/animate-appear/MPAnimateAppear.d.ts +56 -0
  2. package/dist/components/animate-appear/MPAnimateAppear.js +1 -0
  3. package/dist/components/animate-appear/index.d.ts +2 -0
  4. package/dist/components/animate-appear/index.js +1 -0
  5. package/dist/components/animate-blink/MPAnimateBlink.d.ts +41 -0
  6. package/dist/components/animate-blink/MPAnimateBlink.js +1 -0
  7. package/dist/components/animate-blink/index.d.ts +2 -0
  8. package/dist/components/animate-blink/index.js +1 -0
  9. package/dist/components/animate-fade/MPAnimateFade.d.ts +38 -0
  10. package/dist/components/animate-fade/MPAnimateFade.js +1 -0
  11. package/dist/components/animate-fade/index.d.ts +2 -0
  12. package/dist/components/animate-fade/index.js +1 -0
  13. package/dist/components/animate-grow/MPAnimateGrow.d.ts +52 -0
  14. package/dist/components/animate-grow/MPAnimateGrow.js +1 -0
  15. package/dist/components/animate-grow/index.d.ts +2 -0
  16. package/dist/components/animate-grow/index.js +1 -0
  17. package/dist/components/animate-headline/MPAnimateHeadline.d.ts +63 -0
  18. package/dist/components/animate-headline/MPAnimateHeadline.js +1 -0
  19. package/dist/components/animate-headline/index.d.ts +2 -0
  20. package/dist/components/animate-headline/index.js +1 -0
  21. package/dist/components/animate-lighting/MPAnimateLighting.d.ts +68 -0
  22. package/dist/components/animate-lighting/MPAnimateLighting.js +1 -0
  23. package/dist/components/animate-lighting/index.d.ts +2 -0
  24. package/dist/components/animate-lighting/index.js +1 -0
  25. package/dist/components/animate-marquee/MPAnimateMarquee.d.ts +66 -0
  26. package/dist/components/animate-marquee/MPAnimateMarquee.js +1 -0
  27. package/dist/components/animate-marquee/index.d.ts +2 -0
  28. package/dist/components/animate-marquee/index.js +1 -0
  29. package/dist/components/animate-rotate/MPAnimateRotate.d.ts +56 -0
  30. package/dist/components/animate-rotate/MPAnimateRotate.js +1 -0
  31. package/dist/components/animate-rotate/index.d.ts +2 -0
  32. package/dist/components/animate-rotate/index.js +1 -0
  33. package/dist/components/animate-slide/MPAnimateSlide.d.ts +53 -0
  34. package/dist/components/animate-slide/MPAnimateSlide.js +1 -0
  35. package/dist/components/animate-slide/index.d.ts +2 -0
  36. package/dist/components/animate-slide/index.js +1 -0
  37. package/dist/components/animate-typing/MPAnimateTyping.d.ts +59 -0
  38. package/dist/components/animate-typing/MPAnimateTyping.js +1 -0
  39. package/dist/components/animate-typing/index.d.ts +2 -0
  40. package/dist/components/animate-typing/index.js +1 -0
  41. package/dist/components/animate-zoom/MPAnimateZoom.d.ts +44 -0
  42. package/dist/components/animate-zoom/MPAnimateZoom.js +1 -0
  43. package/dist/components/animate-zoom/index.d.ts +2 -0
  44. package/dist/components/animate-zoom/index.js +1 -0
  45. package/dist/components/avatar/MPAvatar.d.ts +9 -2
  46. package/dist/components/avatar/MPAvatar.js +1 -1
  47. package/dist/components/badge/MPBadge.js +1 -1
  48. package/dist/components/bottom-navigation/MPBottomNavigation.d.ts +144 -0
  49. package/dist/components/bottom-navigation/MPBottomNavigation.js +1 -0
  50. package/dist/components/bottom-navigation/index.d.ts +2 -0
  51. package/dist/components/bottom-navigation/index.js +1 -0
  52. package/dist/components/breadcrumb/MPBreadcrumb.d.ts +22 -0
  53. package/dist/components/breadcrumb/MPBreadcrumb.js +1 -1
  54. package/dist/components/button/MPButton.d.ts +7 -2
  55. package/dist/components/button/MPButton.js +1 -1
  56. package/dist/components/carousel/MPCarousel.js +1 -1
  57. package/dist/components/checkbox/MPCheckbox.d.ts +2 -2
  58. package/dist/components/checkbox/MPCheckbox.js +1 -1
  59. package/dist/components/chip/MPChip.d.ts +13 -3
  60. package/dist/components/chip/MPChip.js +1 -1
  61. package/dist/components/color-picker/MPColorPicker.d.ts +21 -3
  62. package/dist/components/color-picker/MPColorPicker.js +1 -1
  63. package/dist/components/combobox/MPCombobox.d.ts +38 -10
  64. package/dist/components/combobox/MPCombobox.js +1 -1
  65. package/dist/components/container/MPContainer.d.ts +75 -0
  66. package/dist/components/container/MPContainer.js +1 -0
  67. package/dist/components/container/index.d.ts +2 -0
  68. package/dist/components/container/index.js +1 -0
  69. package/dist/components/date-picker/MPDatePicker.d.ts +3 -0
  70. package/dist/components/date-picker/MPDatePicker.js +1 -1
  71. package/dist/components/date-range-picker/MPDateRangePicker.js +1 -1
  72. package/dist/components/date-time-picker/MPDateTimePicker.js +1 -1
  73. package/dist/components/dialog/MPDialog.d.ts +8 -3
  74. package/dist/components/dialog/MPDialog.js +1 -1
  75. package/dist/components/drawer/MPDrawer.d.ts +33 -9
  76. package/dist/components/drawer/MPDrawer.js +1 -1
  77. package/dist/components/empty/MPEmpty.d.ts +12 -2
  78. package/dist/components/empty/MPEmpty.js +1 -1
  79. package/dist/components/file-picker/MPFilePicker.d.ts +11 -1
  80. package/dist/components/file-picker/MPFilePicker.js +1 -1
  81. package/dist/components/floating-action-button/MPFloatingActionButton.d.ts +126 -0
  82. package/dist/components/floating-action-button/MPFloatingActionButton.js +1 -0
  83. package/dist/components/floating-action-button/index.d.ts +2 -0
  84. package/dist/components/floating-action-button/index.js +1 -0
  85. package/dist/components/grid/MPGrid.d.ts +155 -0
  86. package/dist/components/grid/MPGrid.js +1 -0
  87. package/dist/components/grid/index.d.ts +2 -0
  88. package/dist/components/grid/index.js +1 -0
  89. package/dist/components/highlight/MPHighlight.js +1 -1
  90. package/dist/components/list/MPList.js +1 -1
  91. package/dist/components/menu/MPMenu.d.ts +10 -1
  92. package/dist/components/menu/MPMenu.js +1 -1
  93. package/dist/components/number-field/MPNumberField.d.ts +21 -3
  94. package/dist/components/number-field/MPNumberField.js +1 -1
  95. package/dist/components/pagination/MPPagination.d.ts +106 -0
  96. package/dist/components/pagination/MPPagination.js +1 -0
  97. package/dist/components/pagination/index.d.ts +2 -0
  98. package/dist/components/pagination/index.js +1 -0
  99. package/dist/components/panes/MPPanes.js +1 -1
  100. package/dist/components/pill/MPPill.js +1 -1
  101. package/dist/components/popover/MPPopover.d.ts +8 -3
  102. package/dist/components/popover/MPPopover.js +1 -1
  103. package/dist/components/radio-group/MPRadioGroup.js +1 -1
  104. package/dist/components/rating/MPRating.d.ts +135 -0
  105. package/dist/components/rating/MPRating.js +1 -0
  106. package/dist/components/rating/index.d.ts +2 -0
  107. package/dist/components/rating/index.js +1 -0
  108. package/dist/components/segmented-button/MPSegmentedButton.js +1 -1
  109. package/dist/components/select/MPSelect.d.ts +23 -6
  110. package/dist/components/select/MPSelect.js +1 -1
  111. package/dist/components/skeleton/MPSkeleton.js +1 -1
  112. package/dist/components/slider/MPSlider.js +1 -1
  113. package/dist/components/snackbar/MPSnackbar.d.ts +8 -3
  114. package/dist/components/snackbar/MPSnackbar.js +1 -1
  115. package/dist/components/spoiler/MPSpoiler.js +1 -1
  116. package/dist/components/switch/MPSwitch.d.ts +2 -2
  117. package/dist/components/switch/MPSwitch.js +1 -1
  118. package/dist/components/table/MPTable.d.ts +14 -1
  119. package/dist/components/table/MPTable.js +1 -1
  120. package/dist/components/tabs/MPTabs.d.ts +145 -0
  121. package/dist/components/tabs/MPTabs.js +1 -0
  122. package/dist/components/tabs/index.d.ts +2 -0
  123. package/dist/components/tabs/index.js +1 -0
  124. package/dist/components/text-field/MPTextField.d.ts +37 -7
  125. package/dist/components/text-field/MPTextField.js +1 -1
  126. package/dist/components/text-link/MPTextLink.js +1 -1
  127. package/dist/components/time-picker/MPTimePicker.js +1 -1
  128. package/dist/components/timeline/MPTimeline.js +1 -1
  129. package/dist/constants/icons.d.ts +13 -0
  130. package/dist/constants/icons.js +1 -1
  131. package/dist/index.d.ts +18 -0
  132. package/dist/index.js +1 -1
  133. package/dist/internal/Calendar.js +1 -1
  134. package/dist/internal/FieldOutline.d.ts +75 -4
  135. package/dist/internal/FieldOutline.js +1 -1
  136. package/dist/internal/Picker.d.ts +52 -9
  137. package/dist/internal/Picker.js +1 -1
  138. package/dist/internal/animate.d.ts +179 -0
  139. package/dist/internal/animate.js +1 -0
  140. package/dist/internal/date.d.ts +2 -2
  141. package/dist/internal/date.js +1 -1
  142. package/dist/internal/i18n.d.ts +110 -0
  143. package/dist/internal/i18n.js +1 -1
  144. package/dist/internal/inert.d.ts +11 -0
  145. package/dist/internal/inert.js +1 -0
  146. package/dist/internal/surface.d.ts +42 -12
  147. package/dist/internal/surface.js +1 -1
  148. package/dist/styles.css +1 -1
  149. package/dist/tailwind.css +640 -4
  150. package/dist/types.d.ts +155 -0
  151. package/package.json +10 -10
@@ -60,8 +60,18 @@ export interface MPFilePickerProps extends MPStyleProps {
60
60
  icon?: React.ReactNode;
61
61
  /** Lists the chosen files under the box, each with a way to remove it. @default true */
62
62
  showList?: boolean;
63
- /** The accessible name of a file's remove button. Receives the file's name. */
63
+ /**
64
+ * The accessible name of a file's remove button. Receives the file's name.
65
+ *
66
+ * Left out, each button is still named for its own file — in `locale`'s own
67
+ * word order — rather than being one of five buttons all called "Remove".
68
+ */
64
69
  removeLabel?: (name: string) => string;
70
+ /**
71
+ * Which language the remove buttons' default names are written in. Falls back
72
+ * to the nearest `MPLocaleProvider`, then to English.
73
+ */
74
+ locale?: string;
65
75
  /** Marks the field required. */
66
76
  required?: boolean;
67
77
  /** Greys the picker out and stops it taking files. */
@@ -1 +1 @@
1
- import{jsx as e,jsxs as r}from"react/jsx-runtime";import*as n from"react";import{MPIcon as t}from"../icon/MPIcon";import{CloseIcon as a,UploadIcon as i}from"../../constants/icons";import{MPStateLayer as o}from"../../internal/StateLayer";import{CONTROL_ICON as l,META_TEXT as s,PROSE_TEXT as c,STACK_GAP as p,hasContent as u}from"../../internal/scale";const m={xs:"p-4",sm:"p-5",md:"p-6",lg:"p-8",xl:"p-10"};export function formatFileSize(e){if(e<1e3)return`${e} B`;const r=["kB","MB","GB","TB"];let n=e/1e3,t=0;for(;n>=1e3&&t<r.length-1;)n/=1e3,t+=1;return`${n<10?n.toFixed(1):Math.round(n)} ${r[t]}`}function d(e,r){const n=e.name.toLowerCase(),t=e.type.toLowerCase();return r.split(",").map(e=>e.trim().toLowerCase()).filter(Boolean).some(e=>e.startsWith(".")?n.endsWith(e):e.endsWith("/*")?t.startsWith(e.slice(0,-1)):t===e)}export const MPFilePicker=n.forwardRef(function({accept:f,multiple:h=!1,maxSize:x,maxFiles:b,value:v,defaultValue:g,onFilesChange:y,onReject:j,label:N,description:k,errorMessage:w,title:z,hint:C,icon:I,showList:B=!0,removeLabel:D=e=>`Remove ${e}`,size:$="md",fullWidth:F=!0,required:L=!1,disabled:M=!1,readOnly:S=!1,name:R,id:T},W){const _=n.useRef(null);n.useImperativeHandle(W,()=>_.current);const[P,E]=n.useState(()=>[...g??[]]),O=v?[...v]:P,q=n.useRef(0),[A,V]=n.useState(!1),G=u(w),H=M||S,Y=n.useId(),J=n.useCallback(e=>{v||E(e),y?.(e)},[y,v]),K=n.useCallback(e=>{const r=[],n=[],t=h?b??Number.POSITIVE_INFINITY:1,a=h?O.length:0;for(const i of e)f&&!d(i,f)?n.push({file:i,reason:"type"}):void 0!==x&&i.size>x?n.push({file:i,reason:"size"}):a+r.length>=t?n.push({file:i,reason:"count"}):r.push(i);return{kept:r,rejections:n}},[f,O.length,b,x,h]),Q=n.useCallback(e=>{const{kept:r,rejections:n}=K(e);n.length>0&&j?.(n),r.length>0&&J(h?[...O,...r]:r)},[K,J,O,h,j]);return r("div",{className:["mp-file-picker flex-col align-top",p[$],F?"flex w-full":"inline-flex"].join(" "),"data-mp-size":$,"data-disabled":M||void 0,"data-invalid":G||void 0,children:[u(N)?r("span",{className:[s,M?"text-mp-on-surface/38":G?"text-mp-error":"text-mp-on-surface-variant"].join(" "),children:[N,L?e("span",{"aria-hidden":"true",children:" *"}):null]}):null,r("div",{className:"flex w-full flex-col",onDragEnter:e=>{H||(e.preventDefault(),q.current+=1,V(!0))},onDragOver:e=>{H||(e.preventDefault(),e.dataTransfer.dropEffect="copy")},onDragLeave:()=>{H||(q.current=Math.max(0,q.current-1),0===q.current&&V(!1))},onDrop:e=>{H||(e.preventDefault(),q.current=0,V(!1),Q(Array.from(e.dataTransfer.files)))},children:[r("button",{type:"button",id:T,disabled:M,"aria-describedby":u(k)||G?Y:void 0,"aria-invalid":G||void 0,className:["mp-file-picker__zone group relative flex w-full flex-col items-center","justify-center gap-2 text-center","rounded-mp-md box-border border-2 border-dashed","appearance-none bg-transparent font-[inherit] outline-none","transition-[border-color,background-color] duration-(--mp-sys-motion-duration-short4)",m[$],c[$],M?"border-mp-on-surface/12 text-mp-on-surface/38 cursor-default":[S?"cursor-default":"cursor-pointer",G?"border-mp-error":"border-mp-outline-variant","text-mp-on-surface",A?"border-mp-primary bg-mp-primary/8":""].filter(Boolean).join(" ")].filter(Boolean).join(" "),onClick:()=>{!H&&_.current&&(_.current.value="",_.current.click())},children:[H?null:e(o,{layer:"inset-0 rounded-[inherit] bg-mp-primary"}),void 0===I?e(t,{icon:i,size:1.6*l[$],className:M?"":"text-mp-primary"}):u(I)?e("span",{className:M?"":"text-mp-primary",children:I}):null,e("span",{className:"font-medium",children:z??"Drop files here, or click to browse"}),u(C)?e("span",{className:[s,M?"text-mp-on-surface/38":"text-mp-on-surface-variant"].join(" "),children:C}):null]}),e("input",{ref:_,type:"file",name:R,accept:f,multiple:h,required:L&&0===O.length,disabled:H,tabIndex:-1,"aria-hidden":"true",className:"absolute size-px overflow-hidden opacity-0 [clip-path:inset(50%)]",onChange:e=>Q(Array.from(e.target.files??[]))})]}),B&&O.length>0?e("ul",{className:["mp-file-picker__list m-0 flex w-full list-none flex-col p-0",p[$]].join(" "),children:O.map((n,i)=>r("li",{className:["rounded-mp-xs bg-mp-surface-container-low flex w-full items-center gap-3","px-3 py-2",c[$],M?"text-mp-on-surface/38":"text-mp-on-surface"].join(" "),children:[e("span",{className:"min-w-0 flex-1 truncate",children:n.name}),e("span",{className:[s,"shrink-0 tabular-nums",M?"text-mp-on-surface/38":"text-mp-on-surface-variant"].join(" "),children:formatFileSize(n.size)}),H?null:r("button",{type:"button","aria-label":D(n.name),className:["group text-mp-on-surface-variant relative flex size-8 shrink-0","cursor-pointer appearance-none items-center justify-center rounded-full","bg-transparent p-0 font-[inherit] outline-none"].join(" "),onClick:()=>J(O.filter((e,r)=>r!==i)),children:[e(o,{}),e(t,{icon:a,size:18})]})]},`${n.name}-${n.size}-${n.lastModified}-${i}`))}):null,G?e("span",{id:Y,className:[s,"text-mp-error"].join(" "),children:w}):u(k)?e("span",{id:Y,className:[s,M?"text-mp-on-surface/38":"text-mp-on-surface-variant"].join(" "),children:k}):null]})});
1
+ import{jsx as e,jsxs as r}from"react/jsx-runtime";import*as n from"react";import{MPIcon as t}from"../icon/MPIcon";import{CloseIcon as a,UploadIcon as i}from"../../constants/icons";import{fillMessage as o}from"../../internal/i18n";import{useMPLocale as l,useMPMessages as s}from"../../internal/locale";import{MPStateLayer as c}from"../../internal/StateLayer";import{CONTROL_ICON as p,META_TEXT as m,PROSE_TEXT as u,STACK_GAP as d,hasContent as f}from"../../internal/scale";const h={xs:"p-4",sm:"p-5",md:"p-6",lg:"p-8",xl:"p-10"};export function formatFileSize(e){if(e<1e3)return`${e} B`;const r=["kB","MB","GB","TB"];let n=e/1e3,t=0;for(;n>=1e3&&t<r.length-1;)n/=1e3,t+=1;return`${n<10?n.toFixed(1):Math.round(n)} ${r[t]}`}function x(e,r){const n=e.name.toLowerCase(),t=e.type.toLowerCase();return r.split(",").map(e=>e.trim().toLowerCase()).filter(Boolean).some(e=>e.startsWith(".")?n.endsWith(e):e.endsWith("/*")?t.startsWith(e.slice(0,-1)):t===e)}export const MPFilePicker=n.forwardRef(function({accept:b,multiple:v=!1,maxSize:g,maxFiles:y,value:N,defaultValue:j,onFilesChange:k,onReject:w,label:z,description:C,errorMessage:I,title:B,hint:D,icon:F,showList:L=!0,removeLabel:M,locale:S,size:$="md",fullWidth:T=!0,required:W=!1,disabled:_=!1,readOnly:P=!1,name:R,id:E},O){const q=l(S),A=s("common",q),V=n.useRef(null);n.useImperativeHandle(O,()=>V.current,[]);const[G,H]=n.useState(()=>[...j??[]]),Y=N?[...N]:G,J=n.useRef(0),[K,Q]=n.useState(!1),U=f(I),X=_||P,Z=n.useId(),ee=n.useId(),re=n.useCallback(e=>{N||H(e),k?.(e)},[k,N]),ne=n.useCallback(e=>{const r=[],n=[],t=v?y??Number.POSITIVE_INFINITY:1,a=v?Y.length:0;for(const i of e)b&&!x(i,b)?n.push({file:i,reason:"type"}):void 0!==g&&i.size>g?n.push({file:i,reason:"size"}):a+r.length>=t?n.push({file:i,reason:"count"}):r.push(i);return{kept:r,rejections:n}},[b,Y.length,y,g,v]),te=n.useCallback(e=>{const{kept:r,rejections:n}=ne(e);n.length>0&&w?.(n),r.length>0&&re(v?[...Y,...r]:r)},[ne,re,Y,v,w]);return r("div",{className:["mp-file-picker flex-col align-top",d[$],T?"flex w-full":"inline-flex"].join(" "),"data-mp-size":$,"data-disabled":_||void 0,"data-invalid":U||void 0,children:[f(z)?r("span",{id:ee,className:[m,_?"text-mp-on-surface/38":U?"text-mp-error":"text-mp-on-surface-variant"].join(" "),children:[z,W?e("span",{"aria-hidden":"true",children:" *"}):null]}):null,r("div",{className:"flex w-full flex-col",onDragEnter:e=>{X||(e.preventDefault(),J.current+=1,Q(!0))},onDragOver:e=>{X||(e.preventDefault(),e.dataTransfer.dropEffect="copy")},onDragLeave:()=>{X||(J.current=Math.max(0,J.current-1),0===J.current&&Q(!1))},onDrop:e=>{X||(e.preventDefault(),J.current=0,Q(!1),te(Array.from(e.dataTransfer.files)))},children:[r("button",{type:"button",id:E,disabled:_,"aria-describedby":f(C)||U?Z:void 0,"aria-invalid":U||void 0,className:["mp-file-picker__zone group relative flex w-full flex-col items-center","justify-center gap-2 text-center","rounded-mp-md box-border border-2 border-dashed","appearance-none bg-transparent font-[inherit] outline-none","transition-[border-color,background-color] duration-(--mp-sys-motion-duration-short4)",h[$],u[$],_?"border-mp-on-surface/12 text-mp-on-surface/38 cursor-default":[P?"cursor-default":"cursor-pointer",U?"border-mp-error":"border-mp-outline-variant","text-mp-on-surface",K?"border-mp-primary bg-mp-primary/8":""].filter(Boolean).join(" ")].filter(Boolean).join(" "),onClick:()=>{!X&&V.current&&(V.current.value="",V.current.click())},children:[X?null:e(c,{layer:"inset-0 rounded-[inherit] bg-mp-primary"}),void 0===F?e(t,{icon:i,size:1.6*p[$],className:_?"":"text-mp-primary"}):f(F)?e("span",{className:_?"":"text-mp-primary",children:F}):null,e("span",{className:"font-medium",children:B??"Drop files here, or click to browse"}),f(D)?e("span",{className:[m,_?"text-mp-on-surface/38":"text-mp-on-surface-variant"].join(" "),children:D}):null]}),e("input",{ref:V,type:"file",name:R,accept:b,multiple:v,required:W&&0===Y.length,disabled:X,tabIndex:-1,"aria-labelledby":f(z)?ee:void 0,"aria-describedby":f(C)||U?Z:void 0,className:"absolute size-px overflow-hidden opacity-0 [clip-path:inset(50%)]",onChange:e=>te(Array.from(e.target.files??[]))})]}),L&&Y.length>0?e("ul",{className:["mp-file-picker__list m-0 flex w-full list-none flex-col p-0",d[$]].join(" "),children:Y.map((n,i)=>r("li",{className:["rounded-mp-xs bg-mp-surface-container-low flex w-full items-center gap-3","px-3 py-2",u[$],_?"text-mp-on-surface/38":"text-mp-on-surface"].join(" "),children:[e("span",{className:"min-w-0 flex-1 truncate",children:n.name}),e("span",{className:[m,"shrink-0 tabular-nums",_?"text-mp-on-surface/38":"text-mp-on-surface-variant"].join(" "),children:formatFileSize(n.size)}),X?null:r("button",{type:"button","aria-label":M?M(n.name):o(A.removeNamed,{label:n.name}),className:["group text-mp-on-surface-variant relative flex size-8 shrink-0","cursor-pointer appearance-none items-center justify-center rounded-full","bg-transparent p-0 font-[inherit] outline-none"].join(" "),onClick:()=>re(Y.filter((e,r)=>r!==i)),children:[e(c,{}),e(t,{icon:a,size:18})]})]},`${n.name}-${n.size}-${n.lastModified}-${i}`))}):null,U?e("span",{id:Z,className:[m,"text-mp-error"].join(" "),children:I}):f(C)?e("span",{id:Z,className:[m,_?"text-mp-on-surface/38":"text-mp-on-surface-variant"].join(" "),children:C}):null]})});
@@ -0,0 +1,126 @@
1
+ import * as React from 'react';
2
+ import type { MPColor, MPCorner, MPPosition, MPSize } from '../../types';
3
+ /**
4
+ * The three containers MD3 gives a floating button, and the reason there are not
5
+ * five of them.
6
+ *
7
+ * - `tonal` is the specification's own default: the accent *container* under its
8
+ * own ink, which is `primary-container` on `on-primary-container` before any
9
+ * colour is chosen.
10
+ * - `filled` is the accent itself, for the one screen where the button has to
11
+ * carry more weight than the content behind it.
12
+ * - `elevated` is MD3's *surface* FAB: a neutral container with the accent as
13
+ * the glyph, for a button floating over something colourful enough that a
14
+ * tonal one has nothing quiet to sit on.
15
+ *
16
+ * `outlined` and `text` are absent because a floating button *is* its container.
17
+ * A hairline disc over a scrolling page is a shape with the page moving through
18
+ * it, and a text one is a glyph with nothing to press.
19
+ */
20
+ export type MPFloatingActionButtonVariant = 'filled' | 'tonal' | 'elevated';
21
+ export interface MPFloatingActionButtonProps extends Omit<React.ComponentPropsWithoutRef<'button'>, 'color'> {
22
+ /**
23
+ * The glyph.
24
+ *
25
+ * Wrap it in an [MPIcon](../display/icon) when it needs a size of its own;
26
+ * passed bare it is drawn at the rung's own glyph size.
27
+ */
28
+ icon?: React.ReactNode;
29
+ /**
30
+ * What the button does, in words.
31
+ *
32
+ * Required, and the one prop here that is. A button whose whole label is a
33
+ * drawing has no accessible name at all, and "a floating button with no
34
+ * `aria-label`" is a defect that ships precisely because the control looks
35
+ * finished without one. With `extended` this is also the word written on the
36
+ * button, so the two can never say different things.
37
+ */
38
+ label: string;
39
+ /**
40
+ * Writes `label` beside the glyph, which turns the disc into a stadium — MD3's
41
+ * extended floating button, for the one action a screen is about.
42
+ * @default false
43
+ */
44
+ extended?: boolean;
45
+ /**
46
+ * Which container it paints.
47
+ * @default 'tonal'
48
+ */
49
+ variant?: MPFloatingActionButtonVariant;
50
+ /**
51
+ * Which accent family it reads. Not an arbitrary colour: to change what
52
+ * `primary` *is*, set the token.
53
+ * @default 'primary'
54
+ */
55
+ color?: MPColor;
56
+ /**
57
+ * The button's size. `md` is MD3's own 56dp; `xs` and `xl` are the
58
+ * specification's small and large floating buttons at 40 and 96dp.
59
+ * @default 'md'
60
+ */
61
+ size?: MPSize;
62
+ /**
63
+ * How it sits in the page. `fixed` — the default, against the `static`
64
+ * everything else in this library defaults to — is what a floating button *is*:
65
+ * held against a corner of the window whatever the page under it does.
66
+ *
67
+ * `absolute` pins it to the nearest positioned ancestor instead, which is what
68
+ * a button floating over a card or a map wants. `static` puts it back in the
69
+ * flow — drawn as `position: relative`, because the state layer still needs
70
+ * something to fill.
71
+ * @default 'fixed'
72
+ */
73
+ position?: MPPosition;
74
+ /**
75
+ * Which corner it is pinned to. Logical, so `bottom-end` is bottom-left under
76
+ * RTL. No effect while `position` is `static`.
77
+ * @default 'bottom-end'
78
+ */
79
+ corner?: MPCorner;
80
+ /**
81
+ * How far in from both edges, as a CSS length or a number of pixels. MD3's own
82
+ * is 16dp.
83
+ * @default 16
84
+ */
85
+ offset?: number | string;
86
+ /** Unavailable. Keeps its place, stops answering, and stops floating. */
87
+ disabled?: boolean;
88
+ /**
89
+ * `button`, not `submit`. A native button defaults to submitting the form
90
+ * around it.
91
+ * @default 'button'
92
+ */
93
+ type?: 'button' | 'submit' | 'reset';
94
+ }
95
+ /**
96
+ * The one action a screen is about, floating over it.
97
+ *
98
+ * MD3's floating action button, drawn from the specification's own component
99
+ * tokens: the three containers, the three sizes with the corner each of them
100
+ * takes, level-3 elevation, the state layer, and the extended shape. The default
101
+ * — `tonal` on `primary` — is the specification's default FAB exactly:
102
+ * `primary-container` under `on-primary-container`.
103
+ *
104
+ * ## Why there is no speed dial
105
+ *
106
+ * A floating button that fans out into three or four smaller ones is a Material
107
+ * **2** pattern, and MD3 dropped it. It was never good: the actions are
108
+ * unlabelled discs in the corner of the screen, they cover the content the
109
+ * reader was looking at, and a fan of buttons that claims `role="menu"` without
110
+ * the keyboard contract of one is worse for a keyboard reader than something
111
+ * that never claimed anything.
112
+ *
113
+ * When there genuinely are several actions, they belong in an
114
+ * [MPMenu](../inputs/menu) — which *is* a menu, with the roving focus, the
115
+ * typeahead and the escape behaviour that word promises — opened from this
116
+ * button.
117
+ *
118
+ * ## Why it is `fixed` by default
119
+ *
120
+ * Because that is the component. Everything else in this library sits in the
121
+ * page's flow and would be wrong to take out of it; this one is defined by not
122
+ * being part of the page. `position="absolute"` is the escape hatch for a button
123
+ * that belongs to a region rather than to the window, and `static` puts it back
124
+ * in the flow entirely.
125
+ */
126
+ export declare const MPFloatingActionButton: React.ForwardRefExoticComponent<MPFloatingActionButtonProps & React.RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1 @@
1
+ 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";import{MPStateLayer as i}from"../../internal/StateLayer";import{hasContent as s}from"../../internal/scale";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=a.forwardRef(function({icon:a,label:b,extended:g=!1,variant:h="tonal",color:w="primary",size:y="md",position:_="fixed",corner:v="bottom-end",offset:j=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[v]}`,N??""].filter(Boolean).join(" "),style:{...n(w),"--_mp-fab-offset":"number"==typeof j?`${j}px`:j,...$},...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})})]})});
@@ -0,0 +1,2 @@
1
+ export { MPFloatingActionButton } from './MPFloatingActionButton';
2
+ export type { MPFloatingActionButtonProps, MPFloatingActionButtonVariant } from './MPFloatingActionButton';
@@ -0,0 +1 @@
1
+ export{MPFloatingActionButton}from"./MPFloatingActionButton";
@@ -0,0 +1,155 @@
1
+ import * as React from 'react';
2
+ import { useRender } from '@base-ui/react/use-render';
3
+ import type { MPResponsive } from '../../types';
4
+ /**
5
+ * How a row divides the space its items did not take.
6
+ *
7
+ * CSS's own words rather than a set of this library's, because this is CSS's own
8
+ * question: a grid is the one component whose props are asking the layout engine
9
+ * for something directly, and inventing a second spelling for `space-between`
10
+ * would mean a caller has to translate what they already know.
11
+ */
12
+ export type MPGridJustify = 'start' | 'center' | 'end' | 'space-between' | 'space-around' | 'space-evenly';
13
+ /** How items sit against each other across a row. */
14
+ export type MPGridAlign = 'start' | 'center' | 'end' | 'stretch' | 'baseline';
15
+ /** The same, for one item overriding the row it is in. */
16
+ export type MPGridAlignSelf = MPGridAlign | 'auto';
17
+ export interface MPGridProps extends React.ComponentPropsWithoutRef<'div'> {
18
+ /**
19
+ * How many columns a row is divided into. Every `span` and every `offset`
20
+ * inside is read against this number, so `columns={24}` makes `span={12}` a
21
+ * half rather than a full width.
22
+ *
23
+ * MD3's own layout grid is `{ compact: 4, medium: 12 }`.
24
+ * @default 12
25
+ */
26
+ columns?: MPResponsive<number>;
27
+ /**
28
+ * The gutter between items, on Tailwind's spacing scale — `spacing={4}` is
29
+ * `1rem`, the same length `gap-4` is. Fractions are allowed, so `1.5` is
30
+ * `0.375rem`.
31
+ *
32
+ * MD3's own gutter is `{ compact: 4, medium: 6 }` — 16dp on a phone, 24dp from
33
+ * a medium window up.
34
+ * @default 4
35
+ */
36
+ spacing?: MPResponsive<number>;
37
+ /** The gutter between rows only. Falls back to `spacing`. */
38
+ rowSpacing?: MPResponsive<number>;
39
+ /** The gutter between columns only. Falls back to `spacing`. */
40
+ columnSpacing?: MPResponsive<number>;
41
+ /** How a row distributes the width its items did not use. */
42
+ justifyContent?: MPGridJustify;
43
+ /**
44
+ * How items sit against each other across a row.
45
+ * @default 'stretch'
46
+ */
47
+ alignItems?: MPGridAlign;
48
+ /** Where the rows sit when the grid is shorter than the box holding it. */
49
+ alignContent?: MPGridJustify | 'stretch';
50
+ /**
51
+ * Whether a row that runs out of columns continues on the next one. Turned
52
+ * off, the grid is one row that overflows — which is what a horizontally
53
+ * scrolling strip wants and nothing else does.
54
+ * @default true
55
+ */
56
+ wrap?: boolean;
57
+ /**
58
+ * Renders something other than a `<div>`: `render={<section />}`,
59
+ * `render={<ul />}`. Base UI's own escape hatch, so it behaves here exactly as
60
+ * it does on every Base UI primitive.
61
+ */
62
+ render?: useRender.RenderProp;
63
+ /** The `MPGridItem`s. */
64
+ children?: React.ReactNode;
65
+ }
66
+ export interface MPGridItemProps extends React.ComponentPropsWithoutRef<'div'> {
67
+ /**
68
+ * How many of the grid's columns the item takes. Read against the grid's
69
+ * `columns`, so `span={6}` is half of the default twelve and a quarter of
70
+ * `columns={24}`.
71
+ *
72
+ * Responsive: `span={{ compact: 12, medium: 6, expanded: 4 }}` is full width on
73
+ * a phone, half from 600dp and a third from 840dp. Each entry applies from its
74
+ * own window class up, so two of them usually describe a whole layout.
75
+ *
76
+ * A span wider than the row is clamped to the row rather than overflowing.
77
+ * @default the grid's full width
78
+ */
79
+ span?: MPResponsive<number>;
80
+ /**
81
+ * Columns left empty *before* the item — space pushed in ahead of it, not an
82
+ * absolute position in the row. First in a twelve-column row, `offset={4}` with
83
+ * `span={4}` is the middle third; after an item that already took four columns,
84
+ * the same offset skips four more and lands on the last third.
85
+ *
86
+ * Responsive in the same way `span` is.
87
+ * @default 0
88
+ */
89
+ offset?: MPResponsive<number>;
90
+ /** Overrides the row's `alignItems` for this item alone. */
91
+ alignSelf?: MPGridAlignSelf;
92
+ /**
93
+ * Renders something other than a `<div>`: `render={<li />}`,
94
+ * `render={<article />}`. Base UI's own escape hatch.
95
+ */
96
+ render?: useRender.RenderProp;
97
+ children?: React.ReactNode;
98
+ }
99
+ /**
100
+ * Material's layout grid: a row divided into columns, and items that take some
101
+ * of them.
102
+ *
103
+ * MD3 describes a page as a number of columns with a gutter between them, and
104
+ * describes how that number changes with the **window size class** rather than
105
+ * with a pixel width — four columns in a compact window, twelve from medium up.
106
+ * That is what this component is, and it is why `span` and `columns` take
107
+ * `{ compact, medium, expanded, large, extra-large }` rather than a set of
108
+ * breakpoints of the library's own invention. See `MPWindowClass` for why those
109
+ * are not Tailwind's four.
110
+ *
111
+ * ## Why the widths are real CSS and not utilities
112
+ *
113
+ * They cannot be utilities. A column is
114
+ * `(100% + gutter) * span / columns - gutter`, it has to be recomputed at four
115
+ * widths, and it is the width of an element whose column count is declared on its
116
+ * *parent* — none of which Tailwind can spell, because Tailwind finds classes by
117
+ * scanning source text and `columns` is a number the caller picks at runtime.
118
+ *
119
+ * So the arithmetic is written once, in `src/styles.css`, and the per-instance
120
+ * numbers arrive as inline `--_mp-*` slots — exactly how a `color` reaches a
121
+ * background in this library. The count and the two gutters are declared on the
122
+ * grid and *inherited* by the items rather than passed through a React context,
123
+ * which is not a shortcut: a media query can change an inherited custom property
124
+ * without React hearing about it, so the column count an item lays itself out
125
+ * against is always the one that is actually on screen. A context would have to
126
+ * re-render the subtree at every window class to say the same thing.
127
+ *
128
+ * ## Why a grid paints nothing
129
+ *
130
+ * No `variant`, no `color`, no padding. A grid is not a surface — it is the
131
+ * arrangement of the surfaces inside it — and the moment it draws a sheet of its
132
+ * own it stops being usable as the outermost thing on a page. Wrap it in an
133
+ * [MPBox](./box) or an [MPCard](./card) when the sheet is wanted, and in an
134
+ * [MPContainer](./container) when what is wanted is the page margin.
135
+ *
136
+ * Nesting is an `MPGrid` inside an `MPGridItem`, not a grid that is also an item:
137
+ * the inner grid redeclares the column count for its own subtree while the item
138
+ * around it keeps the width the outer grid gave it.
139
+ */
140
+ export declare const MPGrid: React.ForwardRefExoticComponent<MPGridProps & React.RefAttributes<HTMLDivElement>>;
141
+ /**
142
+ * One cell of an `MPGrid`.
143
+ *
144
+ * It is a width and nothing else — no surface, no padding, no typography. What
145
+ * goes inside brings its own, which is the whole reason a cell and an
146
+ * [MPBox](./box) are two components: wrapping something in a layout must not
147
+ * change how it looks, and a cell that drew a sheet would make `span` a visual
148
+ * decision.
149
+ *
150
+ * The column count it divides by is inherited from the grid as a custom
151
+ * property, so an item with no `MPGrid` above it falls back to twelve rather than
152
+ * breaking. It will still be a plain block in a plain parent, which is not a
153
+ * layout — always wrap.
154
+ */
155
+ export declare const MPGridItem: React.ForwardRefExoticComponent<MPGridItemProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1 @@
1
+ import*as e from"react";import{useRender as t}from"@base-ui/react/use-render";const n=["compact","medium","expanded","large","extra-large"];function r(e,t,r){const a=function(e){return null==e?{}:"object"==typeof e?e:{compact:e}}(t),s={};for(const t of n){const n=a[t];void 0!==n&&(s[`--_mp-${e}-${t}`]=r(n))}return s}function a(e,t){return null==e?t:"object"==typeof e?{compact:t,...e}:e}function s(e){return String(Math.max(1,Math.round(e)))}function o(e){return String(Math.max(1,Math.round(e)))}function c(e){return String(Math.max(0,Math.round(e)))}function i(e){const t=.25*Math.max(0,e);return`${Number(t.toFixed(5))}rem`}const l={start:"justify-start",center:"justify-center",end:"justify-end","space-between":"justify-between","space-around":"justify-around","space-evenly":"justify-evenly"},f={start:"items-start",center:"items-center",end:"items-end",stretch:"items-stretch",baseline:"items-baseline"},u={start:"content-start",center:"content-center",end:"content-end","space-between":"content-between","space-around":"content-around","space-evenly":"content-evenly",stretch:"content-stretch"},p={auto:"self-auto",start:"self-start",center:"self-center",end:"self-end",stretch:"self-stretch",baseline:"self-baseline"};export const MPGrid=e.forwardRef(function({columns:e,spacing:n,rowSpacing:o,columnSpacing:c,justifyContent:p,alignItems:d,alignContent:m,wrap:y=!0,render:g,className:h,style:x,children:b,...j},w){return t({render:g,ref:w,props:{className:["mp-grid flex",y?"flex-wrap":"flex-nowrap","gap-x-(--_mp-gap-x) gap-y-(--_mp-gap-y)",p?l[p]:"",d?f[d]:"",m?u[m]:"",h??""].filter(Boolean).join(" "),style:{...r("cols",a(e,12),s),...r("gap-x",a(c??n,4),i),...r("gap-y",a(o??n,4),i),...x},children:b,...j}})});export const MPGridItem=e.forwardRef(function({span:e,offset:n,alignSelf:a,render:s,className:i,style:l,children:f,...u},d){return t({render:s,ref:d,props:{className:["mp-grid-item",a?p[a]:"",i??""].filter(Boolean).join(" "),style:{...r("span",e,o),...r("offset",n,c),...l},children:f,...u}})});
@@ -0,0 +1,2 @@
1
+ export { MPGrid, MPGridItem } from './MPGrid';
2
+ export type { MPGridAlign, MPGridAlignSelf, MPGridItemProps, MPGridJustify, MPGridProps } from './MPGrid';
@@ -0,0 +1 @@
1
+ export{MPGrid,MPGridItem}from"./MPGrid";
@@ -1 +1 @@
1
- import{jsx as e}from"react/jsx-runtime";import*as n from"react";import{accentSlots as t}from"../../internal/accent";const r={filled:"bg-(--_mp-accent) text-(--_mp-on-accent)",tonal:"bg-(--_mp-accent-container) text-(--_mp-on-accent-container)",outlined:"border border-(--_mp-accent) bg-transparent text-(--_mp-accent)",text:"bg-transparent text-(--_mp-accent)"},o={regular:"font-normal",medium:"font-medium",semibold:"font-semibold",bold:"font-bold"},i=/[\p{L}\p{N}_]/u;function l(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function a(e,n,t){const r=n>0?e[n-1]:"",o=t<e.length?e[t]:"";return!i.test(r)&&!i.test(o)}function c(e,n,t,r){n.lastIndex=0;const o=[];let i,l=0;for(;null!==(i=n.exec(e));){if(""===i[0]){n.lastIndex+=1;continue}const c=i.index,s=c+i[0].length;t&&!a(e,c,s)||(c>l&&o.push(e.slice(l,c)),o.push(r(i[0],String(c))),l=s)}return 0===o.length?e:(l<e.length&&o.push(e.slice(l)),o)}function s(e,t,r,o){if("string"==typeof e)return c(e,t,r,o);if("number"==typeof e)return c(String(e),t,r,o);if(Array.isArray(e))return n.Children.map(e,e=>s(e,t,r,o));if(n.isValidElement(e)){const i=e.props.children;return void 0===i||"function"==typeof i?e:n.cloneElement(e,void 0,s(i,t,r,o))}return e}export const MPHighlight=n.forwardRef(function({query:i,variant:a="tonal",color:c="tertiary",caseSensitive:u=!1,wholeWord:m=!1,underline:f=!1,weight:p,className:d,style:g,children:h,...x},b){const y=n.useMemo(()=>function(e,n){if(e instanceof RegExp)return e.global?e:new RegExp(e.source,`${e.flags}g`);const t=(Array.isArray(e)?e:[e]).map(e=>e.trim()).filter(Boolean).sort((e,n)=>n.length-e.length);return 0===t.length?null:new RegExp(t.map(l).join("|"),n?"gu":"giu")}(i,u),[i,u]),_=["rounded-mp-xs -mx-0.5 px-0.5","box-decoration-clone",r[a],f?"underline decoration-2 underline-offset-2":"",p?o[p]:""].filter(Boolean).join(" "),j=y?s(h,y,m,(n,t)=>e("mark",{className:_,children:n},t)):h;return e("span",{ref:b,className:["mp-highlight",d??""].filter(Boolean).join(" "),style:{...t(c),...g},...x,children:j})});
1
+ import{jsx as e}from"react/jsx-runtime";import*as n from"react";import{accentSlots as t}from"../../internal/accent";const r={filled:"bg-(--_mp-accent) text-(--_mp-on-accent)",tonal:"bg-(--_mp-accent-container) text-(--_mp-on-accent-container)",outlined:"border border-(--_mp-accent) bg-transparent text-(--_mp-accent)",text:"bg-transparent text-(--_mp-accent)"},o={regular:"font-normal",medium:"font-medium",semibold:"font-semibold",bold:"font-bold"},i=/[\p{L}\p{N}_]/u;function l(e){return e.replace(/[-.*+?^${}()|[\]\\]/g,"\\$&")}function a(e,n,t){const r=n>0?e[n-1]:"",o=t<e.length?e[t]:"";return!i.test(r)&&!i.test(o)}function c(e,n,t,r){n.lastIndex=0;const o=[];let i,l=0;for(;null!==(i=n.exec(e));){if(""===i[0]){n.lastIndex+=1;continue}const c=i.index,s=c+i[0].length;t&&!a(e,c,s)||(c>l&&o.push(e.slice(l,c)),o.push(r(i[0],String(c))),l=s)}return 0===o.length?e:(l<e.length&&o.push(e.slice(l)),o)}function s(e,t,r,o){if("string"==typeof e)return c(e,t,r,o);if("number"==typeof e)return c(String(e),t,r,o);if(Array.isArray(e))return n.Children.map(e,e=>s(e,t,r,o));if(n.isValidElement(e)){const i=e.props.children;return void 0===i||"function"==typeof i?e:n.cloneElement(e,void 0,s(i,t,r,o))}return e}export const MPHighlight=n.forwardRef(function({query:i,variant:a="tonal",color:c="tertiary",caseSensitive:u=!1,wholeWord:f=!1,underline:m=!1,weight:p,className:g,style:d,children:h,...x},b){const y=i instanceof RegExp?`re ${i.source} ${i.flags}`:Array.isArray(i)?`a ${i.join("\0")}`:`s ${i}`,_=n.useMemo(()=>function(e,n){if(e instanceof RegExp)return new RegExp(e.source,e.global?e.flags:`${e.flags}g`);const t=(Array.isArray(e)?e:[e]).map(e=>e.trim()).filter(Boolean).sort((e,n)=>n.length-e.length);return 0===t.length?null:new RegExp(t.map(l).join("|"),n?"gu":"giu")}(i,u),[y,u]),$=["rounded-mp-xs -mx-0.5 px-0.5","box-decoration-clone",r[a],m?"underline decoration-2 underline-offset-2":"",p?o[p]:""].filter(Boolean).join(" "),j=n.useMemo(()=>_?s(h,_,f,(n,t)=>e("mark",{className:$,children:n},t)):h,[h,_,f,$]);return e("span",{ref:b,className:["mp-highlight",g??""].filter(Boolean).join(" "),style:{...t(c),...d},...x,children:j})});
@@ -1 +1 @@
1
- import{jsx as e,jsxs as r,Fragment as n}from"react/jsx-runtime";import*as t from"react";import{useRender as i}from"@base-ui/react/use-render";import{accentSlots as o}from"../../internal/accent";import{CONTROL_GAP as l,hasContent as a,PROSE_TEXT as s,SHEET_PAD_X as c}from"../../internal/scale";import{MPStateLayer as d}from"../../internal/StateLayer";import{CONTAINER_SURFACE as m}from"../../internal/surface";const p=t.createContext({size:"md",color:"primary",dividers:!1}),u={xs:"py-1.5",sm:"py-2.5",md:"py-4",lg:"py-5",xl:"py-6"},f={xs:"text-mp-body-small",sm:"text-mp-body-small",md:"text-mp-body-medium",lg:"text-mp-body-medium",xl:"text-mp-body-medium"},x={xs:"rounded-mp-xs",sm:"rounded-mp-xs",md:"rounded-mp-sm",lg:"rounded-mp-sm",xl:"rounded-mp-md"};export const MPList=t.forwardRef(function({variant:r="outlined",size:n="md",color:l="primary",dividers:a=!1,render:s,className:c,style:d,children:u,...f},x){const h=t.useMemo(()=>({size:n,color:l,dividers:a}),[n,l,a]),v=["mp-list rounded-mp-md flex flex-col",m[r],"text-mp-on-surface",a?"overflow-hidden [&>li+li]:border-mp-outline-variant [&>li+li]:border-t":"p-1",c??""].filter(Boolean).join(" "),b=i({render:s??e("ul",{}),ref:x,props:{role:"list","data-mp-size":n,"data-mp-variant":r,className:v,style:{...o(l),...d},children:u,...f}});return e(p.Provider,{value:h,children:b})});export const MPListItem=t.forwardRef(function({startIcon:i,endIcon:o,description:m,action:h,href:v,selected:b=!1,disabled:y=!1,className:N,children:g,onClick:j,...k},w){const{size:z,dividers:C}=t.useContext(p),B=Boolean(j||v)&&!y,I=c[z],L=["group relative flex min-w-0 flex-1 items-center overflow-hidden text-start","font-[inherit] no-underline",I,u[z],l[z],s[z],"transition-[background-color,color] duration-(--mp-sys-motion-duration-short4)",C?"":x[z],y?"text-mp-on-surface/38 cursor-default":b?"bg-(--_mp-accent-container) text-(--_mp-on-accent-container)":"",B?["cursor-pointer appearance-none border-0 bg-transparent","outline-mp-secondary focus-visible:outline-2 focus-visible:-outline-offset-2","focus-visible:outline-solid outline-none"].join(" "):"",B&&b?"bg-(--_mp-accent-container)":""].filter(Boolean).join(" "),M=r(n,{children:[B?e(d,{}):null,a(i)?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:i}):null,r("span",{className:"flex min-w-0 flex-1 flex-col",children:[a(g)?e("span",{className:"truncate",children:g}):null,a(m)?e("span",{className:["truncate",f[z],b?"opacity-80":"text-mp-on-surface-variant"].join(" "),children:m}):null]}),a(o)?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:o}):null]});return r("li",{ref:w,"data-selected":b||void 0,className:["flex w-full items-center",N??""].filter(Boolean).join(" "),...k,children:[B&&v?e("a",{href:v,className:L,"aria-current":b?"page":void 0,onClick:j,children:M}):B?e("button",{type:"button",className:L,"aria-current":!!b||void 0,onClick:j,children:M}):e("div",{className:L,"aria-disabled":y||void 0,children:M}),a(h)?e("div",{className:`flex shrink-0 items-center ${I}`,children:h}):null]})});
1
+ import{jsx as e,jsxs as r,Fragment as n}from"react/jsx-runtime";import*as t from"react";import{useRender as i}from"@base-ui/react/use-render";import{accentSlots as o}from"../../internal/accent";import{CONTROL_GAP as l,hasContent as s,PROSE_TEXT as a,SHEET_PAD_X as d}from"../../internal/scale";import{MPStateLayer as c}from"../../internal/StateLayer";import{CONTAINER_SURFACE as m}from"../../internal/surface";const p=t.createContext({size:"md",color:"primary",dividers:!1}),u={xs:"py-1.5",sm:"py-2.5",md:"py-4",lg:"py-5",xl:"py-6"},f={xs:"text-mp-body-small",sm:"text-mp-body-small",md:"text-mp-body-medium",lg:"text-mp-body-medium",xl:"text-mp-body-medium"},x={xs:"rounded-mp-xs",sm:"rounded-mp-xs",md:"rounded-mp-sm",lg:"rounded-mp-sm",xl:"rounded-mp-md"};export const MPList=t.forwardRef(function({variant:r="outlined",size:n="md",color:l="primary",dividers:s=!1,render:a,className:d,style:c,children:u,...f},x){const h=t.useMemo(()=>({size:n,color:l,dividers:s}),[n,l,s]),v=["mp-list rounded-mp-md flex flex-col",m[r],"text-mp-on-surface",s?"overflow-hidden [&>li+li]:border-mp-outline-variant [&>li+li]:border-t":"p-1",d??""].filter(Boolean).join(" "),b=i({render:a??e("ul",{}),ref:x,props:{role:"list","data-mp-size":n,"data-mp-variant":r,className:v,style:{...o(l),...c},children:u,...f}});return e(p.Provider,{value:h,children:b})});export const MPListItem=t.forwardRef(function({startIcon:i,endIcon:o,description:m,action:h,href:v,selected:b=!1,disabled:y=!1,className:N,children:g,onClick:j,...k},w){const{size:z,dividers:B}=t.useContext(p),C=Boolean(j||v)&&!y,I=d[z],L=["group relative flex min-w-0 flex-1 items-center overflow-hidden text-start","font-[inherit] no-underline",I,u[z],l[z],a[z],"transition-[background-color,color] duration-(--mp-sys-motion-duration-short4)",B?"":x[z],y?"text-mp-on-surface/38 cursor-default":b?"bg-(--_mp-accent-container) text-(--_mp-on-accent-container)":"",C?["cursor-pointer appearance-none border-0",b?"":"bg-transparent","outline-mp-secondary focus-visible:outline-2 focus-visible:-outline-offset-2","focus-visible:outline-solid outline-none"].filter(Boolean).join(" "):""].filter(Boolean).join(" "),M=r(n,{children:[C?e(c,{}):null,s(i)?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:i}):null,r("span",{className:"flex min-w-0 flex-1 flex-col",children:[s(g)?e("span",{className:"truncate",children:g}):null,s(m)?e("span",{className:["truncate",f[z],b?"opacity-80":"text-mp-on-surface-variant"].join(" "),children:m}):null]}),s(o)?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:o}):null]});return r("li",{ref:w,"data-selected":b||void 0,className:["flex w-full items-center",N??""].filter(Boolean).join(" "),...k,children:[C&&v?e("a",{href:v,className:L,"aria-current":b?"page":void 0,onClick:j,children:M}):C?e("button",{type:"button",className:L,"aria-current":!!b||void 0,onClick:j,children:M}):e("div",{className:L,"aria-disabled":y||void 0,children:M}),s(h)?e("div",{className:`flex shrink-0 items-center ${I}`,children:h}):null]})});
@@ -78,6 +78,15 @@ export interface MPMenuItemProps {
78
78
  href?: string;
79
79
  /** Where the link opens — `_blank` and the rest. Ignored without `href`. */
80
80
  target?: string;
81
+ /**
82
+ * The link's relationship to the page. Ignored without `href`.
83
+ *
84
+ * Left unset, a `target="_blank"` row gets `noopener noreferrer` — the pair
85
+ * that stops the opened page reaching back through `window.opener`. Setting
86
+ * it replaces that rather than adding to it, so a row that needs `nofollow`
87
+ * should say `rel="noopener noreferrer nofollow"`.
88
+ */
89
+ rel?: string;
81
90
  /** Content before the label — an icon, a swatch, an avatar. */
82
91
  startIcon?: React.ReactNode;
83
92
  /** Content after the label, before any `shortcut`. */
@@ -160,7 +169,7 @@ export type MPMenuSeparatorProps = React.ComponentPropsWithoutRef<'div'>;
160
169
  * cannot be copied, and tells a screen reader the wrong thing about every one of
161
170
  * them.
162
171
  */
163
- export declare function MPMenuItem({ onClick, href, target, startIcon, endIcon, shortcut, description, color, closeOnClick, disabled, label, children, className, style }: MPMenuItemProps): React.JSX.Element;
172
+ export declare function MPMenuItem({ onClick, href, target, rel, startIcon, endIcon, shortcut, description, color, closeOnClick, disabled, label, children, className, style }: MPMenuItemProps): React.JSX.Element;
164
173
  /** A row that ticks. The tick lands in the column a `startIcon` would. */
165
174
  export declare function MPMenuCheckboxItem({ checked, defaultChecked, onCheckedChange, endIcon, shortcut, description, color, closeOnClick, disabled, label, children, className, style }: MPMenuCheckboxItemProps): React.JSX.Element;
166
175
  /** One choice out of a set. Wraps the rows that make up the set. */
@@ -1 +1 @@
1
- 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";import{CheckIcon as o,ChevronRightIcon as s}from"../../constants/icons";import{MPMenuContext as i}from"../../internal/menu";import{accentSlots as c}from"../../internal/accent";import{MPStateLayer as d}from"../../internal/StateLayer";import{CONTROL_ICON as m,META_TEXT as u,hasContent as p}from"../../internal/scale";import{FADE as h,PORTAL_LAYER as f}from"../../internal/surface";const x=["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,startIcon:s,endIcon:c,shortcut:d,description:m,color:u,closeOnClick:h=!0,disabled:f=!1,label:x,children:b,className:g,style:N}){const{size:v}=t.useContext(i),P=n(t.Fragment,{children:[e(y,{}),p(s)?e("span",{className:`${k} text-mp-on-surface-variant`,children:s}):null,e(M,{description:m,children:b}),p(c)?e("span",{className:`${k} text-mp-on-surface-variant`,children:c}):null,e(O,{shortcut:d})]}),I=u?{"--_mp-accent":`var(--_mp-color-${u})`}:void 0,$=I||N?{...I,...N}:void 0;return void 0!==r?e(a.LinkItem,{href:r,target:o,label:x,closeOnClick:h,onClick:l,className:C(v,Boolean(u),g),style:$,children:P}):e(a.Item,{disabled:f,label:x,closeOnClick:h,onClick:l,className:C(v,Boolean(u),g),style:$,children:P})}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:I}=t.useContext(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(I,Boolean(f),v),style:$||P?{...$,...P}:void 0,children:[e(y,{}),e("span",{className:`${k} text-(--_mp-accent)`,style:{width:m[I]},children:e(a.CheckboxItemIndicator,{className:"flex items-center justify-center",children:e(r,{icon:o,size:m[I]})})}),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})})})]})})}
1
+ 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";import{CheckIcon as o,ChevronRightIcon as s}from"../../constants/icons";import{MPMenuContext as i}from"../../internal/menu";import{accentSlots as c}from"../../internal/accent";import{MPStateLayer as d}from"../../internal/StateLayer";import{CONTROL_ICON as m,META_TEXT as u,hasContent as p}from"../../internal/scale";import{FADE as h,PORTAL_LAYER as f}from"../../internal/surface";const x=["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),I=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})]}),$=h?{"--_mp-accent":`var(--_mp-color-${h})`}:void 0,z=$||v?{...$,...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:z,children:I}):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:z,children:I})}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:I}=t.useContext(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(I,Boolean(f),v),style:$||P?{...$,...P}:void 0,children:[e(y,{}),e("span",{className:`${k} text-(--_mp-accent)`,style:{width:m[I]},children:e(a.CheckboxItemIndicator,{className:"flex items-center justify-center",children:e(r,{icon:o,size:m[I]})})}),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})})})]})})}
@@ -60,13 +60,31 @@ export interface MPNumberFieldProps extends MPStyleProps {
60
60
  incrementLabel?: string;
61
61
  /** The accessible name of the decrement button. @default 'Decrease' */
62
62
  decrementLabel?: string;
63
- /** Label in the outline's notch. */
63
+ /**
64
+ * Label for the field, drawn in the outline's notch and — while the field is
65
+ * empty, unfocused and has nothing standing at its start — resting on the
66
+ * field's own line where a placeholder would be. See `floatingLabel`.
67
+ */
64
68
  label?: React.ReactNode;
69
+ /**
70
+ * Whether the label rests on the field's line while there is nothing to make
71
+ * room for, and rises into the notch on focus or on the first digit.
72
+ *
73
+ * `false` pins it in the notch, which is the one thing a floating label costs:
74
+ * a field with a label and one without no longer sit at the same height in a
75
+ * form until both are filled. A `startIcon` — or `steppers="split"`, whose
76
+ * minus sits in the same place — holds the label up regardless.
77
+ * @default true
78
+ */
79
+ floatingLabel?: boolean;
65
80
  /** The line under the control. Replaced by `errorMessage` when there is one. */
66
81
  description?: React.ReactNode;
67
82
  /** The message under the control, which also turns the field over. */
68
83
  errorMessage?: React.ReactNode;
69
- /** Placeholder shown while the field is empty. */
84
+ /**
85
+ * Placeholder shown while the field is empty. With a floating label it is held
86
+ * back until the label has risen out of its way.
87
+ */
70
88
  placeholder?: string;
71
89
  /** Content placed before the number — a currency mark, a unit, an icon. */
72
90
  startIcon?: React.ReactNode;
@@ -96,4 +114,4 @@ export interface MPNumberFieldProps extends MPStyleProps {
96
114
  * owns the parsing against the locale, the clamping, the press-and-hold repeat on
97
115
  * the steppers, and the hidden input that submits with a form.
98
116
  */
99
- export declare function MPNumberField({ value, defaultValue, onValueChange, onValueCommitted, min, max, step, largeStep, smallStep, allowWheelScrub, format, locale, steppers, incrementLabel, decrementLabel, label, description, errorMessage, placeholder, startIcon, size, fullWidth, required, disabled, readOnly, name, id }: MPNumberFieldProps): React.JSX.Element;
117
+ export declare function MPNumberField({ value, defaultValue, onValueChange, onValueCommitted, min, max, step, largeStep, smallStep, allowWheelScrub, format, locale, steppers, incrementLabel, decrementLabel, label, floatingLabel, description, errorMessage, placeholder, startIcon, size, fullWidth, required, disabled, readOnly, name, id }: MPNumberFieldProps): React.JSX.Element;
@@ -1 +1 @@
1
- import{jsx as e,jsxs as a}from"react/jsx-runtime";import*as r from"react";import{NumberField as l}from"@base-ui/react/number-field";import{Field as n}from"@base-ui/react/field";import{MPIcon as t}from"../icon/MPIcon";import{AddIcon as i,RemoveIcon as s}from"../../constants/icons";import{MPFieldLabel as o,MPFieldOutline as p}from"../../internal/FieldOutline";import{MPStateLayer as m}from"../../internal/StateLayer";import{MPSupportingText as d}from"../../internal/SupportingText";import{CONTROL_ICON as c,PROSE_TEXT as u,hasContent as f}from"../../internal/scale";const h={xs:{padding:"px-2",height:"h-8",stepper:"size-6"},sm:{padding:"px-3",height:"h-10",stepper:"size-8"},md:{padding:"px-4",height:"h-14",stepper:"size-10"},lg:{padding:"px-4",height:"h-16",stepper:"size-11"},xl:{padding:"px-5",height:"h-18",stepper:"size-12"}};export function MPNumberField({value:x,defaultValue:g,onValueChange:b,onValueCommitted:N,min:v,max:z,step:j,largeStep:y,smallStep:w,allowWheelScrub:S=!1,format:I,locale:V,steppers:q="end",incrementLabel:C="Increase",decrementLabel:M="Decrease",label:k,description:F,errorMessage:L,placeholder:O,startIcon:W,size:D="md",fullWidth:P=!1,required:R=!1,disabled:$=!1,readOnly:_=!1,name:B,id:G}){const T=f(L),A=h[D],E=r.useId(),H=G??`mp-number-field-${B??E}`,J="none"!==q&&!_&&!$,K=["mp-number-field__stepper group relative flex shrink-0 items-center justify-center","rounded-mp-full cursor-pointer appearance-none bg-transparent p-0 font-[inherit]","text-mp-on-surface-variant outline-none","disabled:text-mp-on-surface/38 disabled:cursor-default",A.stepper].join(" "),Q=a(l.Decrement,{"aria-label":M,className:K,children:[e(m,{}),e(t,{icon:s,size:c[D]})]}),U=a(l.Increment,{"aria-label":C,className:K,children:[e(m,{}),e(t,{icon:i,size:c[D]})]});return a(n.Root,{className:["mp-number-field group flex-col align-top",P?"flex w-full":"inline-flex w-fit"].join(" "),disabled:$,invalid:T,"data-mp-size":D,children:[e(l.Root,{id:H,name:B,className:"contents",value:x,defaultValue:g,onValueChange:e=>b?.(e),onValueCommitted:e=>N?.(e),min:v,max:z,step:j,largeStep:y,smallStep:w,allowWheelScrub:S,format:I,locale:V,disabled:$,readOnly:_,required:R,children:a("div",{className:"relative w-full",children:[a(l.Group,{className:["flex w-full items-center gap-2",A.height,J&&"end"===q?`${A.padding} pe-1`:J&&"split"===q?"px-1":A.padding].join(" "),children:[J&&"split"===q?Q:null,W?e("span",{className:["flex shrink-0 items-center",$?"text-mp-on-surface/38":"text-mp-on-surface-variant"].join(" "),children:W}):null,e(l.Input,{placeholder:O,className:["w-full min-w-0 flex-1 tabular-nums",u[D],"font-[family-name:var(--mp-sys-typescale-body-large-font)]","appearance-none border-0 bg-transparent px-0 outline-none","caret-mp-primary text-mp-on-surface","placeholder:text-mp-on-surface-variant","disabled:text-mp-on-surface/38 disabled:placeholder:text-mp-on-surface/38",J&&"split"===q?"text-center":""].filter(Boolean).join(" ")}),J&&"end"===q?a("span",{className:"flex shrink-0 items-center",children:[Q,U]}):null,J&&"split"===q?U:null]}),e(p,{label:k,required:R}),f(k)?e(o,{size:D,label:k,required:R,htmlFor:H}):null]})}),e(d,{description:F,errorMessage:L,className:A.padding})]})}
1
+ import{jsx as e,jsxs as a}from"react/jsx-runtime";import*as l from"react";import{NumberField as n}from"@base-ui/react/number-field";import{Field as r}from"@base-ui/react/field";import{MPIcon as t}from"../icon/MPIcon";import{AddIcon as i,RemoveIcon as s}from"../../constants/icons";import{MPFieldLabel as o,MPFieldOutline as p,useFloatingLabel as d}from"../../internal/FieldOutline";import{MPStateLayer as m}from"../../internal/StateLayer";import{MPSupportingText as c}from"../../internal/SupportingText";import{CONTROL_ICON as u,PROSE_TEXT as f,hasContent as h}from"../../internal/scale";const x={xs:{padding:"px-2",height:"h-8",stepper:"size-6"},sm:{padding:"px-3",height:"h-10",stepper:"size-8"},md:{padding:"px-4",height:"h-14",stepper:"size-10"},lg:{padding:"px-4",height:"h-16",stepper:"size-11"},xl:{padding:"px-5",height:"h-18",stepper:"size-12"}};export function MPNumberField({value:g,defaultValue:b,onValueChange:v,onValueCommitted:N,min:z,max:j,step:y,largeStep:S,smallStep:w,allowWheelScrub:I=!1,format:V,locale:k,steppers:q="end",incrementLabel:C="Increase",decrementLabel:L="Decrease",label:M,floatingLabel:F=!0,description:O,errorMessage:P,placeholder:W,startIcon:D,size:R="md",fullWidth:_=!1,required:B=!1,disabled:G=!1,readOnly:T=!1,name:$,id:A}){const E=h(P),H=x[R],J=l.useId(),K=A??J,Q="none"!==q&&!T&&!G,[U,X]=l.useState(b??null),Y=void 0===g?U:g,{shrunk:Z,focusProps:ee}=d({floating:F&&h(M),filled:null!==Y,pinned:!!D||Q&&"split"===q}),ae=["mp-number-field__stepper group relative flex shrink-0 items-center justify-center","rounded-mp-full cursor-pointer appearance-none bg-transparent p-0 font-[inherit]","text-mp-on-surface-variant outline-none","disabled:text-mp-on-surface/38 disabled:cursor-default",H.stepper].join(" "),le=a(n.Decrement,{"aria-label":L,className:ae,children:[e(m,{}),e(t,{icon:s,size:u[R]})]}),ne=a(n.Increment,{"aria-label":C,className:ae,children:[e(m,{}),e(t,{icon:i,size:u[R]})]});return a(r.Root,{className:["mp-number-field group flex-col align-top",_?"flex w-full":"inline-flex w-fit"].join(" "),disabled:G,invalid:E,"data-mp-size":R,...ee,children:[e(n.Root,{id:K,name:$,className:"contents",value:g,defaultValue:b,onValueChange:e=>{X(e),v?.(e)},onValueCommitted:e=>N?.(e),min:z,max:j,step:y,largeStep:S,smallStep:w,allowWheelScrub:I,format:V,locale:k,disabled:G,readOnly:T,required:B,children:a("div",{className:"relative w-full",children:[a(n.Group,{className:["flex w-full items-center gap-2",H.height,Q&&"end"===q?`${H.padding} pe-1`:Q&&"split"===q?"px-1":H.padding].join(" "),children:[Q&&"split"===q?le:null,D?e("span",{className:["flex shrink-0 items-center",G?"text-mp-on-surface/38":"text-mp-on-surface-variant"].join(" "),children:D}):null,e(n.Input,{placeholder:Z?W:void 0,className:["w-full min-w-0 flex-1 tabular-nums",f[R],"font-[family-name:var(--mp-sys-typescale-body-large-font)]","appearance-none border-0 bg-transparent px-0 outline-none","caret-mp-primary text-mp-on-surface","placeholder:text-mp-on-surface-variant","disabled:text-mp-on-surface/38 disabled:placeholder:text-mp-on-surface/38",Q&&"split"===q?"text-center":""].filter(Boolean).join(" ")}),Q&&"end"===q?a("span",{className:"flex shrink-0 items-center",children:[le,ne]}):null,Q&&"split"===q?ne:null]}),e(p,{label:M,required:B,notched:Z}),h(M)?e(o,{size:R,label:M,required:B,htmlFor:K,shrunk:Z}):null]})}),e(c,{description:O,errorMessage:P,className:H.padding})]})}