plass-ui 1.0.0 → 1.0.2
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 +165 -0
- 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 +5 -3
package/README.md
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# Plass UI for React
|
|
2
|
+
|
|
3
|
+
[](https://github.com/jooy2/plass-ui/blob/main/LICENSE) [](https://www.npmjs.com/package/plass-ui) [](https://www.npmjs.com/package/plass-ui)
|
|
4
|
+
|
|
5
|
+
### 📘 [**plass.cdget.com**](https://plass.cdget.com)
|
|
6
|
+
|
|
7
|
+
Live previews and full props for every component — pick **React** in the sidebar. This README is just the quick start.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
**Plass UI is a component library with a material rather than a theme.** Every surface answers one question — is this pressed, or does it hold something? — and the answer decides everything else.
|
|
12
|
+
|
|
13
|
+
A thing that is pressed is **tinted glass**: a gradient that sweeps between two ends of its colour family at 135°, a drop shadow tinted with that family, and a bloom of light that follows the pointer across it. A thing that holds something is **clear glass**: translucent, heavily blurred, a white hairline round it, and never dyed. There is no third answer.
|
|
14
|
+
|
|
15
|
+
This is the React half of that language. The [Flutter package](https://pub.dev/packages/plass_ui) is the other one, and the two are the same numbers.
|
|
16
|
+
|
|
17
|
+
- **Two materials, one language** — `solid`, `glass`, `ghost`. Not `filled`, `outlined`, `text`.
|
|
18
|
+
- **Light instead of relief** — no bevels and no highlights. The gradient carries the form, and a soft glow follows your pointer across the control.
|
|
19
|
+
- **One shared vocabulary** — `size`, `color`, `variant`, `density`, `elevation`. An `md` is 40px on every control; `primary` is the same family everywhere, and the same family it is in Flutter.
|
|
20
|
+
- **Accessible by construction** — real roles, labels, focus management and keyboard support, not `div`s with click handlers.
|
|
21
|
+
- **Contrast that was checked** — every gradient stop clears 4.5:1 against its own label, the lightest corner included.
|
|
22
|
+
- **Dark mode with no work** — follows `prefers-color-scheme`, and can be forced either way per subtree.
|
|
23
|
+
- **ESM only**, TypeScript declarations included, tree-shakeable, with an entry point per component.
|
|
24
|
+
- **One runtime dependency**, [Base UI](https://base-ui.com), which is where the interaction and accessibility behaviour comes from.
|
|
25
|
+
|
|
26
|
+
> **Both packages ship the same library.** Every component listed below exists in each, under the same prop vocabulary and the same tokens. They version independently, so this package's number and the Flutter one's will not always agree.
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install plass-ui
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
`react` and `react-dom` are peer dependencies — React 18 or 19. Node.js 20.19 or later.
|
|
35
|
+
|
|
36
|
+
### Setup
|
|
37
|
+
|
|
38
|
+
Add one line to your app's CSS entry point:
|
|
39
|
+
|
|
40
|
+
```css
|
|
41
|
+
@import 'plass-ui/styles.css';
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`plass-ui/styles.css` is finished CSS — the design tokens, the compiled rules for every utility class the components use, and a small reset whose every rule is specificity 0 so your own styles always win. [Tailwind CSS](https://tailwindcss.com) v4 builds this package; it does not have to be installed in yours.
|
|
45
|
+
|
|
46
|
+
If your project already runs Tailwind v4, import the token sheet instead:
|
|
47
|
+
|
|
48
|
+
```css
|
|
49
|
+
@import 'tailwindcss';
|
|
50
|
+
@import 'plass-ui/tailwind.css';
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`plass-ui/tailwind.css` registers all 74 components with Tailwind, because Tailwind scans files rather than imports — nothing in a build connects `import { PlButton }` to the classes `PlSelect.js` spells out. A project that uses a handful of components can register the handful instead:
|
|
54
|
+
|
|
55
|
+
```css
|
|
56
|
+
@import 'tailwindcss';
|
|
57
|
+
@import 'plass-ui/css/base.css'; /* tokens + what every component shares */
|
|
58
|
+
@import 'plass-ui/css/button.css';
|
|
59
|
+
@import 'plass-ui/css/text-field.css';
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Still one Tailwind pass, so the utilities keep Tailwind's own order — and about 5 kB gzipped smaller for a small set of components. There is one manifest per component, named after its folder in `dist/components`.
|
|
63
|
+
|
|
64
|
+
### The page under the components
|
|
65
|
+
|
|
66
|
+
Plass draws controls and sheets. It does not paint your `<body>` — but a sheet of glass over a flat white page has nothing to be in front of, and every translucent surface in the library will read as opaque. Two tokens exist for exactly this:
|
|
67
|
+
|
|
68
|
+
```css
|
|
69
|
+
body {
|
|
70
|
+
background: linear-gradient(160deg, var(--plass-bg-from) 0%, var(--plass-bg-to) 100%);
|
|
71
|
+
background-attachment: fixed;
|
|
72
|
+
color: var(--plass-fg);
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Any backdrop with structure in it works. What does not work is nothing at all.
|
|
77
|
+
|
|
78
|
+
## Use
|
|
79
|
+
|
|
80
|
+
```tsx
|
|
81
|
+
import { PlButton, PlTextField } from 'plass-ui';
|
|
82
|
+
|
|
83
|
+
export default function SignIn() {
|
|
84
|
+
return (
|
|
85
|
+
<form onSubmit={submit}>
|
|
86
|
+
<PlTextField label="Email" type="email" fullWidth />
|
|
87
|
+
<PlButton type="submit">Sign in</PlButton>
|
|
88
|
+
<PlButton variant="glass" color="secondary">
|
|
89
|
+
Cancel
|
|
90
|
+
</PlButton>
|
|
91
|
+
</form>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### One entry point per component
|
|
97
|
+
|
|
98
|
+
Every component also has an entry point of its own, for a build that cannot tree-shake a barrel — or for a server render, where the barrel loads all 74 components and their dependencies before the first one is used:
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
import { PlButton } from 'plass-ui/button';
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Same component, same types. The barrel is the one to reach for by default; this is the escape hatch when a bundler, a test runner or Node's own loader is the thing paying for it.
|
|
105
|
+
|
|
106
|
+
### Next.js and server components
|
|
107
|
+
|
|
108
|
+
Every component carries `'use client'`, so a Server Component can import one directly and there is nothing to configure — no `transpilePackages`, no `next.config` entry, no provider. What the directive cannot do is carry a function across the server boundary: a file that passes `onClick`, `onValueChange` or `render` needs its own `'use client'`, which is React's rule for every client component rather than this library's. Outside a server-component graph the directive is inert.
|
|
109
|
+
|
|
110
|
+
### Dark mode
|
|
111
|
+
|
|
112
|
+
Follows `prefers-color-scheme` with no configuration. To force it either way, put `.dark` / `.light` — or `[data-theme='dark']` / `[data-theme='light']` — on any ancestor, `<html>` included.
|
|
113
|
+
|
|
114
|
+
One thing does **not** change with the theme, and it is deliberate: the colour of a key. What changes is the sheet it rests on.
|
|
115
|
+
|
|
116
|
+
## Components
|
|
117
|
+
|
|
118
|
+
Every component is exported under a `Pl` prefix — `Button`, `Card` and `Table` are the most-taken identifiers in the ecosystem, and a consumer should not have to alias ours on import.
|
|
119
|
+
|
|
120
|
+
### Display
|
|
121
|
+
|
|
122
|
+
`PlAvatar` · `PlBadge` · `PlBlockquote` · `PlBreadcrumb` · `PlChip` · `PlDivider` · `PlHighlight` · `PlHotKeys` · `PlIcon` · `PlList` · `PlTable` · `PlTextLink` · `PlTimeline` · `PlTypography`
|
|
123
|
+
|
|
124
|
+
### Feedback
|
|
125
|
+
|
|
126
|
+
`PlAlert` · `PlDrawer` · `PlModal` · `PlOverlay` · `PlPopover` · `PlProgressBox` · `PlProgressCircular` · `PlProgressLinear` · `PlSkeleton` · `PlToast` · `PlTooltip`
|
|
127
|
+
|
|
128
|
+
### Inputs
|
|
129
|
+
|
|
130
|
+
`PlButton` · `PlButtonGroup` · `PlCheckbox` · `PlCombobox` · `PlDatePicker` · `PlDateRangePicker` · `PlDateTimePicker` · `PlFilePicker` · `PlIconButton` · `PlNumberField` · `PlOtpField` · `PlPagination` · `PlRadioGroup` · `PlRating` · `PlSegmentedButton` · `PlSelect` · `PlSlider` · `PlSwitch` · `PlTextField` · `PlTimePicker`
|
|
131
|
+
|
|
132
|
+
### Layout
|
|
133
|
+
|
|
134
|
+
`PlAspectRatio` · `PlContainer` · `PlGrid` · `PlPanes` · `PlScrollZone`
|
|
135
|
+
|
|
136
|
+
### Navigation
|
|
137
|
+
|
|
138
|
+
`PlBottomNavigation` · `PlContextMenu` · `PlFloatingBottomNavigation` · `PlMenu`
|
|
139
|
+
|
|
140
|
+
### Surfaces
|
|
141
|
+
|
|
142
|
+
`PlAccordion` · `PlBox` · `PlCard` · `PlCarousel` · `PlChatBubble` · `PlCollapsible` · `PlPill` · `PlSpoiler` · `PlTabs` · `PlToolbar`
|
|
143
|
+
|
|
144
|
+
### Transitions
|
|
145
|
+
|
|
146
|
+
`PlAnimateAppear` · `PlAnimateBlink` · `PlAnimateFade` · `PlAnimateGrow` · `PlAnimateHeadline` · `PlAnimateLighting` · `PlAnimateMarquee` · `PlAnimateRotate` · `PlAnimateSlide` · `PlAnimateTyping` · `PlAnimateZoom`
|
|
147
|
+
|
|
148
|
+
## Development
|
|
149
|
+
|
|
150
|
+
This package is installed and run from its own folder; there is no install at the repository root.
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
npm install
|
|
154
|
+
npm test # Vitest, single run (headless Chromium)
|
|
155
|
+
npm run typecheck # tsc --noEmit over both TS projects
|
|
156
|
+
npm run build # tsc + terser + build-styles → dist/
|
|
157
|
+
npm run lint # ESLint
|
|
158
|
+
npm run size # what the package costs, packed and installed
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
The documentation site lives at the repository root, in [`docs/`](https://github.com/jooy2/plass-ui/tree/main/docs), and renders these components from `src/` through a Vite alias — so `cd docs && npm run dev` is the develop-and-eyeball loop and there is no separate demo app. [CONTRIBUTING.md](https://github.com/jooy2/plass-ui/blob/main/CONTRIBUTING.md) has the rest.
|
|
162
|
+
|
|
163
|
+
## License
|
|
164
|
+
|
|
165
|
+
MIT © [CDGet](https://cdget.com)
|
|
@@ -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";
|