@saasflare/ui 3.1.2 → 3.2.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.
Files changed (56) hide show
  1. package/README.md +68 -2
  2. package/dist/{button-0Bdl7Nqm.d.ts → button-BA7OcXqy.d.mts} +12 -17
  3. package/dist/{button-Brb4BhPO.d.mts → button-Bfg2Tnvx.d.ts} +12 -17
  4. package/dist/{chunk-D5LKWKG7.js → chunk-2GOPD64T.js} +117 -89
  5. package/dist/{chunk-56PMDC5F.mjs → chunk-2ONA6OMO.mjs} +29 -40
  6. package/dist/{chunk-RW2S3KNB.mjs → chunk-5C65JNGY.mjs} +7 -6
  7. package/dist/{chunk-NPNSPYTX.js → chunk-7UD3SGPP.js} +28 -39
  8. package/dist/chunk-GI6VN7XU.mjs +2143 -0
  9. package/dist/{chunk-FT66KYRN.js → chunk-ITALEYDI.js} +2 -2
  10. package/dist/{chunk-4BOMMZEY.js → chunk-JC7EIEGI.js} +14 -13
  11. package/dist/chunk-N65HIOBD.js +234 -0
  12. package/dist/{chunk-EJHYM2HP.mjs → chunk-OZAWULTM.mjs} +1 -1
  13. package/dist/chunk-R3AVBLJ3.js +2207 -0
  14. package/dist/{chunk-WRONFPRI.mjs → chunk-RMQBB72G.mjs} +118 -91
  15. package/dist/chunk-XNDTCYSO.mjs +211 -0
  16. package/dist/{dialog-BmY55WSX.d.ts → dialog-CZRwrqDa.d.ts} +2 -2
  17. package/dist/{dialog-CcaHMAsS.d.mts → dialog-Cr0becOL.d.mts} +2 -2
  18. package/dist/entries/calendar.d.mts +3 -3
  19. package/dist/entries/calendar.d.ts +3 -3
  20. package/dist/entries/calendar.js +13 -214
  21. package/dist/entries/calendar.mjs +5 -196
  22. package/dist/entries/carousel.d.mts +3 -3
  23. package/dist/entries/carousel.d.ts +3 -3
  24. package/dist/entries/carousel.js +17 -14
  25. package/dist/entries/carousel.mjs +10 -7
  26. package/dist/entries/chart.d.mts +1 -1
  27. package/dist/entries/chart.d.ts +1 -1
  28. package/dist/entries/chart.js +11 -11
  29. package/dist/entries/chart.mjs +1 -1
  30. package/dist/entries/command.d.mts +3 -3
  31. package/dist/entries/command.d.ts +3 -3
  32. package/dist/entries/command.js +21 -19
  33. package/dist/entries/command.mjs +8 -6
  34. package/dist/entries/drawer.d.mts +1 -1
  35. package/dist/entries/drawer.d.ts +1 -1
  36. package/dist/entries/drawer.js +9 -9
  37. package/dist/entries/drawer.mjs +2 -2
  38. package/dist/entries/input-otp.d.mts +2 -2
  39. package/dist/entries/input-otp.d.ts +2 -2
  40. package/dist/entries/input-otp.js +10 -8
  41. package/dist/entries/input-otp.mjs +6 -4
  42. package/dist/entries/resizable.d.mts +3 -2
  43. package/dist/entries/resizable.d.ts +3 -2
  44. package/dist/entries/resizable.js +8 -6
  45. package/dist/entries/resizable.mjs +6 -4
  46. package/dist/index.d.mts +974 -31
  47. package/dist/index.d.ts +974 -31
  48. package/dist/index.js +2992 -554
  49. package/dist/index.mjs +2486 -199
  50. package/dist/{use-saasflare-props-NrM2Glmp.d.mts → use-saasflare-props-BrjMhU0U.d.mts} +53 -4
  51. package/dist/{use-saasflare-props-NrM2Glmp.d.ts → use-saasflare-props-BrjMhU0U.d.ts} +53 -4
  52. package/package.json +4 -3
  53. package/styles/aurora.css +47 -0
  54. package/styles/palettes.css +483 -3
  55. package/styles/surfaces.css +89 -10
  56. package/styles/theme.css +11 -5
package/dist/index.mjs CHANGED
@@ -1,17 +1,19 @@
1
1
  "use client";
2
- import { buttonVariants, Button } from './chunk-56PMDC5F.mjs';
3
- export { Button, buttonVariants } from './chunk-56PMDC5F.mjs';
4
- export { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger } from './chunk-RW2S3KNB.mjs';
5
- import { useSaasflareMotion, springGentle, springBouncy, spring } from './chunk-EJHYM2HP.mjs';
6
- export { fadeIn, noMotion, scaleIn, slideDown, slideUp, spring, springBouncy, springGentle, springStiff, useSaasflareMotion } from './chunk-EJHYM2HP.mjs';
7
- import { useSaasflareProps, cn } from './chunk-WRONFPRI.mjs';
8
- export { SaasflareProvider, SaasflareScript, SaasflareShell, SmoothScrollProvider, cn, useAnimation, useReducedMotion, useSaasflareProps, useSaasflareTheme } from './chunk-WRONFPRI.mjs';
2
+ import { Calendar } from './chunk-XNDTCYSO.mjs';
3
+ import { buttonVariants, Button } from './chunk-2ONA6OMO.mjs';
4
+ export { Button, buttonVariants } from './chunk-2ONA6OMO.mjs';
5
+ export { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger } from './chunk-5C65JNGY.mjs';
6
+ import { useSaasflareMotion, springGentle, springBouncy, spring } from './chunk-OZAWULTM.mjs';
7
+ export { fadeIn, noMotion, scaleIn, slideDown, slideUp, spring, springBouncy, springGentle, springStiff, useSaasflareMotion } from './chunk-OZAWULTM.mjs';
8
+ import { CaretDownIcon, CheckIcon, CaretUpIcon, CircleIcon, CaretRightIcon, XIcon, CircleNotchIcon, XCircleIcon, WarningIcon, InfoIcon, CheckCircleIcon, DotsThreeIcon, MagnifyingGlassIcon, CaretLeftIcon, SidebarSimpleIcon, ArrowUpIcon, TiktokLogoIcon, DribbbleLogoIcon, GitlabLogoIcon, StripeLogoIcon, PaypalLogoIcon, RedditLogoIcon, SlackLogoIcon, MediumLogoIcon, LinkedinLogoIcon, FacebookLogoIcon, DiscordLogoIcon, XLogoIcon, MicrosoftOutlookLogoIcon, AppleLogoIcon, GithubLogoIcon, GoogleLogoIcon, SunIcon, MoonIcon, MonitorIcon } from './chunk-GI6VN7XU.mjs';
9
+ export { ArrowLeftIcon, ArrowRightIcon, ArrowUpIcon, CaretDownIcon, CaretLeftIcon, CaretRightIcon, CaretUpIcon, CheckCircleIcon, CheckIcon, CircleIcon, CircleNotchIcon, DotsSixVerticalIcon, DotsThreeIcon, IconBase, InfoIcon, MagnifyingGlassIcon, MinusIcon, MonitorIcon, MoonIcon, PauseIcon, PlayIcon, QuotesIcon, SidebarSimpleIcon, SunIcon, WarningIcon, XCircleIcon, XIcon } from './chunk-GI6VN7XU.mjs';
10
+ import { useSaasflareProps, cn } from './chunk-RMQBB72G.mjs';
11
+ export { SaasflareProvider, SaasflareScript, SaasflareShell, SmoothScrollProvider, cn, useAnimation, useLocalStorage, useReducedMotion, useSaasflareProps, useSaasflareTheme } from './chunk-RMQBB72G.mjs';
9
12
  import * as React5 from 'react';
10
13
  import React5__default, { useState, useCallback, useMemo, useRef, useEffect, Suspense } from 'react';
11
14
  import { m, useMotionValue, useSpring, useTransform, AnimatePresence } from 'motion/react';
12
15
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
13
16
  import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
14
- import { ChevronDownIcon, CheckIcon, ChevronUpIcon, CircleIcon, ChevronRightIcon, XIcon, Loader2Icon, OctagonXIcon, TriangleAlertIcon, InfoIcon as InfoIcon$1, CircleCheckIcon, ChevronRight, MoreHorizontal, SearchIcon, ChevronLeftIcon, MoreHorizontalIcon, PanelLeftIcon, ArrowUpIcon, Sun, Moon } from 'lucide-react';
15
17
  import * as AccordionPrimitive from '@radix-ui/react-accordion';
16
18
  import { cva } from 'class-variance-authority';
17
19
  import * as TabsPrimitive from '@radix-ui/react-tabs';
@@ -177,6 +179,164 @@ function usePagination(options) {
177
179
  }, [activePage, safeTotal, siblings, boundaries]);
178
180
  return { activePage, range, setPage, next, previous, first, last };
179
181
  }
182
+ function useMergedRef(...refs) {
183
+ return useCallback(
184
+ (node) => {
185
+ for (const ref of refs) {
186
+ if (!ref) continue;
187
+ if (typeof ref === "function") {
188
+ ref(node);
189
+ } else {
190
+ ref.current = node;
191
+ }
192
+ }
193
+ },
194
+ // eslint-disable-next-line react-hooks/exhaustive-deps
195
+ refs
196
+ );
197
+ }
198
+ function useInterval(callback, delay, options = {}) {
199
+ const { autoInvoke = true } = options;
200
+ const [active, setActive] = useState(autoInvoke && delay !== null);
201
+ const intervalRef = useRef(null);
202
+ const callbackRef = useRef(callback);
203
+ useEffect(() => {
204
+ callbackRef.current = callback;
205
+ }, [callback]);
206
+ const stop = useCallback(() => {
207
+ if (intervalRef.current !== null) {
208
+ clearInterval(intervalRef.current);
209
+ intervalRef.current = null;
210
+ }
211
+ setActive(false);
212
+ }, []);
213
+ const start = useCallback(() => {
214
+ if (delay === null) return;
215
+ if (intervalRef.current !== null) clearInterval(intervalRef.current);
216
+ intervalRef.current = setInterval(() => callbackRef.current(), delay);
217
+ setActive(true);
218
+ }, [delay]);
219
+ const toggle = useCallback(() => {
220
+ if (active) stop();
221
+ else start();
222
+ }, [active, start, stop]);
223
+ useEffect(() => {
224
+ if (autoInvoke && delay !== null) start();
225
+ return stop;
226
+ }, [autoInvoke, delay, start, stop]);
227
+ return { active, start, stop, toggle };
228
+ }
229
+ var FOCUSABLE_SELECTOR = [
230
+ "a[href]",
231
+ "button:not([disabled])",
232
+ "input:not([disabled])",
233
+ "select:not([disabled])",
234
+ "textarea:not([disabled])",
235
+ "[tabindex]:not([tabindex='-1'])",
236
+ "[contenteditable='true']",
237
+ "audio[controls]",
238
+ "video[controls]",
239
+ "details > summary:first-of-type"
240
+ ].join(",");
241
+ function getFocusable(container) {
242
+ return Array.from(container.querySelectorAll(FOCUSABLE_SELECTOR)).filter(
243
+ (el) => !el.hasAttribute("disabled") && el.tabIndex !== -1 && isVisible(el)
244
+ );
245
+ }
246
+ function isVisible(el) {
247
+ return !!(el.offsetParent || el.getClientRects().length > 0);
248
+ }
249
+ function useFocusTrap(active) {
250
+ const containerRef = useRef(null);
251
+ const previousFocusRef = useRef(null);
252
+ const setRef = useCallback((node) => {
253
+ containerRef.current = node;
254
+ }, []);
255
+ useEffect(() => {
256
+ if (!active) return;
257
+ const container = containerRef.current;
258
+ if (!container) return;
259
+ previousFocusRef.current = document.activeElement ?? null;
260
+ const focusables = getFocusable(container);
261
+ const first = focusables[0];
262
+ if (first) first.focus();
263
+ else if (container.tabIndex >= 0) container.focus();
264
+ const handleKeyDown = (e) => {
265
+ if (e.key !== "Tab") return;
266
+ const items = getFocusable(container);
267
+ if (items.length === 0) {
268
+ e.preventDefault();
269
+ return;
270
+ }
271
+ const firstItem = items[0];
272
+ const lastItem = items[items.length - 1];
273
+ const active2 = document.activeElement;
274
+ if (e.shiftKey) {
275
+ if (active2 === firstItem || !container.contains(active2)) {
276
+ e.preventDefault();
277
+ lastItem.focus();
278
+ }
279
+ } else {
280
+ if (active2 === lastItem || !container.contains(active2)) {
281
+ e.preventDefault();
282
+ firstItem.focus();
283
+ }
284
+ }
285
+ };
286
+ container.addEventListener("keydown", handleKeyDown);
287
+ return () => {
288
+ container.removeEventListener("keydown", handleKeyDown);
289
+ const previous = previousFocusRef.current;
290
+ if (previous && typeof previous.focus === "function") {
291
+ previous.focus();
292
+ }
293
+ };
294
+ }, [active]);
295
+ return setRef;
296
+ }
297
+ function useFileDialog(options = {}) {
298
+ const { accept, multiple = false, directory = false, capture, onChange } = options;
299
+ const [files, setFiles] = useState([]);
300
+ const inputRef = useRef(null);
301
+ const handleChange = useCallback(
302
+ (e) => {
303
+ const target = e.target;
304
+ const picked = Array.from(target.files ?? []);
305
+ setFiles(picked);
306
+ onChange?.(picked);
307
+ target.value = "";
308
+ },
309
+ [onChange]
310
+ );
311
+ const ensureInput = useCallback(() => {
312
+ if (typeof document === "undefined") {
313
+ throw new Error("useFileDialog: open() called outside the browser");
314
+ }
315
+ if (inputRef.current) return inputRef.current;
316
+ const input = document.createElement("input");
317
+ input.type = "file";
318
+ input.style.display = "none";
319
+ if (accept) input.accept = accept;
320
+ if (multiple) input.multiple = true;
321
+ if (capture) input.capture = capture;
322
+ if (directory) {
323
+ input.setAttribute("webkitdirectory", "");
324
+ input.setAttribute("directory", "");
325
+ }
326
+ input.addEventListener("change", handleChange);
327
+ document.body.appendChild(input);
328
+ inputRef.current = input;
329
+ return input;
330
+ }, [accept, multiple, directory, capture, handleChange]);
331
+ const open = useCallback(() => {
332
+ ensureInput().click();
333
+ }, [ensureInput]);
334
+ const reset = useCallback(() => {
335
+ setFiles([]);
336
+ if (inputRef.current) inputRef.current.value = "";
337
+ }, []);
338
+ return { files, open, reset };
339
+ }
180
340
  function Card({ className, surface, radius, animated, ...props }) {
181
341
  const sf = useSaasflareProps({ surface, radius, animated });
182
342
  const motion = useSaasflareMotion(sf.animated, springGentle);
@@ -415,9 +575,10 @@ function AccordionItem({
415
575
  surface,
416
576
  radius,
417
577
  animated,
578
+ iconWeight,
418
579
  ...props
419
580
  }) {
420
- const sf = useSaasflareProps({ surface, radius, animated });
581
+ const sf = useSaasflareProps({ surface, radius, animated, iconWeight });
421
582
  return /* @__PURE__ */ jsx(
422
583
  AccordionPrimitive.Item,
423
584
  {
@@ -454,7 +615,7 @@ function AccordionTrigger({
454
615
  className: "pointer-events-none shrink-0 translate-y-0.5 text-muted-foreground",
455
616
  animate: { rotate: 0 },
456
617
  transition: motion.transition,
457
- children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4" })
618
+ children: /* @__PURE__ */ jsx(CaretDownIcon, { weight: sf.iconWeight, className: "size-4" })
458
619
  }
459
620
  )
460
621
  ]
@@ -688,9 +849,10 @@ function Checkbox({
688
849
  surface,
689
850
  radius,
690
851
  animated,
852
+ iconWeight,
691
853
  ...props
692
854
  }) {
693
- const sf = useSaasflareProps({ surface, radius, animated });
855
+ const sf = useSaasflareProps({ surface, radius, animated, iconWeight });
694
856
  const motion = useSaasflareMotion(sf.animated, springBouncy);
695
857
  return /* @__PURE__ */ jsx(
696
858
  CheckboxPrimitive.Root,
@@ -717,7 +879,7 @@ function Checkbox({
717
879
  animate: { scale: 1, opacity: 1 },
718
880
  exit: motion.disabled ? void 0 : { scale: 0, opacity: 0 },
719
881
  transition: motion.transition,
720
- children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-3.5" })
882
+ children: /* @__PURE__ */ jsx(CheckIcon, { weight: sf.iconWeight, className: "size-3.5" })
721
883
  }
722
884
  )
723
885
  }
@@ -801,6 +963,100 @@ function Progress({
801
963
  }
802
964
  );
803
965
  }
966
+ var SIZE_PX = {
967
+ sm: 48,
968
+ md: 64,
969
+ lg: 96,
970
+ xl: 128
971
+ };
972
+ function ProgressCircle({
973
+ value,
974
+ max = 100,
975
+ size = "md",
976
+ strokeWidth,
977
+ children,
978
+ className,
979
+ surface,
980
+ radius,
981
+ animated,
982
+ "aria-label": ariaLabel
983
+ }) {
984
+ const sf = useSaasflareProps({ surface, radius, animated });
985
+ const motion = useSaasflareMotion(sf.animated, springGentle);
986
+ const px = SIZE_PX[size];
987
+ const sw = strokeWidth ?? Math.max(3, Math.round(px / 12));
988
+ const radiusPx = (px - sw) / 2;
989
+ const circumference = 2 * Math.PI * radiusPx;
990
+ const clamped = Math.min(Math.max(value, 0), max);
991
+ const percent = clamped / max * 100;
992
+ const dashOffset = circumference * (1 - clamped / max);
993
+ return /* @__PURE__ */ jsxs(
994
+ "div",
995
+ {
996
+ "data-slot": "progress-circle",
997
+ "data-size": size,
998
+ "data-surface": sf.surface,
999
+ "data-animated": String(sf.animated),
1000
+ role: "progressbar",
1001
+ "aria-valuenow": clamped,
1002
+ "aria-valuemin": 0,
1003
+ "aria-valuemax": max,
1004
+ "aria-label": ariaLabel ?? `${Math.round(percent)}%`,
1005
+ className: cn("relative inline-flex items-center justify-center", className),
1006
+ style: { width: px, height: px },
1007
+ children: [
1008
+ /* @__PURE__ */ jsxs(
1009
+ "svg",
1010
+ {
1011
+ width: px,
1012
+ height: px,
1013
+ viewBox: `0 0 ${px} ${px}`,
1014
+ className: "-rotate-90",
1015
+ children: [
1016
+ /* @__PURE__ */ jsx(
1017
+ "circle",
1018
+ {
1019
+ "data-slot": "progress-circle-track",
1020
+ cx: px / 2,
1021
+ cy: px / 2,
1022
+ r: radiusPx,
1023
+ fill: "none",
1024
+ strokeWidth: sw,
1025
+ className: "stroke-primary/15"
1026
+ }
1027
+ ),
1028
+ /* @__PURE__ */ jsx(
1029
+ m.circle,
1030
+ {
1031
+ "data-slot": "progress-circle-indicator",
1032
+ cx: px / 2,
1033
+ cy: px / 2,
1034
+ r: radiusPx,
1035
+ fill: "none",
1036
+ strokeWidth: sw,
1037
+ strokeLinecap: "round",
1038
+ strokeDasharray: circumference,
1039
+ className: "stroke-primary",
1040
+ initial: motion.disabled ? false : { strokeDashoffset: circumference },
1041
+ animate: { strokeDashoffset: dashOffset },
1042
+ transition: motion.transition
1043
+ }
1044
+ )
1045
+ ]
1046
+ }
1047
+ ),
1048
+ children !== void 0 && /* @__PURE__ */ jsx(
1049
+ "div",
1050
+ {
1051
+ "data-slot": "progress-circle-label",
1052
+ className: "pointer-events-none absolute inset-0 flex items-center justify-center",
1053
+ children
1054
+ }
1055
+ )
1056
+ ]
1057
+ }
1058
+ );
1059
+ }
804
1060
  var LEGACY_VARIANT_MAP = {
805
1061
  default: { variant: "solid", intent: "primary" },
806
1062
  destructive: { variant: "solid", intent: "danger" },
@@ -1062,6 +1318,7 @@ function SelectTrigger({
1062
1318
  children,
1063
1319
  ...props
1064
1320
  }) {
1321
+ const sf = useSaasflareProps();
1065
1322
  return /* @__PURE__ */ jsxs(
1066
1323
  SelectPrimitive.Trigger,
1067
1324
  {
@@ -1075,7 +1332,7 @@ function SelectTrigger({
1075
1332
  ...props,
1076
1333
  children: [
1077
1334
  children,
1078
- /* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4 opacity-50" }) })
1335
+ /* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(CaretDownIcon, { weight: sf.iconWeight, className: "size-4 opacity-50" }) })
1079
1336
  ]
1080
1337
  }
1081
1338
  );
@@ -1087,9 +1344,10 @@ function SelectContent({
1087
1344
  surface,
1088
1345
  radius,
1089
1346
  animated,
1347
+ iconWeight,
1090
1348
  ...props
1091
1349
  }) {
1092
- const sf = useSaasflareProps({ surface, radius, animated });
1350
+ const sf = useSaasflareProps({ surface, radius, animated, iconWeight });
1093
1351
  const motion = useSaasflareMotion(sf.animated, springBouncy);
1094
1352
  return /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsx(
1095
1353
  SelectPrimitive.Content,
@@ -1149,6 +1407,7 @@ function SelectItem({
1149
1407
  children,
1150
1408
  ...props
1151
1409
  }) {
1410
+ const sf = useSaasflareProps();
1152
1411
  return /* @__PURE__ */ jsxs(
1153
1412
  SelectPrimitive.Item,
1154
1413
  {
@@ -1159,7 +1418,7 @@ function SelectItem({
1159
1418
  ),
1160
1419
  ...props,
1161
1420
  children: [
1162
- /* @__PURE__ */ jsx("span", { className: "absolute right-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" }) }) }),
1421
+ /* @__PURE__ */ jsx("span", { className: "absolute right-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { weight: sf.iconWeight, className: "size-4" }) }) }),
1163
1422
  /* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children })
1164
1423
  ]
1165
1424
  }
@@ -1182,13 +1441,14 @@ function SelectScrollUpButton({
1182
1441
  className,
1183
1442
  ...props
1184
1443
  }) {
1444
+ const sf = useSaasflareProps();
1185
1445
  return /* @__PURE__ */ jsx(
1186
1446
  SelectPrimitive.ScrollUpButton,
1187
1447
  {
1188
1448
  "data-slot": "select-scroll-up-button",
1189
1449
  className: cn("flex cursor-default items-center justify-center py-1", className),
1190
1450
  ...props,
1191
- children: /* @__PURE__ */ jsx(ChevronUpIcon, { className: "size-4" })
1451
+ children: /* @__PURE__ */ jsx(CaretUpIcon, { weight: sf.iconWeight, className: "size-4" })
1192
1452
  }
1193
1453
  );
1194
1454
  }
@@ -1196,13 +1456,14 @@ function SelectScrollDownButton({
1196
1456
  className,
1197
1457
  ...props
1198
1458
  }) {
1459
+ const sf = useSaasflareProps();
1199
1460
  return /* @__PURE__ */ jsx(
1200
1461
  SelectPrimitive.ScrollDownButton,
1201
1462
  {
1202
1463
  "data-slot": "select-scroll-down-button",
1203
1464
  className: cn("flex cursor-default items-center justify-center py-1", className),
1204
1465
  ...props,
1205
- children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4" })
1466
+ children: /* @__PURE__ */ jsx(CaretDownIcon, { weight: sf.iconWeight, className: "size-4" })
1206
1467
  }
1207
1468
  );
1208
1469
  }
@@ -1230,9 +1491,10 @@ function DropdownMenuContent({
1230
1491
  surface,
1231
1492
  radius,
1232
1493
  animated,
1494
+ iconWeight,
1233
1495
  ...props
1234
1496
  }) {
1235
- const sf = useSaasflareProps({ surface, radius, animated });
1497
+ const sf = useSaasflareProps({ surface, radius, animated, iconWeight });
1236
1498
  const motion = useSaasflareMotion(sf.animated, springBouncy);
1237
1499
  return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
1238
1500
  DropdownMenuPrimitive.Content,
@@ -1276,6 +1538,7 @@ function DropdownMenuItem({ className, inset, variant = "default", ...props }) {
1276
1538
  );
1277
1539
  }
1278
1540
  function DropdownMenuCheckboxItem({ className, children, checked, ...props }) {
1541
+ const sf = useSaasflareProps();
1279
1542
  return /* @__PURE__ */ jsxs(
1280
1543
  DropdownMenuPrimitive.CheckboxItem,
1281
1544
  {
@@ -1287,13 +1550,14 @@ function DropdownMenuCheckboxItem({ className, children, checked, ...props }) {
1287
1550
  checked,
1288
1551
  ...props,
1289
1552
  children: [
1290
- /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" }) }) }),
1553
+ /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { weight: sf.iconWeight, className: "size-4" }) }) }),
1291
1554
  children
1292
1555
  ]
1293
1556
  }
1294
1557
  );
1295
1558
  }
1296
1559
  function DropdownMenuRadioItem({ className, children, ...props }) {
1560
+ const sf = useSaasflareProps();
1297
1561
  return /* @__PURE__ */ jsxs(
1298
1562
  DropdownMenuPrimitive.RadioItem,
1299
1563
  {
@@ -1304,7 +1568,7 @@ function DropdownMenuRadioItem({ className, children, ...props }) {
1304
1568
  ),
1305
1569
  ...props,
1306
1570
  children: [
1307
- /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CircleIcon, { className: "size-2 fill-current" }) }) }),
1571
+ /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CircleIcon, { weight: sf.iconWeight, className: "size-2 fill-current" }) }) }),
1308
1572
  children
1309
1573
  ]
1310
1574
  }
@@ -1342,6 +1606,7 @@ function DropdownMenuShortcut({ className, ...props }) {
1342
1606
  );
1343
1607
  }
1344
1608
  function DropdownMenuSubTrigger({ className, inset, children, ...props }) {
1609
+ const sf = useSaasflareProps();
1345
1610
  return /* @__PURE__ */ jsxs(
1346
1611
  DropdownMenuPrimitive.SubTrigger,
1347
1612
  {
@@ -1354,7 +1619,7 @@ function DropdownMenuSubTrigger({ className, inset, children, ...props }) {
1354
1619
  ...props,
1355
1620
  children: [
1356
1621
  children,
1357
- /* @__PURE__ */ jsx(ChevronRightIcon, { className: "ml-auto size-4" })
1622
+ /* @__PURE__ */ jsx(CaretRightIcon, { weight: sf.iconWeight, className: "ml-auto size-4" })
1358
1623
  ]
1359
1624
  }
1360
1625
  );
@@ -1414,9 +1679,10 @@ function SheetContent({
1414
1679
  surface,
1415
1680
  radius,
1416
1681
  animated,
1682
+ iconWeight,
1417
1683
  ...props
1418
1684
  }) {
1419
- const sf = useSaasflareProps({ surface, radius, animated });
1685
+ const sf = useSaasflareProps({ surface, radius, animated, iconWeight });
1420
1686
  return /* @__PURE__ */ jsxs(SheetPortal, { children: [
1421
1687
  /* @__PURE__ */ jsx(SheetOverlay, {}),
1422
1688
  /* @__PURE__ */ jsxs(
@@ -1437,8 +1703,8 @@ function SheetContent({
1437
1703
  ),
1438
1704
  children: [
1439
1705
  children,
1440
- showCloseButton && /* @__PURE__ */ jsxs(SheetPrimitive.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 data-[state=open]:bg-secondary", children: [
1441
- /* @__PURE__ */ jsx(XIcon, { className: "size-4" }),
1706
+ showCloseButton && /* @__PURE__ */ jsxs(SheetPrimitive.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 data-[state=open]:bg-secondary data-[state=open]:text-secondary-foreground", children: [
1707
+ /* @__PURE__ */ jsx(XIcon, { weight: sf.iconWeight, className: "size-4" }),
1442
1708
  /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
1443
1709
  ] })
1444
1710
  ]
@@ -1576,9 +1842,10 @@ function Alert({
1576
1842
  surface,
1577
1843
  radius,
1578
1844
  animated,
1845
+ iconWeight,
1579
1846
  ...props
1580
1847
  }) {
1581
- const sf = useSaasflareProps({ surface, radius, animated });
1848
+ const sf = useSaasflareProps({ surface, radius, animated, iconWeight });
1582
1849
  let resolvedIntent = intentProp ?? "neutral";
1583
1850
  if (!intentProp && variant === "destructive") {
1584
1851
  resolvedIntent = "danger";
@@ -1772,6 +2039,7 @@ function ContextMenuSubTrigger({
1772
2039
  children,
1773
2040
  ...props
1774
2041
  }) {
2042
+ const sf = useSaasflareProps();
1775
2043
  return /* @__PURE__ */ jsxs(
1776
2044
  ContextMenuPrimitive.SubTrigger,
1777
2045
  {
@@ -1784,7 +2052,7 @@ function ContextMenuSubTrigger({
1784
2052
  ...props,
1785
2053
  children: [
1786
2054
  children,
1787
- /* @__PURE__ */ jsx(ChevronRightIcon, { className: "ml-auto" })
2055
+ /* @__PURE__ */ jsx(CaretRightIcon, { weight: sf.iconWeight, className: "ml-auto" })
1788
2056
  ]
1789
2057
  }
1790
2058
  );
@@ -1810,9 +2078,10 @@ function ContextMenuContent({
1810
2078
  surface,
1811
2079
  radius,
1812
2080
  animated,
2081
+ iconWeight,
1813
2082
  ...props
1814
2083
  }) {
1815
- const sf = useSaasflareProps({ surface, radius, animated });
2084
+ const sf = useSaasflareProps({ surface, radius, animated, iconWeight });
1816
2085
  return /* @__PURE__ */ jsx(ContextMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(
1817
2086
  ContextMenuPrimitive.Content,
1818
2087
  {
@@ -1854,6 +2123,7 @@ function ContextMenuCheckboxItem({
1854
2123
  checked,
1855
2124
  ...props
1856
2125
  }) {
2126
+ const sf = useSaasflareProps();
1857
2127
  return /* @__PURE__ */ jsxs(
1858
2128
  ContextMenuPrimitive.CheckboxItem,
1859
2129
  {
@@ -1865,7 +2135,7 @@ function ContextMenuCheckboxItem({
1865
2135
  checked,
1866
2136
  ...props,
1867
2137
  children: [
1868
- /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(ContextMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" }) }) }),
2138
+ /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(ContextMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { weight: sf.iconWeight, className: "size-4" }) }) }),
1869
2139
  children
1870
2140
  ]
1871
2141
  }
@@ -1876,6 +2146,7 @@ function ContextMenuRadioItem({
1876
2146
  children,
1877
2147
  ...props
1878
2148
  }) {
2149
+ const sf = useSaasflareProps();
1879
2150
  return /* @__PURE__ */ jsxs(
1880
2151
  ContextMenuPrimitive.RadioItem,
1881
2152
  {
@@ -1886,7 +2157,7 @@ function ContextMenuRadioItem({
1886
2157
  ),
1887
2158
  ...props,
1888
2159
  children: [
1889
- /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(ContextMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CircleIcon, { className: "size-2 fill-current" }) }) }),
2160
+ /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(ContextMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CircleIcon, { weight: sf.iconWeight, className: "size-2 fill-current" }) }) }),
1890
2161
  children
1891
2162
  ]
1892
2163
  }
@@ -1944,9 +2215,10 @@ function Menubar({
1944
2215
  surface,
1945
2216
  radius,
1946
2217
  animated,
2218
+ iconWeight,
1947
2219
  ...props
1948
2220
  }) {
1949
- const sf = useSaasflareProps({ surface, radius, animated });
2221
+ const sf = useSaasflareProps({ surface, radius, animated, iconWeight });
1950
2222
  return /* @__PURE__ */ jsx(
1951
2223
  MenubarPrimitive.Root,
1952
2224
  {
@@ -2006,9 +2278,10 @@ function MenubarContent({
2006
2278
  surface,
2007
2279
  radius,
2008
2280
  animated,
2281
+ iconWeight,
2009
2282
  ...props
2010
2283
  }) {
2011
- const sf = useSaasflareProps({ surface, radius, animated });
2284
+ const sf = useSaasflareProps({ surface, radius, animated, iconWeight });
2012
2285
  return /* @__PURE__ */ jsx(MenubarPortal, { children: /* @__PURE__ */ jsx(
2013
2286
  MenubarPrimitive.Content,
2014
2287
  {
@@ -2053,6 +2326,7 @@ function MenubarCheckboxItem({
2053
2326
  checked,
2054
2327
  ...props
2055
2328
  }) {
2329
+ const sf = useSaasflareProps();
2056
2330
  return /* @__PURE__ */ jsxs(
2057
2331
  MenubarPrimitive.CheckboxItem,
2058
2332
  {
@@ -2064,7 +2338,7 @@ function MenubarCheckboxItem({
2064
2338
  checked,
2065
2339
  ...props,
2066
2340
  children: [
2067
- /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(MenubarPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" }) }) }),
2341
+ /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(MenubarPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { weight: sf.iconWeight, className: "size-4" }) }) }),
2068
2342
  children
2069
2343
  ]
2070
2344
  }
@@ -2075,6 +2349,7 @@ function MenubarRadioItem({
2075
2349
  children,
2076
2350
  ...props
2077
2351
  }) {
2352
+ const sf = useSaasflareProps();
2078
2353
  return /* @__PURE__ */ jsxs(
2079
2354
  MenubarPrimitive.RadioItem,
2080
2355
  {
@@ -2085,7 +2360,7 @@ function MenubarRadioItem({
2085
2360
  ),
2086
2361
  ...props,
2087
2362
  children: [
2088
- /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(MenubarPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CircleIcon, { className: "size-2 fill-current" }) }) }),
2363
+ /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute left-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(MenubarPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CircleIcon, { weight: sf.iconWeight, className: "size-2 fill-current" }) }) }),
2089
2364
  children
2090
2365
  ]
2091
2366
  }
@@ -2149,6 +2424,7 @@ function MenubarSubTrigger({
2149
2424
  children,
2150
2425
  ...props
2151
2426
  }) {
2427
+ const sf = useSaasflareProps();
2152
2428
  return /* @__PURE__ */ jsxs(
2153
2429
  MenubarPrimitive.SubTrigger,
2154
2430
  {
@@ -2161,7 +2437,7 @@ function MenubarSubTrigger({
2161
2437
  ...props,
2162
2438
  children: [
2163
2439
  children,
2164
- /* @__PURE__ */ jsx(ChevronRightIcon, { className: "ml-auto h-4 w-4" })
2440
+ /* @__PURE__ */ jsx(CaretRightIcon, { weight: sf.iconWeight, className: "ml-auto h-4 w-4" })
2165
2441
  ]
2166
2442
  }
2167
2443
  );
@@ -2189,9 +2465,10 @@ function NavigationMenu({
2189
2465
  surface,
2190
2466
  radius,
2191
2467
  animated,
2468
+ iconWeight,
2192
2469
  ...props
2193
2470
  }) {
2194
- const sf = useSaasflareProps({ surface, radius, animated });
2471
+ const sf = useSaasflareProps({ surface, radius, animated, iconWeight });
2195
2472
  return /* @__PURE__ */ jsxs(
2196
2473
  NavigationMenuPrimitive.Root,
2197
2474
  {
@@ -2249,6 +2526,7 @@ function NavigationMenuTrigger({
2249
2526
  children,
2250
2527
  ...props
2251
2528
  }) {
2529
+ const sf = useSaasflareProps();
2252
2530
  return /* @__PURE__ */ jsxs(
2253
2531
  NavigationMenuPrimitive.Trigger,
2254
2532
  {
@@ -2259,8 +2537,9 @@ function NavigationMenuTrigger({
2259
2537
  children,
2260
2538
  " ",
2261
2539
  /* @__PURE__ */ jsx(
2262
- ChevronDownIcon,
2540
+ CaretDownIcon,
2263
2541
  {
2542
+ weight: sf.iconWeight,
2264
2543
  className: "relative top-[1px] ml-1 size-3 transition duration-300 group-data-[state=open]:rotate-180",
2265
2544
  "aria-hidden": "true"
2266
2545
  }
@@ -2480,9 +2759,10 @@ function RadioGroup4({
2480
2759
  surface,
2481
2760
  radius,
2482
2761
  animated,
2762
+ iconWeight,
2483
2763
  ...props
2484
2764
  }) {
2485
- const sf = useSaasflareProps({ surface, radius, animated });
2765
+ const sf = useSaasflareProps({ surface, radius, animated, iconWeight });
2486
2766
  return /* @__PURE__ */ jsx(
2487
2767
  RadioGroupPrimitive.Root,
2488
2768
  {
@@ -2499,6 +2779,7 @@ function RadioGroupItem({
2499
2779
  className,
2500
2780
  ...props
2501
2781
  }) {
2782
+ const sf = useSaasflareProps();
2502
2783
  return /* @__PURE__ */ jsx(
2503
2784
  RadioGroupPrimitive.Item,
2504
2785
  {
@@ -2513,7 +2794,7 @@ function RadioGroupItem({
2513
2794
  {
2514
2795
  "data-slot": "radio-group-indicator",
2515
2796
  className: "relative flex items-center justify-center",
2516
- children: /* @__PURE__ */ jsx(CircleIcon, { className: "absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2 fill-primary animate-in zoom-in-50 duration-150" })
2797
+ children: /* @__PURE__ */ jsx(CircleIcon, { weight: sf.iconWeight, className: "absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2 fill-primary animate-in zoom-in-50 duration-150" })
2517
2798
  }
2518
2799
  )
2519
2800
  }
@@ -2556,7 +2837,7 @@ function CollapsibleContent2({
2556
2837
  function Spinner({ className, surface, radius, animated, ...props }) {
2557
2838
  const sf = useSaasflareProps({ animated });
2558
2839
  return /* @__PURE__ */ jsx(
2559
- Loader2Icon,
2840
+ CircleNotchIcon,
2560
2841
  {
2561
2842
  ...props,
2562
2843
  role: "status",
@@ -2640,9 +2921,9 @@ var getAsset = (type) => {
2640
2921
  case "success":
2641
2922
  return SuccessIcon;
2642
2923
  case "info":
2643
- return InfoIcon;
2924
+ return InfoIcon2;
2644
2925
  case "warning":
2645
- return WarningIcon;
2926
+ return WarningIcon2;
2646
2927
  case "error":
2647
2928
  return ErrorIcon;
2648
2929
  default:
@@ -2675,7 +2956,7 @@ var SuccessIcon = /* @__PURE__ */ React5__default.createElement("svg", {
2675
2956
  d: "M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z",
2676
2957
  clipRule: "evenodd"
2677
2958
  }));
2678
- var WarningIcon = /* @__PURE__ */ React5__default.createElement("svg", {
2959
+ var WarningIcon2 = /* @__PURE__ */ React5__default.createElement("svg", {
2679
2960
  xmlns: "http://www.w3.org/2000/svg",
2680
2961
  viewBox: "0 0 24 24",
2681
2962
  fill: "currentColor",
@@ -2686,7 +2967,7 @@ var WarningIcon = /* @__PURE__ */ React5__default.createElement("svg", {
2686
2967
  d: "M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z",
2687
2968
  clipRule: "evenodd"
2688
2969
  }));
2689
- var InfoIcon = /* @__PURE__ */ React5__default.createElement("svg", {
2970
+ var InfoIcon2 = /* @__PURE__ */ React5__default.createElement("svg", {
2690
2971
  xmlns: "http://www.w3.org/2000/svg",
2691
2972
  viewBox: "0 0 20 20",
2692
2973
  fill: "currentColor",
@@ -2969,10 +3250,10 @@ var Observer = class {
2969
3250
  });
2970
3251
  }
2971
3252
  };
2972
- this.custom = (jsx65, data) => {
3253
+ this.custom = (jsx84, data) => {
2973
3254
  const id = (data == null ? void 0 : data.id) || toastsCounter++;
2974
3255
  this.create({
2975
- jsx: jsx65(id),
3256
+ jsx: jsx84(id),
2976
3257
  id,
2977
3258
  ...data
2978
3259
  });
@@ -3058,7 +3339,7 @@ var Toast = (props) => {
3058
3339
  const dragStartTime = React5__default.useRef(null);
3059
3340
  const toastRef = React5__default.useRef(null);
3060
3341
  const isFront = index === 0;
3061
- const isVisible = index + 1 <= visibleToasts;
3342
+ const isVisible2 = index + 1 <= visibleToasts;
3062
3343
  const toastType = toast2.type;
3063
3344
  const dismissible = toast2.dismissible !== false;
3064
3345
  const toastClassname = toast2.className || "";
@@ -3245,7 +3526,7 @@ var Toast = (props) => {
3245
3526
  "data-promise": Boolean(toast2.promise),
3246
3527
  "data-swiped": isSwiped,
3247
3528
  "data-removed": removed,
3248
- "data-visible": isVisible,
3529
+ "data-visible": isVisible2,
3249
3530
  "data-y-position": y,
3250
3531
  "data-x-position": x,
3251
3532
  "data-index": index,
@@ -3707,9 +3988,9 @@ var Toaster = /* @__PURE__ */ React5__default.forwardRef(function Toaster2(props
3707
3988
  }))
3708
3989
  );
3709
3990
  });
3710
- var Toaster3 = ({ surface, radius, animated, ...props }) => {
3991
+ var Toaster3 = ({ surface, radius, animated, iconWeight, ...props }) => {
3711
3992
  const { theme = "system" } = useTheme();
3712
- const sf = useSaasflareProps({ surface, radius, animated });
3993
+ const sf = useSaasflareProps({ surface, radius, animated, iconWeight });
3713
3994
  return /* @__PURE__ */ jsx(
3714
3995
  Toaster,
3715
3996
  {
@@ -3720,11 +4001,11 @@ var Toaster3 = ({ surface, radius, animated, ...props }) => {
3720
4001
  theme,
3721
4002
  className: "toaster group",
3722
4003
  icons: {
3723
- success: /* @__PURE__ */ jsx(CircleCheckIcon, { className: "size-4" }),
3724
- info: /* @__PURE__ */ jsx(InfoIcon$1, { className: "size-4" }),
3725
- warning: /* @__PURE__ */ jsx(TriangleAlertIcon, { className: "size-4" }),
3726
- error: /* @__PURE__ */ jsx(OctagonXIcon, { className: "size-4" }),
3727
- loading: /* @__PURE__ */ jsx(Loader2Icon, { className: "size-4 animate-spin" })
4004
+ success: /* @__PURE__ */ jsx(CheckCircleIcon, { weight: sf.iconWeight, className: "size-4" }),
4005
+ info: /* @__PURE__ */ jsx(InfoIcon, { weight: sf.iconWeight, className: "size-4" }),
4006
+ warning: /* @__PURE__ */ jsx(WarningIcon, { weight: sf.iconWeight, className: "size-4" }),
4007
+ error: /* @__PURE__ */ jsx(XCircleIcon, { weight: sf.iconWeight, className: "size-4" }),
4008
+ loading: /* @__PURE__ */ jsx(CircleNotchIcon, { className: "size-4 animate-spin" })
3728
4009
  },
3729
4010
  style: {
3730
4011
  "--normal-bg": "var(--popover)",
@@ -3741,8 +4022,8 @@ function AspectRatio({
3741
4022
  }) {
3742
4023
  return /* @__PURE__ */ jsx(AspectRatioPrimitive.Root, { "data-slot": "aspect-ratio", ...props });
3743
4024
  }
3744
- function Breadcrumb({ surface, radius, animated, ...props }) {
3745
- const sf = useSaasflareProps({ surface, radius, animated });
4025
+ function Breadcrumb({ surface, radius, animated, iconWeight, ...props }) {
4026
+ const sf = useSaasflareProps({ surface, radius, animated, iconWeight });
3746
4027
  return /* @__PURE__ */ jsx(
3747
4028
  "nav",
3748
4029
  {
@@ -3811,6 +4092,7 @@ function BreadcrumbSeparator({
3811
4092
  className,
3812
4093
  ...props
3813
4094
  }) {
4095
+ const sf = useSaasflareProps();
3814
4096
  return /* @__PURE__ */ jsx(
3815
4097
  "li",
3816
4098
  {
@@ -3819,7 +4101,7 @@ function BreadcrumbSeparator({
3819
4101
  "aria-hidden": "true",
3820
4102
  className: cn("[&>svg]:size-3.5", className),
3821
4103
  ...props,
3822
- children: children ?? /* @__PURE__ */ jsx(ChevronRight, {})
4104
+ children: children ?? /* @__PURE__ */ jsx(CaretRightIcon, { weight: sf.iconWeight })
3823
4105
  }
3824
4106
  );
3825
4107
  }
@@ -3827,6 +4109,7 @@ function BreadcrumbEllipsis({
3827
4109
  className,
3828
4110
  ...props
3829
4111
  }) {
4112
+ const sf = useSaasflareProps();
3830
4113
  return /* @__PURE__ */ jsxs(
3831
4114
  "span",
3832
4115
  {
@@ -3836,7 +4119,7 @@ function BreadcrumbEllipsis({
3836
4119
  className: cn("flex size-9 items-center justify-center", className),
3837
4120
  ...props,
3838
4121
  children: [
3839
- /* @__PURE__ */ jsx(MoreHorizontal, { className: "size-4" }),
4122
+ /* @__PURE__ */ jsx(DotsThreeIcon, { weight: sf.iconWeight, className: "size-4" }),
3840
4123
  /* @__PURE__ */ jsx("span", { className: "sr-only", children: "More" })
3841
4124
  ]
3842
4125
  }
@@ -3962,13 +4245,14 @@ function ComboboxInput({
3962
4245
  className,
3963
4246
  ...props
3964
4247
  }) {
4248
+ const sf = useSaasflareProps();
3965
4249
  return /* @__PURE__ */ jsxs(
3966
4250
  "div",
3967
4251
  {
3968
4252
  "data-slot": "combobox-input-wrapper",
3969
4253
  className: "flex h-9 items-center gap-2 border-b px-3",
3970
4254
  children: [
3971
- /* @__PURE__ */ jsx(SearchIcon, { className: "size-4 shrink-0 opacity-50" }),
4255
+ /* @__PURE__ */ jsx(MagnifyingGlassIcon, { weight: sf.iconWeight, className: "size-4 shrink-0 opacity-50" }),
3972
4256
  /* @__PURE__ */ jsx(
3973
4257
  Command.Input,
3974
4258
  {
@@ -4006,6 +4290,7 @@ function ComboboxItem({
4006
4290
  selected,
4007
4291
  ...props
4008
4292
  }) {
4293
+ const sf = useSaasflareProps();
4009
4294
  return /* @__PURE__ */ jsxs(
4010
4295
  Command.Item,
4011
4296
  {
@@ -4020,6 +4305,7 @@ function ComboboxItem({
4020
4305
  selected ? /* @__PURE__ */ jsx(
4021
4306
  CheckIcon,
4022
4307
  {
4308
+ weight: sf.iconWeight,
4023
4309
  "data-slot": "combobox-item-indicator",
4024
4310
  className: "absolute right-2 size-4"
4025
4311
  }
@@ -5017,9 +5303,10 @@ function NativeSelect({
5017
5303
  surface,
5018
5304
  radius,
5019
5305
  animated,
5306
+ iconWeight,
5020
5307
  ...props
5021
5308
  }) {
5022
- const sf = useSaasflareProps({ surface, radius, animated });
5309
+ const sf = useSaasflareProps({ surface, radius, animated, iconWeight });
5023
5310
  return /* @__PURE__ */ jsxs(
5024
5311
  "div",
5025
5312
  {
@@ -5044,8 +5331,9 @@ function NativeSelect({
5044
5331
  }
5045
5332
  ),
5046
5333
  /* @__PURE__ */ jsx(
5047
- ChevronDownIcon,
5334
+ CaretDownIcon,
5048
5335
  {
5336
+ weight: sf.iconWeight,
5049
5337
  className: "pointer-events-none absolute top-1/2 right-3.5 size-4 -translate-y-1/2 text-muted-foreground opacity-50 select-none",
5050
5338
  "aria-hidden": "true",
5051
5339
  "data-slot": "native-select-icon"
@@ -5126,6 +5414,7 @@ function PaginationPrevious({
5126
5414
  className,
5127
5415
  ...props
5128
5416
  }) {
5417
+ const sf = useSaasflareProps();
5129
5418
  return /* @__PURE__ */ jsxs(
5130
5419
  PaginationLink,
5131
5420
  {
@@ -5134,7 +5423,7 @@ function PaginationPrevious({
5134
5423
  className: cn("gap-1 px-2.5 sm:pl-2.5", className),
5135
5424
  ...props,
5136
5425
  children: [
5137
- /* @__PURE__ */ jsx(ChevronLeftIcon, {}),
5426
+ /* @__PURE__ */ jsx(CaretLeftIcon, { weight: sf.iconWeight }),
5138
5427
  /* @__PURE__ */ jsx("span", { className: "hidden sm:block", children: "Previous" })
5139
5428
  ]
5140
5429
  }
@@ -5144,6 +5433,7 @@ function PaginationNext({
5144
5433
  className,
5145
5434
  ...props
5146
5435
  }) {
5436
+ const sf = useSaasflareProps();
5147
5437
  return /* @__PURE__ */ jsxs(
5148
5438
  PaginationLink,
5149
5439
  {
@@ -5153,7 +5443,7 @@ function PaginationNext({
5153
5443
  ...props,
5154
5444
  children: [
5155
5445
  /* @__PURE__ */ jsx("span", { className: "hidden sm:block", children: "Next" }),
5156
- /* @__PURE__ */ jsx(ChevronRightIcon, {})
5446
+ /* @__PURE__ */ jsx(CaretRightIcon, { weight: sf.iconWeight })
5157
5447
  ]
5158
5448
  }
5159
5449
  );
@@ -5162,6 +5452,7 @@ function PaginationEllipsis({
5162
5452
  className,
5163
5453
  ...props
5164
5454
  }) {
5455
+ const sf = useSaasflareProps();
5165
5456
  return /* @__PURE__ */ jsxs(
5166
5457
  "span",
5167
5458
  {
@@ -5170,7 +5461,7 @@ function PaginationEllipsis({
5170
5461
  className: cn("flex size-9 items-center justify-center", className),
5171
5462
  ...props,
5172
5463
  children: [
5173
- /* @__PURE__ */ jsx(MoreHorizontalIcon, { className: "size-4" }),
5464
+ /* @__PURE__ */ jsx(DotsThreeIcon, { weight: sf.iconWeight, className: "size-4" }),
5174
5465
  /* @__PURE__ */ jsx("span", { className: "sr-only", children: "More pages" })
5175
5466
  ]
5176
5467
  }
@@ -5510,6 +5801,7 @@ function SidebarTrigger({
5510
5801
  ...props
5511
5802
  }) {
5512
5803
  const { toggleSidebar } = useSidebar();
5804
+ const sf = useSaasflareProps();
5513
5805
  return /* @__PURE__ */ jsxs(
5514
5806
  Button,
5515
5807
  {
@@ -5524,7 +5816,7 @@ function SidebarTrigger({
5524
5816
  },
5525
5817
  ...props,
5526
5818
  children: [
5527
- /* @__PURE__ */ jsx(PanelLeftIcon, {}),
5819
+ /* @__PURE__ */ jsx(SidebarSimpleIcon, { weight: sf.iconWeight }),
5528
5820
  /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Toggle Sidebar" })
5529
5821
  ]
5530
5822
  }
@@ -6162,182 +6454,1784 @@ function MetricCard({
6162
6454
  }
6163
6455
  );
6164
6456
  }
6165
- function EmptyState({
6166
- icon,
6167
- title,
6168
- description,
6169
- action,
6457
+ function BarList({
6458
+ data,
6459
+ valueFormatter = (n) => n.toLocaleString(),
6460
+ sortDescending = true,
6461
+ limit,
6170
6462
  className,
6171
6463
  surface,
6172
6464
  radius,
6173
- animated,
6174
- ...props
6465
+ animated
6175
6466
  }) {
6176
6467
  const sf = useSaasflareProps({ surface, radius, animated });
6177
- return /* @__PURE__ */ jsxs(
6468
+ const motion = useSaasflareMotion(sf.animated, springGentle);
6469
+ const sorted = sortDescending ? [...data].sort((a, b) => b.value - a.value) : data;
6470
+ const visible = typeof limit === "number" ? sorted.slice(0, limit) : sorted;
6471
+ const peak = visible.reduce((max, row) => Math.max(max, row.value), 0) || 1;
6472
+ return /* @__PURE__ */ jsx(
6178
6473
  "div",
6179
6474
  {
6180
- ...props,
6181
- "data-slot": "empty-state",
6475
+ "data-slot": "bar-list",
6182
6476
  "data-surface": sf.surface,
6183
6477
  "data-radius": sf.radius,
6184
6478
  "data-animated": String(sf.animated),
6185
- className: cn(
6186
- "flex flex-col items-center justify-center gap-4 py-12 text-center",
6187
- className
6188
- ),
6189
- children: [
6190
- icon && /* @__PURE__ */ jsx("div", { className: "text-muted-foreground [&_svg]:size-12", children: icon }),
6191
- /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
6192
- /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold", children: title }),
6193
- description && /* @__PURE__ */ jsx("p", { className: "max-w-sm text-sm text-muted-foreground", children: description })
6194
- ] }),
6195
- action && /* @__PURE__ */ jsx("div", { className: "mt-2", children: action })
6196
- ]
6197
- }
6198
- );
6199
- }
6200
- function SearchField({
6479
+ className: cn("flex flex-col gap-1.5", className),
6480
+ children: visible.map((row, i) => {
6481
+ const pct = row.value / peak * 100;
6482
+ const labelClasses = cn(
6483
+ "relative z-10 flex flex-1 items-center gap-2 truncate px-2 text-sm",
6484
+ row.href && "hover:underline"
6485
+ );
6486
+ const labelInner = /* @__PURE__ */ jsxs(Fragment, { children: [
6487
+ row.icon !== void 0 && /* @__PURE__ */ jsx("span", { className: "flex shrink-0 items-center [&_svg]:size-4", children: row.icon }),
6488
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: row.name })
6489
+ ] });
6490
+ return /* @__PURE__ */ jsxs(
6491
+ "div",
6492
+ {
6493
+ "data-slot": "bar-list-item",
6494
+ className: "relative flex h-8 items-center",
6495
+ children: [
6496
+ /* @__PURE__ */ jsx(
6497
+ m.div,
6498
+ {
6499
+ "data-slot": "bar-list-bar",
6500
+ className: "absolute inset-y-0 left-0 rounded-md bg-primary/15",
6501
+ style: row.color ? { backgroundColor: row.color, opacity: 0.18 } : void 0,
6502
+ initial: motion.disabled ? false : { width: 0 },
6503
+ animate: { width: `${pct}%` },
6504
+ transition: motion.transition
6505
+ }
6506
+ ),
6507
+ row.href ? /* @__PURE__ */ jsx(
6508
+ "a",
6509
+ {
6510
+ href: row.href,
6511
+ "data-slot": "bar-list-label",
6512
+ className: labelClasses,
6513
+ children: labelInner
6514
+ }
6515
+ ) : /* @__PURE__ */ jsx("span", { "data-slot": "bar-list-label", className: labelClasses, children: labelInner }),
6516
+ /* @__PURE__ */ jsx(
6517
+ "span",
6518
+ {
6519
+ "data-slot": "bar-list-value",
6520
+ className: "relative z-10 shrink-0 px-2 text-sm font-medium tabular-nums",
6521
+ children: valueFormatter(row.value)
6522
+ }
6523
+ )
6524
+ ]
6525
+ },
6526
+ `${row.name}-${i}`
6527
+ );
6528
+ })
6529
+ }
6530
+ );
6531
+ }
6532
+ function buildPath(data, width, height, sw) {
6533
+ const min = Math.min(...data);
6534
+ const max = Math.max(...data);
6535
+ const span = max - min || 1;
6536
+ const innerW = width - sw;
6537
+ const innerH = height - sw;
6538
+ const offset = sw / 2;
6539
+ return data.map((v, i) => {
6540
+ const x = offset + i / (data.length - 1) * innerW;
6541
+ const y = offset + innerH - (v - min) / span * innerH;
6542
+ return `${i === 0 ? "M" : "L"} ${x.toFixed(2)} ${y.toFixed(2)}`;
6543
+ }).join(" ");
6544
+ }
6545
+ function SparkChart({
6546
+ data,
6547
+ variant = "area",
6548
+ color,
6549
+ width = 64,
6550
+ height = 24,
6551
+ strokeWidth = 1.5,
6201
6552
  className,
6202
- loading = false,
6203
- onClear,
6204
- value,
6205
6553
  surface,
6206
6554
  radius,
6207
6555
  animated,
6208
- ...props
6556
+ "aria-label": ariaLabel
6209
6557
  }) {
6210
6558
  const sf = useSaasflareProps({ surface, radius, animated });
6211
- const hasValue = typeof value === "string" ? value.length > 0 : false;
6212
- return /* @__PURE__ */ jsxs(
6213
- "div",
6214
- {
6215
- "data-slot": "search-field",
6559
+ if (data.length < 2) return null;
6560
+ const stroke = color ?? "var(--primary)";
6561
+ const linePath = buildPath(data, width, height, strokeWidth);
6562
+ const areaPath = `${linePath} L ${width - strokeWidth / 2} ${height - strokeWidth / 2} L ${strokeWidth / 2} ${height - strokeWidth / 2} Z`;
6563
+ const min = Math.min(...data);
6564
+ const max = Math.max(...data);
6565
+ const span = max - min || 1;
6566
+ const innerH = height - strokeWidth;
6567
+ const offset = strokeWidth / 2;
6568
+ const barW = (width - strokeWidth * (data.length + 1)) / data.length;
6569
+ return /* @__PURE__ */ jsx(
6570
+ "svg",
6571
+ {
6572
+ "data-slot": "spark-chart",
6573
+ "data-variant": variant,
6216
6574
  "data-surface": sf.surface,
6217
- "data-radius": sf.radius,
6218
6575
  "data-animated": String(sf.animated),
6219
- className: cn("relative", className),
6220
- children: [
6221
- /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground", children: loading ? /* @__PURE__ */ jsx(Loader2Icon, { className: "size-4 animate-spin", "aria-hidden": "true" }) : /* @__PURE__ */ jsx(SearchIcon, { className: "size-4", "aria-hidden": "true" }) }),
6222
- /* @__PURE__ */ jsx(
6223
- "input",
6576
+ width,
6577
+ height,
6578
+ viewBox: `0 0 ${width} ${height}`,
6579
+ role: "img",
6580
+ "aria-label": ariaLabel ?? `Sparkline ${variant}`,
6581
+ className: cn("inline-block align-middle", className),
6582
+ children: variant === "bar" ? data.map((v, i) => {
6583
+ const h = Math.max((v - min) / span * innerH, 1);
6584
+ const x = offset + i * (barW + strokeWidth);
6585
+ const y = offset + innerH - h;
6586
+ return /* @__PURE__ */ jsx(
6587
+ "rect",
6224
6588
  {
6225
- type: "search",
6226
- "data-slot": "search-field-input",
6227
- className: "h-9 w-full rounded-md border border-input bg-background pl-9 pr-9 text-sm outline-none transition-colors placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50",
6228
- value,
6229
- ...props
6589
+ "data-slot": "spark-chart-bar",
6590
+ x,
6591
+ y,
6592
+ width: barW,
6593
+ height: h,
6594
+ fill: stroke,
6595
+ rx: 1
6596
+ },
6597
+ i
6598
+ );
6599
+ }) : /* @__PURE__ */ jsxs(Fragment, { children: [
6600
+ variant === "area" && /* @__PURE__ */ jsx(
6601
+ "path",
6602
+ {
6603
+ "data-slot": "spark-chart-area",
6604
+ d: areaPath,
6605
+ fill: stroke,
6606
+ fillOpacity: 0.18
6230
6607
  }
6231
6608
  ),
6232
- hasValue && onClear && /* @__PURE__ */ jsx(
6233
- "button",
6609
+ /* @__PURE__ */ jsx(
6610
+ "path",
6234
6611
  {
6235
- type: "button",
6236
- "data-slot": "search-field-clear",
6237
- onClick: onClear,
6238
- className: "absolute right-2 top-1/2 -translate-y-1/2 rounded-sm p-0.5 text-muted-foreground transition-colors hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring",
6239
- "aria-label": "Clear search",
6240
- children: /* @__PURE__ */ jsx(XIcon, { className: "size-3.5" })
6612
+ "data-slot": "spark-chart-line",
6613
+ d: linePath,
6614
+ fill: "none",
6615
+ stroke,
6616
+ strokeWidth,
6617
+ strokeLinecap: "round",
6618
+ strokeLinejoin: "round"
6241
6619
  }
6242
6620
  )
6243
- ]
6621
+ ] })
6244
6622
  }
6245
6623
  );
6246
6624
  }
6247
- function SettingsSection({
6248
- label,
6249
- description,
6625
+ var NAMED_COLORS = {
6626
+ emerald: "oklch(0.68 0.17 155)",
6627
+ teal: "oklch(0.70 0.15 185)",
6628
+ blue: "oklch(0.65 0.18 230)",
6629
+ amber: "oklch(0.72 0.17 50)",
6630
+ red: "oklch(0.62 0.21 25)",
6631
+ rose: "oklch(0.65 0.20 10)",
6632
+ gray: "oklch(0.70 0 0)",
6633
+ neutral: "oklch(0.70 0 0)"
6634
+ };
6635
+ function Tracker({
6636
+ data,
6637
+ blockHeight = 32,
6638
+ gap = 2,
6250
6639
  className,
6251
- children,
6252
6640
  surface,
6253
6641
  radius,
6254
- animated,
6255
- ...props
6642
+ animated
6256
6643
  }) {
6257
6644
  const sf = useSaasflareProps({ surface, radius, animated });
6258
- return /* @__PURE__ */ jsxs(
6645
+ return /* @__PURE__ */ jsx(
6259
6646
  "div",
6260
6647
  {
6261
- ...props,
6262
- "data-slot": "settings-section",
6648
+ "data-slot": "tracker",
6263
6649
  "data-surface": sf.surface,
6264
6650
  "data-radius": sf.radius,
6265
6651
  "data-animated": String(sf.animated),
6266
- className: cn(
6267
- "flex flex-col gap-3 py-4 sm:flex-row sm:items-center sm:justify-between sm:gap-6",
6268
- className
6269
- ),
6270
- children: [
6271
- /* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
6272
- /* @__PURE__ */ jsx("div", { className: "text-sm font-medium", children: label }),
6273
- description && /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: description })
6274
- ] }),
6275
- /* @__PURE__ */ jsx("div", { className: "shrink-0", children })
6276
- ]
6652
+ className: cn("flex w-full items-stretch", className),
6653
+ style: { gap, height: blockHeight },
6654
+ role: "group",
6655
+ "aria-label": "Status tracker",
6656
+ children: data.map((block, i) => {
6657
+ const color = block.color ? NAMED_COLORS[block.color] ?? block.color : NAMED_COLORS.gray;
6658
+ return /* @__PURE__ */ jsx(
6659
+ "div",
6660
+ {
6661
+ "data-slot": "tracker-block",
6662
+ title: typeof block.tooltip === "string" ? block.tooltip : void 0,
6663
+ className: cn(
6664
+ "flex-1 rounded-sm transition-[transform,opacity]",
6665
+ "hover:scale-y-110 hover:opacity-90",
6666
+ "motion-reduce:hover:transform-none"
6667
+ ),
6668
+ style: { backgroundColor: color }
6669
+ },
6670
+ block.key ?? i
6671
+ );
6672
+ })
6277
6673
  }
6278
6674
  );
6279
6675
  }
6280
- function PricingCard({
6281
- name,
6282
- price,
6283
- period,
6284
- description,
6285
- features,
6286
- cta,
6287
- featured = false,
6676
+ function matchesAccept(file, accept) {
6677
+ if (!accept) return true;
6678
+ const parts = accept.split(",").map((s) => s.trim().toLowerCase());
6679
+ const name = file.name.toLowerCase();
6680
+ const type = file.type.toLowerCase();
6681
+ return parts.some((p) => {
6682
+ if (p.startsWith(".")) return name.endsWith(p);
6683
+ if (p.endsWith("/*")) return type.startsWith(p.slice(0, -1));
6684
+ return type === p;
6685
+ });
6686
+ }
6687
+ function partition(files, accept, maxSize) {
6688
+ const accepted = [];
6689
+ const rejected = [];
6690
+ for (const file of files) {
6691
+ if (!matchesAccept(file, accept)) {
6692
+ rejected.push({ file, reason: "type-mismatch" });
6693
+ continue;
6694
+ }
6695
+ if (typeof maxSize === "number" && file.size > maxSize) {
6696
+ rejected.push({ file, reason: "too-large" });
6697
+ continue;
6698
+ }
6699
+ accepted.push(file);
6700
+ }
6701
+ return { accepted, rejected };
6702
+ }
6703
+ function Dropzone({
6704
+ onDrop,
6705
+ accept,
6706
+ maxSize,
6707
+ multiple = true,
6708
+ disabled = false,
6709
+ children,
6288
6710
  className,
6289
6711
  surface,
6290
6712
  radius,
6291
- animated,
6292
- ...props
6713
+ animated
6293
6714
  }) {
6294
6715
  const sf = useSaasflareProps({ surface, radius, animated });
6295
- return /* @__PURE__ */ jsxs(
6716
+ const [isDragActive, setIsDragActive] = useState(false);
6717
+ const handle = useCallback(
6718
+ (files) => {
6719
+ const { accepted, rejected } = partition(files, accept, maxSize);
6720
+ onDrop?.(accepted, rejected);
6721
+ },
6722
+ [accept, maxSize, onDrop]
6723
+ );
6724
+ const { open } = useFileDialog({
6725
+ accept,
6726
+ multiple,
6727
+ onChange: handle
6728
+ });
6729
+ const onDragOver = (e) => {
6730
+ e.preventDefault();
6731
+ if (disabled) return;
6732
+ setIsDragActive(true);
6733
+ };
6734
+ const onDragLeave = (e) => {
6735
+ e.preventDefault();
6736
+ setIsDragActive(false);
6737
+ };
6738
+ const onDropEvent = (e) => {
6739
+ e.preventDefault();
6740
+ setIsDragActive(false);
6741
+ if (disabled) return;
6742
+ const files = Array.from(e.dataTransfer.files);
6743
+ handle(multiple ? files : files.slice(0, 1));
6744
+ };
6745
+ return /* @__PURE__ */ jsx(
6296
6746
  "div",
6297
6747
  {
6298
- ...props,
6299
- "data-slot": "pricing-card",
6748
+ "data-slot": "dropzone",
6300
6749
  "data-surface": sf.surface,
6301
6750
  "data-radius": sf.radius,
6302
6751
  "data-animated": String(sf.animated),
6752
+ "data-active": String(isDragActive),
6753
+ "data-disabled": String(disabled),
6754
+ role: "button",
6755
+ tabIndex: disabled ? -1 : 0,
6756
+ "aria-disabled": disabled || void 0,
6757
+ onClick: () => !disabled && open(),
6758
+ onKeyDown: (e) => {
6759
+ if (disabled) return;
6760
+ if (e.key === "Enter" || e.key === " ") {
6761
+ e.preventDefault();
6762
+ open();
6763
+ }
6764
+ },
6765
+ onDragOver,
6766
+ onDragEnter: onDragOver,
6767
+ onDragLeave,
6768
+ onDrop: onDropEvent,
6303
6769
  className: cn(
6304
- "relative flex flex-col rounded-xl border bg-card p-6 text-card-foreground shadow-sm",
6305
- featured && "border-primary shadow-md ring-1 ring-primary/20",
6770
+ "flex min-h-32 cursor-pointer items-center justify-center rounded-xl border-2 border-dashed",
6771
+ "border-border bg-background/40 p-6 text-center text-sm text-muted-foreground",
6772
+ "transition-[border-color,background-color] duration-200",
6773
+ "hover:border-primary/40 hover:bg-primary/5",
6774
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
6775
+ "data-[active=true]:border-primary/60 data-[active=true]:bg-primary/10",
6776
+ "data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50",
6306
6777
  className
6307
6778
  ),
6308
- children: [
6309
- featured && /* @__PURE__ */ jsx("div", { className: "absolute -top-3 left-1/2 -translate-x-1/2 rounded-full bg-primary px-3 py-0.5 text-xs font-medium text-primary-foreground", children: "Recommended" }),
6310
- /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
6311
- /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold", children: name }),
6312
- description && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: description })
6313
- ] }),
6314
- /* @__PURE__ */ jsxs("div", { className: "mt-4 flex items-baseline gap-1", children: [
6315
- /* @__PURE__ */ jsx("span", { className: "text-3xl font-bold tracking-tight", children: price }),
6316
- period && /* @__PURE__ */ jsxs("span", { className: "text-sm text-muted-foreground", children: [
6317
- "/",
6318
- period
6319
- ] })
6779
+ children: typeof children === "function" ? children({ isDragActive }) : children !== void 0 ? children : /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-1", children: [
6780
+ /* @__PURE__ */ jsx("p", { className: "font-medium text-foreground", children: isDragActive ? "Drop files here" : "Drag files here or click to browse" }),
6781
+ accept && /* @__PURE__ */ jsxs("p", { className: "text-xs", children: [
6782
+ "Accepts: ",
6783
+ accept
6320
6784
  ] }),
6321
- /* @__PURE__ */ jsx("ul", { className: "mt-6 space-y-2.5", role: "list", children: features.map((feature) => /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-2 text-sm", children: [
6322
- /* @__PURE__ */ jsx(CheckIcon, { className: "mt-0.5 size-4 shrink-0 text-success", "aria-hidden": "true" }),
6323
- /* @__PURE__ */ jsx("span", { children: feature })
6324
- ] }, feature)) }),
6325
- cta && /* @__PURE__ */ jsx("div", { className: "mt-6", children: cta })
6326
- ]
6785
+ typeof maxSize === "number" && /* @__PURE__ */ jsxs("p", { className: "text-xs", children: [
6786
+ "Max size: ",
6787
+ (maxSize / 1024 / 1024).toFixed(1),
6788
+ " MB"
6789
+ ] })
6790
+ ] })
6327
6791
  }
6328
6792
  );
6329
6793
  }
6330
- function DataToolbar({ className, surface, radius, animated, ...props }) {
6331
- const sf = useSaasflareProps({ surface, radius, animated });
6332
- return /* @__PURE__ */ jsx(
6333
- "div",
6334
- {
6794
+ function CalendarIcon(props) {
6795
+ return /* @__PURE__ */ jsxs(
6796
+ "svg",
6797
+ {
6798
+ xmlns: "http://www.w3.org/2000/svg",
6799
+ viewBox: "0 0 24 24",
6800
+ fill: "none",
6801
+ stroke: "currentColor",
6802
+ strokeWidth: "2",
6803
+ strokeLinecap: "round",
6804
+ strokeLinejoin: "round",
6805
+ "aria-hidden": "true",
6335
6806
  ...props,
6336
- "data-slot": "data-toolbar",
6337
- "data-surface": sf.surface,
6338
- "data-radius": sf.radius,
6339
- "data-animated": String(sf.animated),
6340
- className: cn(
6807
+ children: [
6808
+ /* @__PURE__ */ jsx("rect", { width: "18", height: "18", x: "3", y: "4", rx: "2", ry: "2" }),
6809
+ /* @__PURE__ */ jsx("line", { x1: "16", x2: "16", y1: "2", y2: "6" }),
6810
+ /* @__PURE__ */ jsx("line", { x1: "8", x2: "8", y1: "2", y2: "6" }),
6811
+ /* @__PURE__ */ jsx("line", { x1: "3", x2: "21", y1: "10", y2: "10" })
6812
+ ]
6813
+ }
6814
+ );
6815
+ }
6816
+ function defaultFormat(range) {
6817
+ const fmt = (d) => d.toLocaleDateString(void 0, {
6818
+ year: "numeric",
6819
+ month: "short",
6820
+ day: "numeric"
6821
+ });
6822
+ if (!range.from) return "";
6823
+ if (!range.to) return fmt(range.from);
6824
+ return `${fmt(range.from)} \u2013 ${fmt(range.to)}`;
6825
+ }
6826
+ function DateRangePicker({
6827
+ value,
6828
+ defaultValue,
6829
+ onChange,
6830
+ placeholder = "Pick a date range",
6831
+ numberOfMonths = 2,
6832
+ minDate,
6833
+ maxDate,
6834
+ disabled = false,
6835
+ formatRange = defaultFormat,
6836
+ className,
6837
+ surface,
6838
+ radius,
6839
+ animated,
6840
+ iconWeight
6841
+ }) {
6842
+ const sf = useSaasflareProps({ surface, radius, animated, iconWeight });
6843
+ const isControlled = value !== void 0;
6844
+ const [internal, setInternal] = useState(defaultValue);
6845
+ const range = isControlled ? value : internal;
6846
+ const handleSelect = (next) => {
6847
+ if (!isControlled) setInternal(next);
6848
+ onChange?.(next);
6849
+ };
6850
+ const label = range && range.from ? formatRange(range) : placeholder;
6851
+ return /* @__PURE__ */ jsxs(Popover, { children: [
6852
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
6853
+ Button,
6854
+ {
6855
+ type: "button",
6856
+ variant: "outline",
6857
+ intent: "neutral",
6858
+ disabled,
6859
+ surface: sf.surface,
6860
+ radius: sf.radius,
6861
+ animated: sf.animated,
6862
+ "data-slot": "date-range-picker-trigger",
6863
+ className: cn(
6864
+ "min-w-56 justify-start gap-2 font-normal",
6865
+ !range?.from && "text-muted-foreground",
6866
+ className
6867
+ ),
6868
+ children: [
6869
+ /* @__PURE__ */ jsx(CalendarIcon, { className: "size-4" }),
6870
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: label })
6871
+ ]
6872
+ }
6873
+ ) }),
6874
+ /* @__PURE__ */ jsx(
6875
+ PopoverContent,
6876
+ {
6877
+ "data-slot": "date-range-picker-content",
6878
+ align: "start",
6879
+ className: "w-auto p-0",
6880
+ children: /* @__PURE__ */ jsx(
6881
+ Calendar,
6882
+ {
6883
+ mode: "range",
6884
+ selected: range,
6885
+ onSelect: handleSelect,
6886
+ numberOfMonths,
6887
+ defaultMonth: range?.from ?? /* @__PURE__ */ new Date(),
6888
+ disabled: minDate || maxDate ? (date) => (minDate ? date < minDate : false) || (maxDate ? date > maxDate : false) : void 0
6889
+ }
6890
+ )
6891
+ }
6892
+ )
6893
+ ] });
6894
+ }
6895
+ function CalendarIcon2(props) {
6896
+ return /* @__PURE__ */ jsxs(
6897
+ "svg",
6898
+ {
6899
+ xmlns: "http://www.w3.org/2000/svg",
6900
+ viewBox: "0 0 24 24",
6901
+ fill: "none",
6902
+ stroke: "currentColor",
6903
+ strokeWidth: "2",
6904
+ strokeLinecap: "round",
6905
+ strokeLinejoin: "round",
6906
+ "aria-hidden": "true",
6907
+ ...props,
6908
+ children: [
6909
+ /* @__PURE__ */ jsx("rect", { width: "18", height: "18", x: "3", y: "4", rx: "2", ry: "2" }),
6910
+ /* @__PURE__ */ jsx("line", { x1: "16", x2: "16", y1: "2", y2: "6" }),
6911
+ /* @__PURE__ */ jsx("line", { x1: "8", x2: "8", y1: "2", y2: "6" }),
6912
+ /* @__PURE__ */ jsx("line", { x1: "3", x2: "21", y1: "10", y2: "10" })
6913
+ ]
6914
+ }
6915
+ );
6916
+ }
6917
+ function defaultFormat2(d) {
6918
+ return d.toLocaleDateString(void 0, {
6919
+ year: "numeric",
6920
+ month: "short",
6921
+ day: "numeric"
6922
+ });
6923
+ }
6924
+ function DatePicker({
6925
+ value,
6926
+ defaultValue,
6927
+ onChange,
6928
+ placeholder = "Pick a date",
6929
+ minDate,
6930
+ maxDate,
6931
+ disabled = false,
6932
+ formatDate = defaultFormat2,
6933
+ className,
6934
+ surface,
6935
+ radius,
6936
+ animated,
6937
+ iconWeight
6938
+ }) {
6939
+ const sf = useSaasflareProps({ surface, radius, animated, iconWeight });
6940
+ const isControlled = value !== void 0;
6941
+ const [internal, setInternal] = useState(defaultValue);
6942
+ const date = isControlled ? value : internal;
6943
+ const handleSelect = (next) => {
6944
+ if (!isControlled) setInternal(next);
6945
+ onChange?.(next);
6946
+ };
6947
+ return /* @__PURE__ */ jsxs(Popover, { children: [
6948
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
6949
+ Button,
6950
+ {
6951
+ type: "button",
6952
+ variant: "outline",
6953
+ intent: "neutral",
6954
+ disabled,
6955
+ surface: sf.surface,
6956
+ radius: sf.radius,
6957
+ animated: sf.animated,
6958
+ "data-slot": "date-picker-trigger",
6959
+ className: cn(
6960
+ "min-w-44 justify-start gap-2 font-normal",
6961
+ !date && "text-muted-foreground",
6962
+ className
6963
+ ),
6964
+ children: [
6965
+ /* @__PURE__ */ jsx(CalendarIcon2, { className: "size-4" }),
6966
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: date ? formatDate(date) : placeholder })
6967
+ ]
6968
+ }
6969
+ ) }),
6970
+ /* @__PURE__ */ jsx(
6971
+ PopoverContent,
6972
+ {
6973
+ "data-slot": "date-picker-content",
6974
+ align: "start",
6975
+ className: "w-auto p-0",
6976
+ children: /* @__PURE__ */ jsx(
6977
+ Calendar,
6978
+ {
6979
+ mode: "single",
6980
+ selected: date,
6981
+ onSelect: handleSelect,
6982
+ defaultMonth: date ?? /* @__PURE__ */ new Date(),
6983
+ disabled: minDate || maxDate ? (d) => (minDate ? d < minDate : false) || (maxDate ? d > maxDate : false) : void 0
6984
+ }
6985
+ )
6986
+ }
6987
+ )
6988
+ ] });
6989
+ }
6990
+ function Callout({
6991
+ intent = "info",
6992
+ title,
6993
+ icon,
6994
+ children,
6995
+ className,
6996
+ surface,
6997
+ radius,
6998
+ animated,
6999
+ iconWeight
7000
+ }) {
7001
+ const sf = useSaasflareProps({ surface, radius, animated, iconWeight });
7002
+ return /* @__PURE__ */ jsxs(
7003
+ "div",
7004
+ {
7005
+ "data-slot": "callout",
7006
+ "data-intent": intent,
7007
+ "data-surface": sf.surface,
7008
+ "data-radius": sf.radius,
7009
+ "data-animated": String(sf.animated),
7010
+ role: "note",
7011
+ className: cn(
7012
+ "relative flex gap-3 rounded-lg border-l-4 p-4",
7013
+ "border-l-[var(--intent)] bg-[var(--intent)]/8",
7014
+ "text-foreground",
7015
+ "[&_a]:underline [&_a]:underline-offset-2 [&_a]:text-[var(--intent-text)]",
7016
+ className
7017
+ ),
7018
+ children: [
7019
+ icon !== void 0 && /* @__PURE__ */ jsx(
7020
+ "div",
7021
+ {
7022
+ "data-slot": "callout-icon",
7023
+ className: "mt-0.5 shrink-0 text-[var(--intent-text)] [&_svg]:size-5",
7024
+ children: icon
7025
+ }
7026
+ ),
7027
+ /* @__PURE__ */ jsxs("div", { "data-slot": "callout-body", className: "flex-1 space-y-1", children: [
7028
+ title !== void 0 && /* @__PURE__ */ jsx(
7029
+ "p",
7030
+ {
7031
+ "data-slot": "callout-title",
7032
+ className: "font-semibold leading-tight text-[var(--intent-text)]",
7033
+ children: title
7034
+ }
7035
+ ),
7036
+ children !== void 0 && /* @__PURE__ */ jsx("div", { "data-slot": "callout-content", className: "text-sm leading-relaxed text-muted-foreground", children })
7037
+ ] })
7038
+ ]
7039
+ }
7040
+ );
7041
+ }
7042
+ function TagInput({
7043
+ value,
7044
+ defaultValue,
7045
+ onChange,
7046
+ placeholder,
7047
+ maxTags,
7048
+ separators = [",", "Enter"],
7049
+ unique = true,
7050
+ disabled = false,
7051
+ renderTag,
7052
+ className,
7053
+ surface,
7054
+ radius,
7055
+ animated,
7056
+ "aria-label": ariaLabel
7057
+ }) {
7058
+ const sf = useSaasflareProps({ surface, radius, animated });
7059
+ const isControlled = value !== void 0;
7060
+ const [internal, setInternal] = useState(defaultValue ?? []);
7061
+ const tags = isControlled ? value : internal;
7062
+ const [draft, setDraft] = useState("");
7063
+ const commit = useCallback(
7064
+ (raw) => {
7065
+ const trimmed = raw.trim();
7066
+ if (!trimmed) return;
7067
+ if (unique && tags.includes(trimmed)) return;
7068
+ if (typeof maxTags === "number" && tags.length >= maxTags) return;
7069
+ const next = [...tags, trimmed];
7070
+ if (!isControlled) setInternal(next);
7071
+ onChange?.(next);
7072
+ setDraft("");
7073
+ },
7074
+ [isControlled, maxTags, onChange, tags, unique]
7075
+ );
7076
+ const removeAt = useCallback(
7077
+ (index) => {
7078
+ const next = tags.filter((_, i) => i !== index);
7079
+ if (!isControlled) setInternal(next);
7080
+ onChange?.(next);
7081
+ },
7082
+ [isControlled, onChange, tags]
7083
+ );
7084
+ const handleChange = (e) => {
7085
+ const v = e.target.value;
7086
+ const sep = separators.find((s) => s !== "Enter" && v.includes(s));
7087
+ if (sep) {
7088
+ const parts = v.split(sep);
7089
+ for (let i = 0; i < parts.length - 1; i++) commit(parts[i]);
7090
+ setDraft(parts[parts.length - 1] ?? "");
7091
+ } else {
7092
+ setDraft(v);
7093
+ }
7094
+ };
7095
+ const handleKeyDown = (e) => {
7096
+ if (separators.includes(e.key) || e.key === "," && separators.includes(",")) {
7097
+ e.preventDefault();
7098
+ commit(draft);
7099
+ return;
7100
+ }
7101
+ if (e.key === "Backspace" && draft === "" && tags.length > 0) {
7102
+ e.preventDefault();
7103
+ removeAt(tags.length - 1);
7104
+ }
7105
+ };
7106
+ return /* @__PURE__ */ jsxs(
7107
+ "div",
7108
+ {
7109
+ "data-slot": "tag-input",
7110
+ "data-surface": sf.surface,
7111
+ "data-radius": sf.radius,
7112
+ "data-disabled": String(disabled),
7113
+ className: cn(
7114
+ "flex min-h-9 w-full flex-wrap items-center gap-1.5 rounded-md border border-input bg-transparent px-2 py-1.5 text-sm shadow-xs",
7115
+ "focus-within:border-ring focus-within:ring-[3px] focus-within:ring-ring/50",
7116
+ "data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50",
7117
+ className
7118
+ ),
7119
+ children: [
7120
+ tags.map((tag, i) => {
7121
+ const onRemove = () => removeAt(i);
7122
+ if (renderTag) return /* @__PURE__ */ jsx("span", { children: renderTag(tag, onRemove) }, `${tag}-${i}`);
7123
+ return /* @__PURE__ */ jsxs(
7124
+ "span",
7125
+ {
7126
+ "data-slot": "tag-input-tag",
7127
+ className: "inline-flex items-center gap-1 rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium text-foreground",
7128
+ children: [
7129
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: tag }),
7130
+ /* @__PURE__ */ jsx(
7131
+ "button",
7132
+ {
7133
+ type: "button",
7134
+ "data-slot": "tag-input-remove",
7135
+ onClick: onRemove,
7136
+ disabled,
7137
+ "aria-label": `Remove ${tag}`,
7138
+ className: "inline-flex size-3.5 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-foreground/10 hover:text-foreground",
7139
+ children: /* @__PURE__ */ jsx(
7140
+ "svg",
7141
+ {
7142
+ viewBox: "0 0 12 12",
7143
+ width: "10",
7144
+ height: "10",
7145
+ "aria-hidden": "true",
7146
+ fill: "none",
7147
+ stroke: "currentColor",
7148
+ strokeWidth: "2",
7149
+ strokeLinecap: "round",
7150
+ children: /* @__PURE__ */ jsx("path", { d: "M3 3l6 6M9 3l-6 6" })
7151
+ }
7152
+ )
7153
+ }
7154
+ )
7155
+ ]
7156
+ },
7157
+ `${tag}-${i}`
7158
+ );
7159
+ }),
7160
+ /* @__PURE__ */ jsx(
7161
+ "input",
7162
+ {
7163
+ "data-slot": "tag-input-field",
7164
+ type: "text",
7165
+ value: draft,
7166
+ onChange: handleChange,
7167
+ onKeyDown: handleKeyDown,
7168
+ onBlur: () => commit(draft),
7169
+ disabled,
7170
+ placeholder: tags.length === 0 ? placeholder : void 0,
7171
+ "aria-label": ariaLabel ?? "Add tag",
7172
+ className: "flex-1 min-w-24 bg-transparent text-sm outline-none placeholder:text-muted-foreground"
7173
+ }
7174
+ )
7175
+ ]
7176
+ }
7177
+ );
7178
+ }
7179
+ function clamp(n, min, max) {
7180
+ let out = n;
7181
+ if (typeof min === "number") out = Math.max(out, min);
7182
+ if (typeof max === "number") out = Math.min(out, max);
7183
+ return out;
7184
+ }
7185
+ function precisionFromStep(step) {
7186
+ const s = String(step);
7187
+ const dot = s.indexOf(".");
7188
+ return dot === -1 ? 0 : s.length - dot - 1;
7189
+ }
7190
+ function NumberInput({
7191
+ value,
7192
+ defaultValue,
7193
+ onChange,
7194
+ min,
7195
+ max,
7196
+ step = 1,
7197
+ precision,
7198
+ placeholder,
7199
+ disabled = false,
7200
+ readOnly = false,
7201
+ hideSteppers = false,
7202
+ className,
7203
+ name,
7204
+ surface,
7205
+ radius,
7206
+ animated,
7207
+ "aria-label": ariaLabel
7208
+ }) {
7209
+ const sf = useSaasflareProps({ surface, radius, animated });
7210
+ const isControlled = value !== void 0;
7211
+ const initial = defaultValue ?? (typeof min === "number" ? min : 0);
7212
+ const [internal, setInternal] = useState(initial);
7213
+ const current = isControlled ? value : internal;
7214
+ const decimals = precision ?? precisionFromStep(step);
7215
+ const commit = useCallback(
7216
+ (next) => {
7217
+ const clamped = clamp(Number.isFinite(next) ? next : initial, min, max);
7218
+ if (!isControlled) setInternal(clamped);
7219
+ onChange?.(clamped);
7220
+ },
7221
+ [initial, isControlled, max, min, onChange]
7222
+ );
7223
+ const handleChange = (e) => {
7224
+ const raw = e.target.value;
7225
+ if (raw === "" || raw === "-") {
7226
+ if (!isControlled) setInternal(0);
7227
+ return;
7228
+ }
7229
+ const parsed = Number(raw);
7230
+ if (Number.isNaN(parsed)) return;
7231
+ commit(parsed);
7232
+ };
7233
+ const handleBlur = (e) => {
7234
+ const parsed = Number(e.target.value);
7235
+ commit(Number.isNaN(parsed) ? initial : parsed);
7236
+ };
7237
+ const inc = () => commit(current + step);
7238
+ const dec = () => commit(current - step);
7239
+ const displayValue = decimals > 0 && Number.isFinite(current) ? current.toFixed(decimals) : String(current);
7240
+ return /* @__PURE__ */ jsxs(
7241
+ "div",
7242
+ {
7243
+ "data-slot": "number-input",
7244
+ "data-surface": sf.surface,
7245
+ "data-radius": sf.radius,
7246
+ "data-disabled": String(disabled),
7247
+ className: cn(
7248
+ "inline-flex h-9 w-full min-w-32 items-stretch rounded-md border border-input bg-transparent text-sm shadow-xs",
7249
+ "focus-within:border-ring focus-within:ring-[3px] focus-within:ring-ring/50",
7250
+ "data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50",
7251
+ className
7252
+ ),
7253
+ children: [
7254
+ /* @__PURE__ */ jsx(
7255
+ "input",
7256
+ {
7257
+ "data-slot": "number-input-field",
7258
+ type: "number",
7259
+ inputMode: "decimal",
7260
+ name,
7261
+ value: Number.isFinite(current) ? displayValue : "",
7262
+ onChange: handleChange,
7263
+ onBlur: handleBlur,
7264
+ disabled,
7265
+ readOnly,
7266
+ placeholder,
7267
+ min,
7268
+ max,
7269
+ step,
7270
+ "aria-label": ariaLabel,
7271
+ className: "min-w-0 flex-1 bg-transparent px-3 text-sm outline-none placeholder:text-muted-foreground\n [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
7272
+ }
7273
+ ),
7274
+ !hideSteppers && /* @__PURE__ */ jsxs(
7275
+ "div",
7276
+ {
7277
+ "data-slot": "number-input-steppers",
7278
+ className: "flex flex-col border-l border-input",
7279
+ children: [
7280
+ /* @__PURE__ */ jsx(
7281
+ "button",
7282
+ {
7283
+ type: "button",
7284
+ "data-slot": "number-input-increment",
7285
+ onClick: inc,
7286
+ disabled: disabled || readOnly || typeof max === "number" && current >= max,
7287
+ tabIndex: -1,
7288
+ "aria-label": "Increment",
7289
+ className: "flex h-1/2 w-6 items-center justify-center text-muted-foreground transition-colors hover:bg-foreground/5 hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50",
7290
+ children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 10 10", width: "8", height: "8", "aria-hidden": "true", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M2 6.5l3-3 3 3" }) })
7291
+ }
7292
+ ),
7293
+ /* @__PURE__ */ jsx(
7294
+ "button",
7295
+ {
7296
+ type: "button",
7297
+ "data-slot": "number-input-decrement",
7298
+ onClick: dec,
7299
+ disabled: disabled || readOnly || typeof min === "number" && current <= min,
7300
+ tabIndex: -1,
7301
+ "aria-label": "Decrement",
7302
+ className: "flex h-1/2 w-6 items-center justify-center border-t border-input text-muted-foreground transition-colors hover:bg-foreground/5 hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50",
7303
+ children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 10 10", width: "8", height: "8", "aria-hidden": "true", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "M2 3.5l3 3 3-3" }) })
7304
+ }
7305
+ )
7306
+ ]
7307
+ }
7308
+ )
7309
+ ]
7310
+ }
7311
+ );
7312
+ }
7313
+ var SIZE_PX2 = { sm: 14, md: 20, lg: 28, xl: 36 };
7314
+ function StarPath({
7315
+ fillPercent,
7316
+ color,
7317
+ px,
7318
+ onClick,
7319
+ onMouseMove
7320
+ }) {
7321
+ const id = `star-clip-${Math.random().toString(36).slice(2, 8)}`;
7322
+ return /* @__PURE__ */ jsxs(
7323
+ "svg",
7324
+ {
7325
+ viewBox: "0 0 24 24",
7326
+ width: px,
7327
+ height: px,
7328
+ onClick,
7329
+ onMouseMove,
7330
+ "aria-hidden": "true",
7331
+ style: { display: "block" },
7332
+ children: [
7333
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx("clipPath", { id, children: /* @__PURE__ */ jsx("rect", { x: "0", y: "0", width: 24 * fillPercent, height: "24" }) }) }),
7334
+ /* @__PURE__ */ jsx(
7335
+ "path",
7336
+ {
7337
+ d: "M12 2.5l2.92 6.34 6.96.66-5.23 4.7 1.56 6.8L12 17.6l-6.21 3.4 1.56-6.8L2.12 9.5l6.96-.66z",
7338
+ fill: "none",
7339
+ stroke: color,
7340
+ strokeWidth: "1.5",
7341
+ strokeLinejoin: "round"
7342
+ }
7343
+ ),
7344
+ /* @__PURE__ */ jsx(
7345
+ "path",
7346
+ {
7347
+ d: "M12 2.5l2.92 6.34 6.96.66-5.23 4.7 1.56 6.8L12 17.6l-6.21 3.4 1.56-6.8L2.12 9.5l6.96-.66z",
7348
+ fill: color,
7349
+ clipPath: `url(#${id})`
7350
+ }
7351
+ )
7352
+ ]
7353
+ }
7354
+ );
7355
+ }
7356
+ function Rating({
7357
+ value,
7358
+ defaultValue,
7359
+ onChange,
7360
+ count = 5,
7361
+ allowHalf = false,
7362
+ readOnly = false,
7363
+ disabled = false,
7364
+ size = "md",
7365
+ color = "var(--warning)",
7366
+ className,
7367
+ surface,
7368
+ radius,
7369
+ animated,
7370
+ "aria-label": ariaLabel
7371
+ }) {
7372
+ const sf = useSaasflareProps({ surface, radius, animated });
7373
+ const isControlled = value !== void 0;
7374
+ const [internal, setInternal] = useState(defaultValue ?? 0);
7375
+ const [hover, setHover] = useState(null);
7376
+ const current = isControlled ? value : internal;
7377
+ const display = hover ?? current;
7378
+ const px = SIZE_PX2[size];
7379
+ const interactive = !readOnly && !disabled;
7380
+ const commit = useCallback(
7381
+ (next) => {
7382
+ const clamped = Math.max(0, Math.min(count, next));
7383
+ if (!isControlled) setInternal(clamped);
7384
+ onChange?.(clamped);
7385
+ },
7386
+ [count, isControlled, onChange]
7387
+ );
7388
+ const computeScore = (i, e) => {
7389
+ if (!allowHalf) return i + 1;
7390
+ const rect = e.currentTarget.getBoundingClientRect();
7391
+ const halfway = rect.left + rect.width / 2;
7392
+ return e.clientX < halfway ? i + 0.5 : i + 1;
7393
+ };
7394
+ return /* @__PURE__ */ jsx(
7395
+ "div",
7396
+ {
7397
+ "data-slot": "rating",
7398
+ "data-size": size,
7399
+ "data-readonly": String(readOnly),
7400
+ "data-disabled": String(disabled),
7401
+ "data-surface": sf.surface,
7402
+ "data-animated": String(sf.animated),
7403
+ role: interactive ? "slider" : "img",
7404
+ "aria-label": ariaLabel ?? `Rating: ${current} of ${count}`,
7405
+ "aria-valuemin": interactive ? 0 : void 0,
7406
+ "aria-valuemax": interactive ? count : void 0,
7407
+ "aria-valuenow": interactive ? current : void 0,
7408
+ tabIndex: interactive ? 0 : -1,
7409
+ onKeyDown: interactive ? (e) => {
7410
+ const inc = allowHalf ? 0.5 : 1;
7411
+ if (e.key === "ArrowRight" || e.key === "ArrowUp") {
7412
+ e.preventDefault();
7413
+ commit(current + inc);
7414
+ } else if (e.key === "ArrowLeft" || e.key === "ArrowDown") {
7415
+ e.preventDefault();
7416
+ commit(current - inc);
7417
+ } else if (e.key === "Home") {
7418
+ e.preventDefault();
7419
+ commit(0);
7420
+ } else if (e.key === "End") {
7421
+ e.preventDefault();
7422
+ commit(count);
7423
+ }
7424
+ } : void 0,
7425
+ onMouseLeave: interactive ? () => setHover(null) : void 0,
7426
+ className: cn(
7427
+ "inline-flex items-center gap-0.5 outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-sm",
7428
+ interactive && "cursor-pointer",
7429
+ disabled && "cursor-not-allowed opacity-50",
7430
+ className
7431
+ ),
7432
+ children: Array.from({ length: count }, (_, i) => {
7433
+ const fillPercent = Math.max(0, Math.min(1, display - i));
7434
+ return /* @__PURE__ */ jsx(
7435
+ StarPath,
7436
+ {
7437
+ fillPercent,
7438
+ color,
7439
+ px,
7440
+ onClick: interactive ? (e) => commit(computeScore(i, e)) : void 0,
7441
+ onMouseMove: interactive ? (e) => setHover(computeScore(i, e)) : void 0
7442
+ },
7443
+ i
7444
+ );
7445
+ })
7446
+ }
7447
+ );
7448
+ }
7449
+ var FALLBACK_COLORS = [
7450
+ "oklch(0.65 0.18 230)",
7451
+ // blue
7452
+ "oklch(0.72 0.17 50)",
7453
+ // amber
7454
+ "oklch(0.68 0.17 155)",
7455
+ // emerald
7456
+ "oklch(0.62 0.21 25)",
7457
+ // red
7458
+ "oklch(0.65 0.20 290)",
7459
+ // violet
7460
+ "oklch(0.70 0.15 185)"
7461
+ // teal
7462
+ ];
7463
+ function CategoryBar({
7464
+ segments,
7465
+ height = 8,
7466
+ showLabels = false,
7467
+ valueFormatter,
7468
+ className,
7469
+ surface,
7470
+ radius,
7471
+ animated,
7472
+ "aria-label": ariaLabel
7473
+ }) {
7474
+ const sf = useSaasflareProps({ surface, radius, animated });
7475
+ const motion = useSaasflareMotion(sf.animated, springGentle);
7476
+ const total = segments.reduce((sum, s) => sum + Math.max(0, s.value), 0);
7477
+ if (total === 0 || segments.length === 0) return null;
7478
+ const formatter = valueFormatter ?? ((p) => `${p.toFixed(p < 10 ? 1 : 0)}%`);
7479
+ return /* @__PURE__ */ jsxs(
7480
+ "div",
7481
+ {
7482
+ "data-slot": "category-bar",
7483
+ "data-surface": sf.surface,
7484
+ "data-radius": sf.radius,
7485
+ "data-animated": String(sf.animated),
7486
+ role: "group",
7487
+ "aria-label": ariaLabel ?? "Category breakdown",
7488
+ className: cn("w-full", className),
7489
+ children: [
7490
+ /* @__PURE__ */ jsx(
7491
+ "div",
7492
+ {
7493
+ "data-slot": "category-bar-track",
7494
+ className: "flex w-full overflow-hidden rounded-full bg-primary/10",
7495
+ style: { height },
7496
+ children: segments.map((seg, i) => {
7497
+ const pct = Math.max(0, seg.value) / total * 100;
7498
+ return /* @__PURE__ */ jsx(
7499
+ m.div,
7500
+ {
7501
+ "data-slot": "category-bar-segment",
7502
+ title: seg.label ? `${seg.label}: ${formatter(pct)}` : formatter(pct),
7503
+ initial: motion.disabled ? false : { width: 0 },
7504
+ animate: { width: `${pct}%` },
7505
+ transition: motion.transition,
7506
+ className: "h-full",
7507
+ style: {
7508
+ backgroundColor: seg.color ?? FALLBACK_COLORS[i % FALLBACK_COLORS.length]
7509
+ }
7510
+ },
7511
+ i
7512
+ );
7513
+ })
7514
+ }
7515
+ ),
7516
+ showLabels && /* @__PURE__ */ jsx(
7517
+ "div",
7518
+ {
7519
+ "data-slot": "category-bar-labels",
7520
+ className: "mt-2 flex w-full text-xs text-muted-foreground",
7521
+ children: segments.map((seg, i) => {
7522
+ const pct = Math.max(0, seg.value) / total * 100;
7523
+ return /* @__PURE__ */ jsxs(
7524
+ "div",
7525
+ {
7526
+ "data-slot": "category-bar-label",
7527
+ style: { width: `${pct}%` },
7528
+ className: "flex min-w-0 items-center gap-1.5 truncate px-1",
7529
+ children: [
7530
+ /* @__PURE__ */ jsx(
7531
+ "span",
7532
+ {
7533
+ "aria-hidden": "true",
7534
+ className: "size-2 shrink-0 rounded-full",
7535
+ style: {
7536
+ backgroundColor: seg.color ?? FALLBACK_COLORS[i % FALLBACK_COLORS.length]
7537
+ }
7538
+ }
7539
+ ),
7540
+ /* @__PURE__ */ jsxs("span", { className: "truncate", children: [
7541
+ seg.label ? `${seg.label} ` : "",
7542
+ /* @__PURE__ */ jsx("span", { className: "text-foreground font-medium tabular-nums", children: formatter(pct) })
7543
+ ] })
7544
+ ]
7545
+ },
7546
+ i
7547
+ );
7548
+ })
7549
+ }
7550
+ )
7551
+ ]
7552
+ }
7553
+ );
7554
+ }
7555
+ function flattenVisible(data, expanded) {
7556
+ const out = [];
7557
+ const walk = (nodes, depth, parentId) => {
7558
+ for (const node of nodes) {
7559
+ out.push({ node, depth, parentId });
7560
+ if (node.children && expanded.has(node.id)) {
7561
+ walk(node.children, depth + 1, node.id);
7562
+ }
7563
+ }
7564
+ };
7565
+ walk(data, 0, null);
7566
+ return out;
7567
+ }
7568
+ function TreeView({
7569
+ data,
7570
+ expanded,
7571
+ defaultExpanded,
7572
+ onExpand,
7573
+ selected,
7574
+ defaultSelected,
7575
+ onSelect,
7576
+ className,
7577
+ surface,
7578
+ radius,
7579
+ animated,
7580
+ iconWeight
7581
+ }) {
7582
+ const sf = useSaasflareProps({ surface, radius, animated, iconWeight });
7583
+ const isExpandedControlled = expanded !== void 0;
7584
+ const [internalExpanded, setInternalExpanded] = useState(
7585
+ defaultExpanded ?? []
7586
+ );
7587
+ const expandedSet = useMemo(
7588
+ () => new Set(isExpandedControlled ? expanded : internalExpanded),
7589
+ [isExpandedControlled, expanded, internalExpanded]
7590
+ );
7591
+ const isSelectedControlled = selected !== void 0;
7592
+ const [internalSelected, setInternalSelected] = useState(
7593
+ defaultSelected ?? null
7594
+ );
7595
+ const currentSelected = isSelectedControlled ? selected : internalSelected;
7596
+ const toggle = useCallback(
7597
+ (id) => {
7598
+ const next = new Set(expandedSet);
7599
+ if (next.has(id)) next.delete(id);
7600
+ else next.add(id);
7601
+ const arr = Array.from(next);
7602
+ if (!isExpandedControlled) setInternalExpanded(arr);
7603
+ onExpand?.(arr);
7604
+ },
7605
+ [expandedSet, isExpandedControlled, onExpand]
7606
+ );
7607
+ const select = useCallback(
7608
+ (id) => {
7609
+ if (!isSelectedControlled) setInternalSelected(id);
7610
+ onSelect?.(id);
7611
+ },
7612
+ [isSelectedControlled, onSelect]
7613
+ );
7614
+ const flat = useMemo(() => flattenVisible(data, expandedSet), [data, expandedSet]);
7615
+ const handleKeyDown = (e, index) => {
7616
+ const item = flat[index];
7617
+ if (!item || item.node.disabled) return;
7618
+ const moveTo = (i) => {
7619
+ const target = flat[i];
7620
+ if (!target) return;
7621
+ select(target.node.id);
7622
+ const el = e.currentTarget.parentElement?.querySelectorAll(
7623
+ "[data-slot='tree-view-row']"
7624
+ )[i];
7625
+ el?.focus();
7626
+ };
7627
+ switch (e.key) {
7628
+ case "ArrowDown":
7629
+ e.preventDefault();
7630
+ moveTo(Math.min(index + 1, flat.length - 1));
7631
+ break;
7632
+ case "ArrowUp":
7633
+ e.preventDefault();
7634
+ moveTo(Math.max(index - 1, 0));
7635
+ break;
7636
+ case "ArrowRight":
7637
+ e.preventDefault();
7638
+ if (item.node.children && !expandedSet.has(item.node.id)) {
7639
+ toggle(item.node.id);
7640
+ } else {
7641
+ moveTo(index + 1);
7642
+ }
7643
+ break;
7644
+ case "ArrowLeft":
7645
+ e.preventDefault();
7646
+ if (item.node.children && expandedSet.has(item.node.id)) {
7647
+ toggle(item.node.id);
7648
+ } else if (item.parentId) {
7649
+ const parentIdx = flat.findIndex((f) => f.node.id === item.parentId);
7650
+ if (parentIdx >= 0) moveTo(parentIdx);
7651
+ }
7652
+ break;
7653
+ case "Home":
7654
+ e.preventDefault();
7655
+ moveTo(0);
7656
+ break;
7657
+ case "End":
7658
+ e.preventDefault();
7659
+ moveTo(flat.length - 1);
7660
+ break;
7661
+ case "Enter":
7662
+ case " ":
7663
+ e.preventDefault();
7664
+ if (item.node.children) toggle(item.node.id);
7665
+ select(item.node.id);
7666
+ break;
7667
+ }
7668
+ };
7669
+ return /* @__PURE__ */ jsx(
7670
+ "div",
7671
+ {
7672
+ "data-slot": "tree-view",
7673
+ "data-surface": sf.surface,
7674
+ "data-radius": sf.radius,
7675
+ "data-animated": String(sf.animated),
7676
+ role: "tree",
7677
+ className: cn("text-sm select-none", className),
7678
+ children: flat.map(({ node, depth }, index) => {
7679
+ const hasChildren = !!node.children?.length;
7680
+ const isExpanded = expandedSet.has(node.id);
7681
+ const isSelected = currentSelected === node.id;
7682
+ return /* @__PURE__ */ jsxs(
7683
+ "div",
7684
+ {
7685
+ "data-slot": "tree-view-row",
7686
+ role: "treeitem",
7687
+ "aria-expanded": hasChildren ? isExpanded : void 0,
7688
+ "aria-selected": isSelected,
7689
+ "aria-level": depth + 1,
7690
+ "aria-disabled": node.disabled || void 0,
7691
+ tabIndex: isSelected || currentSelected === null && index === 0 ? 0 : -1,
7692
+ onKeyDown: (e) => handleKeyDown(e, index),
7693
+ onClick: () => {
7694
+ if (node.disabled) return;
7695
+ if (hasChildren) toggle(node.id);
7696
+ select(node.id);
7697
+ },
7698
+ className: cn(
7699
+ "flex h-7 cursor-pointer items-center gap-1 rounded px-1.5",
7700
+ "transition-colors hover:bg-accent/40",
7701
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
7702
+ isSelected && "bg-accent/60 text-foreground",
7703
+ node.disabled && "pointer-events-none opacity-50"
7704
+ ),
7705
+ style: { paddingLeft: 6 + depth * 16 },
7706
+ children: [
7707
+ hasChildren ? /* @__PURE__ */ jsx(
7708
+ CaretRightIcon,
7709
+ {
7710
+ className: cn(
7711
+ "size-3.5 shrink-0 text-muted-foreground transition-transform duration-150",
7712
+ isExpanded && "rotate-90"
7713
+ )
7714
+ }
7715
+ ) : /* @__PURE__ */ jsx("span", { className: "size-3.5 shrink-0", "aria-hidden": "true" }),
7716
+ node.icon !== void 0 && /* @__PURE__ */ jsx("span", { className: "flex shrink-0 items-center [&_svg]:size-4", children: node.icon }),
7717
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: node.label })
7718
+ ]
7719
+ },
7720
+ node.id
7721
+ );
7722
+ })
7723
+ }
7724
+ );
7725
+ }
7726
+ function useClipboard(resetMs = 2e3) {
7727
+ const [copied, setCopied] = useState(false);
7728
+ const [error, setError] = useState(null);
7729
+ const timerRef = useRef(void 0);
7730
+ const copy = useCallback(
7731
+ async (text) => {
7732
+ try {
7733
+ await navigator.clipboard.writeText(text);
7734
+ setCopied(true);
7735
+ setError(null);
7736
+ clearTimeout(timerRef.current);
7737
+ timerRef.current = setTimeout(() => setCopied(false), resetMs);
7738
+ } catch (err) {
7739
+ setCopied(false);
7740
+ setError(err instanceof Error ? err.message : "Failed to copy");
7741
+ }
7742
+ },
7743
+ [resetMs]
7744
+ );
7745
+ return { copy, copied, error };
7746
+ }
7747
+ function CopyIcon(props) {
7748
+ return /* @__PURE__ */ jsxs(
7749
+ "svg",
7750
+ {
7751
+ viewBox: "0 0 24 24",
7752
+ fill: "none",
7753
+ stroke: "currentColor",
7754
+ strokeWidth: "2",
7755
+ strokeLinecap: "round",
7756
+ strokeLinejoin: "round",
7757
+ "aria-hidden": "true",
7758
+ ...props,
7759
+ children: [
7760
+ /* @__PURE__ */ jsx("rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2" }),
7761
+ /* @__PURE__ */ jsx("path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" })
7762
+ ]
7763
+ }
7764
+ );
7765
+ }
7766
+ function CodeBlock({
7767
+ code,
7768
+ highlighted,
7769
+ language,
7770
+ filename,
7771
+ showLineNumbers = false,
7772
+ hideHeader = false,
7773
+ hideCopyButton = false,
7774
+ className,
7775
+ surface,
7776
+ radius,
7777
+ animated
7778
+ }) {
7779
+ const sf = useSaasflareProps({ surface, radius, animated });
7780
+ const { copy, copied } = useClipboard();
7781
+ const plainText = code ?? "";
7782
+ const lines = useMemo(
7783
+ () => showLineNumbers && code ? code.split("\n") : null,
7784
+ [code, showLineNumbers]
7785
+ );
7786
+ const onCopy = () => {
7787
+ const text = code ?? (highlighted ? highlighted.replace(/<[^>]+>/g, "") : "");
7788
+ copy(text);
7789
+ };
7790
+ const showHeader = !hideHeader && (filename || language);
7791
+ return /* @__PURE__ */ jsxs(
7792
+ "div",
7793
+ {
7794
+ "data-slot": "code-block",
7795
+ "data-surface": sf.surface,
7796
+ "data-radius": sf.radius,
7797
+ "data-animated": String(sf.animated),
7798
+ className: cn(
7799
+ "group relative overflow-hidden rounded-lg border bg-card text-card-foreground",
7800
+ className
7801
+ ),
7802
+ children: [
7803
+ showHeader && /* @__PURE__ */ jsx(
7804
+ "div",
7805
+ {
7806
+ "data-slot": "code-block-header",
7807
+ className: "flex items-center justify-between gap-2 border-b bg-muted/40 px-3 py-1.5 text-xs",
7808
+ children: /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
7809
+ filename && /* @__PURE__ */ jsx(
7810
+ "span",
7811
+ {
7812
+ "data-slot": "code-block-filename",
7813
+ className: "truncate font-mono text-muted-foreground",
7814
+ children: filename
7815
+ }
7816
+ ),
7817
+ language && /* @__PURE__ */ jsx(
7818
+ "span",
7819
+ {
7820
+ "data-slot": "code-block-language",
7821
+ className: "rounded-sm bg-primary/10 px-1.5 py-0.5 font-mono text-[10px] uppercase tracking-wide text-muted-foreground",
7822
+ children: language
7823
+ }
7824
+ )
7825
+ ] })
7826
+ }
7827
+ ),
7828
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
7829
+ !hideCopyButton && /* @__PURE__ */ jsx(
7830
+ "button",
7831
+ {
7832
+ type: "button",
7833
+ "data-slot": "code-block-copy",
7834
+ onClick: onCopy,
7835
+ "aria-label": copied ? "Copied" : "Copy code",
7836
+ className: cn(
7837
+ "absolute right-2 top-2 z-10 inline-flex size-7 items-center justify-center rounded-md border bg-background/80 text-muted-foreground shadow-xs backdrop-blur-sm",
7838
+ "transition-colors hover:text-foreground hover:bg-background",
7839
+ "opacity-0 group-hover:opacity-100 focus-visible:opacity-100",
7840
+ "[&_svg]:size-3.5"
7841
+ ),
7842
+ children: copied ? /* @__PURE__ */ jsx(CheckIcon, {}) : /* @__PURE__ */ jsx(CopyIcon, {})
7843
+ }
7844
+ ),
7845
+ highlighted ? /* @__PURE__ */ jsx(
7846
+ "div",
7847
+ {
7848
+ "data-slot": "code-block-content",
7849
+ className: cn(
7850
+ "overflow-x-auto p-4 text-sm font-mono leading-relaxed",
7851
+ "[&_pre]:!bg-transparent [&_pre]:!p-0 [&_pre]:!m-0"
7852
+ ),
7853
+ dangerouslySetInnerHTML: { __html: highlighted }
7854
+ }
7855
+ ) : lines ? /* @__PURE__ */ jsx(
7856
+ "pre",
7857
+ {
7858
+ "data-slot": "code-block-content",
7859
+ className: "overflow-x-auto p-4 text-sm font-mono leading-relaxed",
7860
+ children: /* @__PURE__ */ jsx("code", { children: lines.map((line, i) => /* @__PURE__ */ jsxs("span", { className: "grid grid-cols-[auto_1fr] gap-3", children: [
7861
+ /* @__PURE__ */ jsx(
7862
+ "span",
7863
+ {
7864
+ "data-slot": "code-block-line-number",
7865
+ "aria-hidden": "true",
7866
+ className: "select-none text-right text-muted-foreground/60 tabular-nums",
7867
+ children: i + 1
7868
+ }
7869
+ ),
7870
+ /* @__PURE__ */ jsx("span", { children: line || "\xA0" })
7871
+ ] }, i)) })
7872
+ }
7873
+ ) : /* @__PURE__ */ jsx(
7874
+ "pre",
7875
+ {
7876
+ "data-slot": "code-block-content",
7877
+ className: "overflow-x-auto p-4 text-sm font-mono leading-relaxed",
7878
+ children: /* @__PURE__ */ jsx("code", { children: plainText })
7879
+ }
7880
+ )
7881
+ ] })
7882
+ ]
7883
+ }
7884
+ );
7885
+ }
7886
+ function BellIcon(props) {
7887
+ return /* @__PURE__ */ jsxs(
7888
+ "svg",
7889
+ {
7890
+ xmlns: "http://www.w3.org/2000/svg",
7891
+ viewBox: "0 0 24 24",
7892
+ fill: "none",
7893
+ stroke: "currentColor",
7894
+ strokeWidth: "2",
7895
+ strokeLinecap: "round",
7896
+ strokeLinejoin: "round",
7897
+ "aria-hidden": "true",
7898
+ ...props,
7899
+ children: [
7900
+ /* @__PURE__ */ jsx("path", { d: "M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9" }),
7901
+ /* @__PURE__ */ jsx("path", { d: "M10.3 21a1.94 1.94 0 0 0 3.4 0" })
7902
+ ]
7903
+ }
7904
+ );
7905
+ }
7906
+ function NotificationCenter({
7907
+ items,
7908
+ title = "Notifications",
7909
+ onItemClick,
7910
+ onMarkRead,
7911
+ onMarkAllRead,
7912
+ emptyState,
7913
+ limit,
7914
+ triggerClassName,
7915
+ contentClassName,
7916
+ surface,
7917
+ radius,
7918
+ animated,
7919
+ iconWeight
7920
+ }) {
7921
+ const sf = useSaasflareProps({ surface, radius, animated, iconWeight });
7922
+ const visible = typeof limit === "number" ? items.slice(0, limit) : items;
7923
+ const unreadCount = items.filter((i) => !i.read).length;
7924
+ return /* @__PURE__ */ jsxs(Popover, { children: [
7925
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
7926
+ Button,
7927
+ {
7928
+ type: "button",
7929
+ variant: "ghost",
7930
+ intent: "neutral",
7931
+ size: "icon",
7932
+ "aria-label": `${title}${unreadCount > 0 ? ` (${unreadCount} unread)` : ""}`,
7933
+ surface: sf.surface,
7934
+ radius: sf.radius,
7935
+ animated: sf.animated,
7936
+ iconWeight: sf.iconWeight,
7937
+ "data-slot": "notification-center-trigger",
7938
+ className: cn("relative", triggerClassName),
7939
+ children: [
7940
+ /* @__PURE__ */ jsx(BellIcon, { className: "size-4" }),
7941
+ unreadCount > 0 && /* @__PURE__ */ jsx(
7942
+ "span",
7943
+ {
7944
+ "data-slot": "notification-center-badge",
7945
+ "aria-hidden": "true",
7946
+ className: "absolute right-1 top-1 inline-flex min-w-4 items-center justify-center rounded-full bg-[oklch(0.62_0.21_25)] px-1 text-[10px] font-semibold leading-none text-white",
7947
+ style: { height: 16 },
7948
+ children: unreadCount > 99 ? "99+" : unreadCount
7949
+ }
7950
+ )
7951
+ ]
7952
+ }
7953
+ ) }),
7954
+ /* @__PURE__ */ jsxs(
7955
+ PopoverContent,
7956
+ {
7957
+ "data-slot": "notification-center-content",
7958
+ align: "end",
7959
+ className: cn("w-80 p-0", contentClassName),
7960
+ children: [
7961
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 border-b px-3 py-2", children: [
7962
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
7963
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold", children: title }),
7964
+ unreadCount > 0 && /* @__PURE__ */ jsx(Badge, { variant: "soft", intent: "primary", size: "sm", children: unreadCount })
7965
+ ] }),
7966
+ onMarkAllRead && unreadCount > 0 && /* @__PURE__ */ jsx(
7967
+ "button",
7968
+ {
7969
+ type: "button",
7970
+ "data-slot": "notification-center-mark-all",
7971
+ onClick: onMarkAllRead,
7972
+ className: "text-xs text-muted-foreground transition-colors hover:text-foreground",
7973
+ children: "Mark all as read"
7974
+ }
7975
+ )
7976
+ ] }),
7977
+ /* @__PURE__ */ jsx(
7978
+ "div",
7979
+ {
7980
+ "data-slot": "notification-center-list",
7981
+ className: "max-h-96 overflow-y-auto",
7982
+ children: visible.length === 0 ? /* @__PURE__ */ jsx(
7983
+ "div",
7984
+ {
7985
+ "data-slot": "notification-center-empty",
7986
+ className: "px-4 py-8 text-center text-sm text-muted-foreground",
7987
+ children: emptyState ?? "You're all caught up."
7988
+ }
7989
+ ) : visible.map((item) => {
7990
+ const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
7991
+ !item.read && /* @__PURE__ */ jsx(
7992
+ "span",
7993
+ {
7994
+ "aria-hidden": "true",
7995
+ className: "mt-1.5 size-1.5 shrink-0 rounded-full bg-primary"
7996
+ }
7997
+ ),
7998
+ item.icon !== void 0 && /* @__PURE__ */ jsx("span", { className: "mt-0.5 flex shrink-0 items-center [&_svg]:size-4 text-muted-foreground", children: item.icon }),
7999
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
8000
+ /* @__PURE__ */ jsx("p", { className: "truncate text-sm font-medium text-foreground", children: item.title }),
8001
+ item.description !== void 0 && /* @__PURE__ */ jsx("p", { className: "line-clamp-2 text-xs text-muted-foreground", children: item.description }),
8002
+ item.timestamp && /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-[10px] uppercase tracking-wider text-muted-foreground/70", children: item.timestamp })
8003
+ ] }),
8004
+ !item.read && onMarkRead && /* @__PURE__ */ jsx(
8005
+ "button",
8006
+ {
8007
+ type: "button",
8008
+ "data-slot": "notification-center-mark",
8009
+ onClick: (e) => {
8010
+ e.preventDefault();
8011
+ e.stopPropagation();
8012
+ onMarkRead(item.id);
8013
+ },
8014
+ "aria-label": "Mark as read",
8015
+ className: "shrink-0 text-[10px] text-muted-foreground transition-colors hover:text-foreground",
8016
+ children: "\u2713"
8017
+ }
8018
+ )
8019
+ ] });
8020
+ const rowClass = cn(
8021
+ "flex items-start gap-2 border-b px-3 py-2.5 last:border-b-0",
8022
+ "transition-colors hover:bg-accent/40",
8023
+ !item.read && "bg-primary/5"
8024
+ );
8025
+ const onClick = () => onItemClick?.(item);
8026
+ return item.href ? /* @__PURE__ */ jsx(
8027
+ "a",
8028
+ {
8029
+ href: item.href,
8030
+ "data-slot": "notification-center-item",
8031
+ "data-read": String(!!item.read),
8032
+ onClick,
8033
+ className: rowClass,
8034
+ children: inner
8035
+ },
8036
+ item.id
8037
+ ) : /* @__PURE__ */ jsx(
8038
+ "button",
8039
+ {
8040
+ type: "button",
8041
+ "data-slot": "notification-center-item",
8042
+ "data-read": String(!!item.read),
8043
+ onClick,
8044
+ className: cn(rowClass, "w-full text-left"),
8045
+ children: inner
8046
+ },
8047
+ item.id
8048
+ );
8049
+ })
8050
+ }
8051
+ )
8052
+ ]
8053
+ }
8054
+ )
8055
+ ] });
8056
+ }
8057
+ function EmptyState({
8058
+ icon,
8059
+ title,
8060
+ description,
8061
+ action,
8062
+ className,
8063
+ surface,
8064
+ radius,
8065
+ animated,
8066
+ ...props
8067
+ }) {
8068
+ const sf = useSaasflareProps({ surface, radius, animated });
8069
+ return /* @__PURE__ */ jsxs(
8070
+ "div",
8071
+ {
8072
+ ...props,
8073
+ "data-slot": "empty-state",
8074
+ "data-surface": sf.surface,
8075
+ "data-radius": sf.radius,
8076
+ "data-animated": String(sf.animated),
8077
+ className: cn(
8078
+ "flex flex-col items-center justify-center gap-4 py-12 text-center",
8079
+ className
8080
+ ),
8081
+ children: [
8082
+ icon && /* @__PURE__ */ jsx("div", { className: "text-muted-foreground [&_svg]:size-12", children: icon }),
8083
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
8084
+ /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold", children: title }),
8085
+ description && /* @__PURE__ */ jsx("p", { className: "max-w-sm text-sm text-muted-foreground", children: description })
8086
+ ] }),
8087
+ action && /* @__PURE__ */ jsx("div", { className: "mt-2", children: action })
8088
+ ]
8089
+ }
8090
+ );
8091
+ }
8092
+ function SearchField({
8093
+ className,
8094
+ loading = false,
8095
+ onClear,
8096
+ value,
8097
+ surface,
8098
+ radius,
8099
+ animated,
8100
+ iconWeight,
8101
+ ...props
8102
+ }) {
8103
+ const sf = useSaasflareProps({ surface, radius, animated, iconWeight });
8104
+ const hasValue = typeof value === "string" ? value.length > 0 : false;
8105
+ return /* @__PURE__ */ jsxs(
8106
+ "div",
8107
+ {
8108
+ "data-slot": "search-field",
8109
+ "data-surface": sf.surface,
8110
+ "data-radius": sf.radius,
8111
+ "data-animated": String(sf.animated),
8112
+ className: cn("relative", className),
8113
+ children: [
8114
+ /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground", children: loading ? /* @__PURE__ */ jsx(CircleNotchIcon, { className: "size-4 animate-spin", "aria-hidden": "true" }) : /* @__PURE__ */ jsx(MagnifyingGlassIcon, { weight: sf.iconWeight, className: "size-4", "aria-hidden": "true" }) }),
8115
+ /* @__PURE__ */ jsx(
8116
+ "input",
8117
+ {
8118
+ type: "search",
8119
+ "data-slot": "search-field-input",
8120
+ className: "h-9 w-full rounded-md border border-input bg-background pl-9 pr-9 text-sm outline-none transition-colors placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50",
8121
+ value,
8122
+ ...props
8123
+ }
8124
+ ),
8125
+ hasValue && onClear && /* @__PURE__ */ jsx(
8126
+ "button",
8127
+ {
8128
+ type: "button",
8129
+ "data-slot": "search-field-clear",
8130
+ onClick: onClear,
8131
+ className: "absolute right-2 top-1/2 -translate-y-1/2 rounded-sm p-0.5 text-muted-foreground transition-colors hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring",
8132
+ "aria-label": "Clear search",
8133
+ children: /* @__PURE__ */ jsx(XIcon, { weight: sf.iconWeight, className: "size-3.5" })
8134
+ }
8135
+ )
8136
+ ]
8137
+ }
8138
+ );
8139
+ }
8140
+ function SettingsSection({
8141
+ label,
8142
+ description,
8143
+ className,
8144
+ children,
8145
+ surface,
8146
+ radius,
8147
+ animated,
8148
+ ...props
8149
+ }) {
8150
+ const sf = useSaasflareProps({ surface, radius, animated });
8151
+ return /* @__PURE__ */ jsxs(
8152
+ "div",
8153
+ {
8154
+ ...props,
8155
+ "data-slot": "settings-section",
8156
+ "data-surface": sf.surface,
8157
+ "data-radius": sf.radius,
8158
+ "data-animated": String(sf.animated),
8159
+ className: cn(
8160
+ "flex flex-col gap-3 py-4 sm:flex-row sm:items-center sm:justify-between sm:gap-6",
8161
+ className
8162
+ ),
8163
+ children: [
8164
+ /* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
8165
+ /* @__PURE__ */ jsx("div", { className: "text-sm font-medium", children: label }),
8166
+ description && /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: description })
8167
+ ] }),
8168
+ /* @__PURE__ */ jsx("div", { className: "shrink-0", children })
8169
+ ]
8170
+ }
8171
+ );
8172
+ }
8173
+ function PricingCard({
8174
+ name,
8175
+ price,
8176
+ period,
8177
+ description,
8178
+ features,
8179
+ cta,
8180
+ featured = false,
8181
+ className,
8182
+ surface,
8183
+ radius,
8184
+ animated,
8185
+ iconWeight,
8186
+ ...props
8187
+ }) {
8188
+ const sf = useSaasflareProps({ surface, radius, animated, iconWeight });
8189
+ return /* @__PURE__ */ jsxs(
8190
+ "div",
8191
+ {
8192
+ ...props,
8193
+ "data-slot": "pricing-card",
8194
+ "data-surface": sf.surface,
8195
+ "data-radius": sf.radius,
8196
+ "data-animated": String(sf.animated),
8197
+ className: cn(
8198
+ "relative flex flex-col rounded-xl border bg-card p-6 text-card-foreground shadow-sm",
8199
+ featured && "border-primary shadow-md ring-1 ring-primary/20",
8200
+ className
8201
+ ),
8202
+ children: [
8203
+ featured && /* @__PURE__ */ jsx("div", { className: "absolute -top-3 left-1/2 -translate-x-1/2 rounded-full bg-primary px-3 py-0.5 text-xs font-medium text-primary-foreground", children: "Recommended" }),
8204
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
8205
+ /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold", children: name }),
8206
+ description && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: description })
8207
+ ] }),
8208
+ /* @__PURE__ */ jsxs("div", { className: "mt-4 flex items-baseline gap-1", children: [
8209
+ /* @__PURE__ */ jsx("span", { className: "text-3xl font-bold tracking-tight", children: price }),
8210
+ period && /* @__PURE__ */ jsxs("span", { className: "text-sm text-muted-foreground", children: [
8211
+ "/",
8212
+ period
8213
+ ] })
8214
+ ] }),
8215
+ /* @__PURE__ */ jsx("ul", { className: "mt-6 space-y-2.5", role: "list", children: features.map((feature) => /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-2 text-sm", children: [
8216
+ /* @__PURE__ */ jsx(CheckIcon, { weight: sf.iconWeight, className: "mt-0.5 size-4 shrink-0 text-success", "aria-hidden": "true" }),
8217
+ /* @__PURE__ */ jsx("span", { children: feature })
8218
+ ] }, feature)) }),
8219
+ cta && /* @__PURE__ */ jsx("div", { className: "mt-6", children: cta })
8220
+ ]
8221
+ }
8222
+ );
8223
+ }
8224
+ function DataToolbar({ className, surface, radius, animated, ...props }) {
8225
+ const sf = useSaasflareProps({ surface, radius, animated });
8226
+ return /* @__PURE__ */ jsx(
8227
+ "div",
8228
+ {
8229
+ ...props,
8230
+ "data-slot": "data-toolbar",
8231
+ "data-surface": sf.surface,
8232
+ "data-radius": sf.radius,
8233
+ "data-animated": String(sf.animated),
8234
+ className: cn(
6341
8235
  "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",
6342
8236
  className
6343
8237
  )
@@ -6374,6 +8268,68 @@ function DataToolbarActions({ className, ...props }) {
6374
8268
  }
6375
8269
  );
6376
8270
  }
8271
+ var DEFAULT_COLORS = [
8272
+ "hsl(28 90% 75%)",
8273
+ // peach (top-left)
8274
+ "hsl(220 85% 65%)",
8275
+ // blue (right)
8276
+ "hsl(280 70% 75%)"
8277
+ // violet (bottom-left)
8278
+ ];
8279
+ function AuroraBackground({
8280
+ colors = DEFAULT_COLORS,
8281
+ intensity = 0.55,
8282
+ className,
8283
+ children,
8284
+ surface,
8285
+ radius,
8286
+ animated,
8287
+ ...props
8288
+ }) {
8289
+ const sf = useSaasflareProps({ surface, radius, animated });
8290
+ const blobStyle = (color) => ({
8291
+ background: `radial-gradient(circle, ${color} 0%, transparent 65%)`,
8292
+ opacity: intensity
8293
+ });
8294
+ return /* @__PURE__ */ jsxs(
8295
+ "div",
8296
+ {
8297
+ ...props,
8298
+ "data-slot": "aurora-background",
8299
+ "data-surface": sf.surface,
8300
+ "data-radius": sf.radius,
8301
+ "data-animated": String(sf.animated),
8302
+ className: cn("relative isolate overflow-hidden", className),
8303
+ children: [
8304
+ /* @__PURE__ */ jsx(
8305
+ "div",
8306
+ {
8307
+ "aria-hidden": "true",
8308
+ className: "aurora-blob aurora-blob-1 pointer-events-none absolute -top-1/4 -left-1/4 size-[55%] rounded-full blur-3xl dark:opacity-50",
8309
+ style: blobStyle(colors[0])
8310
+ }
8311
+ ),
8312
+ /* @__PURE__ */ jsx(
8313
+ "div",
8314
+ {
8315
+ "aria-hidden": "true",
8316
+ className: "aurora-blob aurora-blob-2 pointer-events-none absolute top-0 -right-1/4 h-full w-[55%] rounded-full blur-3xl dark:opacity-50",
8317
+ style: blobStyle(colors[1])
8318
+ }
8319
+ ),
8320
+ /* @__PURE__ */ jsx(
8321
+ "div",
8322
+ {
8323
+ "aria-hidden": "true",
8324
+ className: "aurora-blob aurora-blob-3 pointer-events-none absolute -bottom-1/4 -left-1/4 size-[50%] rounded-full blur-3xl dark:opacity-50",
8325
+ style: blobStyle(colors[2])
8326
+ }
8327
+ ),
8328
+ /* @__PURE__ */ jsx("div", { className: "relative z-10", children })
8329
+ ]
8330
+ }
8331
+ );
8332
+ }
6377
8333
 
6378
8334
  // src/types/theme-props.ts
6379
8335
  var PALETTES = [
@@ -6394,11 +8350,14 @@ var PALETTES = [
6394
8350
  { id: "honey", name: "Honey" },
6395
8351
  { id: "teal", name: "Teal" },
6396
8352
  { id: "iris", name: "Iris" },
6397
- { id: "ruby", name: "Ruby" }
8353
+ { id: "ruby", name: "Ruby" },
8354
+ { id: "colorful", name: "Colorful" },
8355
+ { id: "craivo", name: "Craivo" }
6398
8356
  ];
6399
8357
  var STYLES = [
6400
8358
  { id: "flat", name: "Flat" },
6401
- { id: "glass", name: "Glass" }
8359
+ { id: "glass", name: "Glass" },
8360
+ { id: "clay", name: "Clay" }
6402
8361
  ];
6403
8362
  var RADII = [
6404
8363
  { id: "sharp", name: "Sharp" },
@@ -6412,8 +8371,8 @@ function ScrollToTopButton({
6412
8371
  className,
6413
8372
  ...sfProps
6414
8373
  }) {
6415
- const { animated, surface } = useSaasflareProps(sfProps);
6416
- const [isVisible, setIsVisible] = useState(false);
8374
+ const { animated, surface, iconWeight } = useSaasflareProps(sfProps);
8375
+ const [isVisible2, setIsVisible] = useState(false);
6417
8376
  const finalId = useMemo(() => scrollContainerId ?? null, [scrollContainerId]);
6418
8377
  const getContainer = useCallback(() => {
6419
8378
  if (finalId) {
@@ -6443,9 +8402,9 @@ function ScrollToTopButton({
6443
8402
  container.scrollTo({ top: 0, behavior });
6444
8403
  }
6445
8404
  };
6446
- const surfaceClass = surface === "glass" ? "bg-primary/85 text-primary-foreground backdrop-blur-md border border-[oklch(1_0_0_/_0.15)] shadow-[var(--surface-shadow)]" : "bg-primary text-primary-foreground shadow-lg";
8405
+ const surfaceClass = surface === "glass" ? "bg-primary/85 text-primary-foreground backdrop-blur-md border border-[oklch(1_0_0_/_0.15)] shadow-[var(--surface-shadow)]" : surface === "clay" ? "bg-primary text-primary-foreground border-0 shadow-[var(--surface-shadow)] active:translate-y-px" : "bg-primary text-primary-foreground shadow-lg";
6447
8406
  const duration = animated ? 0.3 : 0;
6448
- return /* @__PURE__ */ jsx(AnimatePresence, { children: isVisible && /* @__PURE__ */ jsx(
8407
+ return /* @__PURE__ */ jsx(AnimatePresence, { children: isVisible2 && /* @__PURE__ */ jsx(
6449
8408
  m.button,
6450
8409
  {
6451
8410
  onClick: scrollToTop,
@@ -6459,25 +8418,170 @@ function ScrollToTopButton({
6459
8418
  surfaceClass,
6460
8419
  className
6461
8420
  ),
6462
- children: /* @__PURE__ */ jsx(ArrowUpIcon, { className: "h-5 w-5" })
8421
+ children: /* @__PURE__ */ jsx(ArrowUpIcon, { weight: iconWeight, className: "h-5 w-5" })
6463
8422
  }
6464
8423
  ) });
6465
8424
  }
8425
+ function StatefulButton({
8426
+ loading = false,
8427
+ loadingText,
8428
+ disabled,
8429
+ children,
8430
+ ...rest
8431
+ }) {
8432
+ const label = loading && loadingText !== void 0 ? loadingText : children;
8433
+ return /* @__PURE__ */ jsxs(
8434
+ Button,
8435
+ {
8436
+ ...rest,
8437
+ disabled: disabled || loading,
8438
+ "aria-busy": loading || void 0,
8439
+ children: [
8440
+ loading && /* @__PURE__ */ jsx(CircleNotchIcon, { className: "animate-spin", "aria-hidden": "true" }),
8441
+ label
8442
+ ]
8443
+ }
8444
+ );
8445
+ }
8446
+ var PROVIDERS = [
8447
+ "google",
8448
+ "github",
8449
+ "apple",
8450
+ "microsoft",
8451
+ "x",
8452
+ "discord",
8453
+ "facebook",
8454
+ "linkedin",
8455
+ "medium",
8456
+ "slack",
8457
+ "reddit",
8458
+ "paypal",
8459
+ "stripe",
8460
+ "gitlab",
8461
+ "dribbble",
8462
+ "tiktok"
8463
+ ];
8464
+ var PROVIDER_LABELS = {
8465
+ google: "Google",
8466
+ github: "GitHub",
8467
+ apple: "Apple",
8468
+ microsoft: "Microsoft",
8469
+ x: "X",
8470
+ discord: "Discord",
8471
+ facebook: "Facebook",
8472
+ linkedin: "LinkedIn",
8473
+ medium: "Medium",
8474
+ slack: "Slack",
8475
+ reddit: "Reddit",
8476
+ paypal: "PayPal",
8477
+ stripe: "Stripe",
8478
+ gitlab: "GitLab",
8479
+ dribbble: "Dribbble",
8480
+ tiktok: "TikTok"
8481
+ };
8482
+ var PROVIDER_ICONS = {
8483
+ google: GoogleLogoIcon,
8484
+ github: GithubLogoIcon,
8485
+ apple: AppleLogoIcon,
8486
+ microsoft: MicrosoftOutlookLogoIcon,
8487
+ x: XLogoIcon,
8488
+ discord: DiscordLogoIcon,
8489
+ facebook: FacebookLogoIcon,
8490
+ linkedin: LinkedinLogoIcon,
8491
+ medium: MediumLogoIcon,
8492
+ slack: SlackLogoIcon,
8493
+ reddit: RedditLogoIcon,
8494
+ paypal: PaypalLogoIcon,
8495
+ stripe: StripeLogoIcon,
8496
+ gitlab: GitlabLogoIcon,
8497
+ dribbble: DribbbleLogoIcon,
8498
+ tiktok: TiktokLogoIcon
8499
+ };
8500
+ function SocialAuthButton({
8501
+ provider,
8502
+ label,
8503
+ variant = "outline",
8504
+ intent = "neutral",
8505
+ fullWidth = false,
8506
+ surface,
8507
+ radius,
8508
+ animated,
8509
+ iconWeight,
8510
+ children,
8511
+ ...rest
8512
+ }) {
8513
+ const isColorful = iconWeight === "colorful";
8514
+ const sf = useSaasflareProps({
8515
+ surface,
8516
+ radius,
8517
+ animated,
8518
+ iconWeight: isColorful ? void 0 : iconWeight
8519
+ });
8520
+ const hasChildren = children !== void 0 && children !== null && children !== "";
8521
+ const text = hasChildren ? children : label ?? `Continue with ${PROVIDER_LABELS[provider]}`;
8522
+ const Icon2 = PROVIDER_ICONS[provider];
8523
+ const resolvedWeight = isColorful ? "colorful" : sf.iconWeight;
8524
+ return /* @__PURE__ */ jsxs(
8525
+ StatefulButton,
8526
+ {
8527
+ "data-provider": provider,
8528
+ "data-icon-weight": resolvedWeight,
8529
+ variant,
8530
+ intent,
8531
+ fullWidth,
8532
+ surface: sf.surface,
8533
+ radius: sf.radius,
8534
+ animated: sf.animated,
8535
+ iconWeight: sf.iconWeight,
8536
+ ...rest,
8537
+ children: [
8538
+ /* @__PURE__ */ jsx(Icon2, { weight: resolvedWeight, className: "size-4" }),
8539
+ text
8540
+ ]
8541
+ }
8542
+ );
8543
+ }
8544
+ var GoogleAuthButton = (props) => /* @__PURE__ */ jsx(SocialAuthButton, { provider: "google", ...props });
8545
+ var GitHubAuthButton = (props) => /* @__PURE__ */ jsx(SocialAuthButton, { provider: "github", ...props });
8546
+ var AppleAuthButton = (props) => /* @__PURE__ */ jsx(SocialAuthButton, { provider: "apple", ...props });
8547
+ var MicrosoftAuthButton = (props) => /* @__PURE__ */ jsx(SocialAuthButton, { provider: "microsoft", ...props });
8548
+ var XAuthButton = (props) => /* @__PURE__ */ jsx(SocialAuthButton, { provider: "x", ...props });
8549
+ var DiscordAuthButton = (props) => /* @__PURE__ */ jsx(SocialAuthButton, { provider: "discord", ...props });
8550
+ var FacebookAuthButton = (props) => /* @__PURE__ */ jsx(SocialAuthButton, { provider: "facebook", ...props });
8551
+ var LinkedInAuthButton = (props) => /* @__PURE__ */ jsx(SocialAuthButton, { provider: "linkedin", ...props });
8552
+ var MediumAuthButton = (props) => /* @__PURE__ */ jsx(SocialAuthButton, { provider: "medium", ...props });
8553
+ var SlackAuthButton = (props) => /* @__PURE__ */ jsx(SocialAuthButton, { provider: "slack", ...props });
8554
+ var RedditAuthButton = (props) => /* @__PURE__ */ jsx(SocialAuthButton, { provider: "reddit", ...props });
8555
+ var PayPalAuthButton = (props) => /* @__PURE__ */ jsx(SocialAuthButton, { provider: "paypal", ...props });
8556
+ var StripeAuthButton = (props) => /* @__PURE__ */ jsx(SocialAuthButton, { provider: "stripe", ...props });
8557
+ var GitLabAuthButton = (props) => /* @__PURE__ */ jsx(SocialAuthButton, { provider: "gitlab", ...props });
8558
+ var DribbbleAuthButton = (props) => /* @__PURE__ */ jsx(SocialAuthButton, { provider: "dribbble", ...props });
8559
+ var TikTokAuthButton = (props) => /* @__PURE__ */ jsx(SocialAuthButton, { provider: "tiktok", ...props });
6466
8560
  function ThemeModeToggle({
6467
8561
  showText = false,
6468
- text,
6469
- className
8562
+ textLight = "Switch to Dark Mode",
8563
+ textDark = "Switch to Light Mode",
8564
+ className,
8565
+ surface,
8566
+ radius,
8567
+ animated,
8568
+ iconWeight,
8569
+ initialResolvedTheme
6470
8570
  }) {
6471
- const { theme, setTheme } = useTheme();
8571
+ const { setTheme, resolvedTheme } = useTheme();
8572
+ const sf = useSaasflareProps({ surface, radius, animated, iconWeight });
6472
8573
  const [mounted, setMounted] = React5.useState(false);
6473
8574
  React5.useEffect(() => {
6474
8575
  setMounted(true);
6475
8576
  }, []);
6476
- if (!mounted) {
8577
+ if (initialResolvedTheme === void 0 && !mounted) {
6477
8578
  return null;
6478
8579
  }
8580
+ const effectiveResolved = resolvedTheme ?? initialResolvedTheme;
8581
+ const isDark = effectiveResolved === "dark";
8582
+ const label = isDark ? textDark : textLight;
6479
8583
  const toggleTheme = () => {
6480
- setTheme(theme === "dark" ? "light" : "dark");
8584
+ setTheme(isDark ? "light" : "dark");
6481
8585
  };
6482
8586
  return /* @__PURE__ */ jsxs(
6483
8587
  Button,
@@ -6487,10 +8591,193 @@ function ThemeModeToggle({
6487
8591
  size: showText ? "sm" : "icon",
6488
8592
  className: cn("cursor-pointer", className),
6489
8593
  onClick: toggleTheme,
8594
+ "aria-label": label,
8595
+ children: [
8596
+ isDark ? /* @__PURE__ */ jsx(
8597
+ SunIcon,
8598
+ {
8599
+ weight: sf.iconWeight,
8600
+ "aria-hidden": "true",
8601
+ className: "h-[1.2rem] w-[1.2rem]"
8602
+ }
8603
+ ) : /* @__PURE__ */ jsx(
8604
+ MoonIcon,
8605
+ {
8606
+ weight: sf.iconWeight,
8607
+ "aria-hidden": "true",
8608
+ className: "h-[1.2rem] w-[1.2rem]"
8609
+ }
8610
+ ),
8611
+ showText && /* @__PURE__ */ jsx("span", { className: "font-normal", children: label })
8612
+ ]
8613
+ }
8614
+ );
8615
+ }
8616
+ var DEFAULT_LABELS = {
8617
+ light: "Light mode",
8618
+ dark: "Dark mode",
8619
+ system: "System mode"
8620
+ };
8621
+ var RADIUS_CLASS = {
8622
+ sharp: "rounded-none",
8623
+ soft: "rounded-md",
8624
+ rounded: "rounded-lg",
8625
+ pill: "rounded-full"
8626
+ };
8627
+ var RADIUS_LEFT_CLASS = {
8628
+ sharp: "first:rounded-l-none",
8629
+ soft: "first:rounded-l-md",
8630
+ rounded: "first:rounded-l-lg",
8631
+ pill: "first:rounded-l-full"
8632
+ };
8633
+ var RADIUS_RIGHT_CLASS = {
8634
+ sharp: "last:rounded-r-none",
8635
+ soft: "last:rounded-r-md",
8636
+ rounded: "last:rounded-r-lg",
8637
+ pill: "last:rounded-r-full"
8638
+ };
8639
+ function ThemeModeMultiToggle({
8640
+ labels,
8641
+ className,
8642
+ size = "default",
8643
+ appearance = "icon",
8644
+ surface,
8645
+ radius,
8646
+ animated,
8647
+ iconWeight,
8648
+ initialMode
8649
+ }) {
8650
+ const { theme, setTheme, resolvedTheme } = useTheme();
8651
+ const sf = useSaasflareProps({ surface, animated, iconWeight });
8652
+ const [mounted, setMounted] = React5.useState(false);
8653
+ React5.useEffect(() => {
8654
+ setMounted(true);
8655
+ }, []);
8656
+ if (initialMode === void 0 && !mounted) {
8657
+ return null;
8658
+ }
8659
+ const resolvedRadius = radius ?? "pill";
8660
+ const resolved = theme === "light" || theme === "dark" || theme === "system" ? theme : initialMode ?? "system";
8661
+ const dataResolvedTheme = resolvedTheme ?? (initialMode === "dark" || initialMode === "light" ? initialMode : void 0);
8662
+ const baseLabel = (mode) => labels?.[mode] ?? DEFAULT_LABELS[mode];
8663
+ const segmentLabel = (mode) => {
8664
+ const base = baseLabel(mode);
8665
+ if (mode === "system" && dataResolvedTheme && dataResolvedTheme !== "system") {
8666
+ return `${base} (currently ${dataResolvedTheme})`;
8667
+ }
8668
+ return base;
8669
+ };
8670
+ return /* @__PURE__ */ jsxs(
8671
+ ToggleGroup,
8672
+ {
8673
+ type: "single",
8674
+ value: resolved,
8675
+ onValueChange: (next) => {
8676
+ if (next === "light" || next === "dark" || next === "system") {
8677
+ setTheme(next);
8678
+ }
8679
+ },
8680
+ "data-slot": "theme-mode-multi-toggle",
8681
+ "data-surface": sf.surface,
8682
+ "data-radius": resolvedRadius,
8683
+ "data-animated": String(sf.animated),
8684
+ "data-appearance": appearance,
8685
+ "data-resolved-theme": dataResolvedTheme,
8686
+ suppressHydrationWarning: true,
8687
+ className: cn(
8688
+ "inline-flex items-center bg-muted",
8689
+ RADIUS_CLASS[resolvedRadius],
8690
+ appearance === "button" ? "gap-0 p-0" : "gap-1 p-1",
8691
+ className
8692
+ ),
8693
+ children: [
8694
+ /* @__PURE__ */ jsx(
8695
+ ThemeModeSegment,
8696
+ {
8697
+ mode: "light",
8698
+ size,
8699
+ appearance,
8700
+ radius: resolvedRadius,
8701
+ label: segmentLabel("light"),
8702
+ children: /* @__PURE__ */ jsx(SunIcon, { weight: sf.iconWeight, "aria-hidden": "true" })
8703
+ }
8704
+ ),
8705
+ /* @__PURE__ */ jsx(
8706
+ ThemeModeSegment,
8707
+ {
8708
+ mode: "dark",
8709
+ size,
8710
+ appearance,
8711
+ radius: resolvedRadius,
8712
+ label: segmentLabel("dark"),
8713
+ children: /* @__PURE__ */ jsx(MoonIcon, { weight: sf.iconWeight, "aria-hidden": "true" })
8714
+ }
8715
+ ),
8716
+ /* @__PURE__ */ jsx(
8717
+ ThemeModeSegment,
8718
+ {
8719
+ mode: "system",
8720
+ size,
8721
+ appearance,
8722
+ radius: resolvedRadius,
8723
+ label: segmentLabel("system"),
8724
+ children: /* @__PURE__ */ jsx(MonitorIcon, { weight: sf.iconWeight, "aria-hidden": "true" })
8725
+ }
8726
+ )
8727
+ ]
8728
+ }
8729
+ );
8730
+ }
8731
+ function ThemeModeSegment({
8732
+ mode,
8733
+ size,
8734
+ appearance,
8735
+ radius,
8736
+ label,
8737
+ children
8738
+ }) {
8739
+ const stateClasses = cn(
8740
+ "relative cursor-pointer text-muted-foreground transition-all",
8741
+ "hover:bg-transparent hover:text-foreground",
8742
+ "data-[state=on]:z-10 data-[state=on]:bg-background data-[state=on]:text-foreground",
8743
+ "data-[state=on]:scale-110 data-[state=on]:shadow-md",
8744
+ "data-[state=on]:ring-1 data-[state=on]:ring-border",
8745
+ "data-[state=on]:[&_svg]:scale-110"
8746
+ );
8747
+ if (appearance === "button") {
8748
+ const sizeClass2 = size === "sm" ? "h-7 px-3 [&_svg:not([class*='size-'])]:size-3.5" : size === "lg" ? "h-10 px-5 [&_svg:not([class*='size-'])]:size-5" : "h-8 px-4 [&_svg:not([class*='size-'])]:size-4";
8749
+ return /* @__PURE__ */ jsxs(
8750
+ ToggleGroupItem,
8751
+ {
8752
+ value: mode,
8753
+ "aria-label": label,
8754
+ title: label,
8755
+ className: cn(
8756
+ stateClasses,
8757
+ "rounded-none p-0 flex-1 min-w-0",
8758
+ RADIUS_LEFT_CLASS[radius],
8759
+ RADIUS_RIGHT_CLASS[radius],
8760
+ sizeClass2
8761
+ ),
8762
+ children: [
8763
+ children,
8764
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: label })
8765
+ ]
8766
+ }
8767
+ );
8768
+ }
8769
+ const iconRadiusClass = appearance === "icon-inherit" ? RADIUS_CLASS[radius] : "rounded-full";
8770
+ const sizeClass = size === "sm" ? "size-7 [&_svg:not([class*='size-'])]:size-3.5" : size === "lg" ? "size-10 [&_svg:not([class*='size-'])]:size-5" : "size-8 [&_svg:not([class*='size-'])]:size-4";
8771
+ return /* @__PURE__ */ jsxs(
8772
+ ToggleGroupItem,
8773
+ {
8774
+ value: mode,
8775
+ "aria-label": label,
8776
+ title: label,
8777
+ className: cn(stateClasses, "p-0", iconRadiusClass, sizeClass),
6490
8778
  children: [
6491
- /* @__PURE__ */ jsx(Sun, { className: "h-[1.2rem] w-[1.2rem] hidden dark:block" }),
6492
- /* @__PURE__ */ jsx(Moon, { className: "h-[1.2rem] w-[1.2rem] dark:hidden" }),
6493
- /* @__PURE__ */ jsx("span", { className: cn(!showText && "sr-only", "font-normal"), children: text ?? (theme === "dark" ? "Switch to Light Mode" : "Switch to Dark Mode") })
8779
+ children,
8780
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: label })
6494
8781
  ]
6495
8782
  }
6496
8783
  );
@@ -6634,4 +8921,4 @@ function UserAvatar({ src, name, initials, size = "md", className }) {
6634
8921
  ] });
6635
8922
  }
6636
8923
 
6637
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AnimatedTooltip, AspectRatio, Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage, Badge, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, Combobox, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxList, ComboboxSeparator, ComboboxTrigger, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, DataToolbar, DataToolbarActions, DataToolbarFilters, DataToolbarSearch, DirectionProvider2 as DirectionProvider, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyState, EmptyTitle, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, HoverCard, HoverCardContent, HoverCardTrigger, Icons, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, Item9 as Item, ItemActions, ItemContent, ItemDescription, ItemFooter, ItemGroup, ItemHeader, ItemMedia, ItemSeparator, ItemTitle, Kbd, KbdGroup, Label5 as Label, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, MetricCard, NativeSelect, NativeSelectOptGroup, NativeSelectOption, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, PALETTES, PageHeader, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PricingCard, Progress, RADII, RadioGroup4 as RadioGroup, RadioGroupItem, STYLES, ScrollArea, ScrollBar, ScrollToTopButton, SearchField, SectionCard, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator5 as Separator, SettingsSection, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, Slider, Spinner, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemeModeToggle, Toaster3 as Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopLoadingBar, TypewriterText, UserAvatar, badgeVariants, buttonGroupVariants, navigationMenuTriggerStyle, toggleVariants, useDirection2 as useDirection, useDisclosure, useFormField, useIsMobile, useMeasure, usePagination, useSidebar };
8924
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AnimatedTooltip, AppleAuthButton, AspectRatio, AuroraBackground, Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage, Badge, BarList, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, Callout, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CategoryBar, Checkbox, CodeBlock, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, Combobox, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxList, ComboboxSeparator, ComboboxTrigger, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, DataToolbar, DataToolbarActions, DataToolbarFilters, DataToolbarSearch, DatePicker, DateRangePicker, DirectionProvider2 as DirectionProvider, DiscordAuthButton, DribbbleAuthButton, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Dropzone, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyState, EmptyTitle, FacebookAuthButton, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, GitHubAuthButton, GitLabAuthButton, GoogleAuthButton, HoverCard, HoverCardContent, HoverCardTrigger, Icons, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, Item9 as Item, ItemActions, ItemContent, ItemDescription, ItemFooter, ItemGroup, ItemHeader, ItemMedia, ItemSeparator, ItemTitle, Kbd, KbdGroup, Label5 as Label, LinkedInAuthButton, MediumAuthButton, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, MetricCard, MicrosoftAuthButton, NativeSelect, NativeSelectOptGroup, NativeSelectOption, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, NotificationCenter, NumberInput, PALETTES, PageHeader, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PayPalAuthButton, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PricingCard, Progress, ProgressCircle, RADII, RadioGroup4 as RadioGroup, RadioGroupItem, Rating, RedditAuthButton, PROVIDERS as SOCIAL_AUTH_PROVIDERS, STYLES, ScrollArea, ScrollBar, ScrollToTopButton, SearchField, SectionCard, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator5 as Separator, SettingsSection, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, SlackAuthButton, Slider, SocialAuthButton, SparkChart, Spinner, StatefulButton, StripeAuthButton, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, TagInput, Textarea, ThemeModeMultiToggle, ThemeModeToggle, TikTokAuthButton, Toaster3 as Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopLoadingBar, Tracker, TreeView, TypewriterText, UserAvatar, XAuthButton, badgeVariants, buttonGroupVariants, navigationMenuTriggerStyle, toggleVariants, useDirection2 as useDirection, useDisclosure, useFileDialog, useFocusTrap, useFormField, useInterval, useIsMobile, useMeasure, useMergedRef, usePagination, useSidebar };