material-plus-ui 0.0.1 → 1.0.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 (265) hide show
  1. package/README.md +39 -28
  2. package/dist/components/accordion/MPAccordion.d.ts +115 -0
  3. package/dist/components/accordion/MPAccordion.js +1 -0
  4. package/dist/components/accordion/index.d.ts +2 -0
  5. package/dist/components/accordion/index.js +1 -0
  6. package/dist/components/alert/MPAlert.d.ts +91 -0
  7. package/dist/components/alert/MPAlert.js +1 -0
  8. package/dist/components/alert/index.d.ts +2 -0
  9. package/dist/components/alert/index.js +1 -0
  10. package/dist/components/aspect-ratio/MPAspectRatio.d.ts +69 -0
  11. package/dist/components/aspect-ratio/MPAspectRatio.js +1 -0
  12. package/dist/components/aspect-ratio/index.d.ts +2 -0
  13. package/dist/components/aspect-ratio/index.js +1 -0
  14. package/dist/components/avatar/MPAvatar.d.ts +97 -0
  15. package/dist/components/avatar/MPAvatar.js +1 -0
  16. package/dist/components/avatar/index.d.ts +2 -0
  17. package/dist/components/avatar/index.js +1 -0
  18. package/dist/components/badge/MPBadge.d.ts +104 -0
  19. package/dist/components/badge/MPBadge.js +1 -0
  20. package/dist/components/badge/index.d.ts +2 -0
  21. package/dist/components/badge/index.js +1 -0
  22. package/dist/components/blockquote/MPBlockquote.d.ts +73 -0
  23. package/dist/components/blockquote/MPBlockquote.js +1 -0
  24. package/dist/components/blockquote/index.d.ts +2 -0
  25. package/dist/components/blockquote/index.js +1 -0
  26. package/dist/components/box/MPBox.d.ts +78 -0
  27. package/dist/components/box/MPBox.js +1 -0
  28. package/dist/components/box/index.d.ts +2 -0
  29. package/dist/components/box/index.js +1 -0
  30. package/dist/components/breadcrumb/MPBreadcrumb.d.ts +105 -0
  31. package/dist/components/breadcrumb/MPBreadcrumb.js +1 -0
  32. package/dist/components/breadcrumb/index.d.ts +2 -0
  33. package/dist/components/breadcrumb/index.js +1 -0
  34. package/dist/components/button/MPButton.d.ts +70 -0
  35. package/dist/components/button/MPButton.js +1 -0
  36. package/dist/components/button/index.d.ts +2 -0
  37. package/dist/components/button/index.js +1 -0
  38. package/dist/components/button-group/MPButtonGroup.d.ts +31 -0
  39. package/dist/components/button-group/MPButtonGroup.js +1 -0
  40. package/dist/components/button-group/index.d.ts +2 -0
  41. package/dist/components/button-group/index.js +1 -0
  42. package/dist/components/card/MPCard.d.ts +73 -0
  43. package/dist/components/card/MPCard.js +1 -0
  44. package/dist/components/card/index.d.ts +2 -0
  45. package/dist/components/card/index.js +1 -0
  46. package/dist/components/carousel/MPCarousel.d.ts +116 -0
  47. package/dist/components/carousel/MPCarousel.js +1 -0
  48. package/dist/components/carousel/index.d.ts +2 -0
  49. package/dist/components/carousel/index.js +1 -0
  50. package/dist/components/chat-bubble/MPChatBubble.d.ts +132 -0
  51. package/dist/components/chat-bubble/MPChatBubble.js +1 -0
  52. package/dist/components/chat-bubble/index.d.ts +2 -0
  53. package/dist/components/chat-bubble/index.js +1 -0
  54. package/dist/components/checkbox/MPCheckbox.d.ts +76 -0
  55. package/dist/components/checkbox/MPCheckbox.js +1 -0
  56. package/dist/components/checkbox/index.d.ts +2 -0
  57. package/dist/components/checkbox/index.js +1 -0
  58. package/dist/components/chip/MPChip.d.ts +64 -0
  59. package/dist/components/chip/MPChip.js +1 -0
  60. package/dist/components/chip/index.d.ts +2 -0
  61. package/dist/components/chip/index.js +1 -0
  62. package/dist/components/collapsible/MPCollapsible.d.ts +97 -0
  63. package/dist/components/collapsible/MPCollapsible.js +1 -0
  64. package/dist/components/collapsible/index.d.ts +2 -0
  65. package/dist/components/collapsible/index.js +1 -0
  66. package/dist/components/color-picker/MPColorPicker.d.ts +113 -0
  67. package/dist/components/color-picker/MPColorPicker.js +1 -0
  68. package/dist/components/color-picker/index.d.ts +2 -0
  69. package/dist/components/color-picker/index.js +1 -0
  70. package/dist/components/combobox/MPCombobox.d.ts +147 -0
  71. package/dist/components/combobox/MPCombobox.js +1 -0
  72. package/dist/components/combobox/index.d.ts +2 -0
  73. package/dist/components/combobox/index.js +1 -0
  74. package/dist/components/date-picker/MPDatePicker.d.ts +95 -0
  75. package/dist/components/date-picker/MPDatePicker.js +1 -0
  76. package/dist/components/date-picker/index.d.ts +2 -0
  77. package/dist/components/date-picker/index.js +1 -0
  78. package/dist/components/date-range-picker/MPDateRangePicker.d.ts +98 -0
  79. package/dist/components/date-range-picker/MPDateRangePicker.js +1 -0
  80. package/dist/components/date-range-picker/index.d.ts +2 -0
  81. package/dist/components/date-range-picker/index.js +1 -0
  82. package/dist/components/date-time-picker/MPDateTimePicker.d.ts +78 -0
  83. package/dist/components/date-time-picker/MPDateTimePicker.js +1 -0
  84. package/dist/components/date-time-picker/index.d.ts +2 -0
  85. package/dist/components/date-time-picker/index.js +1 -0
  86. package/dist/components/dialog/MPDialog.d.ts +145 -0
  87. package/dist/components/dialog/MPDialog.js +1 -0
  88. package/dist/components/dialog/index.d.ts +2 -0
  89. package/dist/components/dialog/index.js +1 -0
  90. package/dist/components/divider/MPDivider.d.ts +80 -0
  91. package/dist/components/divider/MPDivider.js +1 -0
  92. package/dist/components/divider/index.d.ts +2 -0
  93. package/dist/components/divider/index.js +1 -0
  94. package/dist/components/drawer/MPDrawer.d.ts +163 -0
  95. package/dist/components/drawer/MPDrawer.js +1 -0
  96. package/dist/components/drawer/index.d.ts +2 -0
  97. package/dist/components/drawer/index.js +1 -0
  98. package/dist/components/empty/MPEmpty.d.ts +64 -0
  99. package/dist/components/empty/MPEmpty.js +1 -0
  100. package/dist/components/empty/index.d.ts +2 -0
  101. package/dist/components/empty/index.js +1 -0
  102. package/dist/components/file-picker/MPFilePicker.d.ts +103 -0
  103. package/dist/components/file-picker/MPFilePicker.js +1 -0
  104. package/dist/components/file-picker/index.d.ts +2 -0
  105. package/dist/components/file-picker/index.js +1 -0
  106. package/dist/components/highlight/MPHighlight.d.ts +95 -0
  107. package/dist/components/highlight/MPHighlight.js +1 -0
  108. package/dist/components/highlight/index.d.ts +2 -0
  109. package/dist/components/highlight/index.js +1 -0
  110. package/dist/components/icon-button/MPIconButton.d.ts +59 -0
  111. package/dist/components/icon-button/MPIconButton.js +1 -0
  112. package/dist/components/icon-button/index.d.ts +2 -0
  113. package/dist/components/icon-button/index.js +1 -0
  114. package/dist/components/list/MPList.d.ts +96 -0
  115. package/dist/components/list/MPList.js +1 -0
  116. package/dist/components/list/index.d.ts +2 -0
  117. package/dist/components/list/index.js +1 -0
  118. package/dist/components/locale/MPLocaleProvider.d.ts +63 -0
  119. package/dist/components/locale/MPLocaleProvider.js +1 -0
  120. package/dist/components/locale/index.d.ts +2 -0
  121. package/dist/components/locale/index.js +1 -0
  122. package/dist/components/menu/MPMenu.d.ts +223 -0
  123. package/dist/components/menu/MPMenu.js +1 -0
  124. package/dist/components/menu/index.d.ts +2 -0
  125. package/dist/components/menu/index.js +1 -0
  126. package/dist/components/number-field/MPNumberField.d.ts +99 -0
  127. package/dist/components/number-field/MPNumberField.js +1 -0
  128. package/dist/components/number-field/index.d.ts +2 -0
  129. package/dist/components/number-field/index.js +1 -0
  130. package/dist/components/otp-field/MPOtpField.d.ts +89 -0
  131. package/dist/components/otp-field/MPOtpField.js +1 -0
  132. package/dist/components/otp-field/index.d.ts +2 -0
  133. package/dist/components/otp-field/index.js +1 -0
  134. package/dist/components/overlay/MPOverlay.d.ts +96 -0
  135. package/dist/components/overlay/MPOverlay.js +1 -0
  136. package/dist/components/overlay/index.d.ts +2 -0
  137. package/dist/components/overlay/index.js +1 -0
  138. package/dist/components/panes/MPPanes.d.ts +100 -0
  139. package/dist/components/panes/MPPanes.js +1 -0
  140. package/dist/components/panes/index.d.ts +2 -0
  141. package/dist/components/panes/index.js +1 -0
  142. package/dist/components/pill/MPPill.d.ts +117 -0
  143. package/dist/components/pill/MPPill.js +1 -0
  144. package/dist/components/pill/index.d.ts +2 -0
  145. package/dist/components/pill/index.js +1 -0
  146. package/dist/components/popover/MPPopover.d.ts +138 -0
  147. package/dist/components/popover/MPPopover.js +1 -0
  148. package/dist/components/popover/index.d.ts +2 -0
  149. package/dist/components/popover/index.js +1 -0
  150. package/dist/components/progress-box/MPProgressBox.d.ts +40 -0
  151. package/dist/components/progress-box/MPProgressBox.js +1 -0
  152. package/dist/components/progress-box/index.d.ts +2 -0
  153. package/dist/components/progress-box/index.js +1 -0
  154. package/dist/components/progress-circular/MPProgressCircular.d.ts +32 -0
  155. package/dist/components/progress-circular/MPProgressCircular.js +1 -0
  156. package/dist/components/progress-circular/index.d.ts +2 -0
  157. package/dist/components/progress-circular/index.js +1 -0
  158. package/dist/components/progress-linear/MPProgressLinear.d.ts +32 -0
  159. package/dist/components/progress-linear/MPProgressLinear.js +1 -0
  160. package/dist/components/progress-linear/index.d.ts +2 -0
  161. package/dist/components/progress-linear/index.js +1 -0
  162. package/dist/components/radio-group/MPRadioGroup.d.ts +81 -0
  163. package/dist/components/radio-group/MPRadioGroup.js +1 -0
  164. package/dist/components/radio-group/index.d.ts +2 -0
  165. package/dist/components/radio-group/index.js +1 -0
  166. package/dist/components/segmented-button/MPSegmentedButton.d.ts +75 -0
  167. package/dist/components/segmented-button/MPSegmentedButton.js +1 -0
  168. package/dist/components/segmented-button/index.d.ts +2 -0
  169. package/dist/components/segmented-button/index.js +1 -0
  170. package/dist/components/select/MPSelect.d.ts +86 -0
  171. package/dist/components/select/MPSelect.js +1 -0
  172. package/dist/components/select/index.d.ts +2 -0
  173. package/dist/components/select/index.js +1 -0
  174. package/dist/components/shortcut/MPShortcut.d.ts +67 -0
  175. package/dist/components/shortcut/MPShortcut.js +1 -0
  176. package/dist/components/shortcut/index.d.ts +2 -0
  177. package/dist/components/shortcut/index.js +1 -0
  178. package/dist/components/skeleton/MPSkeleton.d.ts +76 -0
  179. package/dist/components/skeleton/MPSkeleton.js +1 -0
  180. package/dist/components/skeleton/index.d.ts +2 -0
  181. package/dist/components/skeleton/index.js +1 -0
  182. package/dist/components/slider/MPSlider.d.ts +77 -0
  183. package/dist/components/slider/MPSlider.js +1 -0
  184. package/dist/components/slider/index.d.ts +2 -0
  185. package/dist/components/slider/index.js +1 -0
  186. package/dist/components/snackbar/MPSnackbar.d.ts +170 -0
  187. package/dist/components/snackbar/MPSnackbar.js +1 -0
  188. package/dist/components/snackbar/index.d.ts +2 -0
  189. package/dist/components/snackbar/index.js +1 -0
  190. package/dist/components/spoiler/MPSpoiler.d.ts +106 -0
  191. package/dist/components/spoiler/MPSpoiler.js +1 -0
  192. package/dist/components/spoiler/index.d.ts +2 -0
  193. package/dist/components/spoiler/index.js +1 -0
  194. package/dist/components/switch/MPSwitch.d.ts +75 -0
  195. package/dist/components/switch/MPSwitch.js +1 -0
  196. package/dist/components/switch/index.d.ts +2 -0
  197. package/dist/components/switch/index.js +1 -0
  198. package/dist/components/table/MPTable.d.ts +107 -0
  199. package/dist/components/table/MPTable.js +1 -0
  200. package/dist/components/table/index.d.ts +2 -0
  201. package/dist/components/table/index.js +1 -0
  202. package/dist/components/text-field/MPTextField.d.ts +17 -18
  203. package/dist/components/text-field/MPTextField.js +1 -1
  204. package/dist/components/text-link/MPTextLink.d.ts +88 -0
  205. package/dist/components/text-link/MPTextLink.js +1 -0
  206. package/dist/components/text-link/index.d.ts +2 -0
  207. package/dist/components/text-link/index.js +1 -0
  208. package/dist/components/time-picker/MPTimePicker.d.ts +108 -0
  209. package/dist/components/time-picker/MPTimePicker.js +1 -0
  210. package/dist/components/time-picker/index.d.ts +2 -0
  211. package/dist/components/time-picker/index.js +1 -0
  212. package/dist/components/timeline/MPTimeline.d.ts +96 -0
  213. package/dist/components/timeline/MPTimeline.js +1 -0
  214. package/dist/components/timeline/index.d.ts +2 -0
  215. package/dist/components/timeline/index.js +1 -0
  216. package/dist/components/tooltip/MPTooltip.d.ts +117 -0
  217. package/dist/components/tooltip/MPTooltip.js +1 -0
  218. package/dist/components/tooltip/index.d.ts +2 -0
  219. package/dist/components/tooltip/index.js +1 -0
  220. package/dist/components/typography/MPTypography.d.ts +94 -0
  221. package/dist/components/typography/MPTypography.js +1 -0
  222. package/dist/components/typography/index.d.ts +2 -0
  223. package/dist/components/typography/index.js +1 -0
  224. package/dist/constants/icons.d.ts +36 -0
  225. package/dist/constants/icons.js +1 -1
  226. package/dist/index.d.ts +55 -0
  227. package/dist/index.js +1 -1
  228. package/dist/internal/Calendar.d.ts +118 -0
  229. package/dist/internal/Calendar.js +1 -0
  230. package/dist/internal/FieldOutline.d.ts +38 -0
  231. package/dist/internal/FieldOutline.js +1 -0
  232. package/dist/internal/Picker.d.ts +110 -0
  233. package/dist/internal/Picker.js +1 -0
  234. package/dist/internal/StateLayer.d.ts +45 -0
  235. package/dist/internal/StateLayer.js +1 -0
  236. package/dist/internal/SupportingText.d.ts +23 -0
  237. package/dist/internal/SupportingText.js +1 -0
  238. package/dist/internal/WidthSizer.d.ts +31 -0
  239. package/dist/internal/WidthSizer.js +1 -0
  240. package/dist/internal/accent.d.ts +39 -0
  241. package/dist/internal/accent.js +1 -0
  242. package/dist/internal/button-group.d.ts +21 -0
  243. package/dist/internal/button-group.js +1 -0
  244. package/dist/internal/color.d.ts +125 -0
  245. package/dist/internal/color.js +1 -0
  246. package/dist/internal/date.d.ts +179 -0
  247. package/dist/internal/date.js +1 -0
  248. package/dist/internal/i18n.d.ts +131 -0
  249. package/dist/internal/i18n.js +1 -0
  250. package/dist/internal/locale.d.ts +43 -0
  251. package/dist/internal/locale.js +1 -0
  252. package/dist/internal/menu.d.ts +23 -0
  253. package/dist/internal/menu.js +1 -0
  254. package/dist/internal/progress.d.ts +126 -0
  255. package/dist/internal/progress.js +1 -0
  256. package/dist/internal/scale.d.ts +127 -0
  257. package/dist/internal/scale.js +1 -0
  258. package/dist/internal/surface.d.ts +76 -0
  259. package/dist/internal/surface.js +1 -0
  260. package/dist/internal/visually-hidden.d.ts +23 -0
  261. package/dist/internal/visually-hidden.js +1 -0
  262. package/dist/styles.css +1 -1
  263. package/dist/tailwind.css +1285 -20
  264. package/dist/types.d.ts +107 -16
  265. package/package.json +16 -21
@@ -0,0 +1,75 @@
1
+ import * as React from 'react';
2
+ import type { MPColor, MPSize } from '../../types';
3
+ /** Which side of the track the label sits on. */
4
+ export type MPSwitchLabelPlacement = 'start' | 'end';
5
+ export interface MPSwitchProps {
6
+ /** Whether the switch is on. Use with `onCheckedChange` for a controlled one. */
7
+ checked?: boolean;
8
+ /** Whether it starts on, for an uncontrolled one. */
9
+ defaultChecked?: boolean;
10
+ /** Called with the new state — a boolean, not an event. */
11
+ onCheckedChange?: (checked: boolean) => void;
12
+ /** The text beside the track, wired to it by Base UI's Field. */
13
+ label?: React.ReactNode;
14
+ /** The line under the label. Replaced by `errorMessage` when there is one. */
15
+ description?: React.ReactNode;
16
+ /** The message under the label, which also turns the switch over. */
17
+ errorMessage?: React.ReactNode;
18
+ /**
19
+ * Draws a tick in the thumb when it is on and a cross when it is off.
20
+ *
21
+ * Off by default, and worth turning on wherever the two states are not
22
+ * obviously different in context: the thumb's position and the track's colour
23
+ * are otherwise the only signals, and one of those is a hue.
24
+ * @default false
25
+ */
26
+ icons?: boolean;
27
+ /**
28
+ * Which side the label sits on. `end` reads as a caption for the control;
29
+ * `start` is for a settings list, where the labels form a column and every
30
+ * switch lines up on the right.
31
+ * @default 'end'
32
+ */
33
+ labelPlacement?: MPSwitchLabelPlacement;
34
+ /**
35
+ * The track's size and the label's type scale.
36
+ * @default 'md'
37
+ */
38
+ size?: MPSize;
39
+ /**
40
+ * Which accent family the track takes when it is on.
41
+ * @default 'primary'
42
+ */
43
+ color?: MPColor;
44
+ /** Marks the switch required. */
45
+ required?: boolean;
46
+ /** Greys the switch out and stops it taking input. */
47
+ disabled?: boolean;
48
+ /** Shows the state without allowing it to be changed. */
49
+ readOnly?: boolean;
50
+ /** Name of the form control. */
51
+ name?: string;
52
+ /**
53
+ * The id put on the control and pointed at by the label. Derived from `name`
54
+ * when omitted, and generated when there is no name either.
55
+ */
56
+ id?: string;
57
+ /**
58
+ * Stretches the row, so a `start` label takes the slack and the track sits
59
+ * against the far edge. This is what makes a column of settings line up.
60
+ */
61
+ fullWidth?: boolean;
62
+ }
63
+ /**
64
+ * A Material Design switch.
65
+ *
66
+ * The difference from a checkbox is not visual, it is temporal: a checkbox is a
67
+ * value that gets submitted with a form, a switch takes effect the moment it
68
+ * moves. If there is a Save button underneath, it should have been a checkbox.
69
+ *
70
+ * The thumb is the one thing in this library that actually travels, so this is
71
+ * also the only place the spec's `standard` easing is read — quick to leave, slow
72
+ * to arrive, which is what makes a 200ms move read as something being pushed
73
+ * rather than as something being teleported and then apologised for.
74
+ */
75
+ export declare const MPSwitch: React.ForwardRefExoticComponent<MPSwitchProps & React.RefAttributes<HTMLElement>>;
@@ -0,0 +1 @@
1
+ import{jsx as e,Fragment as t,jsxs as a}from"react/jsx-runtime";import*as r from"react";import{Switch as n}from"@base-ui/react/switch";import{Field as i}from"@base-ui/react/field";import{MPIcon as c}from"../icon/MPIcon";import{CheckIcon as s,CloseIcon as o}from"../../constants/icons";import{accentSlots as l}from"../../internal/accent";import{MPStateLayer as d}from"../../internal/StateLayer";import{MPSupportingText as h}from"../../internal/SupportingText";import{PROSE_TEXT as m,hasContent as p}from"../../internal/scale";const u={xs:{track:"h-5 w-8",thumb:"left-[5px] size-2.5 data-checked:left-[15px] data-checked:size-3.5",halo:"size-8",glyph:8},sm:{track:"h-6 w-10",thumb:"left-1.5 size-3 data-checked:left-[19px] data-checked:size-[18px]",halo:"size-9",glyph:10},md:{track:"h-8 w-13",thumb:"left-2 size-4 data-checked:left-6 data-checked:size-6",halo:"size-10",glyph:14},lg:{track:"h-9 w-15",thumb:"left-[9px] size-[18px] data-checked:left-7 data-checked:size-7",halo:"size-11",glyph:16},xl:{track:"h-10 w-17",thumb:"left-2.5 size-5 data-checked:left-[33px] data-checked:size-[30px]",halo:"size-12",glyph:18}};export const MPSwitch=r.forwardRef(function({checked:f,defaultChecked:g,onCheckedChange:k,label:x,description:b,errorMessage:z,icons:y=!1,labelPlacement:w="end",size:j="md",color:N="primary",required:_=!1,disabled:C=!1,readOnly:M=!1,name:v,id:P,fullWidth:R=!1},S){const W=p(z),q=W?"error":N,F=u[j],I=r.useId(),L=P??`mp-switch-${v??I}`,O=e("span",{className:"flex h-[1lh] shrink-0 items-center",children:e(n.Root,{ref:S,id:L,name:v,checked:f,defaultChecked:g,required:_,disabled:C,readOnly:M,onCheckedChange:e=>k?.(e),className:["mp-switch__track group relative box-border inline-flex shrink-0 p-0","rounded-mp-full appearance-none font-[inherit] outline-none","transition-[background-color,box-shadow]","duration-(--mp-sys-motion-duration-short4) ease-mp-standard",F.track,C?["bg-mp-surface-container-highest inset-ring-2 inset-ring-mp-on-surface/12","cursor-default","data-checked:bg-mp-on-surface/12 data-checked:inset-ring-0"].join(" "):[M?"cursor-default":"cursor-pointer","bg-mp-surface-container-highest inset-ring-2",W?"inset-ring-mp-error":"inset-ring-mp-outline","data-checked:inset-ring-0 data-checked:bg-(--_mp-accent)"].join(" ")].join(" "),children:a(n.Thumb,{className:["mp-switch__thumb absolute top-1/2 flex -translate-y-1/2 items-center justify-center","rounded-full","transition-[left,width,height,background-color]","duration-(--mp-sys-motion-duration-short4) ease-mp-standard",F.thumb,C?"bg-mp-on-surface/38 data-checked:bg-mp-surface-container-highest":[W?"bg-mp-error":"bg-mp-outline","data-checked:bg-(--_mp-on-accent)"].join(" ")].join(" "),children:[C?null:e(d,{layer:["top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 rounded-full",F.halo,"bg-mp-on-surface group-data-checked:bg-(--_mp-accent)"].join(" ")}),y?a(t,{children:[e("span",{className:["hidden items-center group-data-checked:flex",C?"text-mp-surface-container-highest":"text-(--_mp-accent)"].join(" "),children:e(c,{icon:s,size:F.glyph,strokeWidth:3})}),e("span",{className:"text-mp-surface-container-highest flex items-center group-data-checked:hidden",children:e(c,{icon:o,size:F.glyph,strokeWidth:3})})]}):null]})})}),T=p(x)||p(b)||W?a("span",{className:["flex min-w-0 flex-col gap-0.5","start"===w?"flex-1":""].filter(Boolean).join(" "),children:[p(x)?a(i.Label,{htmlFor:L,className:["leading-[1.4]",C?"text-mp-on-surface/38 cursor-default":M?"text-mp-on-surface":"text-mp-on-surface cursor-pointer"].join(" "),children:[x,_?e("span",{"aria-hidden":"true",children:" *"}):null]}):null,e(h,{description:b,errorMessage:z})]}):null;return e(i.Root,{className:["mp-switch align-top",R?"flex w-full":"inline-flex"].join(" "),disabled:C,invalid:W,"data-mp-size":j,style:l(q),children:e("div",{className:["flex w-full items-start gap-3",m[j]].join(" "),children:a(t,"start"===w?{children:[T,O]}:{children:[O,T]})})})});
@@ -0,0 +1,2 @@
1
+ export { MPSwitch } from './MPSwitch';
2
+ export type { MPSwitchLabelPlacement, MPSwitchProps } from './MPSwitch';
@@ -0,0 +1 @@
1
+ export{MPSwitch}from"./MPSwitch";
@@ -0,0 +1,107 @@
1
+ import * as React from 'react';
2
+ import type { MPAlign, MPColor, MPSize, MPVariant } from '../../types';
3
+ /** Which edge the text in a column lines up against. */
4
+ export type MPTableAlign = MPAlign;
5
+ /**
6
+ * A column: its heading, its default width, and how to get a cell out of a row.
7
+ *
8
+ * This is the whole reason the component takes data rather than markup. A `<td>`
9
+ * written out per row can silently disagree with the `<th>` above it about how
10
+ * many there are or what order they come in; a column list cannot.
11
+ */
12
+ export interface MPTableColumn<Row> {
13
+ /**
14
+ * Identifies the column, and — unless `render` says otherwise — names the
15
+ * property to read off each row.
16
+ */
17
+ key: string;
18
+ /** The heading. Defaults to the `key`, which is usually not what you want. */
19
+ label?: React.ReactNode;
20
+ /**
21
+ * The column's default width. A number is pixels; a string is any CSS length.
22
+ *
23
+ * "Default" is meant: the table still balances the columns to fill its width,
24
+ * so this is a starting proportion rather than a guarantee.
25
+ */
26
+ width?: number | string;
27
+ /**
28
+ * Text alignment. Numbers usually want `end` so their digits line up in a
29
+ * column; everything else wants `start`.
30
+ * @default 'start'
31
+ */
32
+ align?: MPTableAlign;
33
+ /**
34
+ * Renders the cell. Without it the cell is `row[key]` rendered as-is, which
35
+ * covers strings and numbers and nothing else.
36
+ */
37
+ render?: (row: Row, index: number) => React.ReactNode;
38
+ }
39
+ export interface MPTableProps<Row> extends Omit<React.ComponentPropsWithoutRef<'div'>, 'color' | 'children'> {
40
+ /** The columns, in the order they appear. */
41
+ headers: readonly MPTableColumn<Row>[];
42
+ /** The rows. */
43
+ items: readonly Row[];
44
+ /**
45
+ * A stable key per row. Defaults to the row's index, which is fine for a
46
+ * static table and wrong for one that sorts or filters.
47
+ */
48
+ getRowKey?: (row: Row, index: number) => React.Key;
49
+ /** Shown above the table, and read out as its accessible name. */
50
+ caption?: React.ReactNode;
51
+ /**
52
+ * What to show instead of rows when `items` is empty.
53
+ * @default 'No data'
54
+ */
55
+ empty?: React.ReactNode;
56
+ /**
57
+ * Tints every other row. Useful for a wide table where the eye has to track
58
+ * across; noise on a narrow one.
59
+ * @default false
60
+ */
61
+ striped?: boolean;
62
+ /**
63
+ * Lights the row under the pointer.
64
+ * @default false
65
+ */
66
+ hoverable?: boolean;
67
+ /**
68
+ * Pins the header while the body scrolls. Only does anything if something
69
+ * around the table actually constrains its height.
70
+ * @default false
71
+ */
72
+ stickyHeader?: boolean;
73
+ /** Makes rows activatable. Also turns on the hover treatment. */
74
+ onRowClick?: (row: Row, index: number) => void;
75
+ /**
76
+ * How much surface the sheet around the table paints.
77
+ * @default 'outlined'
78
+ */
79
+ variant?: MPVariant;
80
+ /**
81
+ * @default 'md'
82
+ */
83
+ size?: MPSize;
84
+ /**
85
+ * Which accent family a hovered or pressed row reads. The cells themselves
86
+ * stay neutral.
87
+ * @default 'primary'
88
+ */
89
+ color?: MPColor;
90
+ }
91
+ /**
92
+ * A grid of data.
93
+ *
94
+ * The sheet takes the same `variant`, `size` and `color` as everything it might
95
+ * sit next to. What the table adds is the part that is genuinely tabular: the
96
+ * columns, the rows, and the fact that the two cannot drift apart.
97
+ *
98
+ * ## Why it is not `React.forwardRef`
99
+ *
100
+ * It is generic in `Row`, and a `forwardRef` component's type erases that: the
101
+ * wrapper is typed as one component rather than as a function with a type
102
+ * parameter, so `headers` and `items` would stop checking against each other and
103
+ * `column.render` would hand back `unknown`. Losing that check would cost more
104
+ * than a ref on the scroll container is worth — and a caller who needs one can
105
+ * put it on a `<div>` of their own around this.
106
+ */
107
+ export declare function MPTable<Row>({ headers, items, getRowKey, caption, empty, striped, hoverable, stickyHeader, onRowClick, variant, size, color, className, style, ...props }: MPTableProps<Row>): React.JSX.Element;
@@ -0,0 +1 @@
1
+ import{jsx as e,jsxs as t}from"react/jsx-runtime";import{accentSlots as r}from"../../internal/accent";import{META_TEXT as a}from"../../internal/scale";import{CONTAINER_SURFACE as l}from"../../internal/surface";const o={xs:"0.625rem",sm:"0.75rem",md:"1rem",lg:"1.25rem",xl:"1.5rem"},m={xs:"0.375rem",sm:"0.625rem",md:"1rem",lg:"1.25rem",xl:"1.5rem"},n={xs:"text-mp-body-small",sm:"text-mp-body-small",md:"text-mp-body-medium",lg:"text-mp-body-medium",xl:"text-mp-body-large"},i={xs:"text-mp-label-medium",sm:"text-mp-label-medium",md:"text-mp-title-small",lg:"text-mp-title-small",xl:"text-mp-title-medium"},s=["[--_mp-row:transparent]","transition-[background-color] duration-(--mp-sys-motion-duration-short4)"].join(" ");export function MPTable({headers:c,items:d,getRowKey:p,caption:x,empty:u="No data",striped:y=!1,hoverable:h=!1,stickyHeader:g=!1,onRowClick:b,variant:f="outlined",size:v="md",color:w="primary",className:k,style:N,..._}){const j=o[v],$=m[v],C=Boolean(b),A=h||C,B={padding:`${$} ${j}`},z={...B,backgroundColor:"var(--_mp-color-surface-container)"},R={borderTop:"1px solid var(--_mp-color-outline-variant)",backgroundColor:"var(--_mp-row)"};return e("div",{"data-mp-size":v,"data-mp-variant":f,className:["mp-table rounded-mp-md overflow-x-auto",l[f],k??""].filter(Boolean).join(" "),style:{...r(w),...N},..._,children:t("table",{className:`text-mp-on-surface w-full text-start ${n[v]}`,style:{borderCollapse:"collapse"},children:[x?e("caption",{className:`text-mp-on-surface-variant ${a}`,style:{...B,textAlign:"start"},children:x}):null,e("colgroup",{children:c.map(t=>{return e("col",{style:void 0===t.width?void 0:{width:(r=t.width,"number"==typeof r?`${r}px`:r)}},t.key);var r})}),e("thead",{children:e("tr",{children:c.map(t=>e("th",{scope:"col",className:["text-mp-on-surface-variant whitespace-nowrap",i[v],g?"sticky top-0 z-10":""].filter(Boolean).join(" "),style:{...z,textAlign:t.align??"start"},children:t.label??t.key},t.key))})}),e("tbody",{children:0===d.length?e("tr",{className:s,style:R,children:e("td",{colSpan:c.length,className:"text-mp-on-surface-variant",style:{padding:`2rem ${j}`,textAlign:"center"},children:u})}):d.map((t,r)=>e("tr",{className:[s,y&&r%2==1?"[--_mp-row:var(--_mp-color-surface-container-low)]":"",A?"hover:[--_mp-row:var(--_mp-color-surface-container)]":"",C?"cursor-pointer":""].filter(Boolean).join(" "),style:R,onClick:b?()=>b(t,r):void 0,children:c.map(a=>e("td",{style:{...B,textAlign:a.align??"start"},children:a.render?a.render(t,r):t[a.key]},a.key))},p?p(t,r):r))})]})})}
@@ -0,0 +1,2 @@
1
+ export { MPTable } from './MPTable';
2
+ export type { MPTableAlign, MPTableColumn, MPTableProps } from './MPTable';
@@ -0,0 +1 @@
1
+ export{MPTable}from"./MPTable";
@@ -1,7 +1,8 @@
1
1
  import * as React from 'react';
2
+ import type { MPStyleProps } from '../../types';
2
3
  /** The input modes this field is built for. */
3
4
  export type MPTextFieldType = 'email' | 'password' | 'text';
4
- export interface MPTextFieldProps {
5
+ export interface MPTextFieldProps extends MPStyleProps {
5
6
  /**
6
7
  * The field's text. This is a controlled component: what is shown is what is
7
8
  * passed, except during composition — see `onChange`.
@@ -20,28 +21,21 @@ export interface MPTextFieldProps {
20
21
  /** Native `autocomplete` token — `'email'`, `'current-password'`, `'off'`. */
21
22
  autoComplete?: string;
22
23
  /**
23
- * Label above the field. Always drawn shrunk and notched rather than floating
24
- * over the placeholder, so a field with a label and a field without one sit
25
- * at the same height in a form.
24
+ * Label above the field. Always drawn in the outline's notch rather than
25
+ * floating over the placeholder, so a field with a label and a field without
26
+ * one sit at the same height in a form.
26
27
  */
27
28
  label?: string;
28
29
  /** Marks the field required, both to assistive technology and to the label. */
29
30
  required?: boolean;
30
31
  /** Greys the field out and stops it taking input. */
31
32
  disabled?: boolean;
32
- /**
33
- * Draws the field at MUI's `medium` size instead of `small`.
34
- * @default false
35
- */
36
- large?: boolean;
37
33
  /**
38
34
  * Focuses the field on mount — except on a small screen, where it would
39
35
  * summon the on-screen keyboard over the page the reader has just arrived at.
40
36
  * @default false
41
37
  */
42
38
  autoFocus?: boolean;
43
- /** Stretches the field to the width of its container. */
44
- fullWidth?: boolean;
45
39
  /**
46
40
  * Shows the value without allowing edits. Unlike `disabled` the text stays
47
41
  * selectable and the field stays in the tab order, which is what you want for
@@ -97,14 +91,19 @@ export interface MPTextFieldProps {
97
91
  onFormReset?: () => void;
98
92
  }
99
93
  /**
100
- * A Material UI text field that survives an IME.
94
+ * A Material Design text field that survives an IME.
95
+ *
96
+ * The control is an outlined text field, drawn from Material Design 3's own
97
+ * component tokens: `outline` at rest, `primary` and a 2px stroke on focus,
98
+ * `error` when there is a message, and the spec's disabled opacities. Behaviour
99
+ * that a field needs but has nothing to do with looks — the label association,
100
+ * the validity plumbing, the `aria-describedby` onto the supporting text —
101
+ * comes from Base UI's `Field`.
101
102
  *
102
- * The field is `@mui/material`'s `OutlinedInput`, and everything MUI decides
103
- * about how a field looks — the notched outline, the sizes, the palette, the
104
- * error colour — it still decides here. What this component adds is the
105
- * handling around a controlled input that a language with an input method
106
- * exposes, plus the parts of a field that are always assembled by hand
107
- * anyway: the label, the helper text, the adornments and the password toggle.
103
+ * What this component adds is the handling around a controlled input that a
104
+ * language with an input method exposes, plus the parts of a field that are
105
+ * always assembled by hand anyway: the notch, the adornments and the password
106
+ * toggle.
108
107
  *
109
108
  * ## The composition problem
110
109
  *
@@ -1 +1 @@
1
- import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as o from"react";import r from"@mui/material/FormControl";import n from"@mui/material/FormHelperText";import i from"@mui/material/IconButton";import a from"@mui/material/InputAdornment";import l from"@mui/material/InputLabel";import s from"@mui/material/OutlinedInput";import m from"@mui/material/useMediaQuery";import{useTheme as u}from"@mui/material/styles";import{MPIcon as d}from"../icon/MPIcon";import{VisibilityIcon as p,VisibilityOffIcon as c}from"../../constants/icons";export const MPTextField=o.forwardRef(function({value:f,name:h,type:x="text",placeholder:y,autoComplete:b,label:g,onChange:v,onFormReset:C,onSubmit:w,errorMessage:I="",required:F=!1,fullWidth:M=!1,readOnly:k=!1,autoFocus:z=!1,large:E=!1,disabled:S=!1,disableEnterKey:D=!1,rows:R,maxLength:j,startIcon:A,resizable:L=!1,id:O},P){const q=o.useRef(null),K=u(),T=m(K.breakpoints.down("sm")),[U,W]=o.useState(!1),[B,H]=o.useState(!1),[Q,$]=o.useState(f),G=o.useId(),J=O??`mp-text-field-${h??G}`,N=!!R,V=o.useCallback(e=>{q.current=e,"function"==typeof P?P(e):P&&(P.current=e)},[P]),X=e=>{e.preventDefault()};return o.useEffect(()=>{B||$(f)},[f,B]),o.useEffect(()=>{z&&!T&&q.current?.focus()},[]),t(r,{required:F,fullWidth:M,error:I.length>0,children:[g&&e(l,{size:"small",color:"secondary",shrink:!0,htmlFor:J,children:g}),e(s,{id:J,autoComplete:b,inputRef:V,type:U?"text":x,label:g,notched:!!g,rows:R,multiline:N,color:k?"secondary":void 0,readOnly:k,placeholder:y,startAdornment:A?e(a,{position:"start",children:A}):null,inputProps:j?{maxLength:j}:void 0,endAdornment:"password"===x?e(a,{position:"end",children:e(i,{"aria-label":U?"hide the password":"display the password",onClick:()=>W(e=>!e),onMouseDown:X,onMouseUp:X,edge:"end",disabled:S,children:e(d,{icon:U?p:c,size:E?22:20})})}):null,size:E?"medium":"small",sx:L&&N?{"& textarea":{resize:"vertical"}}:void 0,name:h,disabled:S,value:B?Q:f,onChange:e=>{C?.();const t=e.target.value;B&&$(t),v?.(t)},onCompositionStart:()=>{H(!0),$(f)},onCompositionUpdate:e=>{$(e.target.value)},onCompositionEnd:e=>{H(!1);const t=e.target.value;v?.(t),$(t)},onKeyDown:e=>{"Enter"===e.key&&(w?.(),N&&!D||e.preventDefault())}}),I.length>0&&e(n,{error:!0,children:I})]})});
1
+ import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as o from"react";import{Field as a}from"@base-ui/react/field";import{MPIcon as n}from"../icon/MPIcon";import{MPFieldLabel as r,MPFieldOutline as l}from"../../internal/FieldOutline";import{VisibilityIcon as i,VisibilityOffIcon as s}from"../../constants/icons";const d={xs:{padding:"px-2",control:"py-1.5",text:"text-mp-body-medium",icon:16},sm:{padding:"px-3",control:"py-2.5",text:"text-mp-body-medium",icon:18},md:{padding:"px-4",control:"py-4",text:"text-mp-body-large",icon:20},lg:{padding:"px-4",control:"py-5",text:"text-mp-body-large",icon:22},xl:{padding:"px-5",control:"py-6",text:"text-mp-body-large",icon:24}};export const MPTextField=o.forwardRef(function({value:p,name:c,type:m="text",placeholder:u,autoComplete:f,label:x,onChange:b,onFormReset:y,onSubmit:g,errorMessage:h="",required:v=!1,fullWidth:w=!1,readOnly:C=!1,autoFocus:j=!1,size:k="md",disabled:z=!1,disableEnterKey:E=!1,rows:M,maxLength:N,startIcon:F,resizable:S=!1,id:q},D){const R=o.useRef(null),[I,O]=o.useState(!1),[B,K]=o.useState(!1),[L,P]=o.useState(p),U=o.useId(),$=q??`mp-text-field-${c??U}`,_=!!M,T=h.length>0,W=d[k],A=o.useCallback(e=>{R.current=e,"function"==typeof D?D(e):D&&(D.current=e)},[D]),G=e=>{e.preventDefault()};return o.useEffect(()=>{B||P(p)},[p,B]),o.useEffect(()=>{j&&!window.matchMedia("(max-width: 599.95px)").matches&&R.current?.focus()},[]),t(a.Root,{className:["mp-text-field group relative",w?"w-full":"inline-block","align-top"].join(" "),disabled:z,invalid:T,"data-mp-size":k,children:[t("div",{className:["relative flex w-full items-center gap-2",W.padding,_?"py-2":""].filter(Boolean).join(" "),children:[e(l,{label:x,required:v}),F?e("span",{className:"text-mp-on-surface-variant group-data-disabled:text-mp-on-surface/38 flex shrink-0 items-center",children:F}):null,e(a.Control,{render:_?e("textarea",{rows:M}):e("input",{}),id:$,name:c,type:_?void 0:I?"text":m,required:v,readOnly:C,disabled:z,autoComplete:f,placeholder:u,maxLength:N,value:B?L:p,ref:A,className:[`${W.text} text-mp-on-surface w-full min-w-0 flex-1`,"font-[family-name:var(--mp-sys-typescale-body-large-font)]","appearance-none border-0 bg-transparent px-0 outline-none","caret-mp-primary",W.control,_?"py-0":"",_&&S?"resize-y":"resize-none","group-data-disabled:text-mp-on-surface/38","placeholder:text-mp-on-surface-variant group-data-disabled:placeholder:text-mp-on-surface/38"].filter(Boolean).join(" "),onChange:e=>{y?.();const t=e.target.value;B&&P(t),b?.(t)},onCompositionStart:()=>{K(!0),P(p)},onCompositionUpdate:e=>{P(e.target.value)},onCompositionEnd:e=>{K(!1);const t=e.target.value;y?.(),b?.(t),P(t)},onKeyDown:e=>{"Enter"===e.key&&(g?.(),_&&!E||e.preventDefault())}}),"password"!==m||_?null:e("button",{type:"button","aria-label":I?"hide the password":"display the password",onClick:()=>O(e=>!e),onMouseDown:G,onMouseUp:G,disabled:z,className:["text-mp-on-surface-variant -mr-1 flex shrink-0 items-center justify-center","cursor-pointer appearance-none border-0 bg-transparent p-1 font-[inherit]","rounded-full outline-none","hover:text-mp-on-surface focus-visible:text-mp-primary","disabled:text-mp-on-surface/38 disabled:cursor-default"].join(" "),children:e(n,{icon:I?i:s,size:W.icon})})]}),x?e(r,{size:k,label:x,required:v,htmlFor:$}):null,T?e(a.Error,{match:!0,className:["mp-text-field__support text-mp-body-small text-mp-error mt-1 block",W.padding,"group-data-disabled:text-mp-on-surface/38"].join(" "),children:h}):null]})});
@@ -0,0 +1,88 @@
1
+ import * as React from 'react';
2
+ import { useRender } from '@base-ui/react/use-render';
3
+ import type { MPColor, MPSize } from '../../types';
4
+ /**
5
+ * When the line under a link is drawn.
6
+ *
7
+ * `always` is the default, and the reason is `color`: an `MPTextLink` takes no
8
+ * accent family unless one is asked for, so with the line off there would be
9
+ * nothing at all distinguishing a link from the sentence it sits in. That is
10
+ * also why this is not a boolean — "no underline" is a real choice for a link in
11
+ * a nav bar or a footer, where position already says what it is, and it should
12
+ * have to be spelled out rather than fallen into.
13
+ */
14
+ export type MPTextLinkUnderline = 'always' | 'hover' | 'none';
15
+ export interface MPTextLinkProps extends Omit<React.ComponentPropsWithoutRef<'a'>, 'color'> {
16
+ /** Where the link goes. */
17
+ href: string;
18
+ /**
19
+ * When the underline is drawn.
20
+ * @default 'always'
21
+ */
22
+ underline?: MPTextLinkUnderline;
23
+ /**
24
+ * Which accent family the link reads. Like `MPTypography` and unlike every
25
+ * control in the library this has **no default** — a link in a paragraph is
26
+ * usually the paragraph's own colour with a line under it, and a component
27
+ * that arrived pre-dyed is one a page has to undo.
28
+ */
29
+ color?: MPColor;
30
+ /**
31
+ * The type scale. Also no default: a link inside a sentence is the size of the
32
+ * sentence. Set it for a link that stands on its own.
33
+ */
34
+ size?: MPSize;
35
+ /**
36
+ * Opens the link in a new tab, with the `rel` that keeps the new page from
37
+ * reaching back into this one.
38
+ *
39
+ * A window changing under the reader is the one thing about a link that cannot
40
+ * be seen before it happens, so this also turns `icon` on by default and adds
41
+ * a line for a screen reader — see `newTabLabel`.
42
+ * @default false
43
+ */
44
+ newTab?: boolean;
45
+ /**
46
+ * The mark after the label. `true` draws the arrow leaving its box when
47
+ * `newTab` is on and the chain otherwise, `false` draws nothing, and a node of
48
+ * your own replaces the glyph.
49
+ *
50
+ * Left out, it follows `newTab`.
51
+ */
52
+ icon?: React.ReactNode | boolean;
53
+ /**
54
+ * What a screen reader hears after the label when `newTab` is on. A link
55
+ * without it says nothing of its own, so this changes nothing there.
56
+ * @default 'Opens in a new tab'
57
+ */
58
+ newTabLabel?: string;
59
+ /**
60
+ * Renders something other than an `<a>` — the `Link` a router brings, most of
61
+ * the time. `href` still goes through, so `render={<NextLink href="…" />}`
62
+ * needs it written once, on the `MPTextLink`.
63
+ */
64
+ render?: useRender.RenderProp;
65
+ /** The label. */
66
+ children?: React.ReactNode;
67
+ }
68
+ /**
69
+ * A link, in a sentence or on its own.
70
+ *
71
+ * Everything about it is deliberately smaller than a button. It has no surface,
72
+ * no height of its own and no colour unless asked — what it has is a line under
73
+ * it, which is the one mark a reader already knows means "this goes somewhere".
74
+ *
75
+ * The three things it does that a bare `<a>` does not: it draws that line on a
76
+ * schedule (`always`, or only under the pointer), it marks a link that opens a
77
+ * new tab both visibly and for a screen reader, and it takes `render`, so the
78
+ * `Link` a router brings can wear all of it.
79
+ *
80
+ * ## Why this is not a button with an `href`
81
+ *
82
+ * `MPButton` deliberately has no `href`, and this is the other half of that
83
+ * decision. A link is announced as a link, opens in a new tab on the middle
84
+ * mouse button, and shows its destination in the status bar; a button does none
85
+ * of those and should not pretend to. Two components, because they are two
86
+ * things.
87
+ */
88
+ export declare const MPTextLink: React.ForwardRefExoticComponent<MPTextLinkProps & React.RefAttributes<HTMLAnchorElement>>;
@@ -0,0 +1 @@
1
+ import{jsx as e,Fragment as n,jsxs as o}from"react/jsx-runtime";import*as r from"react";import{useRender as i}from"@base-ui/react/use-render";import{MPIcon as t}from"../icon/MPIcon";import{ExternalLinkIcon as l,LinkIcon as s}from"../../constants/icons";import{accentSlots as a}from"../../internal/accent";import{PROSE_TEXT as c}from"../../internal/scale";import{VISUALLY_HIDDEN as m}from"../../internal/visually-hidden";const p={always:"[&.mp-link]:underline",hover:"[&.mp-link]:no-underline [&.mp-link]:hover:underline",none:"[&.mp-link]:no-underline"},d=["[&.mp-link]:[text-underline-offset:0.2em]","[&.mp-link]:[text-decoration-thickness:0.08em]","[&.mp-link]:[text-decoration-color:color-mix(in_oklab,currentColor_45%,transparent)]","[&.mp-link]:hover:[text-decoration-color:currentColor]"].join(" ");export const MPTextLink=r.forwardRef(function({href:r,underline:u="always",color:f,size:h,newTab:k=!1,icon:x,newTabLabel:b="Opens in a new tab",render:v,className:y,style:w,children:j,...N},_){const g=x??k,T=!0===g?e(t,{icon:k?l:s,size:"0.95em"}):g,z=["mp-link cursor-pointer","transition-[color,text-decoration-color]","duration-(--mp-sys-motion-duration-short4)","outline-mp-secondary focus-visible:outline-2 focus-visible:outline-offset-2","focus-visible:outline-solid focus-visible:rounded-mp-xs outline-none",h?c[h]:"",p[u],d,f?"[&.mp-link]:text-(--_mp-accent)":"[&.mp-link]:text-inherit",y??""].filter(Boolean).join(" ");return i({render:v??e("a",{}),ref:_,props:{href:r,target:k?"_blank":void 0,rel:k?"noopener noreferrer":void 0,className:z,style:f?{...a(f),...w}:w,children:o(n,{children:[j,T?e("span",{className:"ms-[0.25em] inline-flex align-baseline",children:T}):null,k?o(n,{children:[" ",e("span",{className:m,children:b})]}):null]}),...N}})});
@@ -0,0 +1,2 @@
1
+ export { MPTextLink } from './MPTextLink';
2
+ export type { MPTextLinkProps, MPTextLinkUnderline } from './MPTextLink';
@@ -0,0 +1 @@
1
+ export{MPTextLink}from"./MPTextLink";
@@ -0,0 +1,108 @@
1
+ import * as React from 'react';
2
+ import { type MPPickerLabels } from '../../internal/Calendar';
3
+ import { type MPPickerShellProps } from '../../internal/Picker';
4
+ import { type MPTimeUnit } from '../../internal/date';
5
+ /**
6
+ * Which column of the clock a row belongs to.
7
+ *
8
+ * Re-exported so a caller writing a `shouldDisableTime` rule can name the
9
+ * argument it is handed.
10
+ */
11
+ export type { MPTimeUnit };
12
+ export interface MPTimePickerProps extends MPPickerShellProps {
13
+ /**
14
+ * The chosen time. A `Date`, so it carries a day as well — see
15
+ * `referenceDate`.
16
+ */
17
+ value?: Date | null;
18
+ defaultValue?: Date | null;
19
+ onValueChange?: (value: Date | null) => void;
20
+ open?: boolean;
21
+ defaultOpen?: boolean;
22
+ onOpenChange?: (open: boolean) => void;
23
+ /**
24
+ * The day a chosen time is written onto while there is no value yet.
25
+ * @default today
26
+ */
27
+ referenceDate?: Date;
28
+ /** The earliest time of day that may be chosen. Only the clock is read. */
29
+ minTime?: Date | null;
30
+ /** The latest time of day that may be chosen. */
31
+ maxTime?: Date | null;
32
+ /**
33
+ * Blocks individual rows. Called once per row per column with the instant that
34
+ * row would produce and the column it is in, so a rule may be as coarse as
35
+ * "no afternoons" or as fine as one minute.
36
+ */
37
+ shouldDisableTime?: (value: Date, unit: MPTimeUnit) => boolean;
38
+ /** A 12-hour dial with an AM/PM column. Defaults to whatever the locale does. */
39
+ hour12?: boolean;
40
+ /**
41
+ * Adds the seconds column.
42
+ * @default false
43
+ */
44
+ showSeconds?: boolean;
45
+ /**
46
+ * How far apart the rows of each column are.
47
+ * @default 1
48
+ */
49
+ hourStep?: number;
50
+ minuteStep?: number;
51
+ secondStep?: number;
52
+ /**
53
+ * A BCP 47 tag deciding whether the clock is 12- or 24-hour, what AM and PM
54
+ * are called, and how the trigger writes the time. Falls back to the nearest
55
+ * `MPLocaleProvider`, then to the platform's own.
56
+ */
57
+ locale?: string;
58
+ /**
59
+ * How the trigger writes the chosen time. Passed straight to `Intl`.
60
+ * @default { hour: 'numeric', minute: '2-digit' }, plus seconds when shown
61
+ */
62
+ format?: Intl.DateTimeFormatOptions;
63
+ placeholder?: React.ReactNode;
64
+ clearable?: boolean;
65
+ /**
66
+ * Offers the shortcut to the current time in the footer.
67
+ * @default true
68
+ */
69
+ showNowButton?: boolean;
70
+ /**
71
+ * Closes the popup as soon as any column is touched.
72
+ *
73
+ * `false` by default, and unlike `MPDatePicker`: a time is two answers, and
74
+ * closing after the first one would make choosing 9:30 a matter of opening the
75
+ * popup twice.
76
+ * @default false
77
+ */
78
+ closeOnSelect?: boolean;
79
+ labels?: Partial<MPPickerLabels>;
80
+ /** Identifies the field when a form is submitted, as `HH:MM` (`HH:MM:SS`). */
81
+ name?: string;
82
+ }
83
+ /**
84
+ * A time of day, chosen from columns.
85
+ *
86
+ * The bounds are checked at the granularity of the column being drawn, which is
87
+ * the detail that separates a working time picker from a frustrating one. With a
88
+ * `minTime` of 09:30, the hour `9` stays available — the hour *contains* allowed
89
+ * minutes — and it is the minute column that greys out `00` through `25`. The
90
+ * naive check compares the whole candidate instant, hides the 9 entirely, and
91
+ * makes half past nine unreachable.
92
+ *
93
+ * The value is a `Date` rather than a string or a number of minutes, because
94
+ * everything else in this library that carries a moment is one, and because a
95
+ * time on its own has nowhere to record which day it is on — which is what
96
+ * decides whether it crossed a daylight-saving boundary. `referenceDate` is the
97
+ * day a bare time is written onto.
98
+ *
99
+ * ## Columns, not MD3's dial
100
+ *
101
+ * This is the one place the library knowingly draws something the specification
102
+ * draws differently, and the reason is in `internal/Calendar.tsx` next to the
103
+ * grid itself: a dial is a pointer control, MD3 ships a second "time input" mode
104
+ * precisely because a dial cannot serve a keyboard, and a component with two
105
+ * implementations of one question has the accessible one hidden behind a toggle.
106
+ * Columns answer both readers at once, in the library's own shapes.
107
+ */
108
+ export declare const MPTimePicker: React.ForwardRefExoticComponent<MPTimePickerProps & React.RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1 @@
1
+ import{jsx as e,jsxs as o}from"react/jsx-runtime";import*as n from"react";import{MPButton as l}from"../button/MPButton";import{MPIcon as r}from"../icon/MPIcon";import{ClockIcon as t}from"../../constants/icons";import{MPTimeGrid as a}from"../../internal/Calendar";import{FOOTER_SIZE as i,MPPickerFooter as s,MPPickerShell as c}from"../../internal/Picker";import{useMPLocale as u,useMPMessages as m}from"../../internal/locale";import{CONTROL_ICON as d}from"../../internal/scale";import{displaySamples as p,formatDate as h,isHour12 as f,isValidDate as g,secondsOfDay as S,timeUnitSpan as b,toISOTime as v,withPlaceholder as C,withTime as x}from"../../internal/date";export const MPTimePicker=n.forwardRef(function({value:k,defaultValue:w,onValueChange:z,open:D,defaultOpen:O,onOpenChange:y,referenceDate:M,minTime:P,maxTime:T,shouldDisableTime:j,hour12:I,showSeconds:V=!1,hourStep:B=1,minuteStep:N=1,secondStep:R=1,locale:F,format:H,placeholder:q,clearable:A=!1,showNowButton:E=!0,closeOnSelect:G=!1,labels:J,name:K,size:L="md",color:Q="primary",readOnly:U=!1,disabled:W=!1,startIcon:X,...Y},Z){const $=u(F),_=m("picker",$,J),ee=I??f($),[oe,ne]=n.useState(w??null),le=void 0!==k?k:oe,[re,te]=n.useState(O??!1),ae=D??re,[ie]=n.useState(()=>M??new Date),se=e=>{e&&(U||W)||(void 0===D&&te(e),y?.(e))},ce=e=>{void 0===k&&ne(e),z?.(e)},ue=n.useCallback((e,o)=>{const[n,l]=b(o,e);return!!(g(P)&&l<S(P))||(!!(g(T)&&n>S(T))||(j?.(e,o)??!1))},[P,T,j]),me=H??{hour:"numeric",minute:"2-digit",hour12:ee,...V?{second:"2-digit"}:{}},de=new Date,pe=x(M??ie,{hours:de.getHours(),minutes:de.getMinutes(),seconds:V?de.getSeconds():0}),he=E||A||!G,fe=n.useMemo(()=>C(p($,me),q),[$,me,q]);return e(c,{...Y,slug:"time-picker",size:L,color:Q,readOnly:U,disabled:W,name:K,triggerRef:Z,startIcon:X??e(r,{icon:t,size:d[L]}),display:g(le)?h(le,$,me):q??"",samples:fe,empty:!g(le),clearable:A,onClear:()=>ce(null),open:ae,onOpenChange:se,labels:_,hiddenValues:K?[{name:K,value:g(le)?v(le,V):""}]:void 0,children:o("div",{className:"flex flex-col "+(he?"gap-1.5":""),children:[e(a,{size:L,locale:$,value:g(le)?le:null,referenceDate:M??ie,onChange:e=>{ce(e),G&&se(!1)},hour12:ee,showSeconds:V,hourStep:B,minuteStep:N,secondStep:R,shouldDisableTime:ue,labels:_,autoFocus:!0}),he?o(s,{children:[A?e(l,{variant:"text",size:i[L],color:Q,onClick:()=>{ce(null),se(!1)},children:_.clear}):null,E?e(l,{variant:"text",size:i[L],color:Q,disabled:ue(pe,"second"),onClick:()=>{ce(pe),se(!1)},children:_.now}):null,G?null:e(l,{variant:"filled",size:i[L],color:Q,onClick:()=>se(!1),children:_.done})]}):null]})})});
@@ -0,0 +1,2 @@
1
+ export { MPTimePicker } from './MPTimePicker';
2
+ export type { MPTimePickerProps, MPTimeUnit } from './MPTimePicker';
@@ -0,0 +1 @@
1
+ export{MPTimePicker}from"./MPTimePicker";
@@ -0,0 +1,96 @@
1
+ import * as React from 'react';
2
+ import { useRender } from '@base-ui/react/use-render';
3
+ import type { MPColor, MPOrientation, MPSize } from '../../types';
4
+ /**
5
+ * How far along one item is.
6
+ *
7
+ * Three states rather than two, because "the one you are on" is not the same
8
+ * claim as "done", and a sequence that cannot say which step is current is a
9
+ * list. Each gets its own axis — a filled bullet, a filled bullet with a halo
10
+ * around it, an empty one — rather than three shades of the same thing.
11
+ */
12
+ export type MPTimelineStatus = 'complete' | 'current' | 'upcoming';
13
+ /** How the line between two items is drawn. `none` leaves the gap open. */
14
+ export type MPTimelineConnector = 'solid' | 'dashed' | 'dotted' | 'none';
15
+ export interface MPTimelineProps extends Omit<React.ComponentPropsWithoutRef<'ol'>, 'color'> {
16
+ /**
17
+ * How far the sequence has got: the index of the item being worked on now.
18
+ * Everything before it is complete, everything after it is still to come.
19
+ *
20
+ * An index rather than a value, because a timeline has no selection — nothing
21
+ * here is chosen, and the only question is how far down the list reality has
22
+ * reached. Omit it and every item is `upcoming` unless it says otherwise; pass
23
+ * the item count to mark the whole sequence done.
24
+ */
25
+ active?: number;
26
+ /** @default 'md' */
27
+ size?: MPSize;
28
+ /** @default 'primary' */
29
+ color?: MPColor;
30
+ /**
31
+ * Which way the sequence runs. `vertical` is the default and the one that
32
+ * takes an arbitrary number of steps with an arbitrary amount to say about
33
+ * each; `horizontal` is the stepper across the top of a checkout, and it is
34
+ * only honest while every label is short.
35
+ * @default 'vertical'
36
+ */
37
+ orientation?: MPOrientation;
38
+ /** Renders something other than an `<ol>` — Base UI's own escape hatch. */
39
+ render?: useRender.RenderProp;
40
+ children?: React.ReactNode;
41
+ }
42
+ export interface MPTimelineItemProps extends Omit<React.ComponentPropsWithoutRef<'li'>, 'color' | 'title'> {
43
+ /** The heading of this step. */
44
+ title?: React.ReactNode;
45
+ /**
46
+ * When it happened — a date, a duration, a name. Set beside the title on a
47
+ * wide item and under it on a narrow one.
48
+ */
49
+ meta?: React.ReactNode;
50
+ /**
51
+ * What goes inside the bullet: a number, an icon, an avatar. Omit it and the
52
+ * bullet is a plain disc, which is what a step with nothing to say about
53
+ * itself should be.
54
+ */
55
+ bullet?: React.ReactNode;
56
+ /**
57
+ * Overrides what the timeline's `active` would have computed for this item — a
58
+ * step that failed and stopped the sequence, a step that was skipped.
59
+ */
60
+ status?: MPTimelineStatus;
61
+ /** Overrides the timeline's accent family for this item alone. */
62
+ color?: MPColor;
63
+ /**
64
+ * How the line to the next item is drawn.
65
+ * @default 'solid'
66
+ */
67
+ connector?: MPTimelineConnector;
68
+ /** The body of the step. */
69
+ children?: React.ReactNode;
70
+ }
71
+ /**
72
+ * One step.
73
+ *
74
+ * Its index is not a prop and cannot be: an item that had to be told where it
75
+ * was in the list would be an item every caller could put in the wrong place,
76
+ * and `active={2}` would stop meaning anything. The timeline numbers its
77
+ * children as it walks them and hands each one its index through a context.
78
+ */
79
+ export declare const MPTimelineItem: React.ForwardRefExoticComponent<MPTimelineItemProps & React.RefAttributes<HTMLLIElement>>;
80
+ /**
81
+ * A sequence of steps, in the order they happen in.
82
+ *
83
+ * There is no Base UI primitive under this and there should not be: a timeline
84
+ * has no selection, no roving focus and no keyboard contract — it is a list, and
85
+ * reaching for a composite primitive to draw one would hand every consumer's
86
+ * record of events the semantics of a widget.
87
+ *
88
+ * It is an `<ol>` for the reason it exists at all: the order *is* the content. A
89
+ * screen reader announcing "list of 5 items" over an unordered list would be
90
+ * describing something else.
91
+ *
92
+ * The children are numbered here rather than by a prop on each item, so `active`
93
+ * has something to count against and inserting a step in the middle does not
94
+ * mean renumbering the ones after it.
95
+ */
96
+ export declare const MPTimeline: React.ForwardRefExoticComponent<MPTimelineProps & React.RefAttributes<HTMLOListElement>>;
@@ -0,0 +1 @@
1
+ import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as r from"react";import{useRender as n}from"@base-ui/react/use-render";import{accentSlots as l}from"../../internal/accent";import{hasContent as a,META_TEXT as o,PROSE_TEXT as i,SHEET_TITLE as s}from"../../internal/scale";const c=r.createContext(null),m=r.createContext({index:0,last:!1}),p={xs:"0.875rem",sm:"1rem",md:"1.25rem",lg:"1.5rem",xl:"1.875rem"},d={xs:"gap-2",sm:"gap-2.5",md:"gap-3",lg:"gap-3.5",xl:"gap-4"},u={xs:"pb-5",sm:"pb-6",md:"pb-7",lg:"pb-8",xl:"pb-10"},x={xs:"pe-5",sm:"pe-6",md:"pe-7",lg:"pe-8",xl:"pe-10"},f={solid:"border-solid",dashed:"border-dashed",dotted:"border-dotted",none:""},b={complete:"bg-(--_mp-accent) text-(--_mp-on-accent)",current:"bg-(--_mp-accent) text-(--_mp-on-accent) shadow-[0_0_0_0.25rem_var(--_mp-accent-container)]",upcoming:"border-mp-outline text-mp-on-surface-variant border-2 bg-transparent"},v={complete:"border-(--_mp-accent)",current:"border-mp-outline-variant",upcoming:"border-mp-outline-variant"},h={complete:"text-mp-on-surface",current:"text-(--_mp-accent)",upcoming:"text-mp-on-surface-variant"};export const MPTimelineItem=r.forwardRef(function({title:n,meta:g,bullet:_,status:N,color:y,connector:z="solid",className:j,style:w,children:$,...C},P){const B=r.useContext(c),{index:M,last:k}=r.useContext(m),R=B?.size??"md",T=B?.orientation??"vertical",A=y??B?.color??"primary",I=B?.active??null,q=N??(null===I?"upcoming":M<I?"complete":M===I?"current":"upcoming"),D="horizontal"===T,E="none"!==z&&!k,F=e("span",{"aria-hidden":"true",className:["rounded-mp-full relative z-10 flex shrink-0 items-center justify-center","size-(--_mp-bullet) text-[calc(var(--_mp-bullet)*0.5)] leading-none font-medium","tabular-nums [&>svg]:size-[0.6em]",b[q],"transition-[background-color,border-color,box-shadow,color]","duration-(--mp-sys-motion-duration-short4)"].join(" "),children:_}),G=E?e("span",{"aria-hidden":"true",className:["pointer-events-none absolute",D?"start-(--_mp-bullet) top-[calc(var(--_mp-bullet)/2_-_1px)] end-0 border-t-2":"top-(--_mp-bullet) start-[calc(var(--_mp-bullet)/2_-_1px)] bottom-0 border-s-2",f[z],v[q]].filter(Boolean).join(" ")}):null,H=t("div",{className:"flex min-w-0 flex-col gap-0.5 "+(D?"mt-2":""),children:[a(n)||a(g)?t("div",{className:"flex flex-wrap items-baseline gap-x-2",children:[a(n)?e("span",{className:`${s[R]} ${h[q]}`,children:n}):null,a(g)?e("span",{className:`text-mp-on-surface-variant ${o}`,children:g}):null]}):null,a($)?e("div",{className:`text-mp-on-surface-variant ${i[R]}`,children:$}):null]});return t("li",{ref:P,"aria-current":"current"===q?"step":void 0,"data-status":q,className:["relative",D?`flex min-w-0 flex-1 flex-col ${k?"":x[R]}`:`flex ${d[R]} ${k?"":u[R]}`,j??""].filter(Boolean).join(" "),style:{"--_mp-bullet":p[R],...l(A),...w},...C,children:[G,F,H]})});export const MPTimeline=r.forwardRef(function({active:t,size:l="md",color:a="primary",orientation:o="vertical",render:i,className:s,style:p,children:d,...u},x){const f=r.Children.toArray(d),b=f.length,v=r.useMemo(()=>({size:l,orientation:o,color:a,active:t??null}),[l,o,a,t]),h=n({render:i??e("ol",{}),ref:x,props:{role:"list","data-mp-size":l,className:["mp-timeline flex","horizontal"===o?"flex-row":"flex-col",s??""].filter(Boolean).join(" "),style:p,children:f.map((t,r)=>e(m.Provider,{value:{index:r,last:r===b-1},children:t},r)),...u}});return e(c.Provider,{value:v,children:h})});