@stacksjs/components 0.2.35 → 0.2.54

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 +5 -5
  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
@@ -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:listbox-select', { bubbles: true, detail: optionValue }),
21
+ )
22
+ }
23
+ </script>
24
+
25
+ <component
26
+ :is="{{ as }}"
27
+ class="{{ optionClasses }}"
28
+ data-stx-listbox-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-listbox-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-listbox-option][data-selected="false"] [data-stx-listbox-check],
46
+ [data-stx-listbox-option]:not([data-selected]) [data-stx-listbox-check] {
47
+ display: none;
48
+ }
49
+ </style>
@@ -1,12 +1,16 @@
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
- <component :is="{{ as }}" class="{{ optionsClasses }}" role="listbox">
9
+ <component
10
+ :is="{{ as }}"
11
+ class="{{ optionsClasses }}"
12
+ data-stx-listbox-options
13
+ role="listbox"
14
+ >
11
15
  <slot />
12
16
  </component>
@@ -6,12 +6,27 @@ export const showRememberMe = $props.showRememberMe ?? true
6
6
  export const showForgotPassword = $props.showForgotPassword ?? true
7
7
  export const showSignup = $props.showSignup ?? true
8
8
  export const signupText = $props.signupText || 'Start a 14 day free trial'
9
- export const onSubmit = $props.onSubmit || (() => {})
10
9
  export const className = $props.className || ''
11
10
 
12
11
  export const containerClasses = `min-h-full flex flex-col justify-center py-12 lg:px-8 sm:px-6 dark:bg-blue-gray-900 ${className}`.trim()
13
12
  </script>
14
13
 
14
+ <script client>
15
+ const emit = defineEmits()
16
+
17
+ function onSubmit(event) {
18
+ event.preventDefault()
19
+ const formData = new FormData(event.target)
20
+ const email = formData.get('email')
21
+ const password = formData.get('password')
22
+ emit('submit', { email, password })
23
+ setTimeout(() => {
24
+ const pw = event.target.querySelector('#password')
25
+ if (pw) pw.value = ''
26
+ }, 1000)
27
+ }
28
+ </script>
29
+
15
30
  <div class="{{ containerClasses }}">
16
31
  <div class="sm:mx-auto sm:max-w-md sm:w-full">
17
32
  @if(showLogo)
@@ -22,7 +37,7 @@ export const containerClasses = `min-h-full flex flex-col justify-center py-12 l
22
37
  </h2>
23
38
  </div>
24
39
 
25
- <form onsubmit="event.preventDefault(); handleSubmit(event)">
40
+ <form @submit="onSubmit($event)">
26
41
  <div class="mt-10 sm:mx-auto sm:max-w-[480px] sm:w-full">
27
42
  <div class="bg-white dark:bg-blue-gray-800 px-6 py-12 shadow sm:rounded-lg sm:px-12">
28
43
  <div class="space-y-6">
@@ -144,20 +159,3 @@ export const containerClasses = `min-h-full flex flex-col justify-center py-12 l
144
159
  </div>
145
160
  </form>
146
161
  </div>
147
-
148
- <script>
149
- function handleSubmit(event) {
150
- const formData = new FormData(event.target)
151
- const email = formData.get('email')
152
- const password = formData.get('password')
153
-
154
- if (onSubmit) {
155
- onSubmit({ email, password })
156
- }
157
-
158
- // Clear password after submission
159
- setTimeout(() => {
160
- event.target.querySelector('#password').value = ''
161
- }, 1000)
162
- }
163
- </script>
@@ -0,0 +1,113 @@
1
+ <script server>
2
+ export const items = $props.items || []
3
+ export const active = $props.active || ''
4
+ export const orientation = $props.orientation || 'horizontal'
5
+ export const variant = $props.variant || 'default'
6
+ export const size = $props.size || 'md'
7
+ export const className = $props.className || ''
8
+
9
+ const containerBaseClasses = orientation === 'horizontal' ? 'flex items-center' : 'flex flex-col'
10
+ export const containerClasses = `${containerBaseClasses} ${className}`.trim()
11
+ export const gapClasses = orientation === 'horizontal' ? 'gap-1' : 'gap-0.5'
12
+ </script>
13
+
14
+ <script client>
15
+ const emit = defineEmits()
16
+ const items = {{ items }}
17
+ const variant = {{ variant }}
18
+ const size = {{ size }}
19
+ const initialActive = {{ active }}
20
+ const activeKey = state(initialActive)
21
+
22
+ function isActive(item) {
23
+ const a = activeKey()
24
+ if (typeof item.href === 'string' && typeof a === 'string') {
25
+ if (item.href === a) return true
26
+ if (a.startsWith(item.href)) return true
27
+ }
28
+ if (item.id && item.id === a) return true
29
+ return false
30
+ }
31
+
32
+ function getItemClasses(item) {
33
+ const isActiveItem = isActive(item)
34
+ const sizeClasses = { sm: 'px-2 py-1 text-sm', md: 'px-3 py-2 text-base', lg: 'px-4 py-3 text-lg' }
35
+ let cls = sizeClasses[size] || sizeClasses.md
36
+ if (variant === 'default') {
37
+ cls += isActiveItem
38
+ ? ' text-gray-900 dark:text-gray-100 font-medium'
39
+ : ' text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100'
40
+ }
41
+ else if (variant === 'pills') {
42
+ cls += isActiveItem
43
+ ? ' bg-blue-600 text-white font-medium rounded-full'
44
+ : ' text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-full'
45
+ }
46
+ else if (variant === 'underline') {
47
+ cls += isActiveItem
48
+ ? ' text-blue-600 dark:text-blue-400 font-medium border-b-2 border-blue-600 dark:border-blue-400'
49
+ : ' text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 border-b-2 border-transparent'
50
+ }
51
+ else if (variant === 'sidebar') {
52
+ cls += isActiveItem
53
+ ? ' bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400 font-medium border-l-4 border-blue-600 dark:border-blue-400'
54
+ : ' text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 border-l-4 border-transparent'
55
+ }
56
+ cls += ' transition-all duration-200 cursor-pointer flex items-center gap-2'
57
+ if (item.disabled) cls += ' opacity-50 cursor-not-allowed pointer-events-none'
58
+ return cls.trim()
59
+ }
60
+
61
+ function onClickItem(item, event) {
62
+ if (item.disabled) {
63
+ event.preventDefault()
64
+ return
65
+ }
66
+ event.preventDefault()
67
+ activeKey.set(item.href || item.id || activeKey())
68
+ emit('navigate', item)
69
+ }
70
+
71
+ defineExpose({ activeKey })
72
+ </script>
73
+
74
+ <nav class="{{ containerClasses }} {{ gapClasses }}" role="navigation" aria-label="Main navigation">
75
+ @foreach(item in items)
76
+ @if(item.href)
77
+ <a
78
+ href="{{ item.href }}"
79
+ :class="getItemClasses({{ JSON.stringify(item) }})"
80
+ @click="onClickItem({{ JSON.stringify(item) }}, $event)"
81
+ :aria-current="isActive({{ JSON.stringify(item) }}) ? 'page' : null"
82
+ @if(item.disabled)aria-disabled="true" tabindex="-1"@endif
83
+ >
84
+ @if(item.icon)
85
+ <span class="flex-shrink-0">{!! item.icon !!}</span>
86
+ @endif
87
+ <span>{{ item.label }}</span>
88
+ @if(item.badge)
89
+ <span class="ml-auto px-2 py-0.5 text-xs font-semibold rounded-full bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300">
90
+ {{ item.badge }}
91
+ </span>
92
+ @endif
93
+ </a>
94
+ @else
95
+ <button
96
+ type="button"
97
+ :class="getItemClasses({{ JSON.stringify(item) }})"
98
+ @click="onClickItem({{ JSON.stringify(item) }}, $event)"
99
+ @if(item.disabled)disabled aria-disabled="true"@endif
100
+ >
101
+ @if(item.icon)
102
+ <span class="flex-shrink-0">{!! item.icon !!}</span>
103
+ @endif
104
+ <span>{{ item.label }}</span>
105
+ @if(item.badge)
106
+ <span class="ml-auto px-2 py-0.5 text-xs font-semibold rounded-full bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300">
107
+ {{ item.badge }}
108
+ </span>
109
+ @endif
110
+ </button>
111
+ @endif
112
+ @endforeach
113
+ </nav>
@@ -0,0 +1,78 @@
1
+ <script server>
2
+ export const show = $props.show !== false
3
+ export const title = $props.title || ''
4
+ export const message = $props.message || ''
5
+ export const type = $props.type || 'info'
6
+ export const position = $props.position || 'top-right'
7
+ export const duration = $props.duration || 5000
8
+ export const className = $props.className || ''
9
+
10
+ const typeColors = {
11
+ info: 'bg-blue-50 text-blue-900 dark:bg-blue-900 dark:text-blue-100',
12
+ success: 'bg-green-50 text-green-900 dark:bg-green-900 dark:text-green-100',
13
+ warning: 'bg-yellow-50 text-yellow-900 dark:bg-yellow-900 dark:text-yellow-100',
14
+ error: 'bg-red-50 text-red-900 dark:bg-red-900 dark:text-red-100',
15
+ }
16
+
17
+ const positions = {
18
+ 'top-left': 'top-0 left-0',
19
+ 'top-right': 'top-0 right-0',
20
+ 'top-center': 'top-0 left-1/2 -translate-x-1/2',
21
+ 'bottom-left': 'bottom-0 left-0',
22
+ 'bottom-right': 'bottom-0 right-0',
23
+ 'bottom-center': 'bottom-0 left-1/2 -translate-x-1/2',
24
+ }
25
+
26
+ const baseClasses = 'fixed z-50 m-4 max-w-md w-full pointer-events-auto rounded-lg p-4 shadow-lg ring-1 ring-black ring-opacity-5 transition-all'
27
+ export const notificationClasses = `${baseClasses} ${typeColors[type]} ${positions[position]} ${className}`.trim()
28
+ </script>
29
+
30
+ <script client>
31
+ const emit = defineEmits()
32
+ const duration = {{ duration }}
33
+ const isVisible = state({{ show }})
34
+
35
+ function close() {
36
+ isVisible.set(false)
37
+ emit('close')
38
+ }
39
+
40
+ onMount(() => {
41
+ if (duration > 0 && isVisible()) {
42
+ setTimeout(close, duration)
43
+ }
44
+ })
45
+
46
+ defineExpose({
47
+ show: () => isVisible.set(true),
48
+ close,
49
+ isVisible,
50
+ })
51
+ </script>
52
+
53
+ <div :show="isVisible()" class="{{ notificationClasses }}" role="alert">
54
+ <div class="flex items-start">
55
+ <div class="flex-1">
56
+ @if(title)
57
+ <p class="text-sm font-medium">{{ title }}</p>
58
+ @endif
59
+ @if(message)
60
+ <p class="mt-1 text-sm {{ title ? 'opacity-90' : '' }}">{{ message }}</p>
61
+ @endif
62
+ @if(!title && !message)
63
+ <slot />
64
+ @endif
65
+ </div>
66
+
67
+ <button
68
+ type="button"
69
+ @click="close()"
70
+ class="ml-4 inline-flex rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2"
71
+ >
72
+ <span class="sr-only">Close</span>
73
+ <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
74
+ <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd" />
75
+ </svg>
76
+ </button>
77
+ </div>
78
+ </div>
@@ -1,6 +1,5 @@
1
1
  <script server>
2
2
  export const value = $props.value || ''
3
- export const onChange = $props.onChange || (() => {})
4
3
  export const placeholder = $props.placeholder || '0'
5
4
  export const disabled = $props.disabled || false
6
5
  export const readonly = $props.readonly || false
@@ -16,26 +15,16 @@ export const showControls = $props.showControls ?? true
16
15
  export const className = $props.className || ''
17
16
  export const inputClassName = $props.inputClassName || ''
18
17
 
19
- // Size classes
20
- const sizeClasses = {
21
- sm: 'px-3 py-1.5 text-sm h-8',
22
- md: 'px-4 py-2 text-base h-10',
23
- lg: 'px-5 py-3 text-lg h-12',
24
- }
25
-
26
- // Base and state classes
18
+ const sizeClasses = { sm: 'px-3 py-1.5 text-sm h-8', md: 'px-4 py-2 text-base h-10', lg: 'px-5 py-3 text-lg h-12' }
27
19
  const baseClasses = 'block w-full border-0 rounded-md shadow-sm ring-1 ring-inset transition-colors duration-200 focus:ring-2 focus:ring-inset dark:bg-blue-gray-700 dark:text-gray-100'
28
-
29
20
  const stateClasses = error
30
21
  ? 'ring-red-300 dark:ring-red-600 text-red-900 dark:text-red-300 placeholder-red-300 dark:placeholder-red-500 focus:ring-red-500 dark:focus:ring-red-400'
31
22
  : 'ring-gray-300 dark:ring-gray-600 text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-500 focus:ring-indigo-600 dark:focus:ring-indigo-400'
32
-
33
23
  const disabledClasses = disabled
34
24
  ? 'opacity-50 cursor-not-allowed bg-gray-50 dark:bg-gray-800'
35
25
  : readonly
36
26
  ? 'bg-gray-50 dark:bg-gray-800 cursor-default'
37
27
  : 'bg-white dark:bg-blue-gray-700'
38
-
39
28
  const paddingClasses = showControls ? 'pr-10' : ''
40
29
 
41
30
  export const inputClasses = `${baseClasses} ${sizeClasses[size]} ${stateClasses} ${disabledClasses} ${paddingClasses} ${inputClassName}`.trim()
@@ -43,6 +32,37 @@ export const labelClasses = `block text-sm font-medium leading-6 mb-2 ${error ?
43
32
  export const helperClasses = `mt-2 text-sm ${error ? 'text-red-600 dark:text-red-400' : 'text-gray-500 dark:text-gray-400'}`.trim()
44
33
  </script>
45
34
 
35
+ <script client>
36
+ const emit = defineEmits()
37
+ const stepSize = {{ step }}
38
+ const minVal = {{ min === undefined ? 'undefined' : min }}
39
+ const maxVal = {{ max === undefined ? 'undefined' : max }}
40
+ const inputValue = state({{ value }})
41
+
42
+ function onInput(event) {
43
+ inputValue.set(event.target.value)
44
+ emit('input', inputValue())
45
+ }
46
+
47
+ function increment() {
48
+ const current = Number.parseFloat(inputValue()) || 0
49
+ const next = current + stepSize
50
+ if (maxVal !== undefined && next > maxVal) return
51
+ inputValue.set(String(next))
52
+ emit('input', String(next))
53
+ }
54
+
55
+ function decrement() {
56
+ const current = Number.parseFloat(inputValue()) || 0
57
+ const next = current - stepSize
58
+ if (minVal !== undefined && next < minVal) return
59
+ inputValue.set(String(next))
60
+ emit('input', String(next))
61
+ }
62
+
63
+ defineExpose({ value: inputValue, increment, decrement })
64
+ </script>
65
+
46
66
  <div class="w-full {{ className }}">
47
67
  @if(label)
48
68
  <label for="number-input" class="{{ labelClasses }}">
@@ -58,25 +78,24 @@ export const helperClasses = `mt-2 text-sm ${error ? 'text-red-600 dark:text-red
58
78
  type="number"
59
79
  id="number-input"
60
80
  class="{{ inputClasses }}"
61
- value="{{ value }}"
81
+ :value="inputValue()"
62
82
  placeholder="{{ placeholder }}"
63
- disabled="{{ disabled }}"
64
- readonly="{{ readonly }}"
65
- required="{{ required }}"
83
+ @if(disabled)disabled@endif
84
+ @if(readonly)readonly@endif
85
+ @if(required)required@endif
66
86
  @if(min !== undefined)min="{{ min }}"@endif
67
87
  @if(max !== undefined)max="{{ max }}"@endif
68
88
  step="{{ step }}"
69
- oninput="handleInput(event)"
70
- aria-invalid="{{ error ? 'true' : 'false' }}"
89
+ @input="onInput($event)"
90
+ :aria-invalid="{{ error ? 'true' : 'false' }}"
71
91
  @if(helperText)aria-describedby="helper-text"@endif
72
92
  />
73
93
 
74
94
  @if(showControls && !disabled && !readonly)
75
- <!-- Increment/Decrement controls -->
76
95
  <div class="absolute inset-y-0 right-0 flex flex-col">
77
96
  <button
78
97
  type="button"
79
- @click="handleIncrement()"
98
+ @click="increment()"
80
99
  class="flex items-center justify-center w-8 h-1/2 text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300 focus:outline-none border-b border-gray-300 dark:border-gray-600"
81
100
  aria-label="Increment"
82
101
  >
@@ -86,7 +105,7 @@ export const helperClasses = `mt-2 text-sm ${error ? 'text-red-600 dark:text-red
86
105
  </button>
87
106
  <button
88
107
  type="button"
89
- @click="handleDecrement()"
108
+ @click="decrement()"
90
109
  class="flex items-center justify-center w-8 h-1/2 text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300 focus:outline-none"
91
110
  aria-label="Decrement"
92
111
  >
@@ -104,35 +123,3 @@ export const helperClasses = `mt-2 text-sm ${error ? 'text-red-600 dark:text-red
104
123
  </p>
105
124
  @endif
106
125
  </div>
107
-
108
- <script>
109
- function handleInput(event) {
110
- const newValue = event.target.value
111
-
112
- if (onChange) {
113
- onChange(newValue)
114
- }
115
- }
116
-
117
- function handleIncrement() {
118
- const currentValue = parseFloat(value) || 0
119
- const newValue = currentValue + step
120
-
121
- if (max !== undefined && newValue > max) return
122
-
123
- if (onChange) {
124
- onChange(String(newValue))
125
- }
126
- }
127
-
128
- function handleDecrement() {
129
- const currentValue = parseFloat(value) || 0
130
- const newValue = currentValue - step
131
-
132
- if (min !== undefined && newValue < min) return
133
-
134
- if (onChange) {
135
- onChange(String(newValue))
136
- }
137
- }
138
- </script>