@stacksjs/components 0.2.35 → 0.2.53

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 (237) hide show
  1. package/dist/Accordion-19x8q4rj.stx +88 -0
  2. package/dist/{Audio-vdmg1258.stx → Audio-hjywk3qc.stx} +4 -4
  3. package/dist/{Avatar-365cvrh4.stx → Avatar-h3jmwcq0.stx} +23 -34
  4. package/dist/{Badge-8m3qete4.stx → Badge-k8dy3d53.stx} +11 -19
  5. package/dist/{Button-3tt4vsqt.stx → Button-1vknasy3.stx} +18 -33
  6. package/dist/Calendar-reny0et7.stx +189 -0
  7. package/dist/{Card-6wdbexqr.stx → Card-c1g1fd1w.stx} +27 -33
  8. package/dist/{Checkbox-p3q3e3nf.stx → Checkbox-zgdmy3p5.stx} +36 -44
  9. package/dist/{Checkout-e4037tyy.stx → Checkout-agt0ngpw.stx} +8 -16
  10. package/dist/Combobox-fdkr6cdq.stx +96 -0
  11. package/dist/{ComboboxButton-8gxwkhdx.stx → ComboboxButton-g76stp1e.stx} +14 -2
  12. package/dist/{ComboboxInput-mk99z65n.stx → ComboboxInput-z1293bbh.stx} +12 -5
  13. package/dist/ComboboxOption-hmxt3gte.stx +49 -0
  14. package/dist/{ListboxOptions-8kqvfp7z.stx → ComboboxOptions-sq5360ae.stx} +2 -2
  15. package/dist/CommandPalette-36mxf05w.stx +81 -0
  16. package/dist/CommandPaletteItem-mvk6q7a2.stx +27 -0
  17. package/dist/Dialog-hczpexs4.stx +37 -0
  18. package/dist/{Drawer-p7m351bn.stx → Drawer-xhevp5cw.stx} +29 -49
  19. package/dist/Dropdown-vvhemtc0.stx +82 -0
  20. package/dist/{DropdownButton-9w8zkfwj.stx → DropdownButton-wcz67dxy.stx} +12 -6
  21. package/dist/DropdownItem-c7rz08e5.stx +35 -0
  22. package/dist/{DropdownItems-aygjpxkx.stx → DropdownItems-1sxnd5qn.stx} +2 -2
  23. package/dist/EmailInput-vak3kkmk.stx +30 -0
  24. package/dist/Form-mas630hy.stx +95 -0
  25. package/dist/{Image-jhkm6w1f.stx → Image-yhxcvgzs.stx} +68 -100
  26. package/dist/Listbox-q49tnr90.stx +101 -0
  27. package/dist/{ListboxButton-spwx7513.stx → ListboxButton-keb8gm0q.stx} +12 -1
  28. package/dist/ListboxOption-e0dtv1gc.stx +49 -0
  29. package/dist/{ComboboxOptions-6b5ywc5x.stx → ListboxOptions-ejkatcfg.stx} +7 -3
  30. package/dist/{Login-rx9gyqhx.stx → Login-gepemsth.stx} +17 -19
  31. package/dist/Navigator-rk2a5wvk.stx +113 -0
  32. package/dist/Notification-tb9b525s.stx +78 -0
  33. package/dist/{NumberInput-nzpkx1ry.stx → NumberInput-drnvtqej.stx} +40 -53
  34. package/dist/{Pagination-h61eq390.stx → Pagination-n3d31cns.stx} +73 -108
  35. package/dist/PasswordInput-n02x6053.stx +142 -0
  36. package/dist/{PaymentMethods-j42jsk5x.stx → PaymentMethods-x4vrx9yb.stx} +21 -30
  37. package/dist/Popover-et2q44m7.stx +60 -0
  38. package/dist/{PopoverButton-fnaqc77g.stx → PopoverButton-mffzc9pr.stx} +12 -6
  39. package/dist/{PopoverPanel-y0vtf5w9.stx → PopoverPanel-054yh38h.stx} +6 -6
  40. package/dist/{Portal-s2q37yp0.stx → Portal-1vf14s4x.stx} +20 -37
  41. package/dist/{Progress-vmdkm06p.stx → Progress-yxcntr4x.stx} +36 -48
  42. package/dist/{Radio-04bs3d21.stx → Radio-cgjv2hb2.stx} +29 -34
  43. package/dist/RadioGroup-qxmnm3xm.stx +60 -0
  44. package/dist/RadioGroupOption-s1d6r221.stx +58 -0
  45. package/dist/SearchInput-pdx7agn0.stx +44 -0
  46. package/dist/{Select-g4mmvfv8.stx → Select-28y0pg83.stx} +23 -31
  47. package/dist/Sidebar-73vc78as.stx +236 -0
  48. package/dist/SidebarFooter-zsfsgcxb.stx +109 -0
  49. package/dist/SidebarHeader-7v174a9c.stx +122 -0
  50. package/dist/SidebarItem-3y3e8g2t.stx +92 -0
  51. package/dist/SidebarSection-z5ey6awe.stx +113 -0
  52. package/dist/{Signup-c4dyv6f3.stx → Signup-hxm5hwkr.stx} +26 -28
  53. package/dist/{StepperStep-en4r00zv.stx → StepperStep-wxgembat.stx} +9 -5
  54. package/dist/{SubscriptionCheckout-gawjzf3q.stx → SubscriptionCheckout-zy2ycrmw.stx} +99 -129
  55. package/dist/Switch-r5t5w04w.stx +70 -0
  56. package/dist/{TableHeader-ydys9rzz.stx → TableHeader-0eyzbqpz.stx} +10 -3
  57. package/dist/Tabs-bzvvn4ke.stx +126 -0
  58. package/dist/Teleport-tsx4bt4n.stx +65 -0
  59. package/dist/{TextInput-k2kfkgy1.stx → TextInput-kf084763.stx} +42 -59
  60. package/dist/{Textarea-szad57dz.stx → Textarea-xg4rr2xz.stx} +42 -54
  61. package/dist/{Tooltip-em7t551n.stx → Tooltip-m0tqd72e.stx} +34 -40
  62. package/dist/Transition-7smenaz8.stx +102 -0
  63. package/dist/{TwoFactorChallenge-an9yvxvq.stx → TwoFactorChallenge-y5m3nk79.stx} +49 -63
  64. package/dist/{Video-crxva65p.stx → Video-84j4pv6h.stx} +4 -4
  65. package/dist/VirtualList-fa7v5a3h.stx +67 -0
  66. package/dist/VirtualTable-f9crbfjr.stx +103 -0
  67. package/dist/components/CodeBlock.stx +1 -6
  68. package/dist/index.js +13 -13
  69. package/dist/ui/accordion/Accordion.stx +1 -3
  70. package/dist/ui/auth/Login.stx +0 -1
  71. package/dist/ui/auth/Signup.stx +0 -1
  72. package/dist/ui/auth/TwoFactorChallenge.stx +1 -3
  73. package/dist/ui/avatar/Avatar.stx +0 -2
  74. package/dist/ui/badge/Badge.stx +0 -1
  75. package/dist/ui/button/Button.stx +1 -2
  76. package/dist/ui/calendar/Calendar.stx +12 -2
  77. package/dist/ui/card/Card.stx +0 -2
  78. package/dist/ui/checkbox/Checkbox.stx +2 -2
  79. package/dist/ui/combobox/Combobox.stx +2 -1
  80. package/dist/ui/combobox/ComboboxButton.stx +1 -0
  81. package/dist/ui/combobox/ComboboxInput.stx +1 -4
  82. package/dist/ui/combobox/ComboboxOption.stx +2 -9
  83. package/dist/ui/combobox/ComboboxOptions.stx +1 -1
  84. package/dist/ui/command-palette/CommandPalette.stx +3 -6
  85. package/dist/ui/command-palette/CommandPaletteItem.stx +2 -7
  86. package/dist/ui/dialog/Dialog.stx +1 -3
  87. package/dist/ui/drawer/Drawer.stx +1 -3
  88. package/dist/ui/dropdown/Dropdown.stx +2 -5
  89. package/dist/ui/dropdown/DropdownButton.stx +1 -3
  90. package/dist/ui/dropdown/DropdownItem.stx +2 -7
  91. package/dist/ui/dropdown/DropdownItems.stx +1 -1
  92. package/dist/ui/form/Form.stx +0 -5
  93. package/dist/ui/image/Image.stx +1 -6
  94. package/dist/ui/input/EmailInput.stx +1 -1
  95. package/dist/ui/input/NumberInput.stx +0 -1
  96. package/dist/ui/input/PasswordInput.stx +1 -4
  97. package/dist/ui/input/SearchInput.stx +2 -2
  98. package/dist/ui/input/TextInput.stx +1 -2
  99. package/dist/ui/listbox/Listbox.stx +2 -1
  100. package/dist/ui/listbox/ListboxButton.stx +1 -0
  101. package/dist/ui/listbox/ListboxOption.stx +2 -9
  102. package/dist/ui/listbox/ListboxOptions.stx +1 -1
  103. package/dist/ui/navigator/Navigator.stx +4 -4
  104. package/dist/ui/notification/Notification.stx +1 -5
  105. package/dist/ui/pagination/Pagination.stx +1 -2
  106. package/dist/ui/payment/Checkout.stx +0 -4
  107. package/dist/ui/payment/PaymentMethods.stx +15 -2
  108. package/dist/ui/payment/SubscriptionCheckout.stx +3 -184
  109. package/dist/ui/popover/Popover.stx +2 -5
  110. package/dist/ui/popover/PopoverButton.stx +1 -3
  111. package/dist/ui/popover/PopoverPanel.stx +1 -1
  112. package/dist/ui/portal/Portal.stx +1 -0
  113. package/dist/ui/progress/Progress.stx +6 -1
  114. package/dist/ui/radio/Radio.stx +1 -1
  115. package/dist/ui/radio-group/RadioGroup.stx +2 -1
  116. package/dist/ui/radio-group/RadioGroupOption.stx +2 -9
  117. package/dist/ui/select/Select.stx +1 -1
  118. package/dist/ui/sidebar/Sidebar.stx +9 -26
  119. package/dist/ui/sidebar/SidebarFooter.stx +6 -21
  120. package/dist/ui/sidebar/SidebarHeader.stx +7 -18
  121. package/dist/ui/sidebar/SidebarItem.stx +4 -20
  122. package/dist/ui/sidebar/SidebarSection.stx +5 -18
  123. package/dist/ui/sidebar/index.d.ts +13 -1
  124. package/dist/ui/stepper/StepperStep.stx +1 -5
  125. package/dist/ui/switch/Switch.stx +4 -10
  126. package/dist/ui/table/TableHeader.stx +1 -1
  127. package/dist/ui/tabs/Tabs.stx +0 -1
  128. package/dist/ui/teleport/Teleport.stx +1 -0
  129. package/dist/ui/textarea/Textarea.stx +1 -1
  130. package/dist/ui/tooltip/Tooltip.stx +1 -2
  131. package/dist/ui/transition/Transition.stx +9 -16
  132. package/dist/ui/virtual-list/VirtualList.stx +2 -4
  133. package/dist/ui/virtual-table/VirtualTable.stx +1 -1
  134. package/package.json +3 -3
  135. package/src/components/CodeBlock.stx +26 -29
  136. package/src/components/Footer.stx +1 -1
  137. package/src/components/Hero.stx +1 -1
  138. package/src/components/Installation.stx +5 -7
  139. package/src/ui/accordion/Accordion.stx +48 -68
  140. package/src/ui/audio/Audio.stx +4 -4
  141. package/src/ui/auth/Login.stx +17 -19
  142. package/src/ui/auth/Signup.stx +26 -28
  143. package/src/ui/auth/TwoFactorChallenge.stx +49 -63
  144. package/src/ui/avatar/Avatar.stx +23 -34
  145. package/src/ui/badge/Badge.stx +11 -19
  146. package/src/ui/button/Button.stx +18 -33
  147. package/src/ui/calendar/Calendar.stx +93 -136
  148. package/src/ui/card/Card.stx +27 -33
  149. package/src/ui/checkbox/Checkbox.stx +36 -44
  150. package/src/ui/combobox/Combobox.stx +87 -4
  151. package/src/ui/combobox/ComboboxButton.stx +14 -2
  152. package/src/ui/combobox/ComboboxInput.stx +12 -5
  153. package/src/ui/combobox/ComboboxOption.stx +29 -32
  154. package/src/ui/combobox/ComboboxOptions.stx +7 -3
  155. package/src/ui/command-palette/CommandPalette.stx +70 -28
  156. package/src/ui/command-palette/CommandPaletteItem.stx +15 -20
  157. package/src/ui/dialog/Dialog.stx +28 -10
  158. package/src/ui/drawer/Drawer.stx +29 -49
  159. package/src/ui/dropdown/Dropdown.stx +69 -11
  160. package/src/ui/dropdown/DropdownButton.stx +12 -6
  161. package/src/ui/dropdown/DropdownItem.stx +18 -26
  162. package/src/ui/dropdown/DropdownItems.stx +2 -2
  163. package/src/ui/form/Form.stx +50 -164
  164. package/src/ui/heatmap/Heatmap.stx +16 -37
  165. package/src/ui/image/Image.stx +68 -100
  166. package/src/ui/input/EmailInput.stx +16 -27
  167. package/src/ui/input/NumberInput.stx +40 -53
  168. package/src/ui/input/PasswordInput.stx +64 -77
  169. package/src/ui/input/SearchInput.stx +27 -46
  170. package/src/ui/input/TextInput.stx +42 -59
  171. package/src/ui/listbox/Listbox.stx +91 -4
  172. package/src/ui/listbox/ListboxButton.stx +12 -1
  173. package/src/ui/listbox/ListboxOption.stx +30 -38
  174. package/src/ui/listbox/ListboxOptions.stx +2 -2
  175. package/src/ui/navigator/Navigator.stx +52 -77
  176. package/src/ui/notification/Notification.stx +46 -39
  177. package/src/ui/pagination/Pagination.stx +73 -108
  178. package/src/ui/payment/Checkout.stx +8 -16
  179. package/src/ui/payment/PaymentMethods.stx +21 -30
  180. package/src/ui/payment/SubscriptionCheckout.stx +99 -129
  181. package/src/ui/popover/Popover.stx +50 -14
  182. package/src/ui/popover/PopoverButton.stx +12 -6
  183. package/src/ui/popover/PopoverPanel.stx +6 -6
  184. package/src/ui/portal/Portal.stx +20 -37
  185. package/src/ui/progress/Progress.stx +36 -48
  186. package/src/ui/radio/Radio.stx +29 -34
  187. package/src/ui/radio-group/RadioGroup.stx +51 -4
  188. package/src/ui/radio-group/RadioGroupOption.stx +37 -30
  189. package/src/ui/select/Select.stx +23 -31
  190. package/src/ui/sidebar/Sidebar.stx +136 -188
  191. package/src/ui/sidebar/SidebarFooter.stx +49 -35
  192. package/src/ui/sidebar/SidebarHeader.stx +52 -30
  193. package/src/ui/sidebar/SidebarItem.stx +52 -78
  194. package/src/ui/sidebar/SidebarSection.stx +56 -51
  195. package/src/ui/sidebar/index.ts +21 -1
  196. package/src/ui/stepper/StepperStep.stx +9 -5
  197. package/src/ui/switch/Switch.stx +38 -42
  198. package/src/ui/table/TableHeader.stx +10 -3
  199. package/src/ui/tabs/Tabs.stx +68 -87
  200. package/src/ui/teleport/Teleport.stx +23 -59
  201. package/src/ui/textarea/Textarea.stx +42 -54
  202. package/src/ui/tooltip/Tooltip.stx +34 -40
  203. package/src/ui/transition/Transition.stx +76 -148
  204. package/src/ui/video/Video.stx +4 -4
  205. package/src/ui/virtual-list/VirtualList.stx +45 -61
  206. package/src/ui/virtual-table/VirtualTable.stx +62 -72
  207. package/dist/Accordion-sbfra0mz.stx +0 -108
  208. package/dist/Calendar-58nnkdh8.stx +0 -232
  209. package/dist/Combobox-th5ebw62.stx +0 -13
  210. package/dist/ComboboxOption-an9zyan6.stx +0 -52
  211. package/dist/CommandPalette-kwmdf2np.stx +0 -39
  212. package/dist/CommandPaletteItem-zx2fbpts.stx +0 -32
  213. package/dist/Dialog-rgmj8q2j.stx +0 -19
  214. package/dist/Dropdown-jz4jy0n3.stx +0 -24
  215. package/dist/DropdownItem-wagdspb8.stx +0 -43
  216. package/dist/EmailInput-ajsp9vw6.stx +0 -41
  217. package/dist/Form-1mdmx9b6.stx +0 -209
  218. package/dist/Listbox-pqqh72g8.stx +0 -14
  219. package/dist/ListboxOption-7nxzaexq.stx +0 -57
  220. package/dist/Navigator-aay8bjab.stx +0 -138
  221. package/dist/Notification-gk33gv7b.stx +0 -71
  222. package/dist/PasswordInput-zv4hm43j.stx +0 -155
  223. package/dist/Popover-469gbt6r.stx +0 -24
  224. package/dist/RadioGroup-bvb1mrhd.stx +0 -13
  225. package/dist/RadioGroupOption-cpdwgnhw.stx +0 -51
  226. package/dist/SearchInput-2521m475.stx +0 -63
  227. package/dist/Sidebar-40ckbzh8.stx +0 -288
  228. package/dist/SidebarFooter-hnth56mg.stx +0 -95
  229. package/dist/SidebarHeader-3wrte2p2.stx +0 -100
  230. package/dist/SidebarItem-zqtvvzpc.stx +0 -118
  231. package/dist/SidebarSection-3etwnbjr.stx +0 -108
  232. package/dist/Switch-036j9vm1.stx +0 -74
  233. package/dist/Tabs-svh721m0.stx +0 -145
  234. package/dist/Teleport-qfch3w0b.stx +0 -101
  235. package/dist/Transition-0hmr6zxb.stx +0 -174
  236. package/dist/VirtualList-cndhjejh.stx +0 -83
  237. package/dist/VirtualTable-ng0b48yp.stx +0 -113
@@ -1,6 +1,5 @@
1
1
  <script server>
2
2
  export const checked = $props.checked || false
3
- export const onChange = $props.onChange || (() => {})
4
3
  export const disabled = $props.disabled || false
5
4
  export const indeterminate = $props.indeterminate || false
6
5
  export const size = $props.size || 'md'
@@ -12,42 +11,55 @@ export const value = $props.value || ''
12
11
  export const name = $props.name || ''
13
12
  export const className = $props.className || ''
14
13
 
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
14
+ const sizeClasses = { sm: 'h-4 w-4', md: 'h-5 w-5', lg: 'h-6 w-6' }
23
15
  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'
16
+ const stateClasses = error ? 'border-red-300 dark:border-red-600 text-red-600 dark:text-red-500 focus:ring-red-500 dark:focus:ring-red-400' : ''
17
+ const disabledClasses = disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'
32
18
 
33
19
  export const checkboxClasses = `${baseClasses} ${sizeClasses[size]} ${stateClasses} ${disabledClasses}`.trim()
34
20
  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
21
  export const descriptionClasses = `text-sm ${error ? 'text-red-500 dark:text-red-400' : 'text-gray-500 dark:text-gray-400'}`.trim()
22
+ export const inputId = `checkbox-${value || label}`
23
+ </script>
24
+
25
+ <script client>
26
+ const emit = defineEmits()
27
+ const isDisabled = {{ disabled }}
28
+ const isIndeterminate = {{ indeterminate }}
29
+ const isChecked = state({{ checked }})
30
+
31
+ function onInputChange(event) {
32
+ if (isDisabled) {
33
+ event.target.checked = isChecked()
34
+ return
35
+ }
36
+ isChecked.set(event.target.checked)
37
+ emit('change', isChecked())
38
+ }
39
+
40
+ onMount(() => {
41
+ if (isIndeterminate) {
42
+ const el = document.getElementById({{ inputId }})
43
+ if (el) el.indeterminate = true
44
+ }
45
+ })
46
+
47
+ defineExpose({ isChecked })
36
48
  </script>
37
49
 
38
50
  <div class="relative flex items-start {{ className }}">
39
51
  <div class="flex h-6 items-center">
40
52
  <input
41
- id="checkbox-{{ value || label }}"
53
+ id="{{ inputId }}"
42
54
  type="checkbox"
43
55
  name="{{ name }}"
44
56
  value="{{ value }}"
45
- checked="{{ checked }}"
46
- disabled="{{ disabled }}"
47
- required="{{ required }}"
57
+ :checked="isChecked()"
58
+ @if(disabled)disabled@endif
59
+ @if(required)required@endif
48
60
  class="{{ checkboxClasses }}"
49
- onchange="handleChange(event)"
50
- aria-invalid="{{ error ? 'true' : 'false' }}"
61
+ @change="onInputChange($event)"
62
+ :aria-invalid="{{ error ? 'true' : 'false' }}"
51
63
  @if(description)aria-describedby="checkbox-description"@endif
52
64
  />
53
65
  </div>
@@ -55,7 +67,7 @@ export const descriptionClasses = `text-sm ${error ? 'text-red-500 dark:text-red
55
67
  @if(label || description)
56
68
  <div class="ml-3 text-sm leading-6">
57
69
  @if(label)
58
- <label for="checkbox-{{ value || label }}" class="{{ labelClasses }}">
70
+ <label for="{{ inputId }}" class="{{ labelClasses }}">
59
71
  {{ label }}
60
72
  @if(required)
61
73
  <span class="text-red-500 ml-1">*</span>
@@ -70,23 +82,3 @@ export const descriptionClasses = `text-sm ${error ? 'text-red-500 dark:text-red
70
82
  </div>
71
83
  @endif
72
84
  </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>
@@ -1,36 +1,28 @@
1
1
  <script server>
2
2
  export const products = $props.products || []
3
- export const redirectUrl = $props.redirectUrl || ''
4
3
  export const mode = $props.mode || 'subscription'
5
4
  export const stripePublicKey = $props.stripePublicKey || ''
6
5
  export const apiUrl = $props.apiUrl || ''
7
- export const onSubmit = $props.onSubmit
8
- export const onRemoveProduct = $props.onRemoveProduct
9
6
  export const shipping = $props.shipping || 0
10
7
  export const taxes = $props.taxes || 0
11
8
  export const className = $props.className || ''
12
9
 
13
- // For future expansion - one-time payment support
14
10
  export const isSubscription = mode === 'subscription'
15
11
  export const isOneTime = mode === 'one-time'
16
12
  </script>
17
13
 
18
14
  @if(isSubscription)
19
- @component('SubscriptionCheckout', {
20
- products,
21
- stripePublicKey,
22
- apiUrl,
23
- onSubmit,
24
- onRemoveProduct,
25
- shipping,
26
- taxes,
27
- className
28
- })
29
- @endcomponent
15
+ <SubscriptionCheckout
16
+ :products="products"
17
+ :stripePublicKey="stripePublicKey"
18
+ :apiUrl="apiUrl"
19
+ :shipping="shipping"
20
+ :taxes="taxes"
21
+ :className="className"
22
+ />
30
23
  @endif
31
24
 
32
25
  @if(isOneTime)
33
- <!-- One-time payment component can be implemented here in the future -->
34
26
  <div class="p-8 text-center">
35
27
  <p class="text-gray-600 dark:text-gray-400">
36
28
  One-time payment mode is not yet implemented.
@@ -0,0 +1,96 @@
1
+ <script server>
2
+ export const value = $props.value
3
+ export const className = $props.className || ''
4
+ export const as = $props.as || 'div'
5
+
6
+ const baseClasses = 'relative'
7
+ export const comboboxClasses = `${baseClasses} ${className}`.trim()
8
+ export const comboboxInstanceId = `stx-cb-${Math.random().toString(36).slice(2, 11)}`
9
+ </script>
10
+
11
+ <script client>
12
+ const emit = defineEmits()
13
+ const comboboxInstanceId = {{ comboboxInstanceId }}
14
+ const initialValue = {{ value === undefined ? 'null' : value }}
15
+
16
+ const isOpen = state(false)
17
+ const selected = state(initialValue)
18
+ const query = state('')
19
+ let rootEl = null
20
+ let outsideHandler = null
21
+
22
+ function isSelectedValue(v) {
23
+ return selected() === v
24
+ }
25
+
26
+ function selectValue(v) {
27
+ selected.set(v)
28
+ isOpen.set(false)
29
+ syncOptionStates()
30
+ emit('change', v)
31
+ }
32
+
33
+ function syncOptionStates() {
34
+ if (!rootEl) return
35
+ const options = rootEl.querySelectorAll('[data-stx-combobox-option]')
36
+ for (const opt of options) {
37
+ const raw = opt.dataset.optionValue
38
+ let v
39
+ try { v = JSON.parse(raw ?? 'null') }
40
+ catch { v = raw }
41
+ const sel = isSelectedValue(v)
42
+ opt.setAttribute('aria-selected', sel ? 'true' : 'false')
43
+ opt.setAttribute('data-selected', sel ? 'true' : 'false')
44
+ }
45
+ }
46
+
47
+ function open() { if (!isOpen()) { isOpen.set(true) } }
48
+ function close() { if (isOpen()) isOpen.set(false) }
49
+ function toggle() { isOpen() ? close() : open() }
50
+
51
+ function onToggle(event) { event.stopPropagation(); toggle() }
52
+ function onSelect(event) { event.stopPropagation(); selectValue(event.detail) }
53
+ function onQuery(event) {
54
+ event.stopPropagation()
55
+ query.set(event.detail)
56
+ if (!isOpen()) open()
57
+ emit('query', event.detail)
58
+ }
59
+
60
+ onMount(() => {
61
+ rootEl = document.querySelector(`[data-combobox-id="${comboboxInstanceId}"]`)
62
+ syncOptionStates()
63
+ outsideHandler = (event) => {
64
+ if (!isOpen()) return
65
+ if (rootEl && !rootEl.contains(event.target)) close()
66
+ }
67
+ document.addEventListener('click', outsideHandler, true)
68
+ })
69
+
70
+ onDestroy(() => {
71
+ if (outsideHandler) document.removeEventListener('click', outsideHandler, true)
72
+ })
73
+
74
+ const dataState = derived(() => isOpen() ? 'open' : 'closed')
75
+
76
+ defineExpose({ isOpen, selected, query, toggle, open, close, selectValue })
77
+ </script>
78
+
79
+ <component
80
+ :is="{{ as }}"
81
+ class="{{ comboboxClasses }}"
82
+ data-stx-combobox
83
+ data-combobox-id="{{ comboboxInstanceId }}"
84
+ :data-state="dataState()"
85
+ @stx:combobox-toggle="onToggle($event)"
86
+ @stx:combobox-select="onSelect($event)"
87
+ @stx:combobox-query="onQuery($event)"
88
+ >
89
+ <slot />
90
+ </component>
91
+
92
+ <style>
93
+ [data-stx-combobox][data-state="closed"] [data-stx-combobox-options] {
94
+ display: none;
95
+ }
96
+ </style>
@@ -3,10 +3,22 @@ export const className = $props.className || ''
3
3
  export const as = $props.as || 'button'
4
4
 
5
5
  const baseClasses = 'absolute inset-y-0 right-0 flex items-center pr-2'
6
- const buttonClasses = `${baseClasses} ${className}`.trim()
6
+ export const buttonClasses = `${baseClasses} ${className}`.trim()
7
7
  </script>
8
8
 
9
- <component :is="{{ as }}" class="{{ buttonClasses }}" tabindex="-1">
9
+ <script client>
10
+ function onClick(event) {
11
+ event.currentTarget.dispatchEvent(new CustomEvent('stx:combobox-toggle', { bubbles: true }))
12
+ }
13
+ </script>
14
+
15
+ <component
16
+ :is="{{ as }}"
17
+ class="{{ buttonClasses }}"
18
+ data-stx-combobox-button
19
+ tabindex="-1"
20
+ @click="onClick($event)"
21
+ >
10
22
  <svg class="h-5 w-5 text-neutral-400" viewBox="0 0 20 20" fill="none" stroke="currentColor">
11
23
  <path d="M7 7l3-3 3 3m0 6l-3 3-3-3" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
12
24
  </svg>
@@ -1,25 +1,32 @@
1
1
  <script server>
2
2
  export const displayValue = $props.displayValue
3
- export const onChange = $props.onChange
4
3
  export const className = $props.className || ''
5
4
  export const placeholder = $props.placeholder || ''
6
5
  export const disabled = $props.disabled || false
7
6
 
8
7
  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
8
  const disabledClasses = disabled ? 'opacity-50 cursor-not-allowed' : ''
10
- const inputClasses = `${baseClasses} ${disabledClasses} ${className}`.trim()
9
+ export const inputClasses = `${baseClasses} ${disabledClasses} ${className}`.trim()
10
+ </script>
11
+
12
+ <script client>
13
+ const isDisabled = {{ disabled }}
11
14
 
12
- export function handleChange(e) {
13
- onChange?.(e.target.value)
15
+ function onInput(event) {
16
+ if (isDisabled) return
17
+ event.currentTarget.dispatchEvent(
18
+ new CustomEvent('stx:combobox-query', { bubbles: true, detail: event.target.value }),
19
+ )
14
20
  }
15
21
  </script>
16
22
 
17
23
  <input
18
24
  type="text"
19
25
  class="{{ inputClasses }}"
26
+ data-stx-combobox-input
20
27
  placeholder="{{ placeholder }}"
21
28
  value="{{ displayValue }}"
22
29
  @if(disabled)disabled@endif
23
- @input="handleChange"
30
+ @input="onInput($event)"
24
31
  autocomplete="off"
25
32
  />
@@ -0,0 +1,49 @@
1
+ <script server>
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
+
7
+ const baseClasses = 'relative cursor-pointer select-none py-2 pl-10 pr-4 text-neutral-900 dark:text-neutral-100 hover:bg-blue-100 dark:hover:bg-blue-900'
8
+ const disabledClasses = disabled ? 'opacity-50 cursor-not-allowed' : ''
9
+ export const optionClasses = `${baseClasses} ${disabledClasses} ${className}`.trim()
10
+ export const valueJson = JSON.stringify(value === undefined ? null : value)
11
+ </script>
12
+
13
+ <script client>
14
+ const isDisabled = {{ disabled }}
15
+ const optionValue = {{ value === undefined ? 'null' : value }}
16
+
17
+ function onClick(event) {
18
+ if (isDisabled) return
19
+ event.currentTarget.dispatchEvent(
20
+ new CustomEvent('stx:combobox-select', { bubbles: true, detail: optionValue }),
21
+ )
22
+ }
23
+ </script>
24
+
25
+ <component
26
+ :is="{{ as }}"
27
+ class="{{ optionClasses }}"
28
+ data-stx-combobox-option
29
+ data-option-value="{{ valueJson }}"
30
+ role="option"
31
+ aria-selected="false"
32
+ @if(disabled)aria-disabled="true"@endif
33
+ @click="onClick($event)"
34
+ >
35
+ <span class="absolute inset-y-0 left-0 flex items-center pl-3 text-blue-600 dark:text-blue-400" data-stx-combobox-check>
36
+ <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
37
+ <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" />
38
+ </svg>
39
+ </span>
40
+
41
+ <slot :disabled="disabled" />
42
+ </component>
43
+
44
+ <style>
45
+ [data-stx-combobox-option][data-selected="false"] [data-stx-combobox-check],
46
+ [data-stx-combobox-option]:not([data-selected]) [data-stx-combobox-check] {
47
+ display: none;
48
+ }
49
+ </style>
@@ -1,15 +1,15 @@
1
1
  <script server>
2
2
  export const className = $props.className || ''
3
3
  export const as = $props.as || 'ul'
4
- export const static_ = $props.static || false
5
4
 
6
5
  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()
6
+ export const optionsClasses = `${baseClasses} ${className}`.trim()
8
7
  </script>
9
8
 
10
9
  <component
11
10
  :is="{{ as }}"
12
11
  class="{{ optionsClasses }}"
12
+ data-stx-combobox-options
13
13
  role="listbox"
14
14
  >
15
15
  <slot />
@@ -0,0 +1,81 @@
1
+ <script server>
2
+ export const open = $props.open || false
3
+ export const initialQuery = $props.query || ''
4
+ export const className = $props.className || ''
5
+
6
+ const baseClasses = 'fixed inset-0 z-50 overflow-y-auto p-4 sm:p-6 md:p-20'
7
+ export const paletteClasses = `${baseClasses} ${className}`.trim()
8
+ export const paletteInstanceId = `stx-cmd-${Math.random().toString(36).slice(2, 11)}`
9
+ </script>
10
+
11
+ <script client>
12
+ const emit = defineEmits()
13
+ const paletteInstanceId = {{ paletteInstanceId }}
14
+ const isOpen = state({{ open }})
15
+ const query = state({{ initialQuery }})
16
+ let escHandler = null
17
+
18
+ function close() {
19
+ if (!isOpen()) return
20
+ isOpen.set(false)
21
+ emit('close')
22
+ }
23
+
24
+ function show() {
25
+ if (isOpen()) return
26
+ isOpen.set(true)
27
+ }
28
+
29
+ function onQueryInput(event) {
30
+ query.set(event.target.value)
31
+ emit('query', event.target.value)
32
+ }
33
+
34
+ function onItemSelect(event) {
35
+ event.stopPropagation()
36
+ emit('select', event.detail)
37
+ close()
38
+ }
39
+
40
+ onMount(() => {
41
+ escHandler = (event) => {
42
+ if (event.key === 'Escape' && isOpen()) close()
43
+ }
44
+ document.addEventListener('keydown', escHandler)
45
+ })
46
+
47
+ onDestroy(() => {
48
+ if (escHandler) document.removeEventListener('keydown', escHandler)
49
+ })
50
+
51
+ defineExpose({ isOpen, query, show, close })
52
+ </script>
53
+
54
+ <div
55
+ :show="isOpen()"
56
+ class="{{ paletteClasses }}"
57
+ data-stx-command-palette
58
+ data-palette-id="{{ paletteInstanceId }}"
59
+ @stx:command-select="onItemSelect($event)"
60
+ >
61
+ <div class="fixed inset-0 bg-neutral-500 bg-opacity-25 dark:bg-opacity-50 transition-opacity" @click="close()"></div>
62
+
63
+ <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 relative">
64
+ <div class="relative">
65
+ <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">
66
+ <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" />
67
+ </svg>
68
+ <input
69
+ type="text"
70
+ 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"
71
+ placeholder="Search..."
72
+ :value="query()"
73
+ @input="onQueryInput($event)"
74
+ />
75
+ </div>
76
+
77
+ <div class="max-h-96 overflow-y-auto py-2">
78
+ <slot />
79
+ </div>
80
+ </div>
81
+ </div>
@@ -0,0 +1,27 @@
1
+ <script server>
2
+ export const className = $props.className || ''
3
+ export const value = $props.value
4
+
5
+ const baseClasses = 'flex cursor-pointer select-none items-center px-4 py-2 text-neutral-900 dark:text-neutral-100 hover:bg-blue-600 hover:text-white'
6
+ export const itemClasses = `${baseClasses} ${className}`.trim()
7
+ </script>
8
+
9
+ <script client>
10
+ const emit = defineEmits()
11
+ const itemValue = {{ value === undefined ? 'null' : value }}
12
+
13
+ function onClick(event) {
14
+ emit('click', event)
15
+ event.currentTarget.dispatchEvent(
16
+ new CustomEvent('stx:command-select', { bubbles: true, detail: itemValue }),
17
+ )
18
+ }
19
+ </script>
20
+
21
+ <div
22
+ class="{{ itemClasses }}"
23
+ data-stx-command-item
24
+ @click="onClick($event)"
25
+ >
26
+ <slot />
27
+ </div>
@@ -0,0 +1,37 @@
1
+ <script server>
2
+ export const open = $props.open || false
3
+ export const className = $props.className || ''
4
+
5
+ const baseClasses = 'relative z-50'
6
+ export const dialogClasses = `${baseClasses} ${className}`.trim()
7
+ </script>
8
+
9
+ <script client>
10
+ const emit = defineEmits()
11
+ const isOpen = state({{ open }})
12
+
13
+ function close() {
14
+ isOpen.set(false)
15
+ emit('close')
16
+ }
17
+
18
+ function onBackdropKey(event) {
19
+ if (event.key === 'Escape') close()
20
+ }
21
+
22
+ defineExpose({
23
+ open: () => isOpen.set(true),
24
+ close,
25
+ isOpen,
26
+ })
27
+ </script>
28
+
29
+ <div
30
+ :show="isOpen()"
31
+ class="{{ dialogClasses }}"
32
+ role="dialog"
33
+ aria-modal="true"
34
+ @keydown="onBackdropKey($event)"
35
+ >
36
+ <slot />
37
+ </div>
@@ -1,11 +1,9 @@
1
1
  <script server>
2
2
  export const open = $props.open ?? false
3
- export const onClose = $props.onClose || (() => {})
4
3
  export const position = $props.position || 'right'
5
4
  export const title = $props.title || ''
6
5
  export const className = $props.className || ''
7
6
 
8
- // Position classes
9
7
  const positionClasses = {
10
8
  right: 'inset-y-0 right-0 pl-10 sm:pl-16',
11
9
  left: 'inset-y-0 left-0 pr-10 sm:pr-16',
@@ -13,27 +11,6 @@ const positionClasses = {
13
11
  bottom: 'inset-x-0 bottom-0 pt-10',
14
12
  }
15
13
 
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
14
  const sizeClasses = {
38
15
  right: 'max-w-md w-screen',
39
16
  left: 'max-w-md w-screen',
@@ -41,7 +18,6 @@ const sizeClasses = {
41
18
  bottom: 'max-h-[90vh] w-full',
42
19
  }
43
20
 
44
- // Close button position
45
21
  const closeButtonPosition = {
46
22
  right: 'left-0 -ml-8 sm:-ml-10',
47
23
  left: 'right-0 -mr-8 sm:-mr-10',
@@ -51,33 +27,52 @@ const closeButtonPosition = {
51
27
 
52
28
  export const containerClasses = `pointer-events-none fixed ${positionClasses[position]} flex max-w-full`.trim()
53
29
  export const panelClasses = `pointer-events-auto relative ${sizeClasses[position]} ${className}`.trim()
54
- export const slideAnimation = slideClasses[position]
55
30
  export const closeButtonClasses = `absolute top-0 ${closeButtonPosition[position]} flex pt-4 pr-2 sm:pr-4`.trim()
56
31
  </script>
57
32
 
58
- @if(open)
59
- <!-- Backdrop -->
33
+ <script client>
34
+ const emit = defineEmits()
35
+ const isOpen = state({{ open }})
36
+
37
+ function close() {
38
+ isOpen.set(false)
39
+ emit('close')
40
+ }
41
+
42
+ function onBackdropClick() {
43
+ close()
44
+ }
45
+
46
+ function onPanelKey(event) {
47
+ if (event.key === 'Escape') close()
48
+ }
49
+
50
+ defineExpose({
51
+ open: () => isOpen.set(true),
52
+ close,
53
+ isOpen,
54
+ })
55
+ </script>
56
+
57
+ <div :show="isOpen()">
60
58
  <div
61
59
  class="fixed inset-0 z-50 bg-gray-500/75 dark:bg-gray-900/75 transition-opacity duration-500"
62
60
  style="animation: fadeIn 0.5s ease-in-out"
63
- @click="handleBackdropClick()"
61
+ @click="onBackdropClick()"
64
62
  ></div>
65
63
 
66
- <!-- Drawer Container -->
67
- <div class="fixed inset-0 z-50 overflow-hidden">
64
+ <div class="fixed inset-0 z-50 overflow-hidden" @keydown="onPanelKey($event)">
68
65
  <div class="absolute inset-0 overflow-hidden">
69
66
  <div class="{{ containerClasses }}">
70
- <!-- Drawer Panel -->
71
67
  <div
72
68
  class="{{ panelClasses }}"
73
69
  style="animation: slideIn 0.5s ease-in-out"
74
70
  >
75
- <!-- Close Button -->
76
71
  <div class="{{ closeButtonClasses }}">
77
72
  <button
78
73
  type="button"
79
74
  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
- @click="handleClose()"
75
+ @click="close()"
81
76
  >
82
77
  <span class="absolute -inset-2.5"></span>
83
78
  <span class="sr-only">Close panel</span>
@@ -87,7 +82,6 @@ export const closeButtonClasses = `absolute top-0 ${closeButtonPosition[position
87
82
  </button>
88
83
  </div>
89
84
 
90
- <!-- Drawer Content -->
91
85
  <div class="relative flex h-full flex-col overflow-y-auto bg-white dark:bg-blue-gray-800 py-6 shadow-xl">
92
86
  @if(title)
93
87
  <div class="px-4 sm:px-6">
@@ -104,7 +98,7 @@ export const closeButtonClasses = `absolute top-0 ${closeButtonPosition[position
104
98
  </div>
105
99
  </div>
106
100
  </div>
107
- @endif
101
+ </div>
108
102
 
109
103
  <style>
110
104
  @keyframes fadeIn {
@@ -121,17 +115,3 @@ export const closeButtonClasses = `absolute top-0 ${closeButtonPosition[position
121
115
  }
122
116
  }
123
117
  </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>