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
@@ -1 +1 @@
1
- import{jsx as e,jsxs as o,Fragment as t}from"react/jsx-runtime";import*as n from"react";import{MPButton as r}from"../components/button/MPButton";import{MPIcon as l}from"../components/icon/MPIcon";import{MPIconButton as a}from"../components/icon-button/MPIconButton";import{ChevronDownIcon as s,ChevronLeftIcon as c,ChevronRightIcon as i}from"../constants/icons";import{MPStateLayer as u}from"./StateLayer";import{CONTROL_ICON as m,META_TEXT as d,PROSE_TEXT as h}from"./scale";import{VISUALLY_HIDDEN as p}from"./visually-hidden";import{addDays as f,addMonths as g,addYears as v,calendarWeeks as w,compareDay as x,dateFormatter as y,daysInMonth as b,isDayOutside as D,isMonthBeforeYear as S,isSameDay as N,isSameMonth as M,isValidDate as P,makeDate as C,meridiemLabels as _,monthLabels as k,startOfDay as z,startOfMonth as F,today as Y,weekdayLabels as A,withTime as j,YEAR_PAGE_SIZE as E,yearPageStart as B}from"./date";const R={xs:"1.75rem",sm:"2rem",md:"2.5rem",lg:"2.75rem",xl:"3rem"},T={xs:"xs",sm:"xs",md:"sm",lg:"sm",xl:"md"},$=["group relative flex cursor-pointer items-center justify-center overflow-hidden","box-border appearance-none bg-transparent font-[inherit] tabular-nums select-none","transition-[background-color,border-color,color]","duration-(--mp-sys-motion-duration-short4)","outline-mp-secondary focus-visible:z-10 focus-visible:outline-2","focus-visible:outline-offset-[-2px] focus-visible:outline-solid outline-none"].join(" ");function H({children:t,label:n,selected:r,inRange:l=!1,rangeEdge:a=null,current:s=!1,muted:c=!1,disabled:i=!1,focused:m=!1,className:d,onClick:h,onPointerEnter:p,onKeyDown:f}){return o("button",{type:"button",role:"gridcell","aria-label":n,"aria-selected":r,"aria-current":s?"date":void 0,"aria-disabled":i||void 0,tabIndex:m?0:-1,"data-focus-target":m?"true":void 0,className:[$,"start"===a?"rounded-s-mp-full":"end"===a?"rounded-e-mp-full":"middle"===a?"rounded-none":"rounded-mp-full",i?"cursor-default text-mp-on-surface/38":r?"bg-(--_mp-accent) text-(--_mp-on-accent)":l?"bg-(--_mp-accent-container) text-(--_mp-on-accent-container)":s?"border border-(--_mp-accent) text-(--_mp-accent)":c?"text-mp-on-surface-variant":"text-mp-on-surface",d??""].filter(Boolean).join(" "),onClick:()=>{i||h()},onPointerEnter:p,onKeyDown:f,children:[i?null:e(u,{}),t]})}function K({size:n,color:u,view:d,month:p,locale:f,labels:g,showPreviousButton:v,showNextButton:w,onStep:x,onViewChange:y}){const b=k(f,"long")[p.getMonth()],D=String(p.getFullYear()),N=S(f),M=T[n],P="day"===d?[g.previousMonth,g.nextMonth]:"month"===d?[g.previousYear,g.nextYear]:[g.previousYears,g.nextYears],C=(o,t)=>t?e(a,{size:M,color:u,label:P[-1===o?0:1],icon:e(l,{icon:-1===o?c:i,size:m[M],className:"rtl:rotate-180"}),onClick:()=>x(o)}):e("span",{"aria-hidden":"true",className:"size-(--_mp-cell)"}),_=o=>e(l,{icon:s,size:m[M],className:["transition-transform duration-(--mp-sys-motion-duration-short4)",o?"rotate-180":""].filter(Boolean).join(" ")}),z=e(r,{variant:"text",size:M,color:u,"aria-label":g.chooseMonth,"aria-expanded":"month"===d,endIcon:_("month"===d),onClick:()=>y("month"===d?"day":"month"),children:b},"month"),F=e(r,{variant:"text",size:M,color:u,className:"tabular-nums","aria-label":g.chooseYear,"aria-expanded":"year"===d,endIcon:_("year"===d),onClick:()=>y("year"===d?"day":"year"),children:D},"year"),Y=B(p.getFullYear());return o("div",{className:"flex items-center justify-between gap-1",children:[C(-1,v),e("div",{className:"flex min-w-0 flex-1 items-center justify-center gap-1",children:"year"===d?e("span",{className:`text-mp-on-surface flex h-(--_mp-cell) items-center tabular-nums ${h[n]}`,children:`${Y}–${Y+E-1}`}):"month"===d?F:o(t,N?{children:[z,F]}:{children:[F,z]})}),C(1,w)]})}export function MPCalendar({size:t,color:r,locale:l,weekStartsOn:a,month:s,onMonthChange:c,selected:i,rangeStart:u=null,rangeEnd:m=null,onSelect:d,onPreviewChange:h,minDate:p,maxDate:f,shouldDisableDate:w,showOutsideDays:x=!0,autoFocus:y=!1,showPreviousButton:b=!0,showNextButton:S=!0,labels:N}){const[_,k]=n.useState("day"),A=n.useMemo(()=>i.filter(P),[i]),[j,B]=n.useState(()=>{const e=A.find(e=>M(e,s));return e?z(e):M(Y(),s)?Y():F(s)}),T=n.useRef(y),$=n.useRef(null);n.useEffect(()=>{B(e=>M(e,s)?e:F(s))},[s]),n.useLayoutEffect(()=>{T.current&&(T.current=!1,$.current?.querySelector('[data-focus-target="true"]')?.focus({preventScroll:!0}))});const H=n.useCallback(e=>D(e,p,f)||(w?.(e)??!1),[p,f,w]),q=e=>{T.current=!0,k(e)},I=e=>{T.current=!0,c(e)};return o("div",{ref:$,className:"mp-calendar flex flex-col gap-1",style:{"--_mp-cell":R[t]},onPointerLeave:()=>h?.(null),children:[e(K,{size:t,color:r,view:_,month:s,locale:l,labels:N,showPreviousButton:b,showNextButton:S,onStep:e=>{c("day"===_?g(s,e):v(s,"month"===_?e:e*E))},onViewChange:q}),e("div",{className:"h-[calc(var(--_mp-cell)*7)] w-[calc(var(--_mp-cell)*7)]",children:"day"===_?e(L,{size:t,locale:l,weekStartsOn:a,month:s,chosen:A,rangeStart:u,rangeEnd:m,focusedDate:j,showOutsideDays:x,isDisabled:H,onSelect:e=>{B(e),d(e)},onPreviewChange:h,onMoveFocus:e=>{T.current=!0,B(e),M(e,s)||c(F(e))}}):"month"===_?e(O,{size:t,locale:l,month:s,chosen:A,minDate:p,maxDate:f,onMoveCursor:I,onPick:e=>{c(C(s.getFullYear(),e,1)),q("day")}}):e(U,{size:t,month:s,chosen:A,minDate:p,maxDate:f,onMoveCursor:I,onPick:e=>{c(C(e,s.getMonth(),1)),q("month")}})})]})}function L({size:t,locale:n,weekStartsOn:r,month:l,chosen:a,rangeStart:s,rangeEnd:c,focusedDate:i,showOutsideDays:u,isDisabled:m,onSelect:p,onPreviewChange:v,onMoveFocus:b}){const D=w(l,r),S=A(n,r,"narrow"),C=A(n,r,"long"),_=y(n,{dateStyle:"full"}),k=(F=c,P(z=s)&&P(F)?x(z,F)<=0?[z,F]:[F,z]:null);var z,F;const j=Y();return o("div",{role:"grid",className:"flex h-full flex-col",children:[e("div",{role:"row",className:"grid grid-cols-7",children:S.map((o,t)=>e("span",{role:"columnheader","aria-label":C[t],className:`text-mp-on-surface-variant flex h-(--_mp-cell) items-center justify-center select-none ${d}`,children:o},t))}),D.map((o,n)=>e("div",{role:"row",className:"grid grid-cols-7",children:o.map(o=>{const n=!M(o,l);if(n&&!u)return e("span",{role:"gridcell","aria-hidden":"true",className:"size-(--_mp-cell)"},o.getTime());const s=a.some(e=>N(e,o)),c=null!==k&&x(o,k[0])>=0&&x(o,k[1])<=0,d=null!==k&&c&&N(o,k[0]),w=null!==k&&c&&N(o,k[1]);return e(H,{label:_.format(o),selected:s,inRange:c&&!s,rangeEdge:c?d&&w?"both":d?"start":w?"end":"middle":null,current:N(o,j)&&!s,muted:n,disabled:m(o),focused:N(o,i),className:`size-(--_mp-cell) ${h[t]}`,onClick:()=>p(o),onPointerEnter:()=>v?.(o),onKeyDown:e=>((e,o)=>{const t=(o.getDay()-r+7)%7,n={ArrowLeft:()=>f(o,-1),ArrowRight:()=>f(o,1),ArrowUp:()=>f(o,-7),ArrowDown:()=>f(o,7),Home:()=>f(o,-t),End:()=>f(o,6-t),PageUp:()=>g(o,e.shiftKey?-12:-1),PageDown:()=>g(o,e.shiftKey?12:1)}[e.key];n&&(e.preventDefault(),b(n()))})(e,o),children:o.getDate()},o.getTime())})},n))]})}function O({size:o,locale:t,month:n,chosen:r,minDate:l,maxDate:a,onMoveCursor:s,onPick:c}){const i=k(t,"short"),u=k(t,"long"),m=n.getFullYear(),d=new Date,p=e=>{const o={ArrowLeft:-1,ArrowRight:1,ArrowUp:-3,ArrowDown:3,PageUp:-12,PageDown:12}[e.key];void 0!==o&&(e.preventDefault(),s(g(F(n),o)))};return e("div",{role:"grid",className:"flex h-full flex-col justify-evenly",children:[0,1,2,3].map(t=>e("div",{role:"row",className:"grid grid-cols-3 gap-1",children:[0,1,2].map(s=>{const f=3*t+s,g=C(m,f,1),v=C(m,f,b(m,f));return e(H,{label:`${u[f]} ${m}`,selected:r.some(e=>e.getFullYear()===m&&e.getMonth()===f),current:d.getFullYear()===m&&d.getMonth()===f,disabled:P(l)&&x(v,l)<0||P(a)&&x(g,a)>0,focused:f===n.getMonth(),className:`h-(--_mp-cell) w-full ${h[o]}`,onClick:()=>c(f),onKeyDown:p,children:i[f]},f)})},t))})}function U({size:o,month:t,chosen:n,minDate:r,maxDate:l,onMoveCursor:a,onPick:s}){const c=B(t.getFullYear()),i=(new Date).getFullYear(),u=e=>{const o={ArrowLeft:-1,ArrowRight:1,ArrowUp:-4,ArrowDown:4,PageUp:-E,PageDown:E}[e.key];void 0!==o&&(e.preventDefault(),a(v(F(t),o)))};return e("div",{role:"grid",className:"flex h-full flex-col justify-evenly",children:[0,1,2].map(a=>e("div",{role:"row",className:"grid grid-cols-4 gap-1",children:[0,1,2,3].map(m=>{const d=c+4*a+m;return e(H,{label:String(d),selected:n.some(e=>e.getFullYear()===d),current:d===i,disabled:P(r)&&d<r.getFullYear()||P(l)&&d>l.getFullYear(),focused:d===t.getFullYear(),className:`h-(--_mp-cell) w-full ${h[o]}`,onClick:()=>s(d),onKeyDown:u,children:d},d)})},a))})}function q(e){const o=e.parentElement;if(!o)return;const t=e.getBoundingClientRect(),n=o.getBoundingClientRect(),r=t.top-n.top-o.clientTop+o.scrollTop,l=r+t.height;r<o.scrollTop?o.scrollTop=r:l>o.scrollTop+o.clientHeight&&(o.scrollTop=l-o.clientHeight)}export function MPTimeGrid({size:t,locale:r,value:l,referenceDate:a,onChange:s,hour12:c,showSeconds:i,hourStep:m,minuteStep:d,secondStep:f,shouldDisableTime:g,autoFocus:v=!1,labels:w}){const x=l??a,b=n.useRef(null),[D,S]=n.useMemo(()=>_(r),[r]);n.useEffect(()=>{const e=b.current;if(e?.querySelectorAll('[data-chosen="true"]').forEach(q),v){const o=e?.querySelector('[role="listbox"]');(o?.querySelector('[data-chosen="true"]')??o?.querySelector('[role="option"]'))?.focus({preventScroll:!0})}},[v]);const N=n.useMemo(()=>{const e=Math.ceil((c?12:24)/m),o=Array.from({length:e},(e,o)=>o*m);return c?o.map(e=>0===e?12:e):o},[c,m]),M=n.useMemo(()=>Array.from({length:Math.ceil(60/d)},(e,o)=>o*d),[d]),P=n.useMemo(()=>Array.from({length:Math.ceil(60/f)},(e,o)=>o*f),[f]),C=e=>String(e).padStart(2,"0"),k=c?x.getHours()%12||12:x.getHours(),z=(n,r,a,i,m)=>e("div",{role:"listbox","aria-label":r,className:["mp-time-grid__column flex flex-col gap-0.5 overflow-y-auto overscroll-contain","h-[calc(var(--_mp-cell)*7)] w-[calc(var(--_mp-cell)*1.75)]","scroll-py-0.5 [scrollbar-width:thin]"].join(" "),children:a.map(r=>{const a=((e,o)=>j(x,"hour"===e?{hours:c?o%12+(x.getHours()>=12?12:0):o}:"minute"===e?{minutes:o}:"second"===e?{seconds:o}:{hours:x.getHours()%12+12*o}))(n,r),d=null!==l&&i(r),p=g?.(a,n)??!1;return o("button",{type:"button",role:"option","aria-selected":d,"aria-disabled":p||void 0,"data-chosen":d?"true":void 0,className:[$,"rounded-mp-full h-(--_mp-cell) w-full shrink-0",h[t],p?"cursor-default text-mp-on-surface/38":d?"bg-(--_mp-accent) text-(--_mp-on-accent)":"text-mp-on-surface"].join(" "),onClick:()=>{p||s(a)},children:[p?null:e(u,{}),m(r)]},r)})},n);return o("div",{ref:b,className:"mp-time-grid flex gap-1",style:{"--_mp-cell":R[t]},children:[z("hour",w.hour,N,e=>e===k,e=>c?String(e):C(e)),z("minute",w.minute,M,e=>e===x.getMinutes(),C),i?z("second",w.second,P,e=>e===x.getSeconds(),C):null,c?z("meridiem",w.meridiem,[0,1],e=>(x.getHours()>=12?1:0)===e,e=>0===e?D:S):null,e("span",{className:p,"aria-live":"polite",children:null===l?"":y(r,{hour:"numeric",minute:"2-digit",...i?{second:"2-digit"}:{}}).format(l)})]})}
1
+ import{jsx as e,jsxs as o,Fragment as t}from"react/jsx-runtime";import*as n from"react";import{MPButton as r}from"../components/button/MPButton";import{MPIcon as l}from"../components/icon/MPIcon";import{MPIconButton as a}from"../components/icon-button/MPIconButton";import{ChevronDownIcon as s,ChevronLeftIcon as c,ChevronRightIcon as i}from"../constants/icons";import{MPStateLayer as u}from"./StateLayer";import{CONTROL_ICON as m,META_TEXT as d,PROSE_TEXT as h}from"./scale";import{VISUALLY_HIDDEN as p}from"./visually-hidden";import{addDays as f,addMonths as g,addYears as v,calendarWeeks as y,compareDay as w,dateFormatter as x,daysInMonth as b,isDayOutside as D,isMonthBeforeYear as S,isSameDay as N,isSameMonth as M,isValidDate as P,makeDate as _,meridiemLabels as C,monthLabels as k,startOfDay as z,startOfMonth as F,today as Y,weekdayLabels as A,withTime as E,YEAR_PAGE_SIZE as j,yearPageStart as B}from"./date";const R={xs:"1.75rem",sm:"2rem",md:"2.5rem",lg:"2.75rem",xl:"3rem"},T={xs:"xs",sm:"xs",md:"sm",lg:"sm",xl:"md"},$=["group relative flex cursor-pointer items-center justify-center overflow-hidden","box-border appearance-none bg-transparent font-[inherit] tabular-nums select-none","transition-[background-color,border-color,color]","duration-(--mp-sys-motion-duration-short4)","outline-mp-secondary focus-visible:z-10 focus-visible:outline-2","focus-visible:outline-offset-[-2px] focus-visible:outline-solid outline-none"].join(" ");function H({children:t,label:n,selected:r,inRange:l=!1,rangeEdge:a=null,current:s=!1,muted:c=!1,disabled:i=!1,focused:m=!1,className:d,onClick:h,onPointerEnter:p,onKeyDown:f}){return o("button",{type:"button",role:"gridcell","aria-label":n,"aria-selected":r,"aria-current":s?"date":void 0,"aria-disabled":i||void 0,tabIndex:m?0:-1,"data-focus-target":m?"true":void 0,className:[$,"start"===a?"rounded-s-mp-full":"end"===a?"rounded-e-mp-full":"middle"===a?"rounded-none":"rounded-mp-full",i?"cursor-default text-mp-on-surface/38":r?"bg-(--_mp-accent) text-(--_mp-on-accent)":l?"bg-(--_mp-accent-container) text-(--_mp-on-accent-container)":s?"border border-(--_mp-accent) text-(--_mp-accent)":c?"text-mp-on-surface-variant":"text-mp-on-surface",d??""].filter(Boolean).join(" "),onClick:()=>{i||h()},onPointerEnter:p,onKeyDown:f,children:[i?null:e(u,{}),t]})}function K({size:n,color:u,view:d,month:p,locale:f,labels:g,showPreviousButton:v,showNextButton:y,onStep:w,onViewChange:x}){const b=k(f,"long")[p.getMonth()],D=String(p.getFullYear()),N=S(f),M=T[n],P="day"===d?[g.previousMonth,g.nextMonth]:"month"===d?[g.previousYear,g.nextYear]:[g.previousYears,g.nextYears],_=(o,t)=>t?e(a,{size:M,color:u,label:P[-1===o?0:1],icon:e(l,{icon:-1===o?c:i,size:m[M],className:"rtl:rotate-180"}),onClick:()=>w(o)}):e("span",{"aria-hidden":"true",className:"size-(--_mp-cell)"}),C=o=>e(l,{icon:s,size:m[M],className:["transition-transform duration-(--mp-sys-motion-duration-short4)",o?"rotate-180":""].filter(Boolean).join(" ")}),z=e(r,{variant:"text",size:M,color:u,"aria-label":g.chooseMonth,"aria-expanded":"month"===d,endIcon:C("month"===d),onClick:()=>x("month"===d?"day":"month"),children:b},"month"),F=e(r,{variant:"text",size:M,color:u,className:"tabular-nums","aria-label":g.chooseYear,"aria-expanded":"year"===d,endIcon:C("year"===d),onClick:()=>x("year"===d?"day":"year"),children:D},"year"),Y=B(p.getFullYear());return o("div",{className:"flex items-center justify-between gap-1",children:[_(-1,v),e("div",{className:"flex min-w-0 flex-1 items-center justify-center gap-1",children:"year"===d?e("span",{className:`text-mp-on-surface flex h-(--_mp-cell) items-center tabular-nums ${h[n]}`,children:`${Y}–${Y+j-1}`}):"month"===d?F:o(t,N?{children:[z,F]}:{children:[F,z]})}),_(1,y)]})}export function MPCalendar({size:t,color:r,locale:l,weekStartsOn:a,month:s,onMonthChange:c,selected:i,rangeStart:u=null,rangeEnd:m=null,onSelect:d,onPreviewChange:h,minDate:p,maxDate:f,shouldDisableDate:y,showOutsideDays:w=!0,autoFocus:x=!1,showPreviousButton:b=!0,showNextButton:S=!0,labels:N}){const[C,k]=n.useState("day"),A=n.useMemo(()=>i.filter(P),[i]),[E,B]=n.useState(()=>{const e=A.find(e=>M(e,s));return e?z(e):M(Y(),s)?Y():F(s)}),T=n.useRef(x),$=n.useRef(null);n.useEffect(()=>{B(e=>M(e,s)?e:F(s))},[s]),n.useLayoutEffect(()=>{T.current&&(T.current=!1,$.current?.querySelector('[data-focus-target="true"]')?.focus({preventScroll:!0}))});const H=n.useCallback(e=>D(e,p,f)||(y?.(e)??!1),[p,f,y]),q=e=>{T.current=!0,k(e)},I=e=>{T.current=!0,c(e)};return o("div",{ref:$,className:"mp-calendar flex flex-col gap-1",style:{"--_mp-cell":R[t]},onPointerLeave:()=>h?.(null),children:[e(K,{size:t,color:r,view:C,month:s,locale:l,labels:N,showPreviousButton:b,showNextButton:S,onStep:e=>{c("day"===C?g(s,e):v(s,"month"===C?e:e*j))},onViewChange:q}),e("div",{className:"h-[calc(var(--_mp-cell)*7)] w-[calc(var(--_mp-cell)*7)]",children:"day"===C?e(L,{size:t,locale:l,weekStartsOn:a,month:s,chosen:A,rangeStart:u,rangeEnd:m,focusedDate:E,showOutsideDays:w,isDisabled:H,onSelect:e=>{B(e),d(e)},onPreviewChange:h,onMoveFocus:e=>{T.current=!0,B(e),M(e,s)||c(F(e))}}):"month"===C?e(O,{size:t,locale:l,month:s,chosen:A,minDate:p,maxDate:f,onMoveCursor:I,onPick:e=>{c(_(s.getFullYear(),e,1)),q("day")}}):e(U,{size:t,month:s,chosen:A,minDate:p,maxDate:f,onMoveCursor:I,onPick:e=>{c(_(e,s.getMonth(),1)),q("month")}})})]})}function L({size:t,locale:r,weekStartsOn:l,month:a,chosen:s,rangeStart:c,rangeEnd:i,focusedDate:u,showOutsideDays:m,isDisabled:p,onSelect:v,onPreviewChange:b,onMoveFocus:D}){const S=A(r,l,"narrow"),_=A(r,l,"long"),C=(z=i,P(k=c)&&P(z)?w(k,z)<=0?[k,z]:[z,k]:null);var k,z;const F=Y(),E=n.useMemo(()=>{const e=x(r,{dateStyle:"full"});return y(a,l).map(o=>o.map(o=>({date:o,label:e.format(o)})))},[a,l,r]),j=n.useRef(null),B=n.useRef(a);n.useLayoutEffect(()=>{const e=j.current,o=B.current;if(B.current=a,!e||M(o,a))return;const t=o.getTime()<a.getTime(),n="rtl"===getComputedStyle(e).direction;e.style.setProperty("--_mp-calendar-from",String(t===n?-1:1)),e.dataset.mpPaged="true",e.style.animationName="none",e.offsetWidth,e.style.animationName=""},[a]);return o("div",{role:"grid","aria-label":x(r,{year:"numeric",month:"long"}).format(a),className:"flex h-full flex-col",children:[e("div",{role:"rowgroup",children:e("div",{role:"row",className:"grid grid-cols-7",children:S.map((o,t)=>e("span",{role:"columnheader","aria-label":_[t],className:`text-mp-on-surface-variant flex h-(--_mp-cell) items-center justify-center select-none ${d}`,children:o},t))})}),e("div",{ref:j,role:"rowgroup",className:"mp-calendar__page flex flex-1 flex-col",children:E.map((o,n)=>e("div",{role:"row",className:"grid grid-cols-7",children:o.map(({date:o,label:n})=>{const r=!M(o,a);if(r&&!m)return e("span",{role:"gridcell","aria-hidden":"true",className:"size-(--_mp-cell)"},o.getTime());const c=s.some(e=>N(e,o)),i=null!==C&&w(o,C[0])>=0&&w(o,C[1])<=0,d=null!==C&&i&&N(o,C[0]),y=null!==C&&i&&N(o,C[1]);return e(H,{label:n,selected:c,inRange:i&&!c,rangeEdge:i?d&&y?"both":d?"start":y?"end":"middle":null,current:N(o,F)&&!c,muted:r,disabled:p(o),focused:N(o,u),className:`size-(--_mp-cell) ${h[t]}`,onClick:()=>v(o),onPointerEnter:()=>b?.(o),onKeyDown:e=>((e,o)=>{const t=(o.getDay()-l+7)%7,n={ArrowLeft:()=>f(o,-1),ArrowRight:()=>f(o,1),ArrowUp:()=>f(o,-7),ArrowDown:()=>f(o,7),Home:()=>f(o,-t),End:()=>f(o,6-t),PageUp:()=>g(o,e.shiftKey?-12:-1),PageDown:()=>g(o,e.shiftKey?12:1)}[e.key];n&&(e.preventDefault(),D(n()))})(e,o),children:o.getDate()},o.getTime())})},n))})]})}function O({size:o,locale:t,month:n,chosen:r,minDate:l,maxDate:a,onMoveCursor:s,onPick:c}){const i=k(t,"short"),u=k(t,"long"),m=n.getFullYear(),d=new Date,p=e=>{const o={ArrowLeft:-1,ArrowRight:1,ArrowUp:-3,ArrowDown:3,PageUp:-12,PageDown:12}[e.key];void 0!==o&&(e.preventDefault(),s(g(F(n),o)))};return e("div",{role:"grid",className:"flex h-full flex-col justify-evenly",children:[0,1,2,3].map(t=>e("div",{role:"row",className:"grid grid-cols-3 gap-1",children:[0,1,2].map(s=>{const f=3*t+s,g=_(m,f,1),v=_(m,f,b(m,f));return e(H,{label:`${u[f]} ${m}`,selected:r.some(e=>e.getFullYear()===m&&e.getMonth()===f),current:d.getFullYear()===m&&d.getMonth()===f,disabled:P(l)&&w(v,l)<0||P(a)&&w(g,a)>0,focused:f===n.getMonth(),className:`h-(--_mp-cell) w-full ${h[o]}`,onClick:()=>c(f),onKeyDown:p,children:i[f]},f)})},t))})}function U({size:o,month:t,chosen:n,minDate:r,maxDate:l,onMoveCursor:a,onPick:s}){const c=B(t.getFullYear()),i=(new Date).getFullYear(),u=e=>{const o={ArrowLeft:-1,ArrowRight:1,ArrowUp:-4,ArrowDown:4,PageUp:-j,PageDown:j}[e.key];void 0!==o&&(e.preventDefault(),a(v(F(t),o)))};return e("div",{role:"grid",className:"flex h-full flex-col justify-evenly",children:[0,1,2].map(a=>e("div",{role:"row",className:"grid grid-cols-4 gap-1",children:[0,1,2,3].map(m=>{const d=c+4*a+m;return e(H,{label:String(d),selected:n.some(e=>e.getFullYear()===d),current:d===i,disabled:P(r)&&d<r.getFullYear()||P(l)&&d>l.getFullYear(),focused:d===t.getFullYear(),className:`h-(--_mp-cell) w-full ${h[o]}`,onClick:()=>s(d),onKeyDown:u,children:d},d)})},a))})}function q(e){const o=e.parentElement;if(!o)return;const t=e.getBoundingClientRect(),n=o.getBoundingClientRect(),r=t.top-n.top-o.clientTop+o.scrollTop,l=r+t.height;r<o.scrollTop?o.scrollTop=r:l>o.scrollTop+o.clientHeight&&(o.scrollTop=l-o.clientHeight)}export function MPTimeGrid({size:t,locale:r,value:l,referenceDate:a,onChange:s,hour12:c,showSeconds:i,hourStep:m,minuteStep:d,secondStep:f,shouldDisableTime:g,autoFocus:v=!1,labels:y}){const w=l??a,b=n.useRef(null),[D,S]=n.useMemo(()=>C(r),[r]);n.useEffect(()=>{const e=b.current;if(e?.querySelectorAll('[data-chosen="true"]').forEach(q),v){const o=e?.querySelector('[role="listbox"]');(o?.querySelector('[data-chosen="true"]')??o?.querySelector('[role="option"]'))?.focus({preventScroll:!0})}},[v]);const N=n.useMemo(()=>{const e=Math.ceil((c?12:24)/m),o=Array.from({length:e},(e,o)=>o*m);return c?o.map(e=>0===e?12:e):o},[c,m]),M=n.useMemo(()=>Array.from({length:Math.ceil(60/d)},(e,o)=>o*d),[d]),P=n.useMemo(()=>Array.from({length:Math.ceil(60/f)},(e,o)=>o*f),[f]),_=e=>String(e).padStart(2,"0"),k=c?w.getHours()%12||12:w.getHours(),z=(n,r,a,i,m)=>e("div",{role:"listbox","aria-label":r,className:["mp-time-grid__column flex flex-col gap-0.5 overflow-y-auto overscroll-contain","h-[calc(var(--_mp-cell)*7)] w-[calc(var(--_mp-cell)*1.75)]","scroll-py-0.5 [scrollbar-width:thin]"].join(" "),children:a.map(r=>{const a=((e,o)=>E(w,"hour"===e?{hours:c?o%12+(w.getHours()>=12?12:0):o}:"minute"===e?{minutes:o}:"second"===e?{seconds:o}:{hours:w.getHours()%12+12*o}))(n,r),d=null!==l&&i(r),p=g?.(a,n)??!1;return o("button",{type:"button",role:"option","aria-selected":d,"aria-disabled":p||void 0,"data-chosen":d?"true":void 0,className:[$,"rounded-mp-full h-(--_mp-cell) w-full shrink-0",h[t],p?"cursor-default text-mp-on-surface/38":d?"bg-(--_mp-accent) text-(--_mp-on-accent)":"text-mp-on-surface"].join(" "),onClick:()=>{p||s(a)},children:[p?null:e(u,{}),m(r)]},r)})},n);return o("div",{ref:b,className:"mp-time-grid flex gap-1",style:{"--_mp-cell":R[t]},children:[z("hour",y.hour,N,e=>e===k,e=>c?String(e):_(e)),z("minute",y.minute,M,e=>e===w.getMinutes(),_),i?z("second",y.second,P,e=>e===w.getSeconds(),_):null,c?z("meridiem",y.meridiem,[0,1],e=>(w.getHours()>=12?1:0)===e,e=>0===e?D:S):null,e("span",{className:p,"aria-live":"polite",children:null===l?"":x(r,{hour:"numeric",minute:"2-digit",...i?{second:"2-digit"}:{}}).format(l)})]})}
@@ -4,6 +4,13 @@ export interface MPFieldOutlineProps {
4
4
  /** The label, which is what cuts the notch. Without one the outline is closed. */
5
5
  label?: React.ReactNode;
6
6
  required?: boolean;
7
+ /**
8
+ * Whether the notch is cut. `false` closes it, for the moment the label is
9
+ * resting on the control's line and there is nothing on the border to make
10
+ * room for.
11
+ * @default true
12
+ */
13
+ notched?: boolean;
7
14
  }
8
15
  /**
9
16
  * The outline itself.
@@ -17,15 +24,28 @@ export interface MPFieldOutlineProps {
17
24
  * from the real `<label>`, and announcing a `<fieldset>` as a group around a
18
25
  * single control is noise a screen reader does not need.
19
26
  */
20
- export declare function MPFieldOutline({ label, required }: MPFieldOutlineProps): React.JSX.Element;
27
+ export declare function MPFieldOutline({ label, required, notched }: MPFieldOutlineProps): React.JSX.Element;
21
28
  export interface MPFieldLabelProps extends MPFieldOutlineProps {
22
29
  /**
23
- * Which rung the control is drawn at. Only the inline offset reads it: the
24
- * label has to land over the gap the container's own padding put the notch in.
30
+ * Which rung the control is drawn at. Read twice: for the inline offset, so
31
+ * the label lands over the gap the container's padding put the notch in, and
32
+ * for the type scale it rests at.
25
33
  */
26
34
  size: MPSize;
27
35
  /** The control the label names. */
28
36
  htmlFor?: string;
37
+ /**
38
+ * Whether the label is up in the notch. `false` rests it on the control's own
39
+ * line, at the control's own type scale, where it reads as the placeholder.
40
+ * @default true
41
+ */
42
+ shrunk?: boolean;
43
+ /**
44
+ * Whether the control is a `<textarea>`, which is the one case a resting
45
+ * label cannot simply be centred in. See `MULTILINE_REST`.
46
+ * @default false
47
+ */
48
+ multiline?: boolean;
29
49
  }
30
50
  /**
31
51
  * The label a reader actually gets.
@@ -34,5 +54,56 @@ export interface MPFieldLabelProps extends MPFieldOutlineProps {
34
54
  * border line where the legend cut it away. It cannot *be* the legend: the
35
55
  * outline is `pointer-events-none` so that clicks land on the control
36
56
  * underneath, and a label inside it would stop being clickable.
57
+ *
58
+ * Resting, it is `pointer-events-none` instead — it is lying over the text the
59
+ * caret goes into, and a click on it has to reach the control so the caret
60
+ * lands where the pointer did. A `<label for>` would only have focused the
61
+ * control, which puts the caret at the end of the text rather than under the
62
+ * pointer.
63
+ */
64
+ export declare function MPFieldLabel({ size, label, required, htmlFor, shrunk, multiline }: MPFieldLabelProps): React.JSX.Element;
65
+ export interface MPFloatingLabel {
66
+ /** Whether the label is up in the notch right now. */
67
+ shrunk: boolean;
68
+ /**
69
+ * Spread on the element the control sits inside — the `Field.Root`, or the
70
+ * shell `<div>` under it. Anything focusable within it counts as the field
71
+ * being focused, which is what a reader tabbing onto a password toggle or a
72
+ * stepper means by it.
73
+ */
74
+ focusProps: {
75
+ onFocusCapture: React.FocusEventHandler<HTMLElement>;
76
+ onBlurCapture: React.FocusEventHandler<HTMLElement>;
77
+ };
78
+ }
79
+ export interface MPFloatingLabelOptions {
80
+ /**
81
+ * Whether the label floats at all. `false` pins it in the notch — which is
82
+ * also what a control with no label wants, since there is nothing to rest.
83
+ */
84
+ floating: boolean;
85
+ /** Whether the control holds anything. A filled control keeps its label up. */
86
+ filled: boolean;
87
+ /**
88
+ * Anything else that holds the label up: a start adornment already occupying
89
+ * the resting label's place, or a popup the focus has moved into.
90
+ * @default false
91
+ */
92
+ pinned?: boolean;
93
+ }
94
+ /**
95
+ * Which of its two places the label is in, and how the field learns it moved.
96
+ *
97
+ * Focus is tracked here rather than read from Base UI's `data-focused` because
98
+ * the two do not agree on what a field is. `data-focused` follows the one
99
+ * control the `Field` owns, and half the shells here have a button beside it —
100
+ * a reveal toggle, a stepper, a clear × — that a reader on the keyboard is
101
+ * plainly still *in* the field for. `focus-within` on the shell is the honest
102
+ * boundary, and a capture-phase pair is how React spells it without a
103
+ * `:focus-within` selector, which cannot be read back as a value.
104
+ *
105
+ * The `relatedTarget` test is what keeps the label still while focus moves
106
+ * between two things inside the same shell. Without it, tabbing from the input
107
+ * to the toggle drops the label and lifts it again in the same frame.
37
108
  */
38
- export declare function MPFieldLabel({ size, label, required, htmlFor }: MPFieldLabelProps): React.JSX.Element;
109
+ export declare function useFloatingLabel({ floating, filled, pinned }: MPFloatingLabelOptions): MPFloatingLabel;
@@ -1 +1 @@
1
- import{jsx as r,Fragment as e,jsxs as o}from"react/jsx-runtime";import{Field as t}from"@base-ui/react/field";function a(t,a){return o(e,{children:[t,a?r("span",{"aria-hidden":"true",children:" *"}):null]})}export function MPFieldOutline({label:e,required:o=!1}){return r("fieldset",{"aria-hidden":"true",className:["pointer-events-none absolute inset-0 -top-[5px] m-0 min-w-0 px-2 pt-0","rounded-mp-xs border border-mp-outline","transition-[border-color] duration-(--mp-sys-motion-duration-short4)","group-hover:border-mp-on-surface","group-focus-within:border-2 group-focus-within:border-mp-primary","group-data-focused:border-2 group-data-focused:border-mp-primary","group-data-invalid:border-mp-error","group-data-disabled:border-mp-on-surface/12"].join(" "),children:e?r("legend",{className:"text-mp-body-small invisible float-none block h-[11px] w-auto p-0 px-1 leading-none",children:a(e,o)}):null})}export function MPFieldLabel({size:e,label:o,required:n=!1,htmlFor:i}){return r(t.Label,{htmlFor:i,className:["text-mp-body-small text-mp-on-surface-variant","transition-[color] duration-(--mp-sys-motion-duration-short4)","pointer-events-auto absolute top-0 -translate-y-1/2 px-1 leading-none","xs"===e?"left-1":"sm"===e?"left-2":"xl"===e?"left-4":"left-3","group-focus-within:text-mp-primary","group-data-focused:text-mp-primary","group-data-invalid:text-mp-error","group-data-disabled:text-mp-on-surface/38"].join(" "),children:a(o,n)})}
1
+ import{jsx as r,Fragment as e,jsxs as t}from"react/jsx-runtime";import*as o from"react";import{Field as n}from"@base-ui/react/field";import{PROSE_TEXT as a}from"./scale";const i={xs:"left-1",sm:"left-2",md:"left-3",lg:"left-3",xl:"left-4"},s={xs:"top-[18px]",sm:"top-[18px]",md:"top-5",lg:"top-5",xl:"top-5"};function d(o,n){return t(e,{children:[o,n?r("span",{"aria-hidden":"true",children:" *"}):null]})}export function MPFieldOutline({label:e,required:t=!1,notched:o=!0}){return r("fieldset",{"aria-hidden":"true",className:["pointer-events-none absolute inset-0 -top-[5px] m-0 min-w-0 px-2 pt-0","rounded-mp-xs border border-mp-outline","transition-[border-color] duration-(--mp-sys-motion-duration-short4)","group-hover:border-mp-on-surface","group-focus-within:border-2 group-focus-within:border-mp-primary","group-data-focused:border-2 group-data-focused:border-mp-primary","group-data-invalid:border-mp-error","group-data-disabled:border-mp-on-surface/12"].join(" "),children:e?r("legend",{className:["text-mp-body-small invisible float-none block h-[11px] w-auto overflow-hidden p-0","leading-none","ease-mp-standard transition-[max-width,padding]","duration-(--mp-sys-motion-duration-short4)",o?"max-w-full px-1":"max-w-0 px-0"].join(" "),children:d(e,t)}):null})}export function MPFieldLabel({size:e,label:t,required:o=!1,htmlFor:p,shrunk:l=!0,multiline:u=!1}){return r(n.Label,{htmlFor:p,"data-mp-shrunk":l?"":void 0,className:["text-mp-on-surface-variant","ease-mp-standard transition-[color,top,font-size,max-width]","duration-(--mp-sys-motion-duration-short4)","absolute -translate-y-1/2 px-1 leading-none",i[e],l?"text-mp-body-small pointer-events-auto top-0 max-w-none":[a[e],"pointer-events-none max-w-[calc(100%-2rem)] truncate",u?s[e]:"top-1/2"].join(" "),"group-focus-within:text-mp-primary","group-data-focused:text-mp-primary","group-data-invalid:text-mp-error","group-data-disabled:text-mp-on-surface/38"].join(" "),children:d(t,o)})}export function useFloatingLabel({floating:r,filled:e,pinned:t=!1}){const[n,a]=o.useState(!1);return{shrunk:!r||e||n||t,focusProps:{onFocusCapture:()=>a(!0),onBlurCapture:r=>{r.currentTarget.contains(r.relatedTarget)||a(!1)}}}}
@@ -1,6 +1,30 @@
1
1
  import * as React from 'react';
2
2
  import type { MPPickerLabels } from './Calendar';
3
3
  import type { MPColor, MPSize, MPStyleProps } from '../types';
4
+ /**
5
+ * The strings a trigger is held open by, kept across renders that did not
6
+ * change what it could say.
7
+ *
8
+ * `displaySamples` formats two dozen instants and deduplicates them, which is
9
+ * cheap once and not cheap sixty times a second — and sixty times a second is
10
+ * exactly what a range picker asks for, because moving the pointer across the
11
+ * calendar re-renders the whole control to redraw the band.
12
+ *
13
+ * ## Why it is keyed on the format's *contents*
14
+ *
15
+ * Because an options object is nearly always a fresh one. Three of the four
16
+ * pickers build theirs from a default parameter or a literal, so it is a new
17
+ * object on every render by construction; and a caller who writes
18
+ * `format={{ dateStyle: 'full' }}` inline hands over a new object too. Keyed on
19
+ * identity, the memo would miss every single time — which is what it was doing.
20
+ *
21
+ * Serialising instead means the memo holds for as long as the format *says* the
22
+ * same thing, whoever built the object. `internal/date.ts` keys its formatter
23
+ * cache the same way, and inherits the same harmless quirk: two objects whose
24
+ * keys are in a different order read as two formats. That costs one extra miss,
25
+ * never a wrong answer.
26
+ */
27
+ export declare function useDisplaySamples(locale: string | undefined, options: Intl.DateTimeFormatOptions): string[];
4
28
  /**
5
29
  * The props a picker takes from its shell rather than inventing.
6
30
  *
@@ -16,11 +40,22 @@ export interface MPPickerShellProps extends MPStyleProps {
16
40
  */
17
41
  color?: MPColor;
18
42
  /**
19
- * Label in the outline's notch. Always drawn there rather than floating over
20
- * the value, so a picker with a label and one without sit at the same height
21
- * in a form.
43
+ * Label for the picker, drawn in the outline's notch and — while nothing is
44
+ * chosen, the popup is shut and there is no leading glyph — resting on the
45
+ * trigger's own line where the placeholder would be. See `floatingLabel`.
22
46
  */
23
47
  label?: React.ReactNode;
48
+ /**
49
+ * Whether the label rests on the trigger's line while there is nothing to make
50
+ * room for, and rises into the notch on focus or on the first choice.
51
+ *
52
+ * A picker draws its own glyph before the value, and that glyph stands exactly
53
+ * where a resting label would — so in practice this only takes effect on a
54
+ * picker asked for without one, `startIcon={null}`. Two things cannot share a
55
+ * spot, and of the two the glyph is what says the trigger opens a calendar.
56
+ * @default true
57
+ */
58
+ floatingLabel?: boolean;
24
59
  /** The line under the control. Replaced by `errorMessage` when there is one. */
25
60
  description?: React.ReactNode;
26
61
  /**
@@ -29,7 +64,10 @@ export interface MPPickerShellProps extends MPStyleProps {
29
64
  * way to render a control that is visibly wrong with no explanation of why.
30
65
  */
31
66
  errorMessage?: React.ReactNode;
32
- /** Content placed before the value. Defaults to the picker's own glyph. */
67
+ /**
68
+ * Content placed before the value. Defaults to the picker's own glyph, and
69
+ * `null` is how that glyph is asked for by name to go away.
70
+ */
33
71
  startIcon?: React.ReactNode;
34
72
  /** Marks the picker required, both to assistive technology and to the label. */
35
73
  required?: boolean;
@@ -44,8 +82,8 @@ export interface MPPickerShellProps extends MPStyleProps {
44
82
  */
45
83
  readOnly?: boolean;
46
84
  /**
47
- * The id put on the trigger and pointed at by the label. Derived from `name`
48
- * when omitted, and generated when there is no name either.
85
+ * The id put on the trigger and pointed at by the label. Generated when it is
86
+ * left out.
49
87
  */
50
88
  id?: string;
51
89
  className?: string;
@@ -70,12 +108,17 @@ interface InternalShellProps extends MPPickerShellProps {
70
108
  open: boolean;
71
109
  onOpenChange: (open: boolean) => void;
72
110
  labels: MPPickerLabels;
73
- /** `<input type="hidden">` rows, so the control submits with a form. */
111
+ /**
112
+ * `<input type="hidden">` rows, so the control submits with a form.
113
+ *
114
+ * Each row carries its own name, which is why the shell takes no `name` of
115
+ * its own: a range picker submits two of them under one name, and the id the
116
+ * label points at is generated rather than derived from it.
117
+ */
74
118
  hiddenValues?: Array<{
75
119
  name: string;
76
120
  value: string;
77
121
  }>;
78
- name?: string;
79
122
  children: React.ReactNode;
80
123
  triggerRef?: React.Ref<HTMLButtonElement>;
81
124
  }
@@ -87,7 +130,7 @@ interface InternalShellProps extends MPPickerShellProps {
87
130
  * treatment, and the popup's `surface-container` at elevation 2 — which is the
88
131
  * same floating sheet a menu and a select's list are drawn on.
89
132
  */
90
- export declare function MPPickerShell({ slug, size, color, fullWidth, label, description, errorMessage, startIcon, required, disabled, readOnly, id, className, style, display, samples, empty, clearable, onClear, open, onOpenChange, labels, hiddenValues, name, children, triggerRef }: InternalShellProps): React.JSX.Element;
133
+ export declare function MPPickerShell({ slug, size, color, fullWidth, label, floatingLabel, description, errorMessage, startIcon, required, disabled, readOnly, id, className, style, display, samples, empty, clearable, onClear, open, onOpenChange, labels, hiddenValues, children, triggerRef }: InternalShellProps): React.JSX.Element;
91
134
  /**
92
135
  * The row of shortcuts under a picker's panel.
93
136
  *
@@ -1 +1 @@
1
- import{jsx as e,jsxs as r}from"react/jsx-runtime";import*as i from"react";import{Field as t}from"@base-ui/react/field";import{Popover as n}from"@base-ui/react/popover";import{MPIcon as a}from"../components/icon/MPIcon";import{CloseIcon as o}from"../constants/icons";import{accentSlots as l}from"./accent";import{MPFieldLabel as s,MPFieldOutline as p}from"./FieldOutline";import{MPStateLayer as c}from"./StateLayer";import{MPSupportingText as m}from"./SupportingText";import{MPWidthSizer as d}from"./WidthSizer";import{CONTROL_ICON as u,hasContent as f,PROSE_TEXT as h}from"./scale";import{FADE as x,PORTAL_LAYER as g}from"./surface";const b={xs:{padding:"px-2",height:"h-8"},sm:{padding:"px-3",height:"h-10"},md:{padding:"px-4",height:"h-14"},lg:{padding:"px-4",height:"h-16"},xl:{padding:"px-5",height:"h-18"}},v={xs:"p-1.5",sm:"p-2",md:"p-2.5",lg:"p-3",xl:"p-3.5"};export function MPPickerShell({slug:y,size:N="md",color:j="primary",fullWidth:P=!1,label:w,description:O,errorMessage:z,startIcon:M,required:k=!1,disabled:F=!1,readOnly:S=!1,id:B,className:C,style:I,display:R,samples:$,empty:q,clearable:T=!1,onClear:_,open:E,onOpenChange:W,labels:D,hiddenValues:L,name:V,children:Z,triggerRef:A}){const G=f(z),H=b[N],J=i.useId(),K=B??`mp-${y}-${V??J}`,Q=T&&!q&&!(F||S);return r(t.Root,{disabled:F,invalid:G,"data-mp-size":N,className:[`mp-${y} group flex-col align-top`,P?"flex w-full":"inline-flex w-fit",C??""].filter(Boolean).join(" "),style:{...l(j),...I},children:[r(n.Root,{open:E,onOpenChange:W,children:[r("div",{className:"relative w-full",children:[r(n.Trigger,{id:K,ref:A,disabled:F,nativeButton:!0,className:["relative flex w-full items-center gap-2 select-none","appearance-none bg-transparent font-[inherit] outline-none",H.padding,Q?"pe-10":"",H.height,h[N],F?"text-mp-on-surface/38 cursor-default":"text-mp-on-surface "+(S?"cursor-default":"cursor-pointer")].filter(Boolean).join(" "),children:[M?e("span",{className:["flex shrink-0 items-center",F?"text-mp-on-surface/38":"text-mp-on-surface-variant"].join(" "),children:M}):null,r("span",{className:"flex min-w-0 flex-1 flex-col",children:[e("span",{className:["w-full truncate text-start",q&&!F?"text-mp-on-surface-variant":""].filter(Boolean).join(" "),children:R}),e(d,{samples:$??[]})]})]}),Q?r("button",{type:"button","aria-label":D.clear,onClick:_,className:["group/clear rounded-mp-full text-mp-on-surface-variant absolute inset-y-0","end-1 my-auto flex size-8 cursor-pointer items-center justify-center","appearance-none border-0 bg-transparent font-[inherit]","outline-mp-secondary focus-visible:outline-2 focus-visible:outline-offset-1","focus-visible:outline-solid outline-none"].join(" "),children:[e(c,{className:"group-hover/clear:opacity-8 group-focus-visible/clear:opacity-10"}),e(a,{icon:o,size:u[N]})]}):null,e(p,{label:w,required:k}),f(w)?e(s,{size:N,label:w,required:k,htmlFor:K}):null]}),e(n.Portal,{children:e(n.Positioner,{className:g,sideOffset:4,align:"start",children:e(n.Popup,{initialFocus:!1,className:[`mp-${y}__popup rounded-mp-md shadow-mp-2 bg-mp-surface-container`,"text-mp-on-surface outline-none",v[N],h[N],x].join(" "),children:Z})})})]}),e(m,{description:O,errorMessage:z,className:H.padding}),L?.map((r,i)=>e("input",{type:"hidden",name:r.name,value:r.value},i))]})}export function MPPickerFooter({children:r}){return e("div",{className:"border-mp-outline-variant flex items-center justify-end gap-1 border-t pt-1.5",children:r})}export function MPPickerDivider(){return e("div",{"aria-hidden":"true",className:"bg-mp-outline-variant w-px self-stretch"})}export const FOOTER_SIZE={xs:"xs",sm:"xs",md:"sm",lg:"sm",xl:"md"};
1
+ import{jsx as e,jsxs as r}from"react/jsx-runtime";import*as i from"react";import{Field as n}from"@base-ui/react/field";import{Popover as t}from"@base-ui/react/popover";import{MPIcon as o}from"../components/icon/MPIcon";import{CloseIcon as a}from"../constants/icons";import{accentSlots as l}from"./accent";import{MPFieldLabel as s,MPFieldOutline as p,useFloatingLabel as c}from"./FieldOutline";import{MPStateLayer as m}from"./StateLayer";import{MPSupportingText as d}from"./SupportingText";import{MPWidthSizer as u}from"./WidthSizer";import{displaySamples as f}from"./date";import{CONTROL_ICON as h,hasContent as g,PROSE_TEXT as x}from"./scale";import{FADE as b,PORTAL_LAYER as v}from"./surface";export function useDisplaySamples(e,r){const n=`${e??""} ${JSON.stringify(r)}`;return i.useMemo(()=>f(e,r),[n])}const y={xs:{padding:"px-2",height:"h-8"},sm:{padding:"px-3",height:"h-10"},md:{padding:"px-4",height:"h-14"},lg:{padding:"px-4",height:"h-16"},xl:{padding:"px-5",height:"h-18"}},N={xs:"p-1.5",sm:"p-2",md:"p-2.5",lg:"p-3",xl:"p-3.5"};export function MPPickerShell({slug:f,size:j="md",color:P="primary",fullWidth:w=!1,label:O,floatingLabel:k=!0,description:M,errorMessage:S,startIcon:z,required:F=!1,disabled:B=!1,readOnly:C=!1,id:I,className:R,style:$,display:q,samples:T,empty:_,clearable:D=!1,onClear:E,open:L,onOpenChange:W,labels:J,hiddenValues:V,children:Z,triggerRef:A}){const G=g(S),H=y[j],K=i.useId(),Q=I??K,U=D&&!_&&!(B||C),{shrunk:X,focusProps:Y}=c({floating:k&&g(O),filled:!_,pinned:L||g(z)});return r(n.Root,{disabled:B,invalid:G,"data-mp-size":j,className:[`mp-${f} group flex-col align-top`,w?"flex w-full":"inline-flex w-fit",R??""].filter(Boolean).join(" "),style:{...l(P),...$},...Y,children:[r(t.Root,{open:L,onOpenChange:W,children:[r("div",{className:"relative w-full",children:[r(t.Trigger,{id:Q,ref:A,disabled:B,nativeButton:!0,className:["relative flex w-full items-center gap-2 select-none","appearance-none bg-transparent font-[inherit] outline-none",H.padding,U?"pe-10":"",H.height,x[j],B?"text-mp-on-surface/38 cursor-default":"text-mp-on-surface "+(C?"cursor-default":"cursor-pointer")].filter(Boolean).join(" "),children:[z?e("span",{className:["flex shrink-0 items-center",B?"text-mp-on-surface/38":"text-mp-on-surface-variant"].join(" "),children:z}):null,r("span",{className:"flex min-w-0 flex-1 flex-col",children:[e("span",{className:["w-full truncate text-start",_&&!B?"text-mp-on-surface-variant":""].filter(Boolean).join(" "),children:_&&!X?null:q}),e(u,{samples:T??[]})]})]}),U?r("button",{type:"button","aria-label":J.clear,onClick:E,className:["group/clear rounded-mp-full text-mp-on-surface-variant absolute inset-y-0","end-1 my-auto flex size-8 cursor-pointer items-center justify-center","appearance-none border-0 bg-transparent font-[inherit]","outline-mp-secondary focus-visible:outline-2 focus-visible:outline-offset-1","focus-visible:outline-solid outline-none"].join(" "),children:[e(m,{className:"group-hover/clear:opacity-8 group-focus-visible/clear:opacity-10"}),e(o,{icon:a,size:h[j]})]}):null,e(p,{label:O,required:F,notched:X}),g(O)?e(s,{size:j,label:O,required:F,htmlFor:Q,shrunk:X}):null]}),e(t.Portal,{children:e(t.Positioner,{className:v,sideOffset:4,align:"start",children:e(t.Popup,{initialFocus:!1,className:[`mp-${f}__popup rounded-mp-md shadow-mp-2 bg-mp-surface-container`,"text-mp-on-surface outline-none",N[j],x[j],b].join(" "),children:Z})})})]}),e(d,{description:M,errorMessage:S,className:H.padding}),V?.map((r,i)=>e("input",{type:"hidden",name:r.name,value:r.value},i))]})}export function MPPickerFooter({children:r}){return e("div",{className:"border-mp-outline-variant flex items-center justify-end gap-1 border-t pt-1.5",children:r})}export function MPPickerDivider(){return e("div",{"aria-hidden":"true",className:"bg-mp-outline-variant w-px self-stretch"})}export const FOOTER_SIZE={xs:"xs",sm:"xs",md:"sm",lg:"sm",xl:"md"};
@@ -0,0 +1,179 @@
1
+ /**
2
+ * The machinery every `MPAnimate*` component runs on.
3
+ *
4
+ * It lives in `internal/` for the reason `menu.ts` and `button-group.ts` do:
5
+ * eleven components need it and none of them should have to import another.
6
+ *
7
+ * ## The shape of it
8
+ *
9
+ * Every effect is one `@keyframes` in `styles.css` running from a state written
10
+ * entirely in `--_mp-anim-*` custom properties to the element's natural one.
11
+ * Nothing here generates CSS: it fills slots, and the stylesheet decides what
12
+ * they mean. That is the same split `accentSlots()` makes for colour, for the
13
+ * same reason — Tailwind only ever sees class names that appear literally in
14
+ * the source, so a per-value class would not survive the first prop.
15
+ *
16
+ * Because the from-state is the *keyframe* rather than a second class, running
17
+ * an effect backwards is `animation-direction: reverse` and nothing else. That
18
+ * is what makes `mode="out"` free on all five of the effects that take one —
19
+ * the fade, the grow, the zoom, the slide and the rotate — and, as it happens,
20
+ * correct:
21
+ * CSS mirrors the timing function along with the keyframes, so an entrance
22
+ * eased on `emphasized-decelerate` comes out accelerating on the way back. The
23
+ * specification asks for exactly that pair, and the browser supplies it.
24
+ *
25
+ * ## Why the defaults are `var()` rather than numbers
26
+ *
27
+ * A duration nobody set resolves to `var(--mp-sys-motion-duration-medium4)`,
28
+ * not to `400ms`. Both would draw the same animation today; only one of them
29
+ * moves when a page retunes its motion tokens. Same rule as everywhere else in
30
+ * this library: the value a caller does not name is the *token*, so a theme can
31
+ * still reach it.
32
+ *
33
+ * ## What is deliberately not here
34
+ *
35
+ * An animation that has to know what its children *are* — a marquee that
36
+ * duplicates them, a headline that swaps between them, a typewriter that counts
37
+ * characters — cannot be a class name and a few numbers. Those are components,
38
+ * and their logic stays in their own files.
39
+ */
40
+ import * as React from 'react';
41
+ import type { MPAnimateMode, MPAnimateRepeat, MPAnimateTrigger, MPAnimation, MPEasing, MPSide } from '../types';
42
+ /** The class that reads the slots. Always paired with one of the below. */
43
+ export declare const ANIM_BASE = "mp-anim";
44
+ /**
45
+ * Which keyframe an effect runs.
46
+ *
47
+ * `grow` and `zoom` share one: they are the same arithmetic at two strengths,
48
+ * and a second identical `@keyframes` would only be a second place to fix a
49
+ * bug. What separates them is their defaults and their origin, which is a
50
+ * property rather than a keyframe.
51
+ */
52
+ export declare const ANIMATION_CLASS: Record<MPAnimation, string>;
53
+ /** A curve, as the stylesheet spells it. */
54
+ export declare function easingValue(easing: MPEasing): string;
55
+ /**
56
+ * A duration, as the stylesheet spells it.
57
+ *
58
+ * A number is milliseconds and lands as milliseconds. Nothing at all lands as
59
+ * the effect's own Material token, so a page that retunes its motion moves this
60
+ * animation with it.
61
+ */
62
+ export declare function durationValue(duration: number | undefined, effect: MPAnimation, mode?: MPAnimateMode): string;
63
+ /** A number is pixels; a string is already a CSS length. */
64
+ export declare function lengthValue(value: number | string): string;
65
+ /** `'infinite'` reaches CSS as the word; a count reaches it as the number. */
66
+ export declare function repeatValue(repeat: MPAnimateRepeat): string;
67
+ export declare function isInfinite(repeat: MPAnimateRepeat | undefined): boolean;
68
+ /**
69
+ * `normal`, `reverse`, `alternate`, `alternate-reverse` — the four CSS already
70
+ * has, assembled from the two props that mean something to a caller.
71
+ *
72
+ * `mode="out"` is a reversed run rather than a keyframe of its own, which is
73
+ * also why a reversed animation ends held on its own first frame: `fill-mode`
74
+ * is `both`, so a faded-out element stays faded out instead of snapping back.
75
+ */
76
+ export declare function directionValue(mode: MPAnimateMode, alternate: boolean | undefined): string;
77
+ export interface AnimationSlotOptions {
78
+ /** Which effect's tokens to fall back to, and which keyframe to run. */
79
+ effect: MPAnimation;
80
+ /** Milliseconds. Unset takes the effect's Material duration token. */
81
+ duration?: number;
82
+ /** Milliseconds. */
83
+ delay: number;
84
+ /** Unset takes the effect's Material easing token. */
85
+ easing?: MPEasing;
86
+ repeat: MPAnimateRepeat;
87
+ alternate?: boolean;
88
+ mode?: MPAnimateMode;
89
+ /** Where the animated properties start. Only the ones an effect reads. */
90
+ opacity?: number;
91
+ scale?: number;
92
+ x?: string;
93
+ y?: string;
94
+ angle?: string;
95
+ angleTo?: string;
96
+ }
97
+ /**
98
+ * The `--_mp-anim-*` slots, as an inline style object.
99
+ *
100
+ * Inline rather than utilities for the reason the accent slots are: these are
101
+ * per-instance numbers, and Tailwind cannot generate a class for a duration it
102
+ * has never seen written down.
103
+ */
104
+ export declare function animationSlots(options: AnimationSlotOptions): React.CSSProperties;
105
+ /**
106
+ * Which way a slide starts, given the edge it comes from.
107
+ *
108
+ * `MPSide` is physical everywhere in this library, and it stays physical here:
109
+ * something sliding in from the top of the window comes from the top in every
110
+ * writing direction.
111
+ */
112
+ export declare function slideOffsets(from: MPSide, distance: number | string): {
113
+ x: string;
114
+ y: string;
115
+ };
116
+ export declare function usePrefersReducedMotion(): boolean;
117
+ export interface AnimationRunOptions {
118
+ trigger: MPAnimateTrigger;
119
+ play?: boolean;
120
+ once: boolean;
121
+ threshold: number;
122
+ paused?: boolean;
123
+ /** An infinite effect stops when the pointer leaves; a finite one finishes. */
124
+ infinite: boolean;
125
+ }
126
+ export interface AnimationRun {
127
+ /** Goes on the animated element. */
128
+ ref: React.RefCallback<HTMLElement>;
129
+ /** `running` or `paused`, for `--_mp-anim-state`. */
130
+ state: 'running' | 'paused';
131
+ /** Whether the animation has been let go at all. */
132
+ started: boolean;
133
+ /** Spread onto the element when `trigger` is `hover`; empty otherwise. */
134
+ handlers: React.HTMLAttributes<HTMLElement>;
135
+ }
136
+ /**
137
+ * Starts, restarts and holds an animation.
138
+ *
139
+ * Two things here are less obvious than they look.
140
+ *
141
+ * **Waiting is `animation-play-state: paused`, not a second class.** An element
142
+ * that has not been triggered yet has to already look like its own first frame,
143
+ * or a `visible` fade would be fully drawn until it scrolled into view and then
144
+ * blink out to start. With `fill-mode: both` a paused animation shows exactly
145
+ * that frame, so waiting and running are one animation in two states rather
146
+ * than two states to keep in step.
147
+ *
148
+ * **Restarting reaches for the DOM.** There is no way to rewind a CSS animation
149
+ * from React: re-rendering with the same class changes nothing, and a `key`
150
+ * would restart the animation by unmounting the children, taking their state
151
+ * with it. Clearing `animation-name`, reading a layout property to force the
152
+ * style to settle, and putting it back is the one move that rewinds the element
153
+ * and leaves everything inside it alone.
154
+ */
155
+ export declare function useAnimationRun({ trigger, play, once, threshold, paused, infinite }: AnimationRunOptions): AnimationRun;
156
+ export interface AnimateElementParams extends AnimationSlotOptions, AnimationRunOptions {
157
+ }
158
+ export interface AnimateElement {
159
+ ref: React.RefCallback<HTMLElement>;
160
+ className: string;
161
+ style: React.CSSProperties;
162
+ /** The hover handlers and the two data attributes, ready to be spread. */
163
+ props: React.HTMLAttributes<HTMLElement> & Record<string, unknown>;
164
+ }
165
+ /**
166
+ * Everything an `MPAnimate*` root needs, in one call.
167
+ *
168
+ * The six effect components differ only in their defaults and in which slots
169
+ * they fill, so this is where the identical two-thirds of each of them lives.
170
+ * The ones that have to understand their children — Typing, Marquee, Headline,
171
+ * Appear — call `useAnimationRun` directly and put the classes where their own
172
+ * structure needs them.
173
+ *
174
+ * `data-mp-animation` and `data-mp-state` are here rather than in each
175
+ * component because they are the same two facts every time, and because a test
176
+ * that has to assert on a class name is a test that breaks when a class name
177
+ * changes.
178
+ */
179
+ export declare function useAnimateElement(params: AnimateElementParams): AnimateElement;
@@ -0,0 +1 @@
1
+ import*as e from"react";export const ANIM_BASE="mp-anim";export const ANIMATION_CLASS={fade:"mp-anim-fade",grow:"mp-anim-scale",slide:"mp-anim-slide",zoom:"mp-anim-scale",rotate:"mp-anim-rotate",blink:"mp-anim-blink"};const n={fade:{in:"medium2",out:"short4"},grow:{in:"medium4",out:"short4"},slide:{in:"medium4",out:"short4"},zoom:{in:"medium4",out:"short4"},rotate:{in:"long2",out:"medium2"},blink:{in:"extra-long4",out:"extra-long4"}},t={fade:"emphasized-decelerate",grow:"emphasized-decelerate",slide:"emphasized-decelerate",zoom:"emphasized-decelerate",rotate:"emphasized-decelerate",blink:"standard"};export function easingValue(e){return`var(--mp-sys-motion-easing-${e})`}export function durationValue(e,t,i="in"){return void 0!==e?`${e}ms`:`var(--mp-sys-motion-duration-${n[t][i]})`}export function lengthValue(e){return"number"==typeof e?`${e}px`:e}export function repeatValue(e){return"infinite"===e?"infinite":String(e)}export function isInfinite(e){return"infinite"===e}export function directionValue(e,n){return"out"===e?n?"alternate-reverse":"reverse":n?"alternate":"normal"}export function animationSlots(e){const n=e.mode??"in",i={"--_mp-anim-duration":durationValue(e.duration,e.effect,n),"--_mp-anim-delay":`${e.delay}ms`,"--_mp-anim-ease":easingValue(e.easing??t[e.effect]),"--_mp-anim-repeat":repeatValue(e.repeat),"--_mp-anim-direction":directionValue(n,e.alternate)};return void 0!==e.opacity&&(i["--_mp-anim-opacity"]=String(e.opacity)),void 0!==e.scale&&(i["--_mp-anim-scale"]=String(e.scale)),void 0!==e.x&&(i["--_mp-anim-x"]=e.x),void 0!==e.y&&(i["--_mp-anim-y"]=e.y),void 0!==e.angle&&(i["--_mp-anim-angle"]=e.angle),void 0!==e.angleTo&&(i["--_mp-anim-angle-to"]=e.angleTo),i}export function slideOffsets(e,n){const t=lengthValue(n),i="number"==typeof n?-n+"px":`calc(-1 * ${t})`;switch(e){case"top":return{x:"0px",y:i};case"bottom":return{x:"0px",y:t};case"left":return{x:i,y:"0px"};default:return{x:t,y:"0px"}}}const i="(prefers-reduced-motion: reduce)";function a(e){if("undefined"==typeof window||!window.matchMedia)return()=>{};const n=window.matchMedia(i);return n.addEventListener("change",e),()=>n.removeEventListener("change",e)}function r(){return!("undefined"==typeof window||!window.matchMedia)&&window.matchMedia(i).matches}function o(){return!1}export function usePrefersReducedMotion(){return e.useSyncExternalStore(a,r,o)}export function useAnimationRun({trigger:n,play:t,once:i,threshold:a,paused:r,infinite:o}){const s=e.useRef(null),[u,m]=e.useState("mount"===n),[c,d]=e.useState(0),l=e.useCallback(()=>{m(!0),d(e=>e+1)},[]);e.useLayoutEffect(()=>{const e=s.current;if(!e||0===c)return;const n=[e,...e.querySelectorAll(".mp-anim, .mp-marquee-track")];for(const e of n)e.style.animationName="none";e.offsetWidth;for(const e of n)e.style.animationName=""},[c]),e.useEffect(()=>{if("visible"!==n)return;const e=s.current;if(!e||"undefined"==typeof IntersectionObserver)return void m(!0);const t=new IntersectionObserver(([e])=>{e.isIntersecting?(l(),i&&t.disconnect()):i||m(!1)},{threshold:a});return t.observe(e),()=>t.disconnect()},[n,i,a,l]),e.useEffect(()=>{"manual"===n&&(t?l():m(!1))},[n,t,l]);const p=e.useCallback(()=>{o&&m(!1)},[o]),f="hover"===n?{onPointerEnter:l,onFocus:l,onPointerLeave:p,onBlur:p}:{};return{ref:e.useCallback(e=>{s.current=e},[]),state:u&&!r?"running":"paused",started:u,handlers:f}}export function useAnimateElement(e){const{trigger:n,play:t,once:i,threshold:a,paused:r,infinite:o,...s}=e,u=useAnimationRun({trigger:n,play:t,once:i,threshold:a,paused:r,infinite:o});return{ref:u.ref,className:`mp-anim ${ANIMATION_CLASS[s.effect]}`,style:{...animationSlots(s),"--_mp-anim-state":u.state},props:{...u.handlers,"data-mp-animation":s.effect,"data-mp-state":u.state}}}
@@ -148,9 +148,9 @@ export declare function toISODateTime(date: Date, withSeconds?: boolean): string
148
148
  * (`S`, `M`, `T`, `W`, `T`, `F`, `S`), so the full name goes on the header's
149
149
  * `aria-label` and a screen reader hears "Monday" rather than "M".
150
150
  */
151
- export declare function weekdayLabels(locale: string | undefined, weekStartsOn: MPWeekday, weekday?: 'narrow' | 'short' | 'long'): string[];
151
+ export declare function weekdayLabels(locale: string | undefined, weekStartsOn: MPWeekday, weekday?: 'narrow' | 'short' | 'long'): readonly string[];
152
152
  /** The twelve month names, January first, in the locale's own words. */
153
- export declare function monthLabels(locale: string | undefined, month?: 'short' | 'long'): string[];
153
+ export declare function monthLabels(locale: string | undefined, month?: 'short' | 'long'): readonly string[];
154
154
  /**
155
155
  * Does this locale write the month before the year?
156
156
  *
@@ -1 +1 @@
1
- export const YEAR_PAGE_SIZE=12;export function makeDate(t,e,r){const n=new Date(0);return n.setFullYear(t,e,r),n.setHours(0,0,0,0),n}export function isValidDate(t){return t instanceof Date&&!Number.isNaN(t.getTime())}export function startOfDay(t){const e=new Date(t.getTime());return e.setHours(0,0,0,0),e}export function startOfMonth(t){return makeDate(t.getFullYear(),t.getMonth(),1)}export function daysInMonth(t,e){return makeDate(t,e+1,0).getDate()}export function today(){return startOfDay(new Date)}export function addDays(t,e){const r=new Date(t.getTime());return r.setDate(r.getDate()+e),r}export function addMonths(t,e){const r=new Date(t.getTime()),n=makeDate(t.getFullYear(),t.getMonth()+e,1);return r.setFullYear(n.getFullYear(),n.getMonth(),Math.min(t.getDate(),daysInMonth(n.getFullYear(),n.getMonth()))),r}export function addYears(t,e){return addMonths(t,12*e)}export function compareDay(t,e){return startOfDay(t).getTime()-startOfDay(e).getTime()}export function isSameDay(t,e){return isValidDate(t)&&isValidDate(e)&&0===compareDay(t,e)}export function isSameMonth(t,e){return isValidDate(t)&&isValidDate(e)&&t.getFullYear()===e.getFullYear()&&t.getMonth()===e.getMonth()}export function isDayOutside(t,e,r){return!!(isValidDate(e)&&compareDay(t,e)<0)||isValidDate(r)&&compareDay(t,r)>0}export function secondsOfDay(t){return 3600*t.getHours()+60*t.getMinutes()+t.getSeconds()}export function timeUnitSpan(t,e){const r=secondsOfDay(e);if("hour"===t){const t=3600*Math.floor(r/3600);return[t,t+3599]}if("minute"===t){const t=60*Math.floor(r/60);return[t,t+59]}if("second"===t)return[r,r];const n=e.getHours()<12?0:43200;return[n,n+43200-1]}export function withTime(t,e){const r=new Date(t.getTime());return r.setHours(e.hours??r.getHours(),e.minutes??r.getMinutes(),e.seconds??r.getSeconds(),0),r}export function mergeDateAndTime(t,e){return withTime(startOfDay(t),{hours:e.getHours(),minutes:e.getMinutes(),seconds:e.getSeconds()})}export function calendarWeeks(t,e){const r=startOfMonth(t),n=(r.getDay()-e+7)%7,o=addDays(r,-n);return Array.from({length:6},(t,e)=>Array.from({length:7},(t,r)=>addDays(o,7*e+r)))}export function yearPageStart(t){return t-(t%12+12)%12}const t=new Map;export function dateFormatter(e,r){const n=`${e??""}\0${JSON.stringify(r)}`;let o=t.get(n);return o||(o=new Intl.DateTimeFormat(e,r),t.set(n,o)),o}export function formatDate(t,e,r){return isValidDate(t)?dateFormatter(e,r).format(t):""}const e=Array.from({length:24},(t,e)=>new Date(2027,e%12,21+e%7,e,58,58));export function displaySamples(t,r){const n=dateFormatter(t,r);return[...new Set(e.map(t=>n.format(t)))]}export function withPlaceholder(t,e){return"string"==typeof e&&""!==e?[...t,e]:t}export function toISODate(t){const e=t=>String(t).padStart(2,"0");return`${String(t.getFullYear()).padStart(4,"0")}-${e(t.getMonth()+1)}-${e(t.getDate())}`}export function toISOTime(t,e=!1){const r=t=>String(t).padStart(2,"0"),n=`${r(t.getHours())}:${r(t.getMinutes())}`;return e?`${n}:${r(t.getSeconds())}`:n}export function toISODateTime(t,e=!1){return`${toISODate(t)}T${toISOTime(t,e)}`}const r=makeDate(2021,7,1);export function weekdayLabels(t,e,n="narrow"){const o=dateFormatter(t,{weekday:n});return Array.from({length:7},(t,n)=>o.format(addDays(r,(e+n)%7)))}export function monthLabels(t,e="short"){const r=dateFormatter(t,{month:e});return Array.from({length:12},(t,e)=>r.format(makeDate(2021,e,1)))}export function isMonthBeforeYear(t){const e=dateFormatter(t,{year:"numeric",month:"long"}).formatToParts(r);return e.findIndex(t=>"month"===t.type)<e.findIndex(t=>"year"===t.type)}export function isHour12(t){const e=dateFormatter(t,{hour:"numeric"}).resolvedOptions();return e.hourCycle?"h11"===e.hourCycle||"h12"===e.hourCycle:!0===e.hour12}export function meridiemLabels(t){const e=dateFormatter(t,{hour:"numeric",hour12:!0}),n=t=>{const n=e.formatToParts(withTime(r,{hours:t})).find(t=>"dayPeriod"===t.type);return n?.value??(t<12?"AM":"PM")};return[n(9),n(21)]}export function localeWeekStart(t){try{const e=t??(new Intl.DateTimeFormat).resolvedOptions().locale,r=new Intl.Locale(e),n="function"==typeof r.getWeekInfo?r.getWeekInfo():r.weekInfo;if("number"==typeof n?.firstDay)return n.firstDay%7}catch{}return 0}
1
+ export const YEAR_PAGE_SIZE=12;export function makeDate(t,e,r){const n=new Date(0);return n.setFullYear(t,e,r),n.setHours(0,0,0,0),n}export function isValidDate(t){return t instanceof Date&&!Number.isNaN(t.getTime())}export function startOfDay(t){const e=new Date(t.getTime());return e.setHours(0,0,0,0),e}export function startOfMonth(t){return makeDate(t.getFullYear(),t.getMonth(),1)}export function daysInMonth(t,e){return makeDate(t,e+1,0).getDate()}export function today(){return startOfDay(new Date)}export function addDays(t,e){const r=new Date(t.getTime());return r.setDate(r.getDate()+e),r}export function addMonths(t,e){const r=new Date(t.getTime()),n=makeDate(t.getFullYear(),t.getMonth()+e,1);return r.setFullYear(n.getFullYear(),n.getMonth(),Math.min(t.getDate(),daysInMonth(n.getFullYear(),n.getMonth()))),r}export function addYears(t,e){return addMonths(t,12*e)}export function compareDay(t,e){return startOfDay(t).getTime()-startOfDay(e).getTime()}export function isSameDay(t,e){return isValidDate(t)&&isValidDate(e)&&0===compareDay(t,e)}export function isSameMonth(t,e){return isValidDate(t)&&isValidDate(e)&&t.getFullYear()===e.getFullYear()&&t.getMonth()===e.getMonth()}export function isDayOutside(t,e,r){return!!(isValidDate(e)&&compareDay(t,e)<0)||isValidDate(r)&&compareDay(t,r)>0}export function secondsOfDay(t){return 3600*t.getHours()+60*t.getMinutes()+t.getSeconds()}export function timeUnitSpan(t,e){const r=secondsOfDay(e);if("hour"===t){const t=3600*Math.floor(r/3600);return[t,t+3599]}if("minute"===t){const t=60*Math.floor(r/60);return[t,t+59]}if("second"===t)return[r,r];const n=e.getHours()<12?0:43200;return[n,n+43200-1]}export function withTime(t,e){const r=new Date(t.getTime());return r.setHours(e.hours??r.getHours(),e.minutes??r.getMinutes(),e.seconds??r.getSeconds(),0),r}export function mergeDateAndTime(t,e){return withTime(startOfDay(t),{hours:e.getHours(),minutes:e.getMinutes(),seconds:e.getSeconds()})}export function calendarWeeks(t,e){const r=startOfMonth(t),n=(r.getDay()-e+7)%7,o=addDays(r,-n);return Array.from({length:6},(t,e)=>Array.from({length:7},(t,r)=>addDays(o,7*e+r)))}export function yearPageStart(t){return t-(t%12+12)%12}const t=new Map;export function dateFormatter(e,r){const n=`${e??""}\0${JSON.stringify(r)}`;let o=t.get(n);return o||(o=new Intl.DateTimeFormat(e,r),t.set(n,o)),o}export function formatDate(t,e,r){return isValidDate(t)?dateFormatter(e,r).format(t):""}const e=Array.from({length:24},(t,e)=>new Date(2027,e%12,21+e%7,e,58,58));export function displaySamples(t,r){const n=dateFormatter(t,r);return[...new Set(e.map(t=>n.format(t)))]}export function withPlaceholder(t,e){return"string"==typeof e&&""!==e?[...t,e]:t}export function toISODate(t){const e=t=>String(t).padStart(2,"0");return`${String(t.getFullYear()).padStart(4,"0")}-${e(t.getMonth()+1)}-${e(t.getDate())}`}export function toISOTime(t,e=!1){const r=t=>String(t).padStart(2,"0"),n=`${r(t.getHours())}:${r(t.getMinutes())}`;return e?`${n}:${r(t.getSeconds())}`:n}export function toISODateTime(t,e=!1){return`${toISODate(t)}T${toISOTime(t,e)}`}const r=makeDate(2021,7,1),n=new Map;export function weekdayLabels(t,e,o="narrow"){const a=`w ${t??""} ${e} ${o}`;let s=n.get(a);if(!s){const i=dateFormatter(t,{weekday:o});s=Array.from({length:7},(t,n)=>i.format(addDays(r,(e+n)%7))),n.set(a,s)}return s}export function monthLabels(t,e="short"){const r=`m ${t??""} ${e}`;let o=n.get(r);if(!o){const a=dateFormatter(t,{month:e});o=Array.from({length:12},(t,e)=>a.format(makeDate(2021,e,1))),n.set(r,o)}return o}export function isMonthBeforeYear(t){const e=dateFormatter(t,{year:"numeric",month:"long"}).formatToParts(r);return e.findIndex(t=>"month"===t.type)<e.findIndex(t=>"year"===t.type)}export function isHour12(t){const e=dateFormatter(t,{hour:"numeric"}).resolvedOptions();return e.hourCycle?"h11"===e.hourCycle||"h12"===e.hourCycle:!0===e.hour12}export function meridiemLabels(t){const e=dateFormatter(t,{hour:"numeric",hour12:!0}),n=t=>{const n=e.formatToParts(withTime(r,{hours:t})).find(t=>"dayPeriod"===t.type);return n?.value??(t<12?"AM":"PM")};return[n(9),n(21)]}export function localeWeekStart(t){try{const e=t??(new Intl.DateTimeFormat).resolvedOptions().locale,r=new Intl.Locale(e),n="function"==typeof r.getWeekInfo?r.getWeekInfo():r.weekInfo;if("number"==typeof n?.firstDay)return n.firstDay%7}catch{}return 0}