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