@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.
Files changed (124) hide show
  1. package/.github/workflows/publish.yml +11 -20
  2. package/README.md +1 -1
  3. package/docs/public/.pulse-ui-version +1 -1
  4. package/docs/public/docs.css +19 -1
  5. package/docs/public/pulse-ui.css +1 -0
  6. package/docs/server.js +5 -2
  7. package/docs/src/lib/highlight.js +57 -13
  8. package/docs/src/lib/layout.js +5 -2
  9. package/docs/src/pages/faq.js +5 -2
  10. package/docs/src/pages/home.js +9 -5
  11. package/docs/src/pages/meta.js +21 -0
  12. package/docs/src/pages/routing.js +12 -1
  13. package/package.json +1 -1
  14. package/public/pulse-ui.css +2 -2
  15. package/src/agent/guide-components.md +1 -1
  16. package/src/agent/guide-routing.md +20 -0
  17. package/src/agent/guide-spec.md +10 -1
  18. package/src/agent/guide-styles.md +16 -1
  19. package/src/agent/workflow.md +1 -1
  20. package/src/cli/scaffold.js +63 -2
  21. package/src/mcp/server.js +34 -18
  22. package/src/server/index.js +26 -7
  23. package/src/server/server.test.js +47 -0
  24. package/src/ui/stat.js +1 -1
  25. package/src/ui/ui.test.js +6 -0
  26. package/docs/public/dist/accessibility.boot-5DVTARJU.js +0 -115
  27. package/docs/public/dist/actions.boot-P66HKQEM.js +0 -164
  28. package/docs/public/dist/auth.boot-IMAJAUPH.js +0 -140
  29. package/docs/public/dist/caching.boot-DVR6KDE7.js +0 -53
  30. package/docs/public/dist/components--accordion.boot-3HVKMNWC.js +0 -11
  31. package/docs/public/dist/components--alert.boot-GCEXOZAC.js +0 -6
  32. package/docs/public/dist/components--app-badge.boot-DVT3GCHJ.js +0 -6
  33. package/docs/public/dist/components--avatar.boot-PSW24EVA.js +0 -5
  34. package/docs/public/dist/components--badge.boot-TYDY2RMK.js +0 -7
  35. package/docs/public/dist/components--banner.boot-EI5PZSZK.js +0 -7
  36. package/docs/public/dist/components--breadcrumbs.boot-SMA2E2GO.js +0 -34
  37. package/docs/public/dist/components--button.boot-J54BQM2E.js +0 -23
  38. package/docs/public/dist/components--card.boot-PZGNDIB6.js +0 -138
  39. package/docs/public/dist/components--carousel.boot-TP6LPFZZ.js +0 -12
  40. package/docs/public/dist/components--charts.boot-2EOYQWKL.js +0 -108
  41. package/docs/public/dist/components--checkbox.boot-DS5BSL6T.js +0 -54
  42. package/docs/public/dist/components--cluster.boot-HHVIBBJG.js +0 -9
  43. package/docs/public/dist/components--code-window.boot-2GR2DV33.js +0 -20
  44. package/docs/public/dist/components--container.boot-7LOOGK2K.js +0 -5
  45. package/docs/public/dist/components--cta.boot-FSNZ5YRT.js +0 -11
  46. package/docs/public/dist/components--divider.boot-3NI2C3QG.js +0 -6
  47. package/docs/public/dist/components--empty.boot-YX2UR3PV.js +0 -7
  48. package/docs/public/dist/components--feature.boot-MUD7NSUO.js +0 -13
  49. package/docs/public/dist/components--fieldset.boot-J7BYHMKF.js +0 -19
  50. package/docs/public/dist/components--fileupload.boot-NIKVTTPD.js +0 -52
  51. package/docs/public/dist/components--footer.boot-EYUK5FRG.js +0 -14
  52. package/docs/public/dist/components--grid.boot-URDQVDDR.js +0 -59
  53. package/docs/public/dist/components--heading.boot-BPQKU43E.js +0 -44
  54. package/docs/public/dist/components--hero.boot-4RAPRGAB.js +0 -17
  55. package/docs/public/dist/components--icons.boot-ZITNU5JP.js +0 -68
  56. package/docs/public/dist/components--image.boot-XEEGHQZF.js +0 -19
  57. package/docs/public/dist/components--input.boot-SGASZG5K.js +0 -7
  58. package/docs/public/dist/components--list.boot-W3XC5MHD.js +0 -55
  59. package/docs/public/dist/components--media.boot-5VFIETZO.js +0 -13
  60. package/docs/public/dist/components--modal.boot-RZUYXBN2.js +0 -47
  61. package/docs/public/dist/components--nav.boot-ODBOHU7O.js +0 -33
  62. package/docs/public/dist/components--pricing.boot-4AQ4ZVBY.js +0 -21
  63. package/docs/public/dist/components--progress.boot-GHAGYZOK.js +0 -30
  64. package/docs/public/dist/components--prose.boot-QANJL6JI.js +0 -67
  65. package/docs/public/dist/components--pullquote.boot-Q2WMNAZU.js +0 -22
  66. package/docs/public/dist/components--radio.boot-TJRDQ2OL.js +0 -75
  67. package/docs/public/dist/components--rating.boot-QBAN6DEL.js +0 -38
  68. package/docs/public/dist/components--search.boot-PXH5O5AG.js +0 -17
  69. package/docs/public/dist/components--section.boot-AQGIYHWW.js +0 -12
  70. package/docs/public/dist/components--segmented.boot-BEVTKEJO.js +0 -33
  71. package/docs/public/dist/components--select.boot-47X5RHOC.js +0 -10
  72. package/docs/public/dist/components--slider.boot-PSRRX7XL.js +0 -47
  73. package/docs/public/dist/components--spinner.boot-MZ5MO2OH.js +0 -22
  74. package/docs/public/dist/components--stack.boot-DI4NJXBF.js +0 -9
  75. package/docs/public/dist/components--stat.boot-QMFUWBQT.js +0 -9
  76. package/docs/public/dist/components--stepper.boot-34PP2NEV.js +0 -22
  77. package/docs/public/dist/components--table.boot-FCQGSFIQ.js +0 -11
  78. package/docs/public/dist/components--testimonial.boot-DWQPDKYG.js +0 -11
  79. package/docs/public/dist/components--textarea.boot-QVXLBOJ5.js +0 -4
  80. package/docs/public/dist/components--timeline.boot-26LN52P2.js +0 -95
  81. package/docs/public/dist/components--toggle.boot-IQQEI76S.js +0 -29
  82. package/docs/public/dist/components--tooltip.boot-LGHCO6NN.js +0 -9
  83. package/docs/public/dist/components.boot-SE6PQ4P7.js +0 -103
  84. package/docs/public/dist/config.boot-DTRRWUE6.js +0 -126
  85. package/docs/public/dist/constraints.boot-DUHDZBMC.js +0 -71
  86. package/docs/public/dist/deploy.boot-SLAD3NI2.js +0 -163
  87. package/docs/public/dist/docs-8e3d4b5c.css +0 -1
  88. package/docs/public/dist/extending.boot-UA3CN243.js +0 -159
  89. package/docs/public/dist/faq.boot-6EQAWLQR.js +0 -43
  90. package/docs/public/dist/getting-started.boot-TDKIFL5U.js +0 -86
  91. package/docs/public/dist/guard.boot-AUHAWTG4.js +0 -80
  92. package/docs/public/dist/home.boot-BVQXRH32.js +0 -383
  93. package/docs/public/dist/how-it-works.boot-LTWAKWKW.js +0 -104
  94. package/docs/public/dist/hydration.boot-JRM6IPJL.js +0 -78
  95. package/docs/public/dist/images.boot-M6ZVKTZS.js +0 -80
  96. package/docs/public/dist/manifest.json +0 -94
  97. package/docs/public/dist/meta.boot-7NXGPHR4.js +0 -79
  98. package/docs/public/dist/mutations.boot-F6F43UDX.js +0 -79
  99. package/docs/public/dist/navigation.boot-AOXWS3ZF.js +0 -57
  100. package/docs/public/dist/performance.boot-C3UPCOBK.js +0 -98
  101. package/docs/public/dist/persist.boot-WT32PQOQ.js +0 -61
  102. package/docs/public/dist/project-structure.boot-FB3LRVJ4.js +0 -63
  103. package/docs/public/dist/prompt-examples.boot-YKR4VDK4.js +0 -31
  104. package/docs/public/dist/pulse-ui-81a85c03.css +0 -1
  105. package/docs/public/dist/raw-responses.boot-M4KA5YXL.js +0 -104
  106. package/docs/public/dist/routing.boot-FNX5FDGH.js +0 -70
  107. package/docs/public/dist/runtime-B73WLANC.js +0 -1
  108. package/docs/public/dist/runtime-KO4BHUQ3.js +0 -49
  109. package/docs/public/dist/runtime-L2HNXIHW.js +0 -59
  110. package/docs/public/dist/runtime-QFURDKA2.js +0 -5
  111. package/docs/public/dist/runtime-UVPXO4IR.js +0 -375
  112. package/docs/public/dist/runtime-VMJA3Z4N.js +0 -10
  113. package/docs/public/dist/runtime-ZJ4FXT5O.js +0 -11
  114. package/docs/public/dist/server-api.boot-K7X3LCFB.js +0 -219
  115. package/docs/public/dist/server-data.boot-Y7HQYC4R.js +0 -157
  116. package/docs/public/dist/slash-commands.boot-V2UV7OW2.js +0 -26
  117. package/docs/public/dist/spec.boot-2WU7ZHCV.js +0 -159
  118. package/docs/public/dist/state.boot-B24GUE3R.js +0 -73
  119. package/docs/public/dist/store.boot-TLIB4XHH.js +0 -150
  120. package/docs/public/dist/streaming.boot-W2DZSMW4.js +0 -80
  121. package/docs/public/dist/stripe.boot-QN3C2GEL.js +0 -164
  122. package/docs/public/dist/supabase.boot-BG4XXLZE.js +0 -303
  123. package/docs/public/dist/testing.boot-6U4WKMTE.js +0 -130
  124. package/docs/public/dist/validation.boot-PQHYGW5B.js +0 -100
@@ -1,54 +0,0 @@
1
- import{a as o,b as r}from"./runtime-ZJ4FXT5O.js";import{cb as e,ya as i}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as s,h as d,i as l}from"./runtime-L2HNXIHW.js";import{a,b as n}from"./runtime-B73WLANC.js";var{prev:m,next:h}=s("/components/checkbox"),c={route:"/components/checkbox",meta:{title:"Checkbox \u2014 Pulse Docs",description:"Custom-styled checkbox component for Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>r({currentHref:"/components/checkbox",prev:m,next:h,name:"checkbox",description:'Custom-styled checkbox with animated check mark, full keyboard and screen-reader support. Pairs with <a href="/components/fieldset">fieldset</a> for labelled groups.',content:`
2
-
3
- <h2 class="doc-h2" id="basic">Basic</h2>
4
- <p>Pass <code>label</code> for the visible text. The <code>id</code> is auto-generated from <code>name</code> and <code>value</code>.</p>
5
- ${o(e({name:"agree",label:"I agree to the terms"}),"checkbox({ name: 'agree', label: 'I agree to the terms' })",{col:!0})}
6
-
7
- <h2 class="doc-h2" id="checked">Checked</h2>
8
- ${o(e({name:"newsletter",label:"Send me updates",checked:!0}),"checkbox({ name: 'newsletter', label: 'Send me updates', checked: state.newsletter })",{col:!0})}
9
-
10
- <h2 class="doc-h2" id="hint">Hint</h2>
11
- <p>A <code>hint</code> string renders below the label as supporting copy.</p>
12
- ${o(e({name:"marketing",label:"Marketing emails",hint:"Product news and tips. Unsubscribe any time.",checked:!0}),`checkbox({
13
- name: 'marketing',
14
- label: 'Marketing emails',
15
- hint: 'Product news and tips. Unsubscribe any time.',
16
- checked: state.marketing,
17
- })`,{col:!0})}
18
-
19
- <h2 class="doc-h2" id="error">Error state</h2>
20
- <p>Pass <code>error</code> to show a validation message. The error is announced via <code>role="alert"</code>.</p>
21
- ${o(e({name:"terms",label:"I accept the terms and conditions",error:"You must accept the terms to continue."}),`checkbox({
22
- name: 'terms',
23
- label: 'I accept the terms and conditions',
24
- error: server.errors.terms,
25
- })`,{col:!0})}
26
-
27
- <h2 class="doc-h2" id="disabled">Disabled</h2>
28
- ${o(e({name:"feature",label:"Enable beta features",disabled:!0})+" "+e({name:"feature2",label:"Beta feature (on)",disabled:!0,checked:!0}),"checkbox({ name: 'feature', label: 'Enable beta features', disabled: true })",{col:!0})}
29
-
30
- <h2 class="doc-h2" id="group">Group in a fieldset</h2>
31
- <p>Compose multiple checkboxes inside a <a href="/components/fieldset">fieldset</a> for a semantic group.</p>
32
- ${o(i({legend:"Notifications",content:e({name:"notif",value:"email",label:"Email",checked:!0})+e({name:"notif",value:"sms",label:"SMS"})+e({name:"notif",value:"browser",label:"Browser push",checked:!0})+e({name:"notif",value:"weekly",label:"Weekly digest",disabled:!0})}),`fieldset({
33
- legend: 'Notifications',
34
- content:
35
- checkbox({ name: 'notif', value: 'email', label: 'Email', checked: true }) +
36
- checkbox({ name: 'notif', value: 'sms', label: 'SMS' }) +
37
- checkbox({ name: 'notif', value: 'browser', label: 'Browser push', checked: true }) +
38
- checkbox({ name: 'notif', value: 'weekly', label: 'Weekly digest', disabled: true }),
39
- })`,{col:!0})}
40
-
41
- <h2 class="doc-h2" id="in-forms">In forms</h2>
42
- ${l("note",`Checkboxes submit their <code>value</code> string (defaulting to <code>"on"</code>) under <code>name</code> in FormData only when checked. Unchecked checkboxes are absent from FormData. Read them in <code>action.onStart</code> via <code>formData.get('agree')</code> \u2014 a <code>null</code> result means unchecked.`)}
43
-
44
- <h2 class="doc-h2" id="labelhtml">Custom label HTML</h2>
45
- <p>When the label needs inline styling \u2014 for example a strikethrough on a completed todo \u2014 use <code>labelHtml</code> instead of <code>label</code>. The value is inserted as raw HTML so you are responsible for escaping any user content.</p>
46
- ${o(e({name:"task",labelHtml:'<span style="text-decoration:line-through;opacity:.5">Buy milk</span>',checked:!0}),`checkbox({
47
- name: 'task',
48
- checked: todo.done,
49
- labelHtml: \`<span class="\${todo.done ? 'u-text-muted' : ''}">\${esc(todo.text)}</span>\`,
50
- })`,{col:!0})}
51
-
52
- <h2 class="doc-h2" id="props">Props</h2>
53
- ${d(["Prop","Type","Default",""],[["<code>name</code>","string","\u2014","Field name"],["<code>value</code>","string","\u2014",'Submitted value when checked (defaults to browser default <code>"on"</code>)'],["<code>label</code>","string","\u2014","Visible label text \u2014 escaped"],["<code>labelHtml</code>","string","\u2014","Raw HTML label slot \u2014 not escaped, use for styled spans"],["<code>checked</code>","boolean","false",""],["<code>disabled</code>","boolean","false",""],["<code>id</code>","string","\u2014","Override the auto-generated <code>id</code>"],["<code>event</code>","string","\u2014",'<code>data-event</code> binding, e.g. <code>"change:toggle"</code>'],["<code>hint</code>","string","\u2014","Helper text below the label"],["<code>error</code>","string","\u2014",'Validation error \u2014 announced via <code>role="alert"</code>'],["<code>class</code>","string","\u2014",""]])}
54
- `})};var t=document.getElementById("pulse-root");t&&!t.dataset.pulseMounted&&(t.dataset.pulseMounted="1",a(c,t,window.__PULSE_SERVER__||{},{ssr:!0}),n(t,a));var w=c;export{w as default};
@@ -1,9 +0,0 @@
1
- import{a as c,b as l}from"./runtime-ZJ4FXT5O.js";import{Ra as i,b as e}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as s,h as n}from"./runtime-L2HNXIHW.js";import{a as o,b as a}from"./runtime-B73WLANC.js";var{prev:p,next:d}=s("/components/cluster"),r={route:"/components/cluster",meta:{title:"Cluster \u2014 Pulse Docs",description:"Cluster component for Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>l({currentHref:"/components/cluster",prev:p,next:d,name:"cluster",description:"Flex row with wrapping. Groups inline elements horizontally \u2014 action buttons, badges, app store badges, stat rows.",content:`
2
- ${c(i({gap:"sm",content:e({label:"Performance"})+e({label:"Accessibility"})+e({label:"Zero JS",variant:"success"})+e({label:"SSR",variant:"info"})}),`cluster({ gap: 'sm', justify: 'center', content:
3
- badge({ label: 'Performance' }) +
4
- badge({ label: 'Zero JS', variant: 'success' }) +
5
- appBadge({ store: 'apple', href: url })
6
- })`)}
7
-
8
- ${n(["Prop","Type","Default",""],[["<code>content</code>","string (HTML)","\u2014","Raw HTML slot"],["<code>gap</code>","string","'md'","'xs' \xB7 'sm' \xB7 'md' \xB7 'lg'"],["<code>justify</code>","string","'start'","'start' \xB7 'center' \xB7 'end' \xB7 'between'"],["<code>align</code>","string","'center'","'start' \xB7 'center' \xB7 'end'"],["<code>wrap</code>","boolean","true","Set false to prevent wrapping"]])}
9
- `})};var t=document.getElementById("pulse-root");t&&!t.dataset.pulseMounted&&(t.dataset.pulseMounted="1",o(r,t,window.__PULSE_SERVER__||{},{ssr:!0}),a(t,o));var P=r;export{P as default};
@@ -1,20 +0,0 @@
1
- import{a as r,b as c}from"./runtime-ZJ4FXT5O.js";import"./runtime-UVPXO4IR.js";import{b as i}from"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as n,h as a}from"./runtime-L2HNXIHW.js";import{a as t,b as s}from"./runtime-B73WLANC.js";var{prev:l,next:p}=n("/components/code-window"),o={route:"/components/code-window",meta:{title:"Code Window \u2014 Pulse Docs",description:"macOS-style window chrome around a code block. Accepts pre-highlighted HTML as the content slot.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>c({currentHref:"/components/code-window",prev:l,next:p,name:"codeWindow",description:"macOS-style window chrome around a code block. Accepts pre-highlighted HTML as the content slot \u2014 the component handles all the chrome, layout, scrolling, and monospace typography.",content:`
2
- ${r(i({filename:"home.js",lang:"JavaScript",content:`<span style="color:var(--ui-accent)">export default</span> {
3
- <span style="color:var(--ui-text)">state</span>: { count: <span style="color:var(--ui-green)">0</span> },
4
-
5
- <span style="color:var(--ui-text)">view</span>: (state) =&gt; \`
6
- &lt;h1&gt;\${state.count}&lt;/h1&gt;
7
- &lt;button data-event=<span style="color:var(--ui-yellow)">"inc"</span>&gt;+&lt;/button&gt;
8
- \`,
9
-
10
- <span style="color:var(--ui-text)">mutations</span>: {
11
- inc: (state) =&gt; ({ count: state.count + <span style="color:var(--ui-green)">1</span> }),
12
- },
13
- }`}),`codeWindow({
14
- filename: 'home.js',
15
- lang: 'JavaScript',
16
- content: highlightedHtml, // pre-rendered HTML with syntax token spans
17
- })`)}
18
-
19
- ${a(["Prop","Type","Default",""],[["<code>content</code>","string (HTML)","\u2014","Raw HTML slot \u2014 pre-highlighted code HTML or plain text"],["<code>filename</code>","string","\u2014","Filename shown in the chrome bar (e.g. 'home.js')"],["<code>lang</code>","string","\u2014","Language label shown on the right of the chrome (e.g. 'JavaScript')"]])}
20
- `})};var e=document.getElementById("pulse-root");e&&!e.dataset.pulseMounted&&(e.dataset.pulseMounted="1",t(o,e,window.__PULSE_SERVER__||{},{ssr:!0}),s(e,t));var v=o;export{v as default};
@@ -1,5 +0,0 @@
1
- import{a as i,b as a}from"./runtime-ZJ4FXT5O.js";import{Na as p}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 s}from"./runtime-B73WLANC.js";var{prev:c,next:d}=r("/components/container"),o={route:"/components/container",meta:{title:"Container \u2014 Pulse Docs",description:"Container component for Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>a({currentHref:"/components/container",prev:c,next:d,name:"container",description:"Max-width wrapper with horizontal padding. The four size presets cover the most common layout widths.",content:`
2
- ${i(p({content:'<p style="background:var(--surface-2);border:1px dashed var(--border);padding:1rem;border-radius:6px;text-align:center;color:var(--muted)">Content constrained to 768px</p>',size:"md"}),"container({ size: 'md', content: `\n ${hero({ title: 'Hello' })}\n ${grid({ cols: 3, content: features })}\n` })")}
3
-
4
- ${n(["Prop","Type","Default",""],[["<code>content</code>","string (HTML)","\u2014","Raw HTML slot"],["<code>size</code>","string","'lg'","'sm' (640px) \xB7 'md' (768px) \xB7 'lg' (1100px) \xB7 'xl' (1280px)"]])}
5
- `})};var e=document.getElementById("pulse-root");e&&!e.dataset.pulseMounted&&(e.dataset.pulseMounted="1",t(o,e,window.__PULSE_SERVER__||{},{ssr:!0}),s(e,t));var w=o;export{w as default};
@@ -1,11 +0,0 @@
1
- import{a as s,b as l}from"./runtime-ZJ4FXT5O.js";import{Za as c,a as o}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a,h as n}from"./runtime-L2HNXIHW.js";import{a as e,b as r}from"./runtime-B73WLANC.js";var{prev:d,next:p}=a("/components/cta"),i={route:"/components/cta",meta:{title:"CTA \u2014 Pulse Docs",description:"Call-to-action block with eyebrow, heading, body text, and an actions slot.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>l({currentHref:"/components/cta",prev:d,next:p,name:"cta",description:"Call-to-action block with eyebrow, heading, body text, and an actions slot. Sits inside <code>section()</code> + <code>container()</code> \u2014 adds no padding of its own.",content:`
2
- ${s(c({eyebrow:"Get started today",title:"Ready to build?",subtitle:"One spec file per page. SSR always on. Lighthouse 100 out of the box.",actions:o({label:"Start building \u2192",href:"#",variant:"primary",size:"lg"})+o({label:"View on GitHub",href:"#",variant:"ghost",size:"lg"})}),`cta({
3
- eyebrow: 'Get started today',
4
- title: 'Ready to build?',
5
- subtitle: 'One spec file per page. SSR always on. Lighthouse 100 out of the box.',
6
- actions: button({ label: 'Start building \u2192', href: '/docs', variant: 'primary', size: 'lg' }) +
7
- button({ label: 'View on GitHub', href: 'https://github.com/...', variant: 'ghost', size: 'lg' }),
8
- })`)}
9
-
10
- ${n(["Prop","Type","Default",""],[["<code>eyebrow</code>","string","\u2014","Small label above the heading"],["<code>title</code>","string","\u2014","Main heading"],["<code>level</code>","number","2","Heading tag for the title (1\u20136). Visual style is unchanged."],["<code>subtitle</code>","string","\u2014","Supporting paragraph"],["<code>actions</code>","string (HTML)","\u2014","Raw HTML slot \u2014 typically button() calls"],["<code>align</code>","string","'center'","'center' \xB7 'left'"]])}
11
- `})};var t=document.getElementById("pulse-root");t&&!t.dataset.pulseMounted&&(t.dataset.pulseMounted="1",e(i,t,window.__PULSE_SERVER__||{},{ssr:!0}),r(t,e));var S=i;export{S as default};
@@ -1,6 +0,0 @@
1
- import{a as s,b as l}from"./runtime-ZJ4FXT5O.js";import{Qa as p,Sa as o}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as i,h as n}from"./runtime-L2HNXIHW.js";import{a as t,b as d}from"./runtime-B73WLANC.js";var{prev:a,next:c}=i("/components/divider"),r={route:"/components/divider",meta:{title:"Divider \u2014 Pulse Docs",description:"Divider component for Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>l({currentHref:"/components/divider",prev:a,next:c,name:"divider",description:'Horizontal rule for visual separation. With a <code>label</code>, the line splits either side of the text \u2014 the classic "or" pattern between login options.',content:`
2
- ${s(p({gap:"lg",content:o()+o({label:"or continue with"})}),`divider()
3
- divider({ label: 'or continue with' })`)}
4
-
5
- ${n(["Prop","Type","Default",""],[["<code>label</code>","string","\u2014",'Optional centred text \u2014 renders as <code>&lt;div&gt;</code> with role="separator" when provided, <code>&lt;hr&gt;</code> otherwise']])}
6
- `})};var e=document.getElementById("pulse-root");e&&!e.dataset.pulseMounted&&(e.dataset.pulseMounted="1",t(r,e,window.__PULSE_SERVER__||{},{ssr:!0}),d(e,t));var x=r;export{x as default};
@@ -1,7 +0,0 @@
1
- import{a as s,b as i}from"./runtime-ZJ4FXT5O.js";import{Ea as a}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as r}from"./runtime-L2HNXIHW.js";import{a as e,b as n}from"./runtime-B73WLANC.js";var{prev:p,next:l}=r("/components/empty"),o={route:"/components/empty",meta:{title:"Empty \u2014 Pulse Docs",description:"Empty state component for Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>i({currentHref:"/components/empty",prev:p,next:l,name:"empty",description:"Empty state placeholder. Shows a centred title, optional description, and an optional call-to-action when there is nothing to display.",content:`
2
- ${s(a({title:"No results found",description:"Try adjusting your search or clearing the filters.",action:{label:"Clear filters",href:"#",variant:"secondary"}}),`empty({
3
- title: 'No results found',
4
- description: 'Try adjusting your search or clearing the filters.',
5
- action: { label: 'Clear filters', href: '/products', variant: 'secondary' },
6
- })`)}
7
- `})};var t=document.getElementById("pulse-root");t&&!t.dataset.pulseMounted&&(t.dataset.pulseMounted="1",e(o,t,window.__PULSE_SERVER__||{},{ssr:!0}),n(t,e));var g=o;export{g as default};
@@ -1,13 +0,0 @@
1
- import{a as o,b as p}from"./runtime-ZJ4FXT5O.js";import{Ia as e,K as n,ga as r,qa as s}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a,h as l}from"./runtime-L2HNXIHW.js";import{a as i,b as d}from"./runtime-B73WLANC.js";var{prev:u,next:f}=a("/components/feature"),c={route:"/components/feature",meta:{title:"Feature \u2014 Pulse Docs",description:"Feature component for Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>p({currentHref:"/components/feature",prev:u,next:f,name:"feature",description:'Icon + title + description block. Compose three or four in a CSS grid for the standard "why us" section.',content:`
2
- ${o('<div style="display:grid;grid-template-columns:repeat(3,1fr);gap:2rem">'+e({icon:s({size:20}),title:"Instant load",description:"Streaming SSR ships HTML before data resolves. Fast by default."})+e({icon:n({size:20}),title:"Private by default",description:"No trackers. No third-party scripts. Ever."})+e({icon:r({size:20}),title:"Works offline",description:"Full functionality without a connection."})+"</div>",`import { iconZap, iconLock, iconPhone } from '@invisibleloop/pulse/ui'
3
-
4
- feature({ icon: iconZap({ size: 20 }), title: 'Instant load', description: 'Streaming SSR ships HTML before data resolves.' })
5
- feature({ icon: iconLock({ size: 20 }), title: 'Private by default', description: 'No trackers, ever.' })
6
- feature({ icon: iconPhone({ size: 20 }), title: 'Works offline', description: 'Full functionality without a connection.' })`)}
7
-
8
- ${o('<div style="display:grid;grid-template-columns:repeat(3,1fr);gap:2rem">'+e({icon:s({size:20}),title:"Instant load",description:"Streaming SSR ships HTML before data resolves. Fast by default.",center:!0})+e({icon:n({size:20}),title:"Private by default",description:"No trackers. No third-party scripts. Ever.",center:!0})+e({icon:r({size:20}),title:"Works offline",description:"Full functionality without a connection.",center:!0})+"</div>",`feature({ icon: iconZap({ size: 20 }), title: 'Instant load', description: '...', center: true })
9
- feature({ icon: iconLock({ size: 20 }), title: 'Private by default', description: '...', center: true })
10
- feature({ icon: iconPhone({ size: 20 }), title: 'Works offline', description: '...', center: true })`)}
11
-
12
- ${l(["Prop","Type","Default",""],[["<code>icon</code>","string (HTML)","\u2014","Raw HTML slot \u2014 SVG or emoji; displayed in an accent-tinted box"],["<code>title</code>","string","\u2014",""],["<code>level</code>","number","3","Heading tag for the title (1\u20136). Visual style is unchanged."],["<code>description</code>","string","\u2014",""],["<code>center</code>","boolean","false","Centre-align the icon, title, and description"]])}
13
- `})};var t=document.getElementById("pulse-root");t&&!t.dataset.pulseMounted&&(t.dataset.pulseMounted="1",i(c,t,window.__PULSE_SERVER__||{},{ssr:!0}),d(t,i));var z=c;export{z as default};
@@ -1,19 +0,0 @@
1
- import{a as i,b as d}from"./runtime-ZJ4FXT5O.js";import{Aa as c,Pa as m,a as u,d as t,ya as o}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as s,h as l}from"./runtime-L2HNXIHW.js";import{a as r,b as n}from"./runtime-B73WLANC.js";var{prev:p,next:f}=s("/components/fieldset"),a={route:"/components/fieldset",meta:{title:"Fieldset \u2014 Pulse Docs",description:"Semantic grouping of related form fields with an accessible legend.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>d({currentHref:"/components/fieldset",prev:p,next:f,name:"fieldset",description:'Wraps related fields in a semantic <code>&lt;fieldset&gt;</code> with a styled <code>&lt;legend&gt;</code>. Screen readers announce the legend when focus enters the group \u2014 use it whenever fields belong together (address, card details, contact info). Works naturally inside a <code>&lt;form data-action="..."&gt;</code>.',content:`
2
- ${i('<form class="u-flex u-flex-col u-gap-4">'+o({legend:"Your details",content:m({cols:2,gap:"md",content:t({name:"first",label:"First name",required:!0})+t({name:"last",label:"Last name",required:!0})})+t({name:"email",label:"Email address",type:"email",required:!0})})+o({legend:"Message",content:c({name:"message",label:"Tell us about your project",rows:4,required:!0})})+u({label:"Send message",type:"submit",variant:"primary",fullWidth:!0})+"</form>",`import { fieldset, grid, input, textarea, button } from '@invisibleloop/pulse/ui'
3
-
4
- \`<form data-action="submit" class="u-flex u-flex-col u-gap-4">
5
- \${fieldset({ legend: 'Your details', content: \`
6
- \${grid({ cols: 2, gap: 'md', content: \`
7
- \${input({ name: 'first', label: 'First name', required: true })}
8
- \${input({ name: 'last', label: 'Last name', required: true })}
9
- \` })}
10
- \${input({ name: 'email', label: 'Email address', type: 'email', required: true })}
11
- \` })}
12
- \${fieldset({ legend: 'Message', content: \`
13
- \${textarea({ name: 'message', label: 'Tell us about your project', rows: 4, required: true })}
14
- \` })}
15
- \${button({ label: 'Send message', type: 'submit', variant: 'primary', fullWidth: true })}
16
- </form>\``)}
17
-
18
- ${l(["Prop","Type","Default",""],[["<code>legend</code>","string","\u2014","Group label \u2014 rendered as <code>&lt;legend&gt;</code>, announced by screen readers on focus"],["<code>content</code>","string","\u2014","Raw HTML slot \u2014 input(), select(), textarea(), grid(), etc."],["<code>gap</code>","string","md","Vertical gap between fields: xs / sm / md / lg"],["<code>class</code>","string","\u2014","Extra classes on the <code>&lt;fieldset&gt;</code> element"]])}
19
- `})};var e=document.getElementById("pulse-root");e&&!e.dataset.pulseMounted&&(e.dataset.pulseMounted="1",r(a,e,window.__PULSE_SERVER__||{},{ssr:!0}),n(e,r));var v=a;export{v as default};
@@ -1,52 +0,0 @@
1
- import{a as e,b as m}from"./runtime-ZJ4FXT5O.js";import{ob as t}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as s,h as n,i as r}from"./runtime-L2HNXIHW.js";import{a as i,b as d}from"./runtime-B73WLANC.js";var{prev:u,next:f}=s("/components/file-upload"),c={route:"/components/file-upload",meta:{title:"File Upload \u2014 Pulse Docs",description:"Drag-and-drop file upload zone component for Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{fileName:"",fileSize:""},mutations:{setFile:(o,p)=>{let l=p.target.files[0];return l?{fileName:l.name,fileSize:(l.size/1024).toFixed(1)+" KB"}:{fileName:"",fileSize:""}}},view:o=>m({currentHref:"/components/file-upload",prev:u,next:f,name:"fileUpload",description:'Drag-and-drop upload zone with a hidden <code>&lt;input type="file"&gt;</code>. Clicking or dropping files opens the picker. Requires <code>pulse-ui.js</code> for drag highlighting and click-to-open behaviour.',content:`
2
-
3
- <h2 class="doc-h2" id="basic">Basic</h2>
4
- ${e(t({name:"file",label:"Upload file",hint:"PNG, JPG, PDF up to 10 MB",event:"change:setFile"})+(o.fileName?`<p class="u-mt-3 u-text-sm">Selected: <strong>${o.fileName}</strong> (${o.fileSize})</p>`:""),"fileUpload({ name: 'file', label: 'Upload file', hint: 'PNG, JPG, PDF up to 10 MB', event: 'change:setFile' })",{col:!0})}
5
-
6
- <h2 class="doc-h2" id="accept">Accepted file types</h2>
7
- ${e(t({name:"avatar",label:"Profile photo",accept:"image/*",hint:"PNG or JPG"}),"fileUpload({ name: 'avatar', label: 'Profile photo', accept: 'image/*', hint: 'PNG or JPG' })",{col:!0})}
8
-
9
- <h2 class="doc-h2" id="multiple">Multiple files</h2>
10
- ${e(t({name:"docs",label:"Attachments",multiple:!0,hint:"Select one or more files"}),"fileUpload({ name: 'docs', label: 'Attachments', multiple: true, hint: 'Select one or more files' })",{col:!0})}
11
-
12
- <h2 class="doc-h2" id="error">Error state</h2>
13
- ${e(t({name:"file",label:"Upload file",error:"File must be under 10 MB"}),"fileUpload({ name: 'file', label: 'Upload file', error: 'File must be under 10 MB' })",{col:!0})}
14
-
15
- <h2 class="doc-h2" id="disabled">Disabled</h2>
16
- ${e(t({name:"file",label:"Upload file",disabled:!0,hint:"Uploads are currently unavailable"}),"fileUpload({ name: 'file', label: 'Upload file', disabled: true, hint: 'Uploads are currently unavailable' })",{col:!0})}
17
-
18
- <h2 class="doc-h2" id="with-action">Reading the file in an action</h2>
19
- <p class="u-mb-4 u-text-sm u-color-muted">Use the component inside a <code>&lt;form data-action="..."&gt;</code>. The file is available in FormData under <code>name</code>.</p>
20
- ${e(t({name:"attachment",label:"Attachment",accept:".pdf,.doc,.docx",required:!0}),`// view
21
- \`<form data-action="upload" class="u-flex u-flex-col u-gap-4">
22
- \${fileUpload({ name: 'attachment', label: 'Attachment', accept: '.pdf,.doc,.docx', required: true })}
23
- \${button({ label: 'Upload', type: 'submit', variant: 'primary' })}
24
- </form>\`
25
-
26
- // action
27
- upload: {
28
- onStart: (state) => ({ status: 'loading' }),
29
- run: async (state, serverState, formData) => {
30
- const file = formData.get('attachment') // File object
31
- // process file...
32
- },
33
- onSuccess: (state) => ({ status: 'success' }),
34
- onError: (state, err) => ({ status: 'error', message: err.message }),
35
- }`,{col:!0})}
36
-
37
- <h2 class="doc-h2" id="with-mutation">Live file name via mutation</h2>
38
- <p class="u-mb-4 u-text-sm u-color-muted">Use <code>event: 'change:mutationName'</code> to capture the selected filename in state immediately \u2014 without a form submission.</p>
39
- ${e(t({name:"photo",label:"Photo",event:"change:setFile",accept:"image/*"}),`// state
40
- { fileName: '' }
41
-
42
- // mutation \u2014 e.target.files[0] gives the File object
43
- setFile: (state, e) => ({ fileName: e.target.files[0]?.name ?? '' })
44
-
45
- // view
46
- fileUpload({ name: 'photo', label: 'Photo', accept: 'image/*', event: 'change:setFile' })
47
- \${state.fileName ? \`<p class="u-mt-2 u-text-sm">\${state.fileName}</p>\` : ''}`,{col:!0})}
48
-
49
- ${r("note","The file object itself cannot be stored in Pulse state \u2014 state must be serialisable. Store the filename or a preview URL (via <code>URL.createObjectURL</code>) instead, and upload the file in an action via FormData.")}
50
-
51
- ${n(["Prop","Type","Default",""],[["<code>name</code>","string","\u2014","Field name \u2014 file available in FormData under this key"],["<code>label</code>","string","\u2014","Visible label text"],["<code>hint</code>","string","\u2014","Helper text, e.g. accepted types and max size"],["<code>error</code>","string","\u2014","Validation error message"],["<code>accept</code>","string","\u2014","Accepted MIME types or extensions, e.g. <code>image/*</code> or <code>.pdf,.docx</code>"],["<code>multiple</code>","boolean","false","Allow selecting multiple files"],["<code>required</code>","boolean","false",""],["<code>disabled</code>","boolean","false",""],["<code>event</code>","string","\u2014","data-event on the input \u2014 use <code>change:mutationName</code> to capture file selection in state"],["<code>id</code>","string","\u2014","Override the generated <code>id</code>"],["<code>class</code>","string","\u2014",""]])}
52
- `})};var a=document.getElementById("pulse-root");a&&!a.dataset.pulseMounted&&(a.dataset.pulseMounted="1",i(c,a,window.__PULSE_SERVER__||{},{ssr:!0}),d(a,i));var N=c;export{N as default};
@@ -1,14 +0,0 @@
1
- import{a as s,b as n}from"./runtime-ZJ4FXT5O.js";import{_a as a}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as l,h as r}from"./runtime-L2HNXIHW.js";import{a as e,b as i}from"./runtime-B73WLANC.js";var{prev:c,next:p}=l("/components/footer"),t={route:"/components/footer",meta:{title:"Footer \u2014 Pulse Docs",description:"Accessible site footer with logo slot, navigation links, and legal text.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>n({currentHref:"/components/footer",prev:c,next:p,name:"footer",description:"Accessible site footer with logo slot, navigation links, and legal text. Handles responsive stacking, hover states, and focus styles automatically.",content:`
2
- ${s(a({logo:"MyApp",logoHref:"/",links:[{label:"Docs",href:"/docs"},{label:"Pricing",href:"/pricing"},{label:"Blog",href:"/blog"},{label:"GitHub",href:"https://github.com"}],legal:"\xA9 2026 MyApp Ltd."}),`footer({
3
- logo: 'MyApp',
4
- logoHref: '/',
5
- links: [
6
- { label: 'Docs', href: '/docs' },
7
- { label: 'Pricing', href: '/pricing' },
8
- { label: 'GitHub', href: 'https://github.com' },
9
- ],
10
- legal: '\xA9 2026 MyApp Ltd.',
11
- })`)}
12
-
13
- ${r(["Prop","Type","Default",""],[["<code>logo</code>","string (HTML)","\u2014","Raw HTML slot \u2014 SVG, img, or text"],["<code>logoHref</code>","string","'/'","Logo link destination"],["<code>links</code>","array","[]","[{label, href}] \u2014 footer navigation links"],["<code>legal</code>","string","\u2014","Copyright / legal text"]])}
14
- `})};var o=document.getElementById("pulse-root");o&&!o.dataset.pulseMounted&&(o.dataset.pulseMounted="1",e(t,o,window.__PULSE_SERVER__||{},{ssr:!0}),i(o,e));var v=t;export{v as default};
@@ -1,59 +0,0 @@
1
- import{a as t,b as u}from"./runtime-ZJ4FXT5O.js";import{Ca as n,Ha as r,Ia as c,Pa as o,c as i}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as d,h as p}from"./runtime-L2HNXIHW.js";import{a,b as m}from"./runtime-B73WLANC.js";var{prev:h,next:f}=d("/components/grid"),e=g=>`<div style="background:var(--surface-2);border:1px solid var(--border);border-radius:6px;padding:1.25rem;text-align:center;color:var(--muted)">${g}</div>`,l={route:"/components/grid",meta:{title:"Grid \u2014 Pulse Docs",description:"Grid component for Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>u({currentHref:"/components/grid",prev:h,next:f,name:"grid",description:"Responsive CSS grid. Collapses to a single column on mobile. Direct children of the content slot become grid items \u2014 no wrapper needed.",content:`
2
- <h2 class="doc-h2" id="cols">Column counts</h2>
3
- <p>Use <code>cols</code> to set the number of columns. All layouts collapse to one column on mobile.</p>
4
-
5
- <h3 class="doc-h3">2 columns</h3>
6
- ${t(o({cols:2,content:e("Left")+e("Right")}),"grid({ cols: 2, content: left + right })")}
7
-
8
- <h3 class="doc-h3">3 columns (default)</h3>
9
- ${t(o({cols:3,content:e("One")+e("Two")+e("Three")}),"grid({ cols: 3, content: items.join('') })")}
10
-
11
- <h3 class="doc-h3">4 columns</h3>
12
- ${t(o({cols:4,content:e("A")+e("B")+e("C")+e("D")}),"grid({ cols: 4, content: items.join('') })")}
13
-
14
- <h2 class="doc-h2" id="gap">Gap sizes</h2>
15
- <p>Control spacing between items with <code>gap: 'sm' | 'md' | 'lg'</code>. Default is <code>'md'</code>.</p>
16
-
17
- <h3 class="doc-h3">Small gap</h3>
18
- ${t(o({cols:3,gap:"sm",content:e("One")+e("Two")+e("Three")}),"grid({ cols: 3, gap: 'sm', content: items.join('') })")}
19
-
20
- <h3 class="doc-h3">Large gap</h3>
21
- ${t(o({cols:3,gap:"lg",content:e("One")+e("Two")+e("Three")}),"grid({ cols: 3, gap: 'lg', content: items.join('') })")}
22
-
23
- <h2 class="doc-h2" id="with-components">With components</h2>
24
- <p>Grid accepts any HTML string as content \u2014 pass other component outputs directly.</p>
25
-
26
- <h3 class="doc-h3">Feature grid</h3>
27
- ${t(o({cols:3,content:[c({icon:"\u26A1",title:"Fast",description:"Sub-100ms server responses with streaming SSR."}),c({icon:"\u{1F512}",title:"Secure",description:"Security headers on every response, including errors."}),c({icon:"\u{1F3AF}",title:"Simple",description:"No build step, no virtual DOM, no dependencies."})].join("")}),`grid({
28
- cols: 3,
29
- content: features.map(f => feature(f)).join(''),
30
- })`)}
31
-
32
- <h3 class="doc-h3">Stat grid</h3>
33
- ${t(o({cols:4,content:[n({label:"Monthly users",value:"24.8k",change:"+12%",trend:"up"}),n({label:"Revenue",value:"$18.2k",change:"+8.4%",trend:"up"}),n({label:"Churn rate",value:"2.1%",change:"\u22120.3%",trend:"down"}),n({label:"Uptime",value:"99.98%",change:"0.0%",trend:"neutral"})].join("")}),`grid({
34
- cols: 4,
35
- content: stats.map(s => stat(s)).join(''),
36
- })`)}
37
-
38
- <h3 class="doc-h3">Testimonial grid</h3>
39
- ${t(o({cols:3,content:[r({quote:"Shipped our redesign in a weekend. No boilerplate, no config hell.",name:"Alex Morgan",role:"CTO at Launchpad",rating:5}),r({quote:"The streaming SSR makes our pages feel instant. Lighthouse is happy.",name:"Sara Kim",role:"Lead Engineer, Orbit",rating:5}),r({quote:"Finally a UI kit that doesn't fight the platform. Just HTML.",name:"Dan Okafor",role:"Founder, Stackly",rating:5})].join("")}),`grid({
40
- cols: 3,
41
- content: testimonials.map(t => testimonial(t)).join(''),
42
- })`)}
43
-
44
- <h3 class="doc-h3">Card grid</h3>
45
- ${t(o({cols:3,gap:"md",content:[i({title:"Getting started",content:'<p style="color:var(--muted);margin:0">Install and run your first Pulse app in under five minutes.</p>',footer:'<span class="ui-badge">Guide</span>'}),i({title:"Components",content:'<p style="color:var(--muted);margin:0">30+ accessible, composable UI primitives ready to drop in.</p>',footer:'<span class="ui-badge">Reference</span>'}),i({title:"Deployment",content:'<p style="color:var(--muted);margin:0">Static hosting, Node servers, or edge runtimes \u2014 one build.</p>',footer:'<span class="ui-badge">Deploy</span>'})].join("")}),`grid({
46
- cols: 3,
47
- content: docs.map(d => card({
48
- title: d.title,
49
- content: \`<p>\${d.summary}</p>\`,
50
- footer: badge({ label: d.tag }),
51
- })).join(''),
52
- })`)}
53
-
54
- <h2 class="doc-h2" id="1col">Single column</h2>
55
- <p>Use <code>cols: 1</code> for a stacked list with consistent spacing \u2014 useful for form sections or timelines.</p>
56
- ${t(o({cols:1,gap:"sm",content:e("Step one")+e("Step two")+e("Step three")}),"grid({ cols: 1, gap: 'sm', content: steps.join('') })")}
57
-
58
- ${p(["Prop","Type","Default",""],[["<code>content</code>","string (HTML)","\u2014","Raw HTML slot \u2014 direct children are grid items"],["<code>cols</code>","number","3","1 \xB7 2 \xB7 3 \xB7 4"],["<code>gap</code>","string","'md'","'sm' \xB7 'md' \xB7 'lg'"]])}
59
- `})};var s=document.getElementById("pulse-root");s&&!s.dataset.pulseMounted&&(s.dataset.pulseMounted="1",a(l,s,window.__PULSE_SERVER__||{},{ssr:!0}),m(s,a));var C=l;export{C as default};
@@ -1,44 +0,0 @@
1
- import{a as t,b as d}from"./runtime-ZJ4FXT5O.js";import{c as r,ub as e}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as n,h as i}from"./runtime-L2HNXIHW.js";import{a as l,b as c}from"./runtime-B73WLANC.js";var{prev:h,next:u}=n("/components/heading"),a={route:"/components/heading",meta:{title:"Heading \u2014 Pulse Docs",description:"Styled semantic heading component for Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>d({currentHref:"/components/heading",prev:h,next:u,name:"heading",description:"Styled semantic heading. Renders the correct HTML tag (<code>h1</code>\u2013<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.",content:`
2
-
3
- <h2 class="doc-h2" id="levels">All levels</h2>
4
- <p>Each level has a default visual size. The semantic tag and visual size are independent \u2014 see <a href="#size-override">size override</a> below.</p>
5
- ${t([1,2,3,4,5,6].map(s=>e({level:s,text:`Heading level ${s}`})).join(""),`heading({ level: 1, text: 'Page title' })
6
- heading({ level: 2, text: 'Section title' })
7
- heading({ level: 3, text: 'Subsection' })
8
- heading({ level: 4, text: 'Card heading' })
9
- heading({ level: 5, text: 'Label' })
10
- heading({ level: 6, text: 'Caption' })`,{col:!0})}
11
-
12
- <h2 class="doc-h2" id="size-override">Size override</h2>
13
- <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>
14
- ${t([e({level:2,text:"Semantic h2, looks like h4",size:"xl"}),e({level:3,text:"Semantic h3, extra large",size:"4xl"})].join(""),`// h2 for structure, but visually smaller
15
- heading({ level: 2, text: 'Related articles', size: 'xl' })
16
-
17
- // h3 that needs to be visually prominent
18
- heading({ level: 3, text: 'Featured', size: '4xl' })`,{col:!0})}
19
-
20
- <h2 class="doc-h2" id="color">Color</h2>
21
- ${t([e({level:3,text:"Default colour"}),e({level:3,text:"Muted \u2014 for secondary labels",color:"muted"}),e({level:3,text:"Accent \u2014 for highlights",color:"accent"})].join(""),`heading({ level: 3, text: 'Default colour' })
22
- heading({ level: 3, text: 'Muted \u2014 for secondary labels', color: 'muted' })
23
- heading({ level: 3, text: 'Accent \u2014 for highlights', color: 'accent' })`,{col:!0})}
24
-
25
- <h2 class="doc-h2" id="spacing">Spacing</h2>
26
- <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>
27
- ${t(r({content:`
28
- ${e({level:2,text:"Account settings",class:"u-mb-2"})}
29
- <p class="u-text-muted u-text-sm">Manage your profile and preferences.</p>
30
- `}),`card({ content: \`
31
- \${heading({ level: 2, text: 'Account settings', class: 'u-mb-2' })}
32
- <p class="u-text-muted u-text-sm">Manage your profile and preferences.</p>
33
- \`})`,{col:!0})}
34
-
35
- <h2 class="doc-h2" id="balance">Preventing orphans</h2>
36
- <p>When a heading wraps across lines, the last line can be left with a single short word \u2014 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>
37
- ${t([e({level:2,text:"The quick brown fox jumps over the lazy dog tonight"}),e({level:2,text:"The quick brown fox jumps over the lazy dog tonight",balance:!0})].join('<p class="u-text-muted u-text-sm u-mt-2 u-mb-4">\u2191 without balance \u2014 \u2193 with balance: true</p>'),`// Without \u2014 last line may have a single word
38
- heading({ level: 2, text: 'The quick brown fox jumps over the lazy dog tonight' })
39
-
40
- // With \u2014 text distributed evenly across lines
41
- heading({ level: 2, text: 'The quick brown fox jumps over the lazy dog tonight', balance: true })`,{col:!0})}
42
-
43
- ${i(["Prop","Type","Default",""],[["<code>level</code>","number (1\u20136)","2","Controls both the HTML tag and the default visual size"],["<code>text</code>","string","\u2014","Heading text \u2014 escaped automatically"],["<code>size</code>","<code>xs | sm | base | lg | xl | 2xl | 3xl | 4xl</code>","\u2014","Override the visual font size independently of the semantic level. Defaults: h1=4xl, h2=3xl, h3=2xl, h4=xl, h5=base, h6=sm"],["<code>color</code>","<code>default | muted | accent</code>","<code>default</code>","Text colour token"],["<code>balance</code>","boolean","<code>false</code>","Adds <code>text-wrap: balance</code> \u2014 prevents orphaned words on the last line when the heading wraps"],["<code>class</code>","string","\u2014","Extra classes \u2014 use for spacing utilities such as <code>u-mb-4</code>"]])}
44
- `})};var o=document.getElementById("pulse-root");o&&!o.dataset.pulseMounted&&(o.dataset.pulseMounted="1",l(a,o,window.__PULSE_SERVER__||{},{ssr:!0}),c(o,l));var w=a;export{w as default};
@@ -1,17 +0,0 @@
1
- import{a as t,b as d}from"./runtime-ZJ4FXT5O.js";import{Ga as r,Ma as s}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as l,h as a}from"./runtime-L2HNXIHW.js";import{a as o,b as n}from"./runtime-B73WLANC.js";var{prev:p,next:c}=l("/components/hero"),i={route:"/components/hero",meta:{title:"Hero \u2014 Pulse Docs",description:"Hero component for Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>d({currentHref:"/components/hero",prev:p,next:c,name:"hero",description:"Full-width hero section. The <code>actions</code> slot accepts any combination of <code>button()</code> and <code>appBadge()</code> calls. Set <code>align: 'left'</code> for a split-layout hero. Use <code>size: 'sm'</code> for inner-page headers that don't need the full vertical padding.",content:`
2
- ${t(r({eyebrow:"Now available",title:"The app your phone deserves",subtitle:"Beautifully simple. Ridiculously fast. Available on iOS and Android.",actions:s({store:"apple",href:"#"})+" "+s({store:"google",href:"#"})}),`hero({
3
- eyebrow: 'Now available',
4
- title: 'The app your phone deserves',
5
- subtitle: 'Beautifully simple. Ridiculously fast.',
6
- actions: appBadge({ store: 'apple', href: appStoreUrl }) +
7
- appBadge({ store: 'google', href: playStoreUrl }),
8
- })`)}
9
-
10
- ${t(r({title:"Blog",subtitle:"Thoughts on building for the web.",size:"sm"}),`hero({
11
- title: 'Blog',
12
- subtitle: 'Thoughts on building for the web.',
13
- size: 'sm',
14
- })`)}
15
-
16
- ${a(["Prop","Type","Default",""],[["<code>eyebrow</code>","string","\u2014","Small label above the title"],["<code>title</code>","string","\u2014",""],["<code>subtitle</code>","string","\u2014",""],["<code>actions</code>","string (HTML)","\u2014","Raw HTML slot"],["<code>align</code>","string","'center'","'center' or 'left'"],["<code>size</code>","string","'md'","'md' (5rem padding) or 'sm' (2.5rem top, no bottom) \u2014 use sm for inner-page headers"]])}
17
- `})};var e=document.getElementById("pulse-root");e&&!e.dataset.pulseMounted&&(e.dataset.pulseMounted="1",o(i,e,window.__PULSE_SERVER__||{},{ssr:!0}),n(e,o));var v=i;export{v as default};
@@ -1,68 +0,0 @@
1
- import{a as n,b as x}from"./runtime-ZJ4FXT5O.js";import{$ as ln,A as b,B as X,C as l,D as V,E as C,F as N,G as O,H as Z,I as _,Ia as o,J as W,K as j,L as J,M as t,N as K,O as z,P as Q,Q as Y,R as nn,S as en,T as on,U as cn,V as an,W as rn,X as tn,Y as d,Z as sn,_ as S,a as i,aa as dn,ba as pn,ca as mn,da as un,e as P,ea as p,f as U,fa as gn,g as $,ga as fn,h as D,ha as hn,i as M,ia as bn,j as L,ja as Cn,k as A,ka as zn,l as q,la as Sn,m as E,ma as wn,n as H,na as vn,o as T,oa as yn,p as I,pa as m,q as R,qa as e,r as c,ra as kn,s as g,sa as xn,t as a,ta as Pn,u as B,ua as Un,v as r,va as $n,w as f,wa as Dn,x as F,y as G,z as h}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as v,h as y}from"./runtime-L2HNXIHW.js";import{a as u,b as k}from"./runtime-B73WLANC.js";var{prev:En,next:Hn}=v("/components/icons"),Tn=[{group:"Navigation & Direction",icons:[{name:"iconArrowLeft",fn:P},{name:"iconArrowRight",fn:U},{name:"iconArrowUp",fn:$},{name:"iconArrowDown",fn:D},{name:"iconChevronLeft",fn:M},{name:"iconChevronRight",fn:L},{name:"iconChevronUp",fn:A},{name:"iconChevronDown",fn:q},{name:"iconExternalLink",fn:E},{name:"iconMenu",fn:H},{name:"iconX",fn:T},{name:"iconMoreHorizontal",fn:I},{name:"iconMoreVertical",fn:R}]},{group:"Status",icons:[{name:"iconCheck",fn:c},{name:"iconCheckCircle",fn:g},{name:"iconXCircle",fn:a},{name:"iconAlertCircle",fn:B},{name:"iconAlertTriangle",fn:r},{name:"iconInfo",fn:f}]},{group:"Actions",icons:[{name:"iconPlus",fn:F},{name:"iconMinus",fn:G},{name:"iconEdit",fn:h},{name:"iconTrash",fn:b},{name:"iconCopy",fn:X},{name:"iconSearch",fn:l},{name:"iconFilter",fn:V},{name:"iconDownload",fn:C},{name:"iconUpload",fn:N},{name:"iconRefresh",fn:O},{name:"iconSend",fn:Z}]},{group:"UI Controls",icons:[{name:"iconEye",fn:_},{name:"iconEyeOff",fn:W},{name:"iconLock",fn:j},{name:"iconUnlock",fn:J},{name:"iconSettings",fn:t},{name:"iconBell",fn:K}]},{group:"People & Communication",icons:[{name:"iconUser",fn:z},{name:"iconUsers",fn:Q},{name:"iconMail",fn:Y},{name:"iconMessageSquare",fn:nn}]},{group:"Navigation & Pages",icons:[{name:"iconHome",fn:en},{name:"iconMapPin",fn:Dn},{name:"iconLogOut",fn:on},{name:"iconLogIn",fn:cn}]},{group:"Content & Files",icons:[{name:"iconFile",fn:an},{name:"iconImage",fn:rn},{name:"iconLink",fn:tn},{name:"iconCode",fn:d},{name:"iconCalendar",fn:sn},{name:"iconClock",fn:S},{name:"iconBookmark",fn:ln},{name:"iconTag",fn:dn}]},{group:"Media & Rating",icons:[{name:"iconPlay",fn:pn},{name:"iconPause",fn:mn},{name:"iconVolume",fn:un},{name:"iconStar",fn:p},{name:"iconHeart",fn:gn}]},{group:"Devices",icons:[{name:"iconPhone",fn},{name:"iconGamepad",fn:hn}]},{group:"Hand Pointers",icons:[{name:"iconHandPointUp",fn:bn},{name:"iconHandPointDown",fn:Cn},{name:"iconHandPointLeft",fn:zn},{name:"iconHandPointRight",fn:Sn}]},{group:"Misc",icons:[{name:"iconGlobe",fn:yn},{name:"iconShield",fn:m},{name:"iconZap",fn:e},{name:"iconTrendingUp",fn:kn},{name:"iconTrendingDown",fn:xn},{name:"iconLoader",fn:Pn},{name:"iconGrid",fn:Un},{name:"iconBug",fn:$n}]},{group:"Theme",icons:[{name:"iconSun",fn:wn},{name:"iconMoon",fn:vn}]}];function In(){return Tn.map(({group:Mn,icons:Ln})=>`
2
- <h3 class="doc-h3" style="margin-top:2rem">${Mn}</h3>
3
- <div class="icon-grid">
4
- ${Ln.map(({name:An,fn:qn})=>`
5
- <div class="icon-grid-item">
6
- <div class="icon-grid-preview">${qn({size:20})}</div>
7
- <span class="icon-grid-name">${An}</span>
8
- </div>
9
- `).join("")}
10
- </div>
11
- `).join("")}var w={route:"/components/icons",meta:{title:"Icons \u2014 Pulse Docs",description:"Built-in icon set for Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>x({currentHref:"/components/icons",prev:En,next:Hn,name:"icons",description:'55 curated icons. All are pure functions returning an SVG string \u2014 no external library, no DOM dependency, tree-shakeable. Style: 24\xD724 viewBox, <code>stroke="currentColor"</code>, compatible with any colour token.',content:`
12
-
13
- <h2 class="doc-h2" id="usage">Usage</h2>
14
- <p>Import the icon functions you need alongside other components. Call each as a function \u2014 optionally pass <code>size</code> and <code>class</code>.</p>
15
- ${n('<div style="display:flex;gap:1rem;align-items:center;flex-wrap:wrap">'+c({size:20})+l({size:20})+z({size:20})+p({size:20})+e({size:20})+t({size:20})+"</div>",`import { iconCheck, iconSearch, iconUser } from '@invisibleloop/pulse/ui'
16
-
17
- // Default size (16px)
18
- iconCheck()
19
-
20
- // Custom size
21
- iconSearch({ size: 20 })
22
-
23
- // With extra class
24
- iconUser({ size: 20, class: 'u-text-accent' })`)}
25
-
26
- <h2 class="doc-h2" id="with-button">With button</h2>
27
- <p>Pass an icon into the <code>icon</code> prop of <code>button()</code>.</p>
28
- ${n('<div style="display:flex;gap:.75rem;flex-wrap:wrap;align-items:center">'+i({label:"Download",variant:"primary",icon:C({size:14})})+i({label:"Edit",variant:"secondary",icon:h({size:14})})+i({label:"Delete",variant:"danger",icon:b({size:14})})+i({label:"Search",variant:"ghost",icon:l({size:14})})+"</div>",`button({ label: 'Download', variant: 'primary', icon: iconDownload({ size: 14 }) })
29
- button({ label: 'Edit', variant: 'secondary', icon: iconEdit({ size: 14 }) })
30
- button({ label: 'Delete', variant: 'danger', icon: iconTrash({ size: 14 }) })
31
- button({ label: 'Search', variant: 'ghost', icon: iconSearch({ size: 14 }) })`)}
32
-
33
- <h2 class="doc-h2" id="with-feature">With feature</h2>
34
- <p>Icons compose naturally into the <code>feature()</code> icon slot.</p>
35
- ${n('<div style="display:grid;grid-template-columns:repeat(3,1fr);gap:1rem">'+o({icon:e({size:20}),title:"Fast",description:"Streaming SSR. No build step."})+o({icon:m({size:20}),title:"Secure",description:"Security headers on every response."})+o({icon:d({size:20}),title:"Simple",description:"Plain JS objects, no JSX."})+"</div>",`feature({ icon: iconZap({ size: 20 }), title: 'Fast', description: '...' })
36
- feature({ icon: iconShield({ size: 20 }), title: 'Secure', description: '...' })
37
- feature({ icon: iconCode({ size: 20 }), title: 'Simple', description: '...' })`)}
38
-
39
- <h2 class="doc-h2" id="background">Background</h2>
40
- <p>Add <code>bg: 'circle'</code> or <code>bg: 'square'</code> to wrap the icon in a tinted background. Use <code>bgColor</code> to pick the colour \u2014 defaults to <code>'accent'</code>.</p>
41
-
42
- <h3 class="doc-h3">Circle</h3>
43
- ${n('<div style="display:flex;gap:1rem;align-items:center;flex-wrap:wrap">'+e({size:20,bg:"circle",bgColor:"accent"})+c({size:20,bg:"circle",bgColor:"success"})+r({size:20,bg:"circle",bgColor:"warning"})+a({size:20,bg:"circle",bgColor:"error"})+t({size:20,bg:"circle",bgColor:"muted"})+"</div>",`iconZap({ size: 20, bg: 'circle', bgColor: 'accent' })
44
- iconCheck({ size: 20, bg: 'circle', bgColor: 'success' })
45
- iconAlertTriangle({ size: 20, bg: 'circle', bgColor: 'warning' })
46
- iconXCircle({ size: 20, bg: 'circle', bgColor: 'error' })
47
- iconSettings({ size: 20, bg: 'circle', bgColor: 'muted' })`)}
48
-
49
- <h3 class="doc-h3">Square (rounded)</h3>
50
- ${n('<div style="display:flex;gap:1rem;align-items:center;flex-wrap:wrap">'+e({size:20,bg:"square",bgColor:"accent"})+c({size:20,bg:"square",bgColor:"success"})+r({size:20,bg:"square",bgColor:"warning"})+a({size:20,bg:"square",bgColor:"error"})+t({size:20,bg:"square",bgColor:"muted"})+"</div>","iconZap({ size: 20, bg: 'square', bgColor: 'accent' })")}
51
-
52
- <h3 class="doc-h3">With feature()</h3>
53
- <p>Pairs naturally with the <code>feature()</code> icon slot at larger sizes.</p>
54
- ${n('<div style="display:grid;grid-template-columns:repeat(3,1fr);gap:1rem">'+o({icon:e({size:22,bg:"square",bgColor:"accent"}),title:"Fast",description:"Streaming SSR, zero config."})+o({icon:m({size:22,bg:"square",bgColor:"success"}),title:"Secure",description:"Security headers by default."})+o({icon:d({size:22,bg:"square",bgColor:"muted"}),title:"Simple",description:"Plain JS objects, no JSX."})+"</div>",`feature({ icon: iconZap({ size: 22, bg: 'square', bgColor: 'accent' }), title: 'Fast', description: '...' })
55
- feature({ icon: iconShield({ size: 22, bg: 'square', bgColor: 'success' }), title: 'Secure', description: '...' })
56
- feature({ icon: iconCode({ size: 22, bg: 'square', bgColor: 'muted' }), title: 'Simple', description: '...' })`)}
57
-
58
- <h2 class="doc-h2" id="colour">Colour</h2>
59
- <p>Icons inherit <code>color</code> from their parent \u2014 use utility classes or CSS tokens to tint them.</p>
60
- ${n(`<div style="display:flex;gap:1.25rem;align-items:center"><span class="u-text-accent">${p({size:20})}</span><span class="u-text-green">${g({size:20})}</span><span class="u-text-red">${a({size:20})}</span><span class="u-text-yellow">${r({size:20})}</span><span class="u-text-blue">${f({size:20})}</span><span class="u-text-muted">${S({size:20})}</span></div>`,'<span class="u-text-accent">${iconStar({ size: 20 })}</span>\n<span class="u-text-green">${iconCheckCircle({ size: 20 })}</span>\n<span class="u-text-red">${iconXCircle({ size: 20 })}</span>\n<span class="u-text-yellow">${iconAlertTriangle({ size: 20 })}</span>')}
61
-
62
- <h2 class="doc-h2" id="all-icons">All icons</h2>
63
- <p>Click any icon name to copy the import.</p>
64
-
65
- ${In()}
66
-
67
- ${y(["Prop","Type","Default",""],[["<code>size</code>","number","16","Width and height in px"],["<code>class</code>","string","\u2014","Extra CSS classes (on wrapper when <code>bg</code> is set, otherwise on the SVG)"],["<code>bg</code>","string","\u2014","'circle' \xB7 'square' \u2014 wraps the icon in a tinted background"],["<code>bgColor</code>","string","'accent'","'accent' \xB7 'success' \xB7 'warning' \xB7 'error' \xB7 'muted'"]])}
68
- `})};var s=document.getElementById("pulse-root");s&&!s.dataset.pulseMounted&&(s.dataset.pulseMounted="1",u(w,s,window.__PULSE_SERVER__||{},{ssr:!0}),k(s,u));var Zn=w;export{Zn as default};
@@ -1,19 +0,0 @@
1
- import{a as o,b as s}from"./runtime-ZJ4FXT5O.js";import{rb as t}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as c,h as r}from"./runtime-L2HNXIHW.js";import{a as i,b as d}from"./runtime-B73WLANC.js";var{prev:n,next:p}=c("/components/image"),a={route:"/components/image",meta:{title:"Image \u2014 Pulse Docs",description:"Responsive image component with optional aspect-ratio crop and caption for Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>s({currentHref:"/components/image",prev:n,next:p,name:"uiImage",description:'Responsive image component. Supports aspect-ratio cropping with <code>object-fit: cover</code>, optional caption, and rounded corners. Always uses <code>loading="lazy"</code> and <code>decoding="async"</code>.',content:`
2
-
3
- <h2 class="doc-h2" id="ratio">With aspect ratio</h2>
4
- <p>Set <code>ratio</code> to constrain the image to a fixed aspect ratio. The image fills the crop area with <code>object-fit: cover</code>.</p>
5
- ${o(t({src:"https://picsum.photos/seed/pulse1/800/450",alt:"Mountain landscape at dusk",ratio:"16/9"}),"uiImage({ src: '/img/photo.jpg', alt: 'Mountain landscape at dusk', ratio: '16/9' })",{col:!0})}
6
-
7
- <h2 class="doc-h2" id="rounded">Square and rounded</h2>
8
- ${o(`<div style="max-width:200px;margin:0 auto">${t({src:"https://picsum.photos/seed/pulse2/400/400",alt:"Profile photo",ratio:"1/1",rounded:!0})}</div>`,"uiImage({ src: '/img/avatar.jpg', alt: 'Profile photo', ratio: '1/1', rounded: true })",{col:!0})}
9
-
10
- <h2 class="doc-h2" id="caption">With caption</h2>
11
- ${o(t({src:"https://picsum.photos/seed/pulse3/800/600",alt:"Aerial view of a coastal town",ratio:"4/3",caption:"Aerial view of Porto, Portugal. Photo by Jo\xE3o Silva."}),`uiImage({
12
- src: '/img/photo.jpg',
13
- alt: 'Aerial view of a coastal town',
14
- ratio: '4/3',
15
- caption: 'Aerial view of Porto, Portugal. Photo by Jo\xE3o Silva.',
16
- })`,{col:!0})}
17
-
18
- ${r(["Prop","Type","Default",""],[["<code>src</code>","string","\u2014","Image source URL"],["<code>alt</code>","string","\u2014","Alt text \u2014 required for accessibility"],["<code>caption</code>","string","\u2014","Renders a <code>&lt;figcaption&gt;</code> below the image"],["<code>ratio</code>","string","\u2014","CSS aspect-ratio string e.g. <code>'16/9'</code>, <code>'4/3'</code>, <code>'1/1'</code>. When set, the image fills the crop area with <code>object-fit: cover</code>."],["<code>rounded</code>","boolean","false","Applies full border-radius to the image wrap"],["<code>width</code>","number","\u2014","Sets the <code>width</code> attribute on the <code>&lt;img&gt;</code>"],["<code>height</code>","number","\u2014","Sets the <code>height</code> attribute on the <code>&lt;img&gt;</code>"],["<code>class</code>","string","\u2014",""]])}
19
- `})};var e=document.getElementById("pulse-root");e&&!e.dataset.pulseMounted&&(e.dataset.pulseMounted="1",i(a,e,window.__PULSE_SERVER__||{},{ssr:!0}),d(e,i));var b=a;export{b as default};
@@ -1,7 +0,0 @@
1
- import{a as i,b as n}from"./runtime-ZJ4FXT5O.js";import{d as o}from"./runtime-UVPXO4IR.js";import"./runtime-VMJA3Z4N.js";import"./runtime-QFURDKA2.js";import{a as d,h as r}from"./runtime-L2HNXIHW.js";import{a as t,b as l}from"./runtime-B73WLANC.js";var{prev:c,next:s}=d("/components/input"),a={route:"/components/input",meta:{title:"Input \u2014 Pulse Docs",description:"Input component for Pulse UI.",styles:["/pulse-ui.css","/docs.css"]},state:{},view:()=>n({currentHref:"/components/input",prev:c,next:s,name:"input",description:"The label and error are wired up automatically \u2014 <code>for</code>/<code>id</code> and <code>aria-describedby</code> are set from <code>name</code>. You don't need to manage ids yourself.",content:`
2
- ${i(o({name:"email1",label:"Email address",type:"email",placeholder:"you@example.com"})+o({name:"email2",label:"Email address",type:"email",value:"bad@",error:"Enter a valid email address"})+o({name:"search",label:"Search",placeholder:"Filter by name\u2026",hint:"Results update as you type"}),`input({ name: 'email', label: 'Email address', type: 'email', placeholder: 'you@example.com' })
3
- input({ name: 'email', label: 'Email address', error: 'Enter a valid email address', value: state.email })
4
- input({ name: 'search', label: 'Search', placeholder: 'Filter by name\u2026', hint: 'Results update as you type' })`,{col:!0})}
5
-
6
- ${r(["Prop","Type","Default",""],[["<code>name</code>","string","\u2014","Also used as id base: <code>field-{name}</code>"],["<code>label</code>","string","\u2014",""],["<code>type</code>","string","text","Any valid HTML input type"],["<code>placeholder</code>","string","\u2014",""],["<code>value</code>","string","\u2014","Pre-filled value \u2014 escaped automatically"],["<code>error</code>","string","\u2014",'Triggers <code>aria-invalid</code> and <code>role="alert"</code>'],["<code>hint</code>","string","\u2014","Helper text below the input"],["<code>required</code>","boolean","false","Adds <code>required</code>, <code>aria-required</code>, and a visual asterisk"],["<code>disabled</code>","boolean","false",""],["<code>id</code>","string","\u2014","Override the generated id"],["<code>attrs</code>","object","{}","Extra attributes on the <code>&lt;input&gt;</code> element"]])}
7
- `})};var e=document.getElementById("pulse-root");e&&!e.dataset.pulseMounted&&(e.dataset.pulseMounted="1",t(a,e,window.__PULSE_SERVER__||{},{ssr:!0}),l(e,t));var v=a;export{v as default};