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,116 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { MPColor, MPSize, MPVariant } from '../../types';
|
|
3
|
+
export interface MPCarouselProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'color' | 'defaultValue' | 'onChange'> {
|
|
4
|
+
/** Which slide is showing, counted from 0. Use with `onValueChange`. */
|
|
5
|
+
value?: number;
|
|
6
|
+
/**
|
|
7
|
+
* Which starts showing, for an uncontrolled carousel.
|
|
8
|
+
* @default 0
|
|
9
|
+
*/
|
|
10
|
+
defaultValue?: number;
|
|
11
|
+
onValueChange?: (index: number) => void;
|
|
12
|
+
/**
|
|
13
|
+
* Whether the arrows wrap from the last slide back to the first.
|
|
14
|
+
*
|
|
15
|
+
* With it off they go `disabled` at the ends instead, which is the honest
|
|
16
|
+
* thing for a set that has a beginning and an end — a gallery of three
|
|
17
|
+
* photographs does, a rotating banner does not.
|
|
18
|
+
* @default true
|
|
19
|
+
*/
|
|
20
|
+
loop?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Advances on its own.
|
|
23
|
+
*
|
|
24
|
+
* Off by default and deliberately so: a carousel that moves while it is being
|
|
25
|
+
* read is the most complained-about pattern on the web. It pauses on hover, on
|
|
26
|
+
* focus anywhere inside it, while the tab is in the background, and it does not
|
|
27
|
+
* start at all for a reader who has asked for reduced motion.
|
|
28
|
+
* @default false
|
|
29
|
+
*/
|
|
30
|
+
autoPlay?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* How long each slide is held, in milliseconds.
|
|
33
|
+
* @default 5000
|
|
34
|
+
*/
|
|
35
|
+
interval?: number;
|
|
36
|
+
/**
|
|
37
|
+
* The previous/next buttons.
|
|
38
|
+
* @default true
|
|
39
|
+
*/
|
|
40
|
+
arrows?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* The row of position marks under the frame.
|
|
43
|
+
* @default true
|
|
44
|
+
*/
|
|
45
|
+
indicators?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* How much surface the frame paints behind the slides.
|
|
48
|
+
*
|
|
49
|
+
* `text` is the one to reach for when the pictures already have edges of their
|
|
50
|
+
* own — it draws no frame at all, and the slides are the whole component.
|
|
51
|
+
* @default 'outlined'
|
|
52
|
+
*/
|
|
53
|
+
variant?: MPVariant;
|
|
54
|
+
/**
|
|
55
|
+
* The size of the arrows and the marks, and how far the arrows sit in from the
|
|
56
|
+
* frame's edge. Not the size of a slide, which is whatever the frame is.
|
|
57
|
+
* @default 'md'
|
|
58
|
+
*/
|
|
59
|
+
size?: MPSize;
|
|
60
|
+
/**
|
|
61
|
+
* Which accent family the current mark and the arrows read.
|
|
62
|
+
* @default 'primary'
|
|
63
|
+
*/
|
|
64
|
+
color?: MPColor;
|
|
65
|
+
/**
|
|
66
|
+
* The carousel's accessible name.
|
|
67
|
+
* @default 'Carousel'
|
|
68
|
+
*/
|
|
69
|
+
label?: string;
|
|
70
|
+
/** @default 'Previous slide' */
|
|
71
|
+
previousLabel?: string;
|
|
72
|
+
/** @default 'Next slide' */
|
|
73
|
+
nextLabel?: string;
|
|
74
|
+
/**
|
|
75
|
+
* How one slide is named to a screen reader, and how its mark is labelled.
|
|
76
|
+
* @default (index, count) => `Slide ${index} of ${count}`
|
|
77
|
+
*/
|
|
78
|
+
slideLabel?: (index: number, count: number) => string;
|
|
79
|
+
/** The slides. Every top-level child becomes one. */
|
|
80
|
+
children?: React.ReactNode;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* A strip of slides, one of which is in view.
|
|
84
|
+
*
|
|
85
|
+
* The mechanism is a scroll container with CSS scroll snapping, and nearly
|
|
86
|
+
* everything good about this component follows from that one choice. Swiping on
|
|
87
|
+
* a phone and two-finger dragging on a trackpad both work, because they are the
|
|
88
|
+
* browser's own scrolling rather than a gesture handler pretending to be it. The
|
|
89
|
+
* strip runs the other way under RTL without being told, because scrolling is
|
|
90
|
+
* directional and `translate` is not. And nothing is transformed, so the house
|
|
91
|
+
* rule against moving a surface holds here for free — a translated track would
|
|
92
|
+
* have had to argue for an exception.
|
|
93
|
+
*
|
|
94
|
+
* The motion is `scroll-behavior: smooth`, which means a reader who has asked for
|
|
95
|
+
* reduced motion gets an instant cut out of the same code path rather than out of
|
|
96
|
+
* a second one written to remember them.
|
|
97
|
+
*
|
|
98
|
+
* ## Why every child is a slide
|
|
99
|
+
*
|
|
100
|
+
* There is no `MPCarouselSlide`. `<MPCarousel><img /><img /></MPCarousel>` is the
|
|
101
|
+
* whole API, and the wrapper this component puts around each child is what
|
|
102
|
+
* carries the snap point, the width and the `role="group"` /
|
|
103
|
+
* `aria-roledescription="slide"` pair a screen reader needs — none of which a
|
|
104
|
+
* caller should have to remember to put on a photograph.
|
|
105
|
+
*
|
|
106
|
+
* ## What this is, in MD3's terms
|
|
107
|
+
*
|
|
108
|
+
* The specification describes four carousel layouts, three of which — hero,
|
|
109
|
+
* multi-browse and uncontained — resize their items as they travel past the
|
|
110
|
+
* frame's edge. This is the fourth: one item to a view, snapping. The other three
|
|
111
|
+
* are a per-item transform driven by scroll position, which is a different
|
|
112
|
+
* component and not one this library ships yet; what is here is drawn out of the
|
|
113
|
+
* specification's own parts — a filled icon button either side, a selected
|
|
114
|
+
* indicator that is a bar rather than a bigger dot.
|
|
115
|
+
*/
|
|
116
|
+
export declare const MPCarousel: React.ForwardRefExoticComponent<MPCarouselProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e,jsxs as r}from"react/jsx-runtime";import*as t from"react";import{MPIconButton as n}from"../icon-button/MPIconButton";import{MPIcon as o}from"../icon/MPIcon";import{ChevronLeftIcon as a,ChevronRightIcon as i}from"../../constants/icons";import{accentSlots as l}from"../../internal/accent";import{CONTROL_ICON as s}from"../../internal/scale";import{CONTAINER_SURFACE as c}from"../../internal/surface";import{VISUALLY_HIDDEN as u}from"../../internal/visually-hidden";const d={xs:"start-1 end-1",sm:"start-1.5 end-1.5",md:"start-2 end-2",lg:"start-3 end-3",xl:"start-4 end-4"},m={xs:{rest:"h-1 w-1",current:"h-1 w-3",gap:"gap-1"},sm:{rest:"h-1 w-1",current:"h-1 w-3.5",gap:"gap-1"},md:{rest:"h-1.5 w-1.5",current:"h-1.5 w-4",gap:"gap-1.5"},lg:{rest:"h-1.5 w-1.5",current:"h-1.5 w-5",gap:"gap-2"},xl:{rest:"h-2 w-2",current:"h-2 w-6",gap:"gap-2"}},f=(e,r)=>`Slide ${e} of ${r}`;export const MPCarousel=t.forwardRef(function({value:p,defaultValue:h=0,onValueChange:b,loop:v=!0,autoPlay:w=!1,interval:x=5e3,arrows:g=!0,indicators:N=!0,variant:y="outlined",size:M="md",color:k="primary",label:j="Carousel",previousLabel:C="Previous slide",nextLabel:P="Next slide",slideLabel:z=f,className:I,style:R,children:$,...L},S){const B=t.Children.toArray($),E=B.length,[V,T]=t.useState(h),W=Math.min(Math.max(p??V,0),Math.max(E-1,0)),A=t.useRef(null),F=t.useRef([]),_=t.useRef(!1),q=t.useRef(!1),D=t.useRef(!1),[G,H]=t.useState(!1),J=t.useCallback((e,r=!1)=>{if(0===E)return;const t=v?(e%E+E)%E:Math.min(Math.max(e,0),E-1);_.current=r,void 0===p&&T(t),t!==W&&b?.(t)},[E,v,p,W,b]);t.useEffect(()=>{if(_.current)return void(_.current=!1);if(!q.current)return void(q.current=!0);F.current[W]?.scrollIntoView({block:"nearest",inline:"start"}),D.current=!0;const e=window.setTimeout(()=>{D.current=!1},700);return()=>window.clearTimeout(e)},[W]),t.useEffect(()=>{if(!w||G||E<2)return;if(window.matchMedia?.("(prefers-reduced-motion: reduce)").matches)return;const e=window.setInterval(()=>{document.hidden||J(W+1)},x);return()=>window.clearInterval(e)},[w,G,E,x,W,J]);const K=W<=0,O=W>=E-1;return r("div",{ref:S,role:"region","aria-roledescription":"carousel","aria-label":j,"data-mp-size":M,"data-mp-variant":y,className:["mp-carousel flex w-full flex-col",I??""].filter(Boolean).join(" "),style:{...l(k),...R},onPointerEnter:()=>H(!0),onPointerLeave:()=>H(!1),onFocus:()=>H(!0),onBlur:()=>H(!1),...L,children:[r("div",{className:["relative min-w-0 overflow-hidden","rounded-mp-md box-border",c[y],"text-mp-on-surface"].join(" "),children:[e("div",{ref:A,tabIndex:0,role:"group","aria-label":j,className:["flex min-w-0 snap-x snap-mandatory overflow-x-auto scroll-smooth","motion-reduce:scroll-auto","[scrollbar-width:none] [&::-webkit-scrollbar]:hidden","outline-mp-secondary focus-visible:outline-2 focus-visible:-outline-offset-2","focus-visible:outline-solid outline-none"].join(" "),onScroll:()=>{const e=A.current;if(!e||0===e.clientWidth||D.current)return;const r=Math.round(Math.abs(e.scrollLeft)/e.clientWidth);r!==W&&r>=0&&r<E&&J(r,!0)},children:B.map((r,t)=>e("div",{ref:e=>{F.current[t]=e},role:"group","aria-roledescription":"slide","aria-label":z(t+1,E),className:"w-full shrink-0 grow-0 basis-full snap-start",children:r},t))}),g&&E>1?r("div",{className:`pointer-events-none absolute inset-y-0 flex items-center ${d[M]}`,children:[e(n,{variant:"filled",size:M,color:k,label:C,disabled:!v&&K,className:"pointer-events-auto",icon:e(o,{icon:a,size:s[M],className:"rtl:rotate-180"}),onClick:()=>J(W-1)}),e("span",{className:"flex-1"}),e(n,{variant:"filled",size:M,color:k,label:P,disabled:!v&&O,className:"pointer-events-auto",icon:e(o,{icon:i,size:s[M],className:"rtl:rotate-180"}),onClick:()=>J(W+1)})]}):null]}),N&&E>1?e("div",{className:`flex shrink-0 items-center justify-center pt-2 ${m[M].gap}`,children:B.map((r,t)=>e("button",{type:"button","aria-label":z(t+1,E),"aria-current":t===W?"true":void 0,className:["rounded-mp-full cursor-pointer appearance-none border-0 p-0","transition-[width,background-color] duration-(--mp-sys-motion-duration-short4)","ease-mp-standard motion-reduce:transition-none","outline-mp-secondary focus-visible:outline-2 focus-visible:outline-offset-2","focus-visible:outline-solid outline-none",t===W?`${m[M].current} bg-(--_mp-accent)`:`${m[M].rest} bg-mp-outline-variant hover:bg-mp-outline`].join(" "),onClick:()=>J(t)},t))}):null,e("span",{className:u,"aria-live":w?"off":"polite",children:E>0?z(W+1,E):""})]})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{MPCarousel}from"./MPCarousel";
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { MPColor, MPSize, MPVariant } from '../../types';
|
|
3
|
+
/**
|
|
4
|
+
* Whose message this is.
|
|
5
|
+
*
|
|
6
|
+
* `start` and `end` rather than `them`/`me` or `left`/`right`: a thread runs the
|
|
7
|
+
* way the language does, and the same two words already mean this everywhere
|
|
8
|
+
* else in the library. `start` is the default because a message from somebody
|
|
9
|
+
* else is the one you have no other way of knowing about.
|
|
10
|
+
*/
|
|
11
|
+
export type MPChatBubbleSide = 'start' | 'end';
|
|
12
|
+
/**
|
|
13
|
+
* How far a message has got.
|
|
14
|
+
*
|
|
15
|
+
* The first four are a ladder and the fifth is not on it: `failed` is the
|
|
16
|
+
* message that did not go, which is why it is the only one drawn in another
|
|
17
|
+
* colour family.
|
|
18
|
+
*/
|
|
19
|
+
export type MPChatBubbleStatus = 'sending' | 'sent' | 'delivered' | 'read' | 'failed';
|
|
20
|
+
/** What a link inside a message unfurls to. */
|
|
21
|
+
export interface MPChatBubblePreview {
|
|
22
|
+
/** Where the card goes. */
|
|
23
|
+
url: string;
|
|
24
|
+
/** The page's title. */
|
|
25
|
+
title?: React.ReactNode;
|
|
26
|
+
/** Its summary, clamped to two lines. */
|
|
27
|
+
description?: React.ReactNode;
|
|
28
|
+
/** The share image, drawn across the top of the card. */
|
|
29
|
+
image?: string;
|
|
30
|
+
/** Who published it — a domain, a site name. */
|
|
31
|
+
site?: React.ReactNode;
|
|
32
|
+
/**
|
|
33
|
+
* Opens the card in a new tab.
|
|
34
|
+
* @default false
|
|
35
|
+
*/
|
|
36
|
+
newTab?: boolean;
|
|
37
|
+
}
|
|
38
|
+
export interface MPChatBubbleProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'color' | 'title'> {
|
|
39
|
+
/**
|
|
40
|
+
* Whose message this is.
|
|
41
|
+
* @default 'start'
|
|
42
|
+
*/
|
|
43
|
+
side?: MPChatBubbleSide;
|
|
44
|
+
/** Who sent it, above the bubble. */
|
|
45
|
+
name?: React.ReactNode;
|
|
46
|
+
/** When it was sent, beside the name. */
|
|
47
|
+
time?: React.ReactNode;
|
|
48
|
+
/**
|
|
49
|
+
* The sender's picture — an [MPAvatar](../display/avatar), at the size the
|
|
50
|
+
* thread uses. Left out, the bubble takes the whole row.
|
|
51
|
+
*/
|
|
52
|
+
avatar?: React.ReactNode;
|
|
53
|
+
/**
|
|
54
|
+
* How far the message has got, drawn as a mark under the bubble. Left out,
|
|
55
|
+
* nothing is drawn — a received message has no delivery state worth showing.
|
|
56
|
+
*/
|
|
57
|
+
status?: MPChatBubbleStatus;
|
|
58
|
+
/** Overrides the word the mark is read out as. */
|
|
59
|
+
statusLabel?: string;
|
|
60
|
+
/**
|
|
61
|
+
* Draws the three dots instead of the message. Whatever is in `children` is
|
|
62
|
+
* left alone, so the same bubble can go back to it when the message arrives.
|
|
63
|
+
* @default false
|
|
64
|
+
*/
|
|
65
|
+
typing?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* A picture, a video, a map — drawn edge to edge above the text, so the
|
|
68
|
+
* bubble's own corners crop it.
|
|
69
|
+
*/
|
|
70
|
+
media?: React.ReactNode;
|
|
71
|
+
/** A link in the message, unfurled into a card under the text. */
|
|
72
|
+
preview?: MPChatBubblePreview;
|
|
73
|
+
/**
|
|
74
|
+
* The message's own actions — an [MPMenu](../inputs/menu) trigger, most of the
|
|
75
|
+
* time. Sits beside the bubble and stays out of the way until the row is
|
|
76
|
+
* hovered or something in it takes focus.
|
|
77
|
+
*/
|
|
78
|
+
actions?: React.ReactNode;
|
|
79
|
+
/**
|
|
80
|
+
* Which language the marks are read out in. Falls back to the nearest
|
|
81
|
+
* `MPLocaleProvider`, then to English.
|
|
82
|
+
*/
|
|
83
|
+
locale?: string;
|
|
84
|
+
/**
|
|
85
|
+
* How much surface the bubble paints.
|
|
86
|
+
*
|
|
87
|
+
* A bubble *is* the thing being coloured, unlike a card — so this is the
|
|
88
|
+
* control ladder rather than the container one, and `filled` floods it with
|
|
89
|
+
* the accent. That is what tells your own messages from everyone else's at a
|
|
90
|
+
* glance rather than one line at a time.
|
|
91
|
+
*
|
|
92
|
+
* `side` deliberately does not decide it: which end of the thread is filled is
|
|
93
|
+
* a decision about the product, not about the component, and a thread that
|
|
94
|
+
* fills neither is a perfectly good thread.
|
|
95
|
+
* @default 'tonal'
|
|
96
|
+
*/
|
|
97
|
+
variant?: MPVariant;
|
|
98
|
+
/**
|
|
99
|
+
* The type scale of the message, and the room inside the bubble.
|
|
100
|
+
* @default 'md'
|
|
101
|
+
*/
|
|
102
|
+
size?: MPSize;
|
|
103
|
+
/**
|
|
104
|
+
* @default 'primary'
|
|
105
|
+
*/
|
|
106
|
+
color?: MPColor;
|
|
107
|
+
/** The message. */
|
|
108
|
+
children?: React.ReactNode;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* One message in a conversation.
|
|
112
|
+
*
|
|
113
|
+
* MD3 does not describe a chat bubble — this is the library's own shape, in the
|
|
114
|
+
* sense [MPProgressBox](../feedback/progress-box) is — but every part of it is
|
|
115
|
+
* drawn out of the specification's own roles, so a thread of these sits in a
|
|
116
|
+
* Material page without announcing that it is extra.
|
|
117
|
+
*
|
|
118
|
+
* Everything around the bubble is optional and nothing about it is fixed by
|
|
119
|
+
* `side`: the avatar, the sender's name, the time, the delivery mark, the media
|
|
120
|
+
* above the text and the link card below it are each drawn only when they are
|
|
121
|
+
* given something. What `side` decides is which way the row runs and which
|
|
122
|
+
* corner of the bubble is cut short.
|
|
123
|
+
*
|
|
124
|
+
* ## Why `variant` is not tied to `side`
|
|
125
|
+
*
|
|
126
|
+
* Filling the reading-end column is a convention, not a law. It is also a
|
|
127
|
+
* decision about the product — some threads fill neither end, and a support
|
|
128
|
+
* inbox may want the *agent's* messages filled rather than the reader's. So
|
|
129
|
+
* `side` decides the geometry and `variant` decides the emphasis, and a caller
|
|
130
|
+
* who wants the usual arrangement writes it once.
|
|
131
|
+
*/
|
|
132
|
+
export declare const MPChatBubble: React.ForwardRefExoticComponent<MPChatBubbleProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e,jsxs as n}from"react/jsx-runtime";import*as a from"react";import{MPIcon as r}from"../icon/MPIcon";import{CheckIcon as l,ClockIcon as t,ErrorIcon as i,LinkIcon as o}from"../../constants/icons";import{accentSlots as s}from"../../internal/accent";import{useMPLocale as c,useMPMessages as m}from"../../internal/locale";import{hasContent as d,META_TEXT as p,PROSE_TEXT as u}from"../../internal/scale";import{VISUALLY_HIDDEN as f}from"../../internal/visually-hidden";const h={xs:"px-2 py-1",sm:"px-2.5 py-1.5",md:"px-3 py-2",lg:"px-3.5 py-2.5",xl:"px-4 py-3"},b={start:"[border-start-start-radius:var(--mp-sys-shape-corner-extra-small)]",end:"[border-start-end-radius:var(--mp-sys-shape-corner-extra-small)]"},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-on-surface",outlined:"border-mp-outline-variant border bg-transparent text-mp-on-surface",text:"bg-mp-surface-container-low text-mp-on-surface"};function v(){return n("svg",{viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",className:"size-full",children:[e("path",{d:"m1.5 8.5 2.75 2.75L9.5 6",stroke:"currentColor",strokeWidth:"1.75",strokeLinecap:"round",strokeLinejoin:"round"}),e("path",{d:"M7 10.75 8.25 12l5.25-5.25",stroke:"currentColor",strokeWidth:"1.75",strokeLinecap:"round",strokeLinejoin:"round"})]})}const g={sending:e(r,{icon:t,size:"1.15em"}),sent:e(r,{icon:l,size:"1.15em"}),delivered:e("span",{className:"block size-[1.15em]",children:e(v,{})}),read:e("span",{className:"block size-[1.15em]",children:e(v,{})}),failed:e(r,{icon:i,size:"1.15em"})},N={sending:"text-mp-on-surface-variant",sent:"text-mp-on-surface-variant",delivered:"text-mp-on-surface-variant",read:"text-(--_mp-accent)",failed:"text-mp-error"},w=["rounded-mp-sm block overflow-hidden border no-underline","[border-color:color-mix(in_oklab,currentColor_18%,transparent)]","[background-color:color-mix(in_oklab,currentColor_7%,transparent)]","hover:[background-color:color-mix(in_oklab,currentColor_12%,transparent)]","transition-[background-color] duration-(--mp-sys-motion-duration-short4) ease-mp-standard","outline-mp-secondary focus-visible:outline-2 focus-visible:outline-offset-2","focus-visible:outline-solid outline-none"].join(" "),y=["shrink-0 opacity-0","transition-opacity duration-(--mp-sys-motion-duration-short4) ease-mp-standard","group-hover/bubble:opacity-100 group-focus-within/bubble:opacity-100","[@media(hover:none)]:opacity-100"].join(" ");export const MPChatBubble=a.forwardRef(function({side:a="start",name:r,time:l,avatar:t,status:i,statusLabel:o,typing:v=!1,media:w,preview:j,actions:z,locale:C,variant:L="tonal",size:B="md",color:$="primary",className:M,style:P,children:W,...I},R){const T=c(C),q=m("chat",T),A="end"===a,D=d(r)||d(l),E=v||d(W)||Boolean(j);return n("div",{ref:R,"data-mp-size":B,"data-mp-variant":L,"data-mp-side":a,className:["mp-chat-bubble group/bubble flex w-full items-start gap-2",A?"flex-row-reverse":"",M??""].filter(Boolean).join(" "),style:{...s($),...P},...I,children:[d(t)?e("div",{className:"shrink-0",children:t}):null,n("div",{className:["flex min-w-0 max-w-[min(100%,32rem)] flex-col gap-1",A?"items-end":"items-start"].join(" "),children:[D?n("div",{className:`flex items-baseline gap-2 ${p}`,children:[d(r)?e("span",{className:"font-medium",children:r}):null,d(l)?e("span",{className:"text-mp-on-surface-variant",children:l}):null]}):null,n("div",{className:"flex min-w-0 items-center gap-1 "+(A?"flex-row-reverse":""),children:[n("div",{className:["mp-chat-bubble__sheet rounded-mp-xl flex min-w-0 flex-col overflow-hidden","box-border",b[a],x[L],u[B]].join(" "),children:[d(w)?e("div",{className:"[&_img]:block [&_img]:w-full [&_video]:block [&_video]:w-full",children:w}):null,E?n("div",{className:`flex min-w-0 flex-col gap-2 ${h[B]}`,children:[v?e(k,{label:q.typing}):d(W)?e("div",{className:"min-w-0 break-words whitespace-pre-line",children:W}):null,j?e(_,{preview:j}):null]}):null]}),d(z)?e("div",{className:y,children:z}):null]}),i?n("div",{className:`flex items-center gap-1 ${p} ${N[i]}`,children:[g[i],e("span",{className:f,children:o??q[i]})]}):null]})]})});function k({label:a}){return n("div",{className:"flex items-center gap-1 py-[0.35em]",role:"status",children:[[0,1,2].map(n=>e("span",{"aria-hidden":"true",className:"mp-chat-typing size-[0.45em] rounded-full bg-current",style:{"--_mp-index":n}},n)),e("span",{className:f,children:a})]})}function _({preview:a}){const{url:l,title:t,description:i,image:s,site:c,newTab:m=!1}=a;return n("a",{href:l,target:m?"_blank":void 0,rel:m?"noopener noreferrer":void 0,className:w,children:[s?e("img",{src:s,alt:"",className:"block h-28 w-full object-cover"}):null,n("div",{className:"flex flex-col gap-0.5 p-2",children:[d(c)?n("span",{className:"flex items-center gap-1 text-[0.85em] opacity-70",children:[e(r,{icon:o,size:"1em"}),e("span",{className:"truncate",children:c})]}):null,d(t)?e("span",{className:"font-medium",children:t}):null,d(i)?e("span",{className:"line-clamp-2 text-[0.9em] opacity-80",children:i}):null]})]})}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{MPChatBubble}from"./MPChatBubble";
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { MPColor, MPSize } from '../../types';
|
|
3
|
+
export interface MPCheckboxProps {
|
|
4
|
+
/** Whether the box is ticked. Use with `onCheckedChange` for a controlled box. */
|
|
5
|
+
checked?: boolean;
|
|
6
|
+
/** Whether the box starts ticked, for an uncontrolled one. */
|
|
7
|
+
defaultChecked?: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Called with the new state. A boolean rather than an event, the same bargain
|
|
10
|
+
* `MPTextField.onChange` makes: what a caller wants is the value.
|
|
11
|
+
*/
|
|
12
|
+
onCheckedChange?: (checked: boolean) => void;
|
|
13
|
+
/**
|
|
14
|
+
* Neither ticked nor empty — what a parent box shows when some of its children
|
|
15
|
+
* are ticked. Drawn as a dash, and it is a *display* state: clicking a
|
|
16
|
+
* half-ticked box ticks it.
|
|
17
|
+
* @default false
|
|
18
|
+
*/
|
|
19
|
+
indeterminate?: boolean;
|
|
20
|
+
/** The text beside the tick, wired to it by Base UI's Field. */
|
|
21
|
+
label?: React.ReactNode;
|
|
22
|
+
/** The line under the label. Replaced by `errorMessage` when there is one. */
|
|
23
|
+
description?: React.ReactNode;
|
|
24
|
+
/**
|
|
25
|
+
* The message under the label. Its presence is also what turns the checkbox
|
|
26
|
+
* over into its error state, so there is no way to show one with no
|
|
27
|
+
* explanation.
|
|
28
|
+
*/
|
|
29
|
+
errorMessage?: React.ReactNode;
|
|
30
|
+
/**
|
|
31
|
+
* The tick's size and the label's type scale.
|
|
32
|
+
* @default 'md'
|
|
33
|
+
*/
|
|
34
|
+
size?: MPSize;
|
|
35
|
+
/**
|
|
36
|
+
* Which accent family the ticked box is filled with.
|
|
37
|
+
* @default 'primary'
|
|
38
|
+
*/
|
|
39
|
+
color?: MPColor;
|
|
40
|
+
/** Marks the checkbox required, both to assistive technology and to the label. */
|
|
41
|
+
required?: boolean;
|
|
42
|
+
/** Greys the checkbox out and stops it taking input. */
|
|
43
|
+
disabled?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Shows the state without allowing changes. Unlike `disabled` the box stays in
|
|
46
|
+
* the tab order, which is what a value the reader still has to be able to find
|
|
47
|
+
* needs.
|
|
48
|
+
*/
|
|
49
|
+
readOnly?: boolean;
|
|
50
|
+
/** Name of the form control, as on a native checkbox. */
|
|
51
|
+
name?: string;
|
|
52
|
+
/** The value submitted when the box is ticked. */
|
|
53
|
+
value?: string;
|
|
54
|
+
/**
|
|
55
|
+
* The id put on the control and pointed at by the label. Derived from `name`
|
|
56
|
+
* when omitted, and generated when there is no name either.
|
|
57
|
+
*/
|
|
58
|
+
id?: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* A Material Design checkbox.
|
|
62
|
+
*
|
|
63
|
+
* The box is `on-surface-variant` at rest and fills with the accent family when
|
|
64
|
+
* it is ticked — which is the one place this library expresses a state by
|
|
65
|
+
* swapping the whole surface rather than washing it, because "on" and "off" are
|
|
66
|
+
* not two strengths of the same thing.
|
|
67
|
+
*
|
|
68
|
+
* `label`, `description` and `errorMessage` are props rather than children for
|
|
69
|
+
* the reason they are on `MPTextField`: the arrangement is fixed, and what a
|
|
70
|
+
* caller decides is what goes in each slot. There is no `children`.
|
|
71
|
+
*
|
|
72
|
+
* Base UI's `Checkbox` is underneath, so the hidden input that submits with a
|
|
73
|
+
* form, the `aria-checked="mixed"` an indeterminate box needs, and the label
|
|
74
|
+
* association all come for free.
|
|
75
|
+
*/
|
|
76
|
+
export declare const MPCheckbox: React.ForwardRefExoticComponent<MPCheckboxProps & React.RefAttributes<HTMLElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e,jsxs as r}from"react/jsx-runtime";import*as a from"react";import{Checkbox as t}from"@base-ui/react/checkbox";import{Field as n}from"@base-ui/react/field";import{MPIcon as o}from"../icon/MPIcon";import{CheckIcon as i,RemoveIcon as c}from"../../constants/icons";import{accentSlots as s}from"../../internal/accent";import{MPStateLayer as d}from"../../internal/StateLayer";import{MPSupportingText as l}from"../../internal/SupportingText";import{PROSE_TEXT as m,hasContent as p}from"../../internal/scale";const h={xs:{box:"size-3.5",halo:"size-8",glyph:12},sm:{box:"size-4",halo:"size-9",glyph:14},md:{box:"size-[18px]",halo:"size-10",glyph:16},lg:{box:"size-5",halo:"size-11",glyph:18},xl:{box:"size-[22px]",halo:"size-12",glyph:20}};export const MPCheckbox=a.forwardRef(function({checked:u,defaultChecked:b,onCheckedChange:f,indeterminate:x=!1,label:g,description:k,errorMessage:y,size:z="md",color:j="primary",required:_=!1,disabled:v=!1,readOnly:C=!1,name:N,value:M,id:I},R){const q=p(y),w=q?"error":j,L=h[z],O=a.useId(),P=I??`mp-checkbox-${N??O}`;return e(n.Root,{className:"mp-checkbox inline-block align-top",disabled:v,invalid:q,"data-mp-size":z,style:s(w),children:r("div",{className:["flex items-start gap-3",m[z]].join(" "),children:[e("span",{className:"flex h-[1lh] shrink-0 items-center",children:r(t.Root,{ref:R,id:P,name:N,value:M,checked:u,defaultChecked:b,indeterminate:x,required:_,disabled:v,readOnly:C,onCheckedChange:e=>f?.(e),className:["mp-checkbox__tick group relative inline-flex shrink-0 items-center","box-border justify-center border-2 p-0","rounded-[calc(var(--mp-sys-shape-corner-extra-small)/2)]","appearance-none bg-transparent font-[inherit] outline-none","transition-[background-color,border-color]","duration-(--mp-sys-motion-duration-short4)",L.box,v?["border-mp-on-surface/38 cursor-default","data-checked:bg-mp-on-surface/38 data-checked:border-transparent","data-indeterminate:bg-mp-on-surface/38 data-indeterminate:border-transparent"].join(" "):[C?"cursor-default":"cursor-pointer",q?"border-mp-error":"border-mp-on-surface-variant","data-checked:border-transparent data-checked:bg-(--_mp-accent)","data-checked:text-(--_mp-on-accent)","data-indeterminate:border-transparent data-indeterminate:bg-(--_mp-accent)","data-indeterminate:text-(--_mp-on-accent)"].join(" ")].join(" "),children:[v?null:e(d,{layer:["top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 rounded-full",L.halo,"bg-mp-on-surface","group-data-checked:bg-(--_mp-accent)","group-data-indeterminate:bg-(--_mp-accent)"].join(" ")}),e(t.Indicator,{className:"flex items-center justify-center",children:e(o,{icon:x?c:i,size:L.glyph,strokeWidth:3})})]})}),p(g)||p(k)||q?r("span",{className:"flex min-w-0 flex-col gap-0.5",children:[p(g)?r(n.Label,{htmlFor:P,className:["leading-[1.4]",v?"text-mp-on-surface/38 cursor-default":C?"text-mp-on-surface":"text-mp-on-surface cursor-pointer"].join(" "),children:[g,_?e("span",{"aria-hidden":"true",children:" *"}):null]}):null,e(l,{description:k,errorMessage:y})]}):null]})})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{MPCheckbox}from"./MPCheckbox";
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { MPColor, MPSize, MPVariant } from '../../types';
|
|
3
|
+
export interface MPChipProps extends Omit<React.ComponentPropsWithoutRef<'span'>, 'color'> {
|
|
4
|
+
/**
|
|
5
|
+
* How much surface the chip paints.
|
|
6
|
+
*
|
|
7
|
+
* `outlined` is the default because it is MD3's: an assist, filter and input
|
|
8
|
+
* chip are all outlined at rest, and the outlined chip is the one that stays
|
|
9
|
+
* legible in a row of twenty.
|
|
10
|
+
* @default 'outlined'
|
|
11
|
+
*/
|
|
12
|
+
variant?: MPVariant;
|
|
13
|
+
/**
|
|
14
|
+
* @default 'md'
|
|
15
|
+
*/
|
|
16
|
+
size?: MPSize;
|
|
17
|
+
/** @default 'primary' */
|
|
18
|
+
color?: MPColor;
|
|
19
|
+
/** Content placed before the label — an icon, a status dot, an avatar. */
|
|
20
|
+
startIcon?: React.ReactNode;
|
|
21
|
+
/** Content placed after the label, before any `count`. */
|
|
22
|
+
endIcon?: React.ReactNode;
|
|
23
|
+
/**
|
|
24
|
+
* A number set into the end of the chip. Rendered on its own small plate, so
|
|
25
|
+
* "Errors 12" reads as one token with a count rather than as two words.
|
|
26
|
+
*/
|
|
27
|
+
count?: React.ReactNode;
|
|
28
|
+
/**
|
|
29
|
+
* Called when the chip's delete affordance is pressed. Passing it is what
|
|
30
|
+
* makes the affordance appear.
|
|
31
|
+
*/
|
|
32
|
+
onDelete?: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
|
33
|
+
/**
|
|
34
|
+
* Accessible name of the delete button.
|
|
35
|
+
* @default 'Remove'
|
|
36
|
+
*/
|
|
37
|
+
deleteLabel?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Marks the chip as chosen — a filter that is on.
|
|
40
|
+
*
|
|
41
|
+
* MD3's selected filter chip fills with the container tone of its own family
|
|
42
|
+
* rather than changing family, which is what this does: a filter that is on is
|
|
43
|
+
* still the same filter.
|
|
44
|
+
* @default false
|
|
45
|
+
*/
|
|
46
|
+
selected?: boolean;
|
|
47
|
+
/** Unavailable. Drops the accent family, as everywhere else in the library. */
|
|
48
|
+
disabled?: boolean;
|
|
49
|
+
children?: React.ReactNode;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* A compact token: a tag, a filter, a status, an entity plucked out of a list.
|
|
53
|
+
*
|
|
54
|
+
* The shell is always a `<span>`. What changes is what is inside it: a plain run
|
|
55
|
+
* of content, or — when `onClick` is given — a real `<button>` wrapping that
|
|
56
|
+
* content, plus a second button for `onDelete`. Both are reachable by keyboard,
|
|
57
|
+
* and neither is nested inside the other.
|
|
58
|
+
*
|
|
59
|
+
* An inert `<span>` carrying a click handler is the single most common way a
|
|
60
|
+
* component library loses its keyboard users, and a `<button>` inside a
|
|
61
|
+
* `<button>` is the most common way one invents a chip that Chrome silently
|
|
62
|
+
* rewrites. This shape avoids both.
|
|
63
|
+
*/
|
|
64
|
+
export declare const MPChip: React.ForwardRefExoticComponent<MPChipProps & React.RefAttributes<HTMLSpanElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e,Fragment as t,jsxs as n}from"react/jsx-runtime";import*as o from"react";import{MPIcon as a}from"../icon/MPIcon";import{CloseIcon as r}from"../../constants/icons";import{accentSlots as i}from"../../internal/accent";import{hasContent as l}from"../../internal/scale";import{MPStateLayer as c}from"../../internal/StateLayer";const s={xs:"h-6",sm:"h-7",md:"h-8",lg:"h-10",xl:"h-12"},m={xs:"text-mp-label-medium",sm:"text-mp-label-medium",md:"text-mp-label-large",lg:"text-mp-label-large",xl:"text-mp-title-medium"},p={xs:"px-2",sm:"px-3",md:"px-4",lg:"px-5",xl:"px-6"},d={xs:"gap-1",sm:"gap-1.5",md:"gap-2",lg:"gap-2",xl:"gap-2.5"},u={xs:"rounded-mp-xs",sm:"rounded-mp-sm",md:"rounded-mp-sm",lg:"rounded-mp-sm",xl:"rounded-mp-md"},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-on-surface-variant",outlined:"border-mp-outline text-mp-on-surface-variant border bg-transparent",text:"text-mp-on-surface-variant bg-transparent"},f={filled:"bg-(--_mp-accent) text-(--_mp-on-accent)",tonal:"bg-(--_mp-accent-container) text-(--_mp-on-accent-container)",elevated:"shadow-mp-1 bg-(--_mp-accent-container) text-(--_mp-on-accent-container)",outlined:"border-mp-outline bg-(--_mp-accent-container) text-(--_mp-on-accent-container) border",text:"bg-(--_mp-accent-container) text-(--_mp-on-accent-container)"},b={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 text-mp-on-surface/38 border bg-transparent",text:"bg-transparent text-mp-on-surface/38"},g=["ms-0.5 -me-1 inline-flex shrink-0 cursor-pointer items-center justify-center","rounded-mp-full size-[1.35em] opacity-70","transition-opacity duration-(--mp-sys-motion-duration-short4)","hover:opacity-100 focus-visible:opacity-100","outline-mp-secondary focus-visible:outline-2 focus-visible:outline-offset-1","focus-visible:outline-solid outline-none","disabled:cursor-default disabled:opacity-38"].join(" "),h=["group relative flex min-w-0 flex-1 cursor-pointer items-center justify-center","self-stretch rounded-[inherit] font-[inherit] text-[inherit]","appearance-none border-0 bg-transparent","outline-mp-secondary focus-visible:outline-2 focus-visible:outline-offset-2","focus-visible:outline-solid outline-none"].join(" ");export const MPChip=o.forwardRef(function({variant:o="outlined",size:v="md",color:y="primary",startIcon:_,endIcon:w,count:j,onDelete:k,deleteLabel:N="Remove",selected:z=!1,disabled:C=!1,className:I,style:$,children:B,onClick:L,...M},P){const R=Boolean(L)&&!C,D=["mp-chip relative inline-flex max-w-full shrink-0 items-center","box-border overflow-hidden align-middle leading-none whitespace-nowrap select-none","transition-[background-color,border-color,box-shadow,color]","duration-(--mp-sys-motion-duration-short4)",s[v],m[v],d[v],u[v],C?b[o]:z?f[o]:x[o],R?"ps-0":p[v],k?"pe-2":R?"pe-0":"",I??""].filter(Boolean).join(" "),F=n(t,{children:[_,l(B)?e("span",{className:"min-w-0 truncate",children:B}):null,w,l(j)?e("span",{className:["rounded-mp-full ms-0.5 inline-flex shrink-0 items-center justify-center px-1.5 py-px","text-[0.85em] leading-none font-medium tabular-nums","filled"===o?"bg-(--_mp-on-accent)/20 text-(--_mp-on-accent)":"bg-(--_mp-accent-container) text-(--_mp-on-accent-container)"].join(" "),children:j}):null]});return n("span",{ref:P,"data-mp-size":v,"data-mp-variant":o,"data-selected":z||void 0,className:D,style:{...i(y),...$},"aria-disabled":!(!C||R)||void 0,...M,children:[R?n("button",{type:"button","aria-pressed":z,className:`${h} ${d[v]} ${p[v]}`,onClick:L,children:[e(c,{}),F]}):F,k?e("button",{type:"button","aria-label":N,disabled:C,className:g,onClick:k,children:e(a,{icon:r,size:"1em"})}):null]})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{MPChip}from"./MPChip";
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { MPSize, MPVariant } from '../../types';
|
|
3
|
+
export interface MPCollapsibleProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'title' | 'onChange'> {
|
|
4
|
+
/** Whether the panel is showing. Use with `onOpenChange` for a controlled one. */
|
|
5
|
+
open?: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Whether it starts open, for an uncontrolled one.
|
|
8
|
+
* @default false
|
|
9
|
+
*/
|
|
10
|
+
defaultOpen?: boolean;
|
|
11
|
+
onOpenChange?: (open: boolean) => void;
|
|
12
|
+
/** The heading on the trigger. */
|
|
13
|
+
title?: React.ReactNode;
|
|
14
|
+
/** A second line under it, one step down the type scale and muted. */
|
|
15
|
+
subtitle?: React.ReactNode;
|
|
16
|
+
/** Content before the title — a glyph, a status dot, a count. */
|
|
17
|
+
startIcon?: React.ReactNode;
|
|
18
|
+
/**
|
|
19
|
+
* A control pinned to the end of the header, **outside** the trigger.
|
|
20
|
+
*
|
|
21
|
+
* Deliberately outside it: a header that both folds and holds a switch has two
|
|
22
|
+
* things to press, and a `<button>` inside a `<button>` is markup the browser
|
|
23
|
+
* rewrites on parse. The same shape `MPListItem` and `MPAccordionItem` use.
|
|
24
|
+
*/
|
|
25
|
+
action?: React.ReactNode;
|
|
26
|
+
/**
|
|
27
|
+
* Replaces the header entirely with a control of your own — an `MPButton`, an
|
|
28
|
+
* `MPChip`, a line of text you made pressable.
|
|
29
|
+
*
|
|
30
|
+
* The element you pass *becomes* the trigger: Base UI hands it the click
|
|
31
|
+
* handler, `aria-expanded` and the `aria-controls` pointing at the panel, so
|
|
32
|
+
* there is nothing to wire up. `title` and the slots around it are for the far
|
|
33
|
+
* commoner case of wanting the header that is already there.
|
|
34
|
+
*/
|
|
35
|
+
trigger?: React.ReactElement;
|
|
36
|
+
/**
|
|
37
|
+
* The chevron at the end of the header, turned to report the state.
|
|
38
|
+
* @default true
|
|
39
|
+
*/
|
|
40
|
+
indicator?: boolean;
|
|
41
|
+
/** Unavailable. The trigger stops answering and the panel stays as it is. */
|
|
42
|
+
disabled?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Inner padding around the panel's content. Turn it off for something that
|
|
45
|
+
* should reach the edges — a table, a picture, a list of its own.
|
|
46
|
+
* @default true
|
|
47
|
+
*/
|
|
48
|
+
padded?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* How much surface the sheet paints.
|
|
51
|
+
* @default 'outlined'
|
|
52
|
+
*/
|
|
53
|
+
variant?: MPVariant;
|
|
54
|
+
/**
|
|
55
|
+
* The room inside, and the type scale of the header and the body.
|
|
56
|
+
* @default 'md'
|
|
57
|
+
*/
|
|
58
|
+
size?: MPSize;
|
|
59
|
+
/**
|
|
60
|
+
* Keeps a closed panel in the DOM so the browser's own page search can find
|
|
61
|
+
* and open it. Overrides `keepMounted`.
|
|
62
|
+
* @default false
|
|
63
|
+
*/
|
|
64
|
+
hiddenUntilFound?: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Keeps a closed panel in the DOM. For content that is expensive to build, or
|
|
67
|
+
* that holds form state which should survive being folded away.
|
|
68
|
+
* @default false
|
|
69
|
+
*/
|
|
70
|
+
keepMounted?: boolean;
|
|
71
|
+
/** The body. */
|
|
72
|
+
children?: React.ReactNode;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* One section that folds, standing on its own.
|
|
76
|
+
*
|
|
77
|
+
* An [MPAccordion](./accordion) is a *set* of these and owns which one of them
|
|
78
|
+
* is open; this is the same fold with nothing else beside it, so what it needs
|
|
79
|
+
* is an `open` of its own rather than a place in somebody's list. Reach for it
|
|
80
|
+
* for a "Show more" on a form, an optional block of settings, the detail under
|
|
81
|
+
* a row.
|
|
82
|
+
*
|
|
83
|
+
* Base UI owns the parts that are genuinely hard: the `<button>`/panel pairing
|
|
84
|
+
* and the `aria-controls` / `aria-expanded` wiring between them,
|
|
85
|
+
* `hidden="until-found"`, and measuring the panel so it has a height to animate
|
|
86
|
+
* from. What is here is the surface, the ladders and the state layer.
|
|
87
|
+
*
|
|
88
|
+
* ## Why there is no `color`
|
|
89
|
+
*
|
|
90
|
+
* Because nothing would read it. The sheet stays neutral — a collapsible is a
|
|
91
|
+
* box holding somebody else's content, and dyeing the box dyes their content's
|
|
92
|
+
* background — and the focus ring is `secondary` on every control in the
|
|
93
|
+
* library. A prop that reaches nothing is a prop that has to be supported
|
|
94
|
+
* forever. For a fold that *is* the message rather than a container for one,
|
|
95
|
+
* that is [MPAlert](../feedback/alert).
|
|
96
|
+
*/
|
|
97
|
+
export declare const MPCollapsible: React.ForwardRefExoticComponent<MPCollapsibleProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e,jsxs as n}from"react/jsx-runtime";import*as t from"react";import{Collapsible as a}from"@base-ui/react/collapsible";import{MPIcon as i}from"../icon/MPIcon";import{ChevronDownIcon as r}from"../../constants/icons";import{MPStateLayer as o}from"../../internal/StateLayer";import{CONTROL_GAP as s,CONTROL_ICON as l,hasContent as c,META_TEXT as d,PROSE_TEXT as m,SHEET_PAD_X as p,SHEET_PAD_Y as u,SHEET_TITLE as f}from"../../internal/scale";import{CONTAINER_SURFACE as h}from"../../internal/surface";const x=["h-(--collapsible-panel-height) overflow-hidden","transition-[height] duration-(--mp-sys-motion-duration-short4) ease-mp-standard","motion-reduce:transition-none","data-starting-style:h-0 data-ending-style:h-0"].join(" "),b={xs:"pb-2.5",sm:"pb-3",md:"pb-4",lg:"pb-5",xl:"pb-6"};export const MPCollapsible=t.forwardRef(function({open:t,defaultOpen:g=!1,onOpenChange:v,title:N,subtitle:j,startIcon:w,action:y,trigger:k,indicator:M=!0,disabled:O=!1,padded:z=!0,variant:C="outlined",size:P="md",hiddenUntilFound:$=!1,keepMounted:B=!1,className:F,children:I,...R},T){const U=p[P],L=u[P];return n(a.Root,{ref:T,open:t,defaultOpen:g,onOpenChange:e=>v?.(e),disabled:O,"data-mp-size":P,"data-mp-variant":C,className:["mp-collapsible rounded-mp-md flex w-full flex-col overflow-hidden",h[C],"text-mp-on-surface",F??""].filter(Boolean).join(" "),...R,children:[k?e(a.Trigger,{render:k}):n("div",{className:"flex w-full items-center",children:[n(a.Trigger,{className:["group relative flex min-w-0 flex-1 cursor-pointer items-center text-start","appearance-none border-0 bg-transparent font-[inherit] text-inherit",U,L,s[P],"outline-mp-secondary focus-visible:outline-2 focus-visible:-outline-offset-2","focus-visible:outline-solid outline-none","disabled:text-mp-on-surface/38 disabled:cursor-default"].join(" "),children:[e(o,{}),c(w)?e("span",{className:"text-mp-on-surface-variant flex h-[1lh] shrink-0 items-center",children:w}):null,n("span",{className:"flex min-w-0 flex-1 flex-col",children:[c(N)?e("span",{className:`truncate ${f[P]}`,children:N}):null,c(j)?e("span",{className:`text-mp-on-surface-variant truncate ${d}`,children:j}):null]}),M?e("span",{className:["text-mp-on-surface-variant flex h-[1lh] shrink-0 items-center","transition-[rotate] duration-(--mp-sys-motion-duration-short4)","ease-mp-standard motion-reduce:transition-none","group-data-panel-open:rotate-180"].join(" "),children:e(i,{icon:r,size:l[P]})}):null]}),c(y)?e("span",{className:`flex shrink-0 items-center ${U}`,children:y}):null]}),e(a.Panel,{hiddenUntilFound:$,keepMounted:B,className:x,children:e("div",{className:["min-w-0",m[P],"text-mp-on-surface-variant",z?U:"",z?k?L:b[P]:""].filter(Boolean).join(" "),children:I})})]})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{MPCollapsible}from"./MPCollapsible";
|