@autumnsgrove/groveengine 0.6.5 → 0.8.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 (183) hide show
  1. package/LICENSE +378 -0
  2. package/dist/auth/index.d.ts +1 -2
  3. package/dist/auth/index.js +8 -4
  4. package/dist/auth/session.d.ts +12 -31
  5. package/dist/auth/session.js +5 -103
  6. package/dist/components/custom/ContentWithGutter.svelte +22 -25
  7. package/dist/ui/components/content/RoadmapPreview.svelte +91 -0
  8. package/dist/ui/components/content/RoadmapPreview.svelte.d.ts +36 -0
  9. package/dist/ui/components/content/index.d.ts +1 -0
  10. package/dist/ui/components/content/index.js +1 -0
  11. package/dist/ui/components/nature/Logo.svelte +224 -0
  12. package/dist/ui/components/nature/Logo.svelte.d.ts +14 -0
  13. package/dist/ui/components/nature/botanical/Acorn.svelte +48 -0
  14. package/dist/ui/components/nature/botanical/Acorn.svelte.d.ts +8 -0
  15. package/dist/ui/components/nature/botanical/Berry.svelte +67 -0
  16. package/dist/ui/components/nature/botanical/Berry.svelte.d.ts +8 -0
  17. package/dist/ui/components/nature/botanical/DandelionPuff.svelte +98 -0
  18. package/dist/ui/components/nature/botanical/DandelionPuff.svelte.d.ts +8 -0
  19. package/dist/ui/components/nature/botanical/FallingLeavesLayer.svelte +170 -0
  20. package/dist/ui/components/nature/botanical/FallingLeavesLayer.svelte.d.ts +35 -0
  21. package/dist/ui/components/nature/botanical/FallingPetalsLayer.svelte +174 -0
  22. package/dist/ui/components/nature/botanical/FallingPetalsLayer.svelte.d.ts +25 -0
  23. package/dist/ui/components/nature/botanical/Leaf.svelte +77 -0
  24. package/dist/ui/components/nature/botanical/Leaf.svelte.d.ts +10 -0
  25. package/dist/ui/components/nature/botanical/LeafFalling.svelte +186 -0
  26. package/dist/ui/components/nature/botanical/LeafFalling.svelte.d.ts +22 -0
  27. package/dist/ui/components/nature/botanical/PetalFalling.svelte +266 -0
  28. package/dist/ui/components/nature/botanical/PetalFalling.svelte.d.ts +25 -0
  29. package/dist/ui/components/nature/botanical/PineCone.svelte +61 -0
  30. package/dist/ui/components/nature/botanical/PineCone.svelte.d.ts +7 -0
  31. package/dist/ui/components/nature/botanical/Vine.svelte +102 -0
  32. package/dist/ui/components/nature/botanical/Vine.svelte.d.ts +11 -0
  33. package/dist/ui/components/nature/botanical/index.d.ts +10 -0
  34. package/dist/ui/components/nature/botanical/index.js +11 -0
  35. package/dist/ui/components/nature/creatures/Bee.svelte +78 -0
  36. package/dist/ui/components/nature/creatures/Bee.svelte.d.ts +9 -0
  37. package/dist/ui/components/nature/creatures/Bird.svelte +94 -0
  38. package/dist/ui/components/nature/creatures/Bird.svelte.d.ts +11 -0
  39. package/dist/ui/components/nature/creatures/BirdFlying.svelte +83 -0
  40. package/dist/ui/components/nature/creatures/BirdFlying.svelte.d.ts +9 -0
  41. package/dist/ui/components/nature/creatures/Bluebird.svelte +95 -0
  42. package/dist/ui/components/nature/creatures/Bluebird.svelte.d.ts +12 -0
  43. package/dist/ui/components/nature/creatures/Butterfly.svelte +87 -0
  44. package/dist/ui/components/nature/creatures/Butterfly.svelte.d.ts +9 -0
  45. package/dist/ui/components/nature/creatures/Cardinal.svelte +95 -0
  46. package/dist/ui/components/nature/creatures/Cardinal.svelte.d.ts +12 -0
  47. package/dist/ui/components/nature/creatures/Chickadee.svelte +97 -0
  48. package/dist/ui/components/nature/creatures/Chickadee.svelte.d.ts +12 -0
  49. package/dist/ui/components/nature/creatures/Deer.svelte +95 -0
  50. package/dist/ui/components/nature/creatures/Deer.svelte.d.ts +9 -0
  51. package/dist/ui/components/nature/creatures/Firefly.svelte +111 -0
  52. package/dist/ui/components/nature/creatures/Firefly.svelte.d.ts +10 -0
  53. package/dist/ui/components/nature/creatures/Owl.svelte +91 -0
  54. package/dist/ui/components/nature/creatures/Owl.svelte.d.ts +9 -0
  55. package/dist/ui/components/nature/creatures/Rabbit.svelte +90 -0
  56. package/dist/ui/components/nature/creatures/Rabbit.svelte.d.ts +9 -0
  57. package/dist/ui/components/nature/creatures/Robin.svelte +98 -0
  58. package/dist/ui/components/nature/creatures/Robin.svelte.d.ts +12 -0
  59. package/dist/ui/components/nature/creatures/Squirrel.svelte +97 -0
  60. package/dist/ui/components/nature/creatures/Squirrel.svelte.d.ts +9 -0
  61. package/dist/ui/components/nature/creatures/index.d.ts +13 -0
  62. package/dist/ui/components/nature/creatures/index.js +14 -0
  63. package/dist/ui/components/nature/ground/Bush.svelte +57 -0
  64. package/dist/ui/components/nature/ground/Bush.svelte.d.ts +10 -0
  65. package/dist/ui/components/nature/ground/Crocus.svelte +83 -0
  66. package/dist/ui/components/nature/ground/Crocus.svelte.d.ts +12 -0
  67. package/dist/ui/components/nature/ground/Daffodil.svelte +75 -0
  68. package/dist/ui/components/nature/ground/Daffodil.svelte.d.ts +11 -0
  69. package/dist/ui/components/nature/ground/Fern.svelte +72 -0
  70. package/dist/ui/components/nature/ground/Fern.svelte.d.ts +10 -0
  71. package/dist/ui/components/nature/ground/FlowerWild.svelte +60 -0
  72. package/dist/ui/components/nature/ground/FlowerWild.svelte.d.ts +10 -0
  73. package/dist/ui/components/nature/ground/GrassTuft.svelte +49 -0
  74. package/dist/ui/components/nature/ground/GrassTuft.svelte.d.ts +10 -0
  75. package/dist/ui/components/nature/ground/Log.svelte +42 -0
  76. package/dist/ui/components/nature/ground/Log.svelte.d.ts +7 -0
  77. package/dist/ui/components/nature/ground/Mushroom.svelte +48 -0
  78. package/dist/ui/components/nature/ground/Mushroom.svelte.d.ts +9 -0
  79. package/dist/ui/components/nature/ground/MushroomCluster.svelte +41 -0
  80. package/dist/ui/components/nature/ground/MushroomCluster.svelte.d.ts +8 -0
  81. package/dist/ui/components/nature/ground/Rock.svelte +59 -0
  82. package/dist/ui/components/nature/ground/Rock.svelte.d.ts +8 -0
  83. package/dist/ui/components/nature/ground/Stump.svelte +44 -0
  84. package/dist/ui/components/nature/ground/Stump.svelte.d.ts +8 -0
  85. package/dist/ui/components/nature/ground/Tulip.svelte +79 -0
  86. package/dist/ui/components/nature/ground/Tulip.svelte.d.ts +11 -0
  87. package/dist/ui/components/nature/ground/index.d.ts +12 -0
  88. package/dist/ui/components/nature/ground/index.js +13 -0
  89. package/dist/ui/components/nature/index.d.ts +28 -0
  90. package/dist/ui/components/nature/index.js +38 -0
  91. package/dist/ui/components/nature/palette.d.ts +491 -0
  92. package/dist/ui/components/nature/palette.js +384 -0
  93. package/dist/ui/components/nature/sky/Cloud.svelte +122 -0
  94. package/dist/ui/components/nature/sky/Cloud.svelte.d.ts +11 -0
  95. package/dist/ui/components/nature/sky/CloudWispy.svelte +79 -0
  96. package/dist/ui/components/nature/sky/CloudWispy.svelte.d.ts +9 -0
  97. package/dist/ui/components/nature/sky/Moon.svelte +60 -0
  98. package/dist/ui/components/nature/sky/Moon.svelte.d.ts +9 -0
  99. package/dist/ui/components/nature/sky/Rainbow.svelte +101 -0
  100. package/dist/ui/components/nature/sky/Rainbow.svelte.d.ts +8 -0
  101. package/dist/ui/components/nature/sky/Star.svelte +84 -0
  102. package/dist/ui/components/nature/sky/Star.svelte.d.ts +10 -0
  103. package/dist/ui/components/nature/sky/StarCluster.svelte +85 -0
  104. package/dist/ui/components/nature/sky/StarCluster.svelte.d.ts +9 -0
  105. package/dist/ui/components/nature/sky/StarShooting.svelte +90 -0
  106. package/dist/ui/components/nature/sky/StarShooting.svelte.d.ts +9 -0
  107. package/dist/ui/components/nature/sky/Sun.svelte +70 -0
  108. package/dist/ui/components/nature/sky/Sun.svelte.d.ts +9 -0
  109. package/dist/ui/components/nature/sky/index.d.ts +8 -0
  110. package/dist/ui/components/nature/sky/index.js +9 -0
  111. package/dist/ui/components/nature/structural/Birdhouse.svelte +53 -0
  112. package/dist/ui/components/nature/structural/Birdhouse.svelte.d.ts +8 -0
  113. package/dist/ui/components/nature/structural/Bridge.svelte +65 -0
  114. package/dist/ui/components/nature/structural/Bridge.svelte.d.ts +7 -0
  115. package/dist/ui/components/nature/structural/FencePost.svelte +54 -0
  116. package/dist/ui/components/nature/structural/FencePost.svelte.d.ts +8 -0
  117. package/dist/ui/components/nature/structural/GardenGate.svelte +70 -0
  118. package/dist/ui/components/nature/structural/GardenGate.svelte.d.ts +8 -0
  119. package/dist/ui/components/nature/structural/Lantern.svelte +113 -0
  120. package/dist/ui/components/nature/structural/Lantern.svelte.d.ts +10 -0
  121. package/dist/ui/components/nature/structural/Lattice.svelte +89 -0
  122. package/dist/ui/components/nature/structural/Lattice.svelte.d.ts +8 -0
  123. package/dist/ui/components/nature/structural/LatticeWithVine.svelte +89 -0
  124. package/dist/ui/components/nature/structural/LatticeWithVine.svelte.d.ts +11 -0
  125. package/dist/ui/components/nature/structural/StonePath.svelte +48 -0
  126. package/dist/ui/components/nature/structural/StonePath.svelte.d.ts +7 -0
  127. package/dist/ui/components/nature/structural/index.d.ts +8 -0
  128. package/dist/ui/components/nature/structural/index.js +9 -0
  129. package/dist/ui/components/nature/trees/TreeAspen.svelte +163 -0
  130. package/dist/ui/components/nature/trees/TreeAspen.svelte.d.ts +11 -0
  131. package/dist/ui/components/nature/trees/TreeBirch.svelte +186 -0
  132. package/dist/ui/components/nature/trees/TreeBirch.svelte.d.ts +11 -0
  133. package/dist/ui/components/nature/trees/TreeCherry.svelte +108 -0
  134. package/dist/ui/components/nature/trees/TreeCherry.svelte.d.ts +11 -0
  135. package/dist/ui/components/nature/trees/TreePine.svelte +79 -0
  136. package/dist/ui/components/nature/trees/TreePine.svelte.d.ts +11 -0
  137. package/dist/ui/components/nature/trees/index.d.ts +4 -0
  138. package/dist/ui/components/nature/trees/index.js +5 -0
  139. package/dist/ui/components/nature/water/LilyPad.svelte +99 -0
  140. package/dist/ui/components/nature/water/LilyPad.svelte.d.ts +10 -0
  141. package/dist/ui/components/nature/water/Pond.svelte +104 -0
  142. package/dist/ui/components/nature/water/Pond.svelte.d.ts +8 -0
  143. package/dist/ui/components/nature/water/Reeds.svelte +85 -0
  144. package/dist/ui/components/nature/water/Reeds.svelte.d.ts +11 -0
  145. package/dist/ui/components/nature/water/Stream.svelte +98 -0
  146. package/dist/ui/components/nature/water/Stream.svelte.d.ts +8 -0
  147. package/dist/ui/components/nature/water/index.d.ts +4 -0
  148. package/dist/ui/components/nature/water/index.js +5 -0
  149. package/dist/ui/components/nature/weather/SnowfallLayer.svelte +175 -0
  150. package/dist/ui/components/nature/weather/SnowfallLayer.svelte.d.ts +25 -0
  151. package/dist/ui/components/nature/weather/Snowflake.svelte +99 -0
  152. package/dist/ui/components/nature/weather/Snowflake.svelte.d.ts +11 -0
  153. package/dist/ui/components/nature/weather/SnowflakeFalling.svelte +162 -0
  154. package/dist/ui/components/nature/weather/SnowflakeFalling.svelte.d.ts +23 -0
  155. package/dist/ui/components/nature/weather/index.d.ts +3 -0
  156. package/dist/ui/components/nature/weather/index.js +4 -0
  157. package/dist/ui/components/ui/Glass.svelte +158 -0
  158. package/dist/ui/components/ui/Glass.svelte.d.ts +52 -0
  159. package/dist/ui/components/ui/GlassButton.svelte +157 -0
  160. package/dist/ui/components/ui/GlassButton.svelte.d.ts +39 -0
  161. package/dist/ui/components/ui/GlassCard.svelte +160 -0
  162. package/dist/ui/components/ui/GlassCard.svelte.d.ts +39 -0
  163. package/dist/ui/components/ui/GlassConfirmDialog.svelte +208 -0
  164. package/dist/ui/components/ui/GlassConfirmDialog.svelte.d.ts +52 -0
  165. package/dist/ui/components/ui/GlassLogo.svelte +422 -0
  166. package/dist/ui/components/ui/GlassLogo.svelte.d.ts +23 -0
  167. package/dist/ui/components/ui/GlassNavbar.svelte +120 -0
  168. package/dist/ui/components/ui/GlassNavbar.svelte.d.ts +42 -0
  169. package/dist/ui/components/ui/GlassOverlay.svelte +93 -0
  170. package/dist/ui/components/ui/GlassOverlay.svelte.d.ts +33 -0
  171. package/dist/ui/components/ui/Logo.svelte +47 -52
  172. package/dist/ui/components/ui/Logo.svelte.d.ts +4 -3
  173. package/dist/ui/components/ui/index.d.ts +7 -0
  174. package/dist/ui/components/ui/index.js +8 -0
  175. package/dist/ui/styles/grove.css +151 -1
  176. package/dist/utils/gutter.d.ts +2 -8
  177. package/dist/utils/markdown.d.ts +1 -0
  178. package/dist/utils/markdown.js +32 -11
  179. package/package.json +31 -22
  180. package/static/fonts/alagard.ttf +0 -0
  181. package/static/robots.txt +34 -1
  182. package/dist/auth/jwt.d.ts +0 -20
  183. package/dist/auth/jwt.js +0 -123
@@ -0,0 +1,39 @@
1
+ import type { Snippet } from "svelte";
2
+ import type { HTMLButtonAttributes } from "svelte/elements";
3
+ /**
4
+ * GlassButton - A button with glassmorphism styling
5
+ *
6
+ * Beautiful translucent buttons with backdrop blur effects.
7
+ * Perfect for floating actions, overlays, and modern UI designs.
8
+ *
9
+ * @example Basic glass button
10
+ * ```svelte
11
+ * <GlassButton>Click me</GlassButton>
12
+ * ```
13
+ *
14
+ * @example Accent glass button
15
+ * ```svelte
16
+ * <GlassButton variant="accent">Subscribe</GlassButton>
17
+ * ```
18
+ *
19
+ * @example Ghost glass with icon
20
+ * ```svelte
21
+ * <GlassButton variant="ghost" size="icon">
22
+ * <X class="w-4 h-4" />
23
+ * </GlassButton>
24
+ * ```
25
+ */
26
+ type GlassVariant = "default" | "accent" | "dark" | "ghost" | "outline";
27
+ type ButtonSize = "sm" | "md" | "lg" | "icon";
28
+ interface Props extends Omit<HTMLButtonAttributes, "class"> {
29
+ variant?: GlassVariant;
30
+ size?: ButtonSize;
31
+ disabled?: boolean;
32
+ href?: string;
33
+ class?: string;
34
+ children?: Snippet;
35
+ ref?: HTMLButtonElement | HTMLAnchorElement | null;
36
+ }
37
+ declare const GlassButton: import("svelte").Component<Props, {}, "ref">;
38
+ type GlassButton = ReturnType<typeof GlassButton>;
39
+ export default GlassButton;
@@ -0,0 +1,160 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from "svelte";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+ import { cn } from "../../utils";
5
+
6
+ /**
7
+ * GlassCard - A card component with glassmorphism styling
8
+ *
9
+ * Beautiful translucent cards with backdrop blur effects.
10
+ * Includes optional header, footer, and hoverable state.
11
+ *
12
+ * @example Basic glass card
13
+ * ```svelte
14
+ * <GlassCard title="Settings" description="Manage your preferences">
15
+ * <p>Card content here</p>
16
+ * </GlassCard>
17
+ * ```
18
+ *
19
+ * @example Accent card with footer
20
+ * ```svelte
21
+ * <GlassCard variant="accent" hoverable>
22
+ * {#snippet header()}<CustomHeader />{/snippet}
23
+ * Content here
24
+ * {#snippet footer()}<Button>Save</Button>{/snippet}
25
+ * </GlassCard>
26
+ * ```
27
+ */
28
+
29
+ type GlassVariant =
30
+ | "default" // Light translucent background
31
+ | "accent" // Accent-colored glass
32
+ | "dark" // Dark translucent background
33
+ | "muted" // Very subtle, barely visible
34
+ | "frosted"; // Stronger blur effect, more opaque
35
+
36
+ interface Props extends Omit<HTMLAttributes<HTMLDivElement>, "class"> {
37
+ variant?: GlassVariant;
38
+ title?: string;
39
+ description?: string;
40
+ hoverable?: boolean;
41
+ border?: boolean;
42
+ class?: string;
43
+ header?: Snippet;
44
+ footer?: Snippet;
45
+ children?: Snippet;
46
+ }
47
+
48
+ let {
49
+ variant = "default",
50
+ title,
51
+ description,
52
+ hoverable = false,
53
+ border = true,
54
+ class: className,
55
+ header,
56
+ footer,
57
+ children,
58
+ ...restProps
59
+ }: Props = $props();
60
+
61
+ // Variant-specific styles - warm grove tones with true glass transparency
62
+ const variantClasses: Record<GlassVariant, string> = {
63
+ default: `
64
+ bg-white/60 dark:bg-emerald-950/25
65
+ backdrop-blur-md
66
+ `.trim().replace(/\s+/g, ' '),
67
+
68
+ accent: `
69
+ bg-accent/20 dark:bg-accent/15
70
+ backdrop-blur-md
71
+ `.trim().replace(/\s+/g, ' '),
72
+
73
+ dark: `
74
+ bg-slate-900/40 dark:bg-slate-950/40
75
+ backdrop-blur-md
76
+ text-white
77
+ `.trim().replace(/\s+/g, ' '),
78
+
79
+ muted: `
80
+ bg-white/30 dark:bg-emerald-950/15
81
+ backdrop-blur
82
+ `.trim().replace(/\s+/g, ' '),
83
+
84
+ frosted: `
85
+ bg-white/70 dark:bg-emerald-950/35
86
+ backdrop-blur-lg
87
+ `.trim().replace(/\s+/g, ' ')
88
+ };
89
+
90
+ // Border colors per variant - subtle, warm borders
91
+ const borderClasses: Record<GlassVariant, string> = {
92
+ default: "border-white/40 dark:border-emerald-800/25",
93
+ accent: "border-accent/30 dark:border-accent/20",
94
+ dark: "border-slate-700/30 dark:border-slate-600/30",
95
+ muted: "border-white/20 dark:border-emerald-800/15",
96
+ frosted: "border-white/50 dark:border-emerald-800/30"
97
+ };
98
+
99
+ // Hover styles - slightly more visible on hover
100
+ const hoverClasses: Record<GlassVariant, string> = {
101
+ default: "hover:bg-white/70 dark:hover:bg-emerald-950/35 hover:shadow-lg hover:border-white/50 dark:hover:border-emerald-700/30",
102
+ accent: "hover:bg-accent/30 dark:hover:bg-accent/25 hover:shadow-lg hover:shadow-accent/10 hover:border-accent/40",
103
+ dark: "hover:bg-slate-900/50 dark:hover:bg-slate-950/50 hover:shadow-xl hover:border-slate-600/40",
104
+ muted: "hover:bg-white/40 dark:hover:bg-emerald-950/25 hover:shadow-md hover:border-white/30",
105
+ frosted: "hover:bg-white/80 dark:hover:bg-emerald-950/45 hover:shadow-lg hover:border-white/60"
106
+ };
107
+
108
+ const computedClass = $derived(
109
+ cn(
110
+ "rounded-xl transition-all duration-200",
111
+ variantClasses[variant],
112
+ border && `border ${borderClasses[variant]}`,
113
+ hoverable && `cursor-pointer ${hoverClasses[variant]}`,
114
+ "shadow-sm",
115
+ className
116
+ )
117
+ );
118
+
119
+ // Text color adjustments for dark variant
120
+ const titleClass = $derived(
121
+ variant === "dark"
122
+ ? "text-white"
123
+ : "text-foreground"
124
+ );
125
+
126
+ const descriptionClass = $derived(
127
+ variant === "dark"
128
+ ? "text-slate-300"
129
+ : "text-muted-foreground"
130
+ );
131
+ </script>
132
+
133
+ <div class={computedClass} {...restProps}>
134
+ {#if header || title || description}
135
+ <div class="px-6 py-4 {(children || footer) ? 'border-b border-inherit' : ''}">
136
+ {#if header}
137
+ {@render header()}
138
+ {:else}
139
+ {#if title}
140
+ <h3 class="text-lg font-semibold {titleClass}">{title}</h3>
141
+ {/if}
142
+ {#if description}
143
+ <p class="text-sm {descriptionClass} mt-1">{description}</p>
144
+ {/if}
145
+ {/if}
146
+ </div>
147
+ {/if}
148
+
149
+ {#if children}
150
+ <div class="px-6 py-4">
151
+ {@render children()}
152
+ </div>
153
+ {/if}
154
+
155
+ {#if footer}
156
+ <div class="px-6 py-4 border-t border-inherit">
157
+ {@render footer()}
158
+ </div>
159
+ {/if}
160
+ </div>
@@ -0,0 +1,39 @@
1
+ import type { Snippet } from "svelte";
2
+ import type { HTMLAttributes } from "svelte/elements";
3
+ /**
4
+ * GlassCard - A card component with glassmorphism styling
5
+ *
6
+ * Beautiful translucent cards with backdrop blur effects.
7
+ * Includes optional header, footer, and hoverable state.
8
+ *
9
+ * @example Basic glass card
10
+ * ```svelte
11
+ * <GlassCard title="Settings" description="Manage your preferences">
12
+ * <p>Card content here</p>
13
+ * </GlassCard>
14
+ * ```
15
+ *
16
+ * @example Accent card with footer
17
+ * ```svelte
18
+ * <GlassCard variant="accent" hoverable>
19
+ * {#snippet header()}<CustomHeader />{/snippet}
20
+ * Content here
21
+ * {#snippet footer()}<Button>Save</Button>{/snippet}
22
+ * </GlassCard>
23
+ * ```
24
+ */
25
+ type GlassVariant = "default" | "accent" | "dark" | "muted" | "frosted";
26
+ interface Props extends Omit<HTMLAttributes<HTMLDivElement>, "class"> {
27
+ variant?: GlassVariant;
28
+ title?: string;
29
+ description?: string;
30
+ hoverable?: boolean;
31
+ border?: boolean;
32
+ class?: string;
33
+ header?: Snippet;
34
+ footer?: Snippet;
35
+ children?: Snippet;
36
+ }
37
+ declare const GlassCard: import("svelte").Component<Props, {}, "">;
38
+ type GlassCard = ReturnType<typeof GlassCard>;
39
+ export default GlassCard;
@@ -0,0 +1,208 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from "svelte";
3
+ import { cn } from "../../utils";
4
+ import { fade, scale } from "svelte/transition";
5
+ import { AlertTriangle, Trash2, HelpCircle } from "lucide-svelte";
6
+ import Button from "./Button.svelte";
7
+
8
+ /**
9
+ * GlassConfirmDialog - A confirmation dialog with glassmorphism styling
10
+ *
11
+ * Perfect for destructive actions like delete, or any action that needs user confirmation.
12
+ * Features a glass-effect card over a blurred overlay.
13
+ *
14
+ * @example Basic confirmation
15
+ * ```svelte
16
+ * <GlassConfirmDialog
17
+ * bind:open={showDeleteDialog}
18
+ * title="Delete Post"
19
+ * message="Are you sure you want to delete this post? This cannot be undone."
20
+ * confirmLabel="Delete"
21
+ * variant="danger"
22
+ * onconfirm={handleDelete}
23
+ * />
24
+ * ```
25
+ *
26
+ * @example Custom content
27
+ * ```svelte
28
+ * <GlassConfirmDialog bind:open={showDialog} title="Confirm Changes" onconfirm={save}>
29
+ * <p>You have unsaved changes. Would you like to save them?</p>
30
+ * </GlassConfirmDialog>
31
+ * ```
32
+ */
33
+
34
+ type DialogVariant = "default" | "danger" | "warning";
35
+
36
+ interface Props {
37
+ /** Whether the dialog is open (bindable) */
38
+ open?: boolean;
39
+ /** Dialog title */
40
+ title: string;
41
+ /** Dialog message (if not using children) */
42
+ message?: string;
43
+ /** Confirm button label */
44
+ confirmLabel?: string;
45
+ /** Cancel button label */
46
+ cancelLabel?: string;
47
+ /** Dialog variant (affects styling and icon) */
48
+ variant?: DialogVariant;
49
+ /** Whether the confirm action is loading */
50
+ loading?: boolean;
51
+ /** Called when user confirms */
52
+ onconfirm?: () => void | Promise<void>;
53
+ /** Called when user cancels or closes */
54
+ oncancel?: () => void;
55
+ /** Custom content (overrides message) */
56
+ children?: Snippet;
57
+ }
58
+
59
+ let {
60
+ open = $bindable(false),
61
+ title,
62
+ message,
63
+ confirmLabel = "Confirm",
64
+ cancelLabel = "Cancel",
65
+ variant = "default",
66
+ loading = false,
67
+ onconfirm,
68
+ oncancel,
69
+ children
70
+ }: Props = $props();
71
+
72
+ // Variant-specific styling
73
+ const variantConfig = {
74
+ default: {
75
+ icon: HelpCircle,
76
+ iconClass: "text-accent-muted",
77
+ confirmVariant: "primary" as const
78
+ },
79
+ danger: {
80
+ icon: Trash2,
81
+ iconClass: "text-red-500 dark:text-red-400",
82
+ confirmVariant: "danger" as const
83
+ },
84
+ warning: {
85
+ icon: AlertTriangle,
86
+ iconClass: "text-amber-500 dark:text-amber-400",
87
+ confirmVariant: "primary" as const
88
+ }
89
+ };
90
+
91
+ const config = $derived(variantConfig[variant]);
92
+
93
+ function handleCancel() {
94
+ open = false;
95
+ oncancel?.();
96
+ }
97
+
98
+ async function handleConfirm() {
99
+ try {
100
+ await onconfirm?.();
101
+ open = false;
102
+ } catch (error) {
103
+ // Don't close on error - let the caller handle it
104
+ console.error('Confirm action failed:', error);
105
+ }
106
+ }
107
+
108
+ function handleKeydown(event: KeyboardEvent) {
109
+ if (event.key === "Escape") {
110
+ handleCancel();
111
+ }
112
+ }
113
+
114
+ function handleBackdropClick(event: MouseEvent) {
115
+ // Only close if clicking the backdrop itself, not the dialog
116
+ if (event.target === event.currentTarget) {
117
+ handleCancel();
118
+ }
119
+ }
120
+ </script>
121
+
122
+ <svelte:window onkeydown={handleKeydown} />
123
+
124
+ {#if open}
125
+ <!-- Backdrop with glass effect -->
126
+ <div
127
+ class="fixed inset-0 z-50 flex items-center justify-center p-4"
128
+ onclick={handleBackdropClick}
129
+ role="dialog"
130
+ aria-modal="true"
131
+ aria-labelledby="confirm-dialog-title"
132
+ transition:fade={{ duration: 150 }}
133
+ >
134
+ <!-- Dark overlay with blur -->
135
+ <div
136
+ class="absolute inset-0 bg-black/50 dark:bg-black/60 backdrop-blur-sm"
137
+ aria-hidden="true"
138
+ ></div>
139
+
140
+ <!-- Dialog card -->
141
+ <div
142
+ class={cn(
143
+ "relative z-10 w-full max-w-md",
144
+ "bg-white/80 dark:bg-slate-900/80",
145
+ "backdrop-blur-xl",
146
+ "border border-white/40 dark:border-slate-700/40",
147
+ "rounded-2xl shadow-2xl",
148
+ "overflow-hidden"
149
+ )}
150
+ transition:scale={{ duration: 150, start: 0.95 }}
151
+ >
152
+ <!-- Header with icon -->
153
+ <div class="px-6 pt-6 pb-4 flex items-start gap-4">
154
+ <div class={cn(
155
+ "flex-shrink-0 p-3 rounded-full",
156
+ variant === "danger" && "bg-red-100 dark:bg-red-900/30",
157
+ variant === "warning" && "bg-amber-100 dark:bg-amber-900/30",
158
+ variant === "default" && "bg-accent/10 dark:bg-accent/20"
159
+ )}>
160
+ <svelte:component this={config.icon} class={cn("w-6 h-6", config.iconClass)} />
161
+ </div>
162
+ <div class="flex-1 min-w-0">
163
+ <h3
164
+ id="confirm-dialog-title"
165
+ class="text-lg font-semibold text-foreground leading-tight"
166
+ >
167
+ {title}
168
+ </h3>
169
+ {#if message && !children}
170
+ <p class="mt-2 text-sm text-muted-foreground leading-relaxed">
171
+ {message}
172
+ </p>
173
+ {/if}
174
+ {#if children}
175
+ <div class="mt-2 text-sm text-muted-foreground">
176
+ {@render children()}
177
+ </div>
178
+ {/if}
179
+ </div>
180
+ </div>
181
+
182
+ <!-- Footer with actions -->
183
+ <div class="px-6 py-4 bg-slate-50/50 dark:bg-slate-800/30 border-t border-white/20 dark:border-slate-700/30 flex justify-end gap-3">
184
+ <Button
185
+ variant="ghost"
186
+ onclick={handleCancel}
187
+ disabled={loading}
188
+ >
189
+ {cancelLabel}
190
+ </Button>
191
+ <Button
192
+ variant={config.confirmVariant}
193
+ onclick={handleConfirm}
194
+ disabled={loading}
195
+ >
196
+ {#if loading}
197
+ <span class="inline-flex items-center gap-2">
198
+ <span class="w-4 h-4 border-2 border-current border-t-transparent rounded-full animate-spin"></span>
199
+ Processing...
200
+ </span>
201
+ {:else}
202
+ {confirmLabel}
203
+ {/if}
204
+ </Button>
205
+ </div>
206
+ </div>
207
+ </div>
208
+ {/if}
@@ -0,0 +1,52 @@
1
+ import type { Snippet } from "svelte";
2
+ /**
3
+ * GlassConfirmDialog - A confirmation dialog with glassmorphism styling
4
+ *
5
+ * Perfect for destructive actions like delete, or any action that needs user confirmation.
6
+ * Features a glass-effect card over a blurred overlay.
7
+ *
8
+ * @example Basic confirmation
9
+ * ```svelte
10
+ * <GlassConfirmDialog
11
+ * bind:open={showDeleteDialog}
12
+ * title="Delete Post"
13
+ * message="Are you sure you want to delete this post? This cannot be undone."
14
+ * confirmLabel="Delete"
15
+ * variant="danger"
16
+ * onconfirm={handleDelete}
17
+ * />
18
+ * ```
19
+ *
20
+ * @example Custom content
21
+ * ```svelte
22
+ * <GlassConfirmDialog bind:open={showDialog} title="Confirm Changes" onconfirm={save}>
23
+ * <p>You have unsaved changes. Would you like to save them?</p>
24
+ * </GlassConfirmDialog>
25
+ * ```
26
+ */
27
+ type DialogVariant = "default" | "danger" | "warning";
28
+ interface Props {
29
+ /** Whether the dialog is open (bindable) */
30
+ open?: boolean;
31
+ /** Dialog title */
32
+ title: string;
33
+ /** Dialog message (if not using children) */
34
+ message?: string;
35
+ /** Confirm button label */
36
+ confirmLabel?: string;
37
+ /** Cancel button label */
38
+ cancelLabel?: string;
39
+ /** Dialog variant (affects styling and icon) */
40
+ variant?: DialogVariant;
41
+ /** Whether the confirm action is loading */
42
+ loading?: boolean;
43
+ /** Called when user confirms */
44
+ onconfirm?: () => void | Promise<void>;
45
+ /** Called when user cancels or closes */
46
+ oncancel?: () => void;
47
+ /** Custom content (overrides message) */
48
+ children?: Snippet;
49
+ }
50
+ declare const GlassConfirmDialog: import("svelte").Component<Props, {}, "open">;
51
+ type GlassConfirmDialog = ReturnType<typeof GlassConfirmDialog>;
52
+ export default GlassConfirmDialog;