@autumnsgrove/groveengine 0.6.5 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +378 -0
- package/dist/auth/index.d.ts +1 -2
- package/dist/auth/index.js +8 -4
- package/dist/auth/session.d.ts +12 -31
- package/dist/auth/session.js +5 -103
- package/dist/components/custom/ContentWithGutter.svelte +22 -25
- package/dist/ui/components/ui/Glass.svelte +158 -0
- package/dist/ui/components/ui/Glass.svelte.d.ts +52 -0
- package/dist/ui/components/ui/GlassButton.svelte +157 -0
- package/dist/ui/components/ui/GlassButton.svelte.d.ts +39 -0
- package/dist/ui/components/ui/GlassCard.svelte +160 -0
- package/dist/ui/components/ui/GlassCard.svelte.d.ts +39 -0
- package/dist/ui/components/ui/GlassConfirmDialog.svelte +208 -0
- package/dist/ui/components/ui/GlassConfirmDialog.svelte.d.ts +52 -0
- package/dist/ui/components/ui/GlassOverlay.svelte +93 -0
- package/dist/ui/components/ui/GlassOverlay.svelte.d.ts +33 -0
- package/dist/ui/components/ui/index.d.ts +5 -0
- package/dist/ui/components/ui/index.js +6 -0
- package/dist/ui/styles/grove.css +136 -0
- package/dist/utils/gutter.d.ts +2 -8
- package/dist/utils/markdown.d.ts +1 -0
- package/dist/utils/markdown.js +32 -11
- package/package.json +21 -22
- package/static/fonts/alagard.ttf +0 -0
- package/static/robots.txt +34 -1
- package/dist/auth/jwt.d.ts +0 -20
- package/dist/auth/jwt.js +0 -123
|
@@ -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;
|
|
@@ -0,0 +1,93 @@
|
|
|
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
|
+
* GlassOverlay - A fullscreen overlay with glassmorphism effect
|
|
8
|
+
*
|
|
9
|
+
* Perfect for modal backdrops, loading screens, and focus overlays.
|
|
10
|
+
* Provides a dark translucent backdrop with blur effect.
|
|
11
|
+
*
|
|
12
|
+
* @example Basic overlay
|
|
13
|
+
* ```svelte
|
|
14
|
+
* {#if showModal}
|
|
15
|
+
* <GlassOverlay onclick={closeModal} />
|
|
16
|
+
* {/if}
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @example Custom intensity
|
|
20
|
+
* ```svelte
|
|
21
|
+
* <GlassOverlay variant="light" intensity="strong" />
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
type OverlayVariant =
|
|
26
|
+
| "dark" // Dark overlay (default for modals)
|
|
27
|
+
| "light" // Light overlay
|
|
28
|
+
| "accent"; // Tinted with accent color
|
|
29
|
+
|
|
30
|
+
type BlurIntensity =
|
|
31
|
+
| "none" // No blur
|
|
32
|
+
| "light" // 4px blur
|
|
33
|
+
| "medium" // 8px blur
|
|
34
|
+
| "strong"; // 12px blur
|
|
35
|
+
|
|
36
|
+
interface Props extends Omit<HTMLAttributes<HTMLDivElement>, "class"> {
|
|
37
|
+
variant?: OverlayVariant;
|
|
38
|
+
intensity?: BlurIntensity;
|
|
39
|
+
/** Whether clicking the overlay should be interactive (for close handlers) */
|
|
40
|
+
interactive?: boolean;
|
|
41
|
+
class?: string;
|
|
42
|
+
children?: Snippet;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
let {
|
|
46
|
+
variant = "dark",
|
|
47
|
+
intensity = "light",
|
|
48
|
+
interactive = true,
|
|
49
|
+
class: className,
|
|
50
|
+
children,
|
|
51
|
+
...restProps
|
|
52
|
+
}: Props = $props();
|
|
53
|
+
|
|
54
|
+
// Variant backgrounds
|
|
55
|
+
const variantClasses: Record<OverlayVariant, string> = {
|
|
56
|
+
dark: "bg-black/50 dark:bg-black/60",
|
|
57
|
+
light: "bg-white/50 dark:bg-slate-900/50",
|
|
58
|
+
accent: "bg-accent/30 dark:bg-accent/20"
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// Blur intensities
|
|
62
|
+
const intensityClasses: Record<BlurIntensity, string> = {
|
|
63
|
+
none: "",
|
|
64
|
+
light: "backdrop-blur-sm",
|
|
65
|
+
medium: "backdrop-blur",
|
|
66
|
+
strong: "backdrop-blur-md"
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const computedClass = $derived(
|
|
70
|
+
cn(
|
|
71
|
+
"fixed inset-0 z-50",
|
|
72
|
+
variantClasses[variant],
|
|
73
|
+
intensityClasses[intensity],
|
|
74
|
+
interactive && "cursor-pointer",
|
|
75
|
+
// Animation classes for when used with transitions
|
|
76
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
77
|
+
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
78
|
+
className
|
|
79
|
+
)
|
|
80
|
+
);
|
|
81
|
+
</script>
|
|
82
|
+
|
|
83
|
+
<div
|
|
84
|
+
class={computedClass}
|
|
85
|
+
role={interactive ? "button" : "presentation"}
|
|
86
|
+
tabindex={interactive ? 0 : -1}
|
|
87
|
+
aria-label={interactive ? "Close overlay" : undefined}
|
|
88
|
+
{...restProps}
|
|
89
|
+
>
|
|
90
|
+
{#if children}
|
|
91
|
+
{@render children()}
|
|
92
|
+
{/if}
|
|
93
|
+
</div>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
2
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
3
|
+
/**
|
|
4
|
+
* GlassOverlay - A fullscreen overlay with glassmorphism effect
|
|
5
|
+
*
|
|
6
|
+
* Perfect for modal backdrops, loading screens, and focus overlays.
|
|
7
|
+
* Provides a dark translucent backdrop with blur effect.
|
|
8
|
+
*
|
|
9
|
+
* @example Basic overlay
|
|
10
|
+
* ```svelte
|
|
11
|
+
* {#if showModal}
|
|
12
|
+
* <GlassOverlay onclick={closeModal} />
|
|
13
|
+
* {/if}
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* @example Custom intensity
|
|
17
|
+
* ```svelte
|
|
18
|
+
* <GlassOverlay variant="light" intensity="strong" />
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
type OverlayVariant = "dark" | "light" | "accent";
|
|
22
|
+
type BlurIntensity = "none" | "light" | "medium" | "strong";
|
|
23
|
+
interface Props extends Omit<HTMLAttributes<HTMLDivElement>, "class"> {
|
|
24
|
+
variant?: OverlayVariant;
|
|
25
|
+
intensity?: BlurIntensity;
|
|
26
|
+
/** Whether clicking the overlay should be interactive (for close handlers) */
|
|
27
|
+
interactive?: boolean;
|
|
28
|
+
class?: string;
|
|
29
|
+
children?: Snippet;
|
|
30
|
+
}
|
|
31
|
+
declare const GlassOverlay: import("svelte").Component<Props, {}, "">;
|
|
32
|
+
type GlassOverlay = ReturnType<typeof GlassOverlay>;
|
|
33
|
+
export default GlassOverlay;
|
|
@@ -15,6 +15,11 @@ export { default as Table } from './Table.svelte';
|
|
|
15
15
|
export { default as CollapsibleSection } from './CollapsibleSection.svelte';
|
|
16
16
|
export { default as Logo } from './Logo.svelte';
|
|
17
17
|
export { default as LogoLoader } from './LogoLoader.svelte';
|
|
18
|
+
export { default as Glass } from './Glass.svelte';
|
|
19
|
+
export { default as GlassButton } from './GlassButton.svelte';
|
|
20
|
+
export { default as GlassCard } from './GlassCard.svelte';
|
|
21
|
+
export { default as GlassConfirmDialog } from './GlassConfirmDialog.svelte';
|
|
22
|
+
export { default as GlassOverlay } from './GlassOverlay.svelte';
|
|
18
23
|
export { TableHeader, TableBody, TableRow, TableCell, TableHead, TableFooter, TableCaption, } from '../primitives/table';
|
|
19
24
|
export * from './toast.js';
|
|
20
25
|
export declare const UI_VERSION = "0.2.0";
|
|
@@ -23,6 +23,12 @@ export { default as Table } from './Table.svelte';
|
|
|
23
23
|
export { default as CollapsibleSection } from './CollapsibleSection.svelte';
|
|
24
24
|
export { default as Logo } from './Logo.svelte';
|
|
25
25
|
export { default as LogoLoader } from './LogoLoader.svelte';
|
|
26
|
+
// Glass suite - glassmorphism components
|
|
27
|
+
export { default as Glass } from './Glass.svelte';
|
|
28
|
+
export { default as GlassButton } from './GlassButton.svelte';
|
|
29
|
+
export { default as GlassCard } from './GlassCard.svelte';
|
|
30
|
+
export { default as GlassConfirmDialog } from './GlassConfirmDialog.svelte';
|
|
31
|
+
export { default as GlassOverlay } from './GlassOverlay.svelte';
|
|
26
32
|
// Table sub-components (from primitives)
|
|
27
33
|
export { TableHeader, TableBody, TableRow, TableCell, TableHead, TableFooter, TableCaption, } from '../primitives/table';
|
|
28
34
|
// Toast utility
|
package/dist/ui/styles/grove.css
CHANGED
|
@@ -712,4 +712,140 @@
|
|
|
712
712
|
outline: none;
|
|
713
713
|
box-shadow: inset 0 0 0 2px var(--grove-500);
|
|
714
714
|
}
|
|
715
|
+
|
|
716
|
+
/* ─────────────────────────────────────────────────────────────
|
|
717
|
+
GLASSMORPHISM UTILITIES
|
|
718
|
+
|
|
719
|
+
Apply these classes to any element for glass effects.
|
|
720
|
+
Combine with Tailwind backdrop-blur-* for blur intensity.
|
|
721
|
+
|
|
722
|
+
Usage:
|
|
723
|
+
<div class="glass">...</div>
|
|
724
|
+
<div class="glass-accent backdrop-blur-md">...</div>
|
|
725
|
+
───────────────────────────────────────────────────────────── */
|
|
726
|
+
|
|
727
|
+
/* Base glass - light translucent background */
|
|
728
|
+
.glass {
|
|
729
|
+
background-color: rgb(255 255 255 / 0.7);
|
|
730
|
+
border: 1px solid rgb(255 255 255 / 0.3);
|
|
731
|
+
backdrop-filter: blur(4px);
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
:is(.dark .glass) {
|
|
735
|
+
background-color: rgb(30 41 59 / 0.6);
|
|
736
|
+
border-color: rgb(71 85 105 / 0.3);
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
/* Glass surface - higher opacity for headers/navbars */
|
|
740
|
+
.glass-surface {
|
|
741
|
+
background-color: rgb(255 255 255 / 0.95);
|
|
742
|
+
border: 1px solid rgb(255 255 255 / 0.3);
|
|
743
|
+
backdrop-filter: blur(4px);
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
:is(.dark .glass-surface) {
|
|
747
|
+
background-color: rgb(30 41 59 / 0.95);
|
|
748
|
+
border-color: rgb(71 85 105 / 0.3);
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
/* Glass overlay - dark backdrop for modals */
|
|
752
|
+
.glass-overlay {
|
|
753
|
+
background-color: rgb(0 0 0 / 0.5);
|
|
754
|
+
backdrop-filter: blur(4px);
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
:is(.dark .glass-overlay) {
|
|
758
|
+
background-color: rgb(0 0 0 / 0.6);
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
/* Glass accent - tinted with grove green (accent color) */
|
|
762
|
+
.glass-accent {
|
|
763
|
+
background-color: color-mix(in srgb, var(--grove-500) 20%, transparent);
|
|
764
|
+
border: 1px solid color-mix(in srgb, var(--grove-500) 30%, transparent);
|
|
765
|
+
backdrop-filter: blur(4px);
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
:is(.dark .glass-accent) {
|
|
769
|
+
background-color: color-mix(in srgb, var(--grove-500) 15%, transparent);
|
|
770
|
+
border-color: color-mix(in srgb, var(--grove-500) 20%, transparent);
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
/* Glass muted - subtle, barely visible */
|
|
774
|
+
.glass-muted {
|
|
775
|
+
background-color: rgb(255 255 255 / 0.4);
|
|
776
|
+
border: 1px solid rgb(255 255 255 / 0.2);
|
|
777
|
+
backdrop-filter: blur(4px);
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
:is(.dark .glass-muted) {
|
|
781
|
+
background-color: rgb(15 23 42 / 0.3);
|
|
782
|
+
border-color: rgb(51 65 85 / 0.2);
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
/* Glass tint - light background for text readability */
|
|
786
|
+
.glass-tint {
|
|
787
|
+
background-color: rgb(255 255 255 / 0.6);
|
|
788
|
+
border: 1px solid rgb(255 255 255 / 0.2);
|
|
789
|
+
backdrop-filter: blur(4px);
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
:is(.dark .glass-tint) {
|
|
793
|
+
background-color: rgb(15 23 42 / 0.5);
|
|
794
|
+
border-color: rgb(51 65 85 / 0.3);
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
/* Glass dark - dark translucent background */
|
|
798
|
+
.glass-dark {
|
|
799
|
+
background-color: rgb(15 23 42 / 0.7);
|
|
800
|
+
border: 1px solid rgb(51 65 85 / 0.3);
|
|
801
|
+
backdrop-filter: blur(4px);
|
|
802
|
+
color: white;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
:is(.dark .glass-dark) {
|
|
806
|
+
background-color: rgb(2 6 23 / 0.8);
|
|
807
|
+
border-color: rgb(51 65 85 / 0.3);
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
/* Glass frosted - stronger effect, more opaque */
|
|
811
|
+
.glass-frosted {
|
|
812
|
+
background-color: rgb(255 255 255 / 0.85);
|
|
813
|
+
border: 1px solid rgb(255 255 255 / 0.4);
|
|
814
|
+
backdrop-filter: blur(12px);
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
:is(.dark .glass-frosted) {
|
|
818
|
+
background-color: rgb(30 41 59 / 0.8);
|
|
819
|
+
border-color: rgb(71 85 105 / 0.4);
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
/* No border variants */
|
|
823
|
+
.glass-borderless {
|
|
824
|
+
border: none;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
/* Hover states for interactive glass elements */
|
|
828
|
+
.glass-hover:hover {
|
|
829
|
+
background-color: rgb(255 255 255 / 0.85);
|
|
830
|
+
border-color: rgb(255 255 255 / 0.5);
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
:is(.dark .glass-hover:hover) {
|
|
834
|
+
background-color: rgb(30 41 59 / 0.75);
|
|
835
|
+
border-color: rgb(71 85 105 / 0.4);
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
/* Reduced motion: disable blur effects for performance/accessibility */
|
|
839
|
+
@media (prefers-reduced-motion: reduce) {
|
|
840
|
+
.glass,
|
|
841
|
+
.glass-surface,
|
|
842
|
+
.glass-overlay,
|
|
843
|
+
.glass-accent,
|
|
844
|
+
.glass-muted,
|
|
845
|
+
.glass-tint,
|
|
846
|
+
.glass-dark,
|
|
847
|
+
.glass-frosted {
|
|
848
|
+
backdrop-filter: none;
|
|
849
|
+
}
|
|
850
|
+
}
|
|
715
851
|
}
|
package/dist/utils/gutter.d.ts
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* and anchor resolution. Used by ContentWithGutter component and related
|
|
6
6
|
* functionality across the site.
|
|
7
7
|
*/
|
|
8
|
+
import type { GutterItem as MarkdownGutterItem } from "./markdown.js";
|
|
9
|
+
export type GutterItem = MarkdownGutterItem;
|
|
8
10
|
/** Anchor types supported by the gutter system */
|
|
9
11
|
export type AnchorType = "none" | "paragraph" | "tag" | "header";
|
|
10
12
|
/** Parsed anchor result */
|
|
@@ -18,14 +20,6 @@ export interface Header {
|
|
|
18
20
|
text: string;
|
|
19
21
|
level?: number;
|
|
20
22
|
}
|
|
21
|
-
/** Gutter item with anchor */
|
|
22
|
-
export interface GutterItem {
|
|
23
|
-
anchor?: string;
|
|
24
|
-
type?: string;
|
|
25
|
-
content?: string;
|
|
26
|
-
src?: string;
|
|
27
|
-
[key: string]: unknown;
|
|
28
|
-
}
|
|
29
23
|
/**
|
|
30
24
|
* Parse anchor string to determine anchor type and value
|
|
31
25
|
* @param anchor - The anchor string from manifest
|
package/dist/utils/markdown.d.ts
CHANGED