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.
- package/README.md +39 -28
- package/dist/components/accordion/MPAccordion.d.ts +115 -0
- package/dist/components/accordion/MPAccordion.js +1 -0
- package/dist/components/accordion/index.d.ts +2 -0
- package/dist/components/accordion/index.js +1 -0
- package/dist/components/alert/MPAlert.d.ts +91 -0
- package/dist/components/alert/MPAlert.js +1 -0
- package/dist/components/alert/index.d.ts +2 -0
- package/dist/components/alert/index.js +1 -0
- package/dist/components/aspect-ratio/MPAspectRatio.d.ts +69 -0
- package/dist/components/aspect-ratio/MPAspectRatio.js +1 -0
- package/dist/components/aspect-ratio/index.d.ts +2 -0
- package/dist/components/aspect-ratio/index.js +1 -0
- package/dist/components/avatar/MPAvatar.d.ts +97 -0
- package/dist/components/avatar/MPAvatar.js +1 -0
- package/dist/components/avatar/index.d.ts +2 -0
- package/dist/components/avatar/index.js +1 -0
- package/dist/components/badge/MPBadge.d.ts +104 -0
- package/dist/components/badge/MPBadge.js +1 -0
- package/dist/components/badge/index.d.ts +2 -0
- package/dist/components/badge/index.js +1 -0
- package/dist/components/blockquote/MPBlockquote.d.ts +73 -0
- package/dist/components/blockquote/MPBlockquote.js +1 -0
- package/dist/components/blockquote/index.d.ts +2 -0
- package/dist/components/blockquote/index.js +1 -0
- package/dist/components/box/MPBox.d.ts +78 -0
- package/dist/components/box/MPBox.js +1 -0
- package/dist/components/box/index.d.ts +2 -0
- package/dist/components/box/index.js +1 -0
- package/dist/components/breadcrumb/MPBreadcrumb.d.ts +105 -0
- package/dist/components/breadcrumb/MPBreadcrumb.js +1 -0
- package/dist/components/breadcrumb/index.d.ts +2 -0
- package/dist/components/breadcrumb/index.js +1 -0
- package/dist/components/button/MPButton.d.ts +70 -0
- package/dist/components/button/MPButton.js +1 -0
- package/dist/components/button/index.d.ts +2 -0
- package/dist/components/button/index.js +1 -0
- package/dist/components/button-group/MPButtonGroup.d.ts +31 -0
- package/dist/components/button-group/MPButtonGroup.js +1 -0
- package/dist/components/button-group/index.d.ts +2 -0
- package/dist/components/button-group/index.js +1 -0
- package/dist/components/card/MPCard.d.ts +73 -0
- package/dist/components/card/MPCard.js +1 -0
- package/dist/components/card/index.d.ts +2 -0
- package/dist/components/card/index.js +1 -0
- package/dist/components/carousel/MPCarousel.d.ts +116 -0
- package/dist/components/carousel/MPCarousel.js +1 -0
- package/dist/components/carousel/index.d.ts +2 -0
- package/dist/components/carousel/index.js +1 -0
- package/dist/components/chat-bubble/MPChatBubble.d.ts +132 -0
- package/dist/components/chat-bubble/MPChatBubble.js +1 -0
- package/dist/components/chat-bubble/index.d.ts +2 -0
- package/dist/components/chat-bubble/index.js +1 -0
- package/dist/components/checkbox/MPCheckbox.d.ts +76 -0
- package/dist/components/checkbox/MPCheckbox.js +1 -0
- package/dist/components/checkbox/index.d.ts +2 -0
- package/dist/components/checkbox/index.js +1 -0
- package/dist/components/chip/MPChip.d.ts +64 -0
- package/dist/components/chip/MPChip.js +1 -0
- package/dist/components/chip/index.d.ts +2 -0
- package/dist/components/chip/index.js +1 -0
- package/dist/components/collapsible/MPCollapsible.d.ts +97 -0
- package/dist/components/collapsible/MPCollapsible.js +1 -0
- package/dist/components/collapsible/index.d.ts +2 -0
- package/dist/components/collapsible/index.js +1 -0
- package/dist/components/color-picker/MPColorPicker.d.ts +113 -0
- package/dist/components/color-picker/MPColorPicker.js +1 -0
- package/dist/components/color-picker/index.d.ts +2 -0
- package/dist/components/color-picker/index.js +1 -0
- package/dist/components/combobox/MPCombobox.d.ts +147 -0
- package/dist/components/combobox/MPCombobox.js +1 -0
- package/dist/components/combobox/index.d.ts +2 -0
- package/dist/components/combobox/index.js +1 -0
- package/dist/components/date-picker/MPDatePicker.d.ts +95 -0
- package/dist/components/date-picker/MPDatePicker.js +1 -0
- package/dist/components/date-picker/index.d.ts +2 -0
- package/dist/components/date-picker/index.js +1 -0
- package/dist/components/date-range-picker/MPDateRangePicker.d.ts +98 -0
- package/dist/components/date-range-picker/MPDateRangePicker.js +1 -0
- package/dist/components/date-range-picker/index.d.ts +2 -0
- package/dist/components/date-range-picker/index.js +1 -0
- package/dist/components/date-time-picker/MPDateTimePicker.d.ts +78 -0
- package/dist/components/date-time-picker/MPDateTimePicker.js +1 -0
- package/dist/components/date-time-picker/index.d.ts +2 -0
- package/dist/components/date-time-picker/index.js +1 -0
- package/dist/components/dialog/MPDialog.d.ts +145 -0
- package/dist/components/dialog/MPDialog.js +1 -0
- package/dist/components/dialog/index.d.ts +2 -0
- package/dist/components/dialog/index.js +1 -0
- package/dist/components/divider/MPDivider.d.ts +80 -0
- package/dist/components/divider/MPDivider.js +1 -0
- package/dist/components/divider/index.d.ts +2 -0
- package/dist/components/divider/index.js +1 -0
- package/dist/components/drawer/MPDrawer.d.ts +163 -0
- package/dist/components/drawer/MPDrawer.js +1 -0
- package/dist/components/drawer/index.d.ts +2 -0
- package/dist/components/drawer/index.js +1 -0
- package/dist/components/empty/MPEmpty.d.ts +64 -0
- package/dist/components/empty/MPEmpty.js +1 -0
- package/dist/components/empty/index.d.ts +2 -0
- package/dist/components/empty/index.js +1 -0
- package/dist/components/file-picker/MPFilePicker.d.ts +103 -0
- package/dist/components/file-picker/MPFilePicker.js +1 -0
- package/dist/components/file-picker/index.d.ts +2 -0
- package/dist/components/file-picker/index.js +1 -0
- package/dist/components/highlight/MPHighlight.d.ts +95 -0
- package/dist/components/highlight/MPHighlight.js +1 -0
- package/dist/components/highlight/index.d.ts +2 -0
- package/dist/components/highlight/index.js +1 -0
- package/dist/components/icon-button/MPIconButton.d.ts +59 -0
- package/dist/components/icon-button/MPIconButton.js +1 -0
- package/dist/components/icon-button/index.d.ts +2 -0
- package/dist/components/icon-button/index.js +1 -0
- package/dist/components/list/MPList.d.ts +96 -0
- package/dist/components/list/MPList.js +1 -0
- package/dist/components/list/index.d.ts +2 -0
- package/dist/components/list/index.js +1 -0
- package/dist/components/locale/MPLocaleProvider.d.ts +63 -0
- package/dist/components/locale/MPLocaleProvider.js +1 -0
- package/dist/components/locale/index.d.ts +2 -0
- package/dist/components/locale/index.js +1 -0
- package/dist/components/menu/MPMenu.d.ts +223 -0
- package/dist/components/menu/MPMenu.js +1 -0
- package/dist/components/menu/index.d.ts +2 -0
- package/dist/components/menu/index.js +1 -0
- package/dist/components/number-field/MPNumberField.d.ts +99 -0
- package/dist/components/number-field/MPNumberField.js +1 -0
- package/dist/components/number-field/index.d.ts +2 -0
- package/dist/components/number-field/index.js +1 -0
- package/dist/components/otp-field/MPOtpField.d.ts +89 -0
- package/dist/components/otp-field/MPOtpField.js +1 -0
- package/dist/components/otp-field/index.d.ts +2 -0
- package/dist/components/otp-field/index.js +1 -0
- package/dist/components/overlay/MPOverlay.d.ts +96 -0
- package/dist/components/overlay/MPOverlay.js +1 -0
- package/dist/components/overlay/index.d.ts +2 -0
- package/dist/components/overlay/index.js +1 -0
- package/dist/components/panes/MPPanes.d.ts +100 -0
- package/dist/components/panes/MPPanes.js +1 -0
- package/dist/components/panes/index.d.ts +2 -0
- package/dist/components/panes/index.js +1 -0
- package/dist/components/pill/MPPill.d.ts +117 -0
- package/dist/components/pill/MPPill.js +1 -0
- package/dist/components/pill/index.d.ts +2 -0
- package/dist/components/pill/index.js +1 -0
- package/dist/components/popover/MPPopover.d.ts +138 -0
- package/dist/components/popover/MPPopover.js +1 -0
- package/dist/components/popover/index.d.ts +2 -0
- package/dist/components/popover/index.js +1 -0
- package/dist/components/progress-box/MPProgressBox.d.ts +40 -0
- package/dist/components/progress-box/MPProgressBox.js +1 -0
- package/dist/components/progress-box/index.d.ts +2 -0
- package/dist/components/progress-box/index.js +1 -0
- package/dist/components/progress-circular/MPProgressCircular.d.ts +32 -0
- package/dist/components/progress-circular/MPProgressCircular.js +1 -0
- package/dist/components/progress-circular/index.d.ts +2 -0
- package/dist/components/progress-circular/index.js +1 -0
- package/dist/components/progress-linear/MPProgressLinear.d.ts +32 -0
- package/dist/components/progress-linear/MPProgressLinear.js +1 -0
- package/dist/components/progress-linear/index.d.ts +2 -0
- package/dist/components/progress-linear/index.js +1 -0
- package/dist/components/radio-group/MPRadioGroup.d.ts +81 -0
- package/dist/components/radio-group/MPRadioGroup.js +1 -0
- package/dist/components/radio-group/index.d.ts +2 -0
- package/dist/components/radio-group/index.js +1 -0
- package/dist/components/segmented-button/MPSegmentedButton.d.ts +75 -0
- package/dist/components/segmented-button/MPSegmentedButton.js +1 -0
- package/dist/components/segmented-button/index.d.ts +2 -0
- package/dist/components/segmented-button/index.js +1 -0
- package/dist/components/select/MPSelect.d.ts +86 -0
- package/dist/components/select/MPSelect.js +1 -0
- package/dist/components/select/index.d.ts +2 -0
- package/dist/components/select/index.js +1 -0
- package/dist/components/shortcut/MPShortcut.d.ts +67 -0
- package/dist/components/shortcut/MPShortcut.js +1 -0
- package/dist/components/shortcut/index.d.ts +2 -0
- package/dist/components/shortcut/index.js +1 -0
- package/dist/components/skeleton/MPSkeleton.d.ts +76 -0
- package/dist/components/skeleton/MPSkeleton.js +1 -0
- package/dist/components/skeleton/index.d.ts +2 -0
- package/dist/components/skeleton/index.js +1 -0
- package/dist/components/slider/MPSlider.d.ts +77 -0
- package/dist/components/slider/MPSlider.js +1 -0
- package/dist/components/slider/index.d.ts +2 -0
- package/dist/components/slider/index.js +1 -0
- package/dist/components/snackbar/MPSnackbar.d.ts +170 -0
- package/dist/components/snackbar/MPSnackbar.js +1 -0
- package/dist/components/snackbar/index.d.ts +2 -0
- package/dist/components/snackbar/index.js +1 -0
- package/dist/components/spoiler/MPSpoiler.d.ts +106 -0
- package/dist/components/spoiler/MPSpoiler.js +1 -0
- package/dist/components/spoiler/index.d.ts +2 -0
- package/dist/components/spoiler/index.js +1 -0
- package/dist/components/switch/MPSwitch.d.ts +75 -0
- package/dist/components/switch/MPSwitch.js +1 -0
- package/dist/components/switch/index.d.ts +2 -0
- package/dist/components/switch/index.js +1 -0
- package/dist/components/table/MPTable.d.ts +107 -0
- package/dist/components/table/MPTable.js +1 -0
- package/dist/components/table/index.d.ts +2 -0
- package/dist/components/table/index.js +1 -0
- package/dist/components/text-field/MPTextField.d.ts +17 -18
- package/dist/components/text-field/MPTextField.js +1 -1
- package/dist/components/text-link/MPTextLink.d.ts +88 -0
- package/dist/components/text-link/MPTextLink.js +1 -0
- package/dist/components/text-link/index.d.ts +2 -0
- package/dist/components/text-link/index.js +1 -0
- package/dist/components/time-picker/MPTimePicker.d.ts +108 -0
- package/dist/components/time-picker/MPTimePicker.js +1 -0
- package/dist/components/time-picker/index.d.ts +2 -0
- package/dist/components/time-picker/index.js +1 -0
- package/dist/components/timeline/MPTimeline.d.ts +96 -0
- package/dist/components/timeline/MPTimeline.js +1 -0
- package/dist/components/timeline/index.d.ts +2 -0
- package/dist/components/timeline/index.js +1 -0
- package/dist/components/tooltip/MPTooltip.d.ts +117 -0
- package/dist/components/tooltip/MPTooltip.js +1 -0
- package/dist/components/tooltip/index.d.ts +2 -0
- package/dist/components/tooltip/index.js +1 -0
- package/dist/components/typography/MPTypography.d.ts +94 -0
- package/dist/components/typography/MPTypography.js +1 -0
- package/dist/components/typography/index.d.ts +2 -0
- package/dist/components/typography/index.js +1 -0
- package/dist/constants/icons.d.ts +36 -0
- package/dist/constants/icons.js +1 -1
- package/dist/index.d.ts +55 -0
- package/dist/index.js +1 -1
- package/dist/internal/Calendar.d.ts +118 -0
- package/dist/internal/Calendar.js +1 -0
- package/dist/internal/FieldOutline.d.ts +38 -0
- package/dist/internal/FieldOutline.js +1 -0
- package/dist/internal/Picker.d.ts +110 -0
- package/dist/internal/Picker.js +1 -0
- package/dist/internal/StateLayer.d.ts +45 -0
- package/dist/internal/StateLayer.js +1 -0
- package/dist/internal/SupportingText.d.ts +23 -0
- package/dist/internal/SupportingText.js +1 -0
- package/dist/internal/WidthSizer.d.ts +31 -0
- package/dist/internal/WidthSizer.js +1 -0
- package/dist/internal/accent.d.ts +39 -0
- package/dist/internal/accent.js +1 -0
- package/dist/internal/button-group.d.ts +21 -0
- package/dist/internal/button-group.js +1 -0
- package/dist/internal/color.d.ts +125 -0
- package/dist/internal/color.js +1 -0
- package/dist/internal/date.d.ts +179 -0
- package/dist/internal/date.js +1 -0
- package/dist/internal/i18n.d.ts +131 -0
- package/dist/internal/i18n.js +1 -0
- package/dist/internal/locale.d.ts +43 -0
- package/dist/internal/locale.js +1 -0
- package/dist/internal/menu.d.ts +23 -0
- package/dist/internal/menu.js +1 -0
- package/dist/internal/progress.d.ts +126 -0
- package/dist/internal/progress.js +1 -0
- package/dist/internal/scale.d.ts +127 -0
- package/dist/internal/scale.js +1 -0
- package/dist/internal/surface.d.ts +76 -0
- package/dist/internal/surface.js +1 -0
- package/dist/internal/visually-hidden.d.ts +23 -0
- package/dist/internal/visually-hidden.js +1 -0
- package/dist/styles.css +1 -1
- package/dist/tailwind.css +1285 -20
- package/dist/types.d.ts +107 -16
- package/package.json +16 -21
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { MPColor, MPCorner, MPSize, MPVariant } from '../../types';
|
|
3
|
+
export interface MPBadgeProps extends Omit<React.ComponentPropsWithoutRef<'span'>, 'color' | 'content'> {
|
|
4
|
+
/**
|
|
5
|
+
* What the badge says — usually a count, sometimes a word.
|
|
6
|
+
*
|
|
7
|
+
* Omit it and the badge draws a dot instead, which is the honest thing when
|
|
8
|
+
* there is something to report but nothing to count. MD3 calls those two the
|
|
9
|
+
* large and the small badge, and they are the only two it has.
|
|
10
|
+
*/
|
|
11
|
+
content?: React.ReactNode;
|
|
12
|
+
/**
|
|
13
|
+
* Caps a numeric `content` and adds a `+`. Only applies when the content is
|
|
14
|
+
* actually a number: a badge cannot know how to truncate a word.
|
|
15
|
+
* @default 99
|
|
16
|
+
*/
|
|
17
|
+
max?: number;
|
|
18
|
+
/**
|
|
19
|
+
* Draws the marker as a dot even when there is content, keeping the content
|
|
20
|
+
* for screen readers only. For the corner that has to stay quiet.
|
|
21
|
+
* @default false
|
|
22
|
+
*/
|
|
23
|
+
dot?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Whether a `content` of `0` is shown. Off by default — zero unread messages
|
|
26
|
+
* is not news, and a badge that never goes away stops meaning anything.
|
|
27
|
+
* @default false
|
|
28
|
+
*/
|
|
29
|
+
showZero?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Hides the marker without unmounting the anchor. The badge keeps its place in
|
|
32
|
+
* the DOM, so showing it again does not relayout what it sits on.
|
|
33
|
+
* @default false
|
|
34
|
+
*/
|
|
35
|
+
invisible?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Which corner of the anchor it sits on.
|
|
38
|
+
* @default 'top-end'
|
|
39
|
+
*/
|
|
40
|
+
placement?: MPCorner;
|
|
41
|
+
/**
|
|
42
|
+
* The shape of the thing underneath, which is what decides how far the marker
|
|
43
|
+
* tucks in: a circle's corner is further from its centre than a square's, so a
|
|
44
|
+
* badge that looks right on an avatar hangs off an icon button.
|
|
45
|
+
* @default 'square'
|
|
46
|
+
*/
|
|
47
|
+
overlap?: 'square' | 'circle';
|
|
48
|
+
/**
|
|
49
|
+
* How much surface the marker paints.
|
|
50
|
+
* @default 'filled'
|
|
51
|
+
*/
|
|
52
|
+
variant?: MPVariant;
|
|
53
|
+
/**
|
|
54
|
+
* @default 'md'
|
|
55
|
+
*/
|
|
56
|
+
size?: MPSize;
|
|
57
|
+
/**
|
|
58
|
+
* Which accent family the marker reads.
|
|
59
|
+
*
|
|
60
|
+
* **`error`, not `primary`**, and it is the one component in the library that
|
|
61
|
+
* defaults there. MD3 gives the badge exactly one colour pair — `error` under
|
|
62
|
+
* `on-error` — because a badge exists to be noticed, and the error palette is
|
|
63
|
+
* the one palette in the system that is guaranteed to be loud whatever the
|
|
64
|
+
* source colour is. A count in the brand colour on a brand-coloured app bar is
|
|
65
|
+
* a count nobody sees.
|
|
66
|
+
* @default 'error'
|
|
67
|
+
*/
|
|
68
|
+
color?: MPColor;
|
|
69
|
+
/**
|
|
70
|
+
* What a screen reader hears instead of the raw content. `content={3}` on a
|
|
71
|
+
* bell is "3" to a reader and means nothing; `label="3 unread notifications"`
|
|
72
|
+
* is the sentence.
|
|
73
|
+
*/
|
|
74
|
+
label?: string;
|
|
75
|
+
/**
|
|
76
|
+
* What the badge is pinned to. Without it the badge is a standalone marker
|
|
77
|
+
* that lays out inline, which is what a status pill in a table cell is.
|
|
78
|
+
*/
|
|
79
|
+
children?: React.ReactNode;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* A small mark in the corner of something else: unread mail on an inbox icon, a
|
|
83
|
+
* status dot on an avatar, a count on a tab.
|
|
84
|
+
*
|
|
85
|
+
* The shell is a `<span>` that wraps the anchor and does nothing but establish a
|
|
86
|
+
* positioning context — no width, no padding, `align-middle` — so a badged icon
|
|
87
|
+
* button still measures and lines up exactly like a bare one. With no children
|
|
88
|
+
* the marker lays out inline instead, which is what a standalone status pill is.
|
|
89
|
+
*
|
|
90
|
+
* There is no Base UI primitive under this, and there should not be: a badge has
|
|
91
|
+
* no interaction, no state and no keyboard contract. It is a mark. Wiring it to
|
|
92
|
+
* a widget primitive would hand every decorative dot a role it cannot honour.
|
|
93
|
+
*
|
|
94
|
+
* What it does owe a screen reader is a sentence rather than a number, which is
|
|
95
|
+
* what `label` is for — `content={3}` beside a bell reads out as "3".
|
|
96
|
+
*
|
|
97
|
+
* ## The one place the library draws a pill that is not a button
|
|
98
|
+
*
|
|
99
|
+
* `corner-full`, at every size. MD3 shapes a badge as a full circle or a stadium
|
|
100
|
+
* because it is a *mark laid on* a surface rather than a surface of its own, and
|
|
101
|
+
* a mark has no edge to cut. It is also the only component that overlaps its
|
|
102
|
+
* neighbour, for the same reason.
|
|
103
|
+
*/
|
|
104
|
+
export declare const MPBadge: React.ForwardRefExoticComponent<MPBadgeProps & React.RefAttributes<HTMLSpanElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e,Fragment as t,jsxs as m}from"react/jsx-runtime";import*as n from"react";import{accentSlots as a}from"../../internal/accent";import{hasContent as l}from"../../internal/scale";import{VISUALLY_HIDDEN as s}from"../../internal/visually-hidden";const i={xs:"h-3 min-w-3",sm:"h-3.5 min-w-3.5",md:"h-4 min-w-4",lg:"h-5 min-w-5",xl:"h-6 min-w-6"},o={xs:"size-1",sm:"size-1.5",md:"size-1.5",lg:"size-2",xl:"size-2.5"},r={xs:"text-mp-label-small",sm:"text-mp-label-small",md:"text-mp-label-small",lg:"text-mp-label-medium",xl:"text-mp-label-medium"},d={xs:"px-1",sm:"px-1",md:"px-1.5",lg:"px-1.5",xl:"px-2"},p={xs:{badge:"-mt-1.5 -mb-1.5 -ms-1.5 -me-1.5",dot:"-mt-0.5 -mb-0.5 -ms-0.5 -me-0.5"},sm:{badge:"-mt-1.5 -mb-1.5 -ms-1.5 -me-1.5",dot:"-mt-0.5 -mb-0.5 -ms-0.5 -me-0.5"},md:{badge:"-mt-2 -mb-2 -ms-2 -me-2",dot:"-mt-1 -mb-1 -ms-1 -me-1"},lg:{badge:"-mt-2.5 -mb-2.5 -ms-2.5 -me-2.5",dot:"-mt-1 -mb-1 -ms-1 -me-1"},xl:{badge:"-mt-3 -mb-3 -ms-3 -me-3",dot:"-mt-1.5 -mb-1.5 -ms-1.5 -me-1.5"}},c={"top-start":"top-0 start-0","top-end":"top-0 end-0","bottom-start":"bottom-0 start-0","bottom-end":"bottom-0 end-0"},b={"top-start":"mt-[7%] ms-[7%]","top-end":"mt-[7%] me-[7%]","bottom-start":"mb-[7%] ms-[7%]","bottom-end":"mb-[7%] me-[7%]"},x={filled:"bg-(--_mp-accent) text-(--_mp-on-accent)",tonal:"bg-(--_mp-accent-container) text-(--_mp-on-accent-container)",elevated:"shadow-mp-1 bg-mp-surface-container-low text-(--_mp-accent)",outlined:"border-mp-outline border bg-mp-surface-container text-(--_mp-accent)",text:"text-(--_mp-accent) bg-transparent"};export const MPBadge=n.forwardRef(function({variant:n="filled",size:u="md",color:g="error",content:f,max:h=99,dot:v=!1,showZero:w=!1,invisible:z=!1,placement:_="top-end",overlap:j="square",label:y,className:N,style:k,children:B,...$},q){const F=l(B),M=!l(f)||0===f&&!w,P=v||M,R=z||M&&!v,Z=["mp-badge pointer-events-none z-10 inline-flex shrink-0 items-center justify-center","rounded-mp-full tabular-nums whitespace-nowrap",x[n],P?o[u]:[i[u],r[u],d[u]].join(" "),F?`absolute ${c[_]}`:"relative align-middle",F?P?p[u].dot:p[u].badge:"",F&&"circle"===j?b[_]:"",R?"invisible":"",N??""].filter(Boolean).join(" "),A=function(e,t){return"number"==typeof e&&e>t?`${t}+`:e}(f,h),C=e("span",{ref:q,"data-mp-size":u,"data-mp-variant":n,className:Z,style:{...a(g),...k},"aria-hidden":!!R||void 0,...$,children:R?null:m(t,{children:[P||y?e("span",{className:s,children:y??A}):null,P?null:e("span",{"aria-hidden":!!y||void 0,children:A})]})});return F?m("span",{className:"relative inline-flex shrink-0 align-middle",children:[B,C]}):C});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{MPBadge}from"./MPBadge";
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { MPColor, MPSize, MPVariant } from '../../types';
|
|
3
|
+
/**
|
|
4
|
+
* The props are a `<figure>`'s rather than a `<blockquote>`'s, which is a
|
|
5
|
+
* consequence of where the drawing happens: everything a caller passes lands on
|
|
6
|
+
* the wrapper, and the wrapper is a figure or a div. Both are `HTMLElement`, so
|
|
7
|
+
* an event handler written against one works on the other.
|
|
8
|
+
*/
|
|
9
|
+
export interface MPBlockquoteProps extends Omit<React.ComponentPropsWithoutRef<'figure'>, 'color'> {
|
|
10
|
+
/**
|
|
11
|
+
* How much surface the quote paints behind the words.
|
|
12
|
+
* @default 'text'
|
|
13
|
+
*/
|
|
14
|
+
variant?: MPVariant;
|
|
15
|
+
/**
|
|
16
|
+
* The type scale of the quote and the room around it.
|
|
17
|
+
* @default 'md'
|
|
18
|
+
*/
|
|
19
|
+
size?: MPSize;
|
|
20
|
+
/**
|
|
21
|
+
* Which accent family the rule down the leading edge is drawn in — and, on
|
|
22
|
+
* `filled` and `tonal`, the surface behind the words.
|
|
23
|
+
* @default 'primary'
|
|
24
|
+
*/
|
|
25
|
+
color?: MPColor;
|
|
26
|
+
/**
|
|
27
|
+
* Who said it. Its presence is what turns the quote into a `<figure>` with a
|
|
28
|
+
* `<figcaption>`, which is the markup the HTML specification asks for: an
|
|
29
|
+
* attribution is *about* the quote and is not part of what was said.
|
|
30
|
+
*/
|
|
31
|
+
author?: React.ReactNode;
|
|
32
|
+
/**
|
|
33
|
+
* Where it is from — a book, a talk, a page. Rendered inside a `<cite>`, which
|
|
34
|
+
* is the element for the title of a work and, per the specification, never for
|
|
35
|
+
* the name of a person. That is what `author` is.
|
|
36
|
+
*/
|
|
37
|
+
source?: React.ReactNode;
|
|
38
|
+
/**
|
|
39
|
+
* URL of the document the quote was taken from. Lands on the `<blockquote>`'s
|
|
40
|
+
* own `cite` attribute, which is machine-readable and shown to nobody — use
|
|
41
|
+
* `source` for the part a reader should see.
|
|
42
|
+
*/
|
|
43
|
+
cite?: string;
|
|
44
|
+
/**
|
|
45
|
+
* The mark drawn before the quote. Omit it for the house glyph, pass a node to
|
|
46
|
+
* replace it, pass `false` to take it away.
|
|
47
|
+
*/
|
|
48
|
+
icon?: React.ReactNode | false;
|
|
49
|
+
/** What was said. */
|
|
50
|
+
children?: React.ReactNode;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Somebody else's words, set apart from your own.
|
|
54
|
+
*
|
|
55
|
+
* There is no Base UI primitive under this and there should not be: a quote has
|
|
56
|
+
* no state, no keyboard contract and nothing to interact with. What it has is
|
|
57
|
+
* markup that is easy to get wrong, and getting it right is most of the point.
|
|
58
|
+
*
|
|
59
|
+
* **Nothing is drawn on the `<blockquote>` itself.** The surface, the rule and
|
|
60
|
+
* the padding all belong to the element around it, and that is not tidiness —
|
|
61
|
+
* `blockquote` is one of the handful of tags a host stylesheet still styles by
|
|
62
|
+
* name. VitePress's `.vp-doc blockquote` sets a grey `border-left`, a
|
|
63
|
+
* `padding-left` and a `color`, all at a specificity a one-class utility cannot
|
|
64
|
+
* outrank, so a rule drawn on the quote itself would silently come out grey and
|
|
65
|
+
* a pixel too thin.
|
|
66
|
+
*
|
|
67
|
+
* The wrapper is a `<figure>` when there is an attribution and a `<div>` when
|
|
68
|
+
* there is not, because the HTML specification is explicit that the attribution
|
|
69
|
+
* goes *outside* the blockquote — a name inside it claims the speaker said their
|
|
70
|
+
* own name — and a `<figure>` with no `<figcaption>` in it is a figure of
|
|
71
|
+
* nothing.
|
|
72
|
+
*/
|
|
73
|
+
export declare const MPBlockquote: React.ForwardRefExoticComponent<MPBlockquoteProps & React.RefAttributes<HTMLElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as a from"react";import{accentSlots as r}from"../../internal/accent";import{hasContent as n,META_TEXT as i,SHEET_PAD as l}from"../../internal/scale";const o={xs:"text-mp-body-medium",sm:"text-mp-body-large",md:"text-mp-title-large",lg:"text-mp-headline-small",xl:"text-mp-headline-medium"},c="border-s-2 [border-inline-start-color:var(--_mp-accent)]",s={filled:"bg-(--_mp-accent) text-(--_mp-on-accent)",tonal:"bg-(--_mp-accent-container) text-(--_mp-on-accent-container)",elevated:"shadow-mp-1 bg-mp-surface-container-low text-mp-on-surface",outlined:"border-mp-outline-variant border border-s-2 bg-transparent text-mp-on-surface",text:"bg-transparent text-mp-on-surface"};function m(){return e("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"size-full",children:e("path",{d:"M6.4 3.6c-2.3.9-3.7 2.8-3.7 5.1 0 2 1.2 3.3 2.8 3.3 1.4 0 2.5-1 2.5-2.4 0-1.3-.9-2.2-2.1-2.2-.2 0-.4 0-.6.1.3-1 1.1-1.8 2.2-2.3l-1.1-1.6ZM13.3 3.6c-2.3.9-3.7 2.8-3.7 5.1 0 2 1.2 3.3 2.8 3.3 1.4 0 2.5-1 2.5-2.4 0-1.3-.9-2.2-2.1-2.2-.2 0-.4 0-.6.1.3-1 1.1-1.8 2.2-2.3l-1.1-1.6Z",fill:"currentColor"})})}export const MPBlockquote=a.forwardRef(function({variant:a="text",size:d="md",color:p="primary",author:u,source:f,cite:x,icon:h,className:b,style:g,children:v,...y},N){const j=n(u)||n(f),w=void 0===h?e(m,{}):h,z="text"!==a,_=["mp-blockquote flex flex-col",o[d],c,z?"rounded-mp-md rounded-s-none":"",s[a],z?l[d]:"ps-4",b??""].filter(Boolean).join(" "),k=t("blockquote",{cite:x,children:[n(w)?e("span",{"aria-hidden":"true",className:"mb-1 block size-[2em] opacity-38",children:w}):null,v]}),q={...r(p),...g};return j?t("figure",{ref:N,"data-mp-size":d,"data-mp-variant":a,className:_,style:q,...y,children:[k,t("figcaption",{className:["mt-2 flex flex-wrap items-baseline gap-x-1.5",z?"opacity-80":"text-mp-on-surface-variant",i].join(" "),children:[n(u)?t("span",{className:"font-medium",children:[e("span",{"aria-hidden":"true",children:"— "}),u]}):null,n(f)?e("cite",{className:"not-italic",children:f}):null]})]}):e("div",{ref:N,"data-mp-size":d,"data-mp-variant":a,className:_,style:q,...y,children:k})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{MPBlockquote}from"./MPBlockquote";
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useRender } from '@base-ui/react/use-render';
|
|
3
|
+
import type { MPSize, MPVariant } from '../../types';
|
|
4
|
+
export interface MPBoxProps extends React.ComponentPropsWithoutRef<'div'> {
|
|
5
|
+
/**
|
|
6
|
+
* How much surface the sheet paints.
|
|
7
|
+
*
|
|
8
|
+
* A container's ladder, so `filled` is MD3's own filled-card surface —
|
|
9
|
+
* `surface-container-highest` — and not the accent. See the note on the
|
|
10
|
+
* component below for why a box is never dyed.
|
|
11
|
+
* @default 'outlined'
|
|
12
|
+
*/
|
|
13
|
+
variant?: MPVariant;
|
|
14
|
+
/**
|
|
15
|
+
* The room inside.
|
|
16
|
+
*
|
|
17
|
+
* **This is the one component where `size` sets no height and no type scale.**
|
|
18
|
+
* A box is as tall as what it holds, and its children bring their own
|
|
19
|
+
* typography — a container that reset the type scale would make the same
|
|
20
|
+
* paragraph render at two sizes depending on what it happened to be wrapped
|
|
21
|
+
* in. So here the rung is the padding, and nothing else.
|
|
22
|
+
*
|
|
23
|
+
* The *corner* is not on the ladder either, which is where this library and
|
|
24
|
+
* most others part company. A radius in Material is a statement about what
|
|
25
|
+
* kind of object something is rather than a size to taste, and a box is a
|
|
26
|
+
* sheet: `corner-medium` at every rung, exactly as MD3 draws a card.
|
|
27
|
+
* @default 'md'
|
|
28
|
+
*/
|
|
29
|
+
size?: MPSize;
|
|
30
|
+
/**
|
|
31
|
+
* Inner padding. Turn it off for full-bleed content — a picture, a table, a
|
|
32
|
+
* list that draws its own rows.
|
|
33
|
+
* @default true
|
|
34
|
+
*/
|
|
35
|
+
padded?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Renders something other than a `<div>`: `render={<section />}`,
|
|
38
|
+
* `render={<li />}`, or a function for full control. Base UI's own escape
|
|
39
|
+
* hatch, so it behaves here exactly as it does on every Base UI primitive.
|
|
40
|
+
*/
|
|
41
|
+
render?: useRender.RenderProp;
|
|
42
|
+
children?: React.ReactNode;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* A sheet with content on it. The plainest surface in the library: it groups
|
|
46
|
+
* things, and that is all it does.
|
|
47
|
+
*
|
|
48
|
+
* Everything structural — a heading, a footer, dividers, a picture across the
|
|
49
|
+
* top — belongs to [MPCard](./card), which is exactly this box with those
|
|
50
|
+
* sections laid out on it.
|
|
51
|
+
*
|
|
52
|
+
* ## Why a box is never dyed, and takes no `color`
|
|
53
|
+
*
|
|
54
|
+
* Because what it holds is somebody else's content, and that content arrives
|
|
55
|
+
* with its own colours: body text, links, buttons, fields. On an accent fill
|
|
56
|
+
* every one of them would need an on-accent treatment of its own, which is the
|
|
57
|
+
* opposite of what a container is for.
|
|
58
|
+
*
|
|
59
|
+
* So the ladder runs up the **neutral** surface roles. `filled` is
|
|
60
|
+
* `surface-container-highest`, which is MD3's own filled card; `elevated` and
|
|
61
|
+
* `outlined` are the specification's other two card variants to the letter. What
|
|
62
|
+
* separates them is how much light the sheet holds and whether it carries a
|
|
63
|
+
* hairline — never which family it reads.
|
|
64
|
+
*
|
|
65
|
+
* A component that *is* the thing being coloured says so by taking `color`:
|
|
66
|
+
* that is [MPAlert](../feedback/alert) for a message, [MPChip](../display/chip)
|
|
67
|
+
* for a token, [MPButton](../inputs/button) for an action.
|
|
68
|
+
*
|
|
69
|
+
* ## Why there is no `elevation`
|
|
70
|
+
*
|
|
71
|
+
* There is no `elevation` prop anywhere in this library, and a box is where the
|
|
72
|
+
* absence is most tempting to fix. It stays absent because MD3 does not treat
|
|
73
|
+
* height as a free axis: an elevated surface is `surface-container-low` under a
|
|
74
|
+
* level-1 shadow, and the tone and the shadow are one decision. A prop that
|
|
75
|
+
* raised a `filled` box would produce a surface the specification has no name
|
|
76
|
+
* for. `variant="elevated"` is that decision, made once.
|
|
77
|
+
*/
|
|
78
|
+
export declare const MPBox: React.ForwardRefExoticComponent<MPBoxProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import*as r from"react";import{useRender as e}from"@base-ui/react/use-render";import{SHEET_PAD as a}from"../../internal/scale";import{CONTAINER_SURFACE as o}from"../../internal/surface";export const MPBox=r.forwardRef(function({variant:r="outlined",size:n="md",padded:t=!0,render:d,className:i,children:m,...s},p){return e({render:d,ref:p,props:{"data-mp-size":n,"data-mp-variant":r,className:["mp-box rounded-mp-md block","box-border",t?a[n]:"",o[r],"text-mp-on-surface",i??""].filter(Boolean).join(" "),children:m,...s}})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{MPBox}from"./MPBox";
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { MPColor, MPSize } from '../../types';
|
|
3
|
+
/**
|
|
4
|
+
* What is drawn between two steps of the trail.
|
|
5
|
+
*
|
|
6
|
+
* Four named marks rather than a free-for-all, because a separator is read
|
|
7
|
+
* hundreds of times a day and the difference between them is meaning, not
|
|
8
|
+
* decoration: a `chevron` and an `arrow` say "and then", a `slash` says "path",
|
|
9
|
+
* a `dot` says "these are peers of one thing". Anything else can still be passed
|
|
10
|
+
* as a node.
|
|
11
|
+
*/
|
|
12
|
+
export type MPBreadcrumbSeparator = 'chevron' | 'arrow' | 'slash' | 'dot';
|
|
13
|
+
export interface MPBreadcrumbProps extends Omit<React.ComponentPropsWithoutRef<'nav'>, 'color'> {
|
|
14
|
+
/** @default 'md' */
|
|
15
|
+
size?: MPSize;
|
|
16
|
+
/**
|
|
17
|
+
* The accent family a step picks up when it is hovered.
|
|
18
|
+
* @default 'primary'
|
|
19
|
+
*/
|
|
20
|
+
color?: MPColor;
|
|
21
|
+
/**
|
|
22
|
+
* The mark between two steps. One of the four names, or any node.
|
|
23
|
+
* @default 'chevron'
|
|
24
|
+
*/
|
|
25
|
+
separator?: MPBreadcrumbSeparator | React.ReactNode;
|
|
26
|
+
/**
|
|
27
|
+
* How many steps to show before the middle is folded away behind a `…`. Left
|
|
28
|
+
* out, the whole trail is shown however long it gets.
|
|
29
|
+
*/
|
|
30
|
+
maxItems?: number;
|
|
31
|
+
/**
|
|
32
|
+
* How many steps stay at the front of a folded trail.
|
|
33
|
+
* @default 1
|
|
34
|
+
*/
|
|
35
|
+
itemsBeforeCollapse?: number;
|
|
36
|
+
/**
|
|
37
|
+
* How many stay at the end.
|
|
38
|
+
* @default 1
|
|
39
|
+
*/
|
|
40
|
+
itemsAfterCollapse?: number;
|
|
41
|
+
/**
|
|
42
|
+
* Whether pressing the `…` unfolds the trail in place. Turn it off to leave
|
|
43
|
+
* the fold as a plain mark.
|
|
44
|
+
* @default true
|
|
45
|
+
*/
|
|
46
|
+
expandable?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* The name the trail is announced by.
|
|
49
|
+
* @default 'Breadcrumb'
|
|
50
|
+
*/
|
|
51
|
+
label?: string;
|
|
52
|
+
/**
|
|
53
|
+
* What the `…` is announced as.
|
|
54
|
+
* @default 'Show hidden steps'
|
|
55
|
+
*/
|
|
56
|
+
expandLabel?: string;
|
|
57
|
+
/** The `MPBreadcrumbItem`s. */
|
|
58
|
+
children?: React.ReactNode;
|
|
59
|
+
}
|
|
60
|
+
export interface MPBreadcrumbItemProps extends Omit<React.ComponentPropsWithoutRef<'li'>, 'color' | 'onClick'> {
|
|
61
|
+
/** Renders the step as a link. */
|
|
62
|
+
href?: string;
|
|
63
|
+
/** Fires when the step is pressed. Renders it as a button when there is no `href`. */
|
|
64
|
+
onClick?: React.MouseEventHandler<HTMLElement>;
|
|
65
|
+
/** Content before the label — a home glyph, a repository avatar. */
|
|
66
|
+
startIcon?: React.ReactNode;
|
|
67
|
+
/** Content after the label. */
|
|
68
|
+
endIcon?: React.ReactNode;
|
|
69
|
+
/**
|
|
70
|
+
* Marks this step as the page you are on, which stops it being a link.
|
|
71
|
+
*
|
|
72
|
+
* The last step is the current one on its own, so this is only needed for a
|
|
73
|
+
* trail that ends somewhere the reader is not — and setting it anywhere takes
|
|
74
|
+
* the mark off the last step, because only one step in a trail can be it.
|
|
75
|
+
*/
|
|
76
|
+
current?: boolean;
|
|
77
|
+
/** Unavailable. Stops answering, keeps its place in the trail. */
|
|
78
|
+
disabled?: boolean;
|
|
79
|
+
/** The step's label. */
|
|
80
|
+
children?: React.ReactNode;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* The trail of pages above the one being read.
|
|
84
|
+
*
|
|
85
|
+
* Two things make this more than a row of links. The first is that the last step
|
|
86
|
+
* is where the reader already is, so it is not a link at all — it carries
|
|
87
|
+
* `aria-current="page"` and stops being pressable, and the component works that
|
|
88
|
+
* out rather than asking every caller to remember it. The second is the fold: a
|
|
89
|
+
* trail seven levels deep is a trail nobody reads, so the middle collapses to a
|
|
90
|
+
* `…` that puts it back when pressed.
|
|
91
|
+
*
|
|
92
|
+
* The separators are drawn by the trail rather than by the steps. A step does not
|
|
93
|
+
* know whether anything follows it, and a mark that belonged to a step would have
|
|
94
|
+
* to be taken off the last one by hand.
|
|
95
|
+
*/
|
|
96
|
+
export declare const MPBreadcrumb: React.ForwardRefExoticComponent<MPBreadcrumbProps & React.RefAttributes<HTMLElement>>;
|
|
97
|
+
/**
|
|
98
|
+
* One step of the trail.
|
|
99
|
+
*
|
|
100
|
+
* It renders three different things and the caller picks by what they pass: an
|
|
101
|
+
* `<a>` with an `href`, a `<button>` with an `onClick`, and a plain `<span>` with
|
|
102
|
+
* neither — which is what the last step is, because the page you are already on
|
|
103
|
+
* is not somewhere to go.
|
|
104
|
+
*/
|
|
105
|
+
export declare const MPBreadcrumbItem: React.ForwardRefExoticComponent<MPBreadcrumbItemProps & React.RefAttributes<HTMLLIElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e,jsxs as n,Fragment as r}from"react/jsx-runtime";import*as t from"react";import{MPIcon as a}from"../icon/MPIcon";import{ArrowRightIcon as o,ChevronRightIcon as i,MoreIcon as s}from"../../constants/icons";import{accentSlots as l}from"../../internal/accent";import{CONTROL_GAP as c,hasContent as m,PROSE_TEXT as d}from"../../internal/scale";const u=t.createContext({size:"md",last:!1}),p={xs:"gap-1",sm:"gap-1.5",md:"gap-2",lg:"gap-2.5",xl:"gap-3"},f={xs:"rounded-mp-xs",sm:"rounded-mp-xs",md:"rounded-mp-xs",lg:"rounded-mp-sm",xl:"rounded-mp-sm"};const h=["chevron","arrow","slash","dot"];export const MPBreadcrumb=t.forwardRef(function({size:r="md",color:c="primary",separator:m="chevron",maxItems:f,itemsBeforeCollapse:x=1,itemsAfterCollapse:b=1,expandable:v=!0,label:g="Breadcrumb",expandLabel:N="Show hidden steps",className:y,style:k,children:j,...w},z){const[B,C]=t.useState(!1),M=t.Children.toArray(j).filter(t.isValidElement),I=M.length,P=M.some(e=>!0===e.props.current),_=!B&&void 0!==f&&I>Math.max(f,1)&&I-x-b>1?[...M.slice(0,Math.max(0,x)),null,...M.slice(I-Math.max(0,b))]:M,A="string"==typeof(F=m)&&h.includes(F)?function(n){switch(n){case"chevron":return e(a,{icon:i,size:"1.1em",className:"rtl:rotate-180"});case"arrow":return e(a,{icon:o,size:"1em",className:"rtl:rotate-180"});case"slash":return e("span",{"aria-hidden":"true",children:"/"});case"dot":return e("span",{"aria-hidden":"true",children:"·"});default:return null}}(m):m;var F;const R=["rounded-mp-xs text-mp-on-surface-variant inline-flex items-center px-0.5","appearance-none border-0 bg-transparent font-[inherit]","transition-[background-color,color] duration-(--mp-sys-motion-duration-short4)",v?["cursor-pointer hover:bg-(--_mp-accent-container) hover:text-(--_mp-on-accent-container)","outline-mp-secondary focus-visible:outline-2 focus-visible:outline-offset-1","focus-visible:outline-solid outline-none"].join(" "):""].filter(Boolean).join(" ");return e("nav",{ref:z,"aria-label":g,"data-mp-size":r,className:["mp-breadcrumb flex",d[r],y??""].filter(Boolean).join(" "),style:{...l(c),...k},...w,children:e("ol",{role:"list",className:`flex list-none flex-wrap items-center p-0 ${p[r]}`,children:_.map((o,i)=>n(t.Fragment,{children:[i>0?e("li",{"aria-hidden":"true",className:"text-mp-on-surface-variant flex shrink-0 items-center select-none",children:A}):null,o?e(u.Provider,{value:{size:r,last:!P&&i===_.length-1},children:o}):e("li",{className:"flex shrink-0 items-center",children:v?e("button",{type:"button",className:R,"aria-label":N,onClick:()=>C(!0),children:e(a,{icon:s,size:"1.1em"})}):e("span",{className:R,"aria-hidden":"true",children:e(a,{icon:s,size:"1.1em"})})})]},o?o.key??i:"fold"))})})});export const MPBreadcrumbItem=t.forwardRef(function({href:a,onClick:o,startIcon:i,endIcon:s,current:l,disabled:d=!1,className:p,children:h,...x},b){const{size:v,last:g}=t.useContext(u),N=l??g,y=Boolean(a||o)&&!N&&!d,k=["inline-flex min-w-0 items-center px-1 no-underline","appearance-none border-0 bg-transparent font-[inherit] text-[inherit]",c[v],f[v],"transition-[background-color,color] duration-(--mp-sys-motion-duration-short4)",d?"text-mp-on-surface/38 cursor-default":N?"text-mp-on-surface font-medium":y?["text-mp-on-surface-variant cursor-pointer","hover:bg-(--_mp-accent-container) hover:text-(--_mp-on-accent-container)","outline-mp-secondary focus-visible:outline-2 focus-visible:outline-offset-1","focus-visible:outline-solid outline-none"].join(" "):"text-mp-on-surface-variant"].filter(Boolean).join(" "),j=n(r,{children:[m(i)?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:i}):null,e("span",{className:"truncate",children:h}),m(s)?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:s}):null]});return e("li",{ref:b,className:["flex min-w-0 items-center",p??""].filter(Boolean).join(" "),...x,children:y&&a?e("a",{href:a,className:k,onClick:o,children:j}):y?e("button",{type:"button",className:k,onClick:o,children:j}):e("span",{className:k,"aria-current":N?"page":void 0,"aria-disabled":d||void 0,children:j})})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{MPBreadcrumb,MPBreadcrumbItem}from"./MPBreadcrumb";
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { MPColor, MPStyleProps, MPVariant } from '../../types';
|
|
3
|
+
export interface MPButtonProps extends MPStyleProps, Omit<React.ComponentPropsWithoutRef<'button'>, 'color'> {
|
|
4
|
+
/**
|
|
5
|
+
* How much surface the button paints.
|
|
6
|
+
* @default 'filled'
|
|
7
|
+
*/
|
|
8
|
+
variant?: MPVariant;
|
|
9
|
+
/**
|
|
10
|
+
* Which accent family it reads. Not an arbitrary colour: to change what
|
|
11
|
+
* `primary` *is*, set the token.
|
|
12
|
+
* @default 'primary'
|
|
13
|
+
*/
|
|
14
|
+
color?: MPColor;
|
|
15
|
+
/** Content placed before the label. */
|
|
16
|
+
startIcon?: React.ReactNode;
|
|
17
|
+
/** Content placed after the label. */
|
|
18
|
+
endIcon?: React.ReactNode;
|
|
19
|
+
/**
|
|
20
|
+
* Swaps `startIcon` for a spinner and stops the button firing, while leaving it
|
|
21
|
+
* focusable and otherwise unchanged.
|
|
22
|
+
*
|
|
23
|
+
* Deliberately not `disabled`. A button that vanishes from the tab order the
|
|
24
|
+
* moment it is pressed takes the keyboard focus with it, and the reader is
|
|
25
|
+
* returned to the top of the document while the request they just made is
|
|
26
|
+
* still in flight.
|
|
27
|
+
* @default false
|
|
28
|
+
*/
|
|
29
|
+
loading?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* The accessible name of the spinner, announced while `loading`.
|
|
32
|
+
* @default 'Loading'
|
|
33
|
+
*/
|
|
34
|
+
loadingLabel?: string;
|
|
35
|
+
/**
|
|
36
|
+
* `button`, not `submit`. A native button defaults to submitting the form
|
|
37
|
+
* around it, which turns every unrelated button inside a form into one that
|
|
38
|
+
* submits it.
|
|
39
|
+
* @default 'button'
|
|
40
|
+
*/
|
|
41
|
+
type?: 'button' | 'submit' | 'reset';
|
|
42
|
+
children?: React.ReactNode;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* A Material Design button.
|
|
46
|
+
*
|
|
47
|
+
* Five variants, four accent families and the library's size ladder, drawn from
|
|
48
|
+
* MD3's own component tokens: the container and label colours per variant, the
|
|
49
|
+
* state layer, the spec's disabled opacities, and the shape — `corner-full`,
|
|
50
|
+
* because a Material button has been a pill since 2021 and a rounded rectangle
|
|
51
|
+
* is the single fastest way to make a screen look like it is from 2018.
|
|
52
|
+
*
|
|
53
|
+
* Base UI's `Button` is underneath, which is what makes `disabled` behave: it
|
|
54
|
+
* keeps a disabled button out of the tab order without the composition problems
|
|
55
|
+
* a plain `aria-disabled` brings, and publishes `data-pressed` so a press driven
|
|
56
|
+
* from the keyboard lights the same state layer a pointer press does.
|
|
57
|
+
*
|
|
58
|
+
* ## Two things this does not have
|
|
59
|
+
*
|
|
60
|
+
* **No `href`.** A button that navigates is a link, and the difference is not
|
|
61
|
+
* cosmetic: a link is announced as one, opens in a new tab on the middle button,
|
|
62
|
+
* and shows its destination in the status bar. Wrap an `<a>` in the styling, or
|
|
63
|
+
* pass `render={<a href="…" />}` — Base UI's own escape hatch — rather than
|
|
64
|
+
* teaching the button to lie about what it is.
|
|
65
|
+
*
|
|
66
|
+
* **No ripple.** MD3 dropped it: the state layer below is what replaced it, and
|
|
67
|
+
* it says the same thing without an animation that has to finish before the
|
|
68
|
+
* screen it triggered is allowed to change.
|
|
69
|
+
*/
|
|
70
|
+
export declare const MPButton: React.ForwardRefExoticComponent<MPButtonProps & 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 n}from"@base-ui/react/button";import{MPIcon as r}from"../icon/MPIcon";import{SpinnerIcon as a}from"../../constants/icons";import{accentSlots as i}from"../../internal/accent";import{MPButtonGroupContext as s}from"../../internal/button-group";import{MPStateLayer as l}from"../../internal/StateLayer";import{CONTROL_GAP as c,CONTROL_HEIGHT as p,CONTROL_ICON as d,CONTROL_PAD_X as m,CONTROL_SQUARE as u,CONTROL_TEXT as f,hasContent as b}from"../../internal/scale";const x={filled:"bg-(--_mp-accent) text-(--_mp-on-accent)",tonal:"bg-(--_mp-accent-container) text-(--_mp-on-accent-container)",elevated:"shadow-mp-1 hover:shadow-mp-2 bg-mp-surface-container-low text-(--_mp-accent)",outlined:"border-mp-outline border bg-transparent text-(--_mp-accent)",text:"bg-transparent text-(--_mp-accent)"},g={filled:"bg-mp-on-surface/12 text-mp-on-surface/38",tonal:"bg-mp-on-surface/12 text-mp-on-surface/38",elevated:"bg-mp-on-surface/12 text-mp-on-surface/38 shadow-none",outlined:"border-mp-on-surface/12 border bg-transparent text-mp-on-surface/38",text:"bg-transparent text-mp-on-surface/38"};export const MPButton=o.forwardRef(function({variant:v,size:h,color:w,disabled:y,startIcon:_,endIcon:j,loading:k=!1,loadingLabel:z="Loading",fullWidth:B=!1,type:C="button",className:I,style:L,children:N,onClick:P,...M},D){const R=o.useContext(s),S=v??R?.variant??"filled",W=h??R?.size??"md",$=w??R?.color??"primary",q=y??R?.disabled??!1,A=!b(N);return t(n,{ref:D,type:C,disabled:q,"aria-busy":k||void 0,"aria-disabled":k||void 0,"data-mp-size":W,"data-mp-variant":S,"data-loading":k||void 0,className:["mp-button group relative inline-flex shrink-0 items-center justify-center","rounded-mp-full 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,border-color,box-shadow,color]","duration-(--mp-sys-motion-duration-short4)",p[W],f[W],c[W],A?`${u[W]} px-0`:m[W],q?g[S]:x[S],q?"cursor-default":"",k?"cursor-progress":"",B?"w-full":"",I??""].filter(Boolean).join(" "),style:{...i($),...L},onClick:e=>{if(k)return e.preventDefault(),void e.stopPropagation();P?.(e)},...M,children:[q?null:e(l,{}),k?e(r,{icon:a,size:d[W],label:z,className:"animate-spin"}):_,N,j]})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{MPButton}from"./MPButton";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { MPColor, MPOrientation, MPStyleProps, MPVariant } from '../../types';
|
|
3
|
+
export interface MPButtonGroupProps extends MPStyleProps, Omit<React.ComponentPropsWithoutRef<'div'>, 'color'> {
|
|
4
|
+
/**
|
|
5
|
+
* Which way the buttons run.
|
|
6
|
+
* @default 'horizontal'
|
|
7
|
+
*/
|
|
8
|
+
orientation?: MPOrientation;
|
|
9
|
+
/** Passed to every button in the group. */
|
|
10
|
+
variant?: MPVariant;
|
|
11
|
+
/** Passed to every button in the group. */
|
|
12
|
+
color?: MPColor;
|
|
13
|
+
/** Disables every button in the group at once. */
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
children?: React.ReactNode;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* A run of buttons that belong together.
|
|
19
|
+
*
|
|
20
|
+
* Two things happen here and only one of them is visual. The corners that face a
|
|
21
|
+
* neighbour are cut back — that is the look. The other half is that `variant`,
|
|
22
|
+
* `size`, `color` and `disabled` are set once for the set rather than repeated on
|
|
23
|
+
* every button, which is the failure this exists to prevent: a group where one
|
|
24
|
+
* button is a size out is not a group.
|
|
25
|
+
*
|
|
26
|
+
* The buttons stay real `MPButton`s, and the group does not manage selection.
|
|
27
|
+
* For one-of-a-set, reach for `MPSegmentedButton` — a row of buttons that
|
|
28
|
+
* remembers which one was pressed is a radio group wearing a costume, and it
|
|
29
|
+
* announces itself to a screen reader as four unrelated actions.
|
|
30
|
+
*/
|
|
31
|
+
export declare const MPButtonGroup: React.ForwardRefExoticComponent<MPButtonGroupProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as o}from"react/jsx-runtime";import*as r from"react";import{MPButtonGroupContext as e}from"../../internal/button-group";const t={horizontal:"[&>*:not(:first-child)]:rounded-s-mp-sm [&>*:not(:last-child)]:rounded-e-mp-sm",vertical:"[&>*:not(:first-child)]:rounded-t-mp-sm [&>*:not(:last-child)]:rounded-b-mp-sm"};export const MPButtonGroup=r.forwardRef(function({variant:i,size:l,color:n,disabled:a,orientation:s="horizontal",fullWidth:d=!1,className:c,children:m,...u},f){const p=r.useMemo(()=>({variant:i,size:l,color:n,disabled:a}),[i,l,n,a]);return o(e.Provider,{value:p,children:o("div",{ref:f,role:"group","data-mp-orientation":s,className:["mp-button-group inline-flex gap-0.5 align-middle","vertical"===s?"flex-col":"flex-row",t[s],"[&>*]:relative [&>*:focus-visible]:z-10",d?"flex w-full [&>*]:flex-1":"",c??""].filter(Boolean).join(" "),...u,children:m})})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{MPButtonGroup}from"./MPButtonGroup";
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type MPBoxProps } from '../box/MPBox';
|
|
3
|
+
export interface MPCardProps extends Omit<MPBoxProps, 'title' | 'padded'> {
|
|
4
|
+
/**
|
|
5
|
+
* The card's heading.
|
|
6
|
+
*
|
|
7
|
+
* A plain string is set in the card's own title role. Pass a real heading
|
|
8
|
+
* element — `title={<h3>Totals</h3>}` — when the card should appear in the
|
|
9
|
+
* document outline: it inherits the typography rather than the browser's, so
|
|
10
|
+
* nothing about it looks different.
|
|
11
|
+
*/
|
|
12
|
+
title?: React.ReactNode;
|
|
13
|
+
/** A second line under it, one step down the type scale and muted. */
|
|
14
|
+
subtitle?: React.ReactNode;
|
|
15
|
+
/**
|
|
16
|
+
* Content pinned to the end of the header row — a menu button, a status chip.
|
|
17
|
+
* It stays on the title's line while the title wraps beside it.
|
|
18
|
+
*/
|
|
19
|
+
headerAction?: React.ReactNode;
|
|
20
|
+
/**
|
|
21
|
+
* A picture, a chart, a map: drawn **edge to edge** across the top, so the
|
|
22
|
+
* card's own corners crop it.
|
|
23
|
+
*
|
|
24
|
+
* MD3's own card anatomy puts the media above the headline, and it is a slot
|
|
25
|
+
* of its own rather than part of `children` because it is the one part of a
|
|
26
|
+
* card that must not be padded.
|
|
27
|
+
*/
|
|
28
|
+
media?: React.ReactNode;
|
|
29
|
+
/**
|
|
30
|
+
* The bottom area. Laid out as a wrapping row, so a pair of buttons needs no
|
|
31
|
+
* wrapper of its own; anything else brings its own layout.
|
|
32
|
+
*/
|
|
33
|
+
footer?: React.ReactNode;
|
|
34
|
+
/**
|
|
35
|
+
* Draws a hairline between the sections instead of separating them with space.
|
|
36
|
+
*
|
|
37
|
+
* The rules run the full width of the sheet, so the padding moves off the card
|
|
38
|
+
* and onto each section.
|
|
39
|
+
* @default false
|
|
40
|
+
*/
|
|
41
|
+
dividers?: boolean;
|
|
42
|
+
/** The card's body. */
|
|
43
|
+
children?: React.ReactNode;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* An [MPBox](./box) with the parts a card is made of laid out on it: a picture,
|
|
47
|
+
* a heading, a subheading, a body and a footer.
|
|
48
|
+
*
|
|
49
|
+
* The sections are props rather than compound sub-components — no `<MPCard.Header>`
|
|
50
|
+
* — for the reason [MPDialog](../feedback/dialog) gives: the arrangement of a
|
|
51
|
+
* card is fixed, and what a caller wants to decide is what goes in each slot,
|
|
52
|
+
* not what order the slots come in. Every `MPBox` prop passes straight through,
|
|
53
|
+
* so a card is styled on exactly the same axes as the box it is.
|
|
54
|
+
*
|
|
55
|
+
* ## The surface is MD3's card, and so is the anatomy
|
|
56
|
+
*
|
|
57
|
+
* `corner-medium`, and three of the five variants are the specification's own
|
|
58
|
+
* card variants to the letter: `filled` is `surface-container-highest`,
|
|
59
|
+
* `elevated` is `surface-container-low` under a level-1 shadow, `outlined` is a
|
|
60
|
+
* hairline in `outline-variant`. None of them is dyed, and there is no `color`
|
|
61
|
+
* — see `MPBox` for the argument, which is the same one.
|
|
62
|
+
*
|
|
63
|
+
* ## What a card deliberately is not
|
|
64
|
+
*
|
|
65
|
+
* It is not pressable. MD3 does describe a card as a container that *may* be
|
|
66
|
+
* interactive, and a `href` or an `onClick` here would be the wrong shape for
|
|
67
|
+
* it: a card with a heading, a body and two buttons in its footer that is also
|
|
68
|
+
* one big link is a link containing links, which the HTML parser will take
|
|
69
|
+
* apart. Make the **heading** the link, or give the footer a button. What a
|
|
70
|
+
* whole-card target is for is a grid of tiles, and a tile is an
|
|
71
|
+
* [MPBox](./box) with an `<a>` in it.
|
|
72
|
+
*/
|
|
73
|
+
export declare const MPCard: React.ForwardRefExoticComponent<MPCardProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e,jsxs as l,Fragment as a}from"react/jsx-runtime";import*as r from"react";import{MPBox as n}from"../box/MPBox";import{hasContent as i,META_TEXT as o,PROSE_TEXT as t,SHEET_GAP as c,SHEET_PAD_X as s,SHEET_PAD_Y as d,SHEET_TITLE as m}from"../../internal/scale";export const MPCard=r.forwardRef(function({size:r="md",title:f,subtitle:u,headerAction:p,media:x,footer:h,dividers:_=!1,className:v,children:N,...w},b){const k=s[r],$=d[r],g=_?`${k} ${$}`:k,j=i(f)||i(u)||i(p),y=i(x),B=[j?{key:"header",className:"mp-card__header flex items-start gap-3",content:l(a,{children:[i(f)||i(u)?l("div",{className:"flex min-w-0 flex-1 flex-col",children:[i(f)?e("div",{className:`mp-card__title ${m[r]}`,children:f}):null,i(u)?e("div",{className:`text-mp-on-surface-variant ${o}`,children:u}):null]}):null,i(p)?e("div",{className:"ms-auto shrink-0",children:p}):null]})}:null,i(N)?{key:"content",className:`mp-card__body min-w-0 ${t[r]}`,content:N}:null,i(h)?{key:"footer",className:"mp-card__footer flex flex-wrap items-center gap-2",content:h}:null].filter(e=>null!==e);return l(n,{ref:b,size:r,padded:!1,className:["mp-card flex flex-col",y?"overflow-hidden":"",v??""].filter(Boolean).join(" "),...w,children:[y?e("div",{className:"mp-card__media [&_img]:block [&_img]:w-full [&_video]:block [&_video]:w-full",children:x}):null,B.length>0?e("div",{className:["flex min-w-0 flex-col",_?"":`${$} ${c[r]}`].filter(Boolean).join(" "),children:B.map((l,a)=>e("div",{className:[g,l.className,_&&a>0?"border-mp-outline-variant border-t":""].filter(Boolean).join(" "),children:l.content},l.key))}):null]})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{MPCard}from"./MPCard";
|