@saasflare/ui 3.0.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/button-0Bdl7Nqm.d.ts +87 -0
- package/dist/button-Brb4BhPO.d.mts +87 -0
- package/dist/{chunk-VQQ6MF5I.js → chunk-4BOMMZEY.js} +20 -13
- package/dist/{chunk-OYH6LQWR.js → chunk-D5LKWKG7.js} +50 -150
- package/dist/chunk-DNLCSV5M.js +151 -0
- package/dist/{chunk-W53NTFPB.mjs → chunk-EJHYM2HP.mjs} +7 -16
- package/dist/chunk-FT66KYRN.js +30 -0
- package/dist/{chunk-7UGPCRZ6.mjs → chunk-RW2S3KNB.mjs} +14 -7
- package/dist/chunk-WPOOC2FX.mjs +128 -0
- package/dist/{chunk-QWLQV6FS.mjs → chunk-WRONFPRI.mjs} +22 -121
- package/dist/{dialog-CwyBJeNl.d.mts → dialog-BmY55WSX.d.ts} +4 -1
- package/dist/{dialog-CwyBJeNl.d.ts → dialog-CcaHMAsS.d.mts} +4 -1
- package/dist/entries/calendar.d.mts +5 -3
- package/dist/entries/calendar.d.ts +5 -3
- package/dist/entries/calendar.js +44 -36
- package/dist/entries/calendar.mjs +11 -3
- package/dist/entries/carousel.d.mts +4 -3
- package/dist/entries/carousel.d.ts +4 -3
- package/dist/entries/carousel.js +18 -11
- package/dist/entries/carousel.mjs +11 -4
- package/dist/entries/chart.d.mts +4 -2
- package/dist/entries/chart.d.ts +4 -2
- package/dist/entries/chart.js +17 -10
- package/dist/entries/chart.mjs +8 -1
- package/dist/entries/command.d.mts +5 -2
- package/dist/entries/command.d.ts +5 -2
- package/dist/entries/command.js +25 -18
- package/dist/entries/command.mjs +12 -5
- package/dist/entries/drawer.d.mts +4 -1
- package/dist/entries/drawer.d.ts +4 -1
- package/dist/entries/drawer.js +15 -8
- package/dist/entries/drawer.mjs +9 -2
- package/dist/entries/input-otp.d.mts +4 -2
- package/dist/entries/input-otp.d.ts +4 -2
- package/dist/entries/input-otp.js +13 -6
- package/dist/entries/input-otp.mjs +10 -3
- package/dist/entries/resizable.d.mts +3 -1
- package/dist/entries/resizable.d.ts +3 -1
- package/dist/entries/resizable.js +12 -5
- package/dist/entries/resizable.mjs +10 -3
- package/dist/index.d.mts +181 -79
- package/dist/index.d.ts +181 -79
- package/dist/index.js +807 -477
- package/dist/index.mjs +498 -172
- package/dist/{button-DUQJ0X7e.d.mts → use-saasflare-props-NrM2Glmp.d.mts} +1 -86
- package/dist/{button-DUQJ0X7e.d.ts → use-saasflare-props-NrM2Glmp.d.ts} +1 -86
- package/package.json +1 -1
- package/dist/chunk-CWW36RYE.js +0 -59
- package/dist/chunk-JOVJRQO3.js +0 -12
- package/dist/chunk-S26666D6.mjs +0 -10
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { VariantProps } from 'class-variance-authority';
|
|
5
|
+
import { c as SaasflareComponentProps } from './use-saasflare-props-NrM2Glmp.js';
|
|
6
|
+
|
|
7
|
+
declare const INTENTS: readonly ["primary", "neutral", "success", "warning", "danger", "info"];
|
|
8
|
+
type Intent = (typeof INTENTS)[number];
|
|
9
|
+
/**
|
|
10
|
+
* Button variant definitions using the 3-axis system.
|
|
11
|
+
*
|
|
12
|
+
* Axes:
|
|
13
|
+
* variant — visual treatment: solid, soft, outline, ghost, link, glass, shadow
|
|
14
|
+
* intent — color intent via data-intent attribute + CSS tokens
|
|
15
|
+
* size — dimensional: xs, sm, md, lg, xl, icon, icon-xs, icon-sm, icon-lg
|
|
16
|
+
*/
|
|
17
|
+
declare const buttonVariants: (props?: ({
|
|
18
|
+
variant?: "outline" | "link" | "glass" | "soft" | "solid" | "ghost" | "shadow" | null | undefined;
|
|
19
|
+
size?: "xs" | "sm" | "md" | "lg" | "xl" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
|
|
20
|
+
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
21
|
+
/** Framer-motion event overrides that conflict with React HTML events */
|
|
22
|
+
type MotionConflicts = "onDrag" | "onDragStart" | "onDragEnd" | "onAnimationStart" | "onAnimationEnd";
|
|
23
|
+
/**
|
|
24
|
+
* Props for the Saasflare Button component.
|
|
25
|
+
*
|
|
26
|
+
* Extends {@link SaasflareComponentProps} to accept `surface` and `animated`
|
|
27
|
+
* overrides that are resolved against the <SaasflareProvider> context.
|
|
28
|
+
*/
|
|
29
|
+
interface ButtonProps extends Omit<React.ComponentProps<"button">, MotionConflicts>, VariantProps<typeof buttonVariants>, SaasflareComponentProps {
|
|
30
|
+
/** Render as child element (Radix Slot pattern) */
|
|
31
|
+
asChild?: boolean;
|
|
32
|
+
/** Semantic color intent */
|
|
33
|
+
intent?: Intent;
|
|
34
|
+
/** Show loading spinner (replaces left icon, keeps text visible) */
|
|
35
|
+
loading?: boolean;
|
|
36
|
+
/** Stretch to full width of container */
|
|
37
|
+
fullWidth?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Primary interactive button with motion, loading, and intent support.
|
|
41
|
+
*
|
|
42
|
+
* Resolves `surface` and `animated` via {@link useSaasflareProps} with the
|
|
43
|
+
* precedence: component prop > <SaasflareProvider> context > hardcoded default.
|
|
44
|
+
*
|
|
45
|
+
* When no explicit `variant` is set and the resolved surface is `"glass"`, the
|
|
46
|
+
* button promotes itself to `variant="glass"`. An explicit `variant` prop always
|
|
47
|
+
* wins over the surface-based promotion.
|
|
48
|
+
*
|
|
49
|
+
* @component
|
|
50
|
+
* @layer ui
|
|
51
|
+
*
|
|
52
|
+
* @param {string} variant - Visual treatment: "solid" | "soft" | "outline" | "ghost" | "link" | "glass" | "shadow"
|
|
53
|
+
* @param {string} intent - Color intent: "primary" | "neutral" | "success" | "warning" | "danger" | "info"
|
|
54
|
+
* @param {string} size - Button size: "xs" | "sm" | "md" | "lg" | "xl" | "icon" | "icon-xs" | "icon-sm" | "icon-lg"
|
|
55
|
+
* @param {string} surface - Surface style override: "flat" | "glass" (inherits from provider when omitted)
|
|
56
|
+
* @param {boolean} animated - Gate motion effects (inherits from provider when omitted)
|
|
57
|
+
* @param {boolean} loading - Shows spinner, sets aria-busy, preserves width
|
|
58
|
+
* @param {boolean} fullWidth - Stretches to container width
|
|
59
|
+
* @param {boolean} asChild - Render as child element (Slot pattern)
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* // Solid primary (default)
|
|
63
|
+
* <Button>Save Changes</Button>
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* // Outline danger
|
|
67
|
+
* <Button variant="outline" intent="danger">Delete Account</Button>
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* // Inherits surface from provider — auto-promotes to glass variant
|
|
71
|
+
* <SaasflareProvider surface="glass"><Button>Frosted</Button></SaasflareProvider>
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* // Loading state
|
|
75
|
+
* <Button loading>Processing...</Button>
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* // Icon button
|
|
79
|
+
* <Button variant="ghost" size="icon"><SettingsIcon /></Button>
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* // Legacy API (deprecated but supported)
|
|
83
|
+
* <Button variant="destructive">Delete</Button>
|
|
84
|
+
*/
|
|
85
|
+
declare function Button({ className, variant: variantProp, size, intent: intentProp, asChild, loading, fullWidth, surface, radius, animated, disabled, children, ...props }: ButtonProps): react_jsx_runtime.JSX.Element;
|
|
86
|
+
|
|
87
|
+
export { Button as B, type Intent as I, type ButtonProps as a, buttonVariants as b };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { VariantProps } from 'class-variance-authority';
|
|
5
|
+
import { c as SaasflareComponentProps } from './use-saasflare-props-NrM2Glmp.mjs';
|
|
6
|
+
|
|
7
|
+
declare const INTENTS: readonly ["primary", "neutral", "success", "warning", "danger", "info"];
|
|
8
|
+
type Intent = (typeof INTENTS)[number];
|
|
9
|
+
/**
|
|
10
|
+
* Button variant definitions using the 3-axis system.
|
|
11
|
+
*
|
|
12
|
+
* Axes:
|
|
13
|
+
* variant — visual treatment: solid, soft, outline, ghost, link, glass, shadow
|
|
14
|
+
* intent — color intent via data-intent attribute + CSS tokens
|
|
15
|
+
* size — dimensional: xs, sm, md, lg, xl, icon, icon-xs, icon-sm, icon-lg
|
|
16
|
+
*/
|
|
17
|
+
declare const buttonVariants: (props?: ({
|
|
18
|
+
variant?: "outline" | "link" | "glass" | "soft" | "solid" | "ghost" | "shadow" | null | undefined;
|
|
19
|
+
size?: "xs" | "sm" | "md" | "lg" | "xl" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
|
|
20
|
+
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
21
|
+
/** Framer-motion event overrides that conflict with React HTML events */
|
|
22
|
+
type MotionConflicts = "onDrag" | "onDragStart" | "onDragEnd" | "onAnimationStart" | "onAnimationEnd";
|
|
23
|
+
/**
|
|
24
|
+
* Props for the Saasflare Button component.
|
|
25
|
+
*
|
|
26
|
+
* Extends {@link SaasflareComponentProps} to accept `surface` and `animated`
|
|
27
|
+
* overrides that are resolved against the <SaasflareProvider> context.
|
|
28
|
+
*/
|
|
29
|
+
interface ButtonProps extends Omit<React.ComponentProps<"button">, MotionConflicts>, VariantProps<typeof buttonVariants>, SaasflareComponentProps {
|
|
30
|
+
/** Render as child element (Radix Slot pattern) */
|
|
31
|
+
asChild?: boolean;
|
|
32
|
+
/** Semantic color intent */
|
|
33
|
+
intent?: Intent;
|
|
34
|
+
/** Show loading spinner (replaces left icon, keeps text visible) */
|
|
35
|
+
loading?: boolean;
|
|
36
|
+
/** Stretch to full width of container */
|
|
37
|
+
fullWidth?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Primary interactive button with motion, loading, and intent support.
|
|
41
|
+
*
|
|
42
|
+
* Resolves `surface` and `animated` via {@link useSaasflareProps} with the
|
|
43
|
+
* precedence: component prop > <SaasflareProvider> context > hardcoded default.
|
|
44
|
+
*
|
|
45
|
+
* When no explicit `variant` is set and the resolved surface is `"glass"`, the
|
|
46
|
+
* button promotes itself to `variant="glass"`. An explicit `variant` prop always
|
|
47
|
+
* wins over the surface-based promotion.
|
|
48
|
+
*
|
|
49
|
+
* @component
|
|
50
|
+
* @layer ui
|
|
51
|
+
*
|
|
52
|
+
* @param {string} variant - Visual treatment: "solid" | "soft" | "outline" | "ghost" | "link" | "glass" | "shadow"
|
|
53
|
+
* @param {string} intent - Color intent: "primary" | "neutral" | "success" | "warning" | "danger" | "info"
|
|
54
|
+
* @param {string} size - Button size: "xs" | "sm" | "md" | "lg" | "xl" | "icon" | "icon-xs" | "icon-sm" | "icon-lg"
|
|
55
|
+
* @param {string} surface - Surface style override: "flat" | "glass" (inherits from provider when omitted)
|
|
56
|
+
* @param {boolean} animated - Gate motion effects (inherits from provider when omitted)
|
|
57
|
+
* @param {boolean} loading - Shows spinner, sets aria-busy, preserves width
|
|
58
|
+
* @param {boolean} fullWidth - Stretches to container width
|
|
59
|
+
* @param {boolean} asChild - Render as child element (Slot pattern)
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* // Solid primary (default)
|
|
63
|
+
* <Button>Save Changes</Button>
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* // Outline danger
|
|
67
|
+
* <Button variant="outline" intent="danger">Delete Account</Button>
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* // Inherits surface from provider — auto-promotes to glass variant
|
|
71
|
+
* <SaasflareProvider surface="glass"><Button>Frosted</Button></SaasflareProvider>
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* // Loading state
|
|
75
|
+
* <Button loading>Processing...</Button>
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* // Icon button
|
|
79
|
+
* <Button variant="ghost" size="icon"><SettingsIcon /></Button>
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* // Legacy API (deprecated but supported)
|
|
83
|
+
* <Button variant="destructive">Delete</Button>
|
|
84
|
+
*/
|
|
85
|
+
declare function Button({ className, variant: variantProp, size, intent: intentProp, asChild, loading, fullWidth, surface, radius, animated, disabled, children, ...props }: ButtonProps): react_jsx_runtime.JSX.Element;
|
|
86
|
+
|
|
87
|
+
export { Button as B, type Intent as I, type ButtonProps as a, buttonVariants as b };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
5
|
-
var
|
|
4
|
+
var chunkFT66KYRN_js = require('./chunk-FT66KYRN.js');
|
|
5
|
+
var chunkD5LKWKG7_js = require('./chunk-D5LKWKG7.js');
|
|
6
6
|
var react = require('motion/react');
|
|
7
7
|
var DialogPrimitive = require('@radix-ui/react-dialog');
|
|
8
8
|
var lucideReact = require('lucide-react');
|
|
@@ -56,7 +56,7 @@ function DialogOverlay({
|
|
|
56
56
|
DialogPrimitive__namespace.Overlay,
|
|
57
57
|
{
|
|
58
58
|
"data-slot": "dialog-overlay",
|
|
59
|
-
className:
|
|
59
|
+
className: chunkD5LKWKG7_js.cn(
|
|
60
60
|
"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",
|
|
61
61
|
className
|
|
62
62
|
),
|
|
@@ -67,25 +67,32 @@ function DialogOverlay({
|
|
|
67
67
|
function DialogContent({
|
|
68
68
|
className,
|
|
69
69
|
children,
|
|
70
|
+
surface,
|
|
71
|
+
radius,
|
|
72
|
+
animated,
|
|
70
73
|
...props
|
|
71
74
|
}) {
|
|
72
|
-
const
|
|
75
|
+
const sf = chunkD5LKWKG7_js.useSaasflareProps({ surface, radius, animated });
|
|
76
|
+
const motion = chunkFT66KYRN_js.useSaasflareMotion(sf.animated, chunkFT66KYRN_js.springBouncy);
|
|
73
77
|
return /* @__PURE__ */ jsxRuntime.jsxs(DialogPortal, { children: [
|
|
74
78
|
/* @__PURE__ */ jsxRuntime.jsx(DialogOverlay, {}),
|
|
75
79
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
76
80
|
DialogPrimitive__namespace.Content,
|
|
77
81
|
{
|
|
82
|
+
...props,
|
|
78
83
|
"data-slot": "dialog-content",
|
|
79
84
|
asChild: true,
|
|
80
|
-
...props,
|
|
81
85
|
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
82
86
|
react.m.div,
|
|
83
87
|
{
|
|
84
|
-
|
|
88
|
+
"data-surface": sf.surface,
|
|
89
|
+
"data-radius": sf.radius,
|
|
90
|
+
"data-animated": String(sf.animated),
|
|
91
|
+
initial: motion.disabled ? { opacity: 1 } : { opacity: 0, scale: 0.95, y: 10 },
|
|
85
92
|
animate: { opacity: 1, scale: 1, y: 0 },
|
|
86
|
-
exit:
|
|
87
|
-
transition:
|
|
88
|
-
className:
|
|
93
|
+
exit: motion.disabled ? { opacity: 0 } : { opacity: 0, scale: 0.95, y: 10 },
|
|
94
|
+
transition: motion.transition,
|
|
95
|
+
className: chunkD5LKWKG7_js.cn(
|
|
89
96
|
"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",
|
|
90
97
|
className
|
|
91
98
|
),
|
|
@@ -107,7 +114,7 @@ function DialogHeader({ className, ...props }) {
|
|
|
107
114
|
"div",
|
|
108
115
|
{
|
|
109
116
|
"data-slot": "dialog-header",
|
|
110
|
-
className:
|
|
117
|
+
className: chunkD5LKWKG7_js.cn("flex flex-col gap-2 text-center sm:text-left", className),
|
|
111
118
|
...props
|
|
112
119
|
}
|
|
113
120
|
);
|
|
@@ -117,7 +124,7 @@ function DialogFooter({ className, ...props }) {
|
|
|
117
124
|
"div",
|
|
118
125
|
{
|
|
119
126
|
"data-slot": "dialog-footer",
|
|
120
|
-
className:
|
|
127
|
+
className: chunkD5LKWKG7_js.cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className),
|
|
121
128
|
...props
|
|
122
129
|
}
|
|
123
130
|
);
|
|
@@ -130,7 +137,7 @@ function DialogTitle({
|
|
|
130
137
|
DialogPrimitive__namespace.Title,
|
|
131
138
|
{
|
|
132
139
|
"data-slot": "dialog-title",
|
|
133
|
-
className:
|
|
140
|
+
className: chunkD5LKWKG7_js.cn("text-lg leading-none font-semibold", className),
|
|
134
141
|
...props
|
|
135
142
|
}
|
|
136
143
|
);
|
|
@@ -143,7 +150,7 @@ function DialogDescription({
|
|
|
143
150
|
DialogPrimitive__namespace.Description,
|
|
144
151
|
{
|
|
145
152
|
"data-slot": "dialog-description",
|
|
146
|
-
className:
|
|
153
|
+
className: chunkD5LKWKG7_js.cn("text-sm text-muted-foreground", className),
|
|
147
154
|
...props
|
|
148
155
|
}
|
|
149
156
|
);
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
-
|
|
4
|
+
var clsx = require('clsx');
|
|
5
|
+
var tailwindMerge = require('tailwind-merge');
|
|
6
|
+
var React2 = require('react');
|
|
7
|
+
require('class-variance-authority');
|
|
8
8
|
var jsxRuntime = require('react/jsx-runtime');
|
|
9
9
|
var nextThemes = require('next-themes');
|
|
10
|
-
var react
|
|
11
|
-
var lucideReact = require('lucide-react');
|
|
12
|
-
var Slot = require('@radix-ui/react-slot');
|
|
10
|
+
var react = require('motion/react');
|
|
13
11
|
|
|
14
12
|
function _interopNamespace(e) {
|
|
15
13
|
if (e && e.__esModule) return e;
|
|
@@ -29,7 +27,12 @@ function _interopNamespace(e) {
|
|
|
29
27
|
return Object.freeze(n);
|
|
30
28
|
}
|
|
31
29
|
|
|
32
|
-
var
|
|
30
|
+
var React2__namespace = /*#__PURE__*/_interopNamespace(React2);
|
|
31
|
+
|
|
32
|
+
// src/lib/utils.ts
|
|
33
|
+
function cn(...inputs) {
|
|
34
|
+
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
35
|
+
}
|
|
33
36
|
|
|
34
37
|
// src/lib/color.ts
|
|
35
38
|
function hexToOklch(hex) {
|
|
@@ -75,12 +78,23 @@ function srgbToLinear(c) {
|
|
|
75
78
|
function isHex(input) {
|
|
76
79
|
return typeof input === "string" && /^#?[0-9a-f]{3,8}$/i.test(input.trim());
|
|
77
80
|
}
|
|
78
|
-
var
|
|
81
|
+
var QUERY = "(prefers-reduced-motion: reduce)";
|
|
82
|
+
var subscribe = (cb) => {
|
|
83
|
+
const mql = window.matchMedia(QUERY);
|
|
84
|
+
mql.addEventListener("change", cb);
|
|
85
|
+
return () => mql.removeEventListener("change", cb);
|
|
86
|
+
};
|
|
87
|
+
var getSnapshot = () => window.matchMedia(QUERY).matches;
|
|
88
|
+
var getServerSnapshot = () => false;
|
|
89
|
+
function useReducedMotion() {
|
|
90
|
+
return React2__namespace.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
91
|
+
}
|
|
92
|
+
var AnimationContext = React2.createContext(
|
|
79
93
|
void 0
|
|
80
94
|
);
|
|
81
95
|
function useAnimation() {
|
|
82
|
-
const context =
|
|
83
|
-
const prefersReduced =
|
|
96
|
+
const context = React2.useContext(AnimationContext);
|
|
97
|
+
const prefersReduced = useReducedMotion();
|
|
84
98
|
if (context) return context;
|
|
85
99
|
return { animated: !prefersReduced };
|
|
86
100
|
}
|
|
@@ -88,9 +102,9 @@ function SmoothScrollProvider({
|
|
|
88
102
|
children,
|
|
89
103
|
enabled = true
|
|
90
104
|
}) {
|
|
91
|
-
const reduced =
|
|
105
|
+
const reduced = useReducedMotion();
|
|
92
106
|
const shouldSmooth = enabled && !reduced;
|
|
93
|
-
|
|
107
|
+
React2.useEffect(() => {
|
|
94
108
|
if (!shouldSmooth) return;
|
|
95
109
|
const html = document.documentElement;
|
|
96
110
|
const previous = html.style.scrollBehavior;
|
|
@@ -139,18 +153,18 @@ function SaasflareScript({ nonce, palette, surface, radius, animated, storageKey
|
|
|
139
153
|
}
|
|
140
154
|
var SYNC_PREFIX = "sf-ls:";
|
|
141
155
|
function useLocalStorage(key, initialValue, options) {
|
|
142
|
-
const initialRef =
|
|
143
|
-
const optionsRef =
|
|
156
|
+
const initialRef = React2.useRef(initialValue);
|
|
157
|
+
const optionsRef = React2.useRef(options);
|
|
144
158
|
optionsRef.current = options;
|
|
145
|
-
const serialize =
|
|
159
|
+
const serialize = React2.useCallback(
|
|
146
160
|
(value) => (optionsRef.current?.serializer ?? JSON.stringify)(value),
|
|
147
161
|
[]
|
|
148
162
|
);
|
|
149
|
-
const deserialize =
|
|
163
|
+
const deserialize = React2.useCallback(
|
|
150
164
|
(raw) => (optionsRef.current?.deserializer ?? JSON.parse)(raw),
|
|
151
165
|
[]
|
|
152
166
|
);
|
|
153
|
-
const handleError =
|
|
167
|
+
const handleError = React2.useCallback(
|
|
154
168
|
(error, operation) => {
|
|
155
169
|
if (optionsRef.current?.onError) {
|
|
156
170
|
optionsRef.current.onError(error, operation);
|
|
@@ -160,7 +174,7 @@ function useLocalStorage(key, initialValue, options) {
|
|
|
160
174
|
},
|
|
161
175
|
[key]
|
|
162
176
|
);
|
|
163
|
-
const readValue =
|
|
177
|
+
const readValue = React2.useCallback(() => {
|
|
164
178
|
if (typeof window === "undefined") return initialRef.current;
|
|
165
179
|
try {
|
|
166
180
|
const item = window.localStorage.getItem(key);
|
|
@@ -170,8 +184,8 @@ function useLocalStorage(key, initialValue, options) {
|
|
|
170
184
|
return initialRef.current;
|
|
171
185
|
}
|
|
172
186
|
}, [key, deserialize, handleError]);
|
|
173
|
-
const [storedValue, setStoredValue] =
|
|
174
|
-
const setValue =
|
|
187
|
+
const [storedValue, setStoredValue] = React2.useState(() => readValue());
|
|
188
|
+
const setValue = React2.useCallback(
|
|
175
189
|
(value) => {
|
|
176
190
|
try {
|
|
177
191
|
setStoredValue((prev) => {
|
|
@@ -188,7 +202,7 @@ function useLocalStorage(key, initialValue, options) {
|
|
|
188
202
|
},
|
|
189
203
|
[key, serialize, handleError]
|
|
190
204
|
);
|
|
191
|
-
const removeValue =
|
|
205
|
+
const removeValue = React2.useCallback(() => {
|
|
192
206
|
try {
|
|
193
207
|
if (typeof window !== "undefined") {
|
|
194
208
|
window.localStorage.removeItem(key);
|
|
@@ -199,7 +213,7 @@ function useLocalStorage(key, initialValue, options) {
|
|
|
199
213
|
handleError(error, "remove");
|
|
200
214
|
}
|
|
201
215
|
}, [key, handleError]);
|
|
202
|
-
|
|
216
|
+
React2.useEffect(() => {
|
|
203
217
|
const onStorage = (e) => {
|
|
204
218
|
if (e.key === key) setStoredValue(readValue());
|
|
205
219
|
};
|
|
@@ -212,7 +226,7 @@ function useLocalStorage(key, initialValue, options) {
|
|
|
212
226
|
window.removeEventListener(syncEvent, onSync);
|
|
213
227
|
};
|
|
214
228
|
}, [key, readValue]);
|
|
215
|
-
|
|
229
|
+
React2.useEffect(() => {
|
|
216
230
|
setStoredValue(readValue());
|
|
217
231
|
}, [readValue]);
|
|
218
232
|
return [storedValue, setValue, removeValue];
|
|
@@ -228,9 +242,9 @@ var DEFAULT_CONTEXT = {
|
|
|
228
242
|
setRadius: () => {
|
|
229
243
|
}
|
|
230
244
|
};
|
|
231
|
-
var SaasflareThemeContext =
|
|
245
|
+
var SaasflareThemeContext = React2.createContext(DEFAULT_CONTEXT);
|
|
232
246
|
function useSaasflareTheme() {
|
|
233
|
-
return
|
|
247
|
+
return React2.useContext(SaasflareThemeContext);
|
|
234
248
|
}
|
|
235
249
|
function applyColorAxis(root, prefix, value, injected) {
|
|
236
250
|
if (isHex(value)) {
|
|
@@ -255,7 +269,7 @@ function applyColorAxis(root, prefix, value, injected) {
|
|
|
255
269
|
}
|
|
256
270
|
function CustomPaletteInjector({ palette }) {
|
|
257
271
|
const { resolvedTheme } = nextThemes.useTheme();
|
|
258
|
-
|
|
272
|
+
React2.useEffect(() => {
|
|
259
273
|
const root = document.documentElement;
|
|
260
274
|
const injected = [];
|
|
261
275
|
applyColorAxis(root, "primary", palette.primary, injected);
|
|
@@ -312,21 +326,21 @@ function SaasflareProvider({
|
|
|
312
326
|
const currentPalette = isCustomPalette ? palette.name : palette ?? persisted.palette;
|
|
313
327
|
const currentStyle = surface ?? persisted.surface ?? "flat";
|
|
314
328
|
const currentRadius = radius ?? persisted.radius ?? "rounded";
|
|
315
|
-
const setPalette =
|
|
329
|
+
const setPalette = React2.useCallback(
|
|
316
330
|
(id) => setPersisted((prev) => ({ ...prev, palette: id })),
|
|
317
331
|
[setPersisted]
|
|
318
332
|
);
|
|
319
|
-
const setSurface =
|
|
333
|
+
const setSurface = React2.useCallback(
|
|
320
334
|
(style) => setPersisted((prev) => ({ ...prev, surface: style })),
|
|
321
335
|
[setPersisted]
|
|
322
336
|
);
|
|
323
|
-
const setRadius =
|
|
337
|
+
const setRadius = React2.useCallback(
|
|
324
338
|
(r) => setPersisted((prev) => ({ ...prev, radius: r })),
|
|
325
339
|
[setPersisted]
|
|
326
340
|
);
|
|
327
|
-
const prefersReduced =
|
|
341
|
+
const prefersReduced = useReducedMotion();
|
|
328
342
|
const effectiveAnimated = animated && !prefersReduced;
|
|
329
|
-
|
|
343
|
+
React2.useEffect(() => {
|
|
330
344
|
const root = document.documentElement;
|
|
331
345
|
if (currentPalette) {
|
|
332
346
|
root.setAttribute(SAASFLARE_DATA_ATTR.palette, currentPalette);
|
|
@@ -337,7 +351,7 @@ function SaasflareProvider({
|
|
|
337
351
|
root.setAttribute(SAASFLARE_DATA_ATTR.radius, currentRadius);
|
|
338
352
|
root.setAttribute(SAASFLARE_DATA_ATTR.animated, String(effectiveAnimated));
|
|
339
353
|
}, [currentPalette, currentStyle, currentRadius, effectiveAnimated]);
|
|
340
|
-
return /* @__PURE__ */ jsxRuntime.jsx(react
|
|
354
|
+
return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domAnimation, strict: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
341
355
|
nextThemes.ThemeProvider,
|
|
342
356
|
{
|
|
343
357
|
attribute: "class",
|
|
@@ -424,7 +438,7 @@ function SaasflareShell({
|
|
|
424
438
|
}
|
|
425
439
|
function useSaasflareProps(props = {}) {
|
|
426
440
|
const ctx = useSaasflareTheme();
|
|
427
|
-
const anim =
|
|
441
|
+
const anim = React2.useContext(AnimationContext);
|
|
428
442
|
return {
|
|
429
443
|
surface: props.surface ?? ctx.surface,
|
|
430
444
|
radius: props.radius ?? ctx.radius,
|
|
@@ -432,127 +446,13 @@ function useSaasflareProps(props = {}) {
|
|
|
432
446
|
palette: ctx.palette
|
|
433
447
|
};
|
|
434
448
|
}
|
|
435
|
-
var MotionSlot = react$1.m.create(Slot__namespace.Root);
|
|
436
|
-
var LEGACY_VARIANT_MAP = {
|
|
437
|
-
default: { variant: "solid", intent: "primary" },
|
|
438
|
-
destructive: { variant: "solid", intent: "danger" },
|
|
439
|
-
secondary: { variant: "soft", intent: "neutral" }
|
|
440
|
-
};
|
|
441
|
-
var buttonVariants = classVarianceAuthority.cva(
|
|
442
|
-
"inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
443
|
-
{
|
|
444
|
-
variants: {
|
|
445
|
-
variant: {
|
|
446
|
-
solid: "bg-[var(--intent)] text-[var(--intent-fg)] shadow-xs hover:brightness-110 dark:hover:brightness-125",
|
|
447
|
-
soft: "bg-[var(--intent)]/15 text-[var(--intent)] hover:bg-[var(--intent)]/25 dark:bg-[var(--intent)]/20 dark:hover:bg-[var(--intent)]/30",
|
|
448
|
-
outline: "border border-[var(--intent)]/30 text-[var(--intent)] shadow-xs hover:bg-[var(--intent)]/10 dark:border-[var(--intent)]/40 dark:hover:bg-[var(--intent)]/15",
|
|
449
|
-
ghost: "text-[var(--intent)] hover:bg-[var(--intent)]/10 dark:hover:bg-[var(--intent)]/15",
|
|
450
|
-
link: "text-[var(--intent)] underline-offset-4 hover:underline",
|
|
451
|
-
glass: "bg-[var(--glass-bg)] text-[var(--intent)] border border-[var(--glass-border)] backdrop-blur-lg shadow-[var(--glass-shadow)] hover:bg-[var(--glass-bg-hover)] hover:border-[var(--glass-border-hover)]",
|
|
452
|
-
shadow: "bg-[var(--intent)] text-[var(--intent-fg)] shadow-[var(--btn-shadow)] hover:shadow-[var(--btn-shadow-hover)] hover:brightness-110 dark:hover:brightness-125"
|
|
453
|
-
},
|
|
454
|
-
size: {
|
|
455
|
-
xs: "h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
|
|
456
|
-
sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
|
|
457
|
-
md: "h-9 px-4 py-2 has-[>svg]:px-3",
|
|
458
|
-
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
|
|
459
|
-
xl: "h-12 rounded-lg px-8 text-base has-[>svg]:px-5 [&_svg:not([class*='size-'])]:size-5",
|
|
460
|
-
icon: "size-9",
|
|
461
|
-
"icon-xs": "size-6 rounded-md [&_svg:not([class*='size-'])]:size-3",
|
|
462
|
-
"icon-sm": "size-8",
|
|
463
|
-
"icon-lg": "size-10"
|
|
464
|
-
}
|
|
465
|
-
},
|
|
466
|
-
defaultVariants: {
|
|
467
|
-
variant: "solid",
|
|
468
|
-
size: "md"
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
);
|
|
472
|
-
function Button({
|
|
473
|
-
className,
|
|
474
|
-
variant: variantProp,
|
|
475
|
-
size = "md",
|
|
476
|
-
intent: intentProp = "primary",
|
|
477
|
-
asChild = false,
|
|
478
|
-
loading = false,
|
|
479
|
-
fullWidth = false,
|
|
480
|
-
surface,
|
|
481
|
-
animated,
|
|
482
|
-
disabled,
|
|
483
|
-
children,
|
|
484
|
-
...props
|
|
485
|
-
}) {
|
|
486
|
-
const sfProps = useSaasflareProps({ surface, animated });
|
|
487
|
-
const reduced = chunkCWW36RYE_js.useReducedMotion();
|
|
488
|
-
const effectiveVariant = variantProp ?? (sfProps.surface === "glass" ? "glass" : "solid");
|
|
489
|
-
let resolvedVariant = effectiveVariant;
|
|
490
|
-
let resolvedIntent = intentProp;
|
|
491
|
-
const legacy = LEGACY_VARIANT_MAP[effectiveVariant];
|
|
492
|
-
if (legacy) {
|
|
493
|
-
resolvedVariant = legacy.variant;
|
|
494
|
-
if (legacy.intent) {
|
|
495
|
-
resolvedIntent = legacy.intent;
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
const motionDisabled = !sfProps.animated || reduced || disabled || loading;
|
|
499
|
-
const transition = !sfProps.animated || reduced ? chunkCWW36RYE_js.noMotion : chunkCWW36RYE_js.spring;
|
|
500
|
-
if (asChild) {
|
|
501
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
502
|
-
MotionSlot,
|
|
503
|
-
{
|
|
504
|
-
"data-slot": "button",
|
|
505
|
-
"data-variant": resolvedVariant,
|
|
506
|
-
"data-intent": resolvedIntent,
|
|
507
|
-
"data-size": size,
|
|
508
|
-
"data-surface": sfProps.surface,
|
|
509
|
-
whileHover: motionDisabled ? void 0 : { scale: 1.02 },
|
|
510
|
-
whileTap: motionDisabled ? void 0 : { scale: 0.97 },
|
|
511
|
-
transition,
|
|
512
|
-
className: chunkJOVJRQO3_js.cn(
|
|
513
|
-
buttonVariants({ variant: resolvedVariant, size }),
|
|
514
|
-
fullWidth && "w-full",
|
|
515
|
-
className
|
|
516
|
-
),
|
|
517
|
-
...props,
|
|
518
|
-
children
|
|
519
|
-
}
|
|
520
|
-
);
|
|
521
|
-
}
|
|
522
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
523
|
-
react$1.m.button,
|
|
524
|
-
{
|
|
525
|
-
"data-slot": "button",
|
|
526
|
-
"data-variant": resolvedVariant,
|
|
527
|
-
"data-intent": resolvedIntent,
|
|
528
|
-
"data-size": size,
|
|
529
|
-
"data-surface": sfProps.surface,
|
|
530
|
-
whileHover: motionDisabled ? void 0 : { scale: 1.02 },
|
|
531
|
-
whileTap: motionDisabled ? void 0 : { scale: 0.97 },
|
|
532
|
-
transition,
|
|
533
|
-
className: chunkJOVJRQO3_js.cn(
|
|
534
|
-
buttonVariants({ variant: resolvedVariant, size }),
|
|
535
|
-
fullWidth && "w-full",
|
|
536
|
-
className
|
|
537
|
-
),
|
|
538
|
-
disabled,
|
|
539
|
-
"aria-busy": loading || void 0,
|
|
540
|
-
"aria-disabled": disabled || void 0,
|
|
541
|
-
...props,
|
|
542
|
-
children: [
|
|
543
|
-
loading && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2Icon, { className: "animate-spin", "aria-hidden": "true" }),
|
|
544
|
-
children
|
|
545
|
-
]
|
|
546
|
-
}
|
|
547
|
-
);
|
|
548
|
-
}
|
|
549
449
|
|
|
550
|
-
exports.Button = Button;
|
|
551
450
|
exports.SaasflareProvider = SaasflareProvider;
|
|
552
451
|
exports.SaasflareScript = SaasflareScript;
|
|
553
452
|
exports.SaasflareShell = SaasflareShell;
|
|
554
453
|
exports.SmoothScrollProvider = SmoothScrollProvider;
|
|
555
|
-
exports.
|
|
454
|
+
exports.cn = cn;
|
|
556
455
|
exports.useAnimation = useAnimation;
|
|
456
|
+
exports.useReducedMotion = useReducedMotion;
|
|
557
457
|
exports.useSaasflareProps = useSaasflareProps;
|
|
558
458
|
exports.useSaasflareTheme = useSaasflareTheme;
|