@invisibleloop/pulse 0.1.28 → 0.1.30
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/.github/workflows/publish.yml +11 -20
- package/README.md +1 -1
- package/docs/public/.pulse-ui-version +1 -1
- package/docs/public/docs.css +19 -1
- package/docs/public/pulse-ui.css +1 -0
- package/docs/server.js +5 -2
- package/docs/src/lib/highlight.js +57 -13
- package/docs/src/lib/layout.js +5 -2
- package/docs/src/pages/faq.js +5 -2
- package/docs/src/pages/home.js +9 -5
- package/docs/src/pages/meta.js +21 -0
- package/docs/src/pages/routing.js +12 -1
- package/package.json +1 -1
- package/public/pulse-ui.css +2 -2
- package/src/agent/guide-components.md +1 -1
- package/src/agent/guide-routing.md +20 -0
- package/src/agent/guide-spec.md +10 -1
- package/src/agent/guide-styles.md +16 -1
- package/src/agent/workflow.md +1 -1
- package/src/cli/scaffold.js +63 -2
- package/src/mcp/server.js +34 -18
- package/src/server/index.js +26 -7
- package/src/server/server.test.js +47 -0
- package/src/ui/stat.js +1 -1
- package/src/ui/ui.test.js +6 -0
- package/docs/public/dist/accessibility.boot-5DVTARJU.js +0 -115
- package/docs/public/dist/actions.boot-P66HKQEM.js +0 -164
- package/docs/public/dist/auth.boot-IMAJAUPH.js +0 -140
- package/docs/public/dist/caching.boot-DVR6KDE7.js +0 -53
- package/docs/public/dist/components--accordion.boot-3HVKMNWC.js +0 -11
- package/docs/public/dist/components--alert.boot-GCEXOZAC.js +0 -6
- package/docs/public/dist/components--app-badge.boot-DVT3GCHJ.js +0 -6
- package/docs/public/dist/components--avatar.boot-PSW24EVA.js +0 -5
- package/docs/public/dist/components--badge.boot-TYDY2RMK.js +0 -7
- package/docs/public/dist/components--banner.boot-EI5PZSZK.js +0 -7
- package/docs/public/dist/components--breadcrumbs.boot-SMA2E2GO.js +0 -34
- package/docs/public/dist/components--button.boot-J54BQM2E.js +0 -23
- package/docs/public/dist/components--card.boot-PZGNDIB6.js +0 -138
- package/docs/public/dist/components--carousel.boot-TP6LPFZZ.js +0 -12
- package/docs/public/dist/components--charts.boot-2EOYQWKL.js +0 -108
- package/docs/public/dist/components--checkbox.boot-DS5BSL6T.js +0 -54
- package/docs/public/dist/components--cluster.boot-HHVIBBJG.js +0 -9
- package/docs/public/dist/components--code-window.boot-2GR2DV33.js +0 -20
- package/docs/public/dist/components--container.boot-7LOOGK2K.js +0 -5
- package/docs/public/dist/components--cta.boot-FSNZ5YRT.js +0 -11
- package/docs/public/dist/components--divider.boot-3NI2C3QG.js +0 -6
- package/docs/public/dist/components--empty.boot-YX2UR3PV.js +0 -7
- package/docs/public/dist/components--feature.boot-MUD7NSUO.js +0 -13
- package/docs/public/dist/components--fieldset.boot-J7BYHMKF.js +0 -19
- package/docs/public/dist/components--fileupload.boot-NIKVTTPD.js +0 -52
- package/docs/public/dist/components--footer.boot-EYUK5FRG.js +0 -14
- package/docs/public/dist/components--grid.boot-URDQVDDR.js +0 -59
- package/docs/public/dist/components--heading.boot-BPQKU43E.js +0 -44
- package/docs/public/dist/components--hero.boot-4RAPRGAB.js +0 -17
- package/docs/public/dist/components--icons.boot-ZITNU5JP.js +0 -68
- package/docs/public/dist/components--image.boot-XEEGHQZF.js +0 -19
- package/docs/public/dist/components--input.boot-SGASZG5K.js +0 -7
- package/docs/public/dist/components--list.boot-W3XC5MHD.js +0 -55
- package/docs/public/dist/components--media.boot-5VFIETZO.js +0 -13
- package/docs/public/dist/components--modal.boot-RZUYXBN2.js +0 -47
- package/docs/public/dist/components--nav.boot-ODBOHU7O.js +0 -33
- package/docs/public/dist/components--pricing.boot-4AQ4ZVBY.js +0 -21
- package/docs/public/dist/components--progress.boot-GHAGYZOK.js +0 -30
- package/docs/public/dist/components--prose.boot-QANJL6JI.js +0 -67
- package/docs/public/dist/components--pullquote.boot-Q2WMNAZU.js +0 -22
- package/docs/public/dist/components--radio.boot-TJRDQ2OL.js +0 -75
- package/docs/public/dist/components--rating.boot-QBAN6DEL.js +0 -38
- package/docs/public/dist/components--search.boot-PXH5O5AG.js +0 -17
- package/docs/public/dist/components--section.boot-AQGIYHWW.js +0 -12
- package/docs/public/dist/components--segmented.boot-BEVTKEJO.js +0 -33
- package/docs/public/dist/components--select.boot-47X5RHOC.js +0 -10
- package/docs/public/dist/components--slider.boot-PSRRX7XL.js +0 -47
- package/docs/public/dist/components--spinner.boot-MZ5MO2OH.js +0 -22
- package/docs/public/dist/components--stack.boot-DI4NJXBF.js +0 -9
- package/docs/public/dist/components--stat.boot-QMFUWBQT.js +0 -9
- package/docs/public/dist/components--stepper.boot-34PP2NEV.js +0 -22
- package/docs/public/dist/components--table.boot-FCQGSFIQ.js +0 -11
- package/docs/public/dist/components--testimonial.boot-DWQPDKYG.js +0 -11
- package/docs/public/dist/components--textarea.boot-QVXLBOJ5.js +0 -4
- package/docs/public/dist/components--timeline.boot-26LN52P2.js +0 -95
- package/docs/public/dist/components--toggle.boot-IQQEI76S.js +0 -29
- package/docs/public/dist/components--tooltip.boot-LGHCO6NN.js +0 -9
- package/docs/public/dist/components.boot-SE6PQ4P7.js +0 -103
- package/docs/public/dist/config.boot-DTRRWUE6.js +0 -126
- package/docs/public/dist/constraints.boot-DUHDZBMC.js +0 -71
- package/docs/public/dist/deploy.boot-SLAD3NI2.js +0 -163
- package/docs/public/dist/docs-8e3d4b5c.css +0 -1
- package/docs/public/dist/extending.boot-UA3CN243.js +0 -159
- package/docs/public/dist/faq.boot-6EQAWLQR.js +0 -43
- package/docs/public/dist/getting-started.boot-TDKIFL5U.js +0 -86
- package/docs/public/dist/guard.boot-AUHAWTG4.js +0 -80
- package/docs/public/dist/home.boot-BVQXRH32.js +0 -383
- package/docs/public/dist/how-it-works.boot-LTWAKWKW.js +0 -104
- package/docs/public/dist/hydration.boot-JRM6IPJL.js +0 -78
- package/docs/public/dist/images.boot-M6ZVKTZS.js +0 -80
- package/docs/public/dist/manifest.json +0 -94
- package/docs/public/dist/meta.boot-7NXGPHR4.js +0 -79
- package/docs/public/dist/mutations.boot-F6F43UDX.js +0 -79
- package/docs/public/dist/navigation.boot-AOXWS3ZF.js +0 -57
- package/docs/public/dist/performance.boot-C3UPCOBK.js +0 -98
- package/docs/public/dist/persist.boot-WT32PQOQ.js +0 -61
- package/docs/public/dist/project-structure.boot-FB3LRVJ4.js +0 -63
- package/docs/public/dist/prompt-examples.boot-YKR4VDK4.js +0 -31
- package/docs/public/dist/pulse-ui-81a85c03.css +0 -1
- package/docs/public/dist/raw-responses.boot-M4KA5YXL.js +0 -104
- package/docs/public/dist/routing.boot-FNX5FDGH.js +0 -70
- package/docs/public/dist/runtime-B73WLANC.js +0 -1
- package/docs/public/dist/runtime-KO4BHUQ3.js +0 -49
- package/docs/public/dist/runtime-L2HNXIHW.js +0 -59
- package/docs/public/dist/runtime-QFURDKA2.js +0 -5
- package/docs/public/dist/runtime-UVPXO4IR.js +0 -375
- package/docs/public/dist/runtime-VMJA3Z4N.js +0 -10
- package/docs/public/dist/runtime-ZJ4FXT5O.js +0 -11
- package/docs/public/dist/server-api.boot-K7X3LCFB.js +0 -219
- package/docs/public/dist/server-data.boot-Y7HQYC4R.js +0 -157
- package/docs/public/dist/slash-commands.boot-V2UV7OW2.js +0 -26
- package/docs/public/dist/spec.boot-2WU7ZHCV.js +0 -159
- package/docs/public/dist/state.boot-B24GUE3R.js +0 -73
- package/docs/public/dist/store.boot-TLIB4XHH.js +0 -150
- package/docs/public/dist/streaming.boot-W2DZSMW4.js +0 -80
- package/docs/public/dist/stripe.boot-QN3C2GEL.js +0 -164
- package/docs/public/dist/supabase.boot-BG4XXLZE.js +0 -303
- package/docs/public/dist/testing.boot-6U4WKMTE.js +0 -130
- package/docs/public/dist/validation.boot-PQHYGW5B.js +0 -100
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import{a as t,b as c}from"./runtime-ZJ4FXT5O.js";import{vb as e}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as d,h as i}from"./runtime-L2HNXIHW.js";import{a as o,b as n}from"./runtime-B73WLANC.js";var{prev:a,next:p}=d("/components/list"),r={route:"/components/list",meta:{title:"List \u2014 Pulse Docs",description:"Styled ordered and unordered list component for Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>c({currentHref:"/components/list",prev:a,next:p,name:"list",description:"Styled unordered or ordered list with consistent spacing and colour tokens. Use this instead of raw <code><ul></code> / <code><ol></code>. Items are HTML strings \u2014 other components can be passed as items.",content:`
|
|
2
|
-
|
|
3
|
-
<h2 class="doc-h2" id="unordered">Unordered</h2>
|
|
4
|
-
${t(e({items:["Streaming SSR on every page","Security headers by default","Zero client-side dependencies","Lighthouse 100 out of the box"]}),`list({
|
|
5
|
-
items: [
|
|
6
|
-
'Streaming SSR on every page',
|
|
7
|
-
'Security headers by default',
|
|
8
|
-
'Zero client-side dependencies',
|
|
9
|
-
'Lighthouse 100 out of the box',
|
|
10
|
-
],
|
|
11
|
-
})`,{col:!0})}
|
|
12
|
-
|
|
13
|
-
<h2 class="doc-h2" id="ordered">Ordered</h2>
|
|
14
|
-
${t(e({ordered:!0,items:["Create a new Pulse project","Add your pages to <code>src/pages/</code>","Run <code>pulse dev</code> to start the server","Deploy when ready"]}),`list({
|
|
15
|
-
ordered: true,
|
|
16
|
-
items: [
|
|
17
|
-
'Create a new Pulse project',
|
|
18
|
-
'Add your pages to src/pages/',
|
|
19
|
-
'Run pulse dev to start the server',
|
|
20
|
-
'Deploy when ready',
|
|
21
|
-
],
|
|
22
|
-
})`,{col:!0})}
|
|
23
|
-
|
|
24
|
-
<h2 class="doc-h2" id="gap">Gap</h2>
|
|
25
|
-
<p>Control vertical spacing between items with the <code>gap</code> prop.</p>
|
|
26
|
-
${t(`<div class="u-flex u-gap-8">
|
|
27
|
-
<div>
|
|
28
|
-
<p class="u-text-muted u-text-sm u-mb-2">xs</p>
|
|
29
|
-
${e({gap:"xs",items:["Design","Build","Ship"]})}
|
|
30
|
-
</div>
|
|
31
|
-
<div>
|
|
32
|
-
<p class="u-text-muted u-text-sm u-mb-2">sm (default)</p>
|
|
33
|
-
${e({gap:"sm",items:["Design","Build","Ship"]})}
|
|
34
|
-
</div>
|
|
35
|
-
<div>
|
|
36
|
-
<p class="u-text-muted u-text-sm u-mb-2">md</p>
|
|
37
|
-
${e({gap:"md",items:["Design","Build","Ship"]})}
|
|
38
|
-
</div>
|
|
39
|
-
</div>`,`list({ gap: 'xs', items: [...] })
|
|
40
|
-
list({ gap: 'sm', items: [...] }) // default
|
|
41
|
-
list({ gap: 'md', items: [...] })`,{col:!0})}
|
|
42
|
-
|
|
43
|
-
<h2 class="doc-h2" id="rich-items">Items with markup</h2>
|
|
44
|
-
<p>Items are HTML strings \u2014 pass any markup including other components. Always escape user data before including it in item strings.</p>
|
|
45
|
-
${t(e({items:["<strong>spec.state</strong> \u2014 initial client state, deep-cloned on mount","<strong>spec.mutations</strong> \u2014 synchronous state updates","<strong>spec.actions</strong> \u2014 async operations with lifecycle hooks","<strong>spec.server</strong> \u2014 server-side data fetchers"]}),`list({
|
|
46
|
-
items: [
|
|
47
|
-
'<strong>spec.state</strong> \u2014 initial client state',
|
|
48
|
-
'<strong>spec.mutations</strong> \u2014 synchronous state updates',
|
|
49
|
-
'<strong>spec.actions</strong> \u2014 async operations with lifecycle hooks',
|
|
50
|
-
'<strong>spec.server</strong> \u2014 server-side data fetchers',
|
|
51
|
-
],
|
|
52
|
-
})`,{col:!0})}
|
|
53
|
-
|
|
54
|
-
${i(["Prop","Type","Default",""],[["<code>items</code>","string[]","\u2014","Array of HTML strings for each list item \u2014 escape user data before passing"],["<code>ordered</code>","boolean","<code>false</code>","<code>false</code> renders <code><ul></code>, <code>true</code> renders <code><ol></code>"],["<code>gap</code>","<code>xs | sm | md</code>","<code>sm</code>","Vertical spacing between items"],["<code>class</code>","string","\u2014","Extra classes on the list element"]])}
|
|
55
|
-
`})};var s=document.getElementById("pulse-root");s&&!s.dataset.pulseMounted&&(s.dataset.pulseMounted="1",o(r,s,window.__PULSE_SERVER__||{},{ssr:!0}),n(s,o));var x=r;export{x as default};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import{a as i,b as s}from"./runtime-ZJ4FXT5O.js";import{Qa as d,Ua as m,a as c}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as r,h as n}from"./runtime-L2HNXIHW.js";import{a as t,b as a}from"./runtime-B73WLANC.js";var{prev:l,next:p}=r("/components/media"),o={route:"/components/media",meta:{title:"Media \u2014 Pulse Docs",description:"Media component for Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>s({currentHref:"/components/media",prev:l,next:p,name:"media",description:"Two-column image + text layout. Stacks vertically on mobile. Set <code>reverse</code> to alternate image position for multi-block feature sections.",content:`
|
|
2
|
-
${i(m({image:'<div style="background:var(--ui-surface-2);border:1px solid var(--ui-border);border-radius:8px;aspect-ratio:16/9;display:flex;align-items:center;justify-content:center;color:var(--ui-muted);font-size:.875rem">Screenshot</div>',content:d({gap:"md",content:'<h3 style="font-size:1.25rem;font-weight:700;color:var(--ui-text);margin:0">One-tap controls</h3><p style="color:var(--ui-muted);margin:0">Tap to flap. Chippy Bird takes seconds to learn and a lifetime to conquer.</p>'+c({label:"Download",href:"#"})})}),`media({
|
|
3
|
-
image: \`<img src="\${screenshot}" alt="App screenshot">\`,
|
|
4
|
-
content: stack({ gap: 'md', content:
|
|
5
|
-
'<h3>One-tap controls</h3>' +
|
|
6
|
-
'<p>Tap to flap.</p>' +
|
|
7
|
-
button({ label: 'Download', href: appStoreUrl })
|
|
8
|
-
}),
|
|
9
|
-
reverse: false,
|
|
10
|
-
})`)}
|
|
11
|
-
|
|
12
|
-
${n(["Prop","Type","Default",""],[["<code>image</code>","string (HTML)","\u2014","Raw HTML slot \u2014 img, figure, SVG, or styled div"],["<code>content</code>","string (HTML)","\u2014","Raw HTML slot"],["<code>reverse</code>","boolean","false","Puts text left, image right"],["<code>align</code>","string","'center'","'center' \xB7 'start'"],["<code>gap</code>","string","'md'","'sm' \xB7 'md' \xB7 'lg'"]])}
|
|
13
|
-
`})};var e=document.getElementById("pulse-root");e&&!e.dataset.pulseMounted&&(e.dataset.pulseMounted="1",t(o,e,window.__PULSE_SERVER__||{},{ssr:!0}),a(e,t));var w=o;export{w as default};
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import{a as i,b as g}from"./runtime-ZJ4FXT5O.js";import{Ra as l,Wa as o,Xa as t,a as r}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as c,h as a,i as d}from"./runtime-L2HNXIHW.js";import{a as n,b as m}from"./runtime-B73WLANC.js";var{prev:p,next:u}=c("/components/modal"),s={route:"/components/modal",meta:{title:"Modal \u2014 Pulse Docs",description:"Modal dialog component for Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>g({currentHref:"/components/modal",prev:p,next:u,name:"modal / modalTrigger",description:"A <code><dialog></code>-based modal with backdrop, animated open/close, and keyboard dismiss. The Pulse runtime handles open and close natively \u2014 no extra script needed.",content:`
|
|
2
|
-
${i(l({justify:"center",content:t({target:"demo-modal",label:"Open modal"})+o({id:"demo-modal",title:"Confirm action",content:'<p style="color:var(--ui-muted);margin:0">Are you sure you want to delete this item? This action cannot be undone.</p>',footer:r({label:"Cancel",variant:"secondary",type:"submit"})+r({label:"Delete",variant:"danger"})})}),`// Render the dialog somewhere on the page
|
|
3
|
-
modal({
|
|
4
|
-
id: 'confirm-delete',
|
|
5
|
-
title: 'Confirm action',
|
|
6
|
-
content: '<p>Are you sure? This cannot be undone.</p>',
|
|
7
|
-
footer:
|
|
8
|
-
button({ label: 'Cancel', variant: 'secondary' }) +
|
|
9
|
-
button({ label: 'Delete', variant: 'danger' }),
|
|
10
|
-
})
|
|
11
|
-
|
|
12
|
-
// Open it with a trigger button (or any element with data-dialog-open)
|
|
13
|
-
modalTrigger({ target: 'confirm-delete', label: 'Delete item', variant: 'danger' })`)}
|
|
14
|
-
|
|
15
|
-
<h3 class="doc-h3" id="sizes"><a href="#sizes" class="heading-anchor">Sizes</a></h3>
|
|
16
|
-
${i(l({gap:"sm",justify:"center",content:t({target:"demo-sm",label:"Small",variant:"secondary",size:"sm"})+t({target:"demo-lg",label:"Large",variant:"secondary",size:"sm"})+o({id:"demo-sm",title:"Small modal",size:"sm",content:'<p style="color:var(--ui-muted);margin:0">A compact dialog for quick confirmations.</p>'})+o({id:"demo-lg",title:"Large modal",size:"lg",content:'<p style="color:var(--ui-muted);margin:0">Use large modals for forms, rich content, or detail views that need more space.</p>'})}),"modal({ id: 'my-modal', title: 'Large modal', size: 'lg', content: '...' })")}
|
|
17
|
-
|
|
18
|
-
${a(["Prop","Type","Default",""],[["<code>id</code>","string","\u2014","Unique ID \u2014 required for triggers to target this dialog"],["<code>title</code>","string","\u2014",""],["<code>level</code>","number","2","Heading tag for the title (1\u20136). Visual style is unchanged."],["<code>content</code>","string (HTML)","\u2014","Body HTML"],["<code>footer</code>","string (HTML)","\u2014","Footer HTML \u2014 typically button() calls"],["<code>size</code>","<code>sm | md | lg | xl</code>","<code>md</code>",""],["<code>class</code>","string","\u2014",""]])}
|
|
19
|
-
|
|
20
|
-
<h3 class="doc-h3" id="trigger-props"><a href="#trigger-props" class="heading-anchor">modalTrigger props</a></h3>
|
|
21
|
-
|
|
22
|
-
${a(["Prop","Type","Default",""],[["<code>target</code>","string","\u2014","The modal's <code>id</code>"],["<code>label</code>","string","<code>Open</code>",""],["<code>variant</code>","<code>primary | secondary | ghost | danger</code>","<code>primary</code>",""],["<code>size</code>","<code>sm | md | lg</code>","<code>md</code>",""],["<code>class</code>","string","\u2014",""]])}
|
|
23
|
-
|
|
24
|
-
<h3 class="doc-h3" id="custom-trigger"><a href="#custom-trigger" class="heading-anchor">Custom triggers</a></h3>
|
|
25
|
-
<p class="doc-body">Any element with <code>data-dialog-open="<id>"</code> opens the dialog when clicked. Use <code>data-dialog-close</code> on any element inside or outside the dialog to close it programmatically:</p>
|
|
26
|
-
<pre class="code-block"><code><button data-dialog-open="my-modal">Open</button>
|
|
27
|
-
<button data-dialog-close>Cancel</button></code></pre>
|
|
28
|
-
${d("tip",'The dialog also closes on ESC, backdrop click, and <code><form method="dialog"></code> submit \u2014 all native browser behaviour, no JavaScript needed.')}
|
|
29
|
-
|
|
30
|
-
<h3 class="doc-h3" id="forms-inside"><a href="#forms-inside" class="heading-anchor">Forms inside a modal</a></h3>
|
|
31
|
-
<p class="doc-body"><code>modal()</code> wraps all content in <code><form method="dialog"></code> for native close behaviour. You <strong>cannot nest a <code><form data-action="..."></code> inside it</strong> \u2014 browsers silently discard nested forms, so the action will never fire.</p>
|
|
32
|
-
<p class="doc-body">When a modal button needs to trigger a Pulse action, place the form <em>outside</em> the modal and use the HTML <code>form</code> attribute to associate the button with it:</p>
|
|
33
|
-
<pre class="code-block"><code>// The action form lives outside the modal \u2014 hidden, no visible fields needed
|
|
34
|
-
<form id="delete-form" data-action="deleteAccount" style="display:none"></form>
|
|
35
|
-
|
|
36
|
-
\${modal({
|
|
37
|
-
id: 'confirm-delete',
|
|
38
|
-
title: 'Delete account?',
|
|
39
|
-
content: '<p>This cannot be undone.</p>',
|
|
40
|
-
footer:
|
|
41
|
-
// type="submit" with no form= closes the modal natively (submits <form method="dialog">)
|
|
42
|
-
button({ label: 'Cancel', variant: 'secondary', type: 'submit' }) +
|
|
43
|
-
// form="delete-form" associates this button with the external form \u2192 fires the action
|
|
44
|
-
button({ label: 'Confirm delete', variant: 'danger', attrs: { form: 'delete-form', type: 'submit' } }),
|
|
45
|
-
})}</code></pre>
|
|
46
|
-
${d("note","The hidden form needs no visible fields. <code>onStart</code> receives <code>state</code> and <code>formData</code> \u2014 read anything you need from state directly.")}
|
|
47
|
-
`})};var e=document.getElementById("pulse-root");e&&!e.dataset.pulseMounted&&(e.dataset.pulseMounted="1",n(s,e,window.__PULSE_SERVER__||{},{ssr:!0}),m(e,n));var C=s;export{C as default};
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import{a as s,b as d}from"./runtime-ZJ4FXT5O.js";import{La as t,a as o}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as i,h as a}from"./runtime-L2HNXIHW.js";import{a as l,b as r}from"./runtime-B73WLANC.js";var{prev:c,next:p}=i("/components/nav"),n={route:"/components/nav",meta:{title:"Nav \u2014 Pulse Docs",description:"Nav component for Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>d({currentHref:"/components/nav",prev:c,next:p,name:"nav",description:"Sticky-capable site header with logo, navigation links, and an optional CTA button. On mobile (< 640px) links collapse behind a burger button \u2014 clicking it reveals an overlay panel that sits on top of page content without pushing it down. Wired automatically by <code>pulse-ui.js</code>.",content:`
|
|
2
|
-
${s(t({logo:"<strong>MyApp</strong>",logoHref:"/",links:[{label:"Features",href:"#features"},{label:"Pricing",href:"#pricing"},{label:"FAQ",href:"#faq"}],action:o({label:"Download",size:"sm"}),sticky:!1}),`nav({
|
|
3
|
-
logo: '<strong>MyApp</strong>',
|
|
4
|
-
logoHref: '/',
|
|
5
|
-
links: [
|
|
6
|
-
{ label: 'Features', href: '#features' },
|
|
7
|
-
{ label: 'Pricing', href: '#pricing' },
|
|
8
|
-
{ label: 'FAQ', href: '#faq' },
|
|
9
|
-
],
|
|
10
|
-
action: button({ label: 'Download', size: 'sm' }),
|
|
11
|
-
sticky: true,
|
|
12
|
-
})`)}
|
|
13
|
-
|
|
14
|
-
<h2 class="doc-h2" id="mobile">Mobile view</h2>
|
|
15
|
-
<p>At < 640px the links and action are hidden and replaced with a burger button. The panel opens as an overlay \u2014 no layout shift.</p>
|
|
16
|
-
|
|
17
|
-
<div class="demo-phone demo-mobile-nav">
|
|
18
|
-
<div class="demo-phone-statusbar"><div class="demo-phone-pill"></div></div>
|
|
19
|
-
${t({logo:"<strong>MyApp</strong>",logoHref:"/",links:[{label:"Features",href:"#features"},{label:"Pricing",href:"#pricing"},{label:"FAQ",href:"#faq"}],action:o({label:"Download",size:"sm"})})}
|
|
20
|
-
<div class="demo-phone-content"><p>Tap the burger to open the overlay</p></div>
|
|
21
|
-
</div>
|
|
22
|
-
|
|
23
|
-
<h2 class="doc-h2" id="burger-left">Burger on the left</h2>
|
|
24
|
-
<p>Set <code>burgerAlign: 'left'</code> to place the burger before the logo \u2014 common in app-style layouts.</p>
|
|
25
|
-
|
|
26
|
-
<div class="demo-phone demo-mobile-nav">
|
|
27
|
-
<div class="demo-phone-statusbar"><div class="demo-phone-pill"></div></div>
|
|
28
|
-
${t({logo:"<strong>MyApp</strong>",logoHref:"/",links:[{label:"Features",href:"#features"},{label:"Pricing",href:"#pricing"},{label:"FAQ",href:"#faq"}],action:o({label:"Download",size:"sm"}),burgerAlign:"left"})}
|
|
29
|
-
<div class="demo-phone-content"><p>Burger on the left \u2014 logo stays right</p></div>
|
|
30
|
-
</div>
|
|
31
|
-
|
|
32
|
-
${a(["Prop","Type","Default",""],[["<code>logo</code>","string (HTML)","\u2014","Raw HTML slot \u2014 SVG, img, or text"],["<code>logoHref</code>","string","'/'",""],["<code>links</code>","array","[]","<code>{ label, href }[]</code>"],["<code>action</code>","string (HTML)","\u2014","Raw HTML slot \u2014 shown in desktop bar and mobile menu"],["<code>sticky</code>","boolean","false","position: sticky with backdrop blur"],["<code>burgerAlign</code>","string","'right'","'right' or 'left' \u2014 mobile burger position"]])}
|
|
33
|
-
`})};var e=document.getElementById("pulse-root");e&&!e.dataset.pulseMounted&&(e.dataset.pulseMounted="1",l(n,e,window.__PULSE_SERVER__||{},{ssr:!0}),r(e,l));var k=n;export{k as default};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import{a as o,b as p}from"./runtime-ZJ4FXT5O.js";import{Ja as t,a as e}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a,e as d,h as c}from"./runtime-L2HNXIHW.js";import{a as r,b as s}from"./runtime-B73WLANC.js";var{prev:l,next:g}=a("/components/pricing"),n={route:"/components/pricing",meta:{title:"Pricing \u2014 Pulse Docs",description:"Pricing component for Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>p({currentHref:"/components/pricing",prev:l,next:g,name:"pricing",description:"Single plan card with a feature list and CTA. Set <code>highlighted: true</code> on the recommended plan \u2014 it gets an accent border and a floating <code>badge</code> label.",content:`
|
|
2
|
-
${o(t({name:"Pro",price:"$9",period:"/month",description:"For growing teams",features:["Unlimited pages","Priority support","Custom domain"],highlighted:!0,badge:"Most popular",action:e({label:"Get started",fullWidth:!0})}),`pricing({
|
|
3
|
-
name: 'Pro',
|
|
4
|
-
price: '$9',
|
|
5
|
-
period: '/month',
|
|
6
|
-
description: 'For growing teams',
|
|
7
|
-
features: ['Unlimited pages', 'Priority support', 'Custom domain'],
|
|
8
|
-
highlighted: true,
|
|
9
|
-
badge: 'Most popular',
|
|
10
|
-
action: button({ label: 'Get started', fullWidth: true }),
|
|
11
|
-
})`,{col:!0})}
|
|
12
|
-
|
|
13
|
-
${d("multi-plan","Multi-plan layout")}
|
|
14
|
-
${o('<div class="ui-pricing-grid ui-pricing-grid--cols-3">'+t({name:"Free",price:"$0",period:"/month",description:"For personal projects",features:["3 pages","Community support"],action:e({label:"Get started",variant:"secondary",fullWidth:!0})})+t({name:"Pro",price:"$9",period:"/month",description:"For growing teams",features:["Unlimited pages","Priority support","Custom domain"],highlighted:!0,badge:"Most popular",action:e({label:"Get started",fullWidth:!0})})+t({name:"Team",price:"$29",period:"/month",description:"For large organisations",features:["Everything in Pro","SSO","SLA"],action:e({label:"Get started",variant:"secondary",fullWidth:!0})})+"</div>",`<div class="ui-pricing-grid ui-pricing-grid--cols-3">
|
|
15
|
-
\${pricing({ name: 'Free', price: '$0', ... })}
|
|
16
|
-
\${pricing({ name: 'Pro', price: '$9', highlighted: true, badge: 'Most popular', ... })}
|
|
17
|
-
\${pricing({ name: 'Team', price: '$29', ... })}
|
|
18
|
-
</div>`)}
|
|
19
|
-
|
|
20
|
-
${c(["Prop","Type","Default",""],[["<code>name</code>","string","\u2014",""],["<code>level</code>","number","3","Heading tag for the plan name (1\u20136). Visual style is unchanged."],["<code>price</code>","string","\u2014",'Formatted string \u2014 e.g. "$9", "Free"'],["<code>period</code>","string","\u2014",'e.g. "/month", "/year"'],["<code>description</code>","string","\u2014",""],["<code>features</code>","string[]","[]","List of feature strings"],["<code>action</code>","string (HTML)","\u2014","Raw HTML slot \u2014 typically a button()"],["<code>highlighted</code>","boolean","false","Accent border + elevated appearance"],["<code>badge</code>","string","\u2014","Floating label above the card"]])}
|
|
21
|
-
`})};var i=document.getElementById("pulse-root");i&&!i.dataset.pulseMounted&&(i.dataset.pulseMounted="1",r(n,i,window.__PULSE_SERVER__||{},{ssr:!0}),s(i,r));var v=n;export{v as default};
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import{a as o,b as d}from"./runtime-ZJ4FXT5O.js";import{Qa as a,hb as e}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as l,h as n}from"./runtime-L2HNXIHW.js";import{a as t,b as c}from"./runtime-B73WLANC.js";var{prev:u,next:i}=l("/components/progress"),s={route:"/components/progress",meta:{title:"Progress \u2014 Pulse Docs",description:"Progress bar component for Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>d({currentHref:"/components/progress",prev:u,next:i,name:"progress",description:'Horizontal progress bar with determinate and indeterminate states. Correct <code>role="progressbar"</code> and ARIA attributes are set automatically.',content:`
|
|
2
|
-
|
|
3
|
-
<h2 class="doc-h2" id="default">Default</h2>
|
|
4
|
-
${o(a({gap:"md",content:e({value:25})+e({value:50})+e({value:75})+e({value:100})}),`progress({ value: 25 })
|
|
5
|
-
progress({ value: 50 })
|
|
6
|
-
progress({ value: 75 })
|
|
7
|
-
progress({ value: 100 })`,{col:!0})}
|
|
8
|
-
|
|
9
|
-
<h2 class="doc-h2" id="label">With label and value</h2>
|
|
10
|
-
<p>Set <code>showLabel</code> and <code>showValue</code> to render text above the bar.</p>
|
|
11
|
-
${o(a({gap:"lg",content:e({value:68,label:"Storage used",showLabel:!0,showValue:!0})+e({value:32,label:"Upload complete",showLabel:!0,showValue:!0})}),`progress({ value: 68, label: 'Storage used', showLabel: true, showValue: true })
|
|
12
|
-
progress({ value: 32, label: 'Upload complete', showLabel: true, showValue: true })`,{col:!0})}
|
|
13
|
-
|
|
14
|
-
<h2 class="doc-h2" id="variants">Variants</h2>
|
|
15
|
-
${o(a({gap:"md",content:e({value:80,variant:"accent"})+e({value:80,variant:"success"})+e({value:80,variant:"warning"})+e({value:80,variant:"error"})}),`progress({ value: 80, variant: 'accent' })
|
|
16
|
-
progress({ value: 80, variant: 'success' })
|
|
17
|
-
progress({ value: 80, variant: 'warning' })
|
|
18
|
-
progress({ value: 80, variant: 'error' })`,{col:!0})}
|
|
19
|
-
|
|
20
|
-
<h2 class="doc-h2" id="sizes">Sizes</h2>
|
|
21
|
-
${o(a({gap:"md",content:e({value:60,size:"sm"})+e({value:60,size:"md"})+e({value:60,size:"lg"})}),`progress({ value: 60, size: 'sm' })
|
|
22
|
-
progress({ value: 60, size: 'md' })
|
|
23
|
-
progress({ value: 60, size: 'lg' })`,{col:!0})}
|
|
24
|
-
|
|
25
|
-
<h2 class="doc-h2" id="indeterminate">Indeterminate</h2>
|
|
26
|
-
<p>Omit <code>value</code> when the total duration is unknown \u2014 the bar animates continuously.</p>
|
|
27
|
-
${o(e({label:"Loading\u2026"}),"progress({ label: 'Loading\u2026' }) // no value = indeterminate",{col:!0})}
|
|
28
|
-
|
|
29
|
-
${n(["Prop","Type","Default",""],[["<code>value</code>","number","\u2014","Current value. Omit for indeterminate."],["<code>max</code>","number","100",""],["<code>label</code>","string","\u2014","Sets <code>aria-label</code> and the visible label when <code>showLabel</code> is true"],["<code>showLabel</code>","boolean","false","Render label text above the bar"],["<code>showValue</code>","boolean","false","Render percentage above the bar (right-aligned)"],["<code>variant</code>","<code>accent | success | warning | error</code>","<code>accent</code>",""],["<code>size</code>","<code>sm | md | lg</code>","<code>md</code>",".25rem / .5rem / 1rem"],["<code>class</code>","string","\u2014",""]])}
|
|
30
|
-
`})};var r=document.getElementById("pulse-root");r&&!r.dataset.pulseMounted&&(r.dataset.pulseMounted="1",t(s,r,window.__PULSE_SERVER__||{},{ssr:!0}),c(r,t));var z=s;export{z as default};
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import{a as o,b as d}from"./runtime-ZJ4FXT5O.js";import{tb as e}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as i,h as n,i as l}from"./runtime-L2HNXIHW.js";import{a as s,b as a}from"./runtime-B73WLANC.js";var{prev:c,next:p}=i("/components/prose"),u=`<h2>Why great coffee starts with water</h2>
|
|
2
|
-
<p>Most home baristas obsess over beans and grinders, but water quality is the single biggest variable in your cup. Tap water that is too hard leaves bitter, chalky espresso. Too soft and your shots taste flat and lifeless.</p>
|
|
3
|
-
<h3>The ideal mineral balance</h3>
|
|
4
|
-
<p>Speciality roasters recommend water with a total dissolved solids (TDS) between <strong>75\u2013150 mg/L</strong> and a magnesium content of at least 10 mg/L. Magnesium is the mineral most responsible for extracting the fruity, floral notes from light roasts.</p>
|
|
5
|
-
<h3>What to do if your tap water is off</h3>
|
|
6
|
-
<ul>
|
|
7
|
-
<li>Use a filter jug \u2014 Brita Maxtra+ reduces hardness and chlorine</li>
|
|
8
|
-
<li>Try third-wave water sachets \u2014 add to distilled water for precise control</li>
|
|
9
|
-
<li>Blend tap with still mineral water to hit the right TDS range</li>
|
|
10
|
-
</ul>
|
|
11
|
-
<blockquote>Water is the ingredient you can control most precisely, yet almost nobody does.</blockquote>
|
|
12
|
-
<p>Once your water is dialled in, even a modest grinder will produce noticeably better results. <a href="#">Read our water guide</a> for a full breakdown by region.</p>`,r={route:"/components/prose",meta:{title:"Prose \u2014 Pulse Docs",description:"Typography wrapper for CMS output and rich text content in Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>d({currentHref:"/components/prose",prev:c,next:p,name:"prose",description:"Typography wrapper for rich text you don't control: CMS output, markdown-rendered HTML, database content, blog posts. Styles all descendant elements \u2014 headings, paragraphs, lists, blockquotes, code, tables \u2014 using <code>--ui-*</code> tokens. No classes needed on individual elements.",content:`
|
|
13
|
-
|
|
14
|
-
<h2 class="doc-h2" id="basic">Basic</h2>
|
|
15
|
-
<p>Pass any HTML string to <code>content</code>. All elements inside are styled automatically.</p>
|
|
16
|
-
${o(e({content:u}),`import { prose } from '@invisibleloop/pulse/ui'
|
|
17
|
-
|
|
18
|
-
// CMS rich text field \u2014 output directly, fully styled
|
|
19
|
-
prose({ content: server.article.bodyHtml })
|
|
20
|
-
|
|
21
|
-
// Markdown rendered to HTML
|
|
22
|
-
prose({ content: renderMarkdown(server.post.body) })`,{col:!0})}
|
|
23
|
-
|
|
24
|
-
<h2 class="doc-h2" id="size">Size</h2>
|
|
25
|
-
<p>Scale the base font size for different contexts.</p>
|
|
26
|
-
${o(`<div class="u-flex u-flex-col u-gap-8">
|
|
27
|
-
<div>
|
|
28
|
-
<p class="u-text-muted u-text-sm u-mb-3">sm \u2014 footnotes, sidebars</p>
|
|
29
|
-
${e({content:"<p>The quick brown fox jumps over the lazy dog. Pack my box with five dozen liquor jugs.</p><ul><li>Smaller text</li><li>Tighter line height</li></ul>",size:"sm"})}
|
|
30
|
-
</div>
|
|
31
|
-
<div>
|
|
32
|
-
<p class="u-text-muted u-text-sm u-mb-3">base (default)</p>
|
|
33
|
-
${e({content:"<p>The quick brown fox jumps over the lazy dog. Pack my box with five dozen liquor jugs.</p><ul><li>Default size</li><li>Standard line height</li></ul>"})}
|
|
34
|
-
</div>
|
|
35
|
-
<div>
|
|
36
|
-
<p class="u-text-muted u-text-sm u-mb-3">lg \u2014 hero intro, feature descriptions</p>
|
|
37
|
-
${e({content:"<p>The quick brown fox jumps over the lazy dog. Pack my box with five dozen liquor jugs.</p><ul><li>Larger text</li><li>More generous spacing</li></ul>",size:"lg"})}
|
|
38
|
-
</div>
|
|
39
|
-
</div>`,`prose({ content: cms.body, size: 'sm' }) // footnotes, sidebars
|
|
40
|
-
prose({ content: cms.body }) // default
|
|
41
|
-
prose({ content: cms.intro, size: 'lg' }) // hero intro`,{col:!0})}
|
|
42
|
-
|
|
43
|
-
<h2 class="doc-h2" id="elements">Styled elements</h2>
|
|
44
|
-
<p>Every common HTML element rendered inside <code>prose()</code> is styled using <code>--ui-*</code> tokens:</p>
|
|
45
|
-
${o(e({content:`
|
|
46
|
-
<h2>h2 heading</h2>
|
|
47
|
-
<h3>h3 heading</h3>
|
|
48
|
-
<p>A paragraph with <strong>bold</strong>, <em>italic</em>, and <a href="#">a link</a>. Also <code>inline code</code>.</p>
|
|
49
|
-
<ul><li>Unordered item one</li><li>Unordered item two</li></ul>
|
|
50
|
-
<ol><li>Ordered item one</li><li>Ordered item two</li></ol>
|
|
51
|
-
<blockquote>A blockquote with an accent left border.</blockquote>
|
|
52
|
-
<pre><code>// A code block
|
|
53
|
-
const x = 1 + 2</code></pre>
|
|
54
|
-
<hr>
|
|
55
|
-
<p class="u-text-sm u-text-muted">End of content.</p>
|
|
56
|
-
`}),`prose({ content: \`
|
|
57
|
-
<h2>Section heading</h2>
|
|
58
|
-
<p>Paragraph with <strong>bold</strong> and <a href="#">a link</a>.</p>
|
|
59
|
-
<ul><li>List item</li></ul>
|
|
60
|
-
<blockquote>A quote.</blockquote>
|
|
61
|
-
<pre><code>const x = 1</code></pre>
|
|
62
|
-
\` })`,{col:!0})}
|
|
63
|
-
|
|
64
|
-
${l("warning","<strong>Do not escape the content prop.</strong> <code>prose()</code> renders raw HTML \u2014 it is designed for trusted server-side content only. Never pass unescaped user input directly. Sanitise CMS output before rendering if your CMS allows arbitrary HTML.")}
|
|
65
|
-
|
|
66
|
-
${n(["Prop","Type","Default",""],[["<code>content</code>","string","\u2014","Raw HTML string \u2014 rendered as-is, not escaped. Use for server-side content only."],["<code>size</code>","<code>sm | base | lg</code>","<code>base</code>","Base font size scale. <code>sm</code>=0.875rem, <code>base</code>=1rem, <code>lg</code>=1.125rem"],["<code>class</code>","string","\u2014","Extra classes on the wrapper <code><div></code>"]])}
|
|
67
|
-
`})};var t=document.getElementById("pulse-root");t&&!t.dataset.pulseMounted&&(t.dataset.pulseMounted="1",s(r,t,window.__PULSE_SERVER__||{},{ssr:!0}),a(t,s));var x=r;export{x as default};
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import{a as t,b as d}from"./runtime-ZJ4FXT5O.js";import{sb as o}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as n,h as l}from"./runtime-L2HNXIHW.js";import{a as i,b as c}from"./runtime-B73WLANC.js";var{prev:u,next:r}=n("/components/pullquote"),s={route:"/components/pullquote",meta:{title:"Pullquote \u2014 Pulse Docs",description:"Styled blockquote component for Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>d({currentHref:"/components/pullquote",prev:u,next:r,name:"pullquote",description:"Styled blockquote with an accent left border and optional attribution. Use it to highlight key quotes or testimonials within body content.",content:`
|
|
2
|
-
|
|
3
|
-
<h2 class="doc-h2" id="basic">Basic</h2>
|
|
4
|
-
${t(o({quote:"Design is not just what it looks like and feels like. Design is how it works.",cite:"Steve Jobs, co-founder of Apple"}),`pullquote({
|
|
5
|
-
quote: 'Design is not just what it looks like and feels like. Design is how it works.',
|
|
6
|
-
cite: 'Steve Jobs, co-founder of Apple',
|
|
7
|
-
})`)}
|
|
8
|
-
|
|
9
|
-
<h2 class="doc-h2" id="large">Large</h2>
|
|
10
|
-
${t(o({quote:"Simplicity is the ultimate sophistication.",cite:"Leonardo da Vinci",size:"lg"}),`pullquote({
|
|
11
|
-
quote: 'Simplicity is the ultimate sophistication.',
|
|
12
|
-
cite: 'Leonardo da Vinci',
|
|
13
|
-
size: 'lg',
|
|
14
|
-
})`)}
|
|
15
|
-
|
|
16
|
-
<h2 class="doc-h2" id="no-cite">Without attribution</h2>
|
|
17
|
-
${t(o({quote:"Good design makes a product understandable."}),`pullquote({
|
|
18
|
-
quote: 'Good design makes a product understandable.',
|
|
19
|
-
})`)}
|
|
20
|
-
|
|
21
|
-
${l(["Prop","Type","Default",""],[["<code>quote</code>","string","\u2014","The quote text \u2014 escaped automatically"],["<code>cite</code>","string","\u2014","Attribution text \u2014 rendered in a <code><figcaption></code>"],["<code>size</code>","<code>md | lg</code>","<code>md</code>","Controls the font size of the quote text"],["<code>class</code>","string","\u2014",""]])}
|
|
22
|
-
`})};var e=document.getElementById("pulse-root");e&&!e.dataset.pulseMounted&&(e.dataset.pulseMounted="1",i(s,e,window.__PULSE_SERVER__||{},{ssr:!0}),c(e,i));var k=s;export{k as default};
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import{a as e,b as s}from"./runtime-ZJ4FXT5O.js";import{db as t,eb as o,ya as p}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as i,h as l,i as n}from"./runtime-L2HNXIHW.js";import{a as d,b as c}from"./runtime-B73WLANC.js";var{prev:u,next:m}=i("/components/radio"),r={route:"/components/radio",meta:{title:"Radio \u2014 Pulse Docs",description:"Radio button and radio group components for Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>s({currentHref:"/components/radio",prev:u,next:m,name:"radio",description:"Custom-styled radio buttons with full keyboard and screen-reader support. Use <code>radio()</code> for a single option or <code>radioGroup()</code> for a semantic group inside a form.",content:`
|
|
2
|
-
|
|
3
|
-
<h2 class="doc-h2" id="group">Radio group</h2>
|
|
4
|
-
<p>The standard usage. <code>radioGroup()</code> renders a <code><fieldset></code> with a <code><legend></code> and marks the currently selected option via the <code>value</code> prop.</p>
|
|
5
|
-
${e(o({name:"plan",legend:"Plan",value:"pro",options:[{value:"starter",label:"Starter"},{value:"pro",label:"Pro"},{value:"team",label:"Team"}]}),`radioGroup({
|
|
6
|
-
name: 'plan',
|
|
7
|
-
legend: 'Plan',
|
|
8
|
-
value: state.plan, // marks the selected option
|
|
9
|
-
options: [
|
|
10
|
-
{ value: 'starter', label: 'Starter' },
|
|
11
|
-
{ value: 'pro', label: 'Pro' },
|
|
12
|
-
{ value: 'team', label: 'Team' },
|
|
13
|
-
],
|
|
14
|
-
})`,{col:!0})}
|
|
15
|
-
|
|
16
|
-
<h2 class="doc-h2" id="hints">Per-option hints</h2>
|
|
17
|
-
<p>Each option accepts a <code>hint</code> string for supporting copy below the label.</p>
|
|
18
|
-
${e(o({name:"billing",legend:"Billing cycle",value:"annual",options:[{value:"monthly",label:"Monthly",hint:"Billed every month. Cancel any time."},{value:"annual",label:"Annual",hint:"Billed once a year. Save 20%."}]}),`radioGroup({
|
|
19
|
-
name: 'billing',
|
|
20
|
-
legend: 'Billing cycle',
|
|
21
|
-
value: state.billing,
|
|
22
|
-
options: [
|
|
23
|
-
{ value: 'monthly', label: 'Monthly', hint: 'Billed every month. Cancel any time.' },
|
|
24
|
-
{ value: 'annual', label: 'Annual', hint: 'Billed once a year. Save 20%.' },
|
|
25
|
-
],
|
|
26
|
-
})`,{col:!0})}
|
|
27
|
-
|
|
28
|
-
<h2 class="doc-h2" id="error">Error state</h2>
|
|
29
|
-
<p>Pass <code>error</code> to show a validation message below the group. The message is linked via <code>aria-describedby</code>.</p>
|
|
30
|
-
${e(o({name:"size",legend:"Size",error:"Please select a size.",options:[{value:"sm",label:"Small"},{value:"md",label:"Medium"},{value:"lg",label:"Large"}]}),`radioGroup({
|
|
31
|
-
name: 'size',
|
|
32
|
-
legend: 'Size',
|
|
33
|
-
error: server.errors.size,
|
|
34
|
-
options: [
|
|
35
|
-
{ value: 'sm', label: 'Small' },
|
|
36
|
-
{ value: 'md', label: 'Medium' },
|
|
37
|
-
{ value: 'lg', label: 'Large' },
|
|
38
|
-
],
|
|
39
|
-
})`,{col:!0})}
|
|
40
|
-
|
|
41
|
-
<h2 class="doc-h2" id="disabled">Disabled options</h2>
|
|
42
|
-
<p>Set <code>disabled: true</code> on individual options, or pass <code>disabled</code> at the group level to disable all.</p>
|
|
43
|
-
${e(o({name:"tier",legend:"Tier",value:"basic",options:[{value:"basic",label:"Basic"},{value:"pro",label:"Pro"},{value:"enterprise",label:"Enterprise",disabled:!0}]}),`radioGroup({
|
|
44
|
-
name: 'tier',
|
|
45
|
-
legend: 'Tier',
|
|
46
|
-
value: state.tier,
|
|
47
|
-
options: [
|
|
48
|
-
{ value: 'basic', label: 'Basic' },
|
|
49
|
-
{ value: 'pro', label: 'Pro' },
|
|
50
|
-
{ value: 'enterprise', label: 'Enterprise', disabled: true },
|
|
51
|
-
],
|
|
52
|
-
})`,{col:!0})}
|
|
53
|
-
|
|
54
|
-
<h2 class="doc-h2" id="gap">Gap</h2>
|
|
55
|
-
<p>Control spacing between options with <code>gap</code>: <code>'sm'</code> \xB7 <code>'md'</code> (default) \xB7 <code>'lg'</code>.</p>
|
|
56
|
-
${e(o({name:"color",legend:"Colour",gap:"lg",value:"blue",options:[{value:"red",label:"Red"},{value:"blue",label:"Blue"},{value:"green",label:"Green"}]}),"radioGroup({ ..., gap: 'lg' })")}
|
|
57
|
-
|
|
58
|
-
<h2 class="doc-h2" id="single">Single radio</h2>
|
|
59
|
-
<p>Use <code>radio()</code> directly when you need to compose your own group layout \u2014 for example inside a <a href="/components/fieldset">fieldset</a> alongside other controls.</p>
|
|
60
|
-
${e(p({legend:"Preferred contact",content:t({name:"contact",value:"email",label:"Email",checked:!0})+t({name:"contact",value:"phone",label:"Phone"})}),`fieldset({
|
|
61
|
-
legend: 'Preferred contact',
|
|
62
|
-
content:
|
|
63
|
-
radio({ name: 'contact', value: 'email', label: 'Email', checked: true }) +
|
|
64
|
-
radio({ name: 'contact', value: 'phone', label: 'Phone' }),
|
|
65
|
-
})`,{col:!0})}
|
|
66
|
-
|
|
67
|
-
<h2 class="doc-h2" id="in-forms">In forms</h2>
|
|
68
|
-
${n("note","Radio groups submit the selected <code>value</code> string under <code>name</code> in FormData. If nothing is selected, the field is absent from FormData. Read it in <code>action.onStart</code> or <code>action.run</code> via <code>formData.get('plan')</code>.")}
|
|
69
|
-
|
|
70
|
-
<h2 class="doc-h2" id="props-group">radioGroup() props</h2>
|
|
71
|
-
${l(["Prop","Type","Default",""],[["<code>name</code>","string","\u2014","Shared <code>name</code> attribute for all inputs in the group"],["<code>legend</code>","string","\u2014","Group label \u2014 renders as a <code><legend></code>"],["<code>options</code>","array","<code>[]</code>","Array of <code>{ value, label, hint?, disabled? }</code>"],["<code>value</code>","string","\u2014","The currently selected value \u2014 marks the matching option as <code>checked</code>"],["<code>hint</code>","string","\u2014","Helper text below the group"],["<code>error</code>","string","\u2014","Validation error \u2014 linked via <code>aria-describedby</code>"],["<code>gap</code>","<code>sm | md | lg</code>","<code>md</code>","Spacing between options"],["<code>class</code>","string","\u2014",""]])}
|
|
72
|
-
|
|
73
|
-
<h2 class="doc-h2" id="props-radio">radio() props</h2>
|
|
74
|
-
${l(["Prop","Type","Default",""],[["<code>name</code>","string","\u2014","Field name"],["<code>value</code>","string","\u2014","Submitted value when this option is selected"],["<code>label</code>","string","\u2014","Visible label"],["<code>checked</code>","boolean","false",""],["<code>disabled</code>","boolean","false",""],["<code>id</code>","string","\u2014","Override the generated <code>id</code>"],["<code>class</code>","string","\u2014",""]])}
|
|
75
|
-
`})};var a=document.getElementById("pulse-root");a&&!a.dataset.pulseMounted&&(a.dataset.pulseMounted="1",d(r,a,window.__PULSE_SERVER__||{},{ssr:!0}),c(a,d));var w=r;export{w as default};
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import{a,b as l}from"./runtime-ZJ4FXT5O.js";import{c,fb as e}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as s,h as r,i as n}from"./runtime-L2HNXIHW.js";import{a as i,b as d}from"./runtime-B73WLANC.js";var{prev:m,next:u}=s("/components/rating"),o={route:"/components/rating",meta:{title:"Rating \u2014 Pulse Docs",description:"Star rating display and interactive input component for Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>l({currentHref:"/components/rating",prev:m,next:u,name:"rating",description:"Star rating component with two modes. Without <code>name</code>: a read-only display that supports half-star values. With <code>name</code>: an interactive radio group that submits the selected value in FormData \u2014 no JavaScript required.",content:`
|
|
2
|
-
|
|
3
|
-
<h2 class="doc-h2" id="display">Display (read-only)</h2>
|
|
4
|
-
<p>Omit <code>name</code> to render a read-only display. Pass <code>value</code> as a number \u2014 halves are supported.</p>
|
|
5
|
-
${a('<div style="display:flex;flex-direction:column;gap:1rem;align-items:flex-start">'+e({value:5})+e({value:3.5})+e({value:2})+e({value:0})+"</div>",`rating({ value: 5 }) // 5 stars
|
|
6
|
-
rating({ value: 3.5 }) // 3\xBD stars
|
|
7
|
-
rating({ value: 2 }) // 2 stars
|
|
8
|
-
rating({ value: 0 }) // empty`)}
|
|
9
|
-
|
|
10
|
-
<h2 class="doc-h2" id="sizes">Sizes</h2>
|
|
11
|
-
<p><code>'sm'</code> \xB7 <code>'md'</code> (default) \xB7 <code>'lg'</code></p>
|
|
12
|
-
${a('<div style="display:flex;flex-direction:column;gap:1rem;align-items:flex-start">'+e({value:4,size:"sm"})+e({value:4,size:"md"})+e({value:4,size:"lg"})+"</div>",`rating({ value: 4, size: 'sm' })
|
|
13
|
-
rating({ value: 4, size: 'md' })
|
|
14
|
-
rating({ value: 4, size: 'lg' })`)}
|
|
15
|
-
|
|
16
|
-
<h2 class="doc-h2" id="interactive">Interactive</h2>
|
|
17
|
-
<p>Add <code>name</code> to render radio inputs. Hovering a star previews the selection; clicking locks it. The selected value is submitted in FormData.</p>
|
|
18
|
-
${a(e({name:"score",label:"Your rating",value:3,size:"lg"}),"rating({ name: 'score', label: 'Your rating', value: state.score, size: 'lg' })")}
|
|
19
|
-
|
|
20
|
-
<h2 class="doc-h2" id="in-card">In a card</h2>
|
|
21
|
-
${a('<div style="max-width:320px">'+c({title:"Noise-Cancelling Headphones",content:'<div style="display:flex;align-items:center;gap:.75rem;margin-bottom:.75rem">'+e({value:4.5})+'<span style="color:var(--ui-muted);font-size:.85rem">4.5 \xB7 1,284 reviews</span></div><p style="color:var(--ui-muted);margin:0;font-size:.9rem">Crystal-clear audio with 40-hour battery life and adaptive noise cancellation.</p>'})+"</div>",`card({
|
|
22
|
-
title: 'Noise-Cancelling Headphones',
|
|
23
|
-
content:
|
|
24
|
-
'<div style="display:flex;align-items:center;gap:.75rem">' +
|
|
25
|
-
rating({ value: 4.5 }) +
|
|
26
|
-
'<span>4.5 \xB7 1,284 reviews</span>' +
|
|
27
|
-
'</div>' +
|
|
28
|
-
'<p>Crystal-clear audio...</p>',
|
|
29
|
-
})`)}
|
|
30
|
-
|
|
31
|
-
<h2 class="doc-h2" id="disabled">Disabled</h2>
|
|
32
|
-
${a(e({name:"locked",value:4,disabled:!0}),"rating({ name: 'locked', value: 4, disabled: true })")}
|
|
33
|
-
|
|
34
|
-
<h2 class="doc-h2" id="in-forms">In forms</h2>
|
|
35
|
-
${n("note","The interactive rating submits the selected star count as a number string under <code>name</code> in FormData. Read it with <code>Number(formData.get('score'))</code>. If nothing is selected, the field is absent from FormData.")}
|
|
36
|
-
|
|
37
|
-
${r(["Prop","Type","Default",""],[["<code>value</code>","number","0","Current rating. Supports 0.5 steps in display mode."],["<code>max</code>","number","5","Total number of stars"],["<code>name</code>","string","\u2014","Field name \u2014 enables interactive radio mode"],["<code>label</code>","string","\u2014","Accessible group label (interactive mode only)"],["<code>size</code>","<code>sm | md | lg</code>","<code>md</code>","1rem / 1.5rem / 2rem"],["<code>disabled</code>","boolean","false","Interactive mode only"],["<code>class</code>","string","\u2014",""]])}
|
|
38
|
-
`})};var t=document.getElementById("pulse-root");t&&!t.dataset.pulseMounted&&(t.dataset.pulseMounted="1",i(o,t,window.__PULSE_SERVER__||{},{ssr:!0}),d(t,i));var z=o;export{z as default};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import{a as d,b as l}from"./runtime-ZJ4FXT5O.js";import{xa as o}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as c,h as n}from"./runtime-L2HNXIHW.js";import{a as t,b as r}from"./runtime-B73WLANC.js";var{prev:s,next:i}=c("/components/search"),a={route:"/components/search",meta:{title:"Search \u2014 Pulse Docs",description:"Search input component with icon, debounce binding, and clear button.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>l({currentHref:"/components/search",prev:s,next:i,name:"search",description:"A search input with a built-in icon and optional clear button. Handles the native browser cancel button, <code>data-event</code> binding, and debounce in one component. Use this instead of <code>input({ type: 'search' })</code>.",content:`
|
|
2
|
-
${d(o({name:"q",label:"Search",placeholder:"Search products\u2026"})+o({name:"q2",label:"Search",placeholder:"Search\u2026",value:"lamp",clearEvent:"clearSearch",labelHidden:!0}),`search({ name: 'q', label: 'Search', placeholder: 'Search products\u2026' })
|
|
3
|
-
|
|
4
|
-
// With value, clear button, and hidden label:
|
|
5
|
-
search({
|
|
6
|
-
name: 'q',
|
|
7
|
-
label: 'Search',
|
|
8
|
-
labelHidden: true,
|
|
9
|
-
placeholder: 'Search\u2026',
|
|
10
|
-
value: state.search,
|
|
11
|
-
event: 'input:setSearch',
|
|
12
|
-
debounce: 200,
|
|
13
|
-
clearEvent: 'clearSearch',
|
|
14
|
-
})`,{col:!0})}
|
|
15
|
-
|
|
16
|
-
${n(["Prop","Type","Default",""],[["<code>name</code>","string","\u2014","Field name and id base"],["<code>label</code>","string","\u2014","Label text \u2014 always provide for accessibility"],["<code>labelHidden</code>","boolean","false","Hides label visually; still read by screen readers"],["<code>placeholder</code>","string","\u2014",""],["<code>value</code>","string","\u2014","Current value \u2014 controls clear button visibility"],["<code>event</code>","string","\u2014","<code>data-event</code> binding, e.g. <code>'input:setSearch'</code>"],["<code>debounce</code>","number","200","Debounce delay in ms \u2014 only applied when <code>event</code> is set"],["<code>clearEvent</code>","string","\u2014","Click event for the \xD7 button \u2014 only shown when <code>value</code> is non-empty"],["<code>disabled</code>","boolean","false",""],["<code>id</code>","string","\u2014","Override generated id"],["<code>class</code>","string","\u2014","Extra classes on the wrapper"],["<code>attrs</code>","object","{}","Extra attributes on the <code><input></code>"]])}
|
|
17
|
-
`})};var e=document.getElementById("pulse-root");e&&!e.dataset.pulseMounted&&(e.dataset.pulseMounted="1",t(a,e,window.__PULSE_SERVER__||{},{ssr:!0}),r(e,t));var S=a;export{S as default};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import{a as s,b as d}from"./runtime-ZJ4FXT5O.js";import{Na as o,Oa as n}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as r,h as c}from"./runtime-L2HNXIHW.js";import{a as t,b as a}from"./runtime-B73WLANC.js";var{prev:l,next:p}=r("/components/section"),i={route:"/components/section",meta:{title:"Section \u2014 Pulse Docs",description:"Vertical padding wrapper with optional background. Compose with container() for full-width background with constrained content.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>d({currentHref:"/components/section",prev:l,next:p,name:"section",description:"Vertical padding wrapper with optional background. Compose with <code>container()</code> for full-width background with constrained content.",content:`
|
|
2
|
-
${s(n({eyebrow:"Why Pulse",title:"Built for speed.",subtitle:"Every page scores 100 on Lighthouse by design, not by optimisation.",align:"center",variant:"alt",content:o({size:"md",content:'<p style="text-align:center;color:var(--ui-muted)">Content goes here</p>'})})+n({variant:"dark",content:o({size:"md",content:'<p style="text-align:center;color:var(--ui-muted)">Dark background \xB7 no header</p>'})}),`section({
|
|
3
|
-
eyebrow: 'Why Pulse',
|
|
4
|
-
title: 'Built for speed.',
|
|
5
|
-
subtitle: 'Every page scores 100 on Lighthouse by design.',
|
|
6
|
-
align: 'center',
|
|
7
|
-
variant: 'alt',
|
|
8
|
-
content: container({ size: 'lg', content: featureGrid }),
|
|
9
|
-
})`)}
|
|
10
|
-
|
|
11
|
-
${c(["Prop","Type","Default",""],[["<code>content</code>","string (HTML)","\u2014","Raw HTML slot"],["<code>variant</code>","string","'default'","'default' \xB7 'alt' \xB7 'dark'"],["<code>padding</code>","string","'md'","'sm' \xB7 'md' \xB7 'lg'"],["<code>id</code>","string","\u2014","Anchor id for nav links"],["<code>eyebrow</code>","string","\u2014","Small label above the title"],["<code>title</code>","string","\u2014","Section heading"],["<code>level</code>","number","2","Heading tag for the title (1\u20136). Visual style is unchanged."],["<code>subtitle</code>","string","\u2014","Supporting text beneath the heading"],["<code>align</code>","string","'left'","'left' \xB7 'center'"]])}
|
|
12
|
-
`})};var e=document.getElementById("pulse-root");e&&!e.dataset.pulseMounted&&(e.dataset.pulseMounted="1",t(i,e,window.__PULSE_SERVER__||{},{ssr:!0}),a(e,t));var v=i;export{v as default};
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import{a as t,b as m}from"./runtime-ZJ4FXT5O.js";import{Qa as c,nb as e}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as s,h as i,i as n}from"./runtime-L2HNXIHW.js";import{a,b as d}from"./runtime-B73WLANC.js";var{prev:r,next:u}=s("/components/segmented"),l={route:"/components/segmented",meta:{title:"Segmented \u2014 Pulse Docs",description:"iOS-style segmented control component for Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>m({currentHref:"/components/segmented",prev:r,next:u,name:"segmented",description:"iOS-style segmented control built from hidden radio inputs. The selected segment is highlighted via CSS \u2014 no JavaScript required.",content:`
|
|
2
|
-
|
|
3
|
-
<h2 class="doc-h2" id="basic">Basic</h2>
|
|
4
|
-
${t(e({name:"period",value:"week",options:[{value:"day",label:"Day"},{value:"week",label:"Week"},{value:"month",label:"Month"}]}),`segmented({
|
|
5
|
-
name: 'period',
|
|
6
|
-
value: state.period,
|
|
7
|
-
options: [
|
|
8
|
-
{ value: 'day', label: 'Day' },
|
|
9
|
-
{ value: 'week', label: 'Week' },
|
|
10
|
-
{ value: 'month', label: 'Month' },
|
|
11
|
-
],
|
|
12
|
-
})`)}
|
|
13
|
-
|
|
14
|
-
<h2 class="doc-h2" id="sizes">Sizes</h2>
|
|
15
|
-
${t(c({gap:"md",content:e({name:"size-sm",value:"b",size:"sm",options:[{value:"a",label:"Small"},{value:"b",label:"Sizes"},{value:"c",label:"Here"}]})+e({name:"size-md",value:"b",size:"md",options:[{value:"a",label:"Medium"},{value:"b",label:"Default"},{value:"c",label:"Size"}]})+e({name:"size-lg",value:"b",size:"lg",options:[{value:"a",label:"Large"},{value:"b",label:"Size"},{value:"c",label:"Here"}]})}),`segmented({ name: 'view', value: 'b', size: 'sm', options: [...] })
|
|
16
|
-
segmented({ name: 'view', value: 'b', size: 'md', options: [...] })
|
|
17
|
-
segmented({ name: 'view', value: 'b', size: 'lg', options: [...] })`)}
|
|
18
|
-
|
|
19
|
-
<h2 class="doc-h2" id="ui-context">View toggle</h2>
|
|
20
|
-
<p>A common use case \u2014 toggling between Grid and List views.</p>
|
|
21
|
-
${t(e({name:"layout",value:"grid",options:[{value:"grid",label:"Grid"},{value:"list",label:"List"}]}),`segmented({
|
|
22
|
-
name: 'layout',
|
|
23
|
-
value: state.layout,
|
|
24
|
-
options: [
|
|
25
|
-
{ value: 'grid', label: 'Grid' },
|
|
26
|
-
{ value: 'list', label: 'List' },
|
|
27
|
-
],
|
|
28
|
-
})`)}
|
|
29
|
-
|
|
30
|
-
${n("note","The segmented control submits the selected <code>value</code> string under <code>name</code> in FormData. Read it via <code>formData.get('period')</code> in <code>action.onStart</code> or <code>action.run</code>.")}
|
|
31
|
-
|
|
32
|
-
${i(["Prop","Type","Default",""],[["<code>name</code>","string","\u2014","Field name \u2014 submitted in FormData"],["<code>options</code>","array","[]","Array of <code>{ value, label }</code>"],["<code>value</code>","string","\u2014","The currently selected value"],["<code>size</code>","<code>sm | md | lg</code>","<code>md</code>",""],["<code>disabled</code>","boolean","false","Disables all options"],["<code>class</code>","string","\u2014",""]])}
|
|
33
|
-
`})};var o=document.getElementById("pulse-root");o&&!o.dataset.pulseMounted&&(o.dataset.pulseMounted="1",a(l,o,window.__PULSE_SERVER__||{},{ssr:!0}),d(o,a));var w=l;export{w as default};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import{a as n,b as a}from"./runtime-ZJ4FXT5O.js";import{za as o}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as l}from"./runtime-L2HNXIHW.js";import{a as t,b as r}from"./runtime-B73WLANC.js";var{prev:i,next:c}=l("/components/select"),s={route:"/components/select",meta:{title:"Select \u2014 Pulse Docs",description:"Select component for Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>a({currentHref:"/components/select",prev:i,next:c,name:"select",description:"Options can be plain strings or <code>{ value, label }</code> objects. Pass <code>value</code> to mark the current selection.",content:`
|
|
2
|
-
${n(o({name:"role",label:"Role",options:["Admin","Editor","Viewer"],value:"Editor"})+o({name:"status",label:"Status",options:[{value:"active",label:"Active"},{value:"paused",label:"Paused"}],error:"Please select a status"}),`select({ name: 'role', label: 'Role', options: ['Admin', 'Editor', 'Viewer'], value: state.role })
|
|
3
|
-
select({
|
|
4
|
-
name: 'country',
|
|
5
|
-
label: 'Country',
|
|
6
|
-
options: [{ value: 'gb', label: 'United Kingdom' }, { value: 'us', label: 'United States' }],
|
|
7
|
-
value: state.country,
|
|
8
|
-
required: true,
|
|
9
|
-
})`,{col:!0})}
|
|
10
|
-
`})};var e=document.getElementById("pulse-root");e&&!e.dataset.pulseMounted&&(e.dataset.pulseMounted="1",t(s,e,window.__PULSE_SERVER__||{},{ssr:!0}),r(e,t));var E=s;export{E as default};
|