@saasflare/ui 2.0.0 → 3.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/README.md +85 -45
- package/dist/{button-B2DR7obe.d.mts → button-DUQJ0X7e.d.mts} +0 -23
- package/dist/{button-B2DR7obe.d.ts → button-DUQJ0X7e.d.ts} +0 -23
- package/dist/chunk-7UGPCRZ6.mjs +130 -0
- package/dist/chunk-CWW36RYE.js +59 -0
- package/dist/chunk-JOVJRQO3.js +0 -1
- package/dist/{chunk-TU6BBAA7.js → chunk-OYH6LQWR.js} +33 -65
- package/dist/{chunk-OT4ZNLTB.mjs → chunk-QWLQV6FS.mjs} +2 -24
- package/dist/chunk-S26666D6.mjs +0 -1
- package/dist/chunk-VQQ6MF5I.js +161 -0
- package/dist/chunk-W53NTFPB.mjs +28 -0
- package/dist/dialog-CwyBJeNl.d.mts +22 -0
- package/dist/dialog-CwyBJeNl.d.ts +22 -0
- package/dist/entries/calendar.d.mts +13 -0
- package/dist/entries/calendar.d.ts +13 -0
- package/dist/entries/calendar.js +211 -0
- package/dist/entries/calendar.mjs +188 -0
- package/dist/entries/carousel.d.mts +1 -1
- package/dist/entries/carousel.d.ts +1 -1
- package/dist/entries/carousel.js +4 -3
- package/dist/entries/carousel.mjs +2 -1
- package/dist/entries/command.d.mts +21 -0
- package/dist/entries/command.d.ts +21 -0
- package/dist/entries/command.js +172 -0
- package/dist/entries/command.mjs +162 -0
- package/dist/entries/drawer.d.mts +16 -0
- package/dist/entries/drawer.d.ts +16 -0
- package/dist/entries/drawer.js +124 -0
- package/dist/entries/drawer.mjs +113 -0
- package/dist/entries/input-otp.d.mts +14 -0
- package/dist/entries/input-otp.d.ts +14 -0
- package/dist/entries/input-otp.js +89 -0
- package/dist/entries/input-otp.mjs +64 -0
- package/dist/entries/resizable.d.mts +10 -0
- package/dist/entries/resizable.d.ts +10 -0
- package/dist/entries/resizable.js +69 -0
- package/dist/entries/resizable.mjs +45 -0
- package/dist/index.d.mts +12 -103
- package/dist/index.d.ts +12 -103
- package/dist/index.js +1265 -832
- package/dist/index.mjs +1172 -740
- package/package.json +36 -12
package/README.md
CHANGED
|
@@ -57,30 +57,41 @@ pnpm add react react-dom next next-themes framer-motion
|
|
|
57
57
|
`tailwindcss` is **not** a peer dependency — it's a build-time tool. Install it
|
|
58
58
|
in your app and add a `@source` directive (see Setup below).
|
|
59
59
|
|
|
60
|
-
### Optional (
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
`
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
|
68
|
-
|
|
|
69
|
-
| `
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
60
|
+
### Optional (in main barrel — tree-shake-friendly)
|
|
61
|
+
|
|
62
|
+
`Form` lives in the main barrel because `react-hook-form` declares
|
|
63
|
+
`"sideEffects": false`, so consumer bundlers reliably eliminate the import when
|
|
64
|
+
`Form` is unused. Install only if you use it. `peerDependenciesMeta.optional`
|
|
65
|
+
is set, so package managers won't warn if you skip it.
|
|
66
|
+
|
|
67
|
+
| Component | Install |
|
|
68
|
+
| ------------------ | -------------------------------------------------------- |
|
|
69
|
+
| `Form` + resolvers | `react-hook-form@^7`, `@hookform/resolvers@^5`, `zod@^4` |
|
|
70
|
+
|
|
71
|
+
### Bundled (no install required)
|
|
72
|
+
|
|
73
|
+
`Toaster` (sonner-based toast notifications) is bundled directly into
|
|
74
|
+
`@saasflare/ui` — no separate `sonner` install needed. Sonner injects ~6 KB
|
|
75
|
+
of toast CSS into the document at module load, which adds ~13 KB gzip to the
|
|
76
|
+
main barrel for all consumers, including those who don't render `<Toaster />`.
|
|
77
|
+
We accepted this trade-off because Toaster usage is >80 % across the Saasflare
|
|
78
|
+
codebase and consumers; the extra-import friction was worse than the byte cost.
|
|
79
|
+
|
|
80
|
+
### Subpath imports (heavy, low-frequency, or non-tree-shakeable peers)
|
|
81
|
+
|
|
82
|
+
These components are **not in the main barrel** — import them via their
|
|
83
|
+
subpath. This keeps the peer (and its side-effects, e.g. CSS injection) out of
|
|
84
|
+
consumers who don't use the component.
|
|
85
|
+
|
|
86
|
+
| Subpath | Install | Notes |
|
|
87
|
+
| -------------------------- | ---------------------------------------- | ---------------------------------------- |
|
|
88
|
+
| `@saasflare/ui/chart` | `recharts@^3` | ~95 KB gzip peer |
|
|
89
|
+
| `@saasflare/ui/carousel` | `embla-carousel-react@^8` | ~25 KB peer |
|
|
90
|
+
| `@saasflare/ui/calendar` | `react-day-picker@^9`, `date-fns@^4` | ~30 KB peer combined |
|
|
91
|
+
| `@saasflare/ui/drawer` | `vaul@^1` | Mobile drawer / bottom sheet |
|
|
92
|
+
| `@saasflare/ui/command` | (no extra install — `cmdk` bundled) | Full Command palette / cmdk-based modal |
|
|
93
|
+
| `@saasflare/ui/input-otp` | `input-otp@^1` | OTP / 2FA input |
|
|
94
|
+
| `@saasflare/ui/resizable` | `react-resizable-panels@^4` | Split-view panels |
|
|
84
95
|
|
|
85
96
|
---
|
|
86
97
|
|
|
@@ -104,7 +115,11 @@ light/dark surface variables, and motion tokens.
|
|
|
104
115
|
> content: ["./node_modules/@saasflare/ui/dist/**/*.{js,mjs}", /* ... */]
|
|
105
116
|
> ```
|
|
106
117
|
|
|
107
|
-
### 2.
|
|
118
|
+
### 2. Make `SaasflareShell` your document root *(mandatory)*
|
|
119
|
+
|
|
120
|
+
`SaasflareShell` **is the document** — it renders `<html>` and `<body>`
|
|
121
|
+
itself, plus the design-system context inside. Do **not** wrap it in your
|
|
122
|
+
own `<html>`/`<body>` tags; replace them entirely.
|
|
108
123
|
|
|
109
124
|
```tsx
|
|
110
125
|
// app/layout.tsx
|
|
@@ -114,24 +129,39 @@ import "./globals.css";
|
|
|
114
129
|
|
|
115
130
|
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
116
131
|
return (
|
|
117
|
-
<
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
132
|
+
<SaasflareShell
|
|
133
|
+
lang="en"
|
|
134
|
+
palette="saasflare"
|
|
135
|
+
theme="dark"
|
|
136
|
+
className={fontVariables}
|
|
137
|
+
>
|
|
138
|
+
{children}
|
|
139
|
+
</SaasflareShell>
|
|
122
140
|
);
|
|
123
141
|
}
|
|
124
142
|
```
|
|
125
143
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
144
|
+
`SaasflareShell` accepts `palette`, `theme`, `surface`, `radius`,
|
|
145
|
+
`animated`, `smoothScrolling`, `storageKey`, plus a `lang`, `className`
|
|
146
|
+
(applied to `<html>`), `bodyClassName`, and a `head` slot for `<head>`
|
|
147
|
+
content. The chosen `palette`/`surface`/`radius`/`animated` props are
|
|
148
|
+
baked into the SSR HTML as `data-*` attributes, so there is **zero FOUT**
|
|
149
|
+
and the pre-hydration script is disabled by default.
|
|
150
|
+
|
|
151
|
+
> **⚠️ Required, not optional.** `@saasflare/ui` uses `LazyMotion
|
|
152
|
+
> features={domAnimation} strict` to keep the motion bundle tight.
|
|
153
|
+
> Animated components use the `m.*` API (e.g. `m.button`) which throws at
|
|
154
|
+
> runtime if `LazyMotion` is missing. `SaasflareShell` (or
|
|
155
|
+
> `SaasflareProvider` directly, when you need to own `<html>`/`<body>`
|
|
156
|
+
> yourself) provides it. Without one, every `Button`, `Card`, `Dialog`,
|
|
157
|
+
> etc. will error on mount.
|
|
158
|
+
|
|
159
|
+
**When to use `SaasflareProvider` instead:** if you need a runtime palette
|
|
160
|
+
switcher (user picks a palette via a toggle, persisted in localStorage),
|
|
161
|
+
keep your own `<html>`/`<body>` and wrap children in `SaasflareProvider`.
|
|
162
|
+
The provider's pre-hydration script reads localStorage before paint.
|
|
163
|
+
`SaasflareShell` is for brand-locked apps where the palette is decided at
|
|
164
|
+
SSR time.
|
|
135
165
|
|
|
136
166
|
### 3. Use components
|
|
137
167
|
|
|
@@ -152,11 +182,16 @@ export function Example() {
|
|
|
152
182
|
}
|
|
153
183
|
```
|
|
154
184
|
|
|
155
|
-
|
|
185
|
+
Components with heavy or low-frequency peers ship as subpaths:
|
|
156
186
|
|
|
157
187
|
```tsx
|
|
158
188
|
import { ChartContainer, ChartTooltip } from "@saasflare/ui/chart";
|
|
159
189
|
import { Carousel, CarouselContent, CarouselItem } from "@saasflare/ui/carousel";
|
|
190
|
+
import { Calendar } from "@saasflare/ui/calendar";
|
|
191
|
+
import { Drawer, DrawerContent, DrawerTrigger } from "@saasflare/ui/drawer";
|
|
192
|
+
import { Command, CommandInput, CommandList } from "@saasflare/ui/command";
|
|
193
|
+
import { InputOTP, InputOTPGroup, InputOTPSlot } from "@saasflare/ui/input-otp";
|
|
194
|
+
import { ResizablePanel, ResizablePanelGroup } from "@saasflare/ui/resizable";
|
|
160
195
|
```
|
|
161
196
|
|
|
162
197
|
---
|
|
@@ -215,9 +250,14 @@ the design system pick them up automatically.
|
|
|
215
250
|
|
|
216
251
|
| Path | What it is |
|
|
217
252
|
| --------------------------------- | ------------------------------------------------------------------- |
|
|
218
|
-
| `@saasflare/ui` | Core: components, hooks, providers, utilities
|
|
253
|
+
| `@saasflare/ui` | Core: components, hooks, providers, utilities (incl. Form, Toaster) |
|
|
254
|
+
| `@saasflare/ui/calendar` | Calendar (requires `react-day-picker`, `date-fns`) |
|
|
255
|
+
| `@saasflare/ui/carousel` | Carousel (requires `embla-carousel-react`) |
|
|
219
256
|
| `@saasflare/ui/chart` | Chart primitives (requires `recharts`) |
|
|
220
|
-
| `@saasflare/ui/
|
|
257
|
+
| `@saasflare/ui/command` | Command palette / cmdk modal |
|
|
258
|
+
| `@saasflare/ui/drawer` | Mobile drawer (requires `vaul`) |
|
|
259
|
+
| `@saasflare/ui/input-otp` | OTP input (requires `input-otp`) |
|
|
260
|
+
| `@saasflare/ui/resizable` | Resizable panels (requires `react-resizable-panels`) |
|
|
221
261
|
| `@saasflare/ui/styles` | Full CSS bundle (alias for `globals.css`) |
|
|
222
262
|
| `@saasflare/ui/globals.css` | Same as above, explicit |
|
|
223
263
|
| `@saasflare/ui/theme.css` | Token root only (advanced use) |
|
|
@@ -239,9 +279,9 @@ the design system pick them up automatically.
|
|
|
239
279
|
`Density`, …)
|
|
240
280
|
- **Composed widgets:** `ScrollToTopButton`, `ThemeModeToggle`,
|
|
241
281
|
`TopLoadingBar`, `UserAvatar`
|
|
242
|
-
- **All core UI primitives** from `components/ui` (
|
|
243
|
-
*not* here — see Subpath imports
|
|
244
|
-
the [catalog](https://ui.saasflare.io).
|
|
282
|
+
- **All core UI primitives** from `components/ui` (Calendar, Carousel, Chart,
|
|
283
|
+
Command, Drawer, InputOTP, and Resizable are *not* here — see Subpath imports
|
|
284
|
+
above) — full list and live examples in the [catalog](https://ui.saasflare.io).
|
|
245
285
|
|
|
246
286
|
---
|
|
247
287
|
|
|
@@ -181,29 +181,6 @@ type Surface = StyleVariant;
|
|
|
181
181
|
*/
|
|
182
182
|
type RadiusProp = Radius;
|
|
183
183
|
|
|
184
|
-
/**
|
|
185
|
-
* @fileoverview Base props and resolver hook for Saasflare components.
|
|
186
|
-
* @module packages/ui/providers/use-saasflare-props
|
|
187
|
-
* @package ui
|
|
188
|
-
*
|
|
189
|
-
* Every Saasflare component MUST:
|
|
190
|
-
* 1. Extend SaasflareComponentProps in its props interface
|
|
191
|
-
* 2. Call useSaasflareProps(props) to resolve effective values
|
|
192
|
-
*
|
|
193
|
-
* This ensures consistent precedence:
|
|
194
|
-
* component prop > provider context > hardcoded defaults
|
|
195
|
-
*
|
|
196
|
-
* @example
|
|
197
|
-
* interface CardProps extends SaasflareComponentProps {
|
|
198
|
-
* title: string
|
|
199
|
-
* }
|
|
200
|
-
*
|
|
201
|
-
* function Card({ title, ...sfProps }: CardProps) {
|
|
202
|
-
* const { surface, radius, animated } = useSaasflareProps(sfProps)
|
|
203
|
-
* // surface/radius are guaranteed to be resolved, never undefined
|
|
204
|
-
* }
|
|
205
|
-
*/
|
|
206
|
-
|
|
207
184
|
/** Props that every Saasflare component accepts for theme integration. */
|
|
208
185
|
interface SaasflareComponentProps {
|
|
209
186
|
/** Surface style override. Omit to inherit from provider. */
|
|
@@ -181,29 +181,6 @@ type Surface = StyleVariant;
|
|
|
181
181
|
*/
|
|
182
182
|
type RadiusProp = Radius;
|
|
183
183
|
|
|
184
|
-
/**
|
|
185
|
-
* @fileoverview Base props and resolver hook for Saasflare components.
|
|
186
|
-
* @module packages/ui/providers/use-saasflare-props
|
|
187
|
-
* @package ui
|
|
188
|
-
*
|
|
189
|
-
* Every Saasflare component MUST:
|
|
190
|
-
* 1. Extend SaasflareComponentProps in its props interface
|
|
191
|
-
* 2. Call useSaasflareProps(props) to resolve effective values
|
|
192
|
-
*
|
|
193
|
-
* This ensures consistent precedence:
|
|
194
|
-
* component prop > provider context > hardcoded defaults
|
|
195
|
-
*
|
|
196
|
-
* @example
|
|
197
|
-
* interface CardProps extends SaasflareComponentProps {
|
|
198
|
-
* title: string
|
|
199
|
-
* }
|
|
200
|
-
*
|
|
201
|
-
* function Card({ title, ...sfProps }: CardProps) {
|
|
202
|
-
* const { surface, radius, animated } = useSaasflareProps(sfProps)
|
|
203
|
-
* // surface/radius are guaranteed to be resolved, never undefined
|
|
204
|
-
* }
|
|
205
|
-
*/
|
|
206
|
-
|
|
207
184
|
/** Props that every Saasflare component accepts for theme integration. */
|
|
208
185
|
interface SaasflareComponentProps {
|
|
209
186
|
/** Surface style override. Omit to inherit from provider. */
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useReducedMotion, noMotion, springBouncy } from './chunk-W53NTFPB.mjs';
|
|
3
|
+
import { cn } from './chunk-S26666D6.mjs';
|
|
4
|
+
import { m } from 'motion/react';
|
|
5
|
+
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
6
|
+
import { XIcon } from 'lucide-react';
|
|
7
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
8
|
+
|
|
9
|
+
function Dialog({
|
|
10
|
+
...props
|
|
11
|
+
}) {
|
|
12
|
+
return /* @__PURE__ */ jsx(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
13
|
+
}
|
|
14
|
+
function DialogTrigger({
|
|
15
|
+
...props
|
|
16
|
+
}) {
|
|
17
|
+
return /* @__PURE__ */ jsx(DialogPrimitive.Trigger, { "data-slot": "dialog-trigger", ...props });
|
|
18
|
+
}
|
|
19
|
+
function DialogPortal({
|
|
20
|
+
...props
|
|
21
|
+
}) {
|
|
22
|
+
return /* @__PURE__ */ jsx(DialogPrimitive.Portal, { "data-slot": "dialog-portal", ...props });
|
|
23
|
+
}
|
|
24
|
+
function DialogClose({
|
|
25
|
+
...props
|
|
26
|
+
}) {
|
|
27
|
+
return /* @__PURE__ */ jsx(DialogPrimitive.Close, { "data-slot": "dialog-close", ...props });
|
|
28
|
+
}
|
|
29
|
+
function DialogOverlay({
|
|
30
|
+
className,
|
|
31
|
+
...props
|
|
32
|
+
}) {
|
|
33
|
+
return /* @__PURE__ */ jsx(
|
|
34
|
+
DialogPrimitive.Overlay,
|
|
35
|
+
{
|
|
36
|
+
"data-slot": "dialog-overlay",
|
|
37
|
+
className: cn(
|
|
38
|
+
"fixed inset-0 z-50 bg-black/50 backdrop-blur-[2px] data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
39
|
+
className
|
|
40
|
+
),
|
|
41
|
+
...props
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
function DialogContent({
|
|
46
|
+
className,
|
|
47
|
+
children,
|
|
48
|
+
...props
|
|
49
|
+
}) {
|
|
50
|
+
const reduced = useReducedMotion();
|
|
51
|
+
return /* @__PURE__ */ jsxs(DialogPortal, { children: [
|
|
52
|
+
/* @__PURE__ */ jsx(DialogOverlay, {}),
|
|
53
|
+
/* @__PURE__ */ jsx(
|
|
54
|
+
DialogPrimitive.Content,
|
|
55
|
+
{
|
|
56
|
+
"data-slot": "dialog-content",
|
|
57
|
+
asChild: true,
|
|
58
|
+
...props,
|
|
59
|
+
children: /* @__PURE__ */ jsxs(
|
|
60
|
+
m.div,
|
|
61
|
+
{
|
|
62
|
+
initial: reduced ? { opacity: 1 } : { opacity: 0, scale: 0.95, y: 10 },
|
|
63
|
+
animate: { opacity: 1, scale: 1, y: 0 },
|
|
64
|
+
exit: reduced ? { opacity: 0 } : { opacity: 0, scale: 0.95, y: 10 },
|
|
65
|
+
transition: reduced ? noMotion : springBouncy,
|
|
66
|
+
className: cn(
|
|
67
|
+
"fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg sm:max-w-lg",
|
|
68
|
+
className
|
|
69
|
+
),
|
|
70
|
+
children: [
|
|
71
|
+
children,
|
|
72
|
+
/* @__PURE__ */ jsxs(DialogPrimitive.Close, { className: "absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none cursor-pointer [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", children: [
|
|
73
|
+
/* @__PURE__ */ jsx(XIcon, {}),
|
|
74
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
|
|
75
|
+
] })
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
)
|
|
81
|
+
] });
|
|
82
|
+
}
|
|
83
|
+
function DialogHeader({ className, ...props }) {
|
|
84
|
+
return /* @__PURE__ */ jsx(
|
|
85
|
+
"div",
|
|
86
|
+
{
|
|
87
|
+
"data-slot": "dialog-header",
|
|
88
|
+
className: cn("flex flex-col gap-2 text-center sm:text-left", className),
|
|
89
|
+
...props
|
|
90
|
+
}
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
function DialogFooter({ className, ...props }) {
|
|
94
|
+
return /* @__PURE__ */ jsx(
|
|
95
|
+
"div",
|
|
96
|
+
{
|
|
97
|
+
"data-slot": "dialog-footer",
|
|
98
|
+
className: cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className),
|
|
99
|
+
...props
|
|
100
|
+
}
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
function DialogTitle({
|
|
104
|
+
className,
|
|
105
|
+
...props
|
|
106
|
+
}) {
|
|
107
|
+
return /* @__PURE__ */ jsx(
|
|
108
|
+
DialogPrimitive.Title,
|
|
109
|
+
{
|
|
110
|
+
"data-slot": "dialog-title",
|
|
111
|
+
className: cn("text-lg leading-none font-semibold", className),
|
|
112
|
+
...props
|
|
113
|
+
}
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
function DialogDescription({
|
|
117
|
+
className,
|
|
118
|
+
...props
|
|
119
|
+
}) {
|
|
120
|
+
return /* @__PURE__ */ jsx(
|
|
121
|
+
DialogPrimitive.Description,
|
|
122
|
+
{
|
|
123
|
+
"data-slot": "dialog-description",
|
|
124
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
125
|
+
...props
|
|
126
|
+
}
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var React = require('react');
|
|
5
|
+
|
|
6
|
+
function _interopNamespace(e) {
|
|
7
|
+
if (e && e.__esModule) return e;
|
|
8
|
+
var n = Object.create(null);
|
|
9
|
+
if (e) {
|
|
10
|
+
Object.keys(e).forEach(function (k) {
|
|
11
|
+
if (k !== 'default') {
|
|
12
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
13
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function () { return e[k]; }
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
n.default = e;
|
|
21
|
+
return Object.freeze(n);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
25
|
+
|
|
26
|
+
// src/hooks/use-reduced-motion.ts
|
|
27
|
+
var QUERY = "(prefers-reduced-motion: reduce)";
|
|
28
|
+
var subscribe = (cb) => {
|
|
29
|
+
const mql = window.matchMedia(QUERY);
|
|
30
|
+
mql.addEventListener("change", cb);
|
|
31
|
+
return () => mql.removeEventListener("change", cb);
|
|
32
|
+
};
|
|
33
|
+
var getSnapshot = () => window.matchMedia(QUERY).matches;
|
|
34
|
+
var getServerSnapshot = () => false;
|
|
35
|
+
function useReducedMotion() {
|
|
36
|
+
return React__namespace.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// src/components/ui/motion-config.ts
|
|
40
|
+
var spring = { type: "spring", stiffness: 400, damping: 25 };
|
|
41
|
+
var springBouncy = { type: "spring", stiffness: 300, damping: 15 };
|
|
42
|
+
var springGentle = { type: "spring", stiffness: 200, damping: 20 };
|
|
43
|
+
var springStiff = { type: "spring", stiffness: 500, damping: 30 };
|
|
44
|
+
var noMotion = { duration: 0 };
|
|
45
|
+
var fadeIn = { initial: { opacity: 0 }, animate: { opacity: 1 } };
|
|
46
|
+
var scaleIn = { initial: { opacity: 0, scale: 0.95 }, animate: { opacity: 1, scale: 1 } };
|
|
47
|
+
var slideUp = { initial: { opacity: 0, y: 8 }, animate: { opacity: 1, y: 0 } };
|
|
48
|
+
var slideDown = { initial: { opacity: 0, y: -8 }, animate: { opacity: 1, y: 0 } };
|
|
49
|
+
|
|
50
|
+
exports.fadeIn = fadeIn;
|
|
51
|
+
exports.noMotion = noMotion;
|
|
52
|
+
exports.scaleIn = scaleIn;
|
|
53
|
+
exports.slideDown = slideDown;
|
|
54
|
+
exports.slideUp = slideUp;
|
|
55
|
+
exports.spring = spring;
|
|
56
|
+
exports.springBouncy = springBouncy;
|
|
57
|
+
exports.springGentle = springGentle;
|
|
58
|
+
exports.springStiff = springStiff;
|
|
59
|
+
exports.useReducedMotion = useReducedMotion;
|
package/dist/chunk-JOVJRQO3.js
CHANGED