@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,142 @@
1
+ <script>
2
+ export const value = $props.value || 0
3
+ export const max = $props.max || 100
4
+ export const variant = $props.variant || 'linear'
5
+ export const size = $props.size || 'md'
6
+ export const color = $props.color || 'primary'
7
+ export const showLabel = $props.showLabel ?? false
8
+ export const indeterminate = $props.indeterminate || false
9
+ export const className = $props.className || ''
10
+
11
+ // Calculate percentage
12
+ const percentage = Math.min(Math.max((value / max) * 100, 0), 100)
13
+
14
+ // Size classes for linear
15
+ const linearSizeClasses = {
16
+ sm: 'h-1',
17
+ md: 'h-2',
18
+ lg: 'h-3',
19
+ }
20
+
21
+ // Size classes for circular
22
+ const circularSizeClasses = {
23
+ sm: 'w-12 h-12',
24
+ md: 'w-16 h-16',
25
+ lg: 'w-24 h-24',
26
+ }
27
+
28
+ // Color classes
29
+ const colorClasses = {
30
+ primary: 'bg-blue-600 dark:bg-blue-500',
31
+ secondary: 'bg-purple-600 dark:bg-purple-500',
32
+ success: 'bg-green-600 dark:bg-green-500',
33
+ warning: 'bg-yellow-600 dark:bg-yellow-500',
34
+ danger: 'bg-red-600 dark:bg-red-500',
35
+ info: 'bg-cyan-600 dark:bg-cyan-500',
36
+ }
37
+
38
+ // Circular SVG values
39
+ const circularSize = size === 'sm' ? 48 : size === 'md' ? 64 : 96
40
+ const strokeWidth = size === 'sm' ? 4 : size === 'md' ? 6 : 8
41
+ const radius = (circularSize - strokeWidth) / 2
42
+ const circumference = 2 * Math.PI * radius
43
+ const strokeDashoffset = indeterminate ? 0 : circumference - (percentage / 100) * circumference
44
+
45
+ export const containerClasses = variant === 'linear'
46
+ ? `w-full ${className}`.trim()
47
+ : `inline-flex items-center justify-center ${className}`.trim()
48
+
49
+ export const linearTrackClasses = `w-full ${linearSizeClasses[size]} bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden`.trim()
50
+ export const linearBarClasses = `h-full ${colorClasses[color]} transition-all duration-300 ease-in-out ${indeterminate ? 'animate-progress-indeterminate' : ''}`.trim()
51
+ export const labelClasses = `text-sm font-medium text-gray-700 dark:text-gray-300 mb-2`.trim()
52
+ export const circularTrackColor = 'stroke-gray-200 dark:stroke-gray-700'
53
+ export const circularBarColor = color === 'primary' ? 'stroke-blue-600 dark:stroke-blue-500' :
54
+ color === 'secondary' ? 'stroke-purple-600 dark:stroke-purple-500' :
55
+ color === 'success' ? 'stroke-green-600 dark:stroke-green-500' :
56
+ color === 'warning' ? 'stroke-yellow-600 dark:stroke-yellow-500' :
57
+ color === 'danger' ? 'stroke-red-600 dark:stroke-red-500' :
58
+ 'stroke-cyan-600 dark:stroke-cyan-500'
59
+ </script>
60
+
61
+ @if(variant === 'linear')
62
+ <div class="{{ containerClasses }}">
63
+ @if(showLabel)
64
+ <div class="flex items-center justify-between mb-2">
65
+ <span class="{{ labelClasses }}">{{ Math.round(percentage) }}%</span>
66
+ </div>
67
+ @endif
68
+
69
+ <div
70
+ class="{{ linearTrackClasses }}"
71
+ role="progressbar"
72
+ aria-valuenow="{{ value }}"
73
+ aria-valuemin="0"
74
+ aria-valuemax="{{ max }}"
75
+ >
76
+ <div
77
+ class="{{ linearBarClasses }}"
78
+ style="width: {{ indeterminate ? '30%' : percentage + '%' }}"
79
+ ></div>
80
+ </div>
81
+ </div>
82
+ @else
83
+ <!-- Circular Progress -->
84
+ <div class="{{ containerClasses }}">
85
+ <div class="{{ circularSizeClasses[size] }} relative">
86
+ <svg
87
+ class="transform -rotate-90"
88
+ width="{{ circularSize }}"
89
+ height="{{ circularSize }}"
90
+ role="progressbar"
91
+ aria-valuenow="{{ value }}"
92
+ aria-valuemin="0"
93
+ aria-valuemax="{{ max }}"
94
+ >
95
+ <!-- Background circle -->
96
+ <circle
97
+ class="{{ circularTrackColor }}"
98
+ cx="{{ circularSize / 2 }}"
99
+ cy="{{ circularSize / 2 }}"
100
+ r="{{ radius }}"
101
+ stroke-width="{{ strokeWidth }}"
102
+ fill="none"
103
+ />
104
+ <!-- Progress circle -->
105
+ <circle
106
+ class="{{ circularBarColor }} transition-all duration-300 ease-in-out {{ indeterminate ? 'animate-spin' : '' }}"
107
+ cx="{{ circularSize / 2 }}"
108
+ cy="{{ circularSize / 2 }}"
109
+ r="{{ radius }}"
110
+ stroke-width="{{ strokeWidth }}"
111
+ fill="none"
112
+ stroke-dasharray="{{ circumference }}"
113
+ stroke-dashoffset="{{ strokeDashoffset }}"
114
+ stroke-linecap="round"
115
+ />
116
+ </svg>
117
+
118
+ @if(showLabel)
119
+ <div class="absolute inset-0 flex items-center justify-center">
120
+ <span class="text-sm font-semibold text-gray-700 dark:text-gray-300">
121
+ {{ Math.round(percentage) }}%
122
+ </span>
123
+ </div>
124
+ @endif
125
+ </div>
126
+ </div>
127
+ @endif
128
+
129
+ <style>
130
+ @keyframes progress-indeterminate {
131
+ 0% {
132
+ transform: translateX(-100%);
133
+ }
134
+ 100% {
135
+ transform: translateX(400%);
136
+ }
137
+ }
138
+
139
+ .animate-progress-indeterminate {
140
+ animation: progress-indeterminate 1.5s ease-in-out infinite;
141
+ }
142
+ </style>
@@ -0,0 +1,12 @@
1
+ export { default as Progress } from './Progress.stx'
2
+
3
+ export interface ProgressProps {
4
+ value?: number
5
+ max?: number
6
+ variant?: 'linear' | 'circular'
7
+ size?: 'sm' | 'md' | 'lg'
8
+ color?: 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info'
9
+ showLabel?: boolean
10
+ indeterminate?: boolean
11
+ className?: string
12
+ }
@@ -0,0 +1,81 @@
1
+ <script>
2
+ export const checked = $props.checked || false
3
+ export const onChange = $props.onChange || (() => {})
4
+ export const disabled = $props.disabled || false
5
+ export const size = $props.size || 'md'
6
+ export const label = $props.label || ''
7
+ export const description = $props.description || ''
8
+ export const error = $props.error || false
9
+ export const required = $props.required || false
10
+ export const value = $props.value || ''
11
+ export const name = $props.name || ''
12
+ export const className = $props.className || ''
13
+
14
+ // Size classes
15
+ const sizeClasses = {
16
+ sm: 'h-4 w-4',
17
+ md: 'h-5 w-5',
18
+ lg: 'h-6 w-6',
19
+ }
20
+
21
+ // Base classes for radio
22
+ const baseClasses = 'border-gray-300 dark:border-gray-600 text-indigo-600 dark:text-indigo-500 focus:ring-indigo-600 dark:focus:ring-indigo-500 focus:ring-2 focus:ring-offset-2 dark:focus:ring-offset-gray-900 transition-colors'
23
+
24
+ const stateClasses = error
25
+ ? 'border-red-300 dark:border-red-600 text-red-600 dark:text-red-500 focus:ring-red-500 dark:focus:ring-red-400'
26
+ : ''
27
+
28
+ const disabledClasses = disabled
29
+ ? 'opacity-50 cursor-not-allowed'
30
+ : 'cursor-pointer'
31
+
32
+ export const radioClasses = `${baseClasses} ${sizeClasses[size]} ${stateClasses} ${disabledClasses}`.trim()
33
+ export const labelClasses = `text-sm font-medium ${error ? 'text-red-600 dark:text-red-400' : 'text-gray-900 dark:text-gray-100'} ${disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}`.trim()
34
+ export const descriptionClasses = `text-sm ${error ? 'text-red-500 dark:text-red-400' : 'text-gray-500 dark:text-gray-400'}`.trim()
35
+ </script>
36
+
37
+ <div class="relative flex items-start {{ className }}">
38
+ <div class="flex h-6 items-center">
39
+ <input
40
+ id="radio-{{ value || label }}"
41
+ type="radio"
42
+ name="{{ name }}"
43
+ value="{{ value }}"
44
+ checked="{{ checked }}"
45
+ disabled="{{ disabled }}"
46
+ required="{{ required }}"
47
+ class="{{ radioClasses }}"
48
+ onchange="handleChange(event)"
49
+ aria-invalid="{{ error ? 'true' : 'false' }}"
50
+ @if(description)aria-describedby="radio-description"@endif
51
+ />
52
+ </div>
53
+
54
+ @if(label || description)
55
+ <div class="ml-3 text-sm leading-6">
56
+ @if(label)
57
+ <label for="radio-{{ value || label }}" class="{{ labelClasses }}">
58
+ {{ label }}
59
+ @if(required)
60
+ <span class="text-red-500 ml-1">*</span>
61
+ @endif
62
+ </label>
63
+ @endif
64
+ @if(description)
65
+ <p id="radio-description" class="{{ descriptionClasses }}">
66
+ {{ description }}
67
+ </p>
68
+ @endif
69
+ </div>
70
+ @endif
71
+ </div>
72
+
73
+ <script>
74
+ function handleChange(event) {
75
+ const isChecked = event.target.checked
76
+
77
+ if (!disabled && onChange) {
78
+ onChange(value, isChecked)
79
+ }
80
+ }
81
+ </script>
@@ -0,0 +1,15 @@
1
+ export { default as Radio } from './Radio.stx'
2
+
3
+ export interface RadioProps {
4
+ checked?: boolean
5
+ onChange?: (value: string, checked: boolean) => void
6
+ disabled?: boolean
7
+ size?: 'sm' | 'md' | 'lg'
8
+ label?: string
9
+ description?: string
10
+ error?: boolean
11
+ required?: boolean
12
+ value?: string
13
+ name?: string
14
+ className?: string
15
+ }
@@ -0,0 +1,145 @@
1
+ # Radio Group Component
2
+
3
+ A set of checkable buttons (radio buttons) where only one can be checked at a time.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ bun add @stacksjs/components
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```stx
14
+ <script>
15
+ export let selected = 'option1'
16
+
17
+ export function handleChange(value) {
18
+ selected = value
19
+ }
20
+ </script>
21
+
22
+ @component('RadioGroup', { value: selected, onChange: handleChange })
23
+ @component('RadioGroupLabel')
24
+ Choose an option
25
+ @endcomponent
26
+
27
+ @component('RadioGroupOption', { value: 'option1', currentValue: selected, onChange: handleChange })
28
+ Option 1
29
+ @endcomponent
30
+
31
+ @component('RadioGroupOption', { value: 'option2', currentValue: selected, onChange: handleChange })
32
+ Option 2
33
+ @endcomponent
34
+ @endcomponent
35
+ ```
36
+
37
+ ## Props
38
+
39
+ ### RadioGroup
40
+ | Prop | Type | Default | Description |
41
+ |------|------|---------|-------------|
42
+ | `value` | `any` | - | Currently selected value |
43
+ | `onChange` | `(value: any) => void` | - | Change handler |
44
+ | `className` | `string` | `''` | Additional CSS classes |
45
+ | `as` | `string` | `'div'` | HTML element to render |
46
+
47
+ ### RadioGroupLabel
48
+ | Prop | Type | Default | Description |
49
+ |------|------|---------|-------------|
50
+ | `className` | `string` | `''` | Additional CSS classes |
51
+ | `as` | `string` | `'label'` | HTML element to render |
52
+
53
+ ### RadioGroupOption
54
+ | Prop | Type | Default | Description |
55
+ |------|------|---------|-------------|
56
+ | `value` | `any` | - | Option value |
57
+ | `disabled` | `boolean` | `false` | Disable the option |
58
+ | `className` | `string` | `''` | Additional CSS classes |
59
+ | `as` | `string` | `'div'` | HTML element to render |
60
+ | `currentValue` | `any` | - | Current selected value |
61
+ | `onChange` | `(value: any) => void` | - | Change handler |
62
+
63
+ ### RadioGroupDescription
64
+ | Prop | Type | Default | Description |
65
+ |------|------|---------|-------------|
66
+ | `className` | `string` | `''` | Additional CSS classes |
67
+ | `as` | `string` | `'span'` | HTML element to render |
68
+
69
+ ## Examples
70
+
71
+ ### Server Plans
72
+
73
+ ```stx
74
+ <script>
75
+ export const plans = [
76
+ { name: 'Startup', ram: '12GB', cpus: '6 CPUs', disk: '160 GB SSD' },
77
+ { name: 'Business', ram: '16GB', cpus: '8 CPUs', disk: '512 GB SSD' },
78
+ { name: 'Enterprise', ram: '32GB', cpus: '12 CPUs', disk: '1024 GB SSD' }
79
+ ]
80
+
81
+ export let selected = plans[0]
82
+
83
+ export function handleChange(plan) {
84
+ selected = plan
85
+ }
86
+ </script>
87
+
88
+ @component('RadioGroup', { value: selected, onChange: handleChange })
89
+ @component('RadioGroupLabel', { className: 'sr-only' })
90
+ Server size
91
+ @endcomponent
92
+
93
+ <div class="space-y-2">
94
+ @foreach(plan in plans)
95
+ @component('RadioGroupOption', {
96
+ value: plan,
97
+ currentValue: selected,
98
+ onChange: handleChange
99
+ })
100
+ <div class="w-full flex items-center justify-between">
101
+ <div class="flex items-center">
102
+ <div class="text-sm">
103
+ @component('RadioGroupLabel', {
104
+ className: 'font-medium'
105
+ })
106
+ {{ plan.name }}
107
+ @endcomponent
108
+
109
+ @component('RadioGroupDescription')
110
+ {{ plan.ram }}/{{ plan.cpus }} · {{ plan.disk }}
111
+ @endcomponent
112
+ </div>
113
+ </div>
114
+
115
+ @if(selected === plan)
116
+ <svg class="h-6 w-6 shrink-0 text-white" viewBox="0 0 24 24" fill="none">
117
+ <circle cx="12" cy="12" r="12" fill="#fff" fill-opacity="0.2" />
118
+ <path d="M7 13l3 3 7-7" stroke="#fff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
119
+ </svg>
120
+ @endif
121
+ </div>
122
+ @endcomponent
123
+ @endforeach
124
+ </div>
125
+ @endcomponent
126
+ ```
127
+
128
+ ### With Disabled Option
129
+
130
+ ```stx
131
+ @component('RadioGroupOption', { value: 'disabled', disabled: true })
132
+ This option is disabled
133
+ @endcomponent
134
+ ```
135
+
136
+ ## Features
137
+
138
+ - Single selection from multiple options
139
+ - Keyboard navigation
140
+ - Focus management
141
+ - Dark mode support
142
+ - Accessible (WAI-ARIA)
143
+ - Disabled state support
144
+ - Active state on focus
145
+ - Customizable styling
@@ -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 = 'w-full'
8
+ const groupClasses = `${baseClasses} ${className}`.trim()
9
+ </script>
10
+
11
+ <component :is="{{ as }}" class="{{ groupClasses }}" role="radiogroup">
12
+ <slot :value="value" :onChange="onChange" />
13
+ </component>
@@ -0,0 +1,11 @@
1
+ <script>
2
+ export const className = $props.className || ''
3
+ export const as = $props.as || 'span'
4
+
5
+ const baseClasses = 'inline 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,11 @@
1
+ <script>
2
+ export const className = $props.className || ''
3
+ export const as = $props.as || 'label'
4
+
5
+ const baseClasses = 'block text-sm font-medium text-neutral-900 dark:text-white'
6
+ const labelClasses = `${baseClasses} ${className}`.trim()
7
+ </script>
8
+
9
+ <component :is="{{ as }}" class="{{ labelClasses }}">
10
+ <slot />
11
+ </component>
@@ -0,0 +1,51 @@
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 || 'div'
6
+ export const currentValue = $props.currentValue
7
+ export const onChange = $props.onChange
8
+
9
+ export let active = false
10
+ export const checked = currentValue === value
11
+
12
+ const baseClasses = 'relative flex cursor-pointer rounded-lg px-5 py-4 shadow-md focus:outline-none transition-all'
13
+ const stateClasses = checked
14
+ ? 'bg-blue-900 bg-opacity-75 text-white dark:bg-blue-800'
15
+ : 'bg-white dark:bg-neutral-800'
16
+ const activeClasses = active
17
+ ? 'ring-2 ring-white ring-opacity-60 ring-offset-2 ring-offset-blue-300 dark:ring-offset-blue-700'
18
+ : ''
19
+ const disabledClasses = disabled
20
+ ? 'opacity-50 cursor-not-allowed'
21
+ : ''
22
+
23
+ const optionClasses = `${baseClasses} ${stateClasses} ${activeClasses} ${disabledClasses} ${className}`.trim()
24
+
25
+ export function handleClick() {
26
+ if (disabled) return
27
+ onChange?.(value)
28
+ }
29
+
30
+ export function handleFocus() {
31
+ if (!disabled) active = true
32
+ }
33
+
34
+ export function handleBlur() {
35
+ active = false
36
+ }
37
+ </script>
38
+
39
+ <component
40
+ :is="{{ as }}"
41
+ class="{{ optionClasses }}"
42
+ role="radio"
43
+ aria-checked="{{ checked ? 'true' : 'false' }}"
44
+ @if(disabled)aria-disabled="true"@endif
45
+ tabindex="{{ disabled ? '-1' : '0' }}"
46
+ @click="handleClick"
47
+ @focus="handleFocus"
48
+ @blur="handleBlur"
49
+ >
50
+ <slot :active="active" :checked="checked" :disabled="disabled" />
51
+ </component>
@@ -0,0 +1,30 @@
1
+ export { default as RadioGroup } from './RadioGroup.stx'
2
+ export { default as RadioGroupDescription } from './RadioGroupDescription.stx'
3
+ export { default as RadioGroupLabel } from './RadioGroupLabel.stx'
4
+ export { default as RadioGroupOption } from './RadioGroupOption.stx'
5
+
6
+ export interface RadioGroupProps {
7
+ value?: any
8
+ onChange?: (value: any) => void
9
+ className?: string
10
+ as?: string
11
+ }
12
+
13
+ export interface RadioGroupLabelProps {
14
+ className?: string
15
+ as?: string
16
+ }
17
+
18
+ export interface RadioGroupOptionProps {
19
+ value: any
20
+ disabled?: boolean
21
+ className?: string
22
+ as?: string
23
+ currentValue?: any
24
+ onChange?: (value: any) => void
25
+ }
26
+
27
+ export interface RadioGroupDescriptionProps {
28
+ className?: string
29
+ as?: string
30
+ }