@stacksjs/components 0.2.20 → 0.2.24

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 (283) hide show
  1. package/README.md +36 -92
  2. package/dist/{Accordion-x2gjedap.stx → Accordion-sbfra0mz.stx} +2 -2
  3. package/dist/{Audio-0fk6p9tn.stx → Audio-vdmg1258.stx} +1 -1
  4. package/dist/{Avatar-5m0v0s4x.stx → Avatar-365cvrh4.stx} +1 -1
  5. package/dist/{Badge-ynes82vv.stx → Badge-8m3qete4.stx} +2 -2
  6. package/dist/{Breadcrumb-h9n427sk.stx → Breadcrumb-7f7s4d02.stx} +1 -1
  7. package/dist/{Button-7xtrzn14.stx → Button-3tt4vsqt.stx} +2 -2
  8. package/dist/{Calendar-egvx1pma.stx → Calendar-58nnkdh8.stx} +5 -5
  9. package/dist/{Card-r9w7vy1a.stx → Card-6wdbexqr.stx} +2 -2
  10. package/dist/{Checkbox-m8v46pmx.stx → Checkbox-p3q3e3nf.stx} +1 -1
  11. package/dist/{Checkout-vcnnr176.stx → Checkout-e4037tyy.stx} +1 -1
  12. package/dist/{Combobox-npb08vkp.stx → Combobox-th5ebw62.stx} +1 -1
  13. package/dist/{ComboboxButton-vcdyq4zw.stx → ComboboxButton-8gxwkhdx.stx} +1 -1
  14. package/dist/{ComboboxInput-c9d2p02m.stx → ComboboxInput-mk99z65n.stx} +1 -1
  15. package/dist/{ComboboxOption-7d0h9ash.stx → ComboboxOption-an9zyan6.stx} +1 -1
  16. package/dist/{ComboboxOptions-4dtqc0qa.stx → ComboboxOptions-6b5ywc5x.stx} +1 -1
  17. package/dist/{CommandPalette-ah00bf8v.stx → CommandPalette-kwmdf2np.stx} +1 -1
  18. package/dist/{CommandPaletteItem-2yx0gvtj.stx → CommandPaletteItem-zx2fbpts.stx} +1 -1
  19. package/dist/{DefaultPaymentMethod-emw5fg8s.stx → DefaultPaymentMethod-shhf6aap.stx} +1 -1
  20. package/dist/{Dialog-1w4rz7x0.stx → Dialog-rgmj8q2j.stx} +1 -1
  21. package/dist/{DialogBackdrop-qbm3y5ab.stx → DialogBackdrop-rxax3sec.stx} +1 -1
  22. package/dist/{DialogDescription-01w5j74b.stx → DialogDescription-76prd1m2.stx} +1 -1
  23. package/dist/{DialogPanel-brsszrrs.stx → DialogPanel-44d8jeqy.stx} +1 -1
  24. package/dist/{DialogTitle-3rxhwg21.stx → DialogTitle-x0r6k8x9.stx} +1 -1
  25. package/dist/{Drawer-yfaz8q7f.stx → Drawer-p7m351bn.stx} +3 -3
  26. package/dist/{Dropdown-ng7nx556.stx → Dropdown-jz4jy0n3.stx} +1 -1
  27. package/dist/{DropdownButton-vc4zpyrb.stx → DropdownButton-9w8zkfwj.stx} +1 -1
  28. package/dist/{DropdownItem-z491y23c.stx → DropdownItem-wagdspb8.stx} +1 -1
  29. package/dist/{DropdownItems-7ykf29sj.stx → DropdownItems-aygjpxkx.stx} +1 -1
  30. package/dist/{EmailInput-bfshpj92.stx → EmailInput-ajsp9vw6.stx} +1 -1
  31. package/dist/{Form-z4f7w6r1.stx → Form-1mdmx9b6.stx} +1 -1
  32. package/dist/{Image-ktk0451c.stx → Image-jhkm6w1f.stx} +1 -1
  33. package/dist/{Listbox-xcejcmyc.stx → Listbox-pqqh72g8.stx} +1 -1
  34. package/dist/{ListboxButton-nx5kmw19.stx → ListboxButton-spwx7513.stx} +1 -1
  35. package/dist/{RadioGroupLabel-aky8a73n.stx → ListboxLabel-7mymt1b8.stx} +1 -1
  36. package/dist/{ListboxOption-6h4hsdz5.stx → ListboxOption-7nxzaexq.stx} +1 -1
  37. package/dist/{ListboxOptions-2sacdtm5.stx → ListboxOptions-8kqvfp7z.stx} +1 -1
  38. package/dist/{Login-s2jkvd9y.stx → Login-rx9gyqhx.stx} +1 -1
  39. package/dist/{Navigator-tqqdgdkw.stx → Navigator-aay8bjab.stx} +3 -3
  40. package/dist/{Notification-sry8egea.stx → Notification-gk33gv7b.stx} +1 -1
  41. package/dist/{NumberInput-zm93ddfw.stx → NumberInput-nzpkx1ry.stx} +3 -3
  42. package/dist/{Pagination-yza9v4qw.stx → Pagination-h61eq390.stx} +6 -6
  43. package/dist/{PasswordInput-4xnndp5y.stx → PasswordInput-zv4hm43j.stx} +2 -2
  44. package/dist/{PaymentMethods-jxba6kek.stx → PaymentMethods-j42jsk5x.stx} +3 -3
  45. package/dist/{Popover-scbqatjq.stx → Popover-469gbt6r.stx} +1 -1
  46. package/dist/{PopoverButton-rbxhzj4k.stx → PopoverButton-fnaqc77g.stx} +1 -1
  47. package/dist/{PopoverPanel-9ng1rm6e.stx → PopoverPanel-y0vtf5w9.stx} +1 -1
  48. package/dist/{Portal-j111yvqp.stx → Portal-s2q37yp0.stx} +1 -1
  49. package/dist/{Progress-gbmw3akr.stx → Progress-vmdkm06p.stx} +1 -1
  50. package/dist/{Radio-1n9qamv1.stx → Radio-04bs3d21.stx} +1 -1
  51. package/dist/{RadioGroup-12dw2vhk.stx → RadioGroup-bvb1mrhd.stx} +1 -1
  52. package/dist/{RadioGroupDescription-bjm3mdht.stx → RadioGroupDescription-yej78fak.stx} +1 -1
  53. package/dist/{ListboxLabel-aky8a73n.stx → RadioGroupLabel-7mymt1b8.stx} +1 -1
  54. package/dist/{RadioGroupOption-9pcxgwmd.stx → RadioGroupOption-cpdwgnhw.stx} +1 -1
  55. package/dist/{SearchInput-g240e2nq.stx → SearchInput-2521m475.stx} +1 -1
  56. package/dist/{Select-p9f94b20.stx → Select-g4mmvfv8.stx} +1 -1
  57. package/dist/{Sidebar-gwxw8q38.stx → Sidebar-40ckbzh8.stx} +1 -1
  58. package/dist/{SidebarFooter-887kxret.stx → SidebarFooter-hnth56mg.stx} +1 -1
  59. package/dist/{SidebarHeader-qjeyx0hv.stx → SidebarHeader-3wrte2p2.stx} +1 -1
  60. package/dist/{SidebarItem-4dpwtmb4.stx → SidebarItem-zqtvvzpc.stx} +1 -1
  61. package/dist/{SidebarSection-kh92fk4m.stx → SidebarSection-3etwnbjr.stx} +1 -1
  62. package/dist/{Signup-3nxq5zag.stx → Signup-c4dyv6f3.stx} +1 -1
  63. package/dist/{Skeleton-g0nx1njm.stx → Skeleton-v1pwa8nr.stx} +1 -1
  64. package/dist/{Spinner-w4zj58xp.stx → Spinner-7dahavkd.stx} +1 -1
  65. package/dist/{Stepper-rwc5actp.stx → Stepper-rgbk76hd.stx} +1 -1
  66. package/dist/{StepperStep-h0k657nm.stx → StepperStep-en4r00zv.stx} +1 -1
  67. package/dist/{SubscriptionCheckout-4cbxdg7w.stx → SubscriptionCheckout-gawjzf3q.stx} +2 -2
  68. package/dist/{Switch-kjq8qd2p.stx → Switch-036j9vm1.stx} +1 -1
  69. package/dist/{Table-59j9qwp0.stx → Table-6cx8az9h.stx} +1 -1
  70. package/dist/{TableBody-reka2gwv.stx → TableBody-wf6t13j9.stx} +1 -1
  71. package/dist/{TableCell-j7nh4sgr.stx → TableCell-ntx0edbn.stx} +1 -1
  72. package/dist/{TableHead-ecbrwpqm.stx → TableHead-3k4hnm2k.stx} +1 -1
  73. package/dist/{TableHeader-jn2shwsv.stx → TableHeader-ydys9rzz.stx} +1 -1
  74. package/dist/{TableRow-xz8rrxhc.stx → TableRow-z09p2ebf.stx} +1 -1
  75. package/dist/{Tabs-kb6ex6m7.stx → Tabs-svh721m0.stx} +2 -2
  76. package/dist/{Teleport-819cg9zm.stx → Teleport-qfch3w0b.stx} +1 -1
  77. package/dist/{TextInput-zx9kgr79.stx → TextInput-k2kfkgy1.stx} +2 -2
  78. package/dist/{Textarea-5xvmrb0z.stx → Textarea-szad57dz.stx} +1 -1
  79. package/dist/{Tooltip-5ehqsy49.stx → Tooltip-em7t551n.stx} +1 -1
  80. package/dist/{Transition-2j39s044.stx → Transition-0hmr6zxb.stx} +1 -1
  81. package/dist/{TwoFactorChallenge-2q4gg89m.stx → TwoFactorChallenge-an9yvxvq.stx} +2 -2
  82. package/dist/{Video-6aq4shh4.stx → Video-crxva65p.stx} +1 -1
  83. package/dist/{VirtualList-weh5qtm1.stx → VirtualList-cndhjejh.stx} +1 -1
  84. package/dist/{VirtualTable-59a1eskc.stx → VirtualTable-ng0b48yp.stx} +1 -1
  85. package/dist/components/CodeBlock.stx +12 -0
  86. package/dist/components/Footer.stx +8 -0
  87. package/dist/components/Hero.stx +3 -0
  88. package/dist/components/Installation.stx +5 -0
  89. package/dist/index.js +9 -9
  90. package/dist/ui/accordion/Accordion.stx +10 -0
  91. package/dist/ui/audio/Audio.stx +11 -0
  92. package/dist/ui/auth/Login.stx +10 -0
  93. package/dist/ui/auth/Signup.stx +5 -0
  94. package/dist/ui/auth/TwoFactorChallenge.stx +9 -0
  95. package/dist/ui/avatar/Avatar.stx +15 -0
  96. package/dist/ui/badge/Badge.stx +9 -0
  97. package/dist/ui/breadcrumb/Breadcrumb.stx +9 -0
  98. package/dist/ui/button/Button.stx +14 -0
  99. package/dist/ui/button/index.d.ts +2 -2
  100. package/dist/ui/calendar/Calendar.stx +10 -0
  101. package/dist/ui/card/Card.stx +12 -0
  102. package/dist/ui/checkbox/Checkbox.stx +15 -0
  103. package/dist/ui/combobox/Combobox.stx +4 -0
  104. package/dist/ui/combobox/ComboboxButton.stx +2 -0
  105. package/dist/ui/combobox/ComboboxInput.stx +8 -0
  106. package/dist/ui/combobox/ComboboxOption.stx +13 -0
  107. package/dist/ui/combobox/ComboboxOptions.stx +3 -0
  108. package/dist/ui/command-palette/CommandPalette.stx +8 -0
  109. package/dist/ui/command-palette/CommandPaletteItem.stx +8 -0
  110. package/dist/ui/dialog/Dialog.stx +5 -0
  111. package/dist/ui/dialog/DialogBackdrop.stx +2 -0
  112. package/dist/ui/dialog/DialogDescription.stx +2 -0
  113. package/dist/ui/dialog/DialogPanel.stx +2 -0
  114. package/dist/ui/dialog/DialogTitle.stx +2 -0
  115. package/dist/ui/drawer/Drawer.stx +9 -0
  116. package/dist/ui/dropdown/Dropdown.stx +7 -0
  117. package/dist/ui/dropdown/DropdownButton.stx +6 -0
  118. package/dist/ui/dropdown/DropdownItem.stx +10 -0
  119. package/dist/ui/dropdown/DropdownItems.stx +3 -0
  120. package/dist/ui/form/Form.stx +11 -0
  121. package/dist/ui/form/index.d.ts +2 -2
  122. package/dist/ui/image/Image.stx +26 -0
  123. package/dist/ui/input/EmailInput.stx +11 -0
  124. package/dist/ui/input/NumberInput.stx +19 -0
  125. package/dist/ui/input/PasswordInput.stx +19 -0
  126. package/dist/ui/input/SearchInput.stx +12 -0
  127. package/dist/ui/input/TextInput.stx +22 -0
  128. package/dist/ui/input/index.d.ts +6 -6
  129. package/dist/ui/listbox/Listbox.stx +5 -0
  130. package/dist/ui/listbox/ListboxButton.stx +3 -0
  131. package/dist/ui/listbox/ListboxLabel.stx +2 -0
  132. package/dist/ui/listbox/ListboxOption.stx +13 -0
  133. package/dist/ui/listbox/ListboxOptions.stx +3 -0
  134. package/dist/ui/navigator/Navigator.stx +8 -0
  135. package/dist/ui/notification/Notification.stx +12 -0
  136. package/dist/ui/pagination/Pagination.stx +12 -0
  137. package/dist/ui/payment/Checkout.stx +13 -0
  138. package/dist/ui/payment/DefaultPaymentMethod.stx +4 -0
  139. package/dist/ui/payment/PaymentMethods.stx +6 -0
  140. package/dist/ui/payment/SubscriptionCheckout.stx +191 -0
  141. package/dist/ui/popover/Popover.stx +7 -0
  142. package/dist/ui/popover/PopoverButton.stx +6 -0
  143. package/dist/ui/popover/PopoverPanel.stx +4 -0
  144. package/dist/ui/portal/Portal.stx +2 -0
  145. package/dist/ui/progress/Progress.stx +14 -0
  146. package/dist/ui/radio/Radio.stx +14 -0
  147. package/dist/ui/radio-group/RadioGroup.stx +4 -0
  148. package/dist/ui/radio-group/RadioGroupDescription.stx +2 -0
  149. package/dist/ui/radio-group/RadioGroupLabel.stx +2 -0
  150. package/dist/ui/radio-group/RadioGroupOption.stx +13 -0
  151. package/dist/ui/select/Select.stx +14 -0
  152. package/dist/ui/sidebar/Sidebar.stx +33 -0
  153. package/dist/ui/sidebar/SidebarFooter.stx +27 -0
  154. package/dist/ui/sidebar/SidebarHeader.stx +26 -0
  155. package/dist/ui/sidebar/SidebarItem.stx +28 -0
  156. package/dist/ui/sidebar/SidebarSection.stx +25 -0
  157. package/dist/ui/skeleton/Skeleton.stx +9 -0
  158. package/dist/ui/spinner/Spinner.stx +9 -0
  159. package/dist/ui/stepper/Stepper.stx +4 -0
  160. package/dist/ui/stepper/StepperStep.stx +12 -0
  161. package/dist/ui/switch/Switch.stx +15 -0
  162. package/dist/ui/table/Table.stx +3 -0
  163. package/dist/ui/table/TableBody.stx +1 -0
  164. package/dist/ui/table/TableCell.stx +1 -0
  165. package/dist/ui/table/TableHead.stx +1 -0
  166. package/dist/ui/table/TableHeader.stx +3 -0
  167. package/dist/ui/table/TableRow.stx +2 -0
  168. package/dist/ui/tabs/Tabs.stx +9 -0
  169. package/dist/ui/teleport/Teleport.stx +3 -0
  170. package/dist/ui/textarea/Textarea.stx +18 -0
  171. package/dist/ui/tooltip/Tooltip.stx +9 -0
  172. package/dist/ui/transition/Transition.stx +27 -0
  173. package/dist/ui/video/Video.stx +15 -0
  174. package/dist/ui/virtual-list/VirtualList.stx +9 -0
  175. package/dist/ui/virtual-table/VirtualTable.stx +16 -0
  176. package/dist/utils/accessibility.d.ts +10 -25
  177. package/dist/utils/animation/easing.d.ts +75 -0
  178. package/dist/utils/error-handling.d.ts +8 -21
  179. package/dist/utils/i18n.d.ts +36 -86
  180. package/package.json +5 -3
  181. package/src/ui/accordion/Accordion.stx +2 -2
  182. package/src/ui/audio/Audio.stx +1 -1
  183. package/src/ui/audio/README.md +5 -6
  184. package/src/ui/auth/Login.stx +1 -1
  185. package/src/ui/auth/README.md +30 -33
  186. package/src/ui/auth/Signup.stx +1 -1
  187. package/src/ui/auth/TwoFactorChallenge.stx +2 -2
  188. package/src/ui/avatar/Avatar.stx +1 -1
  189. package/src/ui/badge/Badge.stx +2 -2
  190. package/src/ui/breadcrumb/Breadcrumb.stx +1 -1
  191. package/src/ui/button/Button.stx +2 -2
  192. package/src/ui/button/README.md +12 -32
  193. package/src/ui/calendar/Calendar.stx +5 -5
  194. package/src/ui/card/Card.stx +2 -2
  195. package/src/ui/checkbox/Checkbox.stx +1 -1
  196. package/src/ui/combobox/Combobox.stx +1 -1
  197. package/src/ui/combobox/ComboboxButton.stx +1 -1
  198. package/src/ui/combobox/ComboboxInput.stx +1 -1
  199. package/src/ui/combobox/ComboboxOption.stx +1 -1
  200. package/src/ui/combobox/ComboboxOptions.stx +1 -1
  201. package/src/ui/combobox/README.md +25 -29
  202. package/src/ui/command-palette/CommandPalette.stx +1 -1
  203. package/src/ui/command-palette/CommandPaletteItem.stx +1 -1
  204. package/src/ui/command-palette/README.md +8 -8
  205. package/src/ui/dialog/Dialog.stx +1 -1
  206. package/src/ui/dialog/DialogBackdrop.stx +1 -1
  207. package/src/ui/dialog/DialogDescription.stx +1 -1
  208. package/src/ui/dialog/DialogPanel.stx +1 -1
  209. package/src/ui/dialog/DialogTitle.stx +1 -1
  210. package/src/ui/dialog/README.md +26 -38
  211. package/src/ui/drawer/Drawer.stx +3 -3
  212. package/src/ui/drawer/README.md +13 -33
  213. package/src/ui/dropdown/Dropdown.stx +1 -1
  214. package/src/ui/dropdown/DropdownButton.stx +1 -1
  215. package/src/ui/dropdown/DropdownItem.stx +1 -1
  216. package/src/ui/dropdown/DropdownItems.stx +1 -1
  217. package/src/ui/dropdown/README.md +28 -56
  218. package/src/ui/form/Form.stx +1 -1
  219. package/src/ui/image/Image.stx +1 -1
  220. package/src/ui/image/README.md +45 -52
  221. package/src/ui/input/EmailInput.stx +1 -1
  222. package/src/ui/input/NumberInput.stx +3 -3
  223. package/src/ui/input/PasswordInput.stx +2 -2
  224. package/src/ui/input/SearchInput.stx +1 -1
  225. package/src/ui/input/TextInput.stx +2 -2
  226. package/src/ui/listbox/Listbox.stx +1 -1
  227. package/src/ui/listbox/ListboxButton.stx +1 -1
  228. package/src/ui/listbox/ListboxLabel.stx +1 -1
  229. package/src/ui/listbox/ListboxOption.stx +1 -1
  230. package/src/ui/listbox/ListboxOptions.stx +1 -1
  231. package/src/ui/listbox/README.md +21 -29
  232. package/src/ui/navigator/Navigator.stx +3 -3
  233. package/src/ui/notification/Notification.stx +1 -1
  234. package/src/ui/notification/README.md +28 -32
  235. package/src/ui/pagination/Pagination.stx +6 -6
  236. package/src/ui/payment/Checkout.stx +1 -1
  237. package/src/ui/payment/DefaultPaymentMethod.stx +1 -1
  238. package/src/ui/payment/PaymentMethods.stx +3 -3
  239. package/src/ui/payment/README.md +59 -141
  240. package/src/ui/payment/SubscriptionCheckout.stx +2 -2
  241. package/src/ui/popover/Popover.stx +1 -1
  242. package/src/ui/popover/PopoverButton.stx +1 -1
  243. package/src/ui/popover/PopoverPanel.stx +1 -1
  244. package/src/ui/popover/README.md +10 -14
  245. package/src/ui/portal/Portal.stx +1 -1
  246. package/src/ui/progress/Progress.stx +1 -1
  247. package/src/ui/radio/Radio.stx +1 -1
  248. package/src/ui/radio-group/README.md +29 -35
  249. package/src/ui/radio-group/RadioGroup.stx +1 -1
  250. package/src/ui/radio-group/RadioGroupDescription.stx +1 -1
  251. package/src/ui/radio-group/RadioGroupLabel.stx +1 -1
  252. package/src/ui/radio-group/RadioGroupOption.stx +1 -1
  253. package/src/ui/select/README.md +49 -73
  254. package/src/ui/select/Select.stx +1 -1
  255. package/src/ui/sidebar/Sidebar.stx +1 -1
  256. package/src/ui/sidebar/SidebarFooter.stx +1 -1
  257. package/src/ui/sidebar/SidebarHeader.stx +1 -1
  258. package/src/ui/sidebar/SidebarItem.stx +1 -1
  259. package/src/ui/sidebar/SidebarSection.stx +1 -1
  260. package/src/ui/skeleton/Skeleton.stx +1 -1
  261. package/src/ui/spinner/Spinner.stx +1 -1
  262. package/src/ui/stepper/README.md +8 -8
  263. package/src/ui/stepper/Stepper.stx +1 -1
  264. package/src/ui/stepper/StepperStep.stx +1 -1
  265. package/src/ui/switch/README.md +10 -29
  266. package/src/ui/switch/Switch.stx +1 -1
  267. package/src/ui/table/README.md +17 -17
  268. package/src/ui/table/Table.stx +1 -1
  269. package/src/ui/table/TableBody.stx +1 -1
  270. package/src/ui/table/TableCell.stx +1 -1
  271. package/src/ui/table/TableHead.stx +1 -1
  272. package/src/ui/table/TableHeader.stx +1 -1
  273. package/src/ui/table/TableRow.stx +1 -1
  274. package/src/ui/tabs/Tabs.stx +2 -2
  275. package/src/ui/teleport/Teleport.stx +1 -1
  276. package/src/ui/textarea/Textarea.stx +1 -1
  277. package/src/ui/tooltip/Tooltip.stx +1 -1
  278. package/src/ui/transition/README.md +4 -4
  279. package/src/ui/transition/Transition.stx +1 -1
  280. package/src/ui/video/README.md +7 -8
  281. package/src/ui/video/Video.stx +1 -1
  282. package/src/ui/virtual-list/VirtualList.stx +1 -1
  283. package/src/ui/virtual-table/VirtualTable.stx +1 -1
package/README.md CHANGED
@@ -94,112 +94,71 @@ yarn add @stacksjs/components
94
94
 
95
95
  ## Component Syntax
96
96
 
97
- stx provides multiple ways to use components, giving you flexibility to choose the syntax that best fits your project:
97
+ Both `<Component>` JSX-style tags and `@component('Name', {...})` Blade-style directives work. **The JSX form is preferred** — it's cleaner, matches the rest of the stx ecosystem (`<StxLink>`, `<Icon>`, etc.), and reads like standard HTML.
98
98
 
99
- ### 1. @component Directive with Object Shorthand (Recommended)
100
-
101
- The most concise syntax using ES6 object shorthand:
99
+ ### Static props
102
100
 
103
101
  ```stx
104
- <script>
105
- export const title = 'Welcome'
106
- export const variant = 'primary'
107
- export const onClick = () => console.log('clicked')
108
- </script>
109
-
110
- @component('Button', {
111
- title,
112
- variant,
113
- onClick
114
- })
115
- @endcomponent
102
+ <Button variant="primary" size="lg">Save Changes</Button>
116
103
  ```
117
104
 
118
- ### 2. @component Directive with Full Props
105
+ ### Dynamic props (server-side)
119
106
 
120
- Traditional explicit prop mapping:
107
+ Use `:prop` to bind server-side expressions:
121
108
 
122
109
  ```stx
123
- @component('Button', {
124
- title: title,
125
- variant: variant,
126
- onClick: onClick
127
- })
128
- @endcomponent
129
- ```
110
+ <script server>
111
+ const variant = isAdmin ? 'danger' : 'primary'
112
+ </script>
130
113
 
131
- ### 3. PascalCase Component Tags with Dynamic Binding (Vue-like)
114
+ <Button :variant="variant">Delete</Button>
115
+ ```
132
116
 
133
- Use `:prop` syntax for dynamic values from context:
117
+ ### Self-closing
134
118
 
135
119
  ```stx
136
- <script>
137
- export const title = 'Welcome'
138
- export const variant = 'primary'
139
- </script>
140
-
141
- <Button
142
- :title="title"
143
- :variant="variant"
144
- :onClick="onClick"
145
- />
120
+ <Switch checked label="Enable notifications" />
121
+ <Avatar src="/photo.jpg" alt="Glenn" size="md" />
146
122
  ```
147
123
 
148
- ### 4. PascalCase Component Tags with Static Values
149
-
150
- Use regular attributes for static strings:
124
+ ### Slots
151
125
 
152
126
  ```stx
153
- <Button
154
- title="Welcome"
155
- variant="primary"
156
- />
127
+ <Dialog :open="isOpen" @close="handleClose">
128
+ <DialogBackdrop />
129
+ <DialogPanel className="max-w-md">
130
+ <DialogTitle>Confirm delete</DialogTitle>
131
+ <p>This action cannot be undone.</p>
132
+ </DialogPanel>
133
+ </Dialog>
157
134
  ```
158
135
 
159
- ### 5. Mixed Static and Dynamic Props
136
+ ### Blade-compat alternative
160
137
 
161
- Combine static strings and dynamic bindings:
138
+ The `@component` directive also works if you prefer the Blade style:
162
139
 
163
140
  ```stx
164
- <Button
165
- title="Static Title"
166
- :variant="dynamicVariant"
167
- size="large"
168
- />
141
+ @component('Button', { variant: 'primary' })
142
+ Save Changes
143
+ @endcomponent
169
144
  ```
170
145
 
171
- All these syntaxes are equivalent and fully interchangeable. Choose the one that fits your coding style!
172
-
173
146
  ## Usage
174
147
 
175
148
  ### Basic Example
176
149
 
177
150
  ```stx
178
- <script>
179
- import { Button, Switch } from '@stacksjs/components'
180
-
181
- let notifications = true
182
-
183
- function handleNotificationChange(checked) {
184
- notifications = checked
185
- }
186
-
187
- module.exports = { notifications, handleNotificationChange }
151
+ <script server>
152
+ const notifications = true
188
153
  </script>
189
154
 
190
155
  <div class="p-6">
191
156
  <h1 class="text-2xl font-bold mb-4">Settings</h1>
192
157
 
193
- @component('Switch', {
194
- checked: notifications,
195
- label: 'Enable notifications',
196
- onChange: handleNotificationChange
197
- })
158
+ <Switch :checked="notifications" label="Enable notifications" />
198
159
 
199
160
  <div class="mt-4">
200
- @component('Button', { variant: 'primary' })
201
- Save Changes
202
- @endcomponent
161
+ <Button variant="primary">Save Changes</Button>
203
162
  </div>
204
163
  </div>
205
164
  ```
@@ -207,42 +166,27 @@ module.exports = { notifications, handleNotificationChange }
207
166
  ### With Code Highlighting
208
167
 
209
168
  ```stx
210
- <script>
211
- import { CodeBlock } from '@stacksjs/components'
212
-
169
+ <script server>
213
170
  const code = `
214
171
  function greet(name: string) {
215
172
  console.log(\`Hello, \${name}!\`)
216
173
  }
217
174
  `
218
-
219
- module.exports = { code }
220
175
  </script>
221
176
 
222
- @component('CodeBlock', {
223
- code: code,
224
- language: 'typescript',
225
- copyable: true
226
- })
177
+ <CodeBlock :code="code" language="typescript" copyable />
227
178
  ```
228
179
 
229
180
  ### Using Composables
230
181
 
231
182
  ```stx
232
- <script>
233
- import { useDarkMode, useCopyCode } from '@stacksjs/components'
234
-
183
+ <script client>
235
184
  const { isDark, toggle } = useDarkMode()
236
-
237
- module.exports = { isDark, toggle }
238
185
  </script>
239
186
 
240
- <button @click="toggle">
241
- @if(isDark)
242
- Switch to Light Mode
243
- @else
244
- Switch to Dark Mode
245
- @endif
187
+ <button @click="toggle()">
188
+ <span :if="isDark()">Switch to Light Mode</span>
189
+ <span :if="!isDark()">Switch to Dark Mode</span>
246
190
  </button>
247
191
  ```
248
192
 
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const items = $props.items || []
3
3
  export const allowMultiple = $props.allowMultiple || false
4
4
  export const defaultOpen = $props.defaultOpen || []
@@ -49,7 +49,7 @@ export const contentClasses = `px-4 py-3 text-gray-700 dark:text-gray-300`.trim(
49
49
  <button
50
50
  type="button"
51
51
  class="{{ headerClasses }}"
52
- onclick="toggleItem({{ $loop.index }})"
52
+ @click="toggleItem({{ $loop.index }})"
53
53
  aria-expanded="{{ isOpen($loop.index) ? 'true' : 'false' }}"
54
54
  aria-controls="accordion-content-{{ $loop.index }}"
55
55
  >
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const src = $props.src || ''
3
3
  export const autoplay = $props.autoplay || false
4
4
  export const loop = $props.loop || false
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const src = $props.src || ''
3
3
  export const alt = $props.alt || ''
4
4
  export const initials = $props.initials || ''
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const variant = $props.variant || 'default'
3
3
  export const size = $props.size || 'md'
4
4
  export const dot = $props.dot || false
@@ -50,7 +50,7 @@ export const removeButtonClasses = `ml-0.5 -mr-1 text-current hover:bg-black hov
50
50
  @if(removable && onRemove)
51
51
  <button
52
52
  type="button"
53
- onclick="handleRemove()"
53
+ @click="handleRemove()"
54
54
  class="{{ removeButtonClasses }}"
55
55
  aria-label="Remove"
56
56
  >
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const items = $props.items || []
3
3
  export const separator = $props.separator || '/'
4
4
  export const maxItems = $props.maxItems || 0
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const variant = $props.variant || 'primary'
3
3
  export const size = $props.size || 'md'
4
4
  export const disabled = $props.disabled || false
@@ -56,7 +56,7 @@ export const spinnerClasses = `animate-spin ${iconClasses}`.trim()
56
56
  type="{{ type }}"
57
57
  class="{{ buttonClasses }}"
58
58
  @if(isDisabled)disabled@endif
59
- @if(onClick)onclick="handleClick(event)"@endif
59
+ @if(onClick)@click="handleClick(event)"@endif
60
60
  aria-busy="{{ loading ? 'true' : 'false' }}"
61
61
  >
62
62
  @if(loading)
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  // Calendar Component Props
3
3
  export const value = $props.value || new Date()
4
4
  export const onChange = $props.onChange
@@ -170,7 +170,7 @@ const calendarDays = getCalendarDays()
170
170
  <button
171
171
  type="button"
172
172
  class="{{ buttonClasses }}"
173
- onclick="previousMonth()"
173
+ @click="previousMonth()"
174
174
  aria-label="Previous month"
175
175
  >
176
176
  <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -185,7 +185,7 @@ const calendarDays = getCalendarDays()
185
185
  <button
186
186
  type="button"
187
187
  class="{{ buttonClasses }}"
188
- onclick="nextMonth()"
188
+ @click="nextMonth()"
189
189
  aria-label="Next month"
190
190
  >
191
191
  <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -207,7 +207,7 @@ const calendarDays = getCalendarDays()
207
207
  <button
208
208
  type="button"
209
209
  class="{{ getDayClasses(day) }}"
210
- onclick="selectDate(day.date)"
210
+ @click="selectDate(day.date)"
211
211
  aria-label="{{ day.date.toLocaleDateString(locale) }}"
212
212
  @if(isDisabled(day.date))
213
213
  disabled
@@ -223,7 +223,7 @@ const calendarDays = getCalendarDays()
223
223
  <button
224
224
  type="button"
225
225
  class="px-4 py-2 text-sm font-medium text-blue-600 dark:text-blue-400 hover:bg-blue-50 dark:hover:bg-gray-700 rounded-md transition-colors"
226
- onclick="goToToday()"
226
+ @click="goToToday()"
227
227
  >
228
228
  Today
229
229
  </button>
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const variant = $props.variant || 'default'
3
3
  export const padding = $props.padding || 'default'
4
4
  export const hover = $props.hover || false
@@ -37,7 +37,7 @@ export const contentClasses = `${image ? paddingClasses[padding] : ''}`.trim()
37
37
  </script>
38
38
 
39
39
  @if(onClick)
40
- <div class="{{ cardClasses }}" onclick="handleClick(event)" role="button" tabindex="0" onkeydown="handleKeyDown(event)">
40
+ <div class="{{ cardClasses }}" @click="handleClick(event)" role="button" tabindex="0" onkeydown="handleKeyDown(event)">
41
41
  @if(image)
42
42
  <img src="{{ image }}" alt="{{ imageAlt }}" class="{{ imageClasses }}" />
43
43
  @endif
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const checked = $props.checked || false
3
3
  export const onChange = $props.onChange || (() => {})
4
4
  export const disabled = $props.disabled || false
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const products = $props.products || []
3
3
  export const redirectUrl = $props.redirectUrl || ''
4
4
  export const mode = $props.mode || 'subscription'
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const value = $props.value
3
3
  export const onChange = $props.onChange
4
4
  export const className = $props.className || ''
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const className = $props.className || ''
3
3
  export const as = $props.as || 'button'
4
4
 
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const displayValue = $props.displayValue
3
3
  export const onChange = $props.onChange
4
4
  export const className = $props.className || ''
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const value = $props.value
3
3
  export const disabled = $props.disabled || false
4
4
  export const className = $props.className || ''
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const className = $props.className || ''
3
3
  export const as = $props.as || 'ul'
4
4
  export const static_ = $props.static || false
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const open = $props.open || false
3
3
  export const onClose = $props.onClose
4
4
  export const query = $props.query || ''
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const className = $props.className || ''
3
3
  export const onClick = $props.onClick
4
4
  export let active = false
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const paymentMethod = $props.paymentMethod
3
3
  export const isLoading = $props.isLoading || false
4
4
  export const className = $props.className || ''
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const open = $props.open || false
3
3
  export const onClose = $props.onClose
4
4
  export const className = $props.className || ''
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const className = $props.className || ''
3
3
  export const as = $props.as || 'div'
4
4
 
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const className = $props.className || ''
3
3
  export const as = $props.as || 'p'
4
4
 
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const className = $props.className || ''
3
3
  export const as = $props.as || 'div'
4
4
 
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const className = $props.className || ''
3
3
  export const as = $props.as || 'h3'
4
4
 
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const open = $props.open ?? false
3
3
  export const onClose = $props.onClose || (() => {})
4
4
  export const position = $props.position || 'right'
@@ -60,7 +60,7 @@ export const closeButtonClasses = `absolute top-0 ${closeButtonPosition[position
60
60
  <div
61
61
  class="fixed inset-0 z-50 bg-gray-500/75 dark:bg-gray-900/75 transition-opacity duration-500"
62
62
  style="animation: fadeIn 0.5s ease-in-out"
63
- onclick="handleBackdropClick()"
63
+ @click="handleBackdropClick()"
64
64
  ></div>
65
65
 
66
66
  <!-- Drawer Container -->
@@ -77,7 +77,7 @@ export const closeButtonClasses = `absolute top-0 ${closeButtonPosition[position
77
77
  <button
78
78
  type="button"
79
79
  class="relative rounded-md text-gray-300 dark:text-gray-400 hover:text-white dark:hover:text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
80
- onclick="handleClose()"
80
+ @click="handleClose()"
81
81
  >
82
82
  <span class="absolute -inset-2.5"></span>
83
83
  <span class="sr-only">Close panel</span>
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const className = $props.className || ''
3
3
  export const as = $props.as || 'div'
4
4
  export let isOpen = false
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const className = $props.className || ''
3
3
  export const as = $props.as || 'button'
4
4
  export const disabled = $props.disabled || false
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const className = $props.className || ''
3
3
  export const as = $props.as || 'div'
4
4
  export const disabled = $props.disabled || false
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const className = $props.className || ''
3
3
  export const as = $props.as || 'div'
4
4
  export const static_ = $props.static || false
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const value = $props.value || ''
3
3
  export const onChange = $props.onChange || (() => {})
4
4
  export const placeholder = $props.placeholder || 'Enter your email'
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const action = $props.action || ''
3
3
  export const method = $props.method || 'POST'
4
4
  export const validationSchema = $props.validationSchema || {}
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const src = $props.src || ''
3
3
  export const srcSet = $props.srcSet || ''
4
4
  export const sizes = $props.sizes || ''
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const value = $props.value
3
3
  export const onChange = $props.onChange
4
4
  export const multiple = $props.multiple || false
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const className = $props.className || ''
3
3
  export const as = $props.as || 'button'
4
4
  export const disabled = $props.disabled || false
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const className = $props.className || ''
3
3
  export const as = $props.as || 'label'
4
4
 
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const value = $props.value
3
3
  export const disabled = $props.disabled || false
4
4
  export const className = $props.className || ''
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const className = $props.className || ''
3
3
  export const as = $props.as || 'ul'
4
4
  export const static_ = $props.static || false
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const showLogo = $props.showLogo ?? true
3
3
  export const headingText = $props.headingText || 'Sign in to your account'
4
4
  export const showSocialLogin = $props.showSocialLogin ?? true
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  // Navigator Component Props
3
3
  export const items = $props.items || []
4
4
  export const active = $props.active || ''
@@ -94,7 +94,7 @@ function handleClick(item, event) {
94
94
  <a
95
95
  href="{{ item.href }}"
96
96
  class="{{ getItemClasses(item) }}"
97
- onclick="handleClick(item, event)"
97
+ @click="handleClick(item, event)"
98
98
  @if(isActive(item))
99
99
  aria-current="page"
100
100
  @endif
@@ -117,7 +117,7 @@ function handleClick(item, event) {
117
117
  <button
118
118
  type="button"
119
119
  class="{{ getItemClasses(item) }}"
120
- onclick="handleClick(item, event)"
120
+ @click="handleClick(item, event)"
121
121
  @if(item.disabled)
122
122
  disabled
123
123
  aria-disabled="true"
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const show = $props.show !== false
3
3
  export const title = $props.title || ''
4
4
  export const message = $props.message || ''
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const value = $props.value || ''
3
3
  export const onChange = $props.onChange || (() => {})
4
4
  export const placeholder = $props.placeholder || '0'
@@ -76,7 +76,7 @@ export const helperClasses = `mt-2 text-sm ${error ? 'text-red-600 dark:text-red
76
76
  <div class="absolute inset-y-0 right-0 flex flex-col">
77
77
  <button
78
78
  type="button"
79
- onclick="handleIncrement()"
79
+ @click="handleIncrement()"
80
80
  class="flex items-center justify-center w-8 h-1/2 text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300 focus:outline-none border-b border-gray-300 dark:border-gray-600"
81
81
  aria-label="Increment"
82
82
  >
@@ -86,7 +86,7 @@ export const helperClasses = `mt-2 text-sm ${error ? 'text-red-600 dark:text-red
86
86
  </button>
87
87
  <button
88
88
  type="button"
89
- onclick="handleDecrement()"
89
+ @click="handleDecrement()"
90
90
  class="flex items-center justify-center w-8 h-1/2 text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300 focus:outline-none"
91
91
  aria-label="Decrement"
92
92
  >
@@ -1,4 +1,4 @@
1
- <script>
1
+ <script server>
2
2
  export const currentPage = $props.currentPage || 1
3
3
  export const totalPages = $props.totalPages || 1
4
4
  export const siblingCount = $props.siblingCount || 1
@@ -94,7 +94,7 @@ export const iconClasses = `w-5 h-5`.trim()
94
94
  @if(showFirstLast)
95
95
  <button
96
96
  type="button"
97
- onclick="goToFirst()"
97
+ @click="goToFirst()"
98
98
  class="{{ buttonClasses }}"
99
99
  aria-label="Go to first page"
100
100
  disabled="{{ currentPage === 1 }}"
@@ -109,7 +109,7 @@ export const iconClasses = `w-5 h-5`.trim()
109
109
  @if(showPrevNext)
110
110
  <button
111
111
  type="button"
112
- onclick="goToPrevious()"
112
+ @click="goToPrevious()"
113
113
  class="{{ buttonClasses }}"
114
114
  aria-label="Go to previous page"
115
115
  disabled="{{ currentPage === 1 }}"
@@ -141,7 +141,7 @@ export const iconClasses = `w-5 h-5`.trim()
141
141
  <!-- Other pages -->
142
142
  <button
143
143
  type="button"
144
- onclick="goToPage({{ page }})"
144
+ @click="goToPage({{ page }})"
145
145
  class="{{ buttonClasses }}"
146
146
  aria-label="Go to page {{ page }}"
147
147
  >
@@ -155,7 +155,7 @@ export const iconClasses = `w-5 h-5`.trim()
155
155
  @if(showPrevNext)
156
156
  <button
157
157
  type="button"
158
- onclick="goToNext()"
158
+ @click="goToNext()"
159
159
  class="{{ buttonClasses }}"
160
160
  aria-label="Go to next page"
161
161
  disabled="{{ currentPage === totalPages }}"
@@ -170,7 +170,7 @@ export const iconClasses = `w-5 h-5`.trim()
170
170
  @if(showFirstLast)
171
171
  <button
172
172
  type="button"
173
- onclick="goToLast()"
173
+ @click="goToLast()"
174
174
  class="{{ buttonClasses }}"
175
175
  aria-label="Go to last page"
176
176
  disabled="{{ currentPage === totalPages }}"