plass-ui 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/accordion/PlAccordion.js +1 -131
- package/dist/components/accordion/index.js +1 -1
- package/dist/components/alert/PlAlert.js +1 -109
- package/dist/components/alert/index.js +1 -1
- package/dist/components/animate-appear/PlAnimateAppear.js +1 -71
- package/dist/components/animate-appear/index.js +1 -1
- package/dist/components/animate-blink/PlAnimateBlink.js +1 -47
- package/dist/components/animate-blink/index.js +1 -1
- package/dist/components/animate-fade/PlAnimateFade.js +1 -48
- package/dist/components/animate-fade/index.js +1 -1
- package/dist/components/animate-grow/PlAnimateGrow.js +1 -49
- package/dist/components/animate-grow/index.js +1 -1
- package/dist/components/animate-headline/PlAnimateHeadline.js +1 -120
- package/dist/components/animate-headline/index.js +1 -1
- package/dist/components/animate-lighting/PlAnimateLighting.js +1 -65
- package/dist/components/animate-lighting/index.js +1 -1
- package/dist/components/animate-marquee/PlAnimateMarquee.js +1 -94
- package/dist/components/animate-marquee/index.js +1 -1
- package/dist/components/animate-rotate/PlAnimateRotate.js +1 -50
- package/dist/components/animate-rotate/index.js +1 -1
- package/dist/components/animate-slide/PlAnimateSlide.js +1 -49
- package/dist/components/animate-slide/index.js +1 -1
- package/dist/components/animate-typing/PlAnimateTyping.js +1 -177
- package/dist/components/animate-typing/index.js +1 -1
- package/dist/components/animate-zoom/PlAnimateZoom.js +1 -45
- package/dist/components/animate-zoom/index.js +1 -1
- package/dist/components/aspect-ratio/PlAspectRatio.js +1 -58
- package/dist/components/aspect-ratio/index.js +1 -1
- package/dist/components/avatar/PlAvatar.js +1 -121
- package/dist/components/avatar/index.js +1 -1
- package/dist/components/badge/PlBadge.js +1 -168
- package/dist/components/badge/index.js +1 -1
- package/dist/components/blockquote/PlBlockquote.js +1 -112
- package/dist/components/blockquote/index.js +1 -1
- package/dist/components/bottom-navigation/PlBottomNavigation.js +1 -141
- package/dist/components/bottom-navigation/index.js +1 -1
- package/dist/components/box/PlBox.js +1 -46
- package/dist/components/box/index.js +1 -1
- package/dist/components/breadcrumb/PlBreadcrumb.js +1 -201
- package/dist/components/breadcrumb/index.js +1 -1
- package/dist/components/button/PlButton.js +1 -196
- package/dist/components/button/index.js +1 -1
- package/dist/components/button-group/PlButtonGroup.js +1 -64
- package/dist/components/button-group/index.js +1 -1
- package/dist/components/card/PlCard.js +1 -102
- package/dist/components/card/index.js +1 -1
- package/dist/components/carousel/PlCarousel.js +1 -177
- package/dist/components/carousel/index.js +1 -1
- package/dist/components/chat-bubble/PlChatBubble.js +1 -206
- package/dist/components/chat-bubble/index.js +1 -1
- package/dist/components/checkbox/PlCheckbox.js +1 -100
- package/dist/components/checkbox/index.js +1 -1
- package/dist/components/chip/PlChip.js +1 -144
- package/dist/components/chip/index.js +1 -1
- package/dist/components/collapsible/PlCollapsible.js +1 -65
- package/dist/components/collapsible/index.js +1 -1
- package/dist/components/combobox/PlCombobox.js +1 -199
- package/dist/components/combobox/index.js +1 -1
- package/dist/components/container/PlContainer.js +1 -47
- package/dist/components/container/index.js +1 -1
- package/dist/components/date-picker/PlDatePicker.js +1 -87
- package/dist/components/date-picker/index.js +1 -1
- package/dist/components/date-range-picker/PlDateRangePicker.js +1 -152
- package/dist/components/date-range-picker/index.js +1 -1
- package/dist/components/date-time-picker/PlDateTimePicker.js +1 -106
- package/dist/components/date-time-picker/index.js +1 -1
- package/dist/components/divider/PlDivider.js +1 -107
- package/dist/components/divider/index.js +1 -1
- package/dist/components/drawer/PlDrawer.js +1 -190
- package/dist/components/drawer/index.js +1 -1
- package/dist/components/file-picker/PlFilePicker.js +1 -274
- package/dist/components/file-picker/index.js +1 -1
- package/dist/components/floating-bottom-navigation/PlFloatingBottomNavigation.js +1 -291
- package/dist/components/floating-bottom-navigation/index.js +1 -1
- package/dist/components/grid/PlGrid.js +1 -51
- package/dist/components/grid/PlGridItem.js +1 -34
- package/dist/components/grid/index.js +1 -2
- package/dist/components/highlight/PlHighlight.js +1 -185
- package/dist/components/highlight/index.js +1 -1
- package/dist/components/hot-keys/PlHotKeys.js +1 -294
- package/dist/components/hot-keys/index.js +1 -1
- package/dist/components/icon/PlIcon.js +1 -58
- package/dist/components/icon/index.js +1 -1
- package/dist/components/icon-button/PlIconButton.js +1 -37
- package/dist/components/icon-button/index.js +1 -1
- package/dist/components/list/PlList.js +1 -160
- package/dist/components/list/index.js +1 -1
- package/dist/components/menu/PlMenu.js +1 -209
- package/dist/components/menu/index.js +1 -1
- package/dist/components/modal/PlModal.js +1 -150
- package/dist/components/modal/index.js +1 -1
- package/dist/components/number-field/PlNumberField.js +1 -111
- package/dist/components/number-field/index.js +1 -1
- package/dist/components/otp-field/PlOtpField.js +1 -109
- package/dist/components/otp-field/index.js +1 -1
- package/dist/components/overlay/PlOverlay.js +1 -77
- package/dist/components/overlay/index.js +1 -1
- package/dist/components/pagination/PlPagination.js +1 -159
- package/dist/components/pagination/index.js +1 -1
- package/dist/components/panes/PlPanes.js +1 -324
- package/dist/components/panes/index.js +1 -1
- package/dist/components/pill/PlPill.js +1 -154
- package/dist/components/pill/index.js +1 -1
- package/dist/components/popover/PlPopover.js +1 -113
- package/dist/components/popover/index.js +1 -1
- package/dist/components/progress-box/PlProgressBox.js +1 -34
- package/dist/components/progress-box/index.js +1 -1
- package/dist/components/progress-circular/PlProgressCircular.js +1 -47
- package/dist/components/progress-circular/index.js +1 -1
- package/dist/components/progress-linear/PlProgressLinear.js +1 -40
- package/dist/components/progress-linear/index.js +1 -1
- package/dist/components/radio-group/PlRadioGroup.js +1 -99
- package/dist/components/radio-group/index.js +1 -1
- package/dist/components/rating/PlRating.js +1 -101
- package/dist/components/rating/index.js +1 -1
- package/dist/components/scroll-zone/PlScrollZone.js +1 -411
- package/dist/components/scroll-zone/index.js +1 -1
- package/dist/components/segmented-button/PlSegmentedButton.js +1 -206
- package/dist/components/segmented-button/index.js +1 -1
- package/dist/components/select/PlSelect.js +1 -115
- package/dist/components/select/index.js +1 -1
- package/dist/components/skeleton/PlSkeleton.js +1 -142
- package/dist/components/skeleton/index.js +1 -1
- package/dist/components/slider/PlSlider.js +1 -132
- package/dist/components/slider/index.js +1 -1
- package/dist/components/spoiler/PlSpoiler.js +1 -74
- package/dist/components/spoiler/index.js +1 -1
- package/dist/components/switch/PlSwitch.js +1 -131
- package/dist/components/switch/index.js +1 -1
- package/dist/components/table/PlTable.js +1 -210
- package/dist/components/table/index.js +1 -1
- package/dist/components/tabs/PlTabs.js +1 -182
- package/dist/components/tabs/index.js +1 -1
- package/dist/components/text-field/PlTextField.js +1 -126
- package/dist/components/text-field/index.js +1 -1
- package/dist/components/text-link/PlTextLink.js +1 -136
- package/dist/components/text-link/index.js +1 -1
- package/dist/components/time-picker/PlTimePicker.js +1 -97
- package/dist/components/time-picker/index.js +1 -1
- package/dist/components/timeline/PlTimeline.js +1 -207
- package/dist/components/timeline/index.js +1 -1
- package/dist/components/toast/PlToast.js +1 -174
- package/dist/components/toast/index.js +1 -1
- package/dist/components/toolbar/PlToolbar.js +1 -65
- package/dist/components/toolbar/index.js +1 -1
- package/dist/components/tooltip/PlTooltip.js +1 -117
- package/dist/components/tooltip/index.js +1 -1
- package/dist/components/typography/PlTypography.js +1 -143
- package/dist/components/typography/index.js +1 -1
- package/dist/index.js +1 -75
- package/dist/internal/animate.js +1 -318
- package/dist/internal/button-group.js +2 -19
- package/dist/internal/calendar.js +1 -501
- package/dist/internal/date.js +1 -353
- package/dist/internal/format.js +1 -41
- package/dist/internal/grid.js +1 -143
- package/dist/internal/icons.js +1 -138
- package/dist/internal/menu.js +1 -18
- package/dist/internal/picker.js +1 -139
- package/dist/internal/progress.js +1 -167
- package/dist/internal/sizer.js +1 -35
- package/dist/internal/styles.js +1 -636
- package/dist/types.js +0 -8
- package/package.json +3 -2
|
@@ -1,131 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
import { Accordion as BaseUIAccordion } from '@base-ui/react/accordion';
|
|
4
|
-
import { ChevronIcon } from '../../internal/icons.js';
|
|
5
|
-
import { focusRingClasses, focusRingInsetClasses, gapClasses, hasContent, iconClasses, metaTextClasses, radiusClasses, sheetBodyClasses, sheetHeaderGapClasses, sheetPaddingXClasses, sheetPaddingYClasses, sheetRestClasses, sheetTitleClasses, surfaceSlots, transitionClasses } from '../../internal/styles.js';
|
|
6
|
-
const AccordionContext = /* @__PURE__ */ React.createContext({
|
|
7
|
-
size: 'md',
|
|
8
|
-
density: 'default',
|
|
9
|
-
dividers: true
|
|
10
|
-
});
|
|
11
|
-
/**
|
|
12
|
-
* A section sits one step down the radius ladder from the sheet it is inside,
|
|
13
|
-
* so a hovered header's corner is visibly inside the pane's own corner rather
|
|
14
|
-
* than fighting it.
|
|
15
|
-
*/
|
|
16
|
-
const itemRadiusClasses = {
|
|
17
|
-
xs: radiusClasses.xs,
|
|
18
|
-
sm: radiusClasses.xs,
|
|
19
|
-
md: radiusClasses.sm,
|
|
20
|
-
lg: radiusClasses.sm,
|
|
21
|
-
xl: radiusClasses.md
|
|
22
|
-
};
|
|
23
|
-
/**
|
|
24
|
-
* The rule between two sections, written as `>div+div` rather than as a class
|
|
25
|
-
* on each item so it holds however the caller composed them — through a
|
|
26
|
-
* `.map()`, through fragments, through a component of their own that renders an
|
|
27
|
-
* item.
|
|
28
|
-
*/
|
|
29
|
-
const dividerClasses = '[&>div+div]:border-t [&>div+div]:[border-color:var(--plass-divider)]';
|
|
30
|
-
/**
|
|
31
|
-
* The space between a header and the body it opened.
|
|
32
|
-
*
|
|
33
|
-
* The header's own padding does **not** pay for it, which is what this used to
|
|
34
|
-
* assume. An open header is a tinted band with its own bottom edge; the body
|
|
35
|
-
* begins at that edge, and the first line of text lands against it with only
|
|
36
|
-
* half a leading in between — the title and the paragraph explaining it read as
|
|
37
|
-
* one run of text broken by a colour change. What the header's padding buys is
|
|
38
|
-
* room around the *title*, and the body has to buy its own.
|
|
39
|
-
*
|
|
40
|
-
* It is a little under the padding below, because a paragraph's first line has
|
|
41
|
-
* the leading above it and its last has nothing under, so equal numbers on the
|
|
42
|
-
* two sides look bottom-heavy.
|
|
43
|
-
*/
|
|
44
|
-
const panelPaddingTopClasses = {
|
|
45
|
-
default: { xs: 'pt-1.5', sm: 'pt-2', md: 'pt-3', lg: 'pt-3.5', xl: 'pt-4' },
|
|
46
|
-
compact: { xs: 'pt-1', sm: 'pt-1.5', md: 'pt-2', lg: 'pt-2.5', xl: 'pt-3' }
|
|
47
|
-
};
|
|
48
|
-
/** And the space under it, on the same two tracks. */
|
|
49
|
-
const panelPaddingBottomClasses = {
|
|
50
|
-
default: { xs: 'pb-2.5', sm: 'pb-3', md: 'pb-5', lg: 'pb-6', xl: 'pb-7' },
|
|
51
|
-
compact: { xs: 'pb-2', sm: 'pb-2.5', md: 'pb-3.5', lg: 'pb-4', xl: 'pb-5' }
|
|
52
|
-
};
|
|
53
|
-
/**
|
|
54
|
-
* A stack of sections, one of which is open.
|
|
55
|
-
*
|
|
56
|
-
* Base UI owns the parts that are genuinely hard: the `button` / `region`
|
|
57
|
-
* pairing and the `aria-controls` / `aria-expanded` wiring between them, the
|
|
58
|
-
* open set, and measuring the panel so it has a height to animate from.
|
|
59
|
-
*
|
|
60
|
-
* What is here is the sheet, the ladders and the one motion decision. The
|
|
61
|
-
* panel's height *is* animated, which looks like an exception to the rule
|
|
62
|
-
* against moving things and is not: nothing is transformed, no text is
|
|
63
|
-
* resampled, and the content does not shift relative to the panel it is in —
|
|
64
|
-
* the panel is a window opening onto it. An accordion whose sections appear
|
|
65
|
-
* instantly is a page that jumps, which is the failure the rule exists to
|
|
66
|
-
* prevent.
|
|
67
|
-
*/
|
|
68
|
-
export const PlAccordion = /* @__PURE__ */ React.forwardRef(function PlAccordion({ variant = 'glass', size = 'md', color = 'primary', density = 'default', elevation = 0, multiple = false, value, defaultValue, onValueChange, dividers = true, disabled = false, hiddenUntilFound = false, keepMounted = false, className, style, children, ...props }, ref) {
|
|
69
|
-
const context = React.useMemo(() => ({ size, density, dividers }), [size, density, dividers]);
|
|
70
|
-
const classNames = [
|
|
71
|
-
'flex flex-col',
|
|
72
|
-
radiusClasses[size],
|
|
73
|
-
sheetRestClasses[variant],
|
|
74
|
-
transitionClasses,
|
|
75
|
-
// Scored, the rules have to reach both edges, so the sheet keeps no padding
|
|
76
|
-
// of its own and the corners clip whatever runs into them. Unscored, the
|
|
77
|
-
// sections are tiles and the sheet keeps a hair of padding so a hovered
|
|
78
|
-
// header does not run into the edge.
|
|
79
|
-
dividers ? `overflow-hidden ${dividerClasses}` : 'p-1',
|
|
80
|
-
className ?? ''
|
|
81
|
-
]
|
|
82
|
-
.filter(Boolean)
|
|
83
|
-
.join(' ');
|
|
84
|
-
return (_jsx(AccordionContext.Provider, { value: context, children: _jsx(BaseUIAccordion.Root, { ref: ref, multiple: multiple, value: value, defaultValue: defaultValue, onValueChange: (next) => onValueChange?.(next), disabled: disabled, hiddenUntilFound: hiddenUntilFound, keepMounted: keepMounted, className: classNames, style: { ...surfaceSlots(color, elevation), ...style }, ...props, children: children }) }));
|
|
85
|
-
});
|
|
86
|
-
/**
|
|
87
|
-
* One section.
|
|
88
|
-
*
|
|
89
|
-
* The header is always a row; what is inside it is a real `<button>` covering
|
|
90
|
-
* the title and the chevron, with `action` sitting outside that button as a
|
|
91
|
-
* control of its own.
|
|
92
|
-
*/
|
|
93
|
-
export const PlAccordionItem = /* @__PURE__ */ React.forwardRef(function PlAccordionItem({ value, title, subtitle, startIcon, action, disabled = false, className, children, ...props }, ref) {
|
|
94
|
-
const { size, density, dividers } = React.useContext(AccordionContext);
|
|
95
|
-
const padX = sheetPaddingXClasses[density][size];
|
|
96
|
-
const padY = sheetPaddingYClasses[density][size];
|
|
97
|
-
return (_jsxs(BaseUIAccordion.Item, { ref: ref, value: value, disabled: disabled, className: ['flex flex-col', className ?? ''].filter(Boolean).join(' '), ...props, children: [_jsxs(BaseUIAccordion.Header, { className: "m-0 flex w-full items-center [font:inherit]", children: [_jsxs(BaseUIAccordion.Trigger, { className: [
|
|
98
|
-
'flex min-w-0 flex-1 cursor-pointer items-center text-start',
|
|
99
|
-
padX,
|
|
100
|
-
padY,
|
|
101
|
-
gapClasses[size],
|
|
102
|
-
transitionClasses,
|
|
103
|
-
iconClasses,
|
|
104
|
-
// An outline on a clipped sheet would be cut off at the first and
|
|
105
|
-
// last section, so it is drawn inside the header instead. Two
|
|
106
|
-
// whole classes rather than one plus an override: a variant that
|
|
107
|
-
// only moves the offset resolves against the base by its position
|
|
108
|
-
// in the generated stylesheet, which is not something to bet a
|
|
109
|
-
// focus ring on.
|
|
110
|
-
dividers ? focusRingInsetClasses : `${focusRingClasses} ${itemRadiusClasses[size]}`,
|
|
111
|
-
'hover:bg-(--p-soft)',
|
|
112
|
-
'data-[panel-open]:bg-(--p-soft) data-[panel-open]:text-(--p-accent)',
|
|
113
|
-
'disabled:cursor-not-allowed disabled:bg-transparent disabled:opacity-50'
|
|
114
|
-
]
|
|
115
|
-
.filter(Boolean)
|
|
116
|
-
.join(' '), children: [hasContent(startIcon) ? (_jsx("span", { className: "flex h-[1lh] shrink-0 items-center text-(--plass-muted-fg)", children: startIcon })) : null, _jsxs("span", { className: `flex min-w-0 flex-1 flex-col ${sheetHeaderGapClasses[size]}`, children: [hasContent(title) ? (_jsx("span", { className: `plass-title truncate font-semibold ${sheetTitleClasses[size]}`, children: title })) : null, hasContent(subtitle) ? (_jsx("span", { className: `truncate text-(--plass-muted-fg) ${metaTextClasses[size]}`, children: subtitle })) : null] }), _jsx("span", { className: [
|
|
117
|
-
'flex h-[1lh] shrink-0 items-center text-(--plass-muted-fg)',
|
|
118
|
-
'[transition:rotate_var(--plass-duration)_var(--plass-ease)]',
|
|
119
|
-
'data-[panel-open]:rotate-180'
|
|
120
|
-
].join(' '), children: _jsx(ChevronIcon, {}) })] }), hasContent(action) ? (_jsx("span", { className: `flex shrink-0 items-center ${padX}`, children: action })) : null] }), _jsx(BaseUIAccordion.Panel, { className: [
|
|
121
|
-
'h-(--accordion-panel-height) overflow-hidden',
|
|
122
|
-
'[transition:height_var(--plass-duration-slow)_var(--plass-ease)]',
|
|
123
|
-
'data-[starting-style]:h-0 data-[ending-style]:h-0'
|
|
124
|
-
].join(' '), children: _jsx("div", { className: [
|
|
125
|
-
'text-(--plass-muted-fg)',
|
|
126
|
-
sheetBodyClasses[size],
|
|
127
|
-
padX,
|
|
128
|
-
panelPaddingTopClasses[density][size],
|
|
129
|
-
panelPaddingBottomClasses[density][size]
|
|
130
|
-
].join(' '), children: children }) })] }));
|
|
131
|
-
});
|
|
1
|
+
"use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import*as l from"react";import{Accordion as s}from"@base-ui/react/accordion";import{ChevronIcon as a}from"../../internal/icons.js";import{focusRingClasses as n,focusRingInsetClasses as i,gapClasses as r,hasContent as d,iconClasses as o,metaTextClasses as c,radiusClasses as p,sheetBodyClasses as m,sheetHeaderGapClasses as f,sheetPaddingXClasses as u,sheetPaddingYClasses as x,sheetRestClasses as h,sheetTitleClasses as v,surfaceSlots as b,transitionClasses as g}from"../../internal/styles.js";const N=/* @__PURE__ */l.createContext({size:"md",density:"default",dividers:!0}),j={xs:p.xs,sm:p.xs,md:p.sm,lg:p.sm,xl:p.md},y={default:{xs:"pt-1.5",sm:"pt-2",md:"pt-3",lg:"pt-3.5",xl:"pt-4"},compact:{xs:"pt-1",sm:"pt-1.5",md:"pt-2",lg:"pt-2.5",xl:"pt-3"}},w={default:{xs:"pb-2.5",sm:"pb-3",md:"pb-5",lg:"pb-6",xl:"pb-7"},compact:{xs:"pb-2",sm:"pb-2.5",md:"pb-3.5",lg:"pb-4",xl:"pb-5"}};export const PlAccordion=/* @__PURE__ */l.forwardRef(function PlAccordion({variant:t="glass",size:a="md",color:n="primary",density:i="default",elevation:r=0,multiple:d=!1,value:o,defaultValue:c,onValueChange:m,dividers:f=!0,disabled:u=!1,hiddenUntilFound:x=!1,keepMounted:v=!1,className:j,style:y,children:w,...P},$){const k=l.useMemo(()=>({size:a,density:i,dividers:f}),[a,i,f]),A=["flex flex-col",p[a],h[t],g,f?"overflow-hidden [&>div+div]:border-t [&>div+div]:[border-color:var(--plass-divider)]":"p-1",j??""].filter(Boolean).join(" ");return e(N.Provider,{value:k,children:e(s.Root,{ref:$,multiple:d,value:o,defaultValue:c,onValueChange:e=>m?.(e),disabled:u,hiddenUntilFound:x,keepMounted:v,className:A,style:{...b(n,r),...y},...P,children:w})})});export const PlAccordionItem=/* @__PURE__ */l.forwardRef(function PlAccordionItem({value:p,title:h,subtitle:b,startIcon:P,action:$,disabled:k=!1,className:A,children:z,...C},I){const{size:V,density:_,dividers:B}=l.useContext(N),M=u[_][V],R=x[_][V];return t(s.Item,{ref:I,value:p,disabled:k,className:["flex flex-col",A??""].filter(Boolean).join(" "),...C,children:[t(s.Header,{className:"m-0 flex w-full items-center [font:inherit]",children:[t(s.Trigger,{className:["flex min-w-0 flex-1 cursor-pointer items-center text-start",M,R,r[V],g,o,B?i:`${n} ${j[V]}`,"hover:bg-(--p-soft)","data-[panel-open]:bg-(--p-soft) data-[panel-open]:text-(--p-accent)","disabled:cursor-not-allowed disabled:bg-transparent disabled:opacity-50"].filter(Boolean).join(" "),children:[d(P)?e("span",{className:"flex h-[1lh] shrink-0 items-center text-(--plass-muted-fg)",children:P}):null,t("span",{className:`flex min-w-0 flex-1 flex-col ${f[V]}`,children:[d(h)?e("span",{className:`plass-title truncate font-semibold ${v[V]}`,children:h}):null,d(b)?e("span",{className:`truncate text-(--plass-muted-fg) ${c[V]}`,children:b}):null]}),e("span",{className:["flex h-[1lh] shrink-0 items-center text-(--plass-muted-fg)","[transition:rotate_var(--plass-duration)_var(--plass-ease)]","data-[panel-open]:rotate-180"].join(" "),children:e(a,{})})]}),d($)?e("span",{className:`flex shrink-0 items-center ${M}`,children:$}):null]}),e(s.Panel,{className:["h-(--accordion-panel-height) overflow-hidden","[transition:height_var(--plass-duration-slow)_var(--plass-ease)]","data-[starting-style]:h-0 data-[ending-style]:h-0"].join(" "),children:e("div",{className:["text-(--plass-muted-fg)",m[V],M,y[_][V],w[_][V]].join(" "),children:z})})]})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export{PlAccordion,PlAccordionItem}from"./PlAccordion.js";
|
|
@@ -1,109 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
import { CloseIcon, severityIcon } from '../../internal/icons.js';
|
|
4
|
-
import { controlSlots, focusRingClasses, glassClasses, hasContent, iconClasses, radiusClasses, sheetBodyClasses, sheetHeaderGapClasses, sheetPaddingXClasses, sheetPaddingYClasses, sheetSectionGapClasses, sheetTitleClasses, transitionClasses } from '../../internal/styles.js';
|
|
5
|
-
/**
|
|
6
|
-
* An alert **is** the thing being coloured — it is a notice about a severity,
|
|
7
|
-
* not a container holding someone else's content — so unlike a PlCard its sheet
|
|
8
|
-
* takes the tint. The same three materials they mean everywhere.
|
|
9
|
-
*
|
|
10
|
-
* `solid` carries no gloss line, exactly as a filled PlButton does not: the
|
|
11
|
-
* gradient is the form, and a white edge over the top of it reads as lacquer.
|
|
12
|
-
*/
|
|
13
|
-
const restClasses = {
|
|
14
|
-
solid: /* @__PURE__ */ [
|
|
15
|
-
'text-(--p-on-solid) [background-image:var(--p-fill)]',
|
|
16
|
-
'[box-shadow:var(--p-elev),var(--p-lift)]'
|
|
17
|
-
].join(' '),
|
|
18
|
-
glass: /* @__PURE__ */ [
|
|
19
|
-
glassClasses,
|
|
20
|
-
'border text-(--plass-fg) bg-(--plass-glass)',
|
|
21
|
-
'[border-color:var(--p-line)]',
|
|
22
|
-
'[box-shadow:var(--p-elev),var(--plass-gloss-glass)]'
|
|
23
|
-
].join(' '),
|
|
24
|
-
// No sheet and no edge, only the tint. For an alert set among form fields,
|
|
25
|
-
// where a second bordered rectangle is one rectangle too many.
|
|
26
|
-
ghost: 'text-(--plass-fg) bg-(--p-soft)'
|
|
27
|
-
};
|
|
28
|
-
/**
|
|
29
|
-
* On `solid` the surface already carries the family, so the glyph and the title
|
|
30
|
-
* ride on it as one ink. On the other two the surface is only faintly tinted:
|
|
31
|
-
* the message has to stay ordinary reading text, and the accent is spent on the
|
|
32
|
-
* two things that say which kind of alert this is.
|
|
33
|
-
*/
|
|
34
|
-
const accentClasses = {
|
|
35
|
-
solid: '',
|
|
36
|
-
glass: 'text-(--p-accent)',
|
|
37
|
-
ghost: 'text-(--p-accent)'
|
|
38
|
-
};
|
|
39
|
-
/**
|
|
40
|
-
* The detail line under a title.
|
|
41
|
-
*
|
|
42
|
-
* On a tinted surface it drops to the muted ink, the same step a field's
|
|
43
|
-
* description takes. On a filled one there is no muted ink to drop to — the
|
|
44
|
-
* page's grey is invisible on a gradient — so the ink stays and the title does
|
|
45
|
-
* the separating with its weight.
|
|
46
|
-
*/
|
|
47
|
-
const detailClasses = {
|
|
48
|
-
solid: '',
|
|
49
|
-
glass: 'text-(--plass-muted-fg)',
|
|
50
|
-
ghost: 'text-(--plass-muted-fg)'
|
|
51
|
-
};
|
|
52
|
-
/**
|
|
53
|
-
* Which live region an alert belongs in.
|
|
54
|
-
*
|
|
55
|
-
* `alert` interrupts whatever a screen reader is in the middle of saying;
|
|
56
|
-
* `status` waits for a pause. "This failed" is worth interrupting for and
|
|
57
|
-
* "saved" is not, so the severity decides — and a caller who knows better still
|
|
58
|
-
* wins, because their props spread after this.
|
|
59
|
-
*/
|
|
60
|
-
const rolesFor = {
|
|
61
|
-
primary: 'status',
|
|
62
|
-
secondary: 'status',
|
|
63
|
-
info: 'status',
|
|
64
|
-
success: 'status',
|
|
65
|
-
warning: 'alert',
|
|
66
|
-
danger: 'alert'
|
|
67
|
-
};
|
|
68
|
-
/**
|
|
69
|
-
* A message about something that happened, set into the page it is about.
|
|
70
|
-
*
|
|
71
|
-
* The three shapes people mean by "an alert" are one component with different
|
|
72
|
-
* slots filled rather than three components: a bare line
|
|
73
|
-
* (`<PlAlert icon={false}>`), a line with a glyph (the default), and a glyph
|
|
74
|
-
* with a headline and the detail under it (`title` plus `children`). Nothing
|
|
75
|
-
* about the surface changes between them — only how much of it is used.
|
|
76
|
-
*
|
|
77
|
-
* There is no Base UI primitive under this, and there should not be: an alert
|
|
78
|
-
* has no interaction to delegate. It is a live region with a layout, and the
|
|
79
|
-
* only interactive parts it can grow — the action and the dismiss button — are
|
|
80
|
-
* real buttons that the caller either passes in or gets by passing `onClose`.
|
|
81
|
-
*/
|
|
82
|
-
export const PlAlert = /* @__PURE__ */ React.forwardRef(function PlAlert({ variant = 'glass', size = 'md',
|
|
83
|
-
// An alert with no severity named is an informational one. This is the one
|
|
84
|
-
// place `primary` would be a lie: it is not the primary anything, it is a
|
|
85
|
-
// note, and the palette already has the word for that.
|
|
86
|
-
color = 'info', density = 'default', elevation = 0, title, icon, action, onClose, closeLabel = 'Dismiss', className, style, children, ...props }, ref) {
|
|
87
|
-
const glyph = icon === undefined ? severityIcon(color) : icon;
|
|
88
|
-
const accent = accentClasses[variant];
|
|
89
|
-
const titled = hasContent(title);
|
|
90
|
-
return (_jsxs("div", { ref: ref, role: rolesFor[color], className: [
|
|
91
|
-
'flex w-full items-start',
|
|
92
|
-
sheetPaddingXClasses[density][size],
|
|
93
|
-
sheetPaddingYClasses[density][size],
|
|
94
|
-
radiusClasses[size],
|
|
95
|
-
sheetSectionGapClasses[size],
|
|
96
|
-
sheetBodyClasses[size],
|
|
97
|
-
transitionClasses,
|
|
98
|
-
restClasses[variant],
|
|
99
|
-
iconClasses,
|
|
100
|
-
className ?? ''
|
|
101
|
-
]
|
|
102
|
-
.filter(Boolean)
|
|
103
|
-
.join(' '), style: { ...controlSlots(color, elevation, variant), ...style }, ...props, children: [hasContent(glyph) ? (_jsx("span", { className: `flex h-[1lh] shrink-0 items-center ${accent}`, children: glyph })) : null, _jsxs("div", { className: `flex min-w-0 flex-1 flex-col ${sheetHeaderGapClasses[size]}`, children: [titled ? (_jsx("div", { className: `plass-title font-semibold ${sheetTitleClasses[size]} ${accent}`, children: title })) : null, hasContent(children) ? (_jsx("div", { className: titled ? detailClasses[variant] : undefined, children: children })) : null] }), hasContent(action) ? (_jsx("div", { className: "flex h-[1lh] shrink-0 items-center", children: action })) : null, onClose ? (_jsx("span", { className: "flex h-[1lh] shrink-0 items-center", children: _jsx("button", { type: "button", "aria-label": closeLabel, onClick: onClose, className: [
|
|
104
|
-
'inline-flex size-[1.15em] cursor-pointer items-center justify-center rounded-full',
|
|
105
|
-
'opacity-70 [transition:opacity_var(--plass-duration)_var(--plass-ease)]',
|
|
106
|
-
'hover:opacity-100 focus-visible:opacity-100',
|
|
107
|
-
focusRingClasses
|
|
108
|
-
].join(' '), children: _jsx(CloseIcon, {}) }) })) : null] }));
|
|
109
|
-
});
|
|
1
|
+
"use client";import{jsx as s,jsxs as e}from"react/jsx-runtime";import*as l from"react";import{CloseIcon as t,severityIcon as a}from"../../internal/icons.js";import{controlSlots as i,focusRingClasses as r,glassClasses as n,hasContent as o,iconClasses as c,radiusClasses as d,sheetBodyClasses as f,sheetHeaderGapClasses as m,sheetPaddingXClasses as p,sheetPaddingYClasses as u,sheetSectionGapClasses as h,sheetTitleClasses as v,transitionClasses as x}from"../../internal/styles.js";const g={solid:/* @__PURE__ */["text-(--p-on-solid) [background-image:var(--p-fill)]","[box-shadow:var(--p-elev),var(--p-lift)]"].join(" "),glass:/* @__PURE__ */[n,"border text-(--plass-fg) bg-(--plass-glass)","[border-color:var(--p-line)]","[box-shadow:var(--p-elev),var(--plass-gloss-glass)]"].join(" "),ghost:"text-(--plass-fg) bg-(--p-soft)"},b={solid:"",glass:"text-(--p-accent)",ghost:"text-(--p-accent)"},y={solid:"",glass:"text-(--plass-muted-fg)",ghost:"text-(--plass-muted-fg)"},j={primary:"status",secondary:"status",info:"status",success:"status",warning:"alert",danger:"alert"};export const PlAlert=/* @__PURE__ */l.forwardRef(function PlAlert({variant:l="glass",size:n="md",color:N="info",density:w="default",elevation:k=0,title:$,icon:z,action:A,onClose:C,closeLabel:P="Dismiss",className:_,style:B,children:D,...L},R){const q=void 0===z?a(N):z,E=b[l],F=o($);return e("div",{ref:R,role:j[N],className:["flex w-full items-start",p[w][n],u[w][n],d[n],h[n],f[n],x,g[l],c,_??""].filter(Boolean).join(" "),style:{...i(N,k,l),...B},...L,children:[o(q)?s("span",{className:`flex h-[1lh] shrink-0 items-center ${E}`,children:q}):null,e("div",{className:`flex min-w-0 flex-1 flex-col ${m[n]}`,children:[F?s("div",{className:`plass-title font-semibold ${v[n]} ${E}`,children:$}):null,o(D)?s("div",{className:F?y[l]:void 0,children:D}):null]}),o(A)?s("div",{className:"flex h-[1lh] shrink-0 items-center",children:A}):null,C?s("span",{className:"flex h-[1lh] shrink-0 items-center",children:s("button",{type:"button","aria-label":P,onClick:C,className:["inline-flex size-[1.15em] cursor-pointer items-center justify-center rounded-full","opacity-70 [transition:opacity_var(--plass-duration)_var(--plass-ease)]","hover:opacity-100 focus-visible:opacity-100",r].join(" "),children:s(t,{})})}):null]})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export{PlAlert}from"./PlAlert.js";
|
|
@@ -1,71 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
import { useRender } from '@base-ui/react/use-render';
|
|
4
|
-
import { animBaseClass, animationClasses, animationSlots, isInfinite, slideOffsets, useAnimationRun } from '../../internal/animate.js';
|
|
5
|
-
import { cx } from '../../internal/styles.js';
|
|
6
|
-
/**
|
|
7
|
-
* A list of things settling into place one after another.
|
|
8
|
-
*
|
|
9
|
-
* Each child takes the same short drift and fade, held back by its position — so
|
|
10
|
-
* the effect belongs to the *set* rather than to any one item, and a reader's
|
|
11
|
-
* eye is walked down the list in the order it should be read.
|
|
12
|
-
*
|
|
13
|
-
* The animation is written onto the children themselves rather than onto
|
|
14
|
-
* wrappers around them. A row of `<li>`s stays a row of `<li>`s, a grid's cells
|
|
15
|
-
* stay its direct children, and nothing about the layout changes because the
|
|
16
|
-
* list is being animated. Only a bare string has no element to write onto, so
|
|
17
|
-
* that one is wrapped in a `<span>`.
|
|
18
|
-
*
|
|
19
|
-
* The stagger is per *child*, which means what you pass matters: eight children
|
|
20
|
-
* are eight steps, and one child holding eight things is one step. That is also
|
|
21
|
-
* how to opt part of a list out — group it.
|
|
22
|
-
*/
|
|
23
|
-
export const PlAnimateAppear = /* @__PURE__ */ React.forwardRef(function PlAnimateAppear({ duration = 380, delay = 0, easing, repeat = 1, alternate, paused, trigger = 'mount', play, once = true, threshold = 0.2, stagger = 70, from = 'bottom', distance = '0.75rem', fade = true, reverse = false, render, className, style, children, ...props }, ref) {
|
|
24
|
-
const run = useAnimationRun({
|
|
25
|
-
trigger,
|
|
26
|
-
play,
|
|
27
|
-
once,
|
|
28
|
-
threshold,
|
|
29
|
-
paused,
|
|
30
|
-
infinite: isInfinite(repeat)
|
|
31
|
-
});
|
|
32
|
-
const { x, y } = slideOffsets(from, distance);
|
|
33
|
-
const items = React.Children.toArray(children);
|
|
34
|
-
const itemClassName = `${animBaseClass} ${animationClasses.slide}`;
|
|
35
|
-
const animated = items.map((child, index) => {
|
|
36
|
-
const step = reverse ? items.length - 1 - index : index;
|
|
37
|
-
const slots = animationSlots({
|
|
38
|
-
duration,
|
|
39
|
-
delay: delay + step * stagger,
|
|
40
|
-
easing,
|
|
41
|
-
repeat,
|
|
42
|
-
alternate,
|
|
43
|
-
x,
|
|
44
|
-
y,
|
|
45
|
-
opacity: fade ? 0 : 1
|
|
46
|
-
});
|
|
47
|
-
if (!React.isValidElement(child)) {
|
|
48
|
-
return (_jsx("span", { className: itemClassName, style: slots, children: child }, index));
|
|
49
|
-
}
|
|
50
|
-
const childProps = child.props;
|
|
51
|
-
return React.cloneElement(child, {
|
|
52
|
-
className: cx(itemClassName, childProps.className),
|
|
53
|
-
style: { ...slots, ...childProps.style }
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
return useRender({
|
|
57
|
-
render,
|
|
58
|
-
ref: [ref, run.ref],
|
|
59
|
-
props: {
|
|
60
|
-
...props,
|
|
61
|
-
className,
|
|
62
|
-
// Only the play state lives on the root. Every other slot is per child,
|
|
63
|
-
// because the delay is what the whole effect is made of.
|
|
64
|
-
style: { '--p-anim-state': run.state, ...style },
|
|
65
|
-
...run.handlers,
|
|
66
|
-
'data-plass-animation': 'appear',
|
|
67
|
-
'data-state': run.state,
|
|
68
|
-
children: animated
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
});
|
|
1
|
+
"use client";import{jsx as e}from"react/jsx-runtime";import*as a from"react";import{useRender as t}from"@base-ui/react/use-render";import{animBaseClass as r,animationClasses as s,animationSlots as n,isInfinite as i,slideOffsets as l,useAnimationRun as o}from"../../internal/animate.js";import{cx as m}from"../../internal/styles.js";export const PlAnimateAppear=/* @__PURE__ */a.forwardRef(function PlAnimateAppear({duration:p=380,delay:d=0,easing:c,repeat:f=1,alternate:y,paused:u,trigger:h="mount",play:g,once:x=!0,threshold:A=.2,stagger:N=70,from:j="bottom",distance:b="0.75rem",fade:E=!0,reverse:P=!1,render:$,className:v,style:w,children:C,...R},V){const k=o({trigger:h,play:g,once:x,threshold:A,paused:u,infinite:i(f)}),{x:q,y:z}=l(j,b),B=a.Children.toArray(C),D=`${r} ${s.slide}`,F=B.map((t,r)=>{const s=P?B.length-1-r:r,i=n({duration:p,delay:d+s*N,easing:c,repeat:f,alternate:y,x:q,y:z,opacity:E?0:1});if(!a.isValidElement(t))return e("span",{className:D,style:i,children:t},r);const l=t.props;return a.cloneElement(t,{className:m(D,l.className),style:{...i,...l.style}})});return t({render:$,ref:[V,k.ref],props:{...R,className:v,style:{"--p-anim-state":k.state,...w},...k.handlers,"data-plass-animation":"appear","data-state":k.state,children:F}})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export{PlAnimateAppear}from"./PlAnimateAppear.js";
|
|
@@ -1,47 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { useRender } from '@base-ui/react/use-render';
|
|
3
|
-
import { isInfinite, useAnimateElement } from '../../internal/animate.js';
|
|
4
|
-
import { cx } from '../../internal/styles.js';
|
|
5
|
-
/**
|
|
6
|
-
* Content pulsing between full opacity and a floor.
|
|
7
|
-
*
|
|
8
|
-
* The cycle is symmetric — full, faint, full — so however many times it runs it
|
|
9
|
-
* ends where it started. A blink that finished halfway would leave the element
|
|
10
|
-
* permanently half drawn, which reads as a rendering fault rather than as an
|
|
11
|
-
* effect that ended.
|
|
12
|
-
*
|
|
13
|
-
* It repeats forever unless told otherwise, because a single blink is a flicker
|
|
14
|
-
* and nobody asks for a flicker. Two things are worth saying about using it at
|
|
15
|
-
* all: something that never stops moving in the corner of a page being read is
|
|
16
|
-
* the one kind of motion this library otherwise refuses, and a reader with a
|
|
17
|
-
* reduced-motion preference will see none of it — so `min` is a dimming, never
|
|
18
|
-
* the only thing carrying the message. If it is urgent, say so in words too.
|
|
19
|
-
*/
|
|
20
|
-
export const PlAnimateBlink = /* @__PURE__ */ React.forwardRef(function PlAnimateBlink({ duration = 1000, delay = 0, easing, repeat = 'infinite', alternate, paused, trigger = 'mount', play, once = true, threshold = 0.2, min = 0, render, className, style, children, ...props }, ref) {
|
|
21
|
-
const animate = useAnimateElement({
|
|
22
|
-
effect: 'blink',
|
|
23
|
-
duration,
|
|
24
|
-
delay,
|
|
25
|
-
easing,
|
|
26
|
-
repeat,
|
|
27
|
-
alternate,
|
|
28
|
-
opacity: min,
|
|
29
|
-
trigger,
|
|
30
|
-
play,
|
|
31
|
-
once,
|
|
32
|
-
threshold,
|
|
33
|
-
paused,
|
|
34
|
-
infinite: isInfinite(repeat)
|
|
35
|
-
});
|
|
36
|
-
return useRender({
|
|
37
|
-
render,
|
|
38
|
-
ref: [ref, animate.ref],
|
|
39
|
-
props: {
|
|
40
|
-
...props,
|
|
41
|
-
className: cx(animate.className, className),
|
|
42
|
-
style: { ...animate.style, ...style },
|
|
43
|
-
...animate.props,
|
|
44
|
-
children
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
});
|
|
1
|
+
"use client";import*as e from"react";import{useRender as r}from"@base-ui/react/use-render";import{isInfinite as t,useAnimateElement as n}from"../../internal/animate.js";import{cx as a}from"../../internal/styles.js";export const PlAnimateBlink=/* @__PURE__ */e.forwardRef(function PlAnimateBlink({duration:e=1e3,delay:i=0,easing:s,repeat:l="infinite",alternate:o,paused:m,trigger:p="mount",play:c,once:d=!0,threshold:f=.2,min:u=0,render:y,className:g,style:h,children:k,...N},b){const j=n({effect:"blink",duration:e,delay:i,easing:s,repeat:l,alternate:o,opacity:u,trigger:p,play:c,once:d,threshold:f,paused:m,infinite:t(l)});return r({render:y,ref:[b,j.ref],props:{...N,className:a(j.className,g),style:{...j.style,...h},...j.props,children:k}})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export{PlAnimateBlink}from"./PlAnimateBlink.js";
|
|
@@ -1,48 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { useRender } from '@base-ui/react/use-render';
|
|
3
|
-
import { isInfinite, useAnimateElement } from '../../internal/animate.js';
|
|
4
|
-
import { cx } from '../../internal/styles.js';
|
|
5
|
-
/**
|
|
6
|
-
* Content arriving or leaving on opacity alone.
|
|
7
|
-
*
|
|
8
|
-
* The plainest effect in the set and the one to reach for first: nothing moves,
|
|
9
|
-
* so nothing reflows and nothing is resampled. A fade is the only entrance that
|
|
10
|
-
* is safe on a block of text at any size.
|
|
11
|
-
*
|
|
12
|
-
* It is also the effect that suits glass. A Plass sheet is defined by what
|
|
13
|
-
* shows through it, and opacity is the axis the material already answers on —
|
|
14
|
-
* the same axis the glass ladder itself is built from.
|
|
15
|
-
*
|
|
16
|
-
* `mode="out"` is the same animation run backwards, and it is held at the end:
|
|
17
|
-
* a faded-out element stays faded out rather than snapping back into view when
|
|
18
|
-
* the animation finishes.
|
|
19
|
-
*/
|
|
20
|
-
export const PlAnimateFade = /* @__PURE__ */ React.forwardRef(function PlAnimateFade({ duration = 300, delay = 0, easing, repeat = 1, alternate, paused, trigger = 'mount', play, once = true, threshold = 0.2, mode = 'in', from = 0, render, className, style, children, ...props }, ref) {
|
|
21
|
-
const animate = useAnimateElement({
|
|
22
|
-
effect: 'fade',
|
|
23
|
-
duration,
|
|
24
|
-
delay,
|
|
25
|
-
easing,
|
|
26
|
-
repeat,
|
|
27
|
-
alternate,
|
|
28
|
-
mode,
|
|
29
|
-
opacity: from,
|
|
30
|
-
trigger,
|
|
31
|
-
play,
|
|
32
|
-
once,
|
|
33
|
-
threshold,
|
|
34
|
-
paused,
|
|
35
|
-
infinite: isInfinite(repeat)
|
|
36
|
-
});
|
|
37
|
-
return useRender({
|
|
38
|
-
render,
|
|
39
|
-
ref: [ref, animate.ref],
|
|
40
|
-
props: {
|
|
41
|
-
...props,
|
|
42
|
-
className: cx(animate.className, className),
|
|
43
|
-
style: { ...animate.style, ...style },
|
|
44
|
-
...animate.props,
|
|
45
|
-
children
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
});
|
|
1
|
+
"use client";import*as e from"react";import{useRender as r}from"@base-ui/react/use-render";import{isInfinite as a,useAnimateElement as t}from"../../internal/animate.js";import{cx as n}from"../../internal/styles.js";export const PlAnimateFade=/* @__PURE__ */e.forwardRef(function PlAnimateFade({duration:e=300,delay:s=0,easing:o,repeat:i=1,alternate:l,paused:d,trigger:m="mount",play:p,once:c=!0,threshold:f=.2,mode:u="in",from:y=0,render:g,className:h,style:N,children:j,...A},F){const P=t({effect:"fade",duration:e,delay:s,easing:o,repeat:i,alternate:l,mode:u,opacity:y,trigger:m,play:p,once:c,threshold:f,paused:d,infinite:a(i)});return r({render:g,ref:[F,P.ref],props:{...A,className:n(P.className,h),style:{...P.style,...N},...P.props,children:j}})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export{PlAnimateFade}from"./PlAnimateFade.js";
|
|
@@ -1,49 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { useRender } from '@base-ui/react/use-render';
|
|
3
|
-
import { isInfinite, useAnimateElement } from '../../internal/animate.js';
|
|
4
|
-
import { cx } from '../../internal/styles.js';
|
|
5
|
-
/**
|
|
6
|
-
* Content unfolding from a point.
|
|
7
|
-
*
|
|
8
|
-
* The difference from Zoom is `origin` and how far it travels: a Grow starts
|
|
9
|
-
* close to its final size and can be anchored to an edge, so it reads as
|
|
10
|
-
* something opening out of the thing beside it — a panel out of a toolbar, a
|
|
11
|
-
* card out of the row it belongs to. A Zoom starts much smaller and always from
|
|
12
|
-
* the middle.
|
|
13
|
-
*
|
|
14
|
-
* Short travel is what makes it safe on glass. A sheet growing from 0.8 stays
|
|
15
|
-
* recognisably the same sheet the whole way, and the blur behind it never has
|
|
16
|
-
* to resolve a surface that is a fifth of the size it is about to be.
|
|
17
|
-
*/
|
|
18
|
-
export const PlAnimateGrow = /* @__PURE__ */ React.forwardRef(function PlAnimateGrow({ duration = 320, delay = 0, easing, repeat = 1, alternate, paused, trigger = 'mount', play, once = true, threshold = 0.2, mode = 'in', from = 0.8, origin = 'center', fade = true, render, className, style, children, ...props }, ref) {
|
|
19
|
-
const animate = useAnimateElement({
|
|
20
|
-
effect: 'grow',
|
|
21
|
-
duration,
|
|
22
|
-
delay,
|
|
23
|
-
easing,
|
|
24
|
-
repeat,
|
|
25
|
-
alternate,
|
|
26
|
-
mode,
|
|
27
|
-
scale: from,
|
|
28
|
-
opacity: fade ? 0 : 1,
|
|
29
|
-
trigger,
|
|
30
|
-
play,
|
|
31
|
-
once,
|
|
32
|
-
threshold,
|
|
33
|
-
paused,
|
|
34
|
-
infinite: isInfinite(repeat)
|
|
35
|
-
});
|
|
36
|
-
return useRender({
|
|
37
|
-
render,
|
|
38
|
-
ref: [ref, animate.ref],
|
|
39
|
-
props: {
|
|
40
|
-
...props,
|
|
41
|
-
className: cx(animate.className, className),
|
|
42
|
-
// `transform-origin` governs the standalone `scale` property too, which
|
|
43
|
-
// is what lets the effect stay off the `transform` shorthand entirely.
|
|
44
|
-
style: { transformOrigin: origin, ...animate.style, ...style },
|
|
45
|
-
...animate.props,
|
|
46
|
-
children
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
});
|
|
1
|
+
"use client";import*as e from"react";import{useRender as r}from"@base-ui/react/use-render";import{isInfinite as t,useAnimateElement as a}from"../../internal/animate.js";import{cx as n}from"../../internal/styles.js";export const PlAnimateGrow=/* @__PURE__ */e.forwardRef(function PlAnimateGrow({duration:e=320,delay:o=0,easing:i,repeat:s=1,alternate:l,paused:m,trigger:c="mount",play:d,once:p=!0,threshold:f=.2,mode:u="in",from:g=.8,origin:y="center",fade:h=!0,render:w,className:N,style:j,children:A,...G},P){const b=a({effect:"grow",duration:e,delay:o,easing:i,repeat:s,alternate:l,mode:u,scale:g,opacity:h?0:1,trigger:c,play:d,once:p,threshold:f,paused:m,infinite:t(s)});return r({render:w,ref:[P,b.ref],props:{...G,className:n(b.className,N),style:{transformOrigin:y,...b.style,...j},...b.props,children:A}})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export{PlAnimateGrow}from"./PlAnimateGrow.js";
|
|
@@ -1,120 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
import { isInfinite, lengthValue, useAnimationRun, usePrefersReducedMotion } from '../../internal/animate.js';
|
|
4
|
-
import { cx } from '../../internal/styles.js';
|
|
5
|
-
/**
|
|
6
|
-
* One line replacing the one above it, on a timer.
|
|
7
|
-
*
|
|
8
|
-
* Every line sits in the same grid cell, so the box is as tall as the longest of
|
|
9
|
-
* them from the first frame and never resizes as the reel turns — which is the
|
|
10
|
-
* whole difficulty with this effect, and the reason the lines that are not
|
|
11
|
-
* showing keep their space with `visibility` rather than being taken out of the
|
|
12
|
-
* layout.
|
|
13
|
-
*
|
|
14
|
-
* It is deliberately not a ticker. A line comes up, it stops, and it is held
|
|
15
|
-
* long enough to read; `interval` is counted from the moment it arrives rather
|
|
16
|
-
* than from the start of the cycle, so raising `duration` does not quietly eat
|
|
17
|
-
* the reading time.
|
|
18
|
-
*
|
|
19
|
-
* Use it for a set of phrases where any one of them would have done — three
|
|
20
|
-
* ways of saying what a product is, a rotating set of customer names. What it is
|
|
21
|
-
* not for is content a reader has to see, because there is no guarantee they are
|
|
22
|
-
* looking during the two seconds it is up, and a screen reader is given the line
|
|
23
|
-
* that happens to be showing rather than the set.
|
|
24
|
-
*/
|
|
25
|
-
export const PlAnimateHeadline = /* @__PURE__ */ React.forwardRef(function PlAnimateHeadline({ duration = 460, delay = 0, easing, repeat = 'infinite', paused, trigger = 'mount', play, once = true, threshold = 0.2, interval = 2600, index, defaultIndex = 0, onIndexChange, loop = true, rise = '100%', className, style, children, ...props }, ref) {
|
|
26
|
-
const run = useAnimationRun({
|
|
27
|
-
trigger,
|
|
28
|
-
play,
|
|
29
|
-
once,
|
|
30
|
-
threshold,
|
|
31
|
-
paused,
|
|
32
|
-
infinite: isInfinite(repeat)
|
|
33
|
-
});
|
|
34
|
-
const reduced = usePrefersReducedMotion();
|
|
35
|
-
const items = React.Children.toArray(children);
|
|
36
|
-
const count = items.length;
|
|
37
|
-
const [uncontrolled, setUncontrolled] = React.useState(defaultIndex);
|
|
38
|
-
const active = Math.min(index ?? uncontrolled, Math.max(count - 1, 0));
|
|
39
|
-
/** The line on its way out. Cleared once its animation has had its time. */
|
|
40
|
-
const [leaving, setLeaving] = React.useState(null);
|
|
41
|
-
const previous = React.useRef(active);
|
|
42
|
-
React.useEffect(() => {
|
|
43
|
-
if (previous.current !== active) {
|
|
44
|
-
setLeaving(previous.current);
|
|
45
|
-
previous.current = active;
|
|
46
|
-
}
|
|
47
|
-
}, [active]);
|
|
48
|
-
React.useEffect(() => {
|
|
49
|
-
if (leaving === null) {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
const timer = setTimeout(() => setLeaving(null), duration);
|
|
53
|
-
return () => clearTimeout(timer);
|
|
54
|
-
}, [leaving, duration]);
|
|
55
|
-
const advance = React.useCallback(() => {
|
|
56
|
-
const next = active + 1;
|
|
57
|
-
if (next >= count) {
|
|
58
|
-
if (!loop) {
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
if (index === undefined) {
|
|
62
|
-
setUncontrolled(0);
|
|
63
|
-
}
|
|
64
|
-
onIndexChange?.(0);
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
if (index === undefined) {
|
|
68
|
-
setUncontrolled(next);
|
|
69
|
-
}
|
|
70
|
-
onIndexChange?.(next);
|
|
71
|
-
}, [active, count, loop, index, onIndexChange]);
|
|
72
|
-
/**
|
|
73
|
-
* The reel only turns on its own when it was not handed an `index`. A
|
|
74
|
-
* controlled Headline is somebody else's timer, and a second one running
|
|
75
|
-
* underneath it would fight for the same state.
|
|
76
|
-
*/
|
|
77
|
-
const turned = React.useRef(false);
|
|
78
|
-
React.useEffect(() => {
|
|
79
|
-
if (index !== undefined || count < 2 || run.state !== 'running') {
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
if (!loop && active === count - 1) {
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
// `delay` is what happens before the reel starts turning at all, so it is
|
|
86
|
-
// added once rather than to every line — which is what an `interval` is.
|
|
87
|
-
const timer = setTimeout(() => {
|
|
88
|
-
turned.current = true;
|
|
89
|
-
advance();
|
|
90
|
-
}, interval + (turned.current ? 0 : delay));
|
|
91
|
-
return () => clearTimeout(timer);
|
|
92
|
-
}, [index, count, run.state, interval, delay, advance, loop, active]);
|
|
93
|
-
return (_jsx("div", { ref: (node) => {
|
|
94
|
-
run.ref(node);
|
|
95
|
-
if (typeof ref === 'function') {
|
|
96
|
-
ref(node);
|
|
97
|
-
}
|
|
98
|
-
else if (ref) {
|
|
99
|
-
ref.current = node;
|
|
100
|
-
}
|
|
101
|
-
}, className: cx('plass-headline', className), style: {
|
|
102
|
-
'--p-anim-duration': `${duration}ms`,
|
|
103
|
-
'--p-anim-rise': lengthValue(rise),
|
|
104
|
-
...(easing ? { '--p-anim-ease': easing } : {}),
|
|
105
|
-
'--p-anim-state': run.state,
|
|
106
|
-
...style
|
|
107
|
-
}, "data-plass-animation": "headline", "data-state": run.state, ...run.handlers, ...props, children: items.map((child, position) => {
|
|
108
|
-
const state = position === active ? 'active' : position === leaving && !reduced ? 'leaving' : undefined;
|
|
109
|
-
const wrap = (content, key) => (_jsx("span", { className: "plass-headline-item", "data-state": state, children: content }, key));
|
|
110
|
-
if (!React.isValidElement(child)) {
|
|
111
|
-
return wrap(child, position);
|
|
112
|
-
}
|
|
113
|
-
const childProps = child.props;
|
|
114
|
-
return React.cloneElement(child, {
|
|
115
|
-
key: position,
|
|
116
|
-
className: cx('plass-headline-item', childProps.className),
|
|
117
|
-
'data-state': state
|
|
118
|
-
});
|
|
119
|
-
}) }));
|
|
120
|
-
});
|
|
1
|
+
"use client";import{jsx as e}from"react/jsx-runtime";import*as t from"react";import{isInfinite as n,lengthValue as a,useAnimationRun as r,usePrefersReducedMotion as i}from"../../internal/animate.js";import{cx as s}from"../../internal/styles.js";export const PlAnimateHeadline=/* @__PURE__ */t.forwardRef(function PlAnimateHeadline({duration:l=460,delay:o=0,easing:u,repeat:c="infinite",paused:m,trigger:d="mount",play:f,once:p=!0,threshold:h=.2,interval:g=2600,index:v,defaultIndex:y=0,onIndexChange:x,loop:E=!0,rise:N="100%",className:j,style:T,children:A,...C},R){const k=r({trigger:d,play:f,once:p,threshold:h,paused:m,infinite:n(c)}),H=i(),I=t.Children.toArray(A),M=I.length,[P,S]=t.useState(y),b=Math.min(v??P,Math.max(M-1,0)),[w,V]=t.useState(null),$=t.useRef(b);t.useEffect(()=>{$.current!==b&&(V($.current),$.current=b)},[b]),t.useEffect(()=>{if(null===w)return;const e=setTimeout(()=>V(null),l);return()=>clearTimeout(e)},[w,l]);const q=t.useCallback(()=>{const e=b+1;if(e>=M){if(!E)return;return void 0===v&&S(0),void x?.(0)}void 0===v&&S(e),x?.(e)},[b,M,E,v,x]),z=t.useRef(!1);return t.useEffect(()=>{if(void 0!==v||M<2||"running"!==k.state)return;if(!E&&b===M-1)return;const e=setTimeout(()=>{z.current=!0,q()},g+(z.current?0:o));return()=>clearTimeout(e)},[v,M,k.state,g,o,q,E,b]),e("div",{ref:e=>{k.ref(e),"function"==typeof R?R(e):R&&(R.current=e)},className:s("plass-headline",j),style:{"--p-anim-duration":`${l}ms`,"--p-anim-rise":a(N),...u?{"--p-anim-ease":u}:{},"--p-anim-state":k.state,...T},"data-plass-animation":"headline","data-state":k.state,...k.handlers,...C,children:I.map((n,a)=>{const r=a===b?"active":a!==w||H?void 0:"leaving";if(!t.isValidElement(n))return e("span",{className:"plass-headline-item","data-state":r,children:n},a);const i=n.props;return t.cloneElement(n,{key:a,className:s("plass-headline-item",i.className),"data-state":r})})})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export{PlAnimateHeadline}from"./PlAnimateHeadline.js";
|