@invisibleloop/pulse 0.20.11 → 0.20.20
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/package.json +6 -5
- package/public/.pulse-ui-version +1 -1
- package/scripts/build.js +26 -0
- package/scripts/release-version.js +17 -8
- package/scripts/strip-server.test.js +60 -0
- package/src/agent/checklist.md +8 -12
- package/src/agent/commands/pulse-start.md +2 -0
- package/src/agent/commands/verify.md +30 -8
- package/src/agent/guide-components.md +7 -25
- package/src/agent/guide-routing.md +0 -12
- package/src/agent/guide-server.md +102 -1
- package/src/agent/guide-spec.md +8 -1
- package/src/agent/guide-styles.md +23 -0
- package/src/agent/identity.md +9 -0
- package/src/agent/workflow.md +4 -23
- package/src/cli/check-bundles.js +113 -0
- package/src/cli/check-bundles.test.js +137 -0
- package/src/cli/cli.test.js +105 -0
- package/src/cli/dev.js +48 -3
- package/src/cli/diagnose.js +105 -0
- package/src/cli/diagnose.test.js +124 -0
- package/src/cli/discover.js +9 -2
- package/src/cli/index.js +171 -9
- package/src/cli/process-utils.js +57 -0
- package/src/cli/process-utils.test.js +114 -0
- package/src/cli/review.js +391 -0
- package/src/cli/review.test.js +143 -0
- package/src/cli/scaffold.js +9 -4
- package/src/cli/stamp.js +102 -0
- package/src/cli/stamp.test.js +149 -0
- package/src/cli/start.js +15 -2
- package/src/cli/validate.js +184 -0
- package/src/cli/validate.test.js +153 -0
- package/src/mcp/mcp.test.js +261 -30
- package/src/mcp/server.js +207 -515
- package/src/mcp/validate-worker.js +18 -1
- package/src/runtime/index.js +144 -11
- package/src/runtime/runtime.test.js +199 -0
- package/src/runtime/ssr.js +13 -6
- package/src/runtime/ssr.test.js +31 -0
- package/src/server/index.js +162 -9
- package/src/server/server.test.js +225 -2
- package/src/spec/schema.js +1 -1
- package/src/ui/index.js +0 -5
- package/src/ui/ui.test.js +0 -75
- package/types/ui.d.ts +0 -21
- package/.claude/commands/build-page.md +0 -63
- package/.claude/commands/new-doc-page.md +0 -45
- package/.claude/commands/pulse-start.md +0 -11
- package/.claude/commands/pulse-stop.md +0 -5
- package/.claude/commands/verify.md +0 -118
- package/.claude/pulse-checklist.md +0 -189
- package/.github/workflows/ci.yml +0 -25
- package/.github/workflows/publish.yml +0 -45
- package/.pulse/load-reports/home/1773432711417.json +0 -22
- package/.pulse-verified +0 -1
- package/AGENTS.md +0 -697
- package/CLAUDE.md +0 -697
- package/README.md +0 -95
- package/benchmark/public/dist/counter.boot-PO6SNSJZ.js +0 -8
- package/benchmark/public/dist/home.boot-YK6VAEQI.js +0 -6
- package/benchmark/public/dist/manifest.json +0 -5
- package/benchmark/public/dist/runtime-5Y7ESAIB.js +0 -2
- package/benchmark/public/dist/runtime-KO4BHUQ3.js +0 -49
- package/benchmark/results/2026-03-27-09-20.json +0 -188
- package/benchmark/results/2026-03-27-09-21.json +0 -188
- package/benchmark/results/2026-03-27-09-29.json +0 -188
- package/benchmark/results/2026-03-27-10-14.json +0 -188
- package/benchmark/results/2026-03-27-10-18.json +0 -232
- package/benchmark/src/pages/counter.js +0 -37
- package/benchmark/src/pages/home.js +0 -21
- package/docs/.claude/commands/pulse-build.md +0 -7
- package/docs/.claude/commands/pulse-dev.md +0 -7
- package/docs/.claude/commands/pulse-start.md +0 -9
- package/docs/.claude/commands/pulse-stop.md +0 -5
- package/docs/.claude/commands/verify.md +0 -84
- package/docs/.claude/coverage-check.js +0 -196
- package/docs/.claude/pulse-checklist.md +0 -189
- package/docs/public/.pulse-ui-version +0 -1
- package/docs/public/andypixel.css +0 -237
- package/docs/public/bookworms.css +0 -422
- package/docs/public/coutumes.css +0 -561
- package/docs/public/docs.css +0 -2388
- package/docs/public/favicon.svg +0 -4
- package/docs/public/home-brut.css +0 -982
- package/docs/public/images/bookworms/hero-books.jpg +0 -0
- package/docs/public/images/bookworms/how-we-read-now.jpg +0 -0
- package/docs/public/images/bookworms/lantern-keepers.jpg +0 -0
- package/docs/public/images/bookworms/provincial-bookseller.jpg +0 -0
- package/docs/public/images/journey/178.jpg +0 -0
- package/docs/public/images/journey/29.jpg +0 -0
- package/docs/public/images/retrowheels/hero.jpg +0 -0
- package/docs/public/images/shop/devbook-pro.jpg +0 -0
- package/docs/public/images/suzukibento/1015.jpg +0 -0
- package/docs/public/images/suzukibento/1025.jpg +0 -0
- package/docs/public/images/suzukibento/1043.jpg +0 -0
- package/docs/public/images/suzukibento/1059.jpg +0 -0
- package/docs/public/images/suzukibento/1062.jpg +0 -0
- package/docs/public/images/suzukibento/1084.jpg +0 -0
- package/docs/public/images/swish/1469334031218-e382a71b716b.jpg +0 -0
- package/docs/public/images/swish/1483985988355-763728e1935b.jpg +0 -0
- package/docs/public/images/swish/1485518882345-15568b007407.jpg +0 -0
- package/docs/public/images/swish/1490481651871-ab68de25d43d.jpg +0 -0
- package/docs/public/images/swish/1496747611176-843222e1e57c.jpg +0 -0
- package/docs/public/images/swish/1502716119720-b23a93e5fe1b.jpg +0 -0
- package/docs/public/images/swish/1539109136881-3be0616acf4b.jpg +0 -0
- package/docs/public/images/swish/1551803091-e20673f15770.jpg +0 -0
- package/docs/public/images/swish/1558769132-cb1aea458c5e.jpg +0 -0
- package/docs/public/images/swish/1572804013309-59a88b7e92f1.jpg +0 -0
- package/docs/public/img/heic1501a.jpg +0 -0
- package/docs/public/img/placeholder-landscape.svg +0 -18
- package/docs/public/img/placeholder-square.svg +0 -14
- package/docs/public/img/placeholder-tall.svg +0 -22
- package/docs/public/journey.css +0 -528
- package/docs/public/menu.js +0 -327
- package/docs/public/pulse-ui.css +0 -3028
- package/docs/public/pulse-ui.js +0 -257
- package/docs/public/retrowheels.css +0 -425
- package/docs/public/shop.css +0 -269
- package/docs/public/sparkys.css +0 -382
- package/docs/public/suzukibento.css +0 -517
- package/docs/public/swish.css +0 -394
- package/docs/public/theme.css +0 -52
- package/docs/public/themes/lumio.css +0 -50
- package/docs/public/themes/observatory.css +0 -104
- package/docs/server.js +0 -161
- package/docs/src/lib/component-page.js +0 -49
- package/docs/src/lib/highlight.js +0 -2
- package/docs/src/lib/layout.js +0 -190
- package/docs/src/lib/metrics-store.js +0 -6
- package/docs/src/lib/nav.js +0 -171
- package/docs/src/lib/stats.js +0 -81
- package/docs/src/pages/accessibility.js +0 -157
- package/docs/src/pages/actions.js +0 -194
- package/docs/src/pages/auth.js +0 -176
- package/docs/src/pages/caching.js +0 -95
- package/docs/src/pages/components/accordion.js +0 -48
- package/docs/src/pages/components/alert.js +0 -35
- package/docs/src/pages/components/app-badge.js +0 -41
- package/docs/src/pages/components/avatar.js +0 -35
- package/docs/src/pages/components/badge.js +0 -36
- package/docs/src/pages/components/breadcrumbs.js +0 -94
- package/docs/src/pages/components/button.js +0 -84
- package/docs/src/pages/components/card.js +0 -225
- package/docs/src/pages/components/charts.js +0 -283
- package/docs/src/pages/components/checkbox.js +0 -129
- package/docs/src/pages/components/cluster.js +0 -47
- package/docs/src/pages/components/container.js +0 -40
- package/docs/src/pages/components/cta.js +0 -54
- package/docs/src/pages/components/divider.js +0 -37
- package/docs/src/pages/components/empty.js +0 -36
- package/docs/src/pages/components/feature.js +0 -60
- package/docs/src/pages/components/fieldset.js +0 -65
- package/docs/src/pages/components/fileupload.js +0 -128
- package/docs/src/pages/components/footer.js +0 -58
- package/docs/src/pages/components/grid.js +0 -169
- package/docs/src/pages/components/heading.js +0 -107
- package/docs/src/pages/components/hero.js +0 -123
- package/docs/src/pages/components/icons.js +0 -410
- package/docs/src/pages/components/image.js +0 -71
- package/docs/src/pages/components/input.js +0 -51
- package/docs/src/pages/components/media.js +0 -51
- package/docs/src/pages/components/modal.js +0 -111
- package/docs/src/pages/components/nav.js +0 -136
- package/docs/src/pages/components/phone-frame.js +0 -74
- package/docs/src/pages/components/progress.js +0 -102
- package/docs/src/pages/components/prose.js +0 -111
- package/docs/src/pages/components/pullquote.js +0 -71
- package/docs/src/pages/components/radio.js +0 -194
- package/docs/src/pages/components/rating.js +0 -106
- package/docs/src/pages/components/search.js +0 -61
- package/docs/src/pages/components/section.js +0 -98
- package/docs/src/pages/components/segmented.js +0 -121
- package/docs/src/pages/components/select.js +0 -45
- package/docs/src/pages/components/slider.js +0 -115
- package/docs/src/pages/components/spinner.js +0 -73
- package/docs/src/pages/components/stack.js +0 -48
- package/docs/src/pages/components/stat.js +0 -55
- package/docs/src/pages/components/stepper.js +0 -66
- package/docs/src/pages/components/table.js +0 -45
- package/docs/src/pages/components/textarea.js +0 -31
- package/docs/src/pages/components/toggle.js +0 -84
- package/docs/src/pages/components/tooltip.js +0 -48
- package/docs/src/pages/components.js +0 -200
- package/docs/src/pages/config.js +0 -193
- package/docs/src/pages/constraints.js +0 -100
- package/docs/src/pages/deploy.js +0 -233
- package/docs/src/pages/error-pages.js +0 -99
- package/docs/src/pages/extending.js +0 -198
- package/docs/src/pages/faq.js +0 -99
- package/docs/src/pages/forms.js +0 -129
- package/docs/src/pages/getting-started.js +0 -147
- package/docs/src/pages/guard.js +0 -120
- package/docs/src/pages/home.js +0 -350
- package/docs/src/pages/how-it-works.js +0 -244
- package/docs/src/pages/hydration.js +0 -108
- package/docs/src/pages/images.js +0 -120
- package/docs/src/pages/markdown.js +0 -156
- package/docs/src/pages/meta.js +0 -193
- package/docs/src/pages/mutations.js +0 -107
- package/docs/src/pages/navigation.js +0 -85
- package/docs/src/pages/performance.js +0 -157
- package/docs/src/pages/persist.js +0 -89
- package/docs/src/pages/project-structure.js +0 -91
- package/docs/src/pages/prompt-examples.js +0 -186
- package/docs/src/pages/raw-responses.js +0 -122
- package/docs/src/pages/routing.js +0 -120
- package/docs/src/pages/server-api.js +0 -291
- package/docs/src/pages/server-data.js +0 -203
- package/docs/src/pages/slash-commands.js +0 -55
- package/docs/src/pages/spec.js +0 -207
- package/docs/src/pages/state.js +0 -102
- package/docs/src/pages/store.js +0 -203
- package/docs/src/pages/streaming.js +0 -107
- package/docs/src/pages/stripe.js +0 -194
- package/docs/src/pages/supabase.js +0 -324
- package/docs/src/pages/templates/andypixel.js +0 -260
- package/docs/src/pages/templates/blog-post.js +0 -226
- package/docs/src/pages/templates/bookworms.js +0 -227
- package/docs/src/pages/templates/coutumes.js +0 -237
- package/docs/src/pages/templates/journey.js +0 -186
- package/docs/src/pages/templates/mobile-app.js +0 -371
- package/docs/src/pages/templates/retrowheels.js +0 -355
- package/docs/src/pages/templates/shop.js +0 -268
- package/docs/src/pages/templates/sparkys.js +0 -264
- package/docs/src/pages/templates/suzukibento.js +0 -200
- package/docs/src/pages/templates/swish.js +0 -313
- package/docs/src/pages/templates.js +0 -534
- package/docs/src/pages/testing.js +0 -199
- package/docs/src/pages/validation.js +0 -138
- package/examples/.claude/commands/pulse-build.md +0 -7
- package/examples/.claude/commands/pulse-dev.md +0 -7
- package/examples/.claude/commands/pulse-start.md +0 -9
- package/examples/.claude/commands/pulse-stop.md +0 -5
- package/examples/.claude/commands/verify.md +0 -84
- package/examples/.claude/coverage-check.js +0 -196
- package/examples/.claude/pulse-checklist.md +0 -189
- package/examples/andypixel.css +0 -237
- package/examples/andypixel.js +0 -258
- package/examples/bookworms.css +0 -422
- package/examples/bookworms.js +0 -225
- package/examples/contact.js +0 -166
- package/examples/counter.js +0 -94
- package/examples/dev.server.js +0 -110
- package/examples/examples.test.js +0 -394
- package/examples/journey.css +0 -528
- package/examples/journey.js +0 -186
- package/examples/pricing.js +0 -262
- package/examples/products.js +0 -190
- package/examples/public/.pulse-ui-version +0 -1
- package/examples/public/pulse-ui.css +0 -3028
- package/examples/public/pulse-ui.js +0 -257
- package/examples/quiz.js +0 -208
- package/examples/retrowheels.css +0 -425
- package/examples/retrowheels.js +0 -353
- package/examples/shared.js +0 -84
- package/examples/suzukibento.css +0 -513
- package/examples/suzukibento.js +0 -200
- package/examples/swish.css +0 -394
- package/examples/swish.js +0 -311
- package/examples/todos.js +0 -162
- package/src/ui/fieldset.js +0 -37
- package/src/ui/phone-frame.js +0 -40
- package/src/ui/search.js +0 -78
- package/src/ui/segmented.js +0 -50
- package/src/ui/tooltip.js +0 -28
package/docs/server.js
DELETED
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import fs from 'fs'
|
|
2
|
-
import { createServer } from '../src/server/index.js'
|
|
3
|
-
import { initLayoutManifest } from './src/lib/layout.js'
|
|
4
|
-
import { metrics } from './src/lib/stats.js'
|
|
5
|
-
import { metricsStore } from './src/lib/metrics-store.js'
|
|
6
|
-
import { NAV } from './src/lib/nav.js'
|
|
7
|
-
metricsStore.current = metrics
|
|
8
|
-
|
|
9
|
-
// Build search index once at startup from nav structure
|
|
10
|
-
const searchIndex = JSON.stringify(
|
|
11
|
-
NAV.flatMap(({ section, items }) =>
|
|
12
|
-
items.map(item => ({ title: item.label, href: item.href, section, body: '' }))
|
|
13
|
-
)
|
|
14
|
-
)
|
|
15
|
-
const searchIndexEtag = `"${Buffer.from(searchIndex).length}-search"`
|
|
16
|
-
|
|
17
|
-
// Populate hashed asset paths in layout.js before any page renders
|
|
18
|
-
try {
|
|
19
|
-
const raw = fs.readFileSync(new URL('./public/dist/manifest.json', import.meta.url), 'utf8')
|
|
20
|
-
initLayoutManifest(JSON.parse(raw))
|
|
21
|
-
} catch { /* dev: no manifest yet, layout falls back to unhashed paths */ }
|
|
22
|
-
|
|
23
|
-
await createServer(
|
|
24
|
-
[
|
|
25
|
-
// Framework
|
|
26
|
-
new URL('./src/pages/home.js', import.meta.url),
|
|
27
|
-
new URL('./src/pages/how-it-works.js', import.meta.url),
|
|
28
|
-
new URL('./src/pages/faq.js', import.meta.url),
|
|
29
|
-
new URL('./src/pages/config.js', import.meta.url),
|
|
30
|
-
new URL('./src/pages/getting-started.js', import.meta.url),
|
|
31
|
-
new URL('./src/pages/slash-commands.js', import.meta.url),
|
|
32
|
-
new URL('./src/pages/prompt-examples.js', import.meta.url),
|
|
33
|
-
new URL('./src/pages/components.js', import.meta.url),
|
|
34
|
-
new URL('./src/pages/project-structure.js', import.meta.url),
|
|
35
|
-
new URL('./src/pages/spec.js', import.meta.url),
|
|
36
|
-
// State & Behaviour
|
|
37
|
-
new URL('./src/pages/state.js', import.meta.url),
|
|
38
|
-
new URL('./src/pages/mutations.js', import.meta.url),
|
|
39
|
-
new URL('./src/pages/actions.js', import.meta.url),
|
|
40
|
-
new URL('./src/pages/validation.js', import.meta.url),
|
|
41
|
-
new URL('./src/pages/constraints.js', import.meta.url),
|
|
42
|
-
new URL('./src/pages/persist.js', import.meta.url),
|
|
43
|
-
// Server
|
|
44
|
-
new URL('./src/pages/server-data.js', import.meta.url),
|
|
45
|
-
new URL('./src/pages/markdown.js', import.meta.url),
|
|
46
|
-
new URL('./src/pages/store.js', import.meta.url),
|
|
47
|
-
new URL('./src/pages/routing.js', import.meta.url),
|
|
48
|
-
new URL('./src/pages/error-pages.js', import.meta.url),
|
|
49
|
-
new URL('./src/pages/streaming.js', import.meta.url),
|
|
50
|
-
new URL('./src/pages/caching.js', import.meta.url),
|
|
51
|
-
new URL('./src/pages/guard.js', import.meta.url),
|
|
52
|
-
new URL('./src/pages/forms.js', import.meta.url),
|
|
53
|
-
new URL('./src/pages/raw-responses.js', import.meta.url),
|
|
54
|
-
new URL('./src/pages/server-api.js', import.meta.url),
|
|
55
|
-
new URL('./src/pages/extending.js', import.meta.url),
|
|
56
|
-
// Client
|
|
57
|
-
new URL('./src/pages/hydration.js', import.meta.url),
|
|
58
|
-
new URL('./src/pages/navigation.js', import.meta.url),
|
|
59
|
-
new URL('./src/pages/images.js', import.meta.url),
|
|
60
|
-
// Deployment
|
|
61
|
-
new URL('./src/pages/deploy.js', import.meta.url),
|
|
62
|
-
// Reference
|
|
63
|
-
new URL('./src/pages/meta.js', import.meta.url),
|
|
64
|
-
new URL('./src/pages/performance.js', import.meta.url),
|
|
65
|
-
new URL('./src/pages/accessibility.js', import.meta.url),
|
|
66
|
-
new URL('./src/pages/testing.js', import.meta.url),
|
|
67
|
-
// Integrations
|
|
68
|
-
new URL('./src/pages/supabase.js', import.meta.url),
|
|
69
|
-
new URL('./src/pages/auth.js', import.meta.url),
|
|
70
|
-
new URL('./src/pages/stripe.js', import.meta.url),
|
|
71
|
-
// UI Components
|
|
72
|
-
new URL('./src/pages/components/alert.js', import.meta.url),
|
|
73
|
-
new URL('./src/pages/components/avatar.js', import.meta.url),
|
|
74
|
-
new URL('./src/pages/components/badge.js', import.meta.url),
|
|
75
|
-
new URL('./src/pages/components/breadcrumbs.js', import.meta.url),
|
|
76
|
-
new URL('./src/pages/components/button.js', import.meta.url),
|
|
77
|
-
new URL('./src/pages/components/card.js', import.meta.url),
|
|
78
|
-
new URL('./src/pages/components/checkbox.js', import.meta.url),
|
|
79
|
-
new URL('./src/pages/components/charts.js', import.meta.url),
|
|
80
|
-
new URL('./src/pages/components/empty.js', import.meta.url),
|
|
81
|
-
new URL('./src/pages/components/fieldset.js', import.meta.url),
|
|
82
|
-
new URL('./src/pages/components/fileupload.js', import.meta.url),
|
|
83
|
-
new URL('./src/pages/components/heading.js', import.meta.url),
|
|
84
|
-
new URL('./src/pages/components/icons.js', import.meta.url),
|
|
85
|
-
new URL('./src/pages/components/image.js', import.meta.url),
|
|
86
|
-
new URL('./src/pages/components/input.js', import.meta.url),
|
|
87
|
-
new URL('./src/pages/components/modal.js', import.meta.url),
|
|
88
|
-
new URL('./src/pages/components/progress.js', import.meta.url),
|
|
89
|
-
new URL('./src/pages/components/prose.js', import.meta.url),
|
|
90
|
-
new URL('./src/pages/components/pullquote.js', import.meta.url),
|
|
91
|
-
new URL('./src/pages/components/radio.js', import.meta.url),
|
|
92
|
-
new URL('./src/pages/components/rating.js', import.meta.url),
|
|
93
|
-
new URL('./src/pages/components/search.js', import.meta.url),
|
|
94
|
-
new URL('./src/pages/components/segmented.js', import.meta.url),
|
|
95
|
-
new URL('./src/pages/components/select.js', import.meta.url),
|
|
96
|
-
new URL('./src/pages/components/slider.js', import.meta.url),
|
|
97
|
-
new URL('./src/pages/components/spinner.js', import.meta.url),
|
|
98
|
-
new URL('./src/pages/components/stat.js', import.meta.url),
|
|
99
|
-
new URL('./src/pages/components/stepper.js', import.meta.url),
|
|
100
|
-
new URL('./src/pages/components/table.js', import.meta.url),
|
|
101
|
-
new URL('./src/pages/components/textarea.js', import.meta.url),
|
|
102
|
-
new URL('./src/pages/components/toggle.js', import.meta.url),
|
|
103
|
-
new URL('./src/pages/components/tooltip.js', import.meta.url),
|
|
104
|
-
// Landing Components
|
|
105
|
-
new URL('./src/pages/components/accordion.js', import.meta.url),
|
|
106
|
-
new URL('./src/pages/components/app-badge.js', import.meta.url),
|
|
107
|
-
new URL('./src/pages/components/cta.js', import.meta.url),
|
|
108
|
-
new URL('./src/pages/components/feature.js', import.meta.url),
|
|
109
|
-
new URL('./src/pages/components/hero.js', import.meta.url),
|
|
110
|
-
new URL('./src/pages/components/nav.js', import.meta.url),
|
|
111
|
-
new URL('./src/pages/components/phone-frame.js', import.meta.url),
|
|
112
|
-
// Templates
|
|
113
|
-
new URL('./src/pages/templates.js', import.meta.url),
|
|
114
|
-
new URL('./src/pages/templates/mobile-app.js', import.meta.url),
|
|
115
|
-
new URL('./src/pages/templates/blog-post.js', import.meta.url),
|
|
116
|
-
new URL('./src/pages/templates/coutumes.js', import.meta.url),
|
|
117
|
-
new URL('./src/pages/templates/sparkys.js', import.meta.url),
|
|
118
|
-
new URL('./src/pages/templates/swish.js', import.meta.url),
|
|
119
|
-
new URL('./src/pages/templates/bookworms.js', import.meta.url),
|
|
120
|
-
new URL('./src/pages/templates/retrowheels.js', import.meta.url),
|
|
121
|
-
new URL('./src/pages/templates/suzukibento.js', import.meta.url),
|
|
122
|
-
new URL('./src/pages/templates/andypixel.js', import.meta.url),
|
|
123
|
-
new URL('./src/pages/templates/journey.js', import.meta.url),
|
|
124
|
-
new URL('./src/pages/templates/shop.js', import.meta.url),
|
|
125
|
-
// Layout Components
|
|
126
|
-
new URL('./src/pages/components/cluster.js', import.meta.url),
|
|
127
|
-
new URL('./src/pages/components/container.js', import.meta.url),
|
|
128
|
-
new URL('./src/pages/components/divider.js', import.meta.url),
|
|
129
|
-
new URL('./src/pages/components/footer.js', import.meta.url),
|
|
130
|
-
new URL('./src/pages/components/grid.js', import.meta.url),
|
|
131
|
-
new URL('./src/pages/components/media.js', import.meta.url),
|
|
132
|
-
new URL('./src/pages/components/section.js', import.meta.url),
|
|
133
|
-
new URL('./src/pages/components/stack.js', import.meta.url),
|
|
134
|
-
],
|
|
135
|
-
{
|
|
136
|
-
port: process.env.PORT ? Number(process.env.PORT) : 4000,
|
|
137
|
-
staticDir: new URL('./public', import.meta.url).pathname,
|
|
138
|
-
root: new URL('.', import.meta.url),
|
|
139
|
-
defaultCache: true,
|
|
140
|
-
csp: {
|
|
141
|
-
'img-src': ['https://picsum.photos', 'https://fastly.picsum.photos', 'https://images.unsplash.com'],
|
|
142
|
-
'style-src': ['https://fonts.googleapis.com'],
|
|
143
|
-
'font-src': ['https://fonts.gstatic.com'],
|
|
144
|
-
},
|
|
145
|
-
onRequest(req, res) {
|
|
146
|
-
if (req.url !== '/search-index.json') return
|
|
147
|
-
if (req.headers['if-none-match'] === searchIndexEtag) {
|
|
148
|
-
res.writeHead(304)
|
|
149
|
-
res.end()
|
|
150
|
-
return false
|
|
151
|
-
}
|
|
152
|
-
res.writeHead(200, {
|
|
153
|
-
'Content-Type': 'application/json; charset=utf-8',
|
|
154
|
-
'Cache-Control': 'public, max-age=3600',
|
|
155
|
-
'ETag': searchIndexEtag,
|
|
156
|
-
})
|
|
157
|
-
res.end(searchIndex)
|
|
158
|
-
return false
|
|
159
|
-
},
|
|
160
|
-
}
|
|
161
|
-
)
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pulse Docs — Component page factory
|
|
3
|
-
*
|
|
4
|
-
* renderComponentPage({ name, description, demos, props, prev, next, currentHref })
|
|
5
|
-
* Returns the HTML content string for a standard component doc page.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { renderLayout, h1, lead, codeBlock } from './layout.js'
|
|
9
|
-
import { highlight } from './highlight.js'
|
|
10
|
-
|
|
11
|
-
export function demo(previewHtml, codeStr, { col = false, scroll = false, bleed = false } = {}) {
|
|
12
|
-
const previewClass = [
|
|
13
|
-
'demo-preview',
|
|
14
|
-
'is-light',
|
|
15
|
-
col ? 'demo-preview--col' : '',
|
|
16
|
-
scroll ? 'demo-preview--scroll' : '',
|
|
17
|
-
bleed ? 'demo-preview--bleed' : '',
|
|
18
|
-
].filter(Boolean).join(' ')
|
|
19
|
-
const toggle = `<button class="demo-theme-toggle" aria-label="Toggle light/dark theme" title="Toggle theme">
|
|
20
|
-
<svg class="demo-theme-toggle__dark" width="14" height="14" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M21 12.79A9 9 0 1111.21 3a7 7 0 109.79 9.79z"/></svg>
|
|
21
|
-
<svg class="demo-theme-toggle__light" width="14" height="14" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><circle cx="12" cy="12" r="5"/><path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
|
|
22
|
-
</button>`
|
|
23
|
-
return `<div class="component-demo">
|
|
24
|
-
<div class="${previewClass}">${toggle}<div class="demo-preview-inner ui-theme-light">${previewHtml}</div></div>
|
|
25
|
-
<div class="demo-code">${codeBlock(highlight(codeStr, 'js'))}</div>
|
|
26
|
-
</div>`
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* @param {object} opts
|
|
31
|
-
* @param {string} opts.currentHref - The route of this page
|
|
32
|
-
* @param {string} opts.name - Component name displayed in h1
|
|
33
|
-
* @param {string} opts.description - Lead paragraph HTML
|
|
34
|
-
* @param {string} opts.content - Full HTML body (demos + props table)
|
|
35
|
-
* @param {object|null} opts.prev - { label, href } or null
|
|
36
|
-
* @param {object|null} opts.next - { label, href } or null
|
|
37
|
-
*/
|
|
38
|
-
export function renderComponentPage({ currentHref, name, description, content, prev = null, next = null }) {
|
|
39
|
-
return renderLayout({
|
|
40
|
-
currentHref,
|
|
41
|
-
prev,
|
|
42
|
-
next,
|
|
43
|
-
content: `
|
|
44
|
-
${h1(name)}
|
|
45
|
-
${lead(description)}
|
|
46
|
-
${content}
|
|
47
|
-
`,
|
|
48
|
-
})
|
|
49
|
-
}
|
package/docs/src/lib/layout.js
DELETED
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pulse Docs — Page layout
|
|
3
|
-
*
|
|
4
|
-
* renderLayout({ currentHref, content, prev, next }) → HTML string
|
|
5
|
-
* Used by every docs page except the home page.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { NAV } from './nav.js'
|
|
9
|
-
import pkg from '../../../package.json' with { type: 'json' }
|
|
10
|
-
|
|
11
|
-
// Resolve static asset paths through the build manifest (hashed in prod, raw in dev).
|
|
12
|
-
// Populated by initLayoutManifest() in server.js before the server starts.
|
|
13
|
-
let _manifest = {}
|
|
14
|
-
export function initLayoutManifest(m) { _manifest = m }
|
|
15
|
-
export const asset = href => _manifest[href] || href
|
|
16
|
-
|
|
17
|
-
const version = typeof pkg !== 'undefined' ? (pkg?.version ?? '') : ''
|
|
18
|
-
|
|
19
|
-
function esc(s) {
|
|
20
|
-
return String(s).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"')
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function sidebar(currentHref) {
|
|
24
|
-
const sections = NAV.map(({ section, items }) => {
|
|
25
|
-
const links = items.map(item => {
|
|
26
|
-
const active = item.href === currentHref
|
|
27
|
-
return `<a href="${esc(item.href)}" class="nav-link${active ? ' active' : ''}"${active ? ' aria-current="page"' : ''}>${esc(item.label)}</a>`
|
|
28
|
-
}).join('')
|
|
29
|
-
return `
|
|
30
|
-
<div class="nav-section">
|
|
31
|
-
<p class="nav-section-title">${esc(section)}</p>
|
|
32
|
-
${links}
|
|
33
|
-
</div>`
|
|
34
|
-
}).join('')
|
|
35
|
-
|
|
36
|
-
return `
|
|
37
|
-
<aside class="docs-sidebar" id="docs-sidebar" aria-label="Documentation navigation">
|
|
38
|
-
<div class="sidebar-logo">
|
|
39
|
-
<a href="/" class="logo-link" aria-label="Pulse home">
|
|
40
|
-
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
|
41
|
-
<path d="M13 2L4.5 13.5H11L10 22L19.5 10.5H13L13 2Z" fill="var(--accent)" stroke="var(--accent)" stroke-width="1" stroke-linejoin="round"/>
|
|
42
|
-
</svg>
|
|
43
|
-
<span class="logo-name">Pulse</span>
|
|
44
|
-
</a>
|
|
45
|
-
<span class="version-badge">v${version}</span>
|
|
46
|
-
</div>
|
|
47
|
-
<div class="sidebar-search-wrap">
|
|
48
|
-
<svg class="sidebar-search-icon" width="14" height="14" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
49
|
-
<path fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" clip-rule="evenodd"/>
|
|
50
|
-
</svg>
|
|
51
|
-
<input
|
|
52
|
-
type="search"
|
|
53
|
-
id="sidebar-search"
|
|
54
|
-
class="sidebar-search"
|
|
55
|
-
placeholder="Filter pages…"
|
|
56
|
-
aria-label="Filter documentation pages"
|
|
57
|
-
autocomplete="off"
|
|
58
|
-
spellcheck="false"
|
|
59
|
-
>
|
|
60
|
-
<button class="sidebar-search-full" aria-label="Search all docs content" title="Search all docs">
|
|
61
|
-
<svg width="14" height="14" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
62
|
-
<path fill-rule="evenodd" d="M3 4a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm0 4a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm0 4a1 1 0 011-1h7a1 1 0 110 2H4a1 1 0 01-1-1z" clip-rule="evenodd"/>
|
|
63
|
-
</svg>
|
|
64
|
-
</button>
|
|
65
|
-
</div>
|
|
66
|
-
<nav class="sidebar-nav" id="sidebar-nav">
|
|
67
|
-
${sections}
|
|
68
|
-
<p class="sidebar-no-results" hidden>No pages found</p>
|
|
69
|
-
</nav>
|
|
70
|
-
</aside>
|
|
71
|
-
<div class="search-overlay" id="search-overlay" role="dialog" aria-modal="true" aria-label="Search documentation" hidden>
|
|
72
|
-
<div class="search-overlay-backdrop"></div>
|
|
73
|
-
<div class="search-overlay-panel">
|
|
74
|
-
<div class="search-overlay-header">
|
|
75
|
-
<div class="search-overlay-input-wrap">
|
|
76
|
-
<svg width="18" height="18" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
77
|
-
<path fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" clip-rule="evenodd"/>
|
|
78
|
-
</svg>
|
|
79
|
-
<input
|
|
80
|
-
type="search"
|
|
81
|
-
id="search-overlay-input"
|
|
82
|
-
class="search-overlay-input"
|
|
83
|
-
placeholder="Search all docs…"
|
|
84
|
-
aria-label="Search all documentation"
|
|
85
|
-
autocomplete="off"
|
|
86
|
-
spellcheck="false"
|
|
87
|
-
>
|
|
88
|
-
</div>
|
|
89
|
-
<button class="search-overlay-close" aria-label="Close search">ESC</button>
|
|
90
|
-
</div>
|
|
91
|
-
<div class="search-overlay-results" id="search-overlay-results" role="listbox" aria-label="Search results"></div>
|
|
92
|
-
<div class="search-overlay-footer">
|
|
93
|
-
<span><kbd>↑</kbd><kbd>↓</kbd> navigate</span>
|
|
94
|
-
<span><kbd>↵</kbd> open</span>
|
|
95
|
-
<span><kbd>ESC</kbd> close</span>
|
|
96
|
-
</div>
|
|
97
|
-
</div>
|
|
98
|
-
</div>`
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
function prevNextBar(prev, next) {
|
|
102
|
-
if (!prev && !next) return ''
|
|
103
|
-
return `
|
|
104
|
-
<nav class="doc-prev-next" aria-label="Previous and next pages">
|
|
105
|
-
<div class="prev-next-grid">
|
|
106
|
-
${prev ? `<a href="${esc(prev.href)}" class="prev-next-link prev-link">
|
|
107
|
-
<span class="prev-next-label">← Previous</span>
|
|
108
|
-
<span class="prev-next-title">${esc(prev.label)}</span>
|
|
109
|
-
</a>` : '<div></div>'}
|
|
110
|
-
${next ? `<a href="${esc(next.href)}" class="prev-next-link next-link">
|
|
111
|
-
<span class="prev-next-label">Next →</span>
|
|
112
|
-
<span class="prev-next-title">${esc(next.label)}</span>
|
|
113
|
-
</a>` : '<div></div>'}
|
|
114
|
-
</div>
|
|
115
|
-
</nav>`
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export function renderLayout({ currentHref, content, prev = null, next = null }) {
|
|
119
|
-
return `
|
|
120
|
-
<a href="#main-content" class="skip-link">Skip to main content</a>
|
|
121
|
-
<div class="sidebar-overlay" aria-hidden="true"></div>
|
|
122
|
-
${sidebar(currentHref)}
|
|
123
|
-
<div class="docs-main">
|
|
124
|
-
<header class="docs-header">
|
|
125
|
-
<button class="mobile-menu-btn" aria-label="Toggle navigation menu" aria-expanded="false" aria-controls="docs-sidebar">
|
|
126
|
-
<svg width="20" height="20" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
127
|
-
<path fill-rule="evenodd" d="M2 4.75A.75.75 0 012.75 4h14.5a.75.75 0 010 1.5H2.75A.75.75 0 012 4.75zm0 10.5a.75.75 0 01.75-.75h14.5a.75.75 0 010 1.5H2.75a.75.75 0 01-.75-.75zM2 10a.75.75 0 01.75-.75h14.5a.75.75 0 010 1.5H2.75A.75.75 0 012 10z" clip-rule="evenodd"/>
|
|
128
|
-
</svg>
|
|
129
|
-
</button>
|
|
130
|
-
<a href="/" class="header-logo-mobile" aria-label="Pulse home">
|
|
131
|
-
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
|
132
|
-
<path d="M13 2L4.5 13.5H11L10 22L19.5 10.5H13L13 2Z" fill="var(--accent)" stroke="var(--accent)" stroke-width="1" stroke-linejoin="round"/>
|
|
133
|
-
</svg>
|
|
134
|
-
</a>
|
|
135
|
-
<a href="https://github.com/invisibleloop/pulse-framework" class="header-github" aria-label="View on GitHub (opens in new tab)" target="_blank" rel="noopener noreferrer">
|
|
136
|
-
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
|
137
|
-
<path d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z"/>
|
|
138
|
-
</svg>
|
|
139
|
-
GitHub
|
|
140
|
-
</a>
|
|
141
|
-
</header>
|
|
142
|
-
<main class="docs-content" id="main-content">
|
|
143
|
-
${content}
|
|
144
|
-
${prevNextBar(prev, next)}
|
|
145
|
-
</main>
|
|
146
|
-
</div>
|
|
147
|
-
<script src="${asset('/menu.js')}" defer></script>
|
|
148
|
-
<script src="${asset('/pulse-ui.js')}" defer></script>`
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Convenience helpers used in every page's view function
|
|
153
|
-
*/
|
|
154
|
-
|
|
155
|
-
export function h1(text) {
|
|
156
|
-
return `<h1 class="doc-h1">${esc(text)}</h1>`
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
export function lead(text) {
|
|
160
|
-
return `<p class="doc-lead">${text}</p>`
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
export function section(id, title) {
|
|
164
|
-
return `<h2 class="doc-h2" id="${esc(id)}"><a href="#${esc(id)}" class="heading-anchor">${esc(title)}</a></h2>`
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
export function sub(id, title) {
|
|
168
|
-
const label = title ?? id
|
|
169
|
-
return `<h3 class="doc-h3" id="${esc(id)}"><a href="#${esc(id)}" class="heading-anchor">${esc(label)}</a></h3>`
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
export function codeBlock(highlighted, filename = '') {
|
|
173
|
-
const header = filename ? `<div class="code-filename">${esc(filename)}</div>` : ''
|
|
174
|
-
return `${header}<pre class="code-block"><code>${highlighted}</code></pre>`
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
export function table(headers, rows, caption = '') {
|
|
178
|
-
const cap = caption ? `<caption>${esc(caption)}</caption>` : ''
|
|
179
|
-
const ths = headers.map(h => `<th scope="col">${h}</th>`).join('')
|
|
180
|
-
const trs = rows.map(row =>
|
|
181
|
-
`<tr>${row.map(cell => `<td>${cell}</td>`).join('')}</tr>`
|
|
182
|
-
).join('')
|
|
183
|
-
return `<div class="table-wrap"><table>${cap}<thead><tr>${ths}</tr></thead><tbody>${trs}</tbody></table></div>`
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
export function callout(type, content) {
|
|
187
|
-
// type: 'note' | 'warning' | 'tip'
|
|
188
|
-
const icons = { note: 'ℹ', warning: '⚠', tip: '✦' }
|
|
189
|
-
return `<div class="callout callout-${esc(type)}"><span class="callout-icon" aria-hidden="true">${icons[type] || 'ℹ'}</span><div class="callout-body">${content}</div></div>`
|
|
190
|
-
}
|
package/docs/src/lib/nav.js
DELETED
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pulse Docs — Navigation structure
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export const NAV = [
|
|
6
|
-
{
|
|
7
|
-
section: 'Framework',
|
|
8
|
-
items: [
|
|
9
|
-
{ label: 'Overview', href: '/' },
|
|
10
|
-
{ label: 'FAQ', href: '/faq' },
|
|
11
|
-
{ label: 'Project Structure', href: '/project-structure' },
|
|
12
|
-
{ label: 'Spec Reference', href: '/spec' },
|
|
13
|
-
{ label: 'Configuration', href: '/config' },
|
|
14
|
-
],
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
section: 'Developer Guide',
|
|
18
|
-
items: [
|
|
19
|
-
{ label: 'Getting Started', href: '/getting-started' },
|
|
20
|
-
{ label: 'How It Works', href: '/how-it-works' },
|
|
21
|
-
{ label: 'Slash Commands', href: '/slash-commands' },
|
|
22
|
-
{ label: 'Prompt Examples', href: '/prompt-examples' },
|
|
23
|
-
{ label: 'Component Library', href: '/components' },
|
|
24
|
-
],
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
section: 'State & Behaviour',
|
|
28
|
-
items: [
|
|
29
|
-
{ label: 'State', href: '/state' },
|
|
30
|
-
{ label: 'Mutations', href: '/mutations' },
|
|
31
|
-
{ label: 'Actions', href: '/actions' },
|
|
32
|
-
{ label: 'Validation', href: '/validation' },
|
|
33
|
-
{ label: 'Constraints', href: '/constraints' },
|
|
34
|
-
{ label: 'Persist', href: '/persist' },
|
|
35
|
-
],
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
section: 'Server',
|
|
39
|
-
items: [
|
|
40
|
-
{ label: 'Server Data', href: '/server-data' },
|
|
41
|
-
{ label: 'Markdown', href: '/markdown' },
|
|
42
|
-
{ label: 'Global Store', href: '/store' },
|
|
43
|
-
{ label: 'Routing', href: '/routing' },
|
|
44
|
-
{ label: 'Error Pages', href: '/error-pages' },
|
|
45
|
-
{ label: 'Streaming SSR', href: '/streaming' },
|
|
46
|
-
{ label: 'Caching', href: '/caching' },
|
|
47
|
-
{ label: 'Guard', href: '/guard' },
|
|
48
|
-
{ label: 'Forms', href: '/forms' },
|
|
49
|
-
{ label: 'Raw Responses', href: '/raw-responses' },
|
|
50
|
-
{ label: 'Server API', href: '/server-api' },
|
|
51
|
-
{ label: 'Extending Pulse', href: '/extending' },
|
|
52
|
-
],
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
section: 'Client',
|
|
56
|
-
items: [
|
|
57
|
-
{ label: 'Hydration', href: '/hydration' },
|
|
58
|
-
{ label: 'Navigation', href: '/navigation' },
|
|
59
|
-
{ label: 'Images', href: '/images' },
|
|
60
|
-
],
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
section: 'Deployment',
|
|
64
|
-
items: [
|
|
65
|
-
{ label: 'Deployment', href: '/deploy' },
|
|
66
|
-
],
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
section: 'Reference',
|
|
70
|
-
items: [
|
|
71
|
-
{ label: 'Metadata & SEO', href: '/meta' },
|
|
72
|
-
{ label: 'Performance', href: '/performance' },
|
|
73
|
-
{ label: 'Accessibility', href: '/accessibility' },
|
|
74
|
-
{ label: 'Testing', href: '/testing' },
|
|
75
|
-
],
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
section: 'UI Components',
|
|
79
|
-
items: [
|
|
80
|
-
{ label: 'Alert', href: '/components/alert' },
|
|
81
|
-
{ label: 'Avatar', href: '/components/avatar' },
|
|
82
|
-
{ label: 'Badge', href: '/components/badge' },
|
|
83
|
-
{ label: 'Breadcrumbs', href: '/components/breadcrumbs' },
|
|
84
|
-
{ label: 'Button', href: '/components/button' },
|
|
85
|
-
{ label: 'Card', href: '/components/card' },
|
|
86
|
-
{ label: 'Checkbox', href: '/components/checkbox' },
|
|
87
|
-
{ label: 'Charts', href: '/components/charts' },
|
|
88
|
-
{ label: 'Empty', href: '/components/empty' },
|
|
89
|
-
{ label: 'Fieldset', href: '/components/fieldset' },
|
|
90
|
-
{ label: 'File Upload', href: '/components/file-upload' },
|
|
91
|
-
{ label: 'Heading', href: '/components/heading' },
|
|
92
|
-
{ label: 'Icons', href: '/components/icons' },
|
|
93
|
-
{ label: 'Image', href: '/components/image' },
|
|
94
|
-
{ label: 'Input', href: '/components/input' },
|
|
95
|
-
{ label: 'Modal', href: '/components/modal' },
|
|
96
|
-
{ label: 'Progress', href: '/components/progress' },
|
|
97
|
-
{ label: 'Prose', href: '/components/prose' },
|
|
98
|
-
{ label: 'Pullquote', href: '/components/pullquote' },
|
|
99
|
-
{ label: 'Radio', href: '/components/radio' },
|
|
100
|
-
{ label: 'Rating', href: '/components/rating' },
|
|
101
|
-
{ label: 'Search', href: '/components/search' },
|
|
102
|
-
{ label: 'Segmented', href: '/components/segmented' },
|
|
103
|
-
{ label: 'Select', href: '/components/select' },
|
|
104
|
-
{ label: 'Slider', href: '/components/slider' },
|
|
105
|
-
{ label: 'Spinner', href: '/components/spinner' },
|
|
106
|
-
{ label: 'Stat', href: '/components/stat' },
|
|
107
|
-
{ label: 'Stepper', href: '/components/stepper' },
|
|
108
|
-
{ label: 'Table', href: '/components/table' },
|
|
109
|
-
{ label: 'Textarea', href: '/components/textarea' },
|
|
110
|
-
{ label: 'Toggle', href: '/components/toggle' },
|
|
111
|
-
{ label: 'Tooltip', href: '/components/tooltip' },
|
|
112
|
-
],
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
section: 'Landing Components',
|
|
116
|
-
items: [
|
|
117
|
-
{ label: 'Accordion', href: '/components/accordion' },
|
|
118
|
-
{ label: 'App Badge', href: '/components/app-badge' },
|
|
119
|
-
{ label: 'CTA', href: '/components/cta' },
|
|
120
|
-
{ label: 'Feature', href: '/components/feature' },
|
|
121
|
-
{ label: 'Hero', href: '/components/hero' },
|
|
122
|
-
{ label: 'Nav', href: '/components/nav' },
|
|
123
|
-
{ label: 'Phone Frame', href: '/components/phone-frame' },
|
|
124
|
-
],
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
section: 'Layout Components',
|
|
128
|
-
items: [
|
|
129
|
-
{ label: 'Cluster', href: '/components/cluster' },
|
|
130
|
-
{ label: 'Container', href: '/components/container' },
|
|
131
|
-
{ label: 'Divider', href: '/components/divider' },
|
|
132
|
-
{ label: 'Footer', href: '/components/footer' },
|
|
133
|
-
{ label: 'Grid', href: '/components/grid' },
|
|
134
|
-
{ label: 'Media', href: '/components/media' },
|
|
135
|
-
{ label: 'Section', href: '/components/section' },
|
|
136
|
-
{ label: 'Stack', href: '/components/stack' },
|
|
137
|
-
],
|
|
138
|
-
},
|
|
139
|
-
{
|
|
140
|
-
section: 'Integrations',
|
|
141
|
-
items: [
|
|
142
|
-
{ label: 'Supabase', href: '/supabase' },
|
|
143
|
-
{ label: 'Auth (Auth0)', href: '/auth' },
|
|
144
|
-
{ label: 'Payments (Stripe)', href: '/stripe' },
|
|
145
|
-
],
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
section: 'Templates',
|
|
149
|
-
items: [
|
|
150
|
-
{ label: 'All Templates', href: '/templates' },
|
|
151
|
-
{ label: 'Mobile App Landing', href: '/templates/mobile-app' },
|
|
152
|
-
{ label: 'Blog Post', href: '/templates/blog-post' },
|
|
153
|
-
{ label: 'Swish — Fashion', href: '/templates/swish' },
|
|
154
|
-
{ label: 'BookWorms', href: '/templates/bookworms' },
|
|
155
|
-
{ label: 'Retro Wheels Co.', href: '/templates/retrowheels' },
|
|
156
|
-
{ label: 'Susuki Bento', href: '/templates/suzukibento' },
|
|
157
|
-
{ label: 'Andy Pixel — Blog', href: '/templates/andypixel' },
|
|
158
|
-
{ label: 'Journey — App', href: '/templates/journey' },
|
|
159
|
-
{ label: 'Shop — Product Page', href: '/templates/shop' },
|
|
160
|
-
],
|
|
161
|
-
},
|
|
162
|
-
]
|
|
163
|
-
|
|
164
|
-
export function prevNext(currentHref) {
|
|
165
|
-
const all = NAV.flatMap(s => s.items)
|
|
166
|
-
const idx = all.findIndex(i => i.href === currentHref)
|
|
167
|
-
return {
|
|
168
|
-
prev: idx > 0 ? all[idx - 1] : null,
|
|
169
|
-
next: idx < all.length - 1 ? all[idx + 1] : null,
|
|
170
|
-
}
|
|
171
|
-
}
|