material-plus-ui 1.3.1 → 1.4.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 +2 -2
- package/dist/components/alert/MPAlert.d.ts +26 -0
- package/dist/components/alert/MPAlert.js +1 -1
- package/dist/components/alert/index.d.ts +1 -1
- package/dist/components/animate-marquee/MPAnimateMarquee.js +1 -1
- package/dist/components/avatar/MPAvatar.js +1 -1
- package/dist/components/avatar-group/MPAvatarGroup.d.ts +74 -0
- package/dist/components/avatar-group/MPAvatarGroup.js +2 -0
- package/dist/components/avatar-group/index.d.ts +2 -0
- package/dist/components/avatar-group/index.js +1 -0
- package/dist/components/breadcrumb/MPBreadcrumb.d.ts +10 -4
- package/dist/components/breadcrumb/MPBreadcrumb.js +1 -1
- package/dist/components/button/MPButton.js +1 -1
- package/dist/components/button-group/MPButtonGroup.d.ts +9 -0
- package/dist/components/button-group/MPButtonGroup.js +1 -1
- package/dist/components/carousel/MPCarousel.d.ts +12 -7
- package/dist/components/carousel/MPCarousel.js +1 -1
- package/dist/components/chat-bubble/MPChatBubble.d.ts +15 -2
- package/dist/components/chat-bubble/MPChatBubble.js +1 -1
- package/dist/components/color-picker/MPColorPicker.d.ts +20 -17
- package/dist/components/color-picker/MPColorPicker.js +1 -1
- package/dist/components/combobox/MPCombobox.d.ts +22 -4
- package/dist/components/combobox/MPCombobox.js +1 -1
- package/dist/components/command-palette/MPCommandPalette.d.ts +132 -0
- package/dist/components/command-palette/MPCommandPalette.js +2 -0
- package/dist/components/command-palette/index.d.ts +2 -0
- package/dist/components/command-palette/index.js +1 -0
- package/dist/components/container/MPContainer.js +1 -1
- package/dist/components/date-time-picker/MPDateTimePicker.d.ts +5 -0
- package/dist/components/dialog/MPDialog.js +1 -1
- package/dist/components/divider/MPDivider.js +1 -1
- package/dist/components/drawer/MPDrawer.js +1 -1
- package/dist/components/fieldset/MPFieldset.d.ts +52 -0
- package/dist/components/fieldset/MPFieldset.js +2 -0
- package/dist/components/fieldset/index.d.ts +2 -0
- package/dist/components/fieldset/index.js +1 -0
- package/dist/components/file-picker/MPFilePicker.d.ts +4 -3
- package/dist/components/file-picker/MPFilePicker.js +1 -1
- package/dist/components/floating-action-button/MPFloatingActionButton.js +1 -1
- package/dist/components/footer/MPFooter.d.ts +94 -0
- package/dist/components/footer/MPFooter.js +2 -0
- package/dist/components/footer/index.d.ts +2 -0
- package/dist/components/footer/index.js +1 -0
- package/dist/components/form/MPForm.d.ts +73 -0
- package/dist/components/form/MPForm.js +2 -0
- package/dist/components/form/index.d.ts +2 -0
- package/dist/components/form/index.js +1 -0
- package/dist/components/header/MPHeader.d.ts +122 -0
- package/dist/components/header/MPHeader.js +2 -0
- package/dist/components/header/index.d.ts +2 -0
- package/dist/components/header/index.js +1 -0
- package/dist/components/highlight/MPHighlight.d.ts +7 -0
- package/dist/components/menu/MPMenu.js +1 -1
- package/dist/components/menubar/MPMenubar.d.ts +82 -0
- package/dist/components/menubar/MPMenubar.js +2 -0
- package/dist/components/menubar/index.d.ts +2 -0
- package/dist/components/menubar/index.js +1 -0
- package/dist/components/navigation-menu/MPNavigationMenu.d.ts +151 -0
- package/dist/components/navigation-menu/MPNavigationMenu.js +2 -0
- package/dist/components/navigation-menu/index.d.ts +2 -0
- package/dist/components/navigation-menu/index.js +1 -0
- package/dist/components/number-field/MPNumberField.d.ts +12 -3
- package/dist/components/number-field/MPNumberField.js +1 -1
- package/dist/components/overlay/MPOverlay.d.ts +8 -2
- package/dist/components/overlay/MPOverlay.js +1 -1
- package/dist/components/page-layout/MPPageLayout.d.ts +145 -0
- package/dist/components/page-layout/MPPageLayout.js +2 -0
- package/dist/components/page-layout/index.d.ts +2 -0
- package/dist/components/page-layout/index.js +1 -0
- package/dist/components/panes/MPPanes.js +1 -1
- package/dist/components/popover/MPPopover.js +1 -1
- package/dist/components/progress-box/MPProgressBox.js +1 -1
- package/dist/components/progress-circular/MPProgressCircular.js +1 -1
- package/dist/components/progress-linear/MPProgressLinear.js +1 -1
- package/dist/components/radio-group/MPRadioGroup.js +1 -1
- package/dist/components/segmented-button/MPSegmentedButton.js +1 -1
- package/dist/components/select/MPSelect.d.ts +12 -1
- package/dist/components/select/MPSelect.js +1 -1
- package/dist/components/shortcut/MPShortcut.js +1 -1
- package/dist/components/sidebar/MPSidebar.d.ts +160 -0
- package/dist/components/sidebar/MPSidebar.js +2 -0
- package/dist/components/sidebar/MPSidebarTrigger.d.ts +45 -0
- package/dist/components/sidebar/MPSidebarTrigger.js +2 -0
- package/dist/components/sidebar/index.d.ts +4 -0
- package/dist/components/sidebar/index.js +1 -0
- package/dist/components/skeleton/MPSkeleton.js +1 -1
- package/dist/components/slider/MPSlider.js +1 -1
- package/dist/components/snackbar/MPSnackbar.js +1 -1
- package/dist/components/switch/MPSwitch.js +1 -1
- package/dist/components/table/MPTable.d.ts +27 -5
- package/dist/components/table/MPTable.js +1 -1
- package/dist/components/text-field/MPTextField.d.ts +13 -2
- package/dist/components/text-field/MPTextField.js +1 -1
- package/dist/components/text-link/MPTextLink.d.ts +7 -1
- package/dist/components/text-link/MPTextLink.js +1 -1
- package/dist/components/time-picker/MPTimePicker.d.ts +4 -0
- package/dist/components/toggle/MPToggle.d.ts +72 -0
- package/dist/components/toggle/MPToggle.js +2 -0
- package/dist/components/toggle/index.d.ts +2 -0
- package/dist/components/toggle/index.js +1 -0
- package/dist/components/toggle-group/MPToggleGroup.d.ts +74 -0
- package/dist/components/toggle-group/MPToggleGroup.js +2 -0
- package/dist/components/toggle-group/index.d.ts +2 -0
- package/dist/components/toggle-group/index.js +1 -0
- package/dist/components/tooltip/MPTooltip.js +1 -1
- package/dist/components/transfer/MPTransfer.d.ts +98 -0
- package/dist/components/transfer/MPTransfer.js +2 -0
- package/dist/components/transfer/index.d.ts +2 -0
- package/dist/components/transfer/index.js +1 -0
- package/dist/constants/glyphs.d.ts +10 -0
- package/dist/constants/glyphs.js +1 -1
- package/dist/constants/icons.d.ts +1 -0
- package/dist/constants/icons.js +1 -1
- package/dist/index.d.ts +13 -0
- package/dist/index.js +1 -1
- package/dist/internal/Calendar.js +1 -1
- package/dist/internal/FieldOutline.js +1 -1
- package/dist/internal/SupportingText.d.ts +1 -1
- package/dist/internal/SupportingText.js +1 -1
- package/dist/internal/animate.d.ts +0 -17
- package/dist/internal/animate.js +1 -1
- package/dist/internal/avatar-group.d.ts +22 -0
- package/dist/internal/avatar-group.js +2 -0
- package/dist/internal/button-group.d.ts +20 -1
- package/dist/internal/button-group.js +1 -1
- package/dist/internal/color.d.ts +0 -5
- package/dist/internal/color.js +1 -1
- package/dist/internal/date.js +1 -1
- package/dist/internal/i18n.d.ts +201 -4
- package/dist/internal/keys.d.ts +72 -0
- package/dist/internal/keys.js +2 -0
- package/dist/internal/length.d.ts +42 -0
- package/dist/internal/length.js +1 -0
- package/dist/internal/link.d.ts +44 -0
- package/dist/internal/link.js +1 -0
- package/dist/internal/locale.d.ts +20 -1
- package/dist/internal/locale.js +1 -1
- package/dist/internal/messages/breadcrumb.d.ts +3 -0
- package/dist/internal/messages/breadcrumb.js +1 -0
- package/dist/internal/messages/carousel.d.ts +3 -0
- package/dist/internal/messages/carousel.js +1 -0
- package/dist/internal/messages/color-picker.d.ts +3 -0
- package/dist/internal/messages/color-picker.js +1 -0
- package/dist/internal/messages/combobox.d.ts +3 -0
- package/dist/internal/messages/combobox.js +1 -0
- package/dist/internal/messages/command.d.ts +3 -0
- package/dist/internal/messages/command.js +1 -0
- package/dist/internal/messages/file-picker.d.ts +3 -0
- package/dist/internal/messages/file-picker.js +1 -0
- package/dist/internal/messages/layout.d.ts +3 -0
- package/dist/internal/messages/layout.js +1 -0
- package/dist/internal/messages/number-field.d.ts +3 -0
- package/dist/internal/messages/number-field.js +1 -0
- package/dist/internal/messages/overlay.d.ts +3 -0
- package/dist/internal/messages/overlay.js +1 -0
- package/dist/internal/messages/table.d.ts +3 -0
- package/dist/internal/messages/table.js +1 -0
- package/dist/internal/messages/text-link.d.ts +3 -0
- package/dist/internal/messages/text-link.js +1 -0
- package/dist/internal/messages/transfer.d.ts +3 -0
- package/dist/internal/messages/transfer.js +1 -0
- package/dist/internal/page-layout.d.ts +182 -0
- package/dist/internal/page-layout.js +2 -0
- package/dist/internal/scale.d.ts +17 -0
- package/dist/internal/scale.js +1 -1
- package/dist/locales/ar.js +1 -1
- package/dist/locales/de.js +1 -1
- package/dist/locales/es.js +1 -1
- package/dist/locales/fr.js +1 -1
- package/dist/locales/hi.js +1 -1
- package/dist/locales/id.js +1 -1
- package/dist/locales/it.js +1 -1
- package/dist/locales/ja.js +1 -1
- package/dist/locales/ko.js +1 -1
- package/dist/locales/nl.js +1 -1
- package/dist/locales/pl.js +1 -1
- package/dist/locales/pt.js +1 -1
- package/dist/locales/ru.js +1 -1
- package/dist/locales/th.js +1 -1
- package/dist/locales/tr.js +1 -1
- package/dist/locales/vi.js +1 -1
- package/dist/locales/zh-hans.js +1 -1
- package/dist/locales/zh-hant.js +1 -1
- package/dist/styles/accordion.css +1 -1
- package/dist/styles/alert.css +1 -1
- package/dist/styles/avatar-group.css +2 -0
- package/dist/styles/avatar.css +1 -1
- package/dist/styles/badge.css +1 -1
- package/dist/styles/blockquote.css +1 -1
- package/dist/styles/bottom-navigation.css +1 -1
- package/dist/styles/box.css +1 -1
- package/dist/styles/breadcrumb.css +1 -1
- package/dist/styles/button-group.css +1 -1
- package/dist/styles/button.css +1 -1
- package/dist/styles/card.css +1 -1
- package/dist/styles/carousel.css +1 -1
- package/dist/styles/chat-bubble.css +1 -1
- package/dist/styles/checkbox.css +1 -1
- package/dist/styles/chip.css +1 -1
- package/dist/styles/collapsible.css +1 -1
- package/dist/styles/color-picker.css +1 -1
- package/dist/styles/combobox.css +1 -1
- package/dist/styles/command-palette.css +2 -0
- package/dist/styles/date-picker.css +1 -1
- package/dist/styles/date-range-picker.css +1 -1
- package/dist/styles/date-time-picker.css +1 -1
- package/dist/styles/dialog.css +1 -1
- package/dist/styles/divider.css +1 -1
- package/dist/styles/drawer.css +1 -1
- package/dist/styles/empty.css +1 -1
- package/dist/styles/fieldset.css +2 -0
- package/dist/styles/file-picker.css +1 -1
- package/dist/styles/floating-action-button.css +1 -1
- package/dist/styles/footer.css +2 -0
- package/dist/styles/form.css +2 -0
- package/dist/styles/header.css +2 -0
- package/dist/styles/highlight.css +1 -1
- package/dist/styles/icon-button.css +1 -1
- package/dist/styles/list.css +1 -1
- package/dist/styles/locale.css +1 -1
- package/dist/styles/menu.css +1 -1
- package/dist/styles/menubar.css +2 -0
- package/dist/styles/navigation-menu.css +2 -0
- package/dist/styles/number-field.css +1 -1
- package/dist/styles/otp-field.css +1 -1
- package/dist/styles/overlay.css +1 -1
- package/dist/styles/page-layout.css +2 -0
- package/dist/styles/pagination.css +1 -1
- package/dist/styles/panes.css +1 -1
- package/dist/styles/pill.css +1 -1
- package/dist/styles/popover.css +1 -1
- package/dist/styles/progress-box.css +1 -1
- package/dist/styles/progress-circular.css +1 -1
- package/dist/styles/progress-linear.css +1 -1
- package/dist/styles/radio-group.css +1 -1
- package/dist/styles/segmented-button.css +1 -1
- package/dist/styles/select.css +1 -1
- package/dist/styles/sidebar.css +2 -0
- package/dist/styles/skeleton.css +1 -1
- package/dist/styles/slider.css +1 -1
- package/dist/styles/spoiler.css +1 -1
- package/dist/styles/switch.css +1 -1
- package/dist/styles/table.css +1 -1
- package/dist/styles/tabs.css +1 -1
- package/dist/styles/text-field.css +1 -1
- package/dist/styles/text-link.css +1 -1
- package/dist/styles/time-picker.css +1 -1
- package/dist/styles/timeline.css +1 -1
- package/dist/styles/toggle-group.css +2 -0
- package/dist/styles/toggle.css +2 -0
- package/dist/styles/transfer.css +2 -0
- package/dist/styles.css +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ It follows the specification directly rather than wrapping somebody's implementa
|
|
|
23
23
|
- **IME-safe by construction.** Korean, Japanese and Chinese composition survives whatever your `onChange` does with the value.
|
|
24
24
|
- **Bring your own icons.** `MPIcon` takes a component or an element from any set. `lucide-react` ships with the package, gathered in one readable constants file.
|
|
25
25
|
- **Works in a Next.js server component**, and in any bundler: the components carry `"use client"`, the barrel and the data do not, and every specifier in `dist/` names a file — so webpack, Vite, esbuild, Rollup and plain Node all resolve it.
|
|
26
|
-
- **ESM only**, TypeScript declarations included, and tree-shakeable for real: one component is 2.9 kB gzipped and five are 7.3 kB, against
|
|
26
|
+
- **ESM only**, TypeScript declarations included, and tree-shakeable for real: one component is 2.9 kB gzipped and five are 7.3 kB, against 74 kB for all hundred and eleven. `npm run measure` prints those numbers off a real bundler, so they cannot quietly stop being true. The stylesheet splits the same way.
|
|
27
27
|
- **One runtime dependency.** React 18 or 19, Node.js 22 or later.
|
|
28
28
|
|
|
29
29
|
## Documentation
|
|
@@ -74,7 +74,7 @@ If Tailwind v4 is already in your project, import the token sheet instead:
|
|
|
74
74
|
@import 'material-plus-ui/tailwind.css';
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
-
A page that renders a handful of components can take the tokens and a sheet each instead of the whole
|
|
77
|
+
A page that renders a handful of components can take the tokens and a sheet each instead of the whole 113 kB — 4.5 kB gzipped for one component against 16.1 kB for the lot. [The guide](https://material-plus.cdget.com/guide/getting-started#if-you-only-render-a-few-components) has the numbers and where the two paths cross.
|
|
78
78
|
|
|
79
79
|
```ts
|
|
80
80
|
import 'material-plus-ui/styles/tokens.css';
|
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import type { MPColor, MPSize, MPVariant } from '../../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* How loudly an alert announces itself.
|
|
5
|
+
*
|
|
6
|
+
* - `assertive` — interrupts whatever a screen reader is in the middle of
|
|
7
|
+
* saying. `role="alert"`.
|
|
8
|
+
* - `polite` — waits for a pause. `role="status"`.
|
|
9
|
+
* - `off` — announces nothing, and is read only by somebody who walks into it.
|
|
10
|
+
*
|
|
11
|
+
* The third is the one worth knowing about. A live region is for content that
|
|
12
|
+
* *arrives*, and an alert that was on the page when it loaded did not arrive —
|
|
13
|
+
* it is part of the page, and interrupting to read it is interrupting to say
|
|
14
|
+
* something the reader was going to reach anyway. A form's list of errors on a
|
|
15
|
+
* server-rendered page is exactly that case.
|
|
16
|
+
*/
|
|
17
|
+
export type MPAlertLive = 'assertive' | 'polite' | 'off';
|
|
3
18
|
export interface MPAlertProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'color' | 'title'> {
|
|
4
19
|
/**
|
|
5
20
|
* How much surface the alert paints.
|
|
@@ -50,6 +65,17 @@ export interface MPAlertProps extends Omit<React.ComponentPropsWithoutRef<'div'>
|
|
|
50
65
|
* `children` so it stays on the first line while the message wraps.
|
|
51
66
|
*/
|
|
52
67
|
action?: React.ReactNode;
|
|
68
|
+
/**
|
|
69
|
+
* How loudly it announces itself.
|
|
70
|
+
*
|
|
71
|
+
* Defaults to `assertive` for the `error` family and `polite` for the other
|
|
72
|
+
* three, which is the right split for a message that *appeared*. Reach for
|
|
73
|
+
* `off` when the alert was on the page before the reader was: an error summary
|
|
74
|
+
* rendered by the server is not news, and a screen reader interrupting itself
|
|
75
|
+
* to read it is interrupting to say something the reader was about to reach on
|
|
76
|
+
* their own.
|
|
77
|
+
*/
|
|
78
|
+
live?: MPAlertLive;
|
|
53
79
|
/** Passing it is what makes the dismiss button appear. */
|
|
54
80
|
onClose?: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
|
55
81
|
/**
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as n from"react";import{MPIcon as r}from"../icon/MPIcon.js";import{CloseIcon as
|
|
2
|
+
import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as n from"react";import{MPIcon as r}from"../icon/MPIcon.js";import{CloseIcon as l,ErrorIcon as i,InfoIcon as o}from"../../constants/icons.js";import{accentSlots as a}from"../../internal/accent.js";import{useMPLocale as s,useMPMessages as c}from"../../internal/locale.js";import{ALERT as m}from"../../internal/messages/alert.js";import{MPStateLayer as p}from"../../internal/StateLayer.js";import{CONTROL_ICON as f,hasContent as d,PROSE_TEXT as u,SHEET_GAP as x,SHEET_PAD as v,SHEET_TITLE as h,STACK_GAP as b}from"../../internal/scale.js";const j={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 border bg-transparent text-mp-on-surface",text:"bg-transparent text-mp-on-surface"},y={filled:"",tonal:"",elevated:"text-(--_mp-accent)",outlined:"text-(--_mp-accent)",text:"text-(--_mp-accent)"},N={filled:"",tonal:"",elevated:"text-mp-on-surface-variant",outlined:"text-mp-on-surface-variant",text:"text-mp-on-surface-variant"},g={primary:"polite",secondary:"polite",tertiary:"polite",error:"assertive"},_={assertive:"alert",polite:"status",off:void 0};export const MPAlert=/*@__PURE__*/n.forwardRef(function({variant:n="tonal",color:w="primary",size:z="md",title:k,icon:B,action:C,live:L,onClose:M,closeLabel:P,locale:A,className:I,style:R,children:S,...$},q){const D=s(A),E=c(m,D),F=y[n],G=d(k),H=void 0===B?e(r,{icon:"error"===w?i:o,size:f[z]}):B;return t("div",{ref:q,role:_[L??g[w]],"data-mp-size":z,"data-mp-variant":n,className:["mp-alert rounded-mp-md flex w-full items-start","box-border",v[z],x[z],u[z],j[n],I??""].filter(Boolean).join(" "),style:{...a(w),...R},...$,children:[d(H)?e("span",{className:["flex h-[1lh] shrink-0 items-center",F].filter(Boolean).join(" "),children:H}):null,t("div",{className:`flex min-w-0 flex-1 flex-col ${b[z]}`,children:[G?e("div",{className:[h[z],F].filter(Boolean).join(" "),children:k}):null,d(S)?e("div",{className:G?N[n]:void 0,children:S}):null]}),d(C)?e("div",{className:"flex h-[1lh] shrink-0 items-center",children:C}):null,M?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:t("button",{type:"button","aria-label":P??E.dismiss,onClick:M,className:["group rounded-mp-full relative -m-1 flex size-8 cursor-pointer items-center","justify-center bg-transparent text-inherit","outline-mp-secondary focus-visible:outline-2 focus-visible:outline-offset-2","focus-visible:outline-solid outline-none"].join(" "),children:[e(p,{}),e(r,{icon:l,size:f[z]})]})}):null]})});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { MPAlert } from './MPAlert.js';
|
|
2
|
-
export type { MPAlertProps } from './MPAlert.js';
|
|
2
|
+
export type { MPAlertLive, MPAlertProps } from './MPAlert.js';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import{jsx as e}from"react/jsx-runtime";import*as r from"react";import{easingValue as t,isInfinite as a,lengthValue as n,repeatValue as i,useAnimationRun as o}from"../../internal/animate.js";export const MPAnimateMarquee=/*@__PURE__*/r.forwardRef(function({duration:
|
|
2
|
+
import{jsx as e}from"react/jsx-runtime";import*as r from"react";import{easingValue as t,isInfinite as a,lengthValue as n,repeatValue as i,useAnimationRun as o}from"../../internal/animate.js";import{inertProps as s}from"../../internal/inert.js";export const MPAnimateMarquee=/*@__PURE__*/r.forwardRef(function({duration:m,delay:p=0,easing:l,repeat:u="infinite",alternate:c,paused:d,trigger:f="mount",play:h,once:v=!0,threshold:g=.2,orientation:y="horizontal",reverse:_=!1,speed:j=60,gap:q="2rem",copies:R=2,pauseOnHover:b=!0,className:x,style:M,children:w,...z},N){const O=o({trigger:f,play:h,once:v,threshold:g,paused:d,infinite:a(u)}),A=r.useRef(null),G=r.useRef(null),[H,S]=r.useState(0),$="vertical"===y;r.useEffect(()=>{const e=A.current,r=G.current;if(!e||!r)return;const t=()=>{const t=getComputedStyle(e),a=parseFloat($?t.rowGap:t.columnGap)||0,n=$?r.offsetHeight:r.offsetWidth;S(n+a)};if(t(),"undefined"==typeof ResizeObserver)return;const a=new ResizeObserver(t);return a.observe(r),a.observe(e),()=>a.disconnect()},[$,w]);const k=m??(H>0?H/j*1e3:12e3);return e("div",{ref:e=>{A.current=e,O.ref(e),"function"==typeof N?N(e):N&&(N.current=e)},className:["mp-marquee",$?"mp-marquee-vertical":"",x??""].filter(Boolean).join(" "),style:{"--_mp-anim-gap":n(q),...l?{"--_mp-anim-ease":t(l)}:{},"--_mp-anim-duration":`${Math.round(k)}ms`,"--_mp-anim-delay":`${p}ms`,"--_mp-anim-repeat":i(u),"--_mp-anim-direction":_?c?"alternate-reverse":"reverse":c?"alternate":"normal","--_mp-anim-state":O.state,...M},"data-mp-animation":"marquee","data-mp-state":O.state,"data-mp-pause-on-hover":b?"":void 0,...O.handlers,...z,children:Array.from({length:Math.max(1,R)},(r,t)=>(r=>e("div",{ref:0===r?G:void 0,className:"mp-marquee-track","aria-hidden":0===r?void 0:"true",...s(0!==r),children:w},r))(t))})});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import{jsx as e,jsxs as a}from"react/jsx-runtime";import*as t from"react";import{Avatar as n}from"@base-ui/react/avatar";import{accentSlots as r}from"../../internal/accent.js";import{CONTROL_SQUARE as
|
|
2
|
+
import{jsx as e,jsxs as a}from"react/jsx-runtime";import*as t from"react";import{Avatar as n}from"@base-ui/react/avatar";import{accentSlots as r}from"../../internal/accent.js";import{MPAvatarGroupContext as l}from"../../internal/avatar-group.js";import{CONTROL_SQUARE as i,hasContent as o}from"../../internal/scale.js";import{VISUALLY_HIDDEN as s}from"../../internal/visually-hidden.js";const m={xs:"text-mp-label-medium",sm:"text-mp-label-large",md:"text-mp-title-large",lg:"text-mp-headline-small",xl:"text-mp-headline-medium"},c={xs:"rounded-mp-xs",sm:"rounded-mp-sm",md:"rounded-mp-md",lg:"rounded-mp-md",xl:"rounded-mp-md"},d={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-transparent text-(--_mp-accent)",text:"text-mp-on-surface-variant bg-transparent"};function p(){return a("svg",{viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":"true",className:"size-[60%]",children:[e("path",{d:"M12 12a4.5 4.5 0 1 0 0-9 4.5 4.5 0 0 0 0 9Z"}),e("path",{d:"M12 14.25c-4.28 0-7.75 2.42-7.75 5.4 0 .75.6 1.35 1.35 1.35h12.8c.75 0 1.35-.6 1.35-1.35 0-2.98-3.47-5.4-7.75-5.4Z"})]})}export const MPAvatar=/*@__PURE__*/t.forwardRef(function({src:u,srcSet:f,alt:h,name:x,initials:g,shape:v,variant:b,size:j,color:y,delay:N,imageProps:w,onLoadingStatusChange:z,className:C,style:_,children:A,...B},S){const L=t.useContext(l),M=v??L?.shape??"circle",k=b??L?.variant??"tonal",F=j??L?.size??"md",P=y??L?.color??"primary",R=x?function(e){const a=e.normalize("NFC").trim().split(/\s+/).filter(Boolean);return 0===a.length?"":((Array.from(a[0])[0]??"")+(a.length>1?Array.from(a[a.length-1])[0]??"":"")).toLocaleUpperCase()}(x):"",Z=h??x,I=o(A)?A:(g??R)||e(p,{}),U=o(A)||Boolean(g??R),q=["mp-avatar relative inline-flex shrink-0 items-center justify-center overflow-hidden","align-middle leading-none font-medium whitespace-nowrap select-none",i[F],m[F],"circle"===M?"rounded-mp-full":c[F],d[k],C??""].filter(Boolean).join(" ");return a(n.Root,{ref:S,"data-mp-size":F,"data-mp-variant":k,className:q,style:{...r(P),..._},...B,children:[u?e(n.Image,{src:u,srcSet:f,alt:Z??"",onLoadingStatusChange:z,...w,className:"size-full object-cover"}):null,a(n.Fallback,{delay:u?N:void 0,className:"flex size-full items-center justify-center",children:[Z&&U?e("span",{className:s,children:Z}):null,e("span",{"aria-hidden":!(!Z||!U)||void 0,className:"contents",children:I})]})]})});
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type MPAvatarShape } from '../avatar/MPAvatar.js';
|
|
3
|
+
import type { MPColor, MPSize, MPVariant } from '../../types.js';
|
|
4
|
+
export interface MPAvatarGroupProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'color'> {
|
|
5
|
+
/**
|
|
6
|
+
* How many avatars are drawn before the rest become a count. Left out, every
|
|
7
|
+
* one of them is drawn.
|
|
8
|
+
*/
|
|
9
|
+
max?: number;
|
|
10
|
+
/**
|
|
11
|
+
* How many there are altogether, when the group was handed only the first few.
|
|
12
|
+
*
|
|
13
|
+
* Without it the count is worked out from the children, which is right only
|
|
14
|
+
* when all of them were passed — and a list of forty faces that ships four
|
|
15
|
+
* `<img>`s and a number is exactly why this prop exists.
|
|
16
|
+
*/
|
|
17
|
+
total?: number;
|
|
18
|
+
/**
|
|
19
|
+
* How far each avatar sits under the one before it — a number in pixels, or
|
|
20
|
+
* any CSS length. Left out it is a fraction of `size`, which keeps the overlap
|
|
21
|
+
* looking the same at every rung.
|
|
22
|
+
*/
|
|
23
|
+
overlap?: number | string;
|
|
24
|
+
/**
|
|
25
|
+
* Passed to every avatar in the group.
|
|
26
|
+
* @default 'md'
|
|
27
|
+
*/
|
|
28
|
+
size?: MPSize;
|
|
29
|
+
/**
|
|
30
|
+
* Passed to every avatar in the group.
|
|
31
|
+
* @default 'circle'
|
|
32
|
+
*/
|
|
33
|
+
shape?: MPAvatarShape;
|
|
34
|
+
/**
|
|
35
|
+
* Passed to every avatar in the group.
|
|
36
|
+
* @default 'tonal'
|
|
37
|
+
*/
|
|
38
|
+
variant?: MPVariant;
|
|
39
|
+
/**
|
|
40
|
+
* Passed to every avatar in the group.
|
|
41
|
+
* @default 'primary'
|
|
42
|
+
*/
|
|
43
|
+
color?: MPColor;
|
|
44
|
+
/** The avatars. */
|
|
45
|
+
children?: React.ReactNode;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* A stack of avatars, overlapping, with the ones that did not fit as a count.
|
|
49
|
+
*
|
|
50
|
+
* `size`, `shape`, `variant` and `color` are set once here rather than on every
|
|
51
|
+
* avatar — a stack whose fourth face is a rung out is not a stack — and an
|
|
52
|
+
* avatar's own prop still wins, which is what lets one of them be marked out
|
|
53
|
+
* from the rest.
|
|
54
|
+
*
|
|
55
|
+
* ## The ring is not decoration
|
|
56
|
+
*
|
|
57
|
+
* Two circles of similar tone laid over each other have no edge between them at
|
|
58
|
+
* all, and the stack reads as one smeared shape. The ring is drawn in the page's
|
|
59
|
+
* own `surface`, so it is the background showing through rather than a colour of
|
|
60
|
+
* its own — which is what puts the near avatar in front instead of putting a
|
|
61
|
+
* white line on it.
|
|
62
|
+
*
|
|
63
|
+
* `isolate` on the group is the other half: it makes the first avatar's ring
|
|
64
|
+
* paint against the page rather than against whatever the group happens to be
|
|
65
|
+
* stacked over.
|
|
66
|
+
*
|
|
67
|
+
* ## The first avatar is on top
|
|
68
|
+
*
|
|
69
|
+
* The order is the DOM order, and each avatar is drawn under the one before it.
|
|
70
|
+
* A stack read from the start is therefore read front to back, so the person the
|
|
71
|
+
* group is *about* comes first rather than last — and under RTL the whole thing
|
|
72
|
+
* flips on its own, because the overlap is a logical margin.
|
|
73
|
+
*/
|
|
74
|
+
export declare const MPAvatarGroup: React.ForwardRefExoticComponent<MPAvatarGroupProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import{jsx as r,jsxs as a}from"react/jsx-runtime";import*as e from"react";import{MPAvatar as t}from"../avatar/MPAvatar.js";import{MPAvatarGroupContext as i}from"../../internal/avatar-group.js";const o={xs:"0.625rem",sm:"0.75rem",md:"1.125rem",lg:"1.25rem",xl:"1.5rem"};export const MPAvatarGroup=/*@__PURE__*/e.forwardRef(function({max:l,total:m,overlap:n,size:s="md",shape:c="circle",variant:p="tonal",color:v="primary",className:d,style:f,children:h,...u},x){const g=e.useMemo(()=>({size:s,shape:c,variant:p,color:v}),[s,c,p,v]),j=e.Children.toArray(h),y=void 0===l?j:j.slice(0,Math.max(0,l)),M=m??j.length,z=Math.max(0,M-y.length);return r(i.Provider,{value:g,children:a("div",{ref:x,"data-mp-size":s,className:["mp-avatar-group isolate inline-flex items-center align-middle","[&>*:not(:first-child)]:[margin-inline-start:calc(var(--_mp-avatar-overlap)*-1)]","ring-mp-surface [&>*]:ring-2",d??""].filter(Boolean).join(" "),style:{"--_mp-avatar-overlap":void 0===n?o[s]:"number"==typeof n?`${n}px`:n,...f},...u,children:[y,z>0?r(t,{initials:`+${z}`}):null]})})});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{MPAvatarGroup}from"./MPAvatarGroup.js";
|
|
@@ -45,15 +45,21 @@ export interface MPBreadcrumbProps extends Omit<React.ComponentPropsWithoutRef<'
|
|
|
45
45
|
*/
|
|
46
46
|
expandable?: boolean;
|
|
47
47
|
/**
|
|
48
|
-
* The name the trail is announced by.
|
|
49
|
-
* @default 'Breadcrumb'
|
|
48
|
+
* The name the trail is announced by. Defaults to the word for it in `locale`.
|
|
50
49
|
*/
|
|
51
50
|
label?: string;
|
|
52
51
|
/**
|
|
53
|
-
* What the `…` is announced as.
|
|
54
|
-
* @default 'Show hidden steps'
|
|
52
|
+
* What the `…` is announced as. Defaults to the wording in `locale`.
|
|
55
53
|
*/
|
|
56
54
|
expandLabel?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Which language those two are written in. Falls back to the nearest
|
|
57
|
+
* `MPLocaleProvider`, then to English.
|
|
58
|
+
*
|
|
59
|
+
* Neither is ever drawn — the steps are the caller's own words — so without it
|
|
60
|
+
* a Korean page announces its trail in English.
|
|
61
|
+
*/
|
|
62
|
+
locale?: string;
|
|
57
63
|
/**
|
|
58
64
|
* Publishes the trail as schema.org `BreadcrumbList` microdata, which is what
|
|
59
65
|
* a search engine reads to draw the trail under a result instead of the bare
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import{jsx as e,jsxs as n,Fragment as t}from"react/jsx-runtime";import*as r from"react";import{MPIcon as o}from"../icon/MPIcon.js";import{ArrowRightIcon as i,ChevronRightIcon as a,MoreIcon as s}from"../../constants/icons.js";import{accentSlots as l}from"../../internal/accent.js";import{
|
|
2
|
+
import{jsx as e,jsxs as n,Fragment as t}from"react/jsx-runtime";import*as r from"react";import{MPIcon as o}from"../icon/MPIcon.js";import{ArrowRightIcon as i,ChevronRightIcon as a,MoreIcon as s}from"../../constants/icons.js";import{accentSlots as l}from"../../internal/accent.js";import{useMPLocale as c,useMPMessages as m}from"../../internal/locale.js";import{BREADCRUMB as d}from"../../internal/messages/breadcrumb.js";import{CONTROL_GAP as u,hasContent as p,PROSE_TEXT as h}from"../../internal/scale.js";const f=/*@__PURE__*/r.createContext({size:"md",last:!1,position:null}),x={xs:"gap-1",sm:"gap-1.5",md:"gap-2",lg:"gap-2.5",xl:"gap-3"},b={xs:"rounded-mp-xs",sm:"rounded-mp-xs",md:"rounded-mp-xs",lg:"rounded-mp-sm",xl:"rounded-mp-sm"};const v=["chevron","arrow","slash","dot"];export const MPBreadcrumb=/*@__PURE__*/r.forwardRef(function({size:t="md",color:u="primary",separator:p="chevron",maxItems:b,itemsBeforeCollapse:g=1,itemsAfterCollapse:N=1,expandable:j=!0,label:y,expandLabel:k,locale:z,structuredData:B=!1,className:C,style:w,children:P,...M},I){const L=m(d,c(z)),[S,_]=r.useState(!1),A=r.Children.toArray(P).filter(r.isValidElement),E=A.length,F=A.some(e=>!0===e.props.current),R=!S&&!B&&void 0!==b&&E>Math.max(b,1)&&E-g-N>1?[...A.slice(0,Math.max(0,g)),null,...A.slice(E-Math.max(0,N))]:A,T="string"==typeof(D=p)&&v.includes(D)?function(n){switch(n){case"chevron":return e(o,{icon:a,size:"1.1em",className:"rtl:rotate-180"});case"arrow":return e(o,{icon:i,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}}(p):p;var D;const V=r.useMemo(()=>Array.from({length:R.length},(e,n)=>({size:t,last:!F&&n===R.length-1,position:B?n+1:null})),[t,F,R.length,B]),$=["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)",j?["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:I,"aria-label":y??L.label,"data-mp-size":t,className:["mp-breadcrumb flex",h[t],C??""].filter(Boolean).join(" "),style:{...l(u),...w},...M,children:e("ol",{role:"list",itemScope:B||void 0,itemType:B?"https://schema.org/BreadcrumbList":void 0,className:`flex list-none flex-wrap items-center p-0 ${x[t]}`,children:R.map((t,i)=>n(r.Fragment,{children:[i>0?e("li",{"aria-hidden":"true",className:"text-mp-on-surface-variant flex shrink-0 items-center select-none",children:T}):null,t?e(f.Provider,{value:V[i],children:t}):e("li",{className:"flex shrink-0 items-center",children:j?e("button",{type:"button",className:$,"aria-label":k??L.expand,onClick:()=>_(!0),children:e(o,{icon:s,size:"1.1em"})}):e("span",{className:$,"aria-hidden":"true",children:e(o,{icon:s,size:"1.1em"})})})]},t?t.key??i:"fold"))})})});export const MPBreadcrumbItem=/*@__PURE__*/r.forwardRef(function({href:o,onClick:i,startIcon:a,endIcon:s,current:l,disabled:c=!1,className:m,children:d,...h},x){const{size:v,last:g,position:N}=r.useContext(f),j=l??g,y=Boolean(o||i)&&!j&&!c,k=null!==N,z=["inline-flex min-w-0 items-center px-1 no-underline","appearance-none border-0 bg-transparent font-[inherit] text-[inherit]",u[v],b[v],"transition-[background-color,color] duration-(--mp-sys-motion-duration-short4)",c?"text-mp-on-surface/38 cursor-default":j?"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(" "),B=n(t,{children:[p(a)?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:a}):null,e("span",{className:"truncate",itemProp:k?"name":void 0,children:d}),p(s)?e("span",{className:"flex h-[1lh] shrink-0 items-center",children:s}):null]});return n("li",{ref:x,itemProp:k?"itemListElement":void 0,itemScope:k||void 0,itemType:k?"https://schema.org/ListItem":void 0,className:["flex min-w-0 items-center",m??""].filter(Boolean).join(" "),...h,children:[k?e("meta",{itemProp:"position",content:String(N)}):null,y&&o?e("a",{href:o,itemProp:k?"item":void 0,className:z,onClick:i,children:B}):y?e("button",{type:"button",className:z,onClick:i,children:B}):e("span",{className:z,"aria-current":j?"page":void 0,"aria-disabled":c||void 0,children:B})]})});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import{jsx as e,jsxs as o}from"react/jsx-runtime";import*as t from"react";import{Button as n}from"@base-ui/react/button";import{MPIcon as r}from"../icon/MPIcon.js";import{SpinnerIcon as a}from"../../constants/icons.js";import{accentSlots as i}from"../../internal/accent.js";import{MPButtonGroupContext as s}from"../../internal/button-group.js";import{useMPLocale as l,useMPMessages as c}from"../../internal/locale.js";import{COMMON as m}from"../../internal/messages/common.js";import{MPStateLayer as p}from"../../internal/StateLayer.js";import{CONTROL_GAP as d,CONTROL_HEIGHT as u,CONTROL_ICON as f,CONTROL_PAD_X as b,CONTROL_SQUARE as g,CONTROL_TEXT as x,hasContent as v}from"../../internal/scale.js";const h={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)"},j={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=/*@__PURE__*/t.forwardRef(function({variant:w,size:y,color:_,disabled:k,startIcon:z,endIcon:B,loading:C=!1,loadingLabel:I,locale:N,fullWidth:P=!1,type:L="button",className:M,style:D,children:R,onClick:S,...W},$){const q=l(N),A=c(m,q),E=t.useContext(s),F=w??E?.variant??"filled",G=y??E?.size??"md",H=_??E?.color??"primary",J=k??E?.disabled??!1,K=!v(R);return o(n,{ref:$,type:L,disabled:J,"aria-busy":C||void 0,"aria-disabled":C||void 0,"data-mp-size":G,"data-mp-variant":F,"data-loading":C||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)",u[G],x[G],d[G],
|
|
2
|
+
import{jsx as e,jsxs as o}from"react/jsx-runtime";import*as t from"react";import{Button as n}from"@base-ui/react/button";import{MPIcon as r}from"../icon/MPIcon.js";import{SpinnerIcon as a}from"../../constants/icons.js";import{accentSlots as i}from"../../internal/accent.js";import{MPButtonGroupContext as s}from"../../internal/button-group.js";import{useMPLocale as l,useMPMessages as c}from"../../internal/locale.js";import{COMMON as m}from"../../internal/messages/common.js";import{MPStateLayer as p}from"../../internal/StateLayer.js";import{CONTROL_GAP as d,CONTROL_HEIGHT as u,CONTROL_ICON as f,CONTROL_PAD_X as b,CONTROL_SQUARE as g,CONTROL_TEXT as x,hasContent as v}from"../../internal/scale.js";const h={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)"},j={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=/*@__PURE__*/t.forwardRef(function({variant:w,size:y,color:_,disabled:k,startIcon:z,endIcon:B,loading:C=!1,loadingLabel:I,locale:N,fullWidth:P=!1,type:L="button",className:M,style:D,children:R,onClick:S,...W},$){const q=l(N),A=c(m,q),E=t.useContext(s),F=w??E?.variant??"filled",G=y??E?.size??"md",H=_??E?.color??"primary",J=k??E?.disabled??!1,K=C||v(z),O=!(v(R)||K&&v(B));return o(n,{ref:$,type:L,disabled:J,"aria-busy":C||void 0,"aria-disabled":C||void 0,"data-mp-size":G,"data-mp-variant":F,"data-loading":C||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)",u[G],x[G],d[G],O?`${g[G]} px-0`:b[G],J?j[F]:h[F],J?"cursor-default":"",C?"cursor-progress":"",P?"w-full":"",M??""].filter(Boolean).join(" "),style:{...i(H),...D},onClick:e=>{if(C)return e.preventDefault(),void e.stopPropagation();S?.(e)},...W,children:[J?null:e(p,{}),C?e(r,{icon:a,size:f[G],label:I??A.loading,className:"animate-spin"}):z,R,B]})});
|
|
@@ -12,6 +12,15 @@ export interface MPButtonGroupProps extends MPStyleProps, Omit<React.ComponentPr
|
|
|
12
12
|
color?: MPColor;
|
|
13
13
|
/** Disables every button in the group at once. */
|
|
14
14
|
disabled?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* The group's name is `aria-label` through the rest props, and is worth
|
|
17
|
+
* setting whenever the run is a *set* rather than a row that happens to be
|
|
18
|
+
* adjacent — "Alignment", "Text style".
|
|
19
|
+
*
|
|
20
|
+
* A screen reader announces the boundaries of a `role="group"` either way; the
|
|
21
|
+
* name is what makes crossing that boundary mean something rather than being
|
|
22
|
+
* an interruption between two buttons.
|
|
23
|
+
*/
|
|
15
24
|
children?: React.ReactNode;
|
|
16
25
|
}
|
|
17
26
|
/**
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import{jsx as
|
|
2
|
+
import{jsx as e}from"react/jsx-runtime";import*as o from"react";import{GROUP_JOIN as r,MPButtonGroupContext as i}from"../../internal/button-group.js";export const MPButtonGroup=/*@__PURE__*/o.forwardRef(function({variant:l,size:t,color:a,disabled:n,orientation:s="horizontal",fullWidth:f=!1,className:c,children:u,...d},m){const p=o.useMemo(()=>({variant:l,size:t,color:a,disabled:n}),[l,t,a,n]);return e(i.Provider,{value:p,children:e("div",{ref:m,role:"group","data-mp-orientation":s,className:["mp-button-group inline-flex gap-0.5 align-middle","vertical"===s?"flex-col":"flex-row",r[s],"[&>*]:relative [&>*:focus-visible]:z-10",f?"flex w-full [&>*]:flex-1":"",c??""].filter(Boolean).join(" "),...d,children:u})})});
|
|
@@ -62,20 +62,25 @@ export interface MPCarouselProps extends Omit<React.ComponentPropsWithoutRef<'di
|
|
|
62
62
|
* @default 'primary'
|
|
63
63
|
*/
|
|
64
64
|
color?: MPColor;
|
|
65
|
-
/**
|
|
66
|
-
* The carousel's accessible name.
|
|
67
|
-
* @default 'Carousel'
|
|
68
|
-
*/
|
|
65
|
+
/** The carousel's accessible name. Defaults to the word for it in `locale`. */
|
|
69
66
|
label?: string;
|
|
70
|
-
/**
|
|
67
|
+
/** Defaults to the wording in `locale`. */
|
|
71
68
|
previousLabel?: string;
|
|
72
|
-
/**
|
|
69
|
+
/** The same. */
|
|
73
70
|
nextLabel?: string;
|
|
74
71
|
/**
|
|
75
72
|
* How one slide is named to a screen reader, and how its mark is labelled.
|
|
76
|
-
*
|
|
73
|
+
* Defaults to the wording in `locale` with the two numbers set into it.
|
|
77
74
|
*/
|
|
78
75
|
slideLabel?: (index: number, count: number) => string;
|
|
76
|
+
/**
|
|
77
|
+
* Which language the carousel's own names are written in. Falls back to the
|
|
78
|
+
* nearest `MPLocaleProvider`, then to English.
|
|
79
|
+
*
|
|
80
|
+
* Nothing here is ever drawn — the strip is pictures and the arrows are
|
|
81
|
+
* chevrons — so without it a Korean page reads its slides out in English.
|
|
82
|
+
*/
|
|
83
|
+
locale?: string;
|
|
79
84
|
/** The slides. Every top-level child becomes one. */
|
|
80
85
|
children?: React.ReactNode;
|
|
81
86
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import{jsx as e,jsxs as r}from"react/jsx-runtime";import*as t from"react";import{MPIconButton as n}from"../icon-button/MPIconButton.js";import{MPIcon as o}from"../icon/MPIcon.js";import{ChevronLeftIcon as a,ChevronRightIcon as i}from"../../constants/icons.js";import{accentSlots as s}from"../../internal/accent.js";import{
|
|
2
|
+
import{jsx as e,jsxs as r}from"react/jsx-runtime";import*as t from"react";import{MPIconButton as n}from"../icon-button/MPIconButton.js";import{MPIcon as o}from"../icon/MPIcon.js";import{ChevronLeftIcon as a,ChevronRightIcon as i}from"../../constants/icons.js";import{accentSlots as s}from"../../internal/accent.js";import{fillMessage as l}from"../../internal/i18n.js";import{useMPLocale as c,useMPMessages as u}from"../../internal/locale.js";import{CAROUSEL as d}from"../../internal/messages/carousel.js";import{CONTROL_ICON as m}from"../../internal/scale.js";import{CONTAINER_SURFACE as f}from"../../internal/surface.js";import{VISUALLY_HIDDEN as p}from"../../internal/visually-hidden.js";const h={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"},b={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"}};export const MPCarousel=/*@__PURE__*/t.forwardRef(function({value:v,defaultValue:w=0,onValueChange:g,loop:x=!0,autoPlay:j=!1,interval:N=5e3,arrows:y=!0,indicators:M=!0,variant:k="outlined",size:R="md",color:C="primary",label:z,previousLabel:I,nextLabel:P,slideLabel:S,locale:L,className:E,style:T,children:$,...A},B){const F=u(d,c(L)),V=z??F.label,W=S??((e,r)=>l(F.slide,{index:String(e),total:String(r)})),q=t.Children.toArray($),_=q.length,[D,G]=t.useState(w),H=Math.min(Math.max(v??D,0),Math.max(_-1,0)),J=t.useRef(null),K=t.useRef([]),O=t.useRef(!1),Q=t.useRef(!1),U=t.useRef(!1),[X,Y]=t.useState(!1),[Z,ee]=t.useState(!1),re=X||Z,te=t.useRef(H),ne=t.useRef(g);te.current=H,ne.current=g;const oe=t.useCallback((e,r=!1)=>{if(0===_)return;const t=x?(e%_+_)%_:Math.min(Math.max(e,0),_-1);O.current=r,void 0===v&&G(t),t!==te.current&&ne.current?.(t)},[_,x,v]);t.useEffect(()=>{if(O.current)return void(O.current=!1);if(!Q.current)return void(Q.current=!0);K.current[H]?.scrollIntoView({block:"nearest",inline:"start"}),U.current=!0;const e=window.setTimeout(()=>{U.current=!1},700);return()=>window.clearTimeout(e)},[H]),t.useEffect(()=>{if(!j||re||_<2)return;if(window.matchMedia?.("(prefers-reduced-motion: reduce)").matches)return;const e=window.setInterval(()=>{document.hidden||oe(te.current+1)},N);return()=>window.clearInterval(e)},[j,re,_,N,oe]);const ae=t.useRef(0);t.useEffect(()=>()=>cancelAnimationFrame(ae.current),[]);const ie=H<=0,se=H>=_-1;return r("div",{ref:B,role:"region","aria-roledescription":"carousel","aria-label":V,"data-mp-size":R,"data-mp-variant":k,className:["mp-carousel flex w-full flex-col",E??""].filter(Boolean).join(" "),style:{...s(C),...T},onPointerEnter:()=>Y(!0),onPointerLeave:()=>Y(!1),onFocus:()=>ee(!0),onBlur:e=>{e.currentTarget.contains(e.relatedTarget)||ee(!1)},...A,children:[r("div",{className:["relative min-w-0 overflow-hidden","rounded-mp-md box-border",f[k],"text-mp-on-surface"].join(" "),children:[e("div",{ref:J,tabIndex:0,role:"group","aria-label":V,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:()=>{ae.current||(ae.current=requestAnimationFrame(()=>{ae.current=0;const e=J.current;if(!e||0===e.clientWidth||U.current)return;const r=Math.round(Math.abs(e.scrollLeft)/e.clientWidth);r!==te.current&&r>=0&&r<_&&oe(r,!0)}))},children:q.map((r,t)=>e("div",{ref:e=>{K.current[t]=e,K.current.length=_},role:"group","aria-roledescription":"slide","aria-label":W(t+1,_),className:"w-full shrink-0 grow-0 basis-full snap-start",children:r},t))}),y&&_>1?r("div",{className:`pointer-events-none absolute inset-y-0 flex items-center ${h[R]}`,children:[e(n,{variant:"filled",size:R,color:C,label:I??F.previous,disabled:!x&&ie,className:"pointer-events-auto",icon:e(o,{icon:a,size:m[R],className:"rtl:rotate-180"}),onClick:()=>oe(H-1)}),e("span",{className:"flex-1"}),e(n,{variant:"filled",size:R,color:C,label:P??F.next,disabled:!x&&se,className:"pointer-events-auto",icon:e(o,{icon:i,size:m[R],className:"rtl:rotate-180"}),onClick:()=>oe(H+1)})]}):null]}),M&&_>1?e("div",{className:`flex shrink-0 items-center justify-center pt-2 ${b[R].gap}`,children:q.map((r,t)=>e("button",{type:"button","aria-label":W(t+1,_),"aria-current":t===H?"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===H?`${b[R].current} bg-(--_mp-accent)`:`${b[R].rest} bg-mp-outline-variant hover:bg-mp-outline`].join(" "),onClick:()=>oe(t)},t))}):null,e("span",{className:p,"aria-live":j?"off":"polite",children:_>0?W(H+1,_):""})]})});
|
|
@@ -17,9 +17,22 @@ export type MPChatBubbleSide = 'start' | 'end';
|
|
|
17
17
|
* colour family.
|
|
18
18
|
*/
|
|
19
19
|
export type MPChatBubbleStatus = 'sending' | 'sent' | 'delivered' | 'read' | 'failed';
|
|
20
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* What a link inside a message unfurls to.
|
|
22
|
+
*
|
|
23
|
+
* This is the one shape in the library whose contents typically come from
|
|
24
|
+
* **somebody else** — a preview is attached to a message another person sent —
|
|
25
|
+
* so `url` is checked before it is rendered rather than trusted. See the note on
|
|
26
|
+
* `LinkPreview` below.
|
|
27
|
+
*/
|
|
21
28
|
export interface MPChatBubblePreview {
|
|
22
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* Where the card goes.
|
|
31
|
+
*
|
|
32
|
+
* Only `http:`, `https:`, `mailto:`, `tel:` and relative URLs are rendered.
|
|
33
|
+
* Anything else — `javascript:`, `data:` — draws the card without a link
|
|
34
|
+
* rather than handing the reader a one-click script execution.
|
|
35
|
+
*/
|
|
23
36
|
url: string;
|
|
24
37
|
/** The page's title. */
|
|
25
38
|
title?: React.ReactNode;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import{jsx as e,jsxs as n}from"react/jsx-runtime";import*as r from"react";import{MPIcon as a}from"../icon/MPIcon.js";import{CheckIcon as l,ClockIcon as
|
|
2
|
+
import{jsx as e,jsxs as n}from"react/jsx-runtime";import*as r from"react";import{MPIcon as a}from"../icon/MPIcon.js";import{CheckIcon as l,ClockIcon as i,ErrorIcon as t,LinkIcon as s}from"../../constants/icons.js";import{accentSlots as o}from"../../internal/accent.js";import{useMPLocale as c,useMPMessages as m}from"../../internal/locale.js";import{linkRel as d,safeHref as p}from"../../internal/link.js";import{CHAT as u}from"../../internal/messages/chat.js";import{hasContent as f,META_TEXT as h,PROSE_TEXT as b}from"../../internal/scale.js";import{VISUALLY_HIDDEN as x}from"../../internal/visually-hidden.js";const v={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"},g={start:"[border-start-start-radius:var(--mp-sys-shape-corner-extra-small)]",end:"[border-start-end-radius:var(--mp-sys-shape-corner-extra-small)]"},y={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 N(){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 w={sending:e(a,{icon:i,size:"1.15em"}),sent:e(a,{icon:l,size:"1.15em"}),delivered:e("span",{className:"block size-[1.15em]",children:e(N,{})}),read:e("span",{className:"block size-[1.15em]",children:e(N,{})}),failed:e(a,{icon:t,size:"1.15em"})},k={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"},j=/*@__PURE__*/["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(" "),_=/*@__PURE__*/["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=/*@__PURE__*/r.forwardRef(function({side:r="start",name:a,time:l,avatar:i,status:t,statusLabel:s,typing:d=!1,media:p,preview:N,actions:j,locale:L,variant:B="tonal",size:$="md",color:M="primary",className:P,style:W,children:I,...R},T){const q=c(L),A=m(u,q),D="end"===r,E=f(a)||f(l),F=d||f(I)||Boolean(N);return n("div",{ref:T,"data-mp-size":$,"data-mp-variant":B,"data-mp-side":r,className:["mp-chat-bubble group/bubble flex w-full items-start gap-2",D?"flex-row-reverse":"",P??""].filter(Boolean).join(" "),style:{...o(M),...W},...R,children:[f(i)?e("div",{className:"shrink-0",children:i}):null,n("div",{className:["flex min-w-0 max-w-[min(100%,32rem)] flex-col gap-1",D?"items-end":"items-start"].join(" "),children:[E?n("div",{className:`flex items-baseline gap-2 ${h}`,children:[f(a)?e("span",{className:"font-medium",children:a}):null,f(l)?e("span",{className:"text-mp-on-surface-variant",children:l}):null]}):null,n("div",{className:"flex min-w-0 items-center gap-1 "+(D?"flex-row-reverse":""),children:[n("div",{className:["mp-chat-bubble__sheet rounded-mp-xl flex min-w-0 flex-col overflow-hidden","box-border",g[r],y[B],b[$]].join(" "),children:[f(p)?e("div",{className:"[&_img]:block [&_img]:w-full [&_video]:block [&_video]:w-full",children:p}):null,F?n("div",{className:`flex min-w-0 flex-col gap-2 ${v[$]}`,children:[d?e(z,{label:A.typing}):f(I)?e("div",{className:"min-w-0 break-words whitespace-pre-line",children:I}):null,N?e(C,{preview:N}):null]}):null]}),f(j)?e("div",{className:_,children:j}):null]}),t?n("div",{className:`flex items-center gap-1 ${h} ${k[t]}`,children:[w[t],e("span",{className:x,children:s??A[t]})]}):null]})]})});function z({label:r}){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:x,children:r})]})}function C({preview:r}){const{url:l,title:i,description:t,image:o,site:c,newTab:m=!1}=r,u=m?"_blank":void 0;return n("a",{href:p(l),target:u,rel:d(u,void 0),className:j,children:[o?e("img",{src:o,alt:"",loading:"lazy",decoding:"async",referrerPolicy:"no-referrer",width:640,height:112,className:"block h-28 w-full object-cover"}):null,n("div",{className:"flex flex-col gap-0.5 p-2",children:[f(c)?n("span",{className:"flex items-center gap-1 text-[0.85em] opacity-70",children:[e(a,{icon:s,size:"1em"}),e("span",{className:"truncate",children:c})]}):null,f(i)?e("span",{className:"font-medium",children:i}):null,f(t)?e("span",{className:"line-clamp-2 text-[0.9em] opacity-80",children:t}):null]})]})}
|
|
@@ -1,23 +1,16 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import type { MPMessages } from '../../internal/i18n.js';
|
|
2
3
|
import type { MPColorFormat } from '../../internal/color.js';
|
|
3
4
|
import type { MPStyleProps } from '../../types.js';
|
|
4
|
-
/**
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
value: string;
|
|
14
|
-
/** The grid of ready-made colours. */
|
|
15
|
-
swatches: string;
|
|
16
|
-
/** The × that empties the control. */
|
|
17
|
-
clear: string;
|
|
18
|
-
/** What the trigger reads before anything has been chosen. */
|
|
19
|
-
empty: string;
|
|
20
|
-
}
|
|
5
|
+
/**
|
|
6
|
+
* The names for the parts of the picker that have no text on them.
|
|
7
|
+
*
|
|
8
|
+
* A namespace in the shared table rather than a set of defaults kept here, which
|
|
9
|
+
* is the rule every other component that invents a word follows: `locale` gets a
|
|
10
|
+
* translation, `MPLocaleProvider` gets one for the whole application at once,
|
|
11
|
+
* and `labels` gets whatever else. See `internal/i18n.ts`.
|
|
12
|
+
*/
|
|
13
|
+
export type MPColorPickerLabels = MPMessages['colorPicker'];
|
|
21
14
|
export interface MPColorPickerProps extends MPStyleProps {
|
|
22
15
|
/** The colour, as a CSS string. Pass it to drive the picker yourself. */
|
|
23
16
|
value?: string;
|
|
@@ -93,6 +86,16 @@ export interface MPColorPickerProps extends MPStyleProps {
|
|
|
93
86
|
defaultOpen?: boolean;
|
|
94
87
|
onOpenChange?: (open: boolean) => void;
|
|
95
88
|
/** Overrides for the accessible names, one at a time. */
|
|
89
|
+
/**
|
|
90
|
+
* Which language the picker's own names are written in — the rails, the
|
|
91
|
+
* square, the × and the word the trigger shows before a colour has been
|
|
92
|
+
* chosen. Falls back to the nearest `MPLocaleProvider`, then to English.
|
|
93
|
+
*/
|
|
94
|
+
locale?: string;
|
|
95
|
+
/**
|
|
96
|
+
* Overrides for the words themselves. They win over the translation, and
|
|
97
|
+
* anything not named stays translated.
|
|
98
|
+
*/
|
|
96
99
|
labels?: Partial<MPColorPickerLabels>;
|
|
97
100
|
/**
|
|
98
101
|
* The id put on the trigger and pointed at by the label. Generated when it is
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import{jsx as e,jsxs as a}from"react/jsx-runtime";import*as r from"react";import{Field as n}from"@base-ui/react/field";import{Popover as t}from"@base-ui/react/popover";import{MPIcon as l}from"../icon/MPIcon.js";import{CheckIcon as o,CloseIcon as i}from"../../constants/icons.js";import{MPFieldLabel as s,MPFieldOutline as u,useFloatingLabel as c}from"../../internal/FieldOutline.js";import{MPStateLayer as d}from"../../internal/StateLayer.js";import{MPSupportingText as p}from"../../internal/SupportingText.js";import{CONTROL_ICON as h,META_TEXT as m,PROSE_TEXT as f,STACK_GAP as g,hasContent as v}from"../../internal/scale.js";import{FADE as b,PORTAL_LAYER as x}from"../../internal/surface.js";import{CHECKER_BACKGROUND as y,DEFAULT_SWATCHES as w,clamp as N,cssColor as j,formatColor as k,parseColor as C,readableInk as _}from"../../internal/color.js";const z={area:"Saturation and brightness",hue:"Hue",alpha:"Opacity",value:"Colour value",swatches:"Swatches",clear:"Clear",empty:"No colour"},P={xs:"w-40",sm:"w-44",md:"w-52",lg:"w-60",xl:"w-72"},$={xs:"h-24",sm:"h-28",md:"h-32",lg:"h-40",xl:"h-48"},M={xs:"h-2.5",sm:"h-3",md:"h-3.5",lg:"h-4",xl:"h-5"},T={xs:"gap-2",sm:"gap-2.5",md:"gap-3",lg:"gap-3.5",xl:"gap-4"},I={xs:12,sm:14,md:16,lg:18,xl:20},O={xs:{padding:"px-2",height:"h-8"},sm:{padding:"px-3",height:"h-10"},md:{padding:"px-4",height:"h-14"},lg:{padding:"px-4",height:"h-16"},xl:{padding:"px-5",height:"h-18"}},S="border-mp-outline-variant relative overflow-hidden border",A=/*@__PURE__*/["pointer-events-none absolute rounded-full border-2 border-white","[box-shadow:0_0_0_1px_rgb(0_0_0/0.35),0_1px_3px_rgb(0_0_0/0.4)]"].join(" ");function B(e,a,r){return{x:0===e.width?0:N((a-e.left)/e.width,0,1),y:0===e.height?0:N((r-e.top)/e.height,0,1)}}function D(e){const a=e.shiftKey?10:1;switch(e.key){case"ArrowLeft":return{x:-a,y:0};case"ArrowRight":return{x:a,y:0};case"ArrowUp":return{x:0,y:a};case"ArrowDown":return{x:0,y:-a};default:return null}}function L({hsv:n,alphaValue:t,onChange:i,text:s,onTextChange:u,withAlpha:c,swatches:d,editable:p,size:h,inert:f,labels:g}){const v=I[h],b=-v/2,x=j({h:n.h,s:100,v:100}),w=j(n),z=r.useRef(null),O=e=>({onPointerDown:a=>{if(f)return;const r=a.currentTarget.getBoundingClientRect();z.current=r,a.currentTarget.setPointerCapture(a.pointerId),e(B(r,a.clientX,a.clientY))},onPointerMove:a=>{const r=z.current;!f&&r&&a.currentTarget.hasPointerCapture(a.pointerId)&&e(B(r,a.clientX,a.clientY))},onPointerUp:()=>{z.current=null},onPointerCancel:()=>{z.current=null}}),L=(e,a,r,n)=>({role:"slider",tabIndex:f?-1:0,"aria-label":e,"aria-valuemin":0,"aria-valuemax":r,"aria-valuenow":Math.round(a),"aria-orientation":"horizontal","aria-disabled":f||void 0,onKeyDown:e=>{const a=D(e);!f&&a&&0!==a.x&&(e.preventDefault(),n(a.x))}}),R=/*@__PURE__*/["outline-mp-secondary focus-visible:outline-2 focus-visible:outline-offset-2","focus-visible:outline-solid outline-none"].join(" "),q=r.useMemo(()=>d?d.map(e=>{const a=C(e);return{swatch:e,parsed:a,hex:null===a?null:k(a.hsv,a.alpha,"hex")}}):[],[d]),V=k(n,t,"hex");return a("div",{className:`mp-color-picker__panel flex flex-col ${P[h]} ${T[h]}`,children:[e("div",{...O(({x:e,y:a})=>i({hsv:{h:n.h,s:100*e,v:100*(1-a)},alpha:t})),role:"slider",tabIndex:f?-1:0,"aria-label":g.area,"aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":Math.round(n.s),"aria-valuetext":`${Math.round(n.s)}%, ${Math.round(n.v)}%`,"aria-disabled":f||void 0,onKeyDown:e=>{const a=D(e);!f&&a&&(e.preventDefault(),i({hsv:{h:n.h,s:N(n.s+a.x,0,100),v:N(n.v+a.y,0,100)},alpha:t}))},className:[S,"rounded-mp-sm",$[h],R,f?"cursor-default":"cursor-crosshair touch-none"].join(" "),style:{backgroundColor:x,backgroundImage:"linear-gradient(to top, #000000, rgb(0 0 0 / 0)), linear-gradient(to right, #ffffff, rgb(255 255 255 / 0))"},children:e("span",{className:A,style:{width:v,height:v,left:`${n.s}%`,top:100-n.v+"%",marginLeft:b,marginTop:b,backgroundColor:w}})}),e("div",{...O(({x:e})=>i({hsv:{...n,h:360*e},alpha:t})),...L(g.hue,n.h,360,e=>i({hsv:{...n,h:(n.h+2*e+360)%360},alpha:t})),className:[S,"rounded-mp-full",M[h],R,f?"cursor-default":"cursor-pointer touch-none"].join(" "),style:{backgroundImage:"linear-gradient(to right, #ff0000 0%, #ffff00 16.66%, #00ff00 33.33%, #00ffff 50%, #0000ff 66.66%, #ff00ff 83.33%, #ff0000 100%)"},children:e("span",{className:A,style:{width:v,height:v,left:n.h/360*100+"%",top:"50%",marginLeft:b,marginTop:b,backgroundColor:x}})}),c?a("div",{...O(({x:e})=>i({hsv:n,alpha:e})),...L(g.alpha,100*t,100,e=>i({hsv:n,alpha:N(t+e/100,0,1)})),className:[S,"rounded-mp-full",M[h],R,f?"cursor-default":"cursor-pointer touch-none"].join(" "),style:y,children:[e("span",{"aria-hidden":"true",className:"absolute inset-0",style:{backgroundImage:`linear-gradient(to right, ${j(n,0)}, ${w})`}}),e("span",{className:A,style:{width:v,height:v,left:100*t+"%",top:"50%",marginLeft:b,marginTop:b,backgroundColor:j(n,t)}})]}):null,p?a("div",{className:`flex items-center ${T[h]}`,children:[e("span",{"aria-hidden":"true",className:"border-mp-outline-variant shrink-0 rounded-full border",style:{width:v+8,height:v+8,...y},children:e("span",{className:"block size-full rounded-full",style:{backgroundColor:j(n,t)}})}),e("input",{type:"text",value:s,readOnly:f,spellCheck:!1,autoComplete:"off","aria-label":g.value,onChange:e=>u(e.target.value),className:["rounded-mp-xs border-mp-outline text-mp-on-surface min-w-0 flex-1 border","bg-transparent px-2 py-1 font-mono lowercase",m,"focus-visible:border-mp-primary outline-none"].join(" ")})]}):null,q.length>0?e("div",{role:"group","aria-label":g.swatches,className:"grid grid-cols-8 gap-1",children:q.map(({swatch:a,parsed:r,hex:n},t)=>{const s=null!==r&&n===V;return e("button",{type:"button",disabled:f,"aria-label":a,"aria-pressed":s,onClick:()=>{r&&i({hsv:r.hsv,alpha:r.alpha})},className:["border-mp-outline-variant flex aspect-square items-center justify-center","rounded-full border","transition-[box-shadow] duration-(--mp-sys-motion-duration-short4)","ease-mp-standard",R,f?"cursor-default":"hover:shadow-mp-1 cursor-pointer"].join(" "),style:{backgroundColor:a},children:e("span",{"aria-hidden":"true",className:["transition-opacity duration-(--mp-sys-motion-duration-short4)","ease-mp-standard",s?"opacity-100":"opacity-0"].join(" "),style:r?{color:_(r.hsv)}:void 0,children:e(l,{icon:o,size:12})})},`${t}:${a}`)})}):null]})}const R={h:202,s:100,v:61};export const MPColorPicker=/*@__PURE__*/r.forwardRef(function({value:o,defaultValue:N="#00639b",onValueChange:_,format:P="hex",alpha:$=!1,swatches:M=w,inline:T=!1,editable:I=!0,label:S,floatingLabel:A=!0,description:B,errorMessage:D,required:q=!1,disabled:V=!1,readOnly:K=!1,clearable:F=!1,name:U,open:X,defaultOpen:Y=!1,onOpenChange:E,labels:H,size:W="md",fullWidth:G=!1,id:J,className:Q,style:Z},ee){const ae=r.useMemo(()=>({...z,...H}),[H]),re=v(D),ne=O[W],te=r.useId(),le=J??te,[oe,ie]=r.useState(N),se=o??oe,[ue,ce]=r.useState(Y),de=X??ue,[pe,he]=r.useState(()=>C(se)??{hsv:R,alpha:1}),[me,fe]=r.useState(()=>se),ge=k(pe.hsv,$?pe.alpha:1,P),ve=""===se;r.useEffect(()=>{const e=C(se);e?k(e.hsv,$?e.alpha:1,P)!==ge&&(fe(se),he(e)):fe(se)},[se,ge,$,P]);const be=V||K,xe=F&&!be&&!ve,{shrunk:ye,focusProps:we}=c({floating:A&&v(S),filled:!ve,pinned:de}),Ne=(e,a)=>{he(e);const r=k(e.hsv,$?e.alpha:1,P);fe(a??r),void 0===o&&ie(r),_?.(r)},je=e(L,{hsv:pe.hsv,alphaValue:pe.alpha,onChange:Ne,text:me,onTextChange:e=>{fe(e);const a=C(e);a&&Ne(a,e)},withAlpha:$,swatches:M,editable:I,size:W,inert:be,labels:ae}),ke=e("span",{"aria-hidden":"true",className:"border-mp-outline-variant block size-5 shrink-0 rounded-full border",style:y,children:e("span",{className:"block size-full rounded-full",style:{backgroundColor:ve?"transparent":j(pe.hsv,$?pe.alpha:1)}})}),Ce=U?e("input",{type:"hidden",name:U,value:ve?"":ge}):null;return T?a("div",{ref:ee,"data-mp-size":W,className:["mp-color-picker flex flex-col",g[W],Q??""].filter(Boolean).join(" "),style:Z,children:[v(S)?a("span",{className:[m,V?"text-mp-on-surface/38":"text-mp-on-surface-variant"].join(" "),children:[S,q?e("span",{"aria-hidden":"true",children:" *"}):null]}):null,je,v(D)?e("span",{className:`${m} text-mp-error`,children:D}):v(B)?e("span",{className:`${m} text-mp-on-surface-variant`,children:B}):null,Ce]}):a(n.Root,{ref:ee,disabled:V,invalid:re,"data-mp-size":W,className:["mp-color-picker group flex-col align-top",G?"flex w-full":"inline-flex w-fit",Q??""].filter(Boolean).join(" "),style:Z,...we,children:[a(t.Root,{open:de,onOpenChange:e=>{void 0===X&&ce(e),E?.(e)},children:[a("div",{className:"relative w-full",children:[a(t.Trigger,{id:le,disabled:V,nativeButton:!0,className:["relative flex w-full items-center gap-2 select-none","appearance-none bg-transparent font-[inherit] outline-none",ne.padding,xe?"pe-10":"",ne.height,f[W],V?"text-mp-on-surface/38 cursor-default":"text-mp-on-surface "+(K?"cursor-default":"cursor-pointer")].filter(Boolean).join(" "),children:[ve&&!ye?null:ke,e("span",{className:["min-w-0 flex-1 truncate text-start",ve?"text-mp-on-surface-variant":""].filter(Boolean).join(" "),children:ve?ye?ae.empty:null:ge})]}),xe?a("button",{type:"button","aria-label":ae.clear,onClick:()=>{void 0===o&&ie(""),fe(""),_?.("")},className:["group/clear rounded-mp-full text-mp-on-surface-variant absolute inset-y-0","end-1 my-auto flex size-8 cursor-pointer items-center justify-center","outline-mp-secondary focus-visible:outline-2 focus-visible:outline-offset-1","focus-visible:outline-solid outline-none"].join(" "),children:[e(d,{className:"group-hover/clear:opacity-8 group-focus-visible/clear:opacity-10"}),e(l,{icon:i,size:h[W]})]}):null,e(u,{label:S,required:q,notched:ye}),v(S)?e(s,{size:W,label:S,required:q,htmlFor:le,shrunk:ye}):null]}),e(t.Portal,{children:e(t.Positioner,{className:x,sideOffset:4,align:"start",children:e(t.Popup,{className:["mp-color-picker__popup rounded-mp-md shadow-mp-2 bg-mp-surface-container","text-mp-on-surface p-3 outline-none",f[W],b].join(" "),children:je})})})]}),e(p,{description:B,errorMessage:D,className:ne.padding}),Ce]})});
|
|
2
|
+
import{jsx as e,jsxs as a}from"react/jsx-runtime";import*as r from"react";import{Field as n}from"@base-ui/react/field";import{Popover as t}from"@base-ui/react/popover";import{MPIcon as l}from"../icon/MPIcon.js";import{CheckIcon as o,CloseIcon as i}from"../../constants/icons.js";import{MPFieldLabel as s,MPFieldOutline as u,useFloatingLabel as c}from"../../internal/FieldOutline.js";import{useMPLocale as d,useMPMessages as p}from"../../internal/locale.js";import{COLOR_PICKER as h}from"../../internal/messages/color-picker.js";import{MPStateLayer as m}from"../../internal/StateLayer.js";import{MPSupportingText as f}from"../../internal/SupportingText.js";import{CONTROL_ICON as g,META_TEXT as v,PROSE_TEXT as x,STACK_GAP as b,hasContent as y}from"../../internal/scale.js";import{FADE as w,PORTAL_LAYER as N}from"../../internal/surface.js";import{CHECKER_BACKGROUND as j,DEFAULT_SWATCHES as k,clamp as C,cssColor as _,formatColor as z,parseColor as P,readableInk as $}from"../../internal/color.js";const M={xs:"w-40",sm:"w-44",md:"w-52",lg:"w-60",xl:"w-72"},T={xs:"h-24",sm:"h-28",md:"h-32",lg:"h-40",xl:"h-48"},I={xs:"h-2.5",sm:"h-3",md:"h-3.5",lg:"h-4",xl:"h-5"},A={xs:"gap-2",sm:"gap-2.5",md:"gap-3",lg:"gap-3.5",xl:"gap-4"},R={xs:12,sm:14,md:16,lg:18,xl:20},O={xs:{padding:"px-2",height:"h-8"},sm:{padding:"px-3",height:"h-10"},md:{padding:"px-4",height:"h-14"},lg:{padding:"px-4",height:"h-16"},xl:{padding:"px-5",height:"h-18"}},B="border-mp-outline-variant relative overflow-hidden border",D=/*@__PURE__*/["pointer-events-none absolute rounded-full border-2 border-white","[box-shadow:0_0_0_1px_rgb(0_0_0/0.35),0_1px_3px_rgb(0_0_0/0.4)]"].join(" ");function L(e,a,r){return{x:0===e.width?0:C((a-e.left)/e.width,0,1),y:0===e.height?0:C((r-e.top)/e.height,0,1)}}function S(e){const a=e.shiftKey?10:1;switch(e.key){case"ArrowLeft":return{x:-a,y:0};case"ArrowRight":return{x:a,y:0};case"ArrowUp":return{x:0,y:a};case"ArrowDown":return{x:0,y:-a};default:return null}}function q({hsv:n,alphaValue:t,onChange:i,text:s,onTextChange:u,withAlpha:c,swatches:d,editable:p,size:h,inert:m,labels:f}){const g=R[h],x=-g/2,b=_({h:n.h,s:100,v:100}),y=_(n),w=r.useRef(null),N=r.useRef(null),k=r.useRef(0);r.useEffect(()=>()=>{k.current&&cancelAnimationFrame(k.current)},[]);const O=e=>({onPointerDown:a=>{if(m)return;const r=a.currentTarget.getBoundingClientRect();w.current=r,a.currentTarget.setPointerCapture(a.pointerId),e(L(r,a.clientX,a.clientY))},onPointerMove:a=>{const r=w.current;var n;!m&&r&&a.currentTarget.hasPointerCapture(a.pointerId)&&(n=L(r,a.clientX,a.clientY),N.current=n,k.current||(k.current=requestAnimationFrame(()=>{k.current=0;const a=N.current;N.current=null,a&&e(a)})))},onPointerUp:()=>{w.current=null},onPointerCancel:()=>{w.current=null}}),q=(e,a,r,n)=>({role:"slider",tabIndex:m?-1:0,"aria-label":e,"aria-valuemin":0,"aria-valuemax":r,"aria-valuenow":Math.round(a),"aria-orientation":"horizontal","aria-disabled":m||void 0,onKeyDown:e=>{const a=S(e);!m&&a&&0!==a.x&&(e.preventDefault(),n(a.x))}}),F=/*@__PURE__*/["outline-mp-secondary focus-visible:outline-2 focus-visible:outline-offset-2","focus-visible:outline-solid outline-none"].join(" "),V=r.useMemo(()=>d?d.map(e=>{const a=P(e);return{swatch:e,parsed:a,hex:null===a?null:z(a.hsv,a.alpha,"hex")}}):[],[d]),K=z(n,t,"hex");return a("div",{className:`mp-color-picker__panel flex flex-col ${M[h]} ${A[h]}`,children:[e("div",{...O(({x:e,y:a})=>i({hsv:{h:n.h,s:100*e,v:100*(1-a)},alpha:t})),role:"slider",tabIndex:m?-1:0,"aria-label":f.area,"aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":Math.round(n.s),"aria-valuetext":`${Math.round(n.s)}%, ${Math.round(n.v)}%`,"aria-disabled":m||void 0,onKeyDown:e=>{const a=S(e);!m&&a&&(e.preventDefault(),i({hsv:{h:n.h,s:C(n.s+a.x,0,100),v:C(n.v+a.y,0,100)},alpha:t}))},className:[B,"rounded-mp-sm",T[h],F,m?"cursor-default":"cursor-crosshair touch-none"].join(" "),style:{backgroundColor:b,backgroundImage:"linear-gradient(to top, #000000, rgb(0 0 0 / 0)), linear-gradient(to right, #ffffff, rgb(255 255 255 / 0))"},children:e("span",{className:D,style:{width:g,height:g,left:`${n.s}%`,top:100-n.v+"%",marginLeft:x,marginTop:x,backgroundColor:y}})}),e("div",{...O(({x:e})=>i({hsv:{...n,h:360*e},alpha:t})),...q(f.hue,n.h,360,e=>i({hsv:{...n,h:(n.h+2*e+360)%360},alpha:t})),className:[B,"rounded-mp-full",I[h],F,m?"cursor-default":"cursor-pointer touch-none"].join(" "),style:{backgroundImage:"linear-gradient(to right, #ff0000 0%, #ffff00 16.66%, #00ff00 33.33%, #00ffff 50%, #0000ff 66.66%, #ff00ff 83.33%, #ff0000 100%)"},children:e("span",{className:D,style:{width:g,height:g,left:n.h/360*100+"%",top:"50%",marginLeft:x,marginTop:x,backgroundColor:b}})}),c?a("div",{...O(({x:e})=>i({hsv:n,alpha:e})),...q(f.alpha,100*t,100,e=>i({hsv:n,alpha:C(t+e/100,0,1)})),className:[B,"rounded-mp-full",I[h],F,m?"cursor-default":"cursor-pointer touch-none"].join(" "),style:j,children:[e("span",{"aria-hidden":"true",className:"absolute inset-0",style:{backgroundImage:`linear-gradient(to right, ${_(n,0)}, ${y})`}}),e("span",{className:D,style:{width:g,height:g,left:100*t+"%",top:"50%",marginLeft:x,marginTop:x,backgroundColor:_(n,t)}})]}):null,p?a("div",{className:`flex items-center ${A[h]}`,children:[e("span",{"aria-hidden":"true",className:"border-mp-outline-variant shrink-0 rounded-full border",style:{width:g+8,height:g+8,...j},children:e("span",{className:"block size-full rounded-full",style:{backgroundColor:_(n,t)}})}),e("input",{type:"text",value:s,readOnly:m,spellCheck:!1,autoComplete:"off","aria-label":f.value,onChange:e=>u(e.target.value),className:["rounded-mp-xs border-mp-outline text-mp-on-surface min-w-0 flex-1 border","bg-transparent px-2 py-1 font-mono lowercase",v,"focus-visible:border-mp-primary outline-none"].join(" ")})]}):null,V.length>0?e("div",{role:"group","aria-label":f.swatches,className:"grid grid-cols-8 gap-1",children:V.map(({swatch:a,parsed:r,hex:n},t)=>{const s=null!==r&&n===K;return e("button",{type:"button",disabled:m,"aria-label":a,"aria-pressed":s,onClick:()=>{r&&i({hsv:r.hsv,alpha:r.alpha})},className:["border-mp-outline-variant flex aspect-square items-center justify-center","rounded-full border","transition-[box-shadow] duration-(--mp-sys-motion-duration-short4)","ease-mp-standard",F,m?"cursor-default":"hover:shadow-mp-1 cursor-pointer"].join(" "),style:{backgroundColor:a},children:e("span",{"aria-hidden":"true",className:["transition-opacity duration-(--mp-sys-motion-duration-short4)","ease-mp-standard",s?"opacity-100":"opacity-0"].join(" "),style:r?{color:$(r.hsv)}:void 0,children:e(l,{icon:o,size:12})})},`${t}:${a}`)})}):null]})}const F={h:202,s:100,v:61};export const MPColorPicker=/*@__PURE__*/r.forwardRef(function({value:o,defaultValue:C="#00639b",onValueChange:$,format:M="hex",alpha:T=!1,swatches:I=k,inline:A=!1,editable:R=!0,label:B,floatingLabel:D=!0,description:L,errorMessage:S,required:V=!1,disabled:K=!1,readOnly:E=!1,clearable:U=!1,name:X,open:Y,defaultOpen:W=!1,onOpenChange:G,locale:H,labels:J,size:Q="md",fullWidth:Z=!1,id:ee,className:ae,style:re},ne){const te=d(H),le=p(h,te,J),oe=y(S),ie=O[Q],se=r.useId(),ue=ee??se,[ce,de]=r.useState(C),pe=o??ce,[he,me]=r.useState(W),fe=Y??he,[ge,ve]=r.useState(()=>P(pe)??{hsv:F,alpha:1}),[xe,be]=r.useState(()=>pe),ye=z(ge.hsv,T?ge.alpha:1,M),we=""===pe;r.useEffect(()=>{const e=P(pe);e?z(e.hsv,T?e.alpha:1,M)!==ye&&(be(pe),ve(e)):be(pe)},[pe,ye,T,M]);const Ne=K||E,je=U&&!Ne&&!we,{shrunk:ke,focusProps:Ce}=c({floating:D&&y(B),filled:!we,pinned:fe}),_e=(e,a)=>{ve(e);const r=z(e.hsv,T?e.alpha:1,M);be(a??r),void 0===o&&de(r),$?.(r)},ze=e(q,{hsv:ge.hsv,alphaValue:ge.alpha,onChange:_e,text:xe,onTextChange:e=>{be(e);const a=P(e);a&&_e(a,e)},withAlpha:T,swatches:I,editable:R,size:Q,inert:Ne,labels:le}),Pe=e("span",{"aria-hidden":"true",className:"border-mp-outline-variant block size-5 shrink-0 rounded-full border",style:j,children:e("span",{className:"block size-full rounded-full",style:{backgroundColor:we?"transparent":_(ge.hsv,T?ge.alpha:1)}})}),$e=X?e("input",{type:"hidden",name:X,value:we?"":ye}):null;return A?a("div",{ref:ne,"data-mp-size":Q,className:["mp-color-picker flex flex-col",b[Q],ae??""].filter(Boolean).join(" "),style:re,children:[y(B)?a("span",{className:[v,K?"text-mp-on-surface/38":"text-mp-on-surface-variant"].join(" "),children:[B,V?e("span",{"aria-hidden":"true",children:" *"}):null]}):null,ze,y(S)?e("span",{className:`${v} text-mp-error`,children:S}):y(L)?e("span",{className:`${v} text-mp-on-surface-variant`,children:L}):null,$e]}):a(n.Root,{ref:ne,disabled:K,invalid:oe,"data-mp-size":Q,className:["mp-color-picker group flex-col align-top",Z?"flex w-full":"inline-flex w-fit",ae??""].filter(Boolean).join(" "),style:re,...Ce,children:[a(t.Root,{open:fe,onOpenChange:e=>{void 0===Y&&me(e),G?.(e)},children:[a("div",{className:"relative w-full",children:[a(t.Trigger,{id:ue,disabled:K,nativeButton:!0,className:["relative flex w-full items-center gap-2 select-none","appearance-none bg-transparent font-[inherit] outline-none",ie.padding,je?"pe-10":"",ie.height,x[Q],K?"text-mp-on-surface/38 cursor-default":"text-mp-on-surface "+(E?"cursor-default":"cursor-pointer")].filter(Boolean).join(" "),children:[we&&!ke?null:Pe,e("span",{className:["min-w-0 flex-1 truncate text-start",we?"text-mp-on-surface-variant":""].filter(Boolean).join(" "),children:we?ke?le.empty:null:ye})]}),je?a("button",{type:"button","aria-label":le.clear,onClick:()=>{void 0===o&&de(""),be(""),$?.("")},className:["group/clear rounded-mp-full text-mp-on-surface-variant absolute inset-y-0","end-1 my-auto flex size-8 cursor-pointer items-center justify-center","outline-mp-secondary focus-visible:outline-2 focus-visible:outline-offset-1","focus-visible:outline-solid outline-none"].join(" "),children:[e(m,{className:"group-hover/clear:opacity-8 group-focus-visible/clear:opacity-10"}),e(l,{icon:i,size:g[Q]})]}):null,e(u,{label:B,required:V,notched:ke}),y(B)?e(s,{size:Q,label:B,required:V,htmlFor:ue,shrunk:ke}):null]}),e(t.Portal,{children:e(t.Positioner,{className:N,sideOffset:4,align:"start",children:e(t.Popup,{className:["mp-color-picker__popup rounded-mp-md shadow-mp-2 bg-mp-surface-container","text-mp-on-surface p-3 outline-none",x[Q],w].join(" "),children:ze})})})]}),e(f,{description:L,errorMessage:S,className:ie.padding}),$e]})});
|