@stackframe/dashboard-ui-components 2.8.76
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/LICENSE +5 -0
- package/dist/chunk-BE-pF4vm.js +34 -0
- package/dist/components/alert.d.ts +22 -0
- package/dist/components/alert.d.ts.map +1 -0
- package/dist/components/alert.js +75 -0
- package/dist/components/alert.js.map +1 -0
- package/dist/components/badge.d.ts +24 -0
- package/dist/components/badge.d.ts.map +1 -0
- package/dist/components/badge.js +59 -0
- package/dist/components/badge.js.map +1 -0
- package/dist/components/button.d.ts +32 -0
- package/dist/components/button.d.ts.map +1 -0
- package/dist/components/button.js +68 -0
- package/dist/components/button.js.map +1 -0
- package/dist/components/card.d.ts +59 -0
- package/dist/components/card.d.ts.map +1 -0
- package/dist/components/card.js +133 -0
- package/dist/components/card.js.map +1 -0
- package/dist/components/chart-card.d.ts +21 -0
- package/dist/components/chart-card.d.ts.map +1 -0
- package/dist/components/chart-card.js +54 -0
- package/dist/components/chart-card.js.map +1 -0
- package/dist/components/chart-container.d.ts +51 -0
- package/dist/components/chart-container.d.ts.map +1 -0
- package/dist/components/chart-container.js +77 -0
- package/dist/components/chart-container.js.map +1 -0
- package/dist/components/chart-legend.d.ts +12 -0
- package/dist/components/chart-legend.d.ts.map +1 -0
- package/dist/components/chart-legend.js +41 -0
- package/dist/components/chart-legend.js.map +1 -0
- package/dist/components/chart-theme.d.ts +26 -0
- package/dist/components/chart-theme.d.ts.map +1 -0
- package/dist/components/chart-theme.js +64 -0
- package/dist/components/chart-theme.js.map +1 -0
- package/dist/components/chart-tooltip.d.ts +41 -0
- package/dist/components/chart-tooltip.d.ts.map +1 -0
- package/dist/components/chart-tooltip.js +89 -0
- package/dist/components/chart-tooltip.js.map +1 -0
- package/dist/components/cursor-blast-effect.d.ts +27 -0
- package/dist/components/cursor-blast-effect.d.ts.map +1 -0
- package/dist/components/cursor-blast-effect.js +243 -0
- package/dist/components/cursor-blast-effect.js.map +1 -0
- package/dist/components/edit-mode.d.ts +12 -0
- package/dist/components/edit-mode.d.ts.map +1 -0
- package/dist/components/edit-mode.js +23 -0
- package/dist/components/edit-mode.js.map +1 -0
- package/dist/components/empty-state.d.ts +21 -0
- package/dist/components/empty-state.d.ts.map +1 -0
- package/dist/components/empty-state.js +37 -0
- package/dist/components/empty-state.js.map +1 -0
- package/dist/components/input.d.ts +18 -0
- package/dist/components/input.d.ts.map +1 -0
- package/dist/components/input.js +53 -0
- package/dist/components/input.js.map +1 -0
- package/dist/components/metric-card.d.ts +31 -0
- package/dist/components/metric-card.d.ts.map +1 -0
- package/dist/components/metric-card.js +88 -0
- package/dist/components/metric-card.js.map +1 -0
- package/dist/components/pill-toggle.d.ts +33 -0
- package/dist/components/pill-toggle.d.ts.map +1 -0
- package/dist/components/pill-toggle.js +86 -0
- package/dist/components/pill-toggle.js.map +1 -0
- package/dist/components/progress-bar.d.ts +25 -0
- package/dist/components/progress-bar.d.ts.map +1 -0
- package/dist/components/progress-bar.js +44 -0
- package/dist/components/progress-bar.js.map +1 -0
- package/dist/components/separator.d.ts +14 -0
- package/dist/components/separator.d.ts.map +1 -0
- package/dist/components/separator.js +20 -0
- package/dist/components/separator.js.map +1 -0
- package/dist/components/skeleton.d.ts +12 -0
- package/dist/components/skeleton.d.ts.map +1 -0
- package/dist/components/skeleton.js +18 -0
- package/dist/components/skeleton.js.map +1 -0
- package/dist/components/table.d.ts +24 -0
- package/dist/components/table.d.ts.map +1 -0
- package/dist/components/table.js +59 -0
- package/dist/components/table.js.map +1 -0
- package/dist/components/tabs.d.ts +34 -0
- package/dist/components/tabs.d.ts.map +1 -0
- package/dist/components/tabs.js +100 -0
- package/dist/components/tabs.js.map +1 -0
- package/dist/dashboard-ui-components.global.js +15232 -0
- package/dist/dashboard-ui-components.global.js.map +7 -0
- package/dist/esm/components/alert.d.ts +22 -0
- package/dist/esm/components/alert.d.ts.map +1 -0
- package/dist/esm/components/alert.js +73 -0
- package/dist/esm/components/alert.js.map +1 -0
- package/dist/esm/components/badge.d.ts +24 -0
- package/dist/esm/components/badge.d.ts.map +1 -0
- package/dist/esm/components/badge.js +57 -0
- package/dist/esm/components/badge.js.map +1 -0
- package/dist/esm/components/button.d.ts +32 -0
- package/dist/esm/components/button.d.ts.map +1 -0
- package/dist/esm/components/button.js +65 -0
- package/dist/esm/components/button.js.map +1 -0
- package/dist/esm/components/card.d.ts +59 -0
- package/dist/esm/components/card.d.ts.map +1 -0
- package/dist/esm/components/card.js +127 -0
- package/dist/esm/components/card.js.map +1 -0
- package/dist/esm/components/chart-card.d.ts +21 -0
- package/dist/esm/components/chart-card.d.ts.map +1 -0
- package/dist/esm/components/chart-card.js +51 -0
- package/dist/esm/components/chart-card.js.map +1 -0
- package/dist/esm/components/chart-container.d.ts +51 -0
- package/dist/esm/components/chart-container.d.ts.map +1 -0
- package/dist/esm/components/chart-container.js +70 -0
- package/dist/esm/components/chart-container.js.map +1 -0
- package/dist/esm/components/chart-legend.d.ts +12 -0
- package/dist/esm/components/chart-legend.d.ts.map +1 -0
- package/dist/esm/components/chart-legend.js +36 -0
- package/dist/esm/components/chart-legend.js.map +1 -0
- package/dist/esm/components/chart-theme.d.ts +26 -0
- package/dist/esm/components/chart-theme.d.ts.map +1 -0
- package/dist/esm/components/chart-theme.js +59 -0
- package/dist/esm/components/chart-theme.js.map +1 -0
- package/dist/esm/components/chart-tooltip.d.ts +41 -0
- package/dist/esm/components/chart-tooltip.d.ts.map +1 -0
- package/dist/esm/components/chart-tooltip.js +84 -0
- package/dist/esm/components/chart-tooltip.js.map +1 -0
- package/dist/esm/components/cursor-blast-effect.d.ts +27 -0
- package/dist/esm/components/cursor-blast-effect.d.ts.map +1 -0
- package/dist/esm/components/cursor-blast-effect.js +241 -0
- package/dist/esm/components/cursor-blast-effect.js.map +1 -0
- package/dist/esm/components/edit-mode.d.ts +12 -0
- package/dist/esm/components/edit-mode.d.ts.map +1 -0
- package/dist/esm/components/edit-mode.js +20 -0
- package/dist/esm/components/edit-mode.js.map +1 -0
- package/dist/esm/components/empty-state.d.ts +21 -0
- package/dist/esm/components/empty-state.d.ts.map +1 -0
- package/dist/esm/components/empty-state.js +34 -0
- package/dist/esm/components/empty-state.js.map +1 -0
- package/dist/esm/components/input.d.ts +18 -0
- package/dist/esm/components/input.d.ts.map +1 -0
- package/dist/esm/components/input.js +50 -0
- package/dist/esm/components/input.js.map +1 -0
- package/dist/esm/components/metric-card.d.ts +31 -0
- package/dist/esm/components/metric-card.d.ts.map +1 -0
- package/dist/esm/components/metric-card.js +85 -0
- package/dist/esm/components/metric-card.js.map +1 -0
- package/dist/esm/components/pill-toggle.d.ts +33 -0
- package/dist/esm/components/pill-toggle.d.ts.map +1 -0
- package/dist/esm/components/pill-toggle.js +84 -0
- package/dist/esm/components/pill-toggle.js.map +1 -0
- package/dist/esm/components/progress-bar.d.ts +25 -0
- package/dist/esm/components/progress-bar.d.ts.map +1 -0
- package/dist/esm/components/progress-bar.js +42 -0
- package/dist/esm/components/progress-bar.js.map +1 -0
- package/dist/esm/components/separator.d.ts +14 -0
- package/dist/esm/components/separator.d.ts.map +1 -0
- package/dist/esm/components/separator.js +18 -0
- package/dist/esm/components/separator.js.map +1 -0
- package/dist/esm/components/skeleton.d.ts +12 -0
- package/dist/esm/components/skeleton.d.ts.map +1 -0
- package/dist/esm/components/skeleton.js +16 -0
- package/dist/esm/components/skeleton.js.map +1 -0
- package/dist/esm/components/table.d.ts +24 -0
- package/dist/esm/components/table.d.ts.map +1 -0
- package/dist/esm/components/table.js +51 -0
- package/dist/esm/components/table.js.map +1 -0
- package/dist/esm/components/tabs.d.ts +34 -0
- package/dist/esm/components/tabs.d.ts.map +1 -0
- package/dist/esm/components/tabs.js +98 -0
- package/dist/esm/components/tabs.js.map +1 -0
- package/dist/esm/index.d.ts +21 -0
- package/dist/esm/index.js +22 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +245 -0
- package/package.json +71 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
import { useEffect, useRef, useState } from "react";
|
|
5
|
+
import { createPortal } from "react-dom";
|
|
6
|
+
|
|
7
|
+
//#region src/components/cursor-blast-effect.tsx
|
|
8
|
+
const DEFAULT_BLAST_LIFETIME_MS = 720;
|
|
9
|
+
const DEFAULT_MAX_ACTIVE_BLASTS = 18;
|
|
10
|
+
/** Minimum rapid clicks in the time window to count as a rage click */
|
|
11
|
+
const DEFAULT_RAGE_CLICK_THRESHOLD = 3;
|
|
12
|
+
/** Time window (ms) in which clicks must occur to be considered rage clicking */
|
|
13
|
+
const DEFAULT_RAGE_CLICK_WINDOW_MS = 600;
|
|
14
|
+
/** Max distance (px) between clicks to still count as same-spot rage clicking */
|
|
15
|
+
const DEFAULT_RAGE_CLICK_RADIUS_PX = 60;
|
|
16
|
+
function CursorBlastEffect({ blastLifetimeMs = DEFAULT_BLAST_LIFETIME_MS, maxActiveBlasts = DEFAULT_MAX_ACTIVE_BLASTS, rageClickThreshold = DEFAULT_RAGE_CLICK_THRESHOLD, rageClickWindowMs = DEFAULT_RAGE_CLICK_WINDOW_MS, rageClickRadiusPx = DEFAULT_RAGE_CLICK_RADIUS_PX, containerRef } = {}) {
|
|
17
|
+
const [blasts, setBlasts] = useState([]);
|
|
18
|
+
const [mounted, setMounted] = useState(false);
|
|
19
|
+
const idCounterRef = useRef(0);
|
|
20
|
+
const timeoutIdsRef = useRef(/* @__PURE__ */ new Map());
|
|
21
|
+
const recentClicksRef = useRef([]);
|
|
22
|
+
const configRef = useRef({
|
|
23
|
+
blastLifetimeMs,
|
|
24
|
+
maxActiveBlasts,
|
|
25
|
+
rageClickThreshold,
|
|
26
|
+
rageClickWindowMs,
|
|
27
|
+
rageClickRadiusPx
|
|
28
|
+
});
|
|
29
|
+
configRef.current = {
|
|
30
|
+
blastLifetimeMs,
|
|
31
|
+
maxActiveBlasts,
|
|
32
|
+
rageClickThreshold,
|
|
33
|
+
rageClickWindowMs,
|
|
34
|
+
rageClickRadiusPx
|
|
35
|
+
};
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
setMounted(true);
|
|
38
|
+
}, []);
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
const removeBlast = (id) => {
|
|
41
|
+
setBlasts((prev) => prev.filter((blast) => blast.id !== id));
|
|
42
|
+
const timeoutId = timeoutIdsRef.current.get(id);
|
|
43
|
+
if (timeoutId !== void 0) {
|
|
44
|
+
window.clearTimeout(timeoutId);
|
|
45
|
+
timeoutIdsRef.current.delete(id);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const spawnBlast = (x, y) => {
|
|
49
|
+
const cfg = configRef.current;
|
|
50
|
+
const nextId = idCounterRef.current;
|
|
51
|
+
idCounterRef.current += 1;
|
|
52
|
+
const nextBlast = {
|
|
53
|
+
id: nextId,
|
|
54
|
+
x,
|
|
55
|
+
y,
|
|
56
|
+
size: 44 + Math.random() * 20,
|
|
57
|
+
hue: 185 + Math.random() * 35
|
|
58
|
+
};
|
|
59
|
+
setBlasts((prev) => {
|
|
60
|
+
const next = [...prev, nextBlast];
|
|
61
|
+
if (next.length <= cfg.maxActiveBlasts) return next;
|
|
62
|
+
return next.slice(next.length - cfg.maxActiveBlasts);
|
|
63
|
+
});
|
|
64
|
+
const timeoutId = window.setTimeout(() => removeBlast(nextId), cfg.blastLifetimeMs);
|
|
65
|
+
timeoutIdsRef.current.set(nextId, timeoutId);
|
|
66
|
+
};
|
|
67
|
+
const onClick = (event) => {
|
|
68
|
+
const cfg = configRef.current;
|
|
69
|
+
const now = performance.now();
|
|
70
|
+
let x;
|
|
71
|
+
let y;
|
|
72
|
+
if (containerRef?.current) {
|
|
73
|
+
const rect = containerRef.current.getBoundingClientRect();
|
|
74
|
+
x = event.clientX - rect.left;
|
|
75
|
+
y = event.clientY - rect.top;
|
|
76
|
+
} else {
|
|
77
|
+
x = event.clientX;
|
|
78
|
+
y = event.clientY;
|
|
79
|
+
}
|
|
80
|
+
recentClicksRef.current = recentClicksRef.current.filter((click) => now - click.time < cfg.rageClickWindowMs);
|
|
81
|
+
recentClicksRef.current.push({
|
|
82
|
+
time: now,
|
|
83
|
+
x,
|
|
84
|
+
y
|
|
85
|
+
});
|
|
86
|
+
if (recentClicksRef.current.filter((click) => {
|
|
87
|
+
const dx = click.x - x;
|
|
88
|
+
const dy = click.y - y;
|
|
89
|
+
return Math.sqrt(dx * dx + dy * dy) <= cfg.rageClickRadiusPx;
|
|
90
|
+
}).length >= cfg.rageClickThreshold) spawnBlast(x, y);
|
|
91
|
+
};
|
|
92
|
+
const target = containerRef?.current ?? window;
|
|
93
|
+
const timeoutIds = timeoutIdsRef.current;
|
|
94
|
+
target.addEventListener("click", onClick);
|
|
95
|
+
return () => {
|
|
96
|
+
target.removeEventListener("click", onClick);
|
|
97
|
+
for (const timeoutId of timeoutIds.values()) window.clearTimeout(timeoutId);
|
|
98
|
+
timeoutIds.clear();
|
|
99
|
+
};
|
|
100
|
+
}, [containerRef]);
|
|
101
|
+
if (!mounted) return null;
|
|
102
|
+
const blastElements = /* @__PURE__ */ jsxs(Fragment, { children: [blasts.map((blast) => /* @__PURE__ */ jsxs("div", {
|
|
103
|
+
style: {
|
|
104
|
+
position: "absolute",
|
|
105
|
+
left: blast.x,
|
|
106
|
+
top: blast.y,
|
|
107
|
+
width: blast.size,
|
|
108
|
+
height: blast.size,
|
|
109
|
+
transform: "translate(-50%, -50%)",
|
|
110
|
+
willChange: "transform, opacity",
|
|
111
|
+
filter: `hue-rotate(${blast.hue}deg)`
|
|
112
|
+
},
|
|
113
|
+
children: [
|
|
114
|
+
/* @__PURE__ */ jsx("span", { className: "cursor-blast-ring" }),
|
|
115
|
+
/* @__PURE__ */ jsx("span", { className: "cursor-blast-core" }),
|
|
116
|
+
Array.from({ length: 10 }).map((_, index) => {
|
|
117
|
+
return /* @__PURE__ */ jsx("span", {
|
|
118
|
+
className: "cursor-blast-shard-wrap",
|
|
119
|
+
style: {
|
|
120
|
+
transform: `translate(-50%, -50%) rotate(${360 / 10 * index}deg)`,
|
|
121
|
+
animationDelay: `${index * 16}ms`
|
|
122
|
+
},
|
|
123
|
+
children: /* @__PURE__ */ jsx("span", { className: "cursor-blast-shard" })
|
|
124
|
+
}, `${blast.id}-${index}`);
|
|
125
|
+
})
|
|
126
|
+
]
|
|
127
|
+
}, blast.id)), /* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: `
|
|
128
|
+
.cursor-blast-ring {
|
|
129
|
+
position: absolute;
|
|
130
|
+
inset: 0;
|
|
131
|
+
border-radius: 999px;
|
|
132
|
+
border: 2px solid hsl(197 98% 67% / 0.9);
|
|
133
|
+
box-shadow:
|
|
134
|
+
0 0 22px hsl(191 100% 72% / 0.6),
|
|
135
|
+
inset 0 0 12px hsl(204 100% 77% / 0.65);
|
|
136
|
+
animation: blast-ring 560ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.cursor-blast-core {
|
|
140
|
+
position: absolute;
|
|
141
|
+
left: 50%;
|
|
142
|
+
top: 50%;
|
|
143
|
+
width: 10px;
|
|
144
|
+
height: 10px;
|
|
145
|
+
border-radius: 999px;
|
|
146
|
+
transform: translate(-50%, -50%);
|
|
147
|
+
background: hsl(196 100% 85%);
|
|
148
|
+
box-shadow:
|
|
149
|
+
0 0 26px hsl(193 100% 72% / 0.9),
|
|
150
|
+
0 0 10px hsl(201 100% 85% / 0.9);
|
|
151
|
+
animation: blast-core 420ms ease-out forwards;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.cursor-blast-shard-wrap {
|
|
155
|
+
position: absolute;
|
|
156
|
+
left: 50%;
|
|
157
|
+
top: 50%;
|
|
158
|
+
width: 0;
|
|
159
|
+
height: 0;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.cursor-blast-shard {
|
|
163
|
+
position: absolute;
|
|
164
|
+
left: 0;
|
|
165
|
+
top: -1.5px;
|
|
166
|
+
width: 12px;
|
|
167
|
+
height: 3px;
|
|
168
|
+
border-radius: 999px;
|
|
169
|
+
background: linear-gradient(90deg, hsl(190 100% 84%), hsl(197 98% 67%));
|
|
170
|
+
box-shadow: 0 0 12px hsl(195 100% 70% / 0.8);
|
|
171
|
+
animation: blast-shard 680ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
@keyframes blast-ring {
|
|
175
|
+
0% {
|
|
176
|
+
transform: scale(0.2);
|
|
177
|
+
opacity: 0.95;
|
|
178
|
+
}
|
|
179
|
+
100% {
|
|
180
|
+
transform: scale(1.6);
|
|
181
|
+
opacity: 0;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
@keyframes blast-core {
|
|
186
|
+
0% {
|
|
187
|
+
transform: translate(-50%, -50%) scale(0.5);
|
|
188
|
+
opacity: 1;
|
|
189
|
+
}
|
|
190
|
+
100% {
|
|
191
|
+
transform: translate(-50%, -50%) scale(2.2);
|
|
192
|
+
opacity: 0;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
@keyframes blast-shard {
|
|
197
|
+
0% {
|
|
198
|
+
transform: translateX(0) scaleX(0.7);
|
|
199
|
+
opacity: 1;
|
|
200
|
+
}
|
|
201
|
+
100% {
|
|
202
|
+
transform: translateX(46px) scaleX(1.1);
|
|
203
|
+
opacity: 0;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
@media (prefers-reduced-motion: reduce) {
|
|
208
|
+
.cursor-blast-ring,
|
|
209
|
+
.cursor-blast-core,
|
|
210
|
+
.cursor-blast-shard {
|
|
211
|
+
animation-duration: 1ms;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
` } })] });
|
|
215
|
+
if (containerRef) return /* @__PURE__ */ jsx("div", {
|
|
216
|
+
"aria-hidden": true,
|
|
217
|
+
style: {
|
|
218
|
+
position: "absolute",
|
|
219
|
+
inset: 0,
|
|
220
|
+
zIndex: 2147483647,
|
|
221
|
+
pointerEvents: "none",
|
|
222
|
+
overflow: "hidden",
|
|
223
|
+
borderRadius: "inherit"
|
|
224
|
+
},
|
|
225
|
+
children: blastElements
|
|
226
|
+
});
|
|
227
|
+
return createPortal(/* @__PURE__ */ jsx("div", {
|
|
228
|
+
"aria-hidden": true,
|
|
229
|
+
style: {
|
|
230
|
+
position: "fixed",
|
|
231
|
+
inset: 0,
|
|
232
|
+
zIndex: 2147483647,
|
|
233
|
+
pointerEvents: "none"
|
|
234
|
+
},
|
|
235
|
+
children: blastElements
|
|
236
|
+
}), document.body);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
//#endregion
|
|
240
|
+
export { CursorBlastEffect };
|
|
241
|
+
//# sourceMappingURL=cursor-blast-effect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-blast-effect.js","names":[],"sources":["../../../src/components/cursor-blast-effect.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\n\ntype Blast = {\n id: number,\n x: number,\n y: number,\n size: number,\n hue: number,\n};\n\nconst DEFAULT_BLAST_LIFETIME_MS = 720;\nconst DEFAULT_MAX_ACTIVE_BLASTS = 18;\n\n/** Minimum rapid clicks in the time window to count as a rage click */\nconst DEFAULT_RAGE_CLICK_THRESHOLD = 3;\n/** Time window (ms) in which clicks must occur to be considered rage clicking */\nconst DEFAULT_RAGE_CLICK_WINDOW_MS = 600;\n/** Max distance (px) between clicks to still count as same-spot rage clicking */\nconst DEFAULT_RAGE_CLICK_RADIUS_PX = 60;\n\ntype RecentClick = {\n time: number,\n x: number,\n y: number,\n};\n\nexport type CursorBlastEffectProps = {\n /** Lifetime of each blast animation in ms. Default: 720 */\n blastLifetimeMs?: number,\n /** Maximum number of concurrent active blasts. Default: 18 */\n maxActiveBlasts?: number,\n /** Minimum rapid clicks in the time window to trigger a blast. Default: 3 */\n rageClickThreshold?: number,\n /** Time window (ms) for counting rage clicks. Default: 600 */\n rageClickWindowMs?: number,\n /** Max distance (px) between clicks to count as same-spot rage clicking. Default: 60 */\n rageClickRadiusPx?: number,\n /**\n * When provided, the blast effect is scoped to this container element.\n * Clicks are only detected within the container and blasts are positioned\n * relative to the container rather than the viewport.\n */\n containerRef?: React.RefObject<HTMLElement | null>,\n};\n\nexport function CursorBlastEffect({\n blastLifetimeMs = DEFAULT_BLAST_LIFETIME_MS,\n maxActiveBlasts = DEFAULT_MAX_ACTIVE_BLASTS,\n rageClickThreshold = DEFAULT_RAGE_CLICK_THRESHOLD,\n rageClickWindowMs = DEFAULT_RAGE_CLICK_WINDOW_MS,\n rageClickRadiusPx = DEFAULT_RAGE_CLICK_RADIUS_PX,\n containerRef,\n}: CursorBlastEffectProps = {}) {\n const [blasts, setBlasts] = useState<Blast[]>([]);\n const [mounted, setMounted] = useState(false);\n const idCounterRef = useRef(0);\n const timeoutIdsRef = useRef<Map<number, number>>(new Map());\n const recentClicksRef = useRef<RecentClick[]>([]);\n\n // Store latest config in refs so the effect callback always reads current values\n const configRef = useRef({\n blastLifetimeMs,\n maxActiveBlasts,\n rageClickThreshold,\n rageClickWindowMs,\n rageClickRadiusPx,\n });\n configRef.current = {\n blastLifetimeMs,\n maxActiveBlasts,\n rageClickThreshold,\n rageClickWindowMs,\n rageClickRadiusPx,\n };\n\n useEffect(() => {\n setMounted(true);\n }, []);\n\n useEffect(() => {\n const removeBlast = (id: number) => {\n setBlasts((prev) => prev.filter((blast) => blast.id !== id));\n const timeoutId = timeoutIdsRef.current.get(id);\n if (timeoutId !== undefined) {\n window.clearTimeout(timeoutId);\n timeoutIdsRef.current.delete(id);\n }\n };\n\n const spawnBlast = (x: number, y: number) => {\n const cfg = configRef.current;\n const nextId = idCounterRef.current;\n idCounterRef.current += 1;\n\n const nextBlast: Blast = {\n id: nextId,\n x,\n y,\n size: 44 + Math.random() * 20,\n hue: 185 + Math.random() * 35,\n };\n\n setBlasts((prev) => {\n const next = [...prev, nextBlast];\n if (next.length <= cfg.maxActiveBlasts) {\n return next;\n }\n return next.slice(next.length - cfg.maxActiveBlasts);\n });\n\n const timeoutId = window.setTimeout(() => removeBlast(nextId), cfg.blastLifetimeMs);\n timeoutIdsRef.current.set(nextId, timeoutId);\n };\n\n const onClick = (event: MouseEvent) => {\n const cfg = configRef.current;\n const now = performance.now();\n\n let x: number;\n let y: number;\n\n if (containerRef?.current) {\n const rect = containerRef.current.getBoundingClientRect();\n x = event.clientX - rect.left;\n y = event.clientY - rect.top;\n } else {\n x = event.clientX;\n y = event.clientY;\n }\n\n // Prune clicks outside the time window\n recentClicksRef.current = recentClicksRef.current.filter(\n (click) => now - click.time < cfg.rageClickWindowMs,\n );\n\n recentClicksRef.current.push({ time: now, x, y });\n\n // Count how many recent clicks are within the radius of the current click\n const nearbyCount = recentClicksRef.current.filter((click) => {\n const dx = click.x - x;\n const dy = click.y - y;\n return Math.sqrt(dx * dx + dy * dy) <= cfg.rageClickRadiusPx;\n }).length;\n\n if (nearbyCount >= cfg.rageClickThreshold) {\n spawnBlast(x, y);\n }\n };\n\n const target = containerRef?.current ?? window;\n const timeoutIds = timeoutIdsRef.current;\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion -- EventTarget union requires cast\n (target as EventTarget).addEventListener(\"click\", onClick as EventListener);\n return () => {\n (target as EventTarget).removeEventListener(\"click\", onClick as EventListener);\n for (const timeoutId of timeoutIds.values()) {\n window.clearTimeout(timeoutId);\n }\n timeoutIds.clear();\n };\n }, [containerRef]);\n\n if (!mounted) {\n return null;\n }\n\n const blastElements = (\n <>\n {blasts.map((blast) => (\n <div\n key={blast.id}\n style={{\n position: \"absolute\",\n left: blast.x,\n top: blast.y,\n width: blast.size,\n height: blast.size,\n transform: \"translate(-50%, -50%)\",\n willChange: \"transform, opacity\",\n filter: `hue-rotate(${blast.hue}deg)`,\n }}\n >\n <span className=\"cursor-blast-ring\" />\n <span className=\"cursor-blast-core\" />\n {Array.from({ length: 10 }).map((_, index) => {\n const angle = (360 / 10) * index;\n return (\n <span\n key={`${blast.id}-${index}`}\n className=\"cursor-blast-shard-wrap\"\n style={{\n transform: `translate(-50%, -50%) rotate(${angle}deg)`,\n animationDelay: `${index * 16}ms`,\n }}\n >\n <span className=\"cursor-blast-shard\" />\n </span>\n );\n })}\n </div>\n ))}\n <style dangerouslySetInnerHTML={{ __html: `\n .cursor-blast-ring {\n position: absolute;\n inset: 0;\n border-radius: 999px;\n border: 2px solid hsl(197 98% 67% / 0.9);\n box-shadow:\n 0 0 22px hsl(191 100% 72% / 0.6),\n inset 0 0 12px hsl(204 100% 77% / 0.65);\n animation: blast-ring 560ms cubic-bezier(0.16, 1, 0.3, 1) forwards;\n }\n\n .cursor-blast-core {\n position: absolute;\n left: 50%;\n top: 50%;\n width: 10px;\n height: 10px;\n border-radius: 999px;\n transform: translate(-50%, -50%);\n background: hsl(196 100% 85%);\n box-shadow:\n 0 0 26px hsl(193 100% 72% / 0.9),\n 0 0 10px hsl(201 100% 85% / 0.9);\n animation: blast-core 420ms ease-out forwards;\n }\n\n .cursor-blast-shard-wrap {\n position: absolute;\n left: 50%;\n top: 50%;\n width: 0;\n height: 0;\n }\n\n .cursor-blast-shard {\n position: absolute;\n left: 0;\n top: -1.5px;\n width: 12px;\n height: 3px;\n border-radius: 999px;\n background: linear-gradient(90deg, hsl(190 100% 84%), hsl(197 98% 67%));\n box-shadow: 0 0 12px hsl(195 100% 70% / 0.8);\n animation: blast-shard 680ms cubic-bezier(0.22, 1, 0.36, 1) forwards;\n }\n\n @keyframes blast-ring {\n 0% {\n transform: scale(0.2);\n opacity: 0.95;\n }\n 100% {\n transform: scale(1.6);\n opacity: 0;\n }\n }\n\n @keyframes blast-core {\n 0% {\n transform: translate(-50%, -50%) scale(0.5);\n opacity: 1;\n }\n 100% {\n transform: translate(-50%, -50%) scale(2.2);\n opacity: 0;\n }\n }\n\n @keyframes blast-shard {\n 0% {\n transform: translateX(0) scaleX(0.7);\n opacity: 1;\n }\n 100% {\n transform: translateX(46px) scaleX(1.1);\n opacity: 0;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .cursor-blast-ring,\n .cursor-blast-core,\n .cursor-blast-shard {\n animation-duration: 1ms;\n }\n }\n ` }} />\n </>\n );\n\n // When scoped to a container, render inline (the container must have position: relative)\n if (containerRef) {\n return (\n <div\n aria-hidden\n style={{\n position: \"absolute\",\n inset: 0,\n zIndex: 2147483647,\n pointerEvents: \"none\",\n overflow: \"hidden\",\n borderRadius: \"inherit\",\n }}\n >\n {blastElements}\n </div>\n );\n }\n\n // Default: portal to body with fixed positioning (original behaviour)\n return createPortal(\n <div\n aria-hidden\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 2147483647,\n pointerEvents: \"none\",\n }}\n >\n {blastElements}\n </div>,\n document.body,\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
2
|
+
|
|
3
|
+
//#region src/components/edit-mode.d.ts
|
|
4
|
+
declare function DesignEditMode({
|
|
5
|
+
children
|
|
6
|
+
}: {
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
}): react_jsx_runtime0.JSX.Element;
|
|
9
|
+
declare function useDesignEditMode(): boolean;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { DesignEditMode, useDesignEditMode };
|
|
12
|
+
//# sourceMappingURL=edit-mode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit-mode.d.ts","names":[],"sources":["../../../src/components/edit-mode.tsx"],"mappings":";;;iBAMgB,cAAA,CAAA;EAAiB;AAAA;EAAc,QAAA,EAAU,KAAA,CAAM,SAAA;AAAA,IAAW,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAQ1D,iBAAA,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
import { createContext, useContext } from "react";
|
|
5
|
+
|
|
6
|
+
//#region src/components/edit-mode.tsx
|
|
7
|
+
const DesignEditModeContext = createContext(false);
|
|
8
|
+
function DesignEditMode({ children }) {
|
|
9
|
+
return /* @__PURE__ */ jsx(DesignEditModeContext.Provider, {
|
|
10
|
+
value: true,
|
|
11
|
+
children
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
function useDesignEditMode() {
|
|
15
|
+
return useContext(DesignEditModeContext);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
export { DesignEditMode, useDesignEditMode };
|
|
20
|
+
//# sourceMappingURL=edit-mode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit-mode.js","names":[],"sources":["../../../src/components/edit-mode.tsx"],"sourcesContent":["\"use client\";\n\nimport { createContext, useContext } from \"react\";\n\nconst DesignEditModeContext = createContext(false);\n\nexport function DesignEditMode({ children }: { children: React.ReactNode }) {\n return (\n <DesignEditModeContext.Provider value={true}>\n {children}\n </DesignEditModeContext.Provider>\n );\n}\n\nexport function useDesignEditMode(): boolean {\n return useContext(DesignEditModeContext);\n}\n"],"mappings":";;;;;;AAIA,MAAM,wBAAwB,cAAc,MAAM;AAElD,SAAgB,eAAe,EAAE,YAA2C;AAC1E,QACE,oBAAC,sBAAsB;EAAS,OAAO;EACpC;GAC8B;;AAIrC,SAAgB,oBAA6B;AAC3C,QAAO,WAAW,sBAAsB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
2
|
+
import React from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/components/empty-state.d.ts
|
|
5
|
+
type DesignEmptyStateProps = {
|
|
6
|
+
icon?: React.ElementType;
|
|
7
|
+
title?: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
children?: React.ReactNode;
|
|
10
|
+
className?: string;
|
|
11
|
+
};
|
|
12
|
+
declare function DesignEmptyState({
|
|
13
|
+
icon: Icon,
|
|
14
|
+
title,
|
|
15
|
+
description,
|
|
16
|
+
children,
|
|
17
|
+
className
|
|
18
|
+
}: DesignEmptyStateProps): react_jsx_runtime0.JSX.Element;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { DesignEmptyState, DesignEmptyStateProps };
|
|
21
|
+
//# sourceMappingURL=empty-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"empty-state.d.ts","names":[],"sources":["../../../src/components/empty-state.tsx"],"mappings":";;;;KAKY,qBAAA;EACV,IAAA,GAAO,KAAA,CAAM,WAAA;EACb,KAAA;EACA,WAAA;EACA,QAAA,GAAW,KAAA,CAAM,SAAA;EACjB,SAAA;AAAA;AAAA,iBAGc,gBAAA,CAAA;EACd,IAAA,EAAM,IAAA;EACN,KAAA;EACA,WAAA;EACA,QAAA;EACA;AAAA,GACC,qBAAA,GAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { cn } from "@stackframe/stack-ui";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import React from "react";
|
|
6
|
+
|
|
7
|
+
//#region src/components/empty-state.tsx
|
|
8
|
+
function DesignEmptyState({ icon: Icon, title = "No data available", description, children, className }) {
|
|
9
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
10
|
+
className: cn("flex flex-col items-center justify-center py-12 px-6 text-center", className),
|
|
11
|
+
children: [
|
|
12
|
+
Icon && /* @__PURE__ */ jsx("div", {
|
|
13
|
+
className: "mb-4",
|
|
14
|
+
children: /* @__PURE__ */ jsx(Icon, { className: "h-10 w-10 text-muted-foreground/30" })
|
|
15
|
+
}),
|
|
16
|
+
/* @__PURE__ */ jsx("h3", {
|
|
17
|
+
className: "text-sm font-medium text-foreground",
|
|
18
|
+
children: title
|
|
19
|
+
}),
|
|
20
|
+
description && /* @__PURE__ */ jsx("p", {
|
|
21
|
+
className: "mt-1 text-xs text-muted-foreground max-w-[280px]",
|
|
22
|
+
children: description
|
|
23
|
+
}),
|
|
24
|
+
children && /* @__PURE__ */ jsx("div", {
|
|
25
|
+
className: "mt-4",
|
|
26
|
+
children
|
|
27
|
+
})
|
|
28
|
+
]
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
//#endregion
|
|
33
|
+
export { DesignEmptyState };
|
|
34
|
+
//# sourceMappingURL=empty-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"empty-state.js","names":[],"sources":["../../../src/components/empty-state.tsx"],"sourcesContent":["\"use client\";\n\nimport { cn } from \"@stackframe/stack-ui\";\nimport React from \"react\";\n\nexport type DesignEmptyStateProps = {\n icon?: React.ElementType,\n title?: string,\n description?: string,\n children?: React.ReactNode,\n className?: string,\n};\n\nexport function DesignEmptyState({\n icon: Icon,\n title = \"No data available\",\n description,\n children,\n className,\n}: DesignEmptyStateProps) {\n return (\n <div\n className={cn(\n \"flex flex-col items-center justify-center py-12 px-6 text-center\",\n className\n )}\n >\n {Icon && (\n <div className=\"mb-4\">\n <Icon className=\"h-10 w-10 text-muted-foreground/30\" />\n </div>\n )}\n <h3 className=\"text-sm font-medium text-foreground\">\n {title}\n </h3>\n {description && (\n <p className=\"mt-1 text-xs text-muted-foreground max-w-[280px]\">\n {description}\n </p>\n )}\n {children && (\n <div className=\"mt-4\">\n {children}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;AAaA,SAAgB,iBAAiB,EAC/B,MAAM,MACN,QAAQ,qBACR,aACA,UACA,aACwB;AACxB,QACE,qBAAC;EACC,WAAW,GACT,oEACA,UACD;;GAEA,QACC,oBAAC;IAAI,WAAU;cACb,oBAAC,QAAK,WAAU,uCAAuC;KACnD;GAER,oBAAC;IAAG,WAAU;cACX;KACE;GACJ,eACC,oBAAC;IAAE,WAAU;cACV;KACC;GAEL,YACC,oBAAC;IAAI,WAAU;IACZ;KACG;;GAEJ"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/components/input.d.ts
|
|
4
|
+
type DesignInputProps = {
|
|
5
|
+
prefixItem?: React.ReactNode;
|
|
6
|
+
leadingIcon?: React.ReactNode;
|
|
7
|
+
size?: "sm" | "md" | "lg";
|
|
8
|
+
} & Omit<React.InputHTMLAttributes<HTMLInputElement>, "size">;
|
|
9
|
+
declare const DesignInput: React.FC<{
|
|
10
|
+
prefixItem?: React.ReactNode;
|
|
11
|
+
leadingIcon?: React.ReactNode;
|
|
12
|
+
size?: "sm" | "md" | "lg";
|
|
13
|
+
} & Omit<React.InputHTMLAttributes<HTMLInputElement>, "size"> & {
|
|
14
|
+
ref?: React.Ref<HTMLInputElement> | undefined;
|
|
15
|
+
}>;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { DesignInput, DesignInputProps };
|
|
18
|
+
//# sourceMappingURL=input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input.d.ts","names":[],"sources":["../../../src/components/input.tsx"],"mappings":";;;KAOY,gBAAA;EACV,UAAA,GAAa,KAAA,CAAM,SAAA;EACnB,WAAA,GAAc,KAAA,CAAM,SAAA;EACpB,IAAA;AAAA,IACE,IAAA,CAAK,KAAA,CAAM,mBAAA,CAAoB,gBAAA;AAAA,cAEtB,WAAA,EAAW,KAAA,CAAA,EAAA;eALT,KAAA,CAAM,SAAA;gBACL,KAAA,CAAM,SAAA"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { cn } from "@stackframe/stack-ui";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { forwardRefIfNeeded } from "@stackframe/stack-shared/dist/utils/react";
|
|
6
|
+
import React from "react";
|
|
7
|
+
|
|
8
|
+
//#region src/components/input.tsx
|
|
9
|
+
const DesignInput = forwardRefIfNeeded(({ className, type, prefixItem, leadingIcon, size = "md", ...props }, ref) => {
|
|
10
|
+
const sizeClasses = size === "sm" ? "h-7 px-2 text-xs" : size === "lg" ? "h-10 px-4 text-sm" : "h-9 px-3 text-sm";
|
|
11
|
+
const baseClasses = cn("stack-scope flex w-full rounded-xl border border-black/[0.08] dark:border-white/[0.06] bg-white/80 dark:bg-foreground/[0.03] shadow-sm ring-1 ring-black/[0.08] dark:ring-white/[0.06]", "file:border-0 file:bg-transparent file:text-sm file:font-medium", "placeholder:text-muted-foreground/50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-foreground/[0.1]", "disabled:cursor-not-allowed disabled:opacity-50", "transition-all duration-150 hover:transition-none hover:bg-white dark:hover:bg-foreground/[0.06]", sizeClasses);
|
|
12
|
+
if (prefixItem) return /* @__PURE__ */ jsxs("div", {
|
|
13
|
+
className: "flex flex-row items-center flex-1 rounded-xl border border-black/[0.08] dark:border-white/[0.06] bg-white/80 dark:bg-foreground/[0.03] shadow-sm ring-1 ring-black/[0.08] dark:ring-white/[0.06] overflow-hidden transition-all duration-150 hover:transition-none hover:bg-white dark:hover:bg-foreground/[0.06] focus-within:ring-1 focus-within:ring-foreground/[0.1]",
|
|
14
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
15
|
+
className: cn("flex self-stretch items-center justify-center select-none text-muted-foreground/70 border-r border-black/[0.06] dark:border-white/[0.06] bg-black/[0.03] dark:bg-white/[0.02]", size === "sm" ? "px-2.5 text-xs" : size === "lg" ? "px-3.5 text-sm" : "px-3 text-sm"),
|
|
16
|
+
children: prefixItem
|
|
17
|
+
}), /* @__PURE__ */ jsx("input", {
|
|
18
|
+
type,
|
|
19
|
+
className: cn("stack-scope flex w-full bg-transparent", "file:border-0 file:bg-transparent file:text-sm file:font-medium", "placeholder:text-muted-foreground/50 focus-visible:outline-none", "disabled:cursor-not-allowed disabled:opacity-50", sizeClasses, "rounded-none border-0 shadow-none ring-0 focus-visible:ring-0", className),
|
|
20
|
+
ref,
|
|
21
|
+
...props
|
|
22
|
+
})]
|
|
23
|
+
});
|
|
24
|
+
if (leadingIcon) return /* @__PURE__ */ jsxs("div", {
|
|
25
|
+
className: "relative flex flex-row items-center flex-1",
|
|
26
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
27
|
+
className: "pointer-events-none absolute left-2.5 flex items-center text-muted-foreground",
|
|
28
|
+
children: leadingIcon
|
|
29
|
+
}), /* @__PURE__ */ jsx("input", {
|
|
30
|
+
type,
|
|
31
|
+
className: cn(baseClasses, "pl-8", className),
|
|
32
|
+
ref,
|
|
33
|
+
...props
|
|
34
|
+
})]
|
|
35
|
+
});
|
|
36
|
+
return /* @__PURE__ */ jsx("div", {
|
|
37
|
+
className: "flex flex-row items-center flex-1",
|
|
38
|
+
children: /* @__PURE__ */ jsx("input", {
|
|
39
|
+
type,
|
|
40
|
+
className: cn(baseClasses, className),
|
|
41
|
+
ref,
|
|
42
|
+
...props
|
|
43
|
+
})
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
DesignInput.displayName = "DesignInput";
|
|
47
|
+
|
|
48
|
+
//#endregion
|
|
49
|
+
export { DesignInput };
|
|
50
|
+
//# sourceMappingURL=input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input.js","names":[],"sources":["../../../src/components/input.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRefIfNeeded } from \"@stackframe/stack-shared/dist/utils/react\";\nimport React from \"react\";\n\nimport { cn } from \"@stackframe/stack-ui\";\n\nexport type DesignInputProps = {\n prefixItem?: React.ReactNode,\n leadingIcon?: React.ReactNode,\n size?: \"sm\" | \"md\" | \"lg\",\n} & Omit<React.InputHTMLAttributes<HTMLInputElement>, \"size\">;\n\nexport const DesignInput = forwardRefIfNeeded<HTMLInputElement, DesignInputProps>(\n ({ className, type, prefixItem, leadingIcon, size = \"md\", ...props }, ref) => {\n const sizeClasses = size === \"sm\"\n ? \"h-7 px-2 text-xs\"\n : size === \"lg\"\n ? \"h-10 px-4 text-sm\"\n : \"h-9 px-3 text-sm\";\n const baseClasses = cn(\n \"stack-scope flex w-full rounded-xl border border-black/[0.08] dark:border-white/[0.06] bg-white/80 dark:bg-foreground/[0.03] shadow-sm ring-1 ring-black/[0.08] dark:ring-white/[0.06]\",\n \"file:border-0 file:bg-transparent file:text-sm file:font-medium\",\n \"placeholder:text-muted-foreground/50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-foreground/[0.1]\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n \"transition-all duration-150 hover:transition-none hover:bg-white dark:hover:bg-foreground/[0.06]\",\n sizeClasses\n );\n\n if (prefixItem) {\n return (\n <div className=\"flex flex-row items-center flex-1 rounded-xl border border-black/[0.08] dark:border-white/[0.06] bg-white/80 dark:bg-foreground/[0.03] shadow-sm ring-1 ring-black/[0.08] dark:ring-white/[0.06] overflow-hidden transition-all duration-150 hover:transition-none hover:bg-white dark:hover:bg-foreground/[0.06] focus-within:ring-1 focus-within:ring-foreground/[0.1]\">\n <div className={cn(\n \"flex self-stretch items-center justify-center select-none text-muted-foreground/70 border-r border-black/[0.06] dark:border-white/[0.06] bg-black/[0.03] dark:bg-white/[0.02]\",\n size === \"sm\" ? \"px-2.5 text-xs\" : size === \"lg\" ? \"px-3.5 text-sm\" : \"px-3 text-sm\"\n )}>\n {prefixItem}\n </div>\n <input\n type={type}\n className={cn(\n \"stack-scope flex w-full bg-transparent\",\n \"file:border-0 file:bg-transparent file:text-sm file:font-medium\",\n \"placeholder:text-muted-foreground/50 focus-visible:outline-none\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n sizeClasses,\n \"rounded-none border-0 shadow-none ring-0 focus-visible:ring-0\",\n className\n )}\n ref={ref}\n {...props}\n />\n </div>\n );\n }\n\n if (leadingIcon) {\n return (\n <div className=\"relative flex flex-row items-center flex-1\">\n <div className=\"pointer-events-none absolute left-2.5 flex items-center text-muted-foreground\">\n {leadingIcon}\n </div>\n <input\n type={type}\n className={cn(baseClasses, \"pl-8\", className)}\n ref={ref}\n {...props}\n />\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-row items-center flex-1\">\n <input\n type={type}\n className={cn(baseClasses, className)}\n ref={ref}\n {...props}\n />\n </div>\n );\n }\n);\nDesignInput.displayName = \"DesignInput\";\n"],"mappings":";;;;;;;;AAaA,MAAa,cAAc,oBACxB,EAAE,WAAW,MAAM,YAAY,aAAa,OAAO,MAAM,GAAG,SAAS,QAAQ;CAC5E,MAAM,cAAc,SAAS,OACzB,qBACA,SAAS,OACP,sBACA;CACN,MAAM,cAAc,GAClB,0LACA,mEACA,4HACA,mDACA,oGACA,YACD;AAED,KAAI,WACF,QACE,qBAAC;EAAI,WAAU;aACb,oBAAC;GAAI,WAAW,GACd,iLACA,SAAS,OAAO,mBAAmB,SAAS,OAAO,mBAAmB,eACvE;aACE;IACG,EACN,oBAAC;GACO;GACN,WAAW,GACT,0CACA,mEACA,mEACA,mDACA,aACA,iEACA,UACD;GACI;GACL,GAAI;IACJ;GACE;AAIV,KAAI,YACF,QACE,qBAAC;EAAI,WAAU;aACb,oBAAC;GAAI,WAAU;aACZ;IACG,EACN,oBAAC;GACO;GACN,WAAW,GAAG,aAAa,QAAQ,UAAU;GACxC;GACL,GAAI;IACJ;GACE;AAIV,QACE,oBAAC;EAAI,WAAU;YACb,oBAAC;GACO;GACN,WAAW,GAAG,aAAa,UAAU;GAChC;GACL,GAAI;IACJ;GACE;EAGX;AACD,YAAY,cAAc"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
2
|
+
import React from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/components/metric-card.d.ts
|
|
5
|
+
type DesignMetricCardGradient = "blue" | "cyan" | "purple" | "green" | "orange" | "default";
|
|
6
|
+
type DesignMetricCardTrend = {
|
|
7
|
+
value: number;
|
|
8
|
+
direction: "up" | "down";
|
|
9
|
+
label?: string;
|
|
10
|
+
};
|
|
11
|
+
type DesignMetricCardProps = {
|
|
12
|
+
label: string;
|
|
13
|
+
value: string | number;
|
|
14
|
+
description?: string;
|
|
15
|
+
trend?: DesignMetricCardTrend;
|
|
16
|
+
icon?: React.ElementType;
|
|
17
|
+
gradient?: DesignMetricCardGradient;
|
|
18
|
+
} & Omit<React.ComponentProps<"div">, "children">;
|
|
19
|
+
declare function DesignMetricCard({
|
|
20
|
+
label,
|
|
21
|
+
value,
|
|
22
|
+
description,
|
|
23
|
+
trend,
|
|
24
|
+
icon: Icon,
|
|
25
|
+
gradient,
|
|
26
|
+
className,
|
|
27
|
+
...props
|
|
28
|
+
}: DesignMetricCardProps): react_jsx_runtime0.JSX.Element;
|
|
29
|
+
//#endregion
|
|
30
|
+
export { DesignMetricCard, DesignMetricCardProps, DesignMetricCardTrend };
|
|
31
|
+
//# sourceMappingURL=metric-card.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metric-card.d.ts","names":[],"sources":["../../../src/components/metric-card.tsx"],"mappings":";;;;KAKK,wBAAA;AAAA,KAWO,qBAAA;EACV,KAAA;EACA,SAAA;EACA,KAAA;AAAA;AAAA,KAGU,qBAAA;EACV,KAAA;EACA,KAAA;EACA,WAAA;EACA,KAAA,GAAQ,qBAAA;EACR,IAAA,GAAO,KAAA,CAAM,WAAA;EACb,QAAA,GAAW,wBAAA;AAAA,IACT,IAAA,CAAK,KAAA,CAAM,cAAA;AAAA,iBAEC,gBAAA,CAAA;EACd,KAAA;EACA,KAAA;EACA,WAAA;EACA,KAAA;EACA,IAAA,EAAM,IAAA;EACN,QAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,qBAAA,GAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { cn } from "@stackframe/stack-ui";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import React from "react";
|
|
6
|
+
|
|
7
|
+
//#region src/components/metric-card.tsx
|
|
8
|
+
const hoverTintClasses = new Map([
|
|
9
|
+
["blue", "group-hover:bg-blue-500/[0.03]"],
|
|
10
|
+
["cyan", "group-hover:bg-cyan-500/[0.03]"],
|
|
11
|
+
["purple", "group-hover:bg-purple-500/[0.03]"],
|
|
12
|
+
["green", "group-hover:bg-emerald-500/[0.03]"],
|
|
13
|
+
["orange", "group-hover:bg-orange-500/[0.03]"],
|
|
14
|
+
["default", "group-hover:bg-slate-500/[0.02]"]
|
|
15
|
+
]);
|
|
16
|
+
function DesignMetricCard({ label, value, description, trend, icon: Icon, gradient = "default", className, ...props }) {
|
|
17
|
+
const hoverTintClass = hoverTintClasses.get(gradient) ?? "group-hover:bg-slate-500/[0.02]";
|
|
18
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
19
|
+
className: cn("group relative rounded-2xl bg-white/90 dark:bg-background/60 backdrop-blur-xl transition-all duration-150 hover:transition-none overflow-hidden", "ring-1 ring-black/[0.06] hover:ring-black/[0.1] dark:ring-white/[0.06] dark:hover:ring-white/[0.1]", "shadow-sm hover:shadow-md", className),
|
|
20
|
+
...props,
|
|
21
|
+
children: [
|
|
22
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-br from-foreground/[0.04] dark:from-foreground/[0.02] to-transparent pointer-events-none rounded-2xl" }),
|
|
23
|
+
/* @__PURE__ */ jsx("div", { className: cn("absolute inset-0 transition-colors duration-150 group-hover:transition-none pointer-events-none rounded-2xl", hoverTintClass) }),
|
|
24
|
+
/* @__PURE__ */ jsx("div", {
|
|
25
|
+
className: "relative p-5",
|
|
26
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
27
|
+
className: "flex items-start justify-between gap-3",
|
|
28
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
29
|
+
className: "flex-1 min-w-0",
|
|
30
|
+
children: [
|
|
31
|
+
/* @__PURE__ */ jsxs("div", {
|
|
32
|
+
className: "flex items-center gap-2",
|
|
33
|
+
children: [Icon && /* @__PURE__ */ jsx("div", {
|
|
34
|
+
className: "p-1.5 rounded-lg bg-foreground/[0.06] dark:bg-foreground/[0.04]",
|
|
35
|
+
children: /* @__PURE__ */ jsx(Icon, { className: "h-3.5 w-3.5 text-foreground/70 dark:text-muted-foreground" })
|
|
36
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
37
|
+
className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider",
|
|
38
|
+
children: label
|
|
39
|
+
})]
|
|
40
|
+
}),
|
|
41
|
+
/* @__PURE__ */ jsxs("div", {
|
|
42
|
+
className: "mt-3 flex items-baseline gap-2",
|
|
43
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
44
|
+
className: "text-3xl font-bold tabular-nums text-foreground",
|
|
45
|
+
children: typeof value === "number" ? value.toLocaleString() : value
|
|
46
|
+
}), trend && /* @__PURE__ */ jsxs("span", {
|
|
47
|
+
className: cn("inline-flex items-center gap-0.5 text-xs font-medium", trend.direction === "up" ? "text-emerald-600 dark:text-emerald-400" : "text-red-600 dark:text-red-400"),
|
|
48
|
+
children: [
|
|
49
|
+
/* @__PURE__ */ jsx("svg", {
|
|
50
|
+
className: cn("h-3 w-3", trend.direction === "down" && "rotate-180"),
|
|
51
|
+
viewBox: "0 0 12 12",
|
|
52
|
+
fill: "none",
|
|
53
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
54
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
55
|
+
d: "M6 2.5V9.5M6 2.5L3 5.5M6 2.5L9 5.5",
|
|
56
|
+
stroke: "currentColor",
|
|
57
|
+
strokeWidth: "1.5",
|
|
58
|
+
strokeLinecap: "round",
|
|
59
|
+
strokeLinejoin: "round"
|
|
60
|
+
})
|
|
61
|
+
}),
|
|
62
|
+
trend.value,
|
|
63
|
+
"%",
|
|
64
|
+
trend.label && /* @__PURE__ */ jsx("span", {
|
|
65
|
+
className: "text-muted-foreground ml-0.5",
|
|
66
|
+
children: trend.label
|
|
67
|
+
})
|
|
68
|
+
]
|
|
69
|
+
})]
|
|
70
|
+
}),
|
|
71
|
+
description && /* @__PURE__ */ jsx("p", {
|
|
72
|
+
className: "mt-1 text-xs text-muted-foreground",
|
|
73
|
+
children: description
|
|
74
|
+
})
|
|
75
|
+
]
|
|
76
|
+
})
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
]
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
//#endregion
|
|
84
|
+
export { DesignMetricCard };
|
|
85
|
+
//# sourceMappingURL=metric-card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metric-card.js","names":[],"sources":["../../../src/components/metric-card.tsx"],"sourcesContent":["\"use client\";\n\nimport { cn } from \"@stackframe/stack-ui\";\nimport React from \"react\";\n\ntype DesignMetricCardGradient = \"blue\" | \"cyan\" | \"purple\" | \"green\" | \"orange\" | \"default\";\n\nconst hoverTintClasses = new Map<DesignMetricCardGradient, string>([\n [\"blue\", \"group-hover:bg-blue-500/[0.03]\"],\n [\"cyan\", \"group-hover:bg-cyan-500/[0.03]\"],\n [\"purple\", \"group-hover:bg-purple-500/[0.03]\"],\n [\"green\", \"group-hover:bg-emerald-500/[0.03]\"],\n [\"orange\", \"group-hover:bg-orange-500/[0.03]\"],\n [\"default\", \"group-hover:bg-slate-500/[0.02]\"],\n]);\n\nexport type DesignMetricCardTrend = {\n value: number,\n direction: \"up\" | \"down\",\n label?: string,\n};\n\nexport type DesignMetricCardProps = {\n label: string,\n value: string | number,\n description?: string,\n trend?: DesignMetricCardTrend,\n icon?: React.ElementType,\n gradient?: DesignMetricCardGradient,\n} & Omit<React.ComponentProps<\"div\">, \"children\">;\n\nexport function DesignMetricCard({\n label,\n value,\n description,\n trend,\n icon: Icon,\n gradient = \"default\",\n className,\n ...props\n}: DesignMetricCardProps) {\n const hoverTintClass = hoverTintClasses.get(gradient) ?? \"group-hover:bg-slate-500/[0.02]\";\n\n return (\n <div\n className={cn(\n \"group relative rounded-2xl bg-white/90 dark:bg-background/60 backdrop-blur-xl transition-all duration-150 hover:transition-none overflow-hidden\",\n \"ring-1 ring-black/[0.06] hover:ring-black/[0.1] dark:ring-white/[0.06] dark:hover:ring-white/[0.1]\",\n \"shadow-sm hover:shadow-md\",\n className\n )}\n {...props}\n >\n <div className=\"absolute inset-0 bg-gradient-to-br from-foreground/[0.04] dark:from-foreground/[0.02] to-transparent pointer-events-none rounded-2xl\" />\n <div\n className={cn(\n \"absolute inset-0 transition-colors duration-150 group-hover:transition-none pointer-events-none rounded-2xl\",\n hoverTintClass\n )}\n />\n <div className=\"relative p-5\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n {Icon && (\n <div className=\"p-1.5 rounded-lg bg-foreground/[0.06] dark:bg-foreground/[0.04]\">\n <Icon className=\"h-3.5 w-3.5 text-foreground/70 dark:text-muted-foreground\" />\n </div>\n )}\n <span className=\"text-xs font-semibold text-muted-foreground uppercase tracking-wider\">\n {label}\n </span>\n </div>\n <div className=\"mt-3 flex items-baseline gap-2\">\n <span className=\"text-3xl font-bold tabular-nums text-foreground\">\n {typeof value === \"number\" ? value.toLocaleString() : value}\n </span>\n {trend && (\n <span\n className={cn(\n \"inline-flex items-center gap-0.5 text-xs font-medium\",\n trend.direction === \"up\"\n ? \"text-emerald-600 dark:text-emerald-400\"\n : \"text-red-600 dark:text-red-400\"\n )}\n >\n <svg\n className={cn(\"h-3 w-3\", trend.direction === \"down\" && \"rotate-180\")}\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M6 2.5V9.5M6 2.5L3 5.5M6 2.5L9 5.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n {trend.value}%\n {trend.label && (\n <span className=\"text-muted-foreground ml-0.5\">{trend.label}</span>\n )}\n </span>\n )}\n </div>\n {description && (\n <p className=\"mt-1 text-xs text-muted-foreground\">\n {description}\n </p>\n )}\n </div>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;AAOA,MAAM,mBAAmB,IAAI,IAAsC;CACjE,CAAC,QAAQ,iCAAiC;CAC1C,CAAC,QAAQ,iCAAiC;CAC1C,CAAC,UAAU,mCAAmC;CAC9C,CAAC,SAAS,oCAAoC;CAC9C,CAAC,UAAU,mCAAmC;CAC9C,CAAC,WAAW,kCAAkC;CAC/C,CAAC;AAiBF,SAAgB,iBAAiB,EAC/B,OACA,OACA,aACA,OACA,MAAM,MACN,WAAW,WACX,WACA,GAAG,SACqB;CACxB,MAAM,iBAAiB,iBAAiB,IAAI,SAAS,IAAI;AAEzD,QACE,qBAAC;EACC,WAAW,GACT,mJACA,sGACA,6BACA,UACD;EACD,GAAI;;GAEJ,oBAAC,SAAI,WAAU,yIAAyI;GACxJ,oBAAC,SACC,WAAW,GACT,+GACA,eACD,GACD;GACF,oBAAC;IAAI,WAAU;cACb,oBAAC;KAAI,WAAU;eACb,qBAAC;MAAI,WAAU;;OACb,qBAAC;QAAI,WAAU;mBACZ,QACC,oBAAC;SAAI,WAAU;mBACb,oBAAC,QAAK,WAAU,8DAA8D;UAC1E,EAER,oBAAC;SAAK,WAAU;mBACb;UACI;SACH;OACN,qBAAC;QAAI,WAAU;mBACb,oBAAC;SAAK,WAAU;mBACb,OAAO,UAAU,WAAW,MAAM,gBAAgB,GAAG;UACjD,EACN,SACC,qBAAC;SACC,WAAW,GACT,wDACA,MAAM,cAAc,OAChB,2CACA,iCACL;;UAED,oBAAC;WACC,WAAW,GAAG,WAAW,MAAM,cAAc,UAAU,aAAa;WACpE,SAAQ;WACR,MAAK;WACL,OAAM;qBAEN,oBAAC;YACC,GAAE;YACF,QAAO;YACP,aAAY;YACZ,eAAc;YACd,gBAAe;aACf;YACE;UACL,MAAM;UAAM;UACZ,MAAM,SACL,oBAAC;WAAK,WAAU;qBAAgC,MAAM;YAAa;;UAEhE;SAEL;OACL,eACC,oBAAC;QAAE,WAAU;kBACV;SACC;;OAEF;MACF;KACF;;GACF"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
2
|
+
|
|
3
|
+
//#region src/components/pill-toggle.d.ts
|
|
4
|
+
type DesignPillToggleSize = "sm" | "md" | "lg";
|
|
5
|
+
type DesignPillToggleGradient = "blue" | "cyan" | "purple" | "green" | "orange" | "default";
|
|
6
|
+
type DesignPillToggleOption = {
|
|
7
|
+
id: string;
|
|
8
|
+
label: string;
|
|
9
|
+
icon?: React.ElementType;
|
|
10
|
+
};
|
|
11
|
+
type DesignPillToggleProps = {
|
|
12
|
+
options: DesignPillToggleOption[];
|
|
13
|
+
selected: string;
|
|
14
|
+
onSelect: (id: string) => void | Promise<void>;
|
|
15
|
+
size?: DesignPillToggleSize;
|
|
16
|
+
glassmorphic?: boolean;
|
|
17
|
+
gradient?: DesignPillToggleGradient; /** When false, hides labels and shows a tooltip on hover instead. Defaults to true. */
|
|
18
|
+
showLabels?: boolean;
|
|
19
|
+
className?: string;
|
|
20
|
+
};
|
|
21
|
+
declare function DesignPillToggle({
|
|
22
|
+
options,
|
|
23
|
+
selected,
|
|
24
|
+
onSelect,
|
|
25
|
+
size,
|
|
26
|
+
glassmorphic: glassmorphicProp,
|
|
27
|
+
gradient,
|
|
28
|
+
showLabels,
|
|
29
|
+
className
|
|
30
|
+
}: DesignPillToggleProps): react_jsx_runtime0.JSX.Element;
|
|
31
|
+
//#endregion
|
|
32
|
+
export { DesignPillToggle, DesignPillToggleOption, DesignPillToggleProps };
|
|
33
|
+
//# sourceMappingURL=pill-toggle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pill-toggle.d.ts","names":[],"sources":["../../../src/components/pill-toggle.tsx"],"mappings":";;;KAQK,oBAAA;AAAA,KACA,wBAAA;AAAA,KAEO,sBAAA;EACV,EAAA;EACA,KAAA;EACA,IAAA,GAAO,KAAA,CAAM,WAAA;AAAA;AAAA,KAGH,qBAAA;EACV,OAAA,EAAS,sBAAA;EACT,QAAA;EACA,QAAA,GAAW,EAAA,oBAAsB,OAAA;EACjC,IAAA,GAAO,oBAAA;EACP,YAAA;EACA,QAAA,GAAW,wBAAA,EAZqB;EAchC,UAAA;EACA,SAAA;AAAA;AAAA,iBA+Bc,gBAAA,CAAA;EACd,OAAA;EACA,QAAA;EACA,QAAA;EACA,IAAA;EACA,YAAA,EAAc,gBAAA;EACd,QAAA;EACA,UAAA;EACA;AAAA,GACC,qBAAA,GAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|