@stacksjs/components 0.2.3

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 (342) hide show
  1. package/README.md +477 -0
  2. package/dist/Accordion-x2gjedap.stx +108 -0
  3. package/dist/Audio-0fk6p9tn.stx +50 -0
  4. package/dist/Avatar-5m0v0s4x.stx +88 -0
  5. package/dist/Badge-ynes82vv.stx +70 -0
  6. package/dist/Breadcrumb-h9n427sk.stx +79 -0
  7. package/dist/Button-7xtrzn14.stx +89 -0
  8. package/dist/Calendar-egvx1pma.stx +232 -0
  9. package/dist/Card-r9w7vy1a.stx +74 -0
  10. package/dist/Checkbox-m8v46pmx.stx +92 -0
  11. package/dist/Checkout-vcnnr176.stx +39 -0
  12. package/dist/CodeBlock-mwex82cm.stx +57 -0
  13. package/dist/Combobox-npb08vkp.stx +13 -0
  14. package/dist/ComboboxButton-vcdyq4zw.stx +13 -0
  15. package/dist/ComboboxInput-c9d2p02m.stx +25 -0
  16. package/dist/ComboboxOption-7d0h9ash.stx +52 -0
  17. package/dist/ComboboxOptions-4dtqc0qa.stx +12 -0
  18. package/dist/CommandPalette-ah00bf8v.stx +39 -0
  19. package/dist/CommandPaletteItem-2yx0gvtj.stx +32 -0
  20. package/dist/DefaultPaymentMethod-emw5fg8s.stx +62 -0
  21. package/dist/Dialog-1w4rz7x0.stx +19 -0
  22. package/dist/DialogBackdrop-qbm3y5ab.stx +9 -0
  23. package/dist/DialogDescription-01w5j74b.stx +11 -0
  24. package/dist/DialogPanel-brsszrrs.stx +16 -0
  25. package/dist/DialogTitle-3rxhwg21.stx +11 -0
  26. package/dist/Drawer-yfaz8q7f.stx +137 -0
  27. package/dist/Dropdown-ng7nx556.stx +24 -0
  28. package/dist/DropdownButton-vc4zpyrb.stx +23 -0
  29. package/dist/DropdownItem-z491y23c.stx +43 -0
  30. package/dist/DropdownItems-7ykf29sj.stx +18 -0
  31. package/dist/EmailInput-bfshpj92.stx +41 -0
  32. package/dist/Footer-xdaf02nr.stx +66 -0
  33. package/dist/Form-z4f7w6r1.stx +209 -0
  34. package/dist/Hero-9vvp7pxf.stx +25 -0
  35. package/dist/Image-ktk0451c.stx +197 -0
  36. package/dist/Installation-33bj4rm7.stx +39 -0
  37. package/dist/Listbox-xcejcmyc.stx +14 -0
  38. package/dist/ListboxButton-nx5kmw19.stx +17 -0
  39. package/dist/ListboxLabel-aky8a73n.stx +11 -0
  40. package/dist/ListboxOption-6h4hsdz5.stx +57 -0
  41. package/dist/ListboxOptions-2sacdtm5.stx +16 -0
  42. package/dist/Login-s2jkvd9y.stx +163 -0
  43. package/dist/Navigator-tqqdgdkw.stx +138 -0
  44. package/dist/Notification-sry8egea.stx +71 -0
  45. package/dist/NumberInput-zm93ddfw.stx +138 -0
  46. package/dist/Pagination-yza9v4qw.stx +183 -0
  47. package/dist/PasswordInput-4xnndp5y.stx +155 -0
  48. package/dist/PaymentMethods-jxba6kek.stx +113 -0
  49. package/dist/Popover-scbqatjq.stx +24 -0
  50. package/dist/PopoverButton-rbxhzj4k.stx +23 -0
  51. package/dist/PopoverPanel-9ng1rm6e.stx +23 -0
  52. package/dist/Portal-j111yvqp.stx +74 -0
  53. package/dist/Progress-gbmw3akr.stx +142 -0
  54. package/dist/Radio-1n9qamv1.stx +81 -0
  55. package/dist/RadioGroup-12dw2vhk.stx +13 -0
  56. package/dist/RadioGroupDescription-bjm3mdht.stx +11 -0
  57. package/dist/RadioGroupLabel-aky8a73n.stx +11 -0
  58. package/dist/RadioGroupOption-9pcxgwmd.stx +51 -0
  59. package/dist/SearchInput-g240e2nq.stx +63 -0
  60. package/dist/Select-p9f94b20.stx +89 -0
  61. package/dist/Sidebar-gwxw8q38.stx +288 -0
  62. package/dist/SidebarFooter-887kxret.stx +95 -0
  63. package/dist/SidebarHeader-qjeyx0hv.stx +100 -0
  64. package/dist/SidebarItem-4dpwtmb4.stx +118 -0
  65. package/dist/SidebarSection-kh92fk4m.stx +108 -0
  66. package/dist/Signup-3nxq5zag.stx +161 -0
  67. package/dist/Skeleton-g0nx1njm.stx +48 -0
  68. package/dist/Spinner-w4zj58xp.stx +109 -0
  69. package/dist/Stepper-rwc5actp.stx +17 -0
  70. package/dist/StepperStep-h0k657nm.stx +53 -0
  71. package/dist/SubscriptionCheckout-4cbxdg7w.stx +353 -0
  72. package/dist/Switch-kjq8qd2p.stx +74 -0
  73. package/dist/Table-59j9qwp0.stx +14 -0
  74. package/dist/TableBody-reka2gwv.stx +10 -0
  75. package/dist/TableCell-j7nh4sgr.stx +10 -0
  76. package/dist/TableHead-ecbrwpqm.stx +10 -0
  77. package/dist/TableHeader-jn2shwsv.stx +13 -0
  78. package/dist/TableRow-xz8rrxhc.stx +11 -0
  79. package/dist/Tabs-kb6ex6m7.stx +145 -0
  80. package/dist/Teleport-819cg9zm.stx +101 -0
  81. package/dist/TextInput-zx9kgr79.stx +146 -0
  82. package/dist/Textarea-5xvmrb0z.stx +119 -0
  83. package/dist/Tooltip-5ehqsy49.stx +76 -0
  84. package/dist/Transition-2j39s044.stx +174 -0
  85. package/dist/TwoFactorChallenge-2q4gg89m.stx +125 -0
  86. package/dist/Video-6aq4shh4.stx +45 -0
  87. package/dist/VirtualList-weh5qtm1.stx +83 -0
  88. package/dist/VirtualTable-59a1eskc.stx +113 -0
  89. package/dist/components/index.d.ts +4 -0
  90. package/dist/composables/index.d.ts +4 -0
  91. package/dist/composables/index.js +3 -0
  92. package/dist/composables/useCopyCode.d.ts +19 -0
  93. package/dist/composables/useDarkMode.d.ts +25 -0
  94. package/dist/composables/useSEO.d.ts +36 -0
  95. package/dist/composables/utilities/index.d.ts +5 -0
  96. package/dist/composables/utilities/useClickOutside.d.ts +28 -0
  97. package/dist/composables/utilities/useFocusTrap.d.ts +34 -0
  98. package/dist/composables/utilities/useKeyboard.d.ts +55 -0
  99. package/dist/composables/utilities/useLocalStorage.d.ts +33 -0
  100. package/dist/composables/utilities/useMediaQuery.d.ts +64 -0
  101. package/dist/index.d.ts +86 -0
  102. package/dist/index.js +19 -0
  103. package/dist/ui/accordion/index.d.ts +12 -0
  104. package/dist/ui/audio/index.d.ts +12 -0
  105. package/dist/ui/auth/index.d.ts +29 -0
  106. package/dist/ui/avatar/index.d.ts +11 -0
  107. package/dist/ui/badge/index.d.ts +9 -0
  108. package/dist/ui/breadcrumb/index.d.ts +13 -0
  109. package/dist/ui/button/index.d.ts +45 -0
  110. package/dist/ui/calendar/index.d.ts +13 -0
  111. package/dist/ui/card/index.d.ts +12 -0
  112. package/dist/ui/checkbox/index.d.ts +15 -0
  113. package/dist/ui/combobox/index.d.ts +35 -0
  114. package/dist/ui/command-palette/index.d.ts +13 -0
  115. package/dist/ui/dialog/index.d.ts +27 -0
  116. package/dist/ui/drawer/index.d.ts +8 -0
  117. package/dist/ui/dropdown/index.d.ts +25 -0
  118. package/dist/ui/form/index.d.ts +48 -0
  119. package/dist/ui/image/index.d.ts +21 -0
  120. package/dist/ui/input/index.d.ts +73 -0
  121. package/dist/ui/listbox/index.d.ts +34 -0
  122. package/dist/ui/navigator/index.d.ts +18 -0
  123. package/dist/ui/notification/index.d.ts +11 -0
  124. package/dist/ui/pagination/index.d.ts +10 -0
  125. package/dist/ui/payment/index.d.ts +53 -0
  126. package/dist/ui/popover/index.d.ts +19 -0
  127. package/dist/ui/portal/index.d.ts +5 -0
  128. package/dist/ui/progress/index.d.ts +11 -0
  129. package/dist/ui/radio/index.d.ts +14 -0
  130. package/dist/ui/radio-group/index.d.ts +26 -0
  131. package/dist/ui/select/index.d.ts +19 -0
  132. package/dist/ui/sidebar/index.d.ts +129 -0
  133. package/dist/ui/skeleton/index.d.ts +10 -0
  134. package/dist/ui/spinner/index.d.ts +8 -0
  135. package/dist/ui/stepper/index.d.ts +17 -0
  136. package/dist/ui/storage/index.d.ts +40 -0
  137. package/dist/ui/switch/index.d.ts +9 -0
  138. package/dist/ui/table/index.d.ts +29 -0
  139. package/dist/ui/tabs/index.d.ts +14 -0
  140. package/dist/ui/teleport/index.d.ts +6 -0
  141. package/dist/ui/textarea/index.d.ts +19 -0
  142. package/dist/ui/tooltip/index.d.ts +9 -0
  143. package/dist/ui/transition/index.d.ts +24 -0
  144. package/dist/ui/video/index.d.ts +15 -0
  145. package/dist/ui/virtual-list/index.d.ts +9 -0
  146. package/dist/ui/virtual-table/index.d.ts +19 -0
  147. package/dist/utils/accessibility.d.ts +285 -0
  148. package/dist/utils/animation/easing.d.ts +112 -0
  149. package/dist/utils/animation/helpers.d.ts +119 -0
  150. package/dist/utils/animation/index.d.ts +3 -0
  151. package/dist/utils/animation/keyframes.d.ts +334 -0
  152. package/dist/utils/error-handling.d.ts +182 -0
  153. package/dist/utils/highlighter.d.ts +27 -0
  154. package/dist/utils/highlighter.js +2 -0
  155. package/dist/utils/i18n.d.ts +245 -0
  156. package/dist/utils/keep-alive.d.ts +171 -0
  157. package/dist/utils/lazy-loading.d.ts +174 -0
  158. package/dist/utils/prop-validation.d.ts +106 -0
  159. package/dist/utils/theme.d.ts +234 -0
  160. package/package.json +69 -0
  161. package/src/components/CodeBlock.stx +57 -0
  162. package/src/components/Footer.stx +66 -0
  163. package/src/components/Hero.stx +25 -0
  164. package/src/components/Installation.stx +39 -0
  165. package/src/components/index.ts +4 -0
  166. package/src/composables/index.ts +4 -0
  167. package/src/composables/useCopyCode.ts +73 -0
  168. package/src/composables/useDarkMode.ts +100 -0
  169. package/src/composables/useSEO.ts +229 -0
  170. package/src/composables/utilities/index.ts +7 -0
  171. package/src/composables/utilities/useClickOutside.ts +72 -0
  172. package/src/composables/utilities/useFocusTrap.ts +159 -0
  173. package/src/composables/utilities/useKeyboard.ts +124 -0
  174. package/src/composables/utilities/useLocalStorage.ts +132 -0
  175. package/src/composables/utilities/useMediaQuery.ts +118 -0
  176. package/src/index.ts +99 -0
  177. package/src/stx.d.ts +4 -0
  178. package/src/ui/accordion/Accordion.stx +108 -0
  179. package/src/ui/accordion/index.ts +14 -0
  180. package/src/ui/audio/Audio.stx +50 -0
  181. package/src/ui/audio/README.md +42 -0
  182. package/src/ui/audio/index.ts +13 -0
  183. package/src/ui/auth/Login.stx +163 -0
  184. package/src/ui/auth/README.md +145 -0
  185. package/src/ui/auth/Signup.stx +161 -0
  186. package/src/ui/auth/TwoFactorChallenge.stx +125 -0
  187. package/src/ui/auth/index.ts +32 -0
  188. package/src/ui/avatar/Avatar.stx +88 -0
  189. package/src/ui/avatar/index.ts +12 -0
  190. package/src/ui/badge/Badge.stx +70 -0
  191. package/src/ui/badge/index.ts +10 -0
  192. package/src/ui/breadcrumb/Breadcrumb.stx +79 -0
  193. package/src/ui/breadcrumb/index.ts +15 -0
  194. package/src/ui/button/Button.stx +89 -0
  195. package/src/ui/button/README.md +100 -0
  196. package/src/ui/button/index.ts +85 -0
  197. package/src/ui/calendar/Calendar.stx +232 -0
  198. package/src/ui/calendar/README.md +254 -0
  199. package/src/ui/calendar/index.ts +14 -0
  200. package/src/ui/card/Card.stx +74 -0
  201. package/src/ui/card/index.ts +13 -0
  202. package/src/ui/checkbox/Checkbox.stx +92 -0
  203. package/src/ui/checkbox/index.ts +16 -0
  204. package/src/ui/combobox/Combobox.stx +13 -0
  205. package/src/ui/combobox/ComboboxButton.stx +13 -0
  206. package/src/ui/combobox/ComboboxInput.stx +25 -0
  207. package/src/ui/combobox/ComboboxOption.stx +52 -0
  208. package/src/ui/combobox/ComboboxOptions.stx +12 -0
  209. package/src/ui/combobox/README.md +154 -0
  210. package/src/ui/combobox/index.ts +40 -0
  211. package/src/ui/command-palette/CommandPalette.stx +39 -0
  212. package/src/ui/command-palette/CommandPaletteItem.stx +32 -0
  213. package/src/ui/command-palette/README.md +42 -0
  214. package/src/ui/command-palette/index.ts +15 -0
  215. package/src/ui/dialog/Dialog.stx +19 -0
  216. package/src/ui/dialog/DialogBackdrop.stx +9 -0
  217. package/src/ui/dialog/DialogDescription.stx +11 -0
  218. package/src/ui/dialog/DialogPanel.stx +16 -0
  219. package/src/ui/dialog/DialogTitle.stx +11 -0
  220. package/src/ui/dialog/README.md +133 -0
  221. package/src/ui/dialog/index.ts +32 -0
  222. package/src/ui/drawer/Drawer.stx +137 -0
  223. package/src/ui/drawer/README.md +110 -0
  224. package/src/ui/drawer/index.ts +9 -0
  225. package/src/ui/dropdown/Dropdown.stx +24 -0
  226. package/src/ui/dropdown/DropdownButton.stx +23 -0
  227. package/src/ui/dropdown/DropdownItem.stx +43 -0
  228. package/src/ui/dropdown/DropdownItems.stx +18 -0
  229. package/src/ui/dropdown/README.md +142 -0
  230. package/src/ui/dropdown/index.ts +29 -0
  231. package/src/ui/form/Form.stx +209 -0
  232. package/src/ui/form/index.ts +67 -0
  233. package/src/ui/heatmap/Heatmap.stx +315 -0
  234. package/src/ui/image/Image.stx +197 -0
  235. package/src/ui/image/README.md +171 -0
  236. package/src/ui/image/index.ts +22 -0
  237. package/src/ui/input/EmailInput.stx +41 -0
  238. package/src/ui/input/NumberInput.stx +138 -0
  239. package/src/ui/input/PasswordInput.stx +155 -0
  240. package/src/ui/input/SearchInput.stx +63 -0
  241. package/src/ui/input/TextInput.stx +146 -0
  242. package/src/ui/input/index.ts +180 -0
  243. package/src/ui/listbox/Listbox.stx +14 -0
  244. package/src/ui/listbox/ListboxButton.stx +17 -0
  245. package/src/ui/listbox/ListboxLabel.stx +11 -0
  246. package/src/ui/listbox/ListboxOption.stx +57 -0
  247. package/src/ui/listbox/ListboxOptions.stx +16 -0
  248. package/src/ui/listbox/README.md +143 -0
  249. package/src/ui/listbox/index.ts +39 -0
  250. package/src/ui/navigator/Navigator.stx +138 -0
  251. package/src/ui/navigator/README.md +352 -0
  252. package/src/ui/navigator/index.ts +20 -0
  253. package/src/ui/notification/Notification.stx +71 -0
  254. package/src/ui/notification/README.md +118 -0
  255. package/src/ui/notification/index.ts +12 -0
  256. package/src/ui/pagination/Pagination.stx +183 -0
  257. package/src/ui/pagination/index.ts +11 -0
  258. package/src/ui/payment/Checkout.stx +39 -0
  259. package/src/ui/payment/DefaultPaymentMethod.stx +62 -0
  260. package/src/ui/payment/PaymentMethods.stx +113 -0
  261. package/src/ui/payment/README.md +427 -0
  262. package/src/ui/payment/SubscriptionCheckout.stx +353 -0
  263. package/src/ui/payment/index.ts +59 -0
  264. package/src/ui/popover/Popover.stx +24 -0
  265. package/src/ui/popover/PopoverButton.stx +23 -0
  266. package/src/ui/popover/PopoverPanel.stx +23 -0
  267. package/src/ui/popover/README.md +95 -0
  268. package/src/ui/popover/index.ts +22 -0
  269. package/src/ui/portal/Portal.stx +74 -0
  270. package/src/ui/portal/index.ts +6 -0
  271. package/src/ui/progress/Progress.stx +142 -0
  272. package/src/ui/progress/index.ts +12 -0
  273. package/src/ui/radio/Radio.stx +81 -0
  274. package/src/ui/radio/index.ts +15 -0
  275. package/src/ui/radio-group/README.md +145 -0
  276. package/src/ui/radio-group/RadioGroup.stx +13 -0
  277. package/src/ui/radio-group/RadioGroupDescription.stx +11 -0
  278. package/src/ui/radio-group/RadioGroupLabel.stx +11 -0
  279. package/src/ui/radio-group/RadioGroupOption.stx +51 -0
  280. package/src/ui/radio-group/index.ts +30 -0
  281. package/src/ui/select/README.md +204 -0
  282. package/src/ui/select/Select.stx +89 -0
  283. package/src/ui/select/index.ts +21 -0
  284. package/src/ui/sidebar/Sidebar.stx +288 -0
  285. package/src/ui/sidebar/SidebarFooter.stx +95 -0
  286. package/src/ui/sidebar/SidebarHeader.stx +100 -0
  287. package/src/ui/sidebar/SidebarItem.stx +118 -0
  288. package/src/ui/sidebar/SidebarSection.stx +108 -0
  289. package/src/ui/sidebar/index.ts +175 -0
  290. package/src/ui/skeleton/Skeleton.stx +48 -0
  291. package/src/ui/skeleton/index.ts +11 -0
  292. package/src/ui/spinner/Spinner.stx +109 -0
  293. package/src/ui/spinner/index.ts +9 -0
  294. package/src/ui/stepper/README.md +36 -0
  295. package/src/ui/stepper/Stepper.stx +17 -0
  296. package/src/ui/stepper/StepperStep.stx +53 -0
  297. package/src/ui/stepper/index.ts +19 -0
  298. package/src/ui/storage/README.md +193 -0
  299. package/src/ui/storage/index.ts +347 -0
  300. package/src/ui/switch/README.md +133 -0
  301. package/src/ui/switch/Switch.stx +74 -0
  302. package/src/ui/switch/index.ts +10 -0
  303. package/src/ui/table/README.md +39 -0
  304. package/src/ui/table/Table.stx +14 -0
  305. package/src/ui/table/TableBody.stx +10 -0
  306. package/src/ui/table/TableCell.stx +10 -0
  307. package/src/ui/table/TableHead.stx +10 -0
  308. package/src/ui/table/TableHeader.stx +13 -0
  309. package/src/ui/table/TableRow.stx +11 -0
  310. package/src/ui/table/index.ts +35 -0
  311. package/src/ui/tabs/Tabs.stx +145 -0
  312. package/src/ui/tabs/index.ts +16 -0
  313. package/src/ui/teleport/Teleport.stx +101 -0
  314. package/src/ui/teleport/index.ts +7 -0
  315. package/src/ui/textarea/Textarea.stx +119 -0
  316. package/src/ui/textarea/index.ts +20 -0
  317. package/src/ui/tooltip/Tooltip.stx +76 -0
  318. package/src/ui/tooltip/index.ts +10 -0
  319. package/src/ui/transition/README.md +30 -0
  320. package/src/ui/transition/Transition.stx +174 -0
  321. package/src/ui/transition/index.ts +25 -0
  322. package/src/ui/video/README.md +48 -0
  323. package/src/ui/video/Video.stx +45 -0
  324. package/src/ui/video/index.ts +16 -0
  325. package/src/ui/virtual-list/VirtualList.stx +83 -0
  326. package/src/ui/virtual-list/index.ts +10 -0
  327. package/src/ui/virtual-table/VirtualTable.stx +113 -0
  328. package/src/ui/virtual-table/index.ts +21 -0
  329. package/src/utils/PROP_VALIDATION.md +458 -0
  330. package/src/utils/THEME_SYSTEM.md +702 -0
  331. package/src/utils/accessibility.ts +841 -0
  332. package/src/utils/animation/easing.ts +368 -0
  333. package/src/utils/animation/helpers.ts +223 -0
  334. package/src/utils/animation/index.ts +5 -0
  335. package/src/utils/animation/keyframes.ts +230 -0
  336. package/src/utils/error-handling.ts +473 -0
  337. package/src/utils/highlighter.ts +93 -0
  338. package/src/utils/i18n.ts +634 -0
  339. package/src/utils/keep-alive.ts +818 -0
  340. package/src/utils/lazy-loading.ts +530 -0
  341. package/src/utils/prop-validation.ts +478 -0
  342. package/src/utils/theme.ts +626 -0
@@ -0,0 +1,13 @@
1
+ <script>
2
+ export const value = $props.value
3
+ export const onChange = $props.onChange
4
+ export const className = $props.className || ''
5
+ export const as = $props.as || 'div'
6
+
7
+ const baseClasses = 'relative'
8
+ const comboboxClasses = `${baseClasses} ${className}`.trim()
9
+ </script>
10
+
11
+ <component :is="{{ as }}" class="{{ comboboxClasses }}">
12
+ <slot :value="value" :onChange="onChange" />
13
+ </component>
@@ -0,0 +1,13 @@
1
+ <script>
2
+ export const className = $props.className || ''
3
+ export const as = $props.as || 'button'
4
+
5
+ const baseClasses = 'absolute inset-y-0 right-0 flex items-center pr-2'
6
+ const buttonClasses = `${baseClasses} ${className}`.trim()
7
+ </script>
8
+
9
+ <component :is="{{ as }}" class="{{ buttonClasses }}" tabindex="-1">
10
+ <svg class="h-5 w-5 text-neutral-400" viewBox="0 0 20 20" fill="none" stroke="currentColor">
11
+ <path d="M7 7l3-3 3 3m0 6l-3 3-3-3" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
12
+ </svg>
13
+ </component>
@@ -0,0 +1,25 @@
1
+ <script>
2
+ export const displayValue = $props.displayValue
3
+ export const onChange = $props.onChange
4
+ export const className = $props.className || ''
5
+ export const placeholder = $props.placeholder || ''
6
+ export const disabled = $props.disabled || false
7
+
8
+ const baseClasses = 'w-full rounded-lg border-none bg-white dark:bg-neutral-800 py-2 pl-3 pr-10 text-sm leading-5 text-neutral-900 dark:text-white focus:ring-0 focus:outline-none focus-visible:border-blue-500 focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75 focus-visible:ring-offset-2'
9
+ const disabledClasses = disabled ? 'opacity-50 cursor-not-allowed' : ''
10
+ const inputClasses = `${baseClasses} ${disabledClasses} ${className}`.trim()
11
+
12
+ export function handleChange(e) {
13
+ onChange?.(e.target.value)
14
+ }
15
+ </script>
16
+
17
+ <input
18
+ type="text"
19
+ class="{{ inputClasses }}"
20
+ placeholder="{{ placeholder }}"
21
+ value="{{ displayValue }}"
22
+ @if(disabled)disabled@endif
23
+ @input="handleChange"
24
+ autocomplete="off"
25
+ />
@@ -0,0 +1,52 @@
1
+ <script>
2
+ export const value = $props.value
3
+ export const disabled = $props.disabled || false
4
+ export const className = $props.className || ''
5
+ export const as = $props.as || 'li'
6
+ export const currentValue = $props.currentValue
7
+ export const onChange = $props.onChange
8
+
9
+ export let active = false
10
+ export const selected = currentValue === value
11
+
12
+ const baseClasses = 'relative cursor-pointer select-none py-2 pl-10 pr-4'
13
+ const stateClasses = active
14
+ ? 'bg-blue-100 text-blue-900 dark:bg-blue-900 dark:text-blue-100'
15
+ : 'text-neutral-900 dark:text-neutral-100'
16
+ const disabledClasses = disabled ? 'opacity-50 cursor-not-allowed' : ''
17
+ const optionClasses = `${baseClasses} ${stateClasses} ${disabledClasses} ${className}`.trim()
18
+
19
+ export function handleClick() {
20
+ if (disabled) return
21
+ onChange?.(value)
22
+ }
23
+
24
+ export function handleMouseEnter() {
25
+ if (!disabled) active = true
26
+ }
27
+
28
+ export function handleMouseLeave() {
29
+ active = false
30
+ }
31
+ </script>
32
+
33
+ <component
34
+ :is="{{ as }}"
35
+ class="{{ optionClasses }}"
36
+ role="option"
37
+ aria-selected="{{ selected ? 'true' : 'false' }}"
38
+ @if(disabled)aria-disabled="true"@endif
39
+ @click="handleClick"
40
+ @mouseenter="handleMouseEnter"
41
+ @mouseleave="handleMouseLeave"
42
+ >
43
+ @if(selected)
44
+ <span class="absolute inset-y-0 left-0 flex items-center pl-3 text-blue-600 dark:text-blue-400">
45
+ <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
46
+ <path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd" />
47
+ </svg>
48
+ </span>
49
+ @endif
50
+
51
+ <slot :active="active" :selected="selected" :disabled="disabled" />
52
+ </component>
@@ -0,0 +1,12 @@
1
+ <script>
2
+ export const className = $props.className || ''
3
+ export const as = $props.as || 'ul'
4
+ export const static_ = $props.static || false
5
+
6
+ const baseClasses = 'absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white dark:bg-neutral-800 py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none'
7
+ const optionsClasses = `${baseClasses} ${className}`.trim()
8
+ </script>
9
+
10
+ <component :is="{{ as }}" class="{{ optionsClasses }}" role="listbox">
11
+ <slot />
12
+ </component>
@@ -0,0 +1,154 @@
1
+ # Combobox Component
2
+
3
+ A searchable select component that combines an input with a listbox.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ bun add @stacksjs/components
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```stx
14
+ <script>
15
+ export const people = [
16
+ { id: 1, name: 'Wade Cooper' },
17
+ { id: 2, name: 'Arlene Mccoy' },
18
+ { id: 3, name: 'Devon Webb' }
19
+ ]
20
+
21
+ export let selected = people[0]
22
+ export let query = ''
23
+
24
+ export const filtered = query === ''
25
+ ? people
26
+ : people.filter(person =>
27
+ person.name.toLowerCase().includes(query.toLowerCase())
28
+ )
29
+
30
+ export function handleChange(person) {
31
+ selected = person
32
+ query = ''
33
+ }
34
+
35
+ export function handleQueryChange(value) {
36
+ query = value
37
+ }
38
+ </script>
39
+
40
+ @component('Combobox', { value: selected, onChange: handleChange })
41
+ <div class="relative mt-1">
42
+ @component('ComboboxInput', {
43
+ displayValue: selected.name,
44
+ onChange: handleQueryChange,
45
+ placeholder: 'Search people...'
46
+ })
47
+
48
+ @component('ComboboxButton')
49
+
50
+ @component('ComboboxOptions')
51
+ @if(filtered.length === 0 && query !== '')
52
+ <div class="relative cursor-default select-none py-2 px-4 text-neutral-700 dark:text-neutral-300">
53
+ Nothing found.
54
+ </div>
55
+ @else
56
+ @foreach(person in filtered)
57
+ @component('ComboboxOption', {
58
+ value: person,
59
+ currentValue: selected,
60
+ onChange: handleChange
61
+ })
62
+ {{ person.name }}
63
+ @endcomponent
64
+ @endforeach
65
+ @endif
66
+ @endcomponent
67
+ </div>
68
+ @endcomponent
69
+ ```
70
+
71
+ ## Props
72
+
73
+ ### Combobox
74
+ | Prop | Type | Default | Description |
75
+ |------|------|---------|-------------|
76
+ | `value` | `any` | - | Currently selected value |
77
+ | `onChange` | `(value: any) => void` | - | Change handler |
78
+ | `className` | `string` | `''` | Additional CSS classes |
79
+ | `as` | `string` | `'div'` | HTML element to render |
80
+
81
+ ### ComboboxInput
82
+ | Prop | Type | Default | Description |
83
+ |------|------|---------|-------------|
84
+ | `displayValue` | `any` | - | Value to display in input |
85
+ | `onChange` | `(value: string) => void` | - | Input change handler |
86
+ | `className` | `string` | `''` | Additional CSS classes |
87
+ | `placeholder` | `string` | `''` | Input placeholder |
88
+ | `disabled` | `boolean` | `false` | Disable the input |
89
+
90
+ ### ComboboxButton
91
+ | Prop | Type | Default | Description |
92
+ |------|------|---------|-------------|
93
+ | `className` | `string` | `''` | Additional CSS classes |
94
+ | `as` | `string` | `'button'` | HTML element to render |
95
+
96
+ ### ComboboxOptions
97
+ | Prop | Type | Default | Description |
98
+ |------|------|---------|-------------|
99
+ | `className` | `string` | `''` | Additional CSS classes |
100
+ | `as` | `string` | `'ul'` | HTML element to render |
101
+ | `static` | `boolean` | `false` | Keep visible regardless of state |
102
+
103
+ ### ComboboxOption
104
+ | Prop | Type | Default | Description |
105
+ |------|------|---------|-------------|
106
+ | `value` | `any` | - | Option value |
107
+ | `disabled` | `boolean` | `false` | Disable the option |
108
+ | `className` | `string` | `''` | Additional CSS classes |
109
+ | `as` | `string` | `'li'` | HTML element to render |
110
+ | `currentValue` | `any` | - | Current selected value |
111
+ | `onChange` | `(value: any) => void` | - | Change handler |
112
+
113
+ ## Examples
114
+
115
+ ### With Empty State
116
+
117
+ ```stx
118
+ @component('ComboboxOptions')
119
+ @if(filtered.length === 0)
120
+ <div class="py-2 px-4 text-neutral-500 dark:text-neutral-400">
121
+ No results found for "{{ query }}"
122
+ </div>
123
+ @else
124
+ @foreach(item in filtered)
125
+ @component('ComboboxOption', { value: item })
126
+ {{ item.name }}
127
+ @endcomponent
128
+ @endforeach
129
+ @endif
130
+ @endcomponent
131
+ ```
132
+
133
+ ### With Avatars
134
+
135
+ ```stx
136
+ @component('ComboboxOption', { value: person })
137
+ <div class="flex items-center gap-2">
138
+ <img src="{{ person.avatar }}" alt="" class="h-6 w-6 rounded-full" />
139
+ <span>{{ person.name }}</span>
140
+ </div>
141
+ @endcomponent
142
+ ```
143
+
144
+ ## Features
145
+
146
+ - Searchable/filterable
147
+ - Keyboard navigation
148
+ - Empty state support
149
+ - Dark mode support
150
+ - Accessible (WAI-ARIA)
151
+ - Disabled state
152
+ - Active state on hover
153
+ - Check icon for selected item
154
+ - Customizable styling
@@ -0,0 +1,40 @@
1
+ export { default as Combobox } from './Combobox.stx'
2
+ export { default as ComboboxButton } from './ComboboxButton.stx'
3
+ export { default as ComboboxInput } from './ComboboxInput.stx'
4
+ export { default as ComboboxOption } from './ComboboxOption.stx'
5
+ export { default as ComboboxOptions } from './ComboboxOptions.stx'
6
+
7
+ export interface ComboboxProps {
8
+ value?: any
9
+ onChange?: (value: any) => void
10
+ className?: string
11
+ as?: string
12
+ }
13
+
14
+ export interface ComboboxInputProps {
15
+ displayValue?: any
16
+ onChange?: (value: string) => void
17
+ className?: string
18
+ placeholder?: string
19
+ disabled?: boolean
20
+ }
21
+
22
+ export interface ComboboxButtonProps {
23
+ className?: string
24
+ as?: string
25
+ }
26
+
27
+ export interface ComboboxOptionsProps {
28
+ className?: string
29
+ as?: string
30
+ static?: boolean
31
+ }
32
+
33
+ export interface ComboboxOptionProps {
34
+ value: any
35
+ disabled?: boolean
36
+ className?: string
37
+ as?: string
38
+ currentValue?: any
39
+ onChange?: (value: any) => void
40
+ }
@@ -0,0 +1,39 @@
1
+ <script>
2
+ export const open = $props.open || false
3
+ export const onClose = $props.onClose
4
+ export const query = $props.query || ''
5
+ export const onQueryChange = $props.onQueryChange
6
+ export const className = $props.className || ''
7
+
8
+ const baseClasses = 'fixed inset-0 z-50 overflow-y-auto p-4 sm:p-6 md:p-20'
9
+ const paletteClasses = `${baseClasses} ${className}`.trim()
10
+
11
+ export function handleClose() {
12
+ onClose?.()
13
+ }
14
+ </script>
15
+
16
+ @if(open)
17
+ <div class="{{ paletteClasses }}">
18
+ <div class="fixed inset-0 bg-neutral-500 bg-opacity-25 dark:bg-opacity-50 transition-opacity" @click="handleClose" />
19
+
20
+ <div class="mx-auto max-w-xl transform divide-y divide-neutral-100 dark:divide-neutral-800 overflow-hidden rounded-xl bg-white dark:bg-neutral-900 shadow-2xl ring-1 ring-black ring-opacity-5 transition-all">
21
+ <div class="relative">
22
+ <svg class="pointer-events-none absolute top-3.5 left-4 h-5 w-5 text-neutral-400" viewBox="0 0 20 20" fill="currentColor">
23
+ <path fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" clip-rule="evenodd" />
24
+ </svg>
25
+ <input
26
+ type="text"
27
+ class="h-12 w-full border-0 bg-transparent pl-11 pr-4 text-neutral-900 dark:text-white placeholder-neutral-400 focus:ring-0 sm:text-sm"
28
+ placeholder="Search..."
29
+ value="{{ query }}"
30
+ @input="(e) => onQueryChange?.(e.target.value)"
31
+ />
32
+ </div>
33
+
34
+ <div class="max-h-96 overflow-y-auto py-2">
35
+ <slot :query="query" />
36
+ </div>
37
+ </div>
38
+ </div>
39
+ @endif
@@ -0,0 +1,32 @@
1
+ <script>
2
+ export const className = $props.className || ''
3
+ export const onClick = $props.onClick
4
+ export let active = false
5
+
6
+ const baseClasses = 'flex cursor-pointer select-none items-center px-4 py-2'
7
+ const activeClasses = active
8
+ ? 'bg-blue-600 text-white'
9
+ : 'text-neutral-900 dark:text-neutral-100'
10
+ const itemClasses = `${baseClasses} ${activeClasses} ${className}`.trim()
11
+
12
+ export function handleClick() {
13
+ onClick?.()
14
+ }
15
+
16
+ export function handleMouseEnter() {
17
+ active = true
18
+ }
19
+
20
+ export function handleMouseLeave() {
21
+ active = false
22
+ }
23
+ </script>
24
+
25
+ <div
26
+ class="{{ itemClasses }}"
27
+ @click="handleClick"
28
+ @mouseenter="handleMouseEnter"
29
+ @mouseleave="handleMouseLeave"
30
+ >
31
+ <slot :active="active" />
32
+ </div>
@@ -0,0 +1,42 @@
1
+ # Command Palette Component
2
+
3
+ A searchable command menu for quick actions and navigation.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ bun add @stacksjs/components
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```stx
14
+ <script>
15
+ export let open = false
16
+ export let query = ''
17
+
18
+ const commands = [
19
+ { name: 'Create new file', action: () => console.log('create') },
20
+ { name: 'Open settings', action: () => console.log('settings') }
21
+ ]
22
+
23
+ export const filtered = query === ''
24
+ ? commands
25
+ : commands.filter(cmd => cmd.name.toLowerCase().includes(query.toLowerCase()))
26
+ </script>
27
+
28
+ @component('CommandPalette', { open, onClose: () => open = false, query, onQueryChange: (q) => query = q })
29
+ @foreach(command in filtered)
30
+ @component('CommandPaletteItem', { onClick: command.action })
31
+ {{ command.name }}
32
+ @endcomponent
33
+ @endforeach
34
+ @endcomponent
35
+ ```
36
+
37
+ ## Features
38
+
39
+ - Searchable
40
+ - Keyboard navigation
41
+ - Dark mode support
42
+ - Accessible
@@ -0,0 +1,15 @@
1
+ export { default as CommandPalette } from './CommandPalette.stx'
2
+ export { default as CommandPaletteItem } from './CommandPaletteItem.stx'
3
+
4
+ export interface CommandPaletteProps {
5
+ open?: boolean
6
+ onClose?: () => void
7
+ query?: string
8
+ onQueryChange?: (query: string) => void
9
+ className?: string
10
+ }
11
+
12
+ export interface CommandPaletteItemProps {
13
+ className?: string
14
+ onClick?: () => void
15
+ }
@@ -0,0 +1,19 @@
1
+ <script>
2
+ export const open = $props.open || false
3
+ export const onClose = $props.onClose
4
+ export const className = $props.className || ''
5
+ export const as = $props.as || 'div'
6
+
7
+ const baseClasses = 'relative z-50'
8
+ const dialogClasses = `${baseClasses} ${className}`.trim()
9
+
10
+ export function handleClose() {
11
+ onClose?.(false)
12
+ }
13
+ </script>
14
+
15
+ @if(open)
16
+ <div class="{{ dialogClasses }}" role="dialog" aria-modal="true">
17
+ <slot />
18
+ </div>
19
+ @endif
@@ -0,0 +1,9 @@
1
+ <script>
2
+ export const className = $props.className || ''
3
+ export const as = $props.as || 'div'
4
+
5
+ const baseClasses = 'fixed inset-0 bg-black bg-opacity-25 dark:bg-opacity-50 transition-opacity'
6
+ const backdropClasses = `${baseClasses} ${className}`.trim()
7
+ </script>
8
+
9
+ <component :is="{{ as }}" class="{{ backdropClasses }}" aria-hidden="true" />
@@ -0,0 +1,11 @@
1
+ <script>
2
+ export const className = $props.className || ''
3
+ export const as = $props.as || 'p'
4
+
5
+ const baseClasses = 'mt-2 text-sm text-neutral-500 dark:text-neutral-400'
6
+ const descriptionClasses = `${baseClasses} ${className}`.trim()
7
+ </script>
8
+
9
+ <component :is="{{ as }}" class="{{ descriptionClasses }}">
10
+ <slot />
11
+ </component>
@@ -0,0 +1,16 @@
1
+ <script>
2
+ export const className = $props.className || ''
3
+ export const as = $props.as || 'div'
4
+
5
+ const baseClasses = 'fixed inset-0 overflow-y-auto'
6
+ const panelWrapperClasses = 'flex min-h-full items-center justify-center p-4 text-center'
7
+ const panelClasses = `transform overflow-hidden rounded-lg bg-white dark:bg-neutral-800 p-6 text-left align-middle shadow-xl transition-all ${className}`.trim()
8
+ </script>
9
+
10
+ <component :is="{{ as }}" class="{{ baseClasses }}">
11
+ <div class="{{ panelWrapperClasses }}">
12
+ <div class="{{ panelClasses }}">
13
+ <slot />
14
+ </div>
15
+ </div>
16
+ </component>
@@ -0,0 +1,11 @@
1
+ <script>
2
+ export const className = $props.className || ''
3
+ export const as = $props.as || 'h3'
4
+
5
+ const baseClasses = 'text-lg font-medium leading-6 text-neutral-900 dark:text-white'
6
+ const titleClasses = `${baseClasses} ${className}`.trim()
7
+ </script>
8
+
9
+ <component :is="{{ as }}" class="{{ titleClasses }}">
10
+ <slot />
11
+ </component>
@@ -0,0 +1,133 @@
1
+ # Dialog Component
2
+
3
+ A modal dialog component for overlays, alerts, and confirmations. Built with STX and headwind.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ bun add @stacksjs/components
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```stx
14
+ <script>
15
+ export let isOpen = false
16
+
17
+ export function closeModal() {
18
+ isOpen = false
19
+ }
20
+
21
+ export function openModal() {
22
+ isOpen = true
23
+ }
24
+ </script>
25
+
26
+ @component('Dialog', { open: isOpen, onClose: closeModal })
27
+ @component('DialogBackdrop')
28
+
29
+ @component('DialogPanel', { className: 'max-w-md' })
30
+ @component('DialogTitle')
31
+ Payment successful
32
+ @endcomponent
33
+
34
+ @component('DialogDescription')
35
+ Your payment has been successfully submitted.
36
+ @endcomponent
37
+
38
+ <div class="mt-4">
39
+ @component('Button', { onClick: closeModal })
40
+ Got it, thanks!
41
+ @endcomponent
42
+ </div>
43
+ @endcomponent
44
+ @endcomponent
45
+ ```
46
+
47
+ ## Props
48
+
49
+ ### Dialog
50
+ | Prop | Type | Default | Description |
51
+ |------|------|---------|-------------|
52
+ | `open` | `boolean` | `false` | Whether dialog is open |
53
+ | `onClose` | `(value: boolean) => void` | - | Close handler |
54
+ | `className` | `string` | `''` | Additional CSS classes |
55
+ | `as` | `string` | `'div'` | HTML element to render |
56
+
57
+ ### DialogBackdrop
58
+ | Prop | Type | Default | Description |
59
+ |------|------|---------|-------------|
60
+ | `className` | `string` | `''` | Additional CSS classes |
61
+ | `as` | `string` | `'div'` | HTML element to render |
62
+
63
+ ### DialogPanel
64
+ | Prop | Type | Default | Description |
65
+ |------|------|---------|-------------|
66
+ | `className` | `string` | `''` | Additional CSS classes |
67
+ | `as` | `string` | `'div'` | HTML element to render |
68
+
69
+ ### DialogTitle
70
+ | Prop | Type | Default | Description |
71
+ |------|------|---------|-------------|
72
+ | `className` | `string` | `''` | Additional CSS classes |
73
+ | `as` | `string` | `'h3'` | HTML element to render |
74
+
75
+ ### DialogDescription
76
+ | Prop | Type | Default | Description |
77
+ |------|------|---------|-------------|
78
+ | `className` | `string` | `''` | Additional CSS classes |
79
+ | `as` | `string` | `'p'` | HTML element to render |
80
+
81
+ ## Examples
82
+
83
+ ### Confirmation Dialog
84
+
85
+ ```stx
86
+ @component('Dialog', { open: isOpen, onClose: closeModal })
87
+ @component('DialogBackdrop')
88
+
89
+ @component('DialogPanel', { className: 'max-w-md' })
90
+ @component('DialogTitle')
91
+ Delete account
92
+ @endcomponent
93
+
94
+ @component('DialogDescription')
95
+ Are you sure you want to delete your account? This action cannot be undone.
96
+ @endcomponent
97
+
98
+ <div class="mt-4 flex gap-2">
99
+ @component('Button', { variant: 'danger', onClick: handleDelete })
100
+ Delete
101
+ @endcomponent
102
+ @component('Button', { variant: 'secondary', onClick: closeModal })
103
+ Cancel
104
+ @endcomponent
105
+ </div>
106
+ @endcomponent
107
+ @endcomponent
108
+ ```
109
+
110
+ ### Large Dialog
111
+
112
+ ```stx
113
+ @component('DialogPanel', { className: 'max-w-4xl' })
114
+ @component('DialogTitle')
115
+ Terms and Conditions
116
+ @endcomponent
117
+
118
+ <div class="mt-4 max-h-96 overflow-y-auto">
119
+ <!-- Long content -->
120
+ </div>
121
+ @endcomponent
122
+ ```
123
+
124
+ ## Features
125
+
126
+ - Focus trap
127
+ - Backdrop overlay
128
+ - Keyboard support (ESC to close)
129
+ - Dark mode support
130
+ - Accessible (WAI-ARIA)
131
+ - Customizable with headwind classes
132
+ - Multiple sizes
133
+ - Scrollable content support
@@ -0,0 +1,32 @@
1
+ export { default as Dialog } from './Dialog.stx'
2
+ export { default as DialogBackdrop } from './DialogBackdrop.stx'
3
+ export { default as DialogDescription } from './DialogDescription.stx'
4
+ export { default as DialogPanel } from './DialogPanel.stx'
5
+ export { default as DialogTitle } from './DialogTitle.stx'
6
+
7
+ export interface DialogProps {
8
+ open?: boolean
9
+ onClose?: (value: boolean) => void
10
+ className?: string
11
+ as?: string
12
+ }
13
+
14
+ export interface DialogBackdropProps {
15
+ className?: string
16
+ as?: string
17
+ }
18
+
19
+ export interface DialogPanelProps {
20
+ className?: string
21
+ as?: string
22
+ }
23
+
24
+ export interface DialogTitleProps {
25
+ className?: string
26
+ as?: string
27
+ }
28
+
29
+ export interface DialogDescriptionProps {
30
+ className?: string
31
+ as?: string
32
+ }