@autumnsgrove/groveengine 0.8.0 → 0.8.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/OnboardingChecklist.svelte +2 -2
- package/dist/components/WispButton.svelte +83 -0
- package/dist/components/WispButton.svelte.d.ts +49 -0
- package/dist/components/WispPanel.svelte +1092 -0
- package/dist/components/WispPanel.svelte.d.ts +49 -0
- package/dist/components/custom/ContentWithGutter.svelte +7 -13
- package/dist/components/custom/TableOfContents.svelte +12 -1
- package/dist/components/quota/UpgradePrompt.svelte +1 -0
- package/dist/config/wisp.d.ts +145 -0
- package/dist/config/wisp.js +175 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/server/inference-client.d.ts +139 -0
- package/dist/server/inference-client.js +294 -0
- package/dist/ui/components/forms/SearchInput.svelte +0 -1
- package/dist/ui/components/gallery/ImageGallery.svelte +14 -3
- package/dist/ui/components/gallery/Lightbox.svelte +8 -3
- package/dist/ui/components/gallery/ZoomableImage.svelte +12 -2
- package/dist/ui/components/nature/Logo.svelte +55 -19
- package/dist/ui/components/nature/botanical/LeafFalling.svelte +2 -2
- package/dist/ui/components/nature/botanical/PetalFalling.svelte +7 -7
- package/dist/ui/components/nature/ground/Crocus.svelte +3 -3
- package/dist/ui/components/nature/ground/Daffodil.svelte +3 -3
- package/dist/ui/components/nature/ground/Tulip.svelte +5 -5
- package/dist/ui/components/nature/palette.d.ts +187 -76
- package/dist/ui/components/nature/palette.js +169 -81
- package/dist/ui/components/nature/trees/TreeCherry.svelte +3 -3
- package/dist/ui/components/nature/trees/TreeCherry.svelte.d.ts +1 -1
- package/dist/ui/components/nature/trees/TreePine.svelte +2 -2
- package/dist/ui/components/nature/trees/TreePine.svelte.d.ts +1 -1
- package/dist/ui/components/primitives/textarea/textarea.svelte +1 -1
- package/dist/ui/components/typography/Alagard.svelte +17 -0
- package/dist/ui/components/typography/Alagard.svelte.d.ts +10 -0
- package/dist/ui/components/typography/Atkinson.svelte +17 -0
- package/dist/ui/components/typography/Atkinson.svelte.d.ts +10 -0
- package/dist/ui/components/typography/Calistoga.svelte +17 -0
- package/dist/ui/components/typography/Calistoga.svelte.d.ts +10 -0
- package/dist/ui/components/typography/Caveat.svelte +17 -0
- package/dist/ui/components/typography/Caveat.svelte.d.ts +10 -0
- package/dist/ui/components/typography/Cozette.svelte +17 -0
- package/dist/ui/components/typography/Cozette.svelte.d.ts +10 -0
- package/dist/ui/components/typography/FontProvider.svelte +98 -0
- package/dist/ui/components/typography/FontProvider.svelte.d.ts +17 -0
- package/dist/ui/components/typography/IBMPlexMono.svelte +17 -0
- package/dist/ui/components/typography/IBMPlexMono.svelte.d.ts +10 -0
- package/dist/ui/components/typography/Lexend.svelte +17 -0
- package/dist/ui/components/typography/Lexend.svelte.d.ts +10 -0
- package/dist/ui/components/typography/OpenDyslexic.svelte +17 -0
- package/dist/ui/components/typography/OpenDyslexic.svelte.d.ts +10 -0
- package/dist/ui/components/typography/PlusJakartaSans.svelte +17 -0
- package/dist/ui/components/typography/PlusJakartaSans.svelte.d.ts +10 -0
- package/dist/ui/components/typography/Quicksand.svelte +17 -0
- package/dist/ui/components/typography/Quicksand.svelte.d.ts +10 -0
- package/dist/ui/components/typography/README.md +153 -0
- package/dist/ui/components/typography/index.d.ts +13 -0
- package/dist/ui/components/typography/index.js +31 -0
- package/dist/ui/components/ui/CollapsibleSection.svelte +10 -0
- package/dist/ui/components/ui/GlassCarousel.svelte +446 -0
- package/dist/ui/components/ui/GlassCarousel.svelte.d.ts +57 -0
- package/dist/ui/components/ui/GlassConfirmDialog.svelte +2 -1
- package/dist/ui/components/ui/GlassLogo.svelte +2 -1
- package/dist/ui/components/ui/GlassOverlay.svelte +1 -1
- package/dist/ui/components/ui/index.d.ts +1 -0
- package/dist/ui/components/ui/index.js +1 -0
- package/dist/ui/index.d.ts +1 -0
- package/dist/ui/index.js +2 -0
- package/dist/ui/tokens/fonts.d.ts +1 -1
- package/dist/ui/tokens/fonts.js +0 -126
- package/dist/ui/vineyard/index.d.ts +9 -0
- package/dist/ui/vineyard/index.js +8 -0
- package/dist/utils/csrf.js +5 -2
- package/dist/utils/readability.d.ts +89 -0
- package/dist/utils/readability.js +204 -0
- package/package.json +38 -21
- package/static/fonts/alagard.ttf +0 -0
- package/LICENSE +0 -378
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onMount } from 'svelte';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
import type { FontId } from '../../tokens/fonts.js';
|
|
5
|
+
import { fontById, getFontUrl, getFontStack } from '../../tokens/fonts.js';
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
/** The font ID to apply */
|
|
9
|
+
font: FontId;
|
|
10
|
+
/** HTML element to render as */
|
|
11
|
+
as?: 'span' | 'div' | 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'code' | 'pre' | 'article' | 'section';
|
|
12
|
+
/** Additional CSS classes */
|
|
13
|
+
class?: string;
|
|
14
|
+
/** Inline styles */
|
|
15
|
+
style?: string;
|
|
16
|
+
/** Content to render */
|
|
17
|
+
children: Snippet;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
let { font, as = 'span', class: className = '', style = '', children }: Props = $props();
|
|
21
|
+
|
|
22
|
+
const fontDef = $derived(fontById[font]);
|
|
23
|
+
const fontStack = $derived(fontDef ? getFontStack(font) : 'inherit');
|
|
24
|
+
const combinedStyle = $derived(`font-family: ${fontStack};${style ? ` ${style}` : ''}`);
|
|
25
|
+
|
|
26
|
+
// Ensure the font is loaded (inject @font-face if not already present)
|
|
27
|
+
onMount(() => {
|
|
28
|
+
if (!fontDef) return;
|
|
29
|
+
|
|
30
|
+
const styleId = `grove-font-${font}`;
|
|
31
|
+
if (document.getElementById(styleId)) return;
|
|
32
|
+
|
|
33
|
+
const styleEl = document.createElement('style');
|
|
34
|
+
styleEl.id = styleId;
|
|
35
|
+
styleEl.textContent = `
|
|
36
|
+
@font-face {
|
|
37
|
+
font-family: '${fontDef.fontFamily}';
|
|
38
|
+
src: url('${getFontUrl(fontDef.file)}') format('${fontDef.format}');
|
|
39
|
+
font-weight: normal;
|
|
40
|
+
font-style: normal;
|
|
41
|
+
font-display: swap;
|
|
42
|
+
}
|
|
43
|
+
`;
|
|
44
|
+
document.head.appendChild(styleEl);
|
|
45
|
+
});
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
{#if as === 'div'}
|
|
49
|
+
<div class={className} style={combinedStyle}>
|
|
50
|
+
{@render children()}
|
|
51
|
+
</div>
|
|
52
|
+
{:else if as === 'p'}
|
|
53
|
+
<p class={className} style={combinedStyle}>
|
|
54
|
+
{@render children()}
|
|
55
|
+
</p>
|
|
56
|
+
{:else if as === 'h1'}
|
|
57
|
+
<h1 class={className} style={combinedStyle}>
|
|
58
|
+
{@render children()}
|
|
59
|
+
</h1>
|
|
60
|
+
{:else if as === 'h2'}
|
|
61
|
+
<h2 class={className} style={combinedStyle}>
|
|
62
|
+
{@render children()}
|
|
63
|
+
</h2>
|
|
64
|
+
{:else if as === 'h3'}
|
|
65
|
+
<h3 class={className} style={combinedStyle}>
|
|
66
|
+
{@render children()}
|
|
67
|
+
</h3>
|
|
68
|
+
{:else if as === 'h4'}
|
|
69
|
+
<h4 class={className} style={combinedStyle}>
|
|
70
|
+
{@render children()}
|
|
71
|
+
</h4>
|
|
72
|
+
{:else if as === 'h5'}
|
|
73
|
+
<h5 class={className} style={combinedStyle}>
|
|
74
|
+
{@render children()}
|
|
75
|
+
</h5>
|
|
76
|
+
{:else if as === 'h6'}
|
|
77
|
+
<h6 class={className} style={combinedStyle}>
|
|
78
|
+
{@render children()}
|
|
79
|
+
</h6>
|
|
80
|
+
{:else if as === 'code'}
|
|
81
|
+
<code class={className} style={combinedStyle}>
|
|
82
|
+
{@render children()}
|
|
83
|
+
</code>
|
|
84
|
+
{:else if as === 'pre'}
|
|
85
|
+
<pre class={className} style={combinedStyle}>{@render children()}</pre>
|
|
86
|
+
{:else if as === 'article'}
|
|
87
|
+
<article class={className} style={combinedStyle}>
|
|
88
|
+
{@render children()}
|
|
89
|
+
</article>
|
|
90
|
+
{:else if as === 'section'}
|
|
91
|
+
<section class={className} style={combinedStyle}>
|
|
92
|
+
{@render children()}
|
|
93
|
+
</section>
|
|
94
|
+
{:else}
|
|
95
|
+
<span class={className} style={combinedStyle}>
|
|
96
|
+
{@render children()}
|
|
97
|
+
</span>
|
|
98
|
+
{/if}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { FontId } from '../../tokens/fonts.js';
|
|
3
|
+
interface Props {
|
|
4
|
+
/** The font ID to apply */
|
|
5
|
+
font: FontId;
|
|
6
|
+
/** HTML element to render as */
|
|
7
|
+
as?: 'span' | 'div' | 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'code' | 'pre' | 'article' | 'section';
|
|
8
|
+
/** Additional CSS classes */
|
|
9
|
+
class?: string;
|
|
10
|
+
/** Inline styles */
|
|
11
|
+
style?: string;
|
|
12
|
+
/** Content to render */
|
|
13
|
+
children: Snippet;
|
|
14
|
+
}
|
|
15
|
+
declare const FontProvider: import("svelte").Component<Props, {}, "">;
|
|
16
|
+
type FontProvider = ReturnType<typeof FontProvider>;
|
|
17
|
+
export default FontProvider;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import FontProvider from './FontProvider.svelte';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
as?: 'span' | 'div' | 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'code' | 'pre' | 'article' | 'section';
|
|
7
|
+
class?: string;
|
|
8
|
+
style?: string;
|
|
9
|
+
children: Snippet;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let { as = 'span', class: className = '', style = '', children }: Props = $props();
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<FontProvider font="ibm-plex-mono" {as} class={className} {style}>
|
|
16
|
+
{@render children()}
|
|
17
|
+
</FontProvider>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
as?: 'span' | 'div' | 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'code' | 'pre' | 'article' | 'section';
|
|
4
|
+
class?: string;
|
|
5
|
+
style?: string;
|
|
6
|
+
children: Snippet;
|
|
7
|
+
}
|
|
8
|
+
declare const IBMPlexMono: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type IBMPlexMono = ReturnType<typeof IBMPlexMono>;
|
|
10
|
+
export default IBMPlexMono;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import FontProvider from './FontProvider.svelte';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
as?: 'span' | 'div' | 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'code' | 'pre' | 'article' | 'section';
|
|
7
|
+
class?: string;
|
|
8
|
+
style?: string;
|
|
9
|
+
children: Snippet;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let { as = 'span', class: className = '', style = '', children }: Props = $props();
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<FontProvider font="lexend" {as} class={className} {style}>
|
|
16
|
+
{@render children()}
|
|
17
|
+
</FontProvider>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
as?: 'span' | 'div' | 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'code' | 'pre' | 'article' | 'section';
|
|
4
|
+
class?: string;
|
|
5
|
+
style?: string;
|
|
6
|
+
children: Snippet;
|
|
7
|
+
}
|
|
8
|
+
declare const Lexend: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type Lexend = ReturnType<typeof Lexend>;
|
|
10
|
+
export default Lexend;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import FontProvider from './FontProvider.svelte';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
as?: 'span' | 'div' | 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'code' | 'pre' | 'article' | 'section';
|
|
7
|
+
class?: string;
|
|
8
|
+
style?: string;
|
|
9
|
+
children: Snippet;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let { as = 'span', class: className = '', style = '', children }: Props = $props();
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<FontProvider font="opendyslexic" {as} class={className} {style}>
|
|
16
|
+
{@render children()}
|
|
17
|
+
</FontProvider>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
as?: 'span' | 'div' | 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'code' | 'pre' | 'article' | 'section';
|
|
4
|
+
class?: string;
|
|
5
|
+
style?: string;
|
|
6
|
+
children: Snippet;
|
|
7
|
+
}
|
|
8
|
+
declare const OpenDyslexic: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type OpenDyslexic = ReturnType<typeof OpenDyslexic>;
|
|
10
|
+
export default OpenDyslexic;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import FontProvider from './FontProvider.svelte';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
as?: 'span' | 'div' | 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'code' | 'pre' | 'article' | 'section';
|
|
7
|
+
class?: string;
|
|
8
|
+
style?: string;
|
|
9
|
+
children: Snippet;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let { as = 'span', class: className = '', style = '', children }: Props = $props();
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<FontProvider font="plus-jakarta-sans" {as} class={className} {style}>
|
|
16
|
+
{@render children()}
|
|
17
|
+
</FontProvider>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
as?: 'span' | 'div' | 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'code' | 'pre' | 'article' | 'section';
|
|
4
|
+
class?: string;
|
|
5
|
+
style?: string;
|
|
6
|
+
children: Snippet;
|
|
7
|
+
}
|
|
8
|
+
declare const PlusJakartaSans: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type PlusJakartaSans = ReturnType<typeof PlusJakartaSans>;
|
|
10
|
+
export default PlusJakartaSans;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import FontProvider from './FontProvider.svelte';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
as?: 'span' | 'div' | 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'code' | 'pre' | 'article' | 'section';
|
|
7
|
+
class?: string;
|
|
8
|
+
style?: string;
|
|
9
|
+
children: Snippet;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let { as = 'span', class: className = '', style = '', children }: Props = $props();
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<FontProvider font="quicksand" {as} class={className} {style}>
|
|
16
|
+
{@render children()}
|
|
17
|
+
</FontProvider>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
as?: 'span' | 'div' | 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'code' | 'pre' | 'article' | 'section';
|
|
4
|
+
class?: string;
|
|
5
|
+
style?: string;
|
|
6
|
+
children: Snippet;
|
|
7
|
+
}
|
|
8
|
+
declare const Quicksand: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type Quicksand = ReturnType<typeof Quicksand>;
|
|
10
|
+
export default Quicksand;
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Typography Components
|
|
2
|
+
|
|
3
|
+
Scoped font wrapper components for the Grove Design System. Each component loads its font from CDN on-demand and applies it to children.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { Alagard, IBMPlexMono, Caveat } from '@autumnsgrove/groveengine/ui/typography';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```svelte
|
|
14
|
+
<!-- Fantasy game header -->
|
|
15
|
+
<Alagard as="h1" class="text-4xl">Welcome to the Grove</Alagard>
|
|
16
|
+
|
|
17
|
+
<!-- Code block -->
|
|
18
|
+
<IBMPlexMono as="code">console.log('hello');</IBMPlexMono>
|
|
19
|
+
|
|
20
|
+
<!-- Handwritten note -->
|
|
21
|
+
<Caveat as="p" class="text-2xl">A personal touch...</Caveat>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Available Fonts
|
|
25
|
+
|
|
26
|
+
### Display & Special (3)
|
|
27
|
+
| Component | Font | Use Case |
|
|
28
|
+
|-----------|------|----------|
|
|
29
|
+
| `Alagard` | Alagard | Fantasy, gaming, medieval themes |
|
|
30
|
+
| `Calistoga` | Calistoga | Friendly headlines, warm branding |
|
|
31
|
+
| `Caveat` | Caveat | Handwritten notes, personal touches |
|
|
32
|
+
|
|
33
|
+
### Serif (6)
|
|
34
|
+
| Component | Font | Use Case |
|
|
35
|
+
|-----------|------|----------|
|
|
36
|
+
| `Cormorant` | Cormorant | Elegant headers, editorial |
|
|
37
|
+
| `BodoniModa` | Bodoni Moda | High fashion, sophisticated |
|
|
38
|
+
| `Lora` | Lora | Body text, readable articles |
|
|
39
|
+
| `EBGaramond` | EB Garamond | Book typography, classic feel |
|
|
40
|
+
| `Merriweather` | Merriweather | Screen reading, long-form content |
|
|
41
|
+
| `Fraunces` | Fraunces | Warm personality, soft serif |
|
|
42
|
+
|
|
43
|
+
### Sans-Serif (6)
|
|
44
|
+
| Component | Font | Use Case |
|
|
45
|
+
|-----------|------|----------|
|
|
46
|
+
| `Lexend` | Lexend | Default, highly readable UI |
|
|
47
|
+
| `Nunito` | Nunito | Friendly, approachable interfaces |
|
|
48
|
+
| `Quicksand` | Quicksand | Light, modern, geometric |
|
|
49
|
+
| `Manrope` | Manrope | Professional, clean interfaces |
|
|
50
|
+
| `InstrumentSans` | Instrument Sans | Elegant simplicity |
|
|
51
|
+
| `PlusJakartaSans` | Plus Jakarta Sans | Balanced, versatile |
|
|
52
|
+
|
|
53
|
+
### Monospace (2)
|
|
54
|
+
| Component | Font | Use Case |
|
|
55
|
+
|-----------|------|----------|
|
|
56
|
+
| `IBMPlexMono` | IBM Plex Mono | Code blocks, technical content |
|
|
57
|
+
| `Cozette` | Cozette | Retro terminal, pixel aesthetic |
|
|
58
|
+
|
|
59
|
+
### Accessibility (3)
|
|
60
|
+
| Component | Font | Use Case |
|
|
61
|
+
|-----------|------|----------|
|
|
62
|
+
| `Atkinson` | Atkinson Hyperlegible | Low vision readers |
|
|
63
|
+
| `OpenDyslexic` | OpenDyslexic | Dyslexic readers |
|
|
64
|
+
| `Luciole` | Luciole | Visually impaired readers |
|
|
65
|
+
|
|
66
|
+
## Props
|
|
67
|
+
|
|
68
|
+
All font components accept the same props:
|
|
69
|
+
|
|
70
|
+
| Prop | Type | Default | Description |
|
|
71
|
+
|------|------|---------|-------------|
|
|
72
|
+
| `as` | `'span' \| 'div' \| 'p' \| 'h1' \| 'h2' \| 'h3' \| 'h4' \| 'h5' \| 'h6' \| 'code' \| 'pre' \| 'article' \| 'section'` | `'span'` | HTML element to render |
|
|
73
|
+
| `class` | `string` | `''` | CSS classes (Tailwind works great) |
|
|
74
|
+
| `style` | `string` | `''` | Inline styles |
|
|
75
|
+
|
|
76
|
+
## Dynamic Font Selection
|
|
77
|
+
|
|
78
|
+
Use `FontProvider` when you need to select fonts programmatically:
|
|
79
|
+
|
|
80
|
+
```svelte
|
|
81
|
+
<script>
|
|
82
|
+
import { FontProvider } from '@autumnsgrove/groveengine/ui/typography';
|
|
83
|
+
let selectedFont = 'cormorant';
|
|
84
|
+
</script>
|
|
85
|
+
|
|
86
|
+
<FontProvider font={selectedFont} as="article">
|
|
87
|
+
<p>Content with dynamic font...</p>
|
|
88
|
+
</FontProvider>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Performance
|
|
92
|
+
|
|
93
|
+
- **On-demand loading**: Fonts load from CDN only when the component mounts
|
|
94
|
+
- **Deduplication**: Each font's `@font-face` is injected once, even with multiple instances
|
|
95
|
+
- **Swap display**: Uses `font-display: swap` for fast initial render
|
|
96
|
+
- **CDN**: All fonts served from `cdn.grove.place` with proper caching
|
|
97
|
+
|
|
98
|
+
## Accessibility Recommendations
|
|
99
|
+
|
|
100
|
+
| Situation | Recommended Font |
|
|
101
|
+
|-----------|-----------------|
|
|
102
|
+
| Low vision users | `Atkinson` (maximum character distinction) |
|
|
103
|
+
| Dyslexic readers | `OpenDyslexic` (weighted letter bottoms) |
|
|
104
|
+
| General accessibility | `Lexend` (designed for reading fluency) |
|
|
105
|
+
| Long-form reading | `Merriweather` or `Lora` (optimized for screens) |
|
|
106
|
+
|
|
107
|
+
## Examples
|
|
108
|
+
|
|
109
|
+
### Blog Post Header
|
|
110
|
+
```svelte
|
|
111
|
+
<Fraunces as="h1" class="text-4xl font-bold text-bark-900">
|
|
112
|
+
A Warm Welcome to the Grove
|
|
113
|
+
</Fraunces>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Code Documentation
|
|
117
|
+
```svelte
|
|
118
|
+
<IBMPlexMono as="pre" class="bg-bark-900 text-cream-100 p-4 rounded-lg">
|
|
119
|
+
{codeExample}
|
|
120
|
+
</IBMPlexMono>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Personal Note Card
|
|
124
|
+
```svelte
|
|
125
|
+
<div class="bg-rose-50 p-6 rounded-lg">
|
|
126
|
+
<Caveat as="p" class="text-2xl text-rose-900">
|
|
127
|
+
Thanks for being here...
|
|
128
|
+
</Caveat>
|
|
129
|
+
</div>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Mixed Typography
|
|
133
|
+
```svelte
|
|
134
|
+
<article>
|
|
135
|
+
<Alagard as="h1" class="text-3xl mb-4">Quest Log</Alagard>
|
|
136
|
+
<Lora as="div" class="prose">
|
|
137
|
+
<p>Your journey begins in the misty forests...</p>
|
|
138
|
+
</Lora>
|
|
139
|
+
</article>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Font Tokens
|
|
143
|
+
|
|
144
|
+
The typography module also exports font metadata for programmatic use:
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
import {
|
|
148
|
+
fonts, // Array of all font definitions
|
|
149
|
+
fontById, // Map of font ID to definition
|
|
150
|
+
getFontStack, // Get full font-family string with fallbacks
|
|
151
|
+
getFontUrl, // Get CDN URL for a font file
|
|
152
|
+
} from '@autumnsgrove/groveengine/ui/typography';
|
|
153
|
+
```
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { default as FontProvider } from './FontProvider.svelte';
|
|
2
|
+
export { default as Lexend } from './Lexend.svelte';
|
|
3
|
+
export { default as Atkinson } from './Atkinson.svelte';
|
|
4
|
+
export { default as OpenDyslexic } from './OpenDyslexic.svelte';
|
|
5
|
+
export { default as Quicksand } from './Quicksand.svelte';
|
|
6
|
+
export { default as PlusJakartaSans } from './PlusJakartaSans.svelte';
|
|
7
|
+
export { default as IBMPlexMono } from './IBMPlexMono.svelte';
|
|
8
|
+
export { default as Cozette } from './Cozette.svelte';
|
|
9
|
+
export { default as Alagard } from './Alagard.svelte';
|
|
10
|
+
export { default as Calistoga } from './Calistoga.svelte';
|
|
11
|
+
export { default as Caveat } from './Caveat.svelte';
|
|
12
|
+
export { fonts, fontById, fontMap, getFontUrl, getFontStack, getFontsByCategory, generateFontFace, generateAllFontFaces, FONT_CDN_BASE, DEFAULT_FONT, FONT_COUNT, fontCategoryLabels, type FontId, type FontCategory, type FontFormat, type FontDefinition, } from '../../tokens/fonts.js';
|
|
13
|
+
export declare const TYPOGRAPHY_VERSION = "0.1.0";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// GroveUI - Typography Components
|
|
2
|
+
//
|
|
3
|
+
// Font wrapper components for scoped font application.
|
|
4
|
+
// Each component automatically loads the font from CDN and applies it to children.
|
|
5
|
+
//
|
|
6
|
+
// Usage:
|
|
7
|
+
// import { Alagard, IBMPlexMono, Caveat } from '@autumnsgrove/groveengine/ui/typography';
|
|
8
|
+
//
|
|
9
|
+
// <Alagard as="h1">Fantasy Header</Alagard>
|
|
10
|
+
// <IBMPlexMono as="code">console.log('code')</IBMPlexMono>
|
|
11
|
+
// <Caveat as="p" class="text-xl">Handwritten note</Caveat>
|
|
12
|
+
// Base provider (for dynamic font selection)
|
|
13
|
+
export { default as FontProvider } from './FontProvider.svelte';
|
|
14
|
+
// Default font
|
|
15
|
+
export { default as Lexend } from './Lexend.svelte';
|
|
16
|
+
// Accessibility fonts
|
|
17
|
+
export { default as Atkinson } from './Atkinson.svelte';
|
|
18
|
+
export { default as OpenDyslexic } from './OpenDyslexic.svelte';
|
|
19
|
+
// Sans-serif fonts
|
|
20
|
+
export { default as Quicksand } from './Quicksand.svelte';
|
|
21
|
+
export { default as PlusJakartaSans } from './PlusJakartaSans.svelte';
|
|
22
|
+
// Monospace fonts
|
|
23
|
+
export { default as IBMPlexMono } from './IBMPlexMono.svelte';
|
|
24
|
+
export { default as Cozette } from './Cozette.svelte';
|
|
25
|
+
// Display/special fonts
|
|
26
|
+
export { default as Alagard } from './Alagard.svelte';
|
|
27
|
+
export { default as Calistoga } from './Calistoga.svelte';
|
|
28
|
+
export { default as Caveat } from './Caveat.svelte';
|
|
29
|
+
// Re-export font tokens for convenience
|
|
30
|
+
export { fonts, fontById, fontMap, getFontUrl, getFontStack, getFontsByCategory, generateFontFace, generateAllFontFaces, FONT_CDN_BASE, DEFAULT_FONT, FONT_COUNT, fontCategoryLabels, } from '../../tokens/fonts.js';
|
|
31
|
+
export const TYPOGRAPHY_VERSION = '0.1.0';
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
let {
|
|
12
12
|
title,
|
|
13
13
|
defaultOpen = false,
|
|
14
|
+
open: externalOpen,
|
|
15
|
+
ontoggle,
|
|
14
16
|
children,
|
|
15
17
|
class: className = '',
|
|
16
18
|
...restProps
|
|
@@ -18,8 +20,16 @@
|
|
|
18
20
|
|
|
19
21
|
let isOpen = $state(defaultOpen);
|
|
20
22
|
|
|
23
|
+
// Sync with external open prop if provided
|
|
24
|
+
$effect(() => {
|
|
25
|
+
if (externalOpen !== undefined) {
|
|
26
|
+
isOpen = externalOpen;
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
|
|
21
30
|
function toggle() {
|
|
22
31
|
isOpen = !isOpen;
|
|
32
|
+
ontoggle?.();
|
|
23
33
|
}
|
|
24
34
|
</script>
|
|
25
35
|
|