@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,92 @@
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 indeterminate = $props.indeterminate || false
6
+ export const size = $props.size || 'md'
7
+ export const label = $props.label || ''
8
+ export const description = $props.description || ''
9
+ export const error = $props.error || false
10
+ export const required = $props.required || false
11
+ export const value = $props.value || ''
12
+ export const name = $props.name || ''
13
+ export const className = $props.className || ''
14
+
15
+ // Size classes
16
+ const sizeClasses = {
17
+ sm: 'h-4 w-4',
18
+ md: 'h-5 w-5',
19
+ lg: 'h-6 w-6',
20
+ }
21
+
22
+ // Base classes for checkbox
23
+ const baseClasses = 'rounded 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'
24
+
25
+ const stateClasses = error
26
+ ? 'border-red-300 dark:border-red-600 text-red-600 dark:text-red-500 focus:ring-red-500 dark:focus:ring-red-400'
27
+ : ''
28
+
29
+ const disabledClasses = disabled
30
+ ? 'opacity-50 cursor-not-allowed'
31
+ : 'cursor-pointer'
32
+
33
+ export const checkboxClasses = `${baseClasses} ${sizeClasses[size]} ${stateClasses} ${disabledClasses}`.trim()
34
+ 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()
35
+ export const descriptionClasses = `text-sm ${error ? 'text-red-500 dark:text-red-400' : 'text-gray-500 dark:text-gray-400'}`.trim()
36
+ </script>
37
+
38
+ <div class="relative flex items-start {{ className }}">
39
+ <div class="flex h-6 items-center">
40
+ <input
41
+ id="checkbox-{{ value || label }}"
42
+ type="checkbox"
43
+ name="{{ name }}"
44
+ value="{{ value }}"
45
+ checked="{{ checked }}"
46
+ disabled="{{ disabled }}"
47
+ required="{{ required }}"
48
+ class="{{ checkboxClasses }}"
49
+ onchange="handleChange(event)"
50
+ aria-invalid="{{ error ? 'true' : 'false' }}"
51
+ @if(description)aria-describedby="checkbox-description"@endif
52
+ />
53
+ </div>
54
+
55
+ @if(label || description)
56
+ <div class="ml-3 text-sm leading-6">
57
+ @if(label)
58
+ <label for="checkbox-{{ value || label }}" class="{{ labelClasses }}">
59
+ {{ label }}
60
+ @if(required)
61
+ <span class="text-red-500 ml-1">*</span>
62
+ @endif
63
+ </label>
64
+ @endif
65
+ @if(description)
66
+ <p id="checkbox-description" class="{{ descriptionClasses }}">
67
+ {{ description }}
68
+ </p>
69
+ @endif
70
+ </div>
71
+ @endif
72
+ </div>
73
+
74
+ <script>
75
+ function handleChange(event) {
76
+ const isChecked = event.target.checked
77
+
78
+ if (!disabled && onChange) {
79
+ onChange(isChecked)
80
+ }
81
+ }
82
+
83
+ // Handle indeterminate state
84
+ if (indeterminate && typeof window !== 'undefined') {
85
+ window.addEventListener('DOMContentLoaded', () => {
86
+ const checkbox = document.getElementById('checkbox-{{ value || label }}')
87
+ if (checkbox) {
88
+ checkbox.indeterminate = true
89
+ }
90
+ })
91
+ }
92
+ </script>
@@ -0,0 +1,39 @@
1
+ <script>
2
+ export const products = $props.products || []
3
+ export const redirectUrl = $props.redirectUrl || ''
4
+ export const mode = $props.mode || 'subscription'
5
+ export const stripePublicKey = $props.stripePublicKey || ''
6
+ export const apiUrl = $props.apiUrl || ''
7
+ export const onSubmit = $props.onSubmit
8
+ export const onRemoveProduct = $props.onRemoveProduct
9
+ export const shipping = $props.shipping || 0
10
+ export const taxes = $props.taxes || 0
11
+ export const className = $props.className || ''
12
+
13
+ // For future expansion - one-time payment support
14
+ export const isSubscription = mode === 'subscription'
15
+ export const isOneTime = mode === 'one-time'
16
+ </script>
17
+
18
+ @if(isSubscription)
19
+ @component('SubscriptionCheckout', {
20
+ products,
21
+ stripePublicKey,
22
+ apiUrl,
23
+ onSubmit,
24
+ onRemoveProduct,
25
+ shipping,
26
+ taxes,
27
+ className
28
+ })
29
+ @endcomponent
30
+ @endif
31
+
32
+ @if(isOneTime)
33
+ <!-- One-time payment component can be implemented here in the future -->
34
+ <div class="p-8 text-center">
35
+ <p class="text-gray-600 dark:text-gray-400">
36
+ One-time payment mode is not yet implemented.
37
+ </p>
38
+ </div>
39
+ @endif
@@ -0,0 +1,57 @@
1
+ <script>
2
+ import { highlight, applyHeadwindClasses } from '../utils/highlighter'
3
+
4
+ export const code = $props.code || ''
5
+ export const language = $props.language || 'typescript'
6
+ export const theme = $props.theme || 'auto'
7
+ export const lineNumbers = $props.lineNumbers !== false
8
+ export const copyable = $props.copyable !== false
9
+ export const className = $props.className || ''
10
+
11
+ export let highlightedCode = ''
12
+ export let copied = false
13
+
14
+ // Highlight the code
15
+ const result = await highlight(code, { language, theme, lineNumbers })
16
+ highlightedCode = applyHeadwindClasses(result.html, className)
17
+
18
+ export async function copyToClipboard() {
19
+ try {
20
+ await navigator.clipboard.writeText(code)
21
+ copied = true
22
+ setTimeout(() => {
23
+ copied = false
24
+ }, 2000)
25
+ } catch (err) {
26
+ console.error('Failed to copy code:', err)
27
+ }
28
+ }
29
+ </script>
30
+
31
+ <div class="relative group">
32
+ {!! highlightedCode !!}
33
+
34
+ @if(copyable)
35
+ <button
36
+ @click="copyToClipboard"
37
+ class="absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity duration-200 px-3 py-1.5 bg-neutral-800 hover:bg-neutral-700 text-white text-xs rounded-md font-medium"
38
+ aria-label="Copy code"
39
+ >
40
+ @if(copied)
41
+ <span class="flex items-center gap-1.5">
42
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
43
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
44
+ </svg>
45
+ Copied!
46
+ </span>
47
+ @else
48
+ <span class="flex items-center gap-1.5">
49
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
50
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
51
+ </svg>
52
+ Copy
53
+ </span>
54
+ @endif
55
+ </button>
56
+ @endif
57
+ </div>
@@ -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,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,62 @@
1
+ <script>
2
+ export const paymentMethod = $props.paymentMethod
3
+ export const isLoading = $props.isLoading || false
4
+ export const className = $props.className || ''
5
+
6
+ const brandIcons = {
7
+ visa: '💳',
8
+ mastercard: '💳',
9
+ amex: '💳',
10
+ discover: '💳',
11
+ default: '💳',
12
+ }
13
+
14
+ export const containerClasses = `mt-16 w-2/3 bg-white dark:bg-blue-gray-800 px-8 py-6 shadow ring-1 ring-black dark:ring-gray-700 ring-opacity-5 sm:rounded-lg ${className}`.trim()
15
+ </script>
16
+
17
+ <div class="{{ containerClasses }}">
18
+ <h2 class="text-lg text-gray-900 dark:text-gray-100 font-medium">
19
+ Payment Info
20
+ </h2>
21
+
22
+ @if(isLoading)
23
+ <!-- Loading skeleton -->
24
+ <div class="mt-8 animate-pulse">
25
+ <div class="h-20 bg-gray-200 dark:bg-gray-700 rounded-lg"></div>
26
+ </div>
27
+ @else
28
+ @if(paymentMethod)
29
+ <div class="col-span-1 mt-8 border border-gray-200 dark:border-gray-700 rounded-lg bg-white dark:bg-blue-gray-800 shadow divide-y divide-gray-200 dark:divide-gray-700">
30
+ <div class="w-full p-3">
31
+ <div class="flex items-center justify-between">
32
+ <div class="flex items-center space-x-4">
33
+ <!-- Card Brand Icon -->
34
+ <div class="flex-shrink-0 h-10 w-10 flex items-center justify-center bg-gray-100 dark:bg-gray-700 rounded-md">
35
+ <span class="text-2xl">{{ brandIcons[paymentMethod.brand.toLowerCase()] || brandIcons.default }}</span>
36
+ </div>
37
+
38
+ <!-- Card Details -->
39
+ <div>
40
+ <h2 class="text-sm text-gray-600 dark:text-gray-300">
41
+ {{ paymentMethod.brand }} •••• {{ paymentMethod.last_four }}
42
+ <span class="ml-4 inline-flex items-center rounded-md bg-indigo-50 dark:bg-indigo-900/30 px-2 py-1 text-xs text-indigo-700 dark:text-indigo-300 font-medium ring-1 ring-indigo-700/10 dark:ring-indigo-300/20 ring-inset">Default</span>
43
+ <br>
44
+ <span class="text-xs text-gray-500 dark:text-gray-400 italic">Expires {{ paymentMethod.exp_month }} / {{ paymentMethod.exp_year }}</span>
45
+ </h2>
46
+ </div>
47
+ </div>
48
+ </div>
49
+ </div>
50
+ </div>
51
+ @else
52
+ <!-- Empty state -->
53
+ <div class="col-span-1 mt-8 border border-gray-200 dark:border-gray-700 rounded-lg bg-white dark:bg-blue-gray-800 shadow divide-y divide-gray-200 dark:divide-gray-700">
54
+ <div class="w-full px-4 py-5">
55
+ <h2 class="text-center text-sm text-gray-600 dark:text-gray-300">
56
+ You haven't added any payment methods yet.
57
+ </h2>
58
+ </div>
59
+ </div>
60
+ @endif
61
+ @endif
62
+ </div>
@@ -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,137 @@
1
+ <script>
2
+ export const open = $props.open ?? false
3
+ export const onClose = $props.onClose || (() => {})
4
+ export const position = $props.position || 'right'
5
+ export const title = $props.title || ''
6
+ export const className = $props.className || ''
7
+
8
+ // Position classes
9
+ const positionClasses = {
10
+ right: 'inset-y-0 right-0 pl-10 sm:pl-16',
11
+ left: 'inset-y-0 left-0 pr-10 sm:pr-16',
12
+ top: 'inset-x-0 top-0 pb-10',
13
+ bottom: 'inset-x-0 bottom-0 pt-10',
14
+ }
15
+
16
+ // Slide animation classes
17
+ const slideClasses = {
18
+ right: {
19
+ enter: 'translate-x-full',
20
+ leave: 'translate-x-0',
21
+ },
22
+ left: {
23
+ enter: '-translate-x-full',
24
+ leave: 'translate-x-0',
25
+ },
26
+ top: {
27
+ enter: '-translate-y-full',
28
+ leave: 'translate-y-0',
29
+ },
30
+ bottom: {
31
+ enter: 'translate-y-full',
32
+ leave: 'translate-y-0',
33
+ },
34
+ }
35
+
36
+ // Size classes based on position
37
+ const sizeClasses = {
38
+ right: 'max-w-md w-screen',
39
+ left: 'max-w-md w-screen',
40
+ top: 'max-h-[90vh] w-full',
41
+ bottom: 'max-h-[90vh] w-full',
42
+ }
43
+
44
+ // Close button position
45
+ const closeButtonPosition = {
46
+ right: 'left-0 -ml-8 sm:-ml-10',
47
+ left: 'right-0 -mr-8 sm:-mr-10',
48
+ top: 'right-0 -mr-8',
49
+ bottom: 'right-0 -mr-8',
50
+ }
51
+
52
+ export const containerClasses = `pointer-events-none fixed ${positionClasses[position]} flex max-w-full`.trim()
53
+ export const panelClasses = `pointer-events-auto relative ${sizeClasses[position]} ${className}`.trim()
54
+ export const slideAnimation = slideClasses[position]
55
+ export const closeButtonClasses = `absolute top-0 ${closeButtonPosition[position]} flex pt-4 pr-2 sm:pr-4`.trim()
56
+ </script>
57
+
58
+ @if(open)
59
+ <!-- Backdrop -->
60
+ <div
61
+ class="fixed inset-0 z-50 bg-gray-500/75 dark:bg-gray-900/75 transition-opacity duration-500"
62
+ style="animation: fadeIn 0.5s ease-in-out"
63
+ onclick="handleBackdropClick()"
64
+ ></div>
65
+
66
+ <!-- Drawer Container -->
67
+ <div class="fixed inset-0 z-50 overflow-hidden">
68
+ <div class="absolute inset-0 overflow-hidden">
69
+ <div class="{{ containerClasses }}">
70
+ <!-- Drawer Panel -->
71
+ <div
72
+ class="{{ panelClasses }}"
73
+ style="animation: slideIn 0.5s ease-in-out"
74
+ >
75
+ <!-- Close Button -->
76
+ <div class="{{ closeButtonClasses }}">
77
+ <button
78
+ type="button"
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()"
81
+ >
82
+ <span class="absolute -inset-2.5"></span>
83
+ <span class="sr-only">Close panel</span>
84
+ <svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
85
+ <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
86
+ </svg>
87
+ </button>
88
+ </div>
89
+
90
+ <!-- Drawer Content -->
91
+ <div class="relative flex h-full flex-col overflow-y-auto bg-white dark:bg-blue-gray-800 py-6 shadow-xl">
92
+ @if(title)
93
+ <div class="px-4 sm:px-6">
94
+ <h2 class="text-base font-semibold text-gray-900 dark:text-gray-100">
95
+ {{ title }}
96
+ </h2>
97
+ </div>
98
+ @endif
99
+ <div class="relative mt-6 flex-1 px-4 sm:px-6">
100
+ <slot />
101
+ </div>
102
+ </div>
103
+ </div>
104
+ </div>
105
+ </div>
106
+ </div>
107
+ @endif
108
+
109
+ <style>
110
+ @keyframes fadeIn {
111
+ from { opacity: 0; }
112
+ to { opacity: 1; }
113
+ }
114
+
115
+ @keyframes slideIn {
116
+ from {
117
+ transform: {{ position === 'right' ? 'translateX(100%)' : position === 'left' ? 'translateX(-100%)' : position === 'top' ? 'translateY(-100%)' : 'translateY(100%)' }};
118
+ }
119
+ to {
120
+ transform: translate(0, 0);
121
+ }
122
+ }
123
+ </style>
124
+
125
+ <script>
126
+ function handleClose() {
127
+ if (onClose) {
128
+ onClose()
129
+ }
130
+ }
131
+
132
+ function handleBackdropClick() {
133
+ if (onClose) {
134
+ onClose()
135
+ }
136
+ }
137
+ </script>