@invisibleloop/pulse 0.20.10 → 0.20.19
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 +14 -7
- package/src/runtime/ssr.test.js +31 -0
- package/src/server/index.js +163 -10
- 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 -345
- 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
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
import { renderComponentPage, demo } from '../../lib/component-page.js'
|
|
2
|
-
import { prevNext } from '../../lib/nav.js'
|
|
3
|
-
import { table } from '../../lib/layout.js'
|
|
4
|
-
import { grid, card, stat, feature } from '../../../../src/ui/index.js'
|
|
5
|
-
|
|
6
|
-
const { prev, next } = prevNext('/components/grid')
|
|
7
|
-
|
|
8
|
-
// Reusable placeholder item
|
|
9
|
-
const item = (label) =>
|
|
10
|
-
`<div style="background:var(--surface-2);border:1px solid var(--border);border-radius:6px;padding:1.25rem;text-align:center;color:var(--muted)">${label}</div>`
|
|
11
|
-
|
|
12
|
-
export default {
|
|
13
|
-
route: '/components/grid',
|
|
14
|
-
meta: {
|
|
15
|
-
theme: 'light',
|
|
16
|
-
title: 'Grid — Pulse Docs',
|
|
17
|
-
description: 'Grid component for Pulse UI.',
|
|
18
|
-
styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
|
|
19
|
-
},
|
|
20
|
-
view: () => renderComponentPage({
|
|
21
|
-
currentHref: '/components/grid',
|
|
22
|
-
prev,
|
|
23
|
-
next,
|
|
24
|
-
name: 'grid',
|
|
25
|
-
description: 'Responsive CSS grid. Collapses to a single column on mobile. Direct children of the content slot become grid items — no wrapper needed.',
|
|
26
|
-
content: `
|
|
27
|
-
<h2 class="doc-h2" id="cols">Column counts</h2>
|
|
28
|
-
<p>Use <code>cols</code> to set the number of columns. All layouts collapse to one column on mobile.</p>
|
|
29
|
-
|
|
30
|
-
<h3 class="doc-h3">2 columns</h3>
|
|
31
|
-
${demo(
|
|
32
|
-
grid({ cols: 2, content: item('Left') + item('Right') }),
|
|
33
|
-
`grid({ cols: 2, content: left + right })`
|
|
34
|
-
)}
|
|
35
|
-
|
|
36
|
-
<h3 class="doc-h3">3 columns (default)</h3>
|
|
37
|
-
${demo(
|
|
38
|
-
grid({ cols: 3, content: item('One') + item('Two') + item('Three') }),
|
|
39
|
-
`grid({ cols: 3, content: items.join('') })`
|
|
40
|
-
)}
|
|
41
|
-
|
|
42
|
-
<h3 class="doc-h3">4 columns</h3>
|
|
43
|
-
${demo(
|
|
44
|
-
grid({ cols: 4, content: item('A') + item('B') + item('C') + item('D') }),
|
|
45
|
-
`grid({ cols: 4, content: items.join('') })`
|
|
46
|
-
)}
|
|
47
|
-
|
|
48
|
-
<h2 class="doc-h2" id="gap">Gap sizes</h2>
|
|
49
|
-
<p>Control spacing between items with <code>gap: 'sm' | 'md' | 'lg'</code>. Default is <code>'md'</code>.</p>
|
|
50
|
-
|
|
51
|
-
<h3 class="doc-h3">Small gap</h3>
|
|
52
|
-
${demo(
|
|
53
|
-
grid({ cols: 3, gap: 'sm', content: item('One') + item('Two') + item('Three') }),
|
|
54
|
-
`grid({ cols: 3, gap: 'sm', content: items.join('') })`
|
|
55
|
-
)}
|
|
56
|
-
|
|
57
|
-
<h3 class="doc-h3">Large gap</h3>
|
|
58
|
-
${demo(
|
|
59
|
-
grid({ cols: 3, gap: 'lg', content: item('One') + item('Two') + item('Three') }),
|
|
60
|
-
`grid({ cols: 3, gap: 'lg', content: items.join('') })`
|
|
61
|
-
)}
|
|
62
|
-
|
|
63
|
-
<h2 class="doc-h2" id="with-components">With components</h2>
|
|
64
|
-
<p>Grid accepts any HTML string as content — pass other component outputs directly.</p>
|
|
65
|
-
|
|
66
|
-
<h3 class="doc-h3">Feature grid</h3>
|
|
67
|
-
${demo(
|
|
68
|
-
grid({
|
|
69
|
-
cols: 3,
|
|
70
|
-
content: [
|
|
71
|
-
feature({ icon: '⚡', title: 'Fast', description: 'Sub-100ms server responses with streaming SSR.' }),
|
|
72
|
-
feature({ icon: '🔒', title: 'Secure', description: 'Security headers on every response, including errors.' }),
|
|
73
|
-
feature({ icon: '🎯', title: 'Simple', description: 'No build step, no virtual DOM, no dependencies.' }),
|
|
74
|
-
].join(''),
|
|
75
|
-
}),
|
|
76
|
-
`grid({
|
|
77
|
-
cols: 3,
|
|
78
|
-
content: features.map(f => feature(f)).join(''),
|
|
79
|
-
})`
|
|
80
|
-
)}
|
|
81
|
-
|
|
82
|
-
<h3 class="doc-h3">Stat grid</h3>
|
|
83
|
-
${demo(
|
|
84
|
-
grid({
|
|
85
|
-
cols: 4,
|
|
86
|
-
content: [
|
|
87
|
-
stat({ label: 'Monthly users', value: '24.8k', change: '+12%', trend: 'up' }),
|
|
88
|
-
stat({ label: 'Revenue', value: '$18.2k', change: '+8.4%', trend: 'up' }),
|
|
89
|
-
stat({ label: 'Churn rate', value: '2.1%', change: '−0.3%', trend: 'down' }),
|
|
90
|
-
stat({ label: 'Uptime', value: '99.98%', change: '0.0%', trend: 'neutral' }),
|
|
91
|
-
].join(''),
|
|
92
|
-
}),
|
|
93
|
-
`grid({
|
|
94
|
-
cols: 4,
|
|
95
|
-
content: stats.map(s => stat(s)).join(''),
|
|
96
|
-
})`
|
|
97
|
-
)}
|
|
98
|
-
|
|
99
|
-
<h3 class="doc-h3">Testimonial grid</h3>
|
|
100
|
-
<p>There is no dedicated <code>testimonial</code> component — build one with <code>card()</code>: the quote in <code>content</code>, the name and role in <code>footer</code>.</p>
|
|
101
|
-
${demo(
|
|
102
|
-
grid({
|
|
103
|
-
cols: 3,
|
|
104
|
-
content: [
|
|
105
|
-
card({ content: `<p style="color:var(--muted);margin:0">“Shipped our redesign in a weekend. No boilerplate, no config hell.”</p>`, footer: `<strong>Alex Morgan</strong><br><span style="color:var(--muted)">CTO at Launchpad</span>` }),
|
|
106
|
-
card({ content: `<p style="color:var(--muted);margin:0">“The streaming SSR makes our pages feel instant. Lighthouse is happy.”</p>`, footer: `<strong>Sara Kim</strong><br><span style="color:var(--muted)">Lead Engineer, Orbit</span>` }),
|
|
107
|
-
card({ content: `<p style="color:var(--muted);margin:0">“Finally a UI kit that doesn\'t fight the platform. Just HTML.”</p>`, footer: `<strong>Dan Okafor</strong><br><span style="color:var(--muted)">Founder, Stackly</span>` }),
|
|
108
|
-
].join(''),
|
|
109
|
-
}),
|
|
110
|
-
`grid({
|
|
111
|
-
cols: 3,
|
|
112
|
-
content: testimonials.map(t => card({
|
|
113
|
-
content: \`<p>\${t.quote}</p>\`,
|
|
114
|
-
footer: \`<strong>\${t.name}</strong><br>\${t.role}\`,
|
|
115
|
-
})).join(''),
|
|
116
|
-
})`
|
|
117
|
-
)}
|
|
118
|
-
|
|
119
|
-
<h3 class="doc-h3">Card grid</h3>
|
|
120
|
-
${demo(
|
|
121
|
-
grid({
|
|
122
|
-
cols: 3,
|
|
123
|
-
gap: 'md',
|
|
124
|
-
content: [
|
|
125
|
-
card({
|
|
126
|
-
title: 'Getting started',
|
|
127
|
-
content: `<p style="color:var(--muted);margin:0">Install and run your first Pulse app in under five minutes.</p>`,
|
|
128
|
-
footer: `<span class="ui-badge">Guide</span>`,
|
|
129
|
-
}),
|
|
130
|
-
card({
|
|
131
|
-
title: 'Components',
|
|
132
|
-
content: `<p style="color:var(--muted);margin:0">30+ accessible, composable UI primitives ready to drop in.</p>`,
|
|
133
|
-
footer: `<span class="ui-badge">Reference</span>`,
|
|
134
|
-
}),
|
|
135
|
-
card({
|
|
136
|
-
title: 'Deployment',
|
|
137
|
-
content: `<p style="color:var(--muted);margin:0">Static hosting, Node servers, or edge runtimes — one build.</p>`,
|
|
138
|
-
footer: `<span class="ui-badge">Deploy</span>`,
|
|
139
|
-
}),
|
|
140
|
-
].join(''),
|
|
141
|
-
}),
|
|
142
|
-
`grid({
|
|
143
|
-
cols: 3,
|
|
144
|
-
content: docs.map(d => card({
|
|
145
|
-
title: d.title,
|
|
146
|
-
content: \`<p>\${d.summary}</p>\`,
|
|
147
|
-
footer: badge({ label: d.tag }),
|
|
148
|
-
})).join(''),
|
|
149
|
-
})`
|
|
150
|
-
)}
|
|
151
|
-
|
|
152
|
-
<h2 class="doc-h2" id="1col">Single column</h2>
|
|
153
|
-
<p>Use <code>cols: 1</code> for a stacked list with consistent spacing — useful for form sections or timelines.</p>
|
|
154
|
-
${demo(
|
|
155
|
-
grid({ cols: 1, gap: 'sm', content: item('Step one') + item('Step two') + item('Step three') }),
|
|
156
|
-
`grid({ cols: 1, gap: 'sm', content: steps.join('') })`
|
|
157
|
-
)}
|
|
158
|
-
|
|
159
|
-
${table(
|
|
160
|
-
['Prop', 'Type', 'Default', 'Description'],
|
|
161
|
-
[
|
|
162
|
-
['<code>content</code>', 'string (HTML)', '—', 'Raw HTML slot — direct children are grid items'],
|
|
163
|
-
['<code>cols</code>', 'number', '3', '1 · 2 · 3 · 4'],
|
|
164
|
-
['<code>gap</code>', 'string', "'md'", "'sm' · 'md' · 'lg'"],
|
|
165
|
-
]
|
|
166
|
-
)}
|
|
167
|
-
`,
|
|
168
|
-
}),
|
|
169
|
-
}
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { renderComponentPage, demo } from '../../lib/component-page.js'
|
|
2
|
-
import { prevNext } from '../../lib/nav.js'
|
|
3
|
-
import { table } from '../../lib/layout.js'
|
|
4
|
-
import { heading, card } from '../../../../src/ui/index.js'
|
|
5
|
-
|
|
6
|
-
const { prev, next } = prevNext('/components/heading')
|
|
7
|
-
|
|
8
|
-
export default {
|
|
9
|
-
route: '/components/heading',
|
|
10
|
-
meta: {
|
|
11
|
-
theme: 'light',
|
|
12
|
-
title: 'Heading — Pulse Docs',
|
|
13
|
-
description: 'Styled semantic heading component for Pulse UI.',
|
|
14
|
-
styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
|
|
15
|
-
},
|
|
16
|
-
view: () => renderComponentPage({
|
|
17
|
-
currentHref: '/components/heading',
|
|
18
|
-
prev,
|
|
19
|
-
next,
|
|
20
|
-
name: 'heading',
|
|
21
|
-
description: 'Styled semantic heading. Renders the correct HTML tag (<code>h1</code>–<code>h6</code>) with consistent typography tokens. Use this instead of raw heading tags so you get the right visual style without remembering utility classes.',
|
|
22
|
-
content: `
|
|
23
|
-
|
|
24
|
-
<h2 class="doc-h2" id="levels">All levels</h2>
|
|
25
|
-
<p>Each level has a default visual size. The semantic tag and visual size are independent — see <a href="#size-override">size override</a> below.</p>
|
|
26
|
-
${demo(
|
|
27
|
-
[1, 2, 3, 4, 5, 6].map(l => heading({ level: l, text: `Heading level ${l}` })).join(''),
|
|
28
|
-
`heading({ level: 1, text: 'Page title' })
|
|
29
|
-
heading({ level: 2, text: 'Section title' })
|
|
30
|
-
heading({ level: 3, text: 'Subsection' })
|
|
31
|
-
heading({ level: 4, text: 'Card heading' })
|
|
32
|
-
heading({ level: 5, text: 'Label' })
|
|
33
|
-
heading({ level: 6, text: 'Caption' })`,
|
|
34
|
-
{ col: true }
|
|
35
|
-
)}
|
|
36
|
-
|
|
37
|
-
<h2 class="doc-h2" id="size-override">Size override</h2>
|
|
38
|
-
<p>The <code>size</code> prop lets you use a different visual scale than the default for that level. Useful when you need the correct semantic structure for SEO or accessibility but want a different visual weight.</p>
|
|
39
|
-
${demo(
|
|
40
|
-
[
|
|
41
|
-
heading({ level: 2, text: 'Semantic h2, looks like h4', size: 'xl' }),
|
|
42
|
-
heading({ level: 3, text: 'Semantic h3, extra large', size: '4xl' }),
|
|
43
|
-
].join(''),
|
|
44
|
-
`// h2 for structure, but visually smaller
|
|
45
|
-
heading({ level: 2, text: 'Related articles', size: 'xl' })
|
|
46
|
-
|
|
47
|
-
// h3 that needs to be visually prominent
|
|
48
|
-
heading({ level: 3, text: 'Featured', size: '4xl' })`,
|
|
49
|
-
{ col: true }
|
|
50
|
-
)}
|
|
51
|
-
|
|
52
|
-
<h2 class="doc-h2" id="color">Color</h2>
|
|
53
|
-
${demo(
|
|
54
|
-
[
|
|
55
|
-
heading({ level: 3, text: 'Default colour' }),
|
|
56
|
-
heading({ level: 3, text: 'Muted — for secondary labels', color: 'muted' }),
|
|
57
|
-
heading({ level: 3, text: 'Accent — for highlights', color: 'accent' }),
|
|
58
|
-
].join(''),
|
|
59
|
-
`heading({ level: 3, text: 'Default colour' })
|
|
60
|
-
heading({ level: 3, text: 'Muted — for secondary labels', color: 'muted' })
|
|
61
|
-
heading({ level: 3, text: 'Accent — for highlights', color: 'accent' })`,
|
|
62
|
-
{ col: true }
|
|
63
|
-
)}
|
|
64
|
-
|
|
65
|
-
<h2 class="doc-h2" id="spacing">Spacing</h2>
|
|
66
|
-
<p><code>heading()</code> adds no margin. Use <code>u-mt-*</code> and <code>u-mb-*</code> utility classes to control spacing in context.</p>
|
|
67
|
-
${demo(
|
|
68
|
-
card({ content: `
|
|
69
|
-
${heading({ level: 2, text: 'Account settings', class: 'u-mb-2' })}
|
|
70
|
-
<p class="u-text-muted u-text-sm">Manage your profile and preferences.</p>
|
|
71
|
-
`}),
|
|
72
|
-
`card({ content: \`
|
|
73
|
-
\${heading({ level: 2, text: 'Account settings', class: 'u-mb-2' })}
|
|
74
|
-
<p class="u-text-muted u-text-sm">Manage your profile and preferences.</p>
|
|
75
|
-
\`})`,
|
|
76
|
-
{ col: true }
|
|
77
|
-
)}
|
|
78
|
-
|
|
79
|
-
<h2 class="doc-h2" id="balance">Preventing orphans</h2>
|
|
80
|
-
<p>When a heading wraps across lines, the last line can be left with a single short word — an orphan. The <code>balance</code> prop adds <code>text-wrap: balance</code>, which distributes text evenly across all lines so no word is stranded.</p>
|
|
81
|
-
${demo(
|
|
82
|
-
[
|
|
83
|
-
heading({ level: 2, text: 'The quick brown fox jumps over the lazy dog tonight' }),
|
|
84
|
-
heading({ level: 2, text: 'The quick brown fox jumps over the lazy dog tonight', balance: true }),
|
|
85
|
-
].join('<p class="u-text-muted u-text-sm u-mt-2 u-mb-4">↑ without balance — ↓ with balance: true</p>'),
|
|
86
|
-
`// Without — last line may have a single word
|
|
87
|
-
heading({ level: 2, text: 'The quick brown fox jumps over the lazy dog tonight' })
|
|
88
|
-
|
|
89
|
-
// With — text distributed evenly across lines
|
|
90
|
-
heading({ level: 2, text: 'The quick brown fox jumps over the lazy dog tonight', balance: true })`,
|
|
91
|
-
{ col: true }
|
|
92
|
-
)}
|
|
93
|
-
|
|
94
|
-
${table(
|
|
95
|
-
['Prop', 'Type', 'Default', 'Description'],
|
|
96
|
-
[
|
|
97
|
-
['<code>level</code>', 'number (1–6)', '2', 'Controls both the HTML tag and the default visual size'],
|
|
98
|
-
['<code>text</code>', 'string', '—', 'Heading text — escaped automatically'],
|
|
99
|
-
['<code>size</code>', '<code>xs | sm | base | lg | xl | 2xl | 3xl | 4xl</code>', '—', 'Override the visual font size independently of the semantic level. Defaults: h1=4xl, h2=3xl, h3=2xl, h4=xl, h5=base, h6=sm'],
|
|
100
|
-
['<code>color</code>', '<code>default | muted | accent</code>', '<code>default</code>', 'Text colour token'],
|
|
101
|
-
['<code>balance</code>', 'boolean', '<code>false</code>', 'Adds <code>text-wrap: balance</code> — prevents orphaned words on the last line when the heading wraps'],
|
|
102
|
-
['<code>class</code>', 'string', '—', 'Extra classes — use for spacing utilities such as <code>u-mb-4</code>'],
|
|
103
|
-
]
|
|
104
|
-
)}
|
|
105
|
-
`,
|
|
106
|
-
}),
|
|
107
|
-
}
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import { renderComponentPage, demo } from '../../lib/component-page.js'
|
|
2
|
-
import { prevNext } from '../../lib/nav.js'
|
|
3
|
-
import { table } from '../../lib/layout.js'
|
|
4
|
-
import { hero, appBadge } from '../../../../src/ui/index.js'
|
|
5
|
-
|
|
6
|
-
const { prev, next } = prevNext('/components/hero')
|
|
7
|
-
|
|
8
|
-
export default {
|
|
9
|
-
route: '/components/hero',
|
|
10
|
-
meta: {
|
|
11
|
-
theme: 'light',
|
|
12
|
-
title: 'Hero — Pulse Docs',
|
|
13
|
-
description: 'Hero component for Pulse UI.',
|
|
14
|
-
styles: ['/pulse-ui.css', '/theme.css', '/docs.css'],
|
|
15
|
-
},
|
|
16
|
-
state: {},
|
|
17
|
-
view: () => {
|
|
18
|
-
const placeholderImg = `<img src="/img/heic1501a.jpg" alt="The Pillars of Creation in the Eagle Nebula, captured by the Hubble Space Telescope" style="width:100%;height:100%;object-fit:cover;border-radius:var(--ui-radius,8px);display:block">`
|
|
19
|
-
return renderComponentPage({
|
|
20
|
-
currentHref: '/components/hero',
|
|
21
|
-
prev,
|
|
22
|
-
next,
|
|
23
|
-
name: 'hero',
|
|
24
|
-
description: 'Full-width hero section. Pass <code>image</code> HTML to activate the split layout — text on one side, image on the other. Use <code>imageAlign</code> to swap sides. Set <code>align: \'left\'</code> for left-aligned text without an image. Use <code>size: \'sm\'</code> for inner-page headers.',
|
|
25
|
-
content: `
|
|
26
|
-
${demo(
|
|
27
|
-
hero({
|
|
28
|
-
eyebrow: 'Now available',
|
|
29
|
-
title: 'The app your phone deserves',
|
|
30
|
-
subtitle: 'Beautifully simple. Ridiculously fast. Available on iOS and Android.',
|
|
31
|
-
actions: appBadge({ store: 'apple', href: '#' }) + ' ' + appBadge({ store: 'google', href: '#' }),
|
|
32
|
-
}),
|
|
33
|
-
`hero({
|
|
34
|
-
eyebrow: 'Now available',
|
|
35
|
-
title: 'The app your phone deserves',
|
|
36
|
-
subtitle: 'Beautifully simple. Ridiculously fast.',
|
|
37
|
-
actions: appBadge({ store: 'apple', href: appStoreUrl }) +
|
|
38
|
-
appBadge({ store: 'google', href: playStoreUrl }),
|
|
39
|
-
})`,
|
|
40
|
-
{ bleed: true }
|
|
41
|
-
)}
|
|
42
|
-
|
|
43
|
-
${demo(
|
|
44
|
-
hero({
|
|
45
|
-
eyebrow: 'Split layout',
|
|
46
|
-
title: 'Text left, image right',
|
|
47
|
-
subtitle: 'Pass an image slot to activate the split layout. The text sits on the left, image on the right.',
|
|
48
|
-
actions: appBadge({ store: 'apple', href: '#' }) + ' ' + appBadge({ store: 'google', href: '#' }),
|
|
49
|
-
image: placeholderImg,
|
|
50
|
-
}),
|
|
51
|
-
`hero({
|
|
52
|
-
eyebrow: 'Split layout',
|
|
53
|
-
title: 'Text left, image right',
|
|
54
|
-
subtitle: 'Pass an image slot to activate the split layout.',
|
|
55
|
-
actions: appBadge({ store: 'apple', href: appStoreUrl }) +
|
|
56
|
-
appBadge({ store: 'google', href: playStoreUrl }),
|
|
57
|
-
image: \`<img src="\${screenshotUrl}" alt="Product screenshot">\`,
|
|
58
|
-
})`,
|
|
59
|
-
{ bleed: true }
|
|
60
|
-
)}
|
|
61
|
-
|
|
62
|
-
${demo(
|
|
63
|
-
hero({
|
|
64
|
-
eyebrow: 'Split layout',
|
|
65
|
-
title: 'Image left, text right',
|
|
66
|
-
subtitle: 'Set imageAlign: \'left\' to put the image on the left and text on the right.',
|
|
67
|
-
image: placeholderImg,
|
|
68
|
-
imageAlign: 'left',
|
|
69
|
-
}),
|
|
70
|
-
`hero({
|
|
71
|
-
eyebrow: 'Split layout',
|
|
72
|
-
title: 'Image left, text right',
|
|
73
|
-
subtitle: 'Set imageAlign to swap sides.',
|
|
74
|
-
image: \`<img src="\${screenshotUrl}" alt="Product screenshot">\`,
|
|
75
|
-
imageAlign: 'left',
|
|
76
|
-
})`,
|
|
77
|
-
{ bleed: true }
|
|
78
|
-
)}
|
|
79
|
-
|
|
80
|
-
${demo(
|
|
81
|
-
`<div style="display:flex;flex-direction:column;gap:0">` +
|
|
82
|
-
hero({ eyebrow: 'Solid colour', title: 'background: color', background: '#0f172a', size: 'sm' }) +
|
|
83
|
-
hero({ eyebrow: 'Custom gradient', title: 'background: CSS gradient', background: 'linear-gradient(135deg, #1e1b4b 0%, #312e81 50%, #1e1b4b 100%)', size: 'sm' }) +
|
|
84
|
-
`</div>`,
|
|
85
|
-
`// Any valid CSS background value
|
|
86
|
-
hero({ title: 'Headline', background: '#0f172a' })
|
|
87
|
-
hero({ title: 'Headline', background: 'linear-gradient(135deg, #1e1b4b, #312e81)' })`,
|
|
88
|
-
{ bleed: true }
|
|
89
|
-
)}
|
|
90
|
-
|
|
91
|
-
${demo(
|
|
92
|
-
hero({
|
|
93
|
-
title: 'Blog',
|
|
94
|
-
subtitle: 'Thoughts on building for the web.',
|
|
95
|
-
size: 'sm',
|
|
96
|
-
}),
|
|
97
|
-
`hero({
|
|
98
|
-
title: 'Blog',
|
|
99
|
-
subtitle: 'Thoughts on building for the web.',
|
|
100
|
-
size: 'sm',
|
|
101
|
-
})`,
|
|
102
|
-
{ bleed: true }
|
|
103
|
-
)}
|
|
104
|
-
|
|
105
|
-
${table(
|
|
106
|
-
['Prop', 'Type', 'Default', 'Description'],
|
|
107
|
-
[
|
|
108
|
-
['<code>eyebrow</code>', 'string', '—', 'Small label above the title'],
|
|
109
|
-
['<code>title</code>', 'string', '—', ''],
|
|
110
|
-
['<code>subtitle</code>', 'string', '—', ''],
|
|
111
|
-
['<code>actions</code>', 'string (HTML)', '—', 'Raw HTML slot — buttons, badges, etc.'],
|
|
112
|
-
['<code>image</code>', 'string (HTML)', '—', 'Raw HTML slot — activates split layout when set'],
|
|
113
|
-
['<code>layout</code>', 'string', "'split'", "When <code>image</code> is set: <code>'split'</code> (even columns) · <code>'asymmetric'</code> (wider text, narrower image) · <code>'overlap'</code> (image overlaps below text)"],
|
|
114
|
-
['<code>imageAlign</code>', 'string', "'right'", "'right' (text left) or 'left' (text right) — only applies when image is set"],
|
|
115
|
-
['<code>align</code>', 'string', "'center'", "'center' or 'left' — text alignment when no image"],
|
|
116
|
-
['<code>size</code>', 'string', "'md'", "'md' (5rem padding) or 'sm' (2.5rem top, no bottom) — use sm for inner-page headers"],
|
|
117
|
-
['<code>background</code>', 'string', '—', 'Any CSS background value — solid colour or custom gradient.'],
|
|
118
|
-
]
|
|
119
|
-
)}
|
|
120
|
-
`,
|
|
121
|
-
})
|
|
122
|
-
},
|
|
123
|
-
}
|