@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,209 +0,0 @@
1
- <script server>
2
- export const action = $props.action || ''
3
- export const method = $props.method || 'POST'
4
- export const validationSchema = $props.validationSchema || {}
5
- export const initialValues = $props.initialValues || {}
6
- export const validateOnChange = $props.validateOnChange ?? true
7
- export const validateOnBlur = $props.validateOnBlur ?? true
8
- export const onSubmit = $props.onSubmit
9
- export const onError = $props.onError
10
- export const className = $props.className || ''
11
-
12
- let values = { ...initialValues }
13
- let errors = {}
14
- let touched = {}
15
- let isSubmitting = false
16
- let isValidating = false
17
- let submitCount = 0
18
-
19
- // Validate a single field
20
- function validateField(name, value) {
21
- const fieldSchema = validationSchema[name]
22
- if (!fieldSchema)
23
- return null
24
-
25
- // Required validation
26
- if (fieldSchema.required && !value) {
27
- return fieldSchema.requiredMessage || `${name} is required`
28
- }
29
-
30
- // Min length validation
31
- if (fieldSchema.minLength && value.length < fieldSchema.minLength) {
32
- return fieldSchema.minLengthMessage || `${name} must be at least ${fieldSchema.minLength} characters`
33
- }
34
-
35
- // Max length validation
36
- if (fieldSchema.maxLength && value.length > fieldSchema.maxLength) {
37
- return fieldSchema.maxLengthMessage || `${name} must be at most ${fieldSchema.maxLength} characters`
38
- }
39
-
40
- // Pattern validation
41
- if (fieldSchema.pattern && !fieldSchema.pattern.test(value)) {
42
- return fieldSchema.patternMessage || `${name} is invalid`
43
- }
44
-
45
- // Custom validation
46
- if (fieldSchema.validate && typeof fieldSchema.validate === 'function') {
47
- return fieldSchema.validate(value, values)
48
- }
49
-
50
- return null
51
- }
52
-
53
- // Validate all fields
54
- function validateForm() {
55
- const newErrors = {}
56
- let isValid = true
57
-
58
- Object.keys(validationSchema).forEach((name) => {
59
- const error = validateField(name, values[name])
60
- if (error) {
61
- newErrors[name] = error
62
- isValid = false
63
- }
64
- })
65
-
66
- errors = newErrors
67
- return isValid
68
- }
69
-
70
- // Handle field change
71
- function handleChange(event) {
72
- const { name, value } = event.target
73
- values[name] = value
74
-
75
- if (validateOnChange && touched[name]) {
76
- const error = validateField(name, value)
77
- if (error) {
78
- errors[name] = error
79
- }
80
- else {
81
- delete errors[name]
82
- }
83
- }
84
- }
85
-
86
- // Handle field blur
87
- function handleBlur(event) {
88
- const { name } = event.target
89
- touched[name] = true
90
-
91
- if (validateOnBlur) {
92
- const error = validateField(name, values[name])
93
- if (error) {
94
- errors[name] = error
95
- }
96
- else {
97
- delete errors[name]
98
- }
99
- }
100
- }
101
-
102
- // Handle form submission
103
- async function handleSubmit(event) {
104
- event.preventDefault()
105
- submitCount++
106
-
107
- // Mark all fields as touched
108
- Object.keys(validationSchema).forEach((name) => {
109
- touched[name] = true
110
- })
111
-
112
- // Validate
113
- isValidating = true
114
- const isValid = validateForm()
115
- isValidating = false
116
-
117
- if (!isValid) {
118
- if (onError) {
119
- onError(errors)
120
- }
121
- return
122
- }
123
-
124
- // Submit
125
- isSubmitting = true
126
-
127
- try {
128
- if (onSubmit) {
129
- await onSubmit(values, { setErrors, setValues, resetForm })
130
- }
131
- }
132
- catch (error) {
133
- if (onError) {
134
- onError(error)
135
- }
136
- }
137
- finally {
138
- isSubmitting = false
139
- }
140
- }
141
-
142
- // Helper functions
143
- function setErrors(newErrors) {
144
- errors = { ...errors, ...newErrors }
145
- }
146
-
147
- function setValues(newValues) {
148
- values = { ...values, ...newValues }
149
- }
150
-
151
- function resetForm() {
152
- values = { ...initialValues }
153
- errors = {}
154
- touched = {}
155
- isSubmitting = false
156
- submitCount = 0
157
- }
158
-
159
- function getFieldProps(name) {
160
- return {
161
- name,
162
- value: values[name] || '',
163
- error: errors[name],
164
- touched: touched[name],
165
- onChange: handleChange,
166
- onBlur: handleBlur,
167
- }
168
- }
169
-
170
- export const formClasses = `space-y-6 ${className}`.trim()
171
- export const errorClasses = `mt-1 text-sm text-red-600 dark:text-red-400`.trim()
172
- </script>
173
-
174
- <form
175
- class="{{ formClasses }}"
176
- @if(action)action="{{ action }}"@endif
177
- method="{{ method }}"
178
- onsubmit="handleSubmit(event)"
179
- novalidate
180
- >
181
- <slot
182
- values="{{ values }}"
183
- errors="{{ errors }}"
184
- touched="{{ touched }}"
185
- isSubmitting="{{ isSubmitting }}"
186
- isValidating="{{ isValidating }}"
187
- submitCount="{{ submitCount }}"
188
- getFieldProps="{{ getFieldProps }}"
189
- setErrors="{{ setErrors }}"
190
- setValues="{{ setValues }}"
191
- resetForm="{{ resetForm }}"
192
- />
193
- </form>
194
-
195
- <script>
196
- // Export context for child components
197
- if (typeof window !== 'undefined') {
198
- window.__formContext = {
199
- values,
200
- errors,
201
- touched,
202
- isSubmitting,
203
- isValidating,
204
- getFieldProps,
205
- handleChange,
206
- handleBlur,
207
- }
208
- }
209
- </script>
@@ -1,14 +0,0 @@
1
- <script server>
2
- export const value = $props.value
3
- export const onChange = $props.onChange
4
- export const multiple = $props.multiple || false
5
- export const className = $props.className || ''
6
- export const as = $props.as || 'div'
7
-
8
- const baseClasses = 'relative'
9
- const listboxClasses = `${baseClasses} ${className}`.trim()
10
- </script>
11
-
12
- <component :is="{{ as }}" class="{{ listboxClasses }}">
13
- <slot :value="value" :onChange="onChange" :multiple="multiple" />
14
- </component>
@@ -1,57 +0,0 @@
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
- export const currentValue = $props.currentValue
7
- export const onChange = $props.onChange
8
-
9
- export let active = false
10
- export const selected = Array.isArray(currentValue)
11
- ? currentValue.includes(value)
12
- : currentValue === value
13
-
14
- const baseClasses = 'relative cursor-pointer select-none py-2 pl-10 pr-4'
15
- const stateClasses = active
16
- ? 'bg-blue-100 text-blue-900 dark:bg-blue-900 dark:text-blue-100'
17
- : 'text-neutral-900 dark:text-neutral-100'
18
- const disabledClasses = disabled
19
- ? 'opacity-50 cursor-not-allowed'
20
- : ''
21
-
22
- const optionClasses = `${baseClasses} ${stateClasses} ${disabledClasses} ${className}`.trim()
23
-
24
- export function handleClick() {
25
- if (disabled) return
26
- onChange?.(value)
27
- }
28
-
29
- export function handleMouseEnter() {
30
- if (!disabled) active = true
31
- }
32
-
33
- export function handleMouseLeave() {
34
- active = false
35
- }
36
- </script>
37
-
38
- <component
39
- :is="{{ as }}"
40
- class="{{ optionClasses }}"
41
- role="option"
42
- aria-selected="{{ selected ? 'true' : 'false' }}"
43
- @if(disabled)aria-disabled="true"@endif
44
- @click="handleClick"
45
- @mouseenter="handleMouseEnter"
46
- @mouseleave="handleMouseLeave"
47
- >
48
- @if(selected)
49
- <span class="absolute inset-y-0 left-0 flex items-center pl-3 text-blue-600 dark:text-blue-400">
50
- <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
51
- <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" />
52
- </svg>
53
- </span>
54
- @endif
55
-
56
- <slot :active="active" :selected="selected" :disabled="disabled" />
57
- </component>
@@ -1,138 +0,0 @@
1
- <script server>
2
- // Navigator Component Props
3
- export const items = $props.items || []
4
- export const active = $props.active || ''
5
- export const orientation = $props.orientation || 'horizontal' // 'horizontal' | 'vertical'
6
- export const variant = $props.variant || 'default' // 'default' | 'pills' | 'underline' | 'sidebar'
7
- export const size = $props.size || 'md' // 'sm' | 'md' | 'lg'
8
- export const onNavigate = $props.onNavigate
9
- export const className = $props.className || ''
10
-
11
- // Helper function to check if item is active
12
- function isActive(item) {
13
- if (typeof item.href === 'string' && typeof active === 'string') {
14
- // Exact match
15
- if (item.href === active) return true
16
- // Match with query params/hash
17
- if (active.startsWith(item.href)) return true
18
- }
19
- if (item.id && item.id === active) return true
20
- return false
21
- }
22
-
23
- // Base classes
24
- const containerBaseClasses = orientation === 'horizontal'
25
- ? 'flex items-center'
26
- : 'flex flex-col'
27
-
28
- const containerClasses = `${containerBaseClasses} ${className}`.trim()
29
-
30
- // Item classes based on variant and size
31
- function getItemClasses(item) {
32
- const active = isActive(item)
33
- let classes = ''
34
-
35
- // Size classes
36
- const sizeClasses = {
37
- sm: 'px-2 py-1 text-sm',
38
- md: 'px-3 py-2 text-base',
39
- lg: 'px-4 py-3 text-lg',
40
- }
41
-
42
- classes += sizeClasses[size] || sizeClasses.md
43
-
44
- // Variant classes
45
- if (variant === 'default') {
46
- classes += active
47
- ? ' text-gray-900 dark:text-gray-100 font-medium'
48
- : ' text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100'
49
- } else if (variant === 'pills') {
50
- classes += active
51
- ? ' bg-blue-600 text-white font-medium rounded-full'
52
- : ' text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-full'
53
- } else if (variant === 'underline') {
54
- classes += active
55
- ? ' text-blue-600 dark:text-blue-400 font-medium border-b-2 border-blue-600 dark:border-blue-400'
56
- : ' text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 border-b-2 border-transparent'
57
- } else if (variant === 'sidebar') {
58
- classes += active
59
- ? ' 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'
60
- : ' text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 border-l-4 border-transparent'
61
- }
62
-
63
- // Common classes
64
- classes += ' transition-all duration-200 cursor-pointer flex items-center gap-2'
65
-
66
- if (item.disabled) {
67
- classes += ' opacity-50 cursor-not-allowed pointer-events-none'
68
- }
69
-
70
- return classes.trim()
71
- }
72
-
73
- // Gap classes between items
74
- const gapClasses = orientation === 'horizontal'
75
- ? 'gap-1'
76
- : 'gap-0.5'
77
-
78
- function handleClick(item, event) {
79
- if (item.disabled) {
80
- event.preventDefault()
81
- return
82
- }
83
-
84
- if (onNavigate) {
85
- event.preventDefault()
86
- onNavigate(item)
87
- }
88
- }
89
- </script>
90
-
91
- <nav class="{{ containerClasses }} {{ gapClasses }}" role="navigation" aria-label="Main navigation">
92
- @foreach(item in items)
93
- @if(item.href)
94
- <a
95
- href="{{ item.href }}"
96
- class="{{ getItemClasses(item) }}"
97
- @click="handleClick(item, event)"
98
- @if(isActive(item))
99
- aria-current="page"
100
- @endif
101
- @if(item.disabled)
102
- aria-disabled="true"
103
- tabindex="-1"
104
- @endif
105
- >
106
- @if(item.icon)
107
- <span class="flex-shrink-0" innerHTML="{!! item.icon !!}"></span>
108
- @endif
109
- <span>{{ item.label }}</span>
110
- @if(item.badge)
111
- <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">
112
- {{ item.badge }}
113
- </span>
114
- @endif
115
- </a>
116
- @else
117
- <button
118
- type="button"
119
- class="{{ getItemClasses(item) }}"
120
- @click="handleClick(item, event)"
121
- @if(item.disabled)
122
- disabled
123
- aria-disabled="true"
124
- @endif
125
- >
126
- @if(item.icon)
127
- <span class="flex-shrink-0" innerHTML="{!! item.icon !!}"></span>
128
- @endif
129
- <span>{{ item.label }}</span>
130
- @if(item.badge)
131
- <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">
132
- {{ item.badge }}
133
- </span>
134
- @endif
135
- </button>
136
- @endif
137
- @endforeach
138
- </nav>
@@ -1,71 +0,0 @@
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 onClose = $props.onClose
9
- export const className = $props.className || ''
10
-
11
- const typeColors = {
12
- info: 'bg-blue-50 text-blue-900 dark:bg-blue-900 dark:text-blue-100',
13
- success: 'bg-green-50 text-green-900 dark:bg-green-900 dark:text-green-100',
14
- warning: 'bg-yellow-50 text-yellow-900 dark:bg-yellow-900 dark:text-yellow-100',
15
- error: 'bg-red-50 text-red-900 dark:bg-red-900 dark:text-red-100',
16
- }
17
-
18
- const positions = {
19
- 'top-left': 'top-0 left-0',
20
- 'top-right': 'top-0 right-0',
21
- 'top-center': 'top-0 left-1/2 -translate-x-1/2',
22
- 'bottom-left': 'bottom-0 left-0',
23
- 'bottom-right': 'bottom-0 right-0',
24
- 'bottom-center': 'bottom-0 left-1/2 -translate-x-1/2',
25
- }
26
-
27
- 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'
28
- const notificationClasses = `${baseClasses} ${typeColors[type]} ${positions[position]} ${className}`.trim()
29
-
30
- export function handleClose() {
31
- onClose?.()
32
- }
33
- </script>
34
-
35
- @if(show)
36
- <div class="{{ notificationClasses }}" role="alert">
37
- <div class="flex items-start">
38
- <div class="flex-1">
39
- @if(title)
40
- <p class="text-sm font-medium">{{ title }}</p>
41
- @endif
42
- @if(message)
43
- <p class="mt-1 text-sm {{ title ? 'opacity-90' : '' }}">{{ message }}</p>
44
- @endif
45
- @if(!title && !message)
46
- <slot />
47
- @endif
48
- </div>
49
-
50
- <button
51
- type="button"
52
- @click="handleClose"
53
- class="ml-4 inline-flex rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2"
54
- >
55
- <span class="sr-only">Close</span>
56
- <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
57
- <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" />
58
- </svg>
59
- </button>
60
- </div>
61
- </div>
62
-
63
- <script>
64
- // Auto-hide after duration (client-side only)
65
- if (typeof window !== 'undefined' && duration > 0) {
66
- setTimeout(() => {
67
- handleClose()
68
- }, duration)
69
- }
70
- </script>
71
- @endif
@@ -1,155 +0,0 @@
1
- <script server>
2
- export const value = $props.value || ''
3
- export const onChange = $props.onChange || (() => {})
4
- export const placeholder = $props.placeholder || 'Enter your password'
5
- export const disabled = $props.disabled || false
6
- export const readonly = $props.readonly || false
7
- export const size = $props.size || 'md'
8
- export const error = $props.error || false
9
- export const label = $props.label || ''
10
- export const helperText = $props.helperText || ''
11
- export const required = $props.required || false
12
- export const showStrength = $props.showStrength || false
13
- export const className = $props.className || ''
14
- export const inputClassName = $props.inputClassName || ''
15
-
16
- // State
17
- let showPassword = false
18
-
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
- // Icon size classes
27
- const iconSizeClasses = {
28
- sm: 'h-4 w-4',
29
- md: 'h-5 w-5',
30
- lg: 'h-6 w-6',
31
- }
32
-
33
- // Base and state classes
34
- 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 pr-10'
35
-
36
- const stateClasses = error
37
- ? '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'
38
- : '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'
39
-
40
- const disabledClasses = disabled
41
- ? 'opacity-50 cursor-not-allowed bg-gray-50 dark:bg-gray-800'
42
- : readonly
43
- ? 'bg-gray-50 dark:bg-gray-800 cursor-default'
44
- : 'bg-white dark:bg-blue-gray-700'
45
-
46
- export const inputClasses = `${baseClasses} ${sizeClasses[size]} ${stateClasses} ${disabledClasses} ${inputClassName}`.trim()
47
- export const labelClasses = `block text-sm font-medium leading-6 mb-2 ${error ? 'text-red-600 dark:text-red-400' : 'text-gray-900 dark:text-gray-100'}`.trim()
48
- export const helperClasses = `mt-2 text-sm ${error ? 'text-red-600 dark:text-red-400' : 'text-gray-500 dark:text-gray-400'}`.trim()
49
- export const iconClasses = iconSizeClasses[size]
50
-
51
- // Password strength calculation
52
- function calculateStrength(password) {
53
- if (!password) return 0
54
- let strength = 0
55
- if (password.length >= 8) strength += 25
56
- if (password.length >= 12) strength += 25
57
- if (/[a-z]/.test(password) && /[A-Z]/.test(password)) strength += 25
58
- if (/\d/.test(password)) strength += 15
59
- if (/[^a-zA-Z\d]/.test(password)) strength += 10
60
- return Math.min(strength, 100)
61
- }
62
-
63
- export const strength = calculateStrength(value)
64
- export const strengthColor = strength < 40 ? 'bg-red-500' : strength < 70 ? 'bg-yellow-500' : 'bg-green-500'
65
- export const strengthText = strength < 40 ? 'Weak' : strength < 70 ? 'Medium' : 'Strong'
66
- </script>
67
-
68
- <div class="w-full {{ className }}">
69
- @if(label)
70
- <label for="password-input" class="{{ labelClasses }}">
71
- {{ label }}
72
- @if(required)
73
- <span class="text-red-500 ml-1">*</span>
74
- @endif
75
- </label>
76
- @endif
77
-
78
- <div class="relative">
79
- <input
80
- type="{{ showPassword ? 'text' : 'password' }}"
81
- id="password-input"
82
- class="{{ inputClasses }}"
83
- value="{{ value }}"
84
- placeholder="{{ placeholder }}"
85
- disabled="{{ disabled }}"
86
- readonly="{{ readonly }}"
87
- required="{{ required }}"
88
- oninput="handleInput(event)"
89
- aria-invalid="{{ error ? 'true' : 'false' }}"
90
- @if(helperText)aria-describedby="helper-text"@endif
91
- />
92
-
93
- <!-- Toggle visibility button -->
94
- <div class="absolute inset-y-0 right-0 flex items-center pr-3">
95
- <button
96
- type="button"
97
- @click="toggleVisibility()"
98
- class="text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300 focus:outline-none"
99
- aria-label="{{ showPassword ? 'Hide password' : 'Show password' }}"
100
- >
101
- @if(showPassword)
102
- <!-- Eye slash icon (hide) -->
103
- <svg class="{{ iconClasses }}" fill="none" viewBox="0 0 24 24" stroke="currentColor">
104
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21" />
105
- </svg>
106
- @else
107
- <!-- Eye icon (show) -->
108
- <svg class="{{ iconClasses }}" fill="none" viewBox="0 0 24 24" stroke="currentColor">
109
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
110
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
111
- </svg>
112
- @endif
113
- </button>
114
- </div>
115
- </div>
116
-
117
- @if(showStrength && value.length > 0)
118
- <!-- Password strength indicator -->
119
- <div class="mt-2">
120
- <div class="flex items-center justify-between mb-1">
121
- <span class="text-xs text-gray-600 dark:text-gray-400">Password strength</span>
122
- <span class="text-xs font-medium {{ strength < 40 ? 'text-red-600' : strength < 70 ? 'text-yellow-600' : 'text-green-600' }}">
123
- {{ strengthText }}
124
- </span>
125
- </div>
126
- <div class="w-full h-1.5 bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden">
127
- <div
128
- class="{{ strengthColor }} h-full transition-all duration-300 rounded-full"
129
- style="width: {{ strength }}%"
130
- ></div>
131
- </div>
132
- </div>
133
- @endif
134
-
135
- @if(helperText)
136
- <p id="helper-text" class="{{ helperClasses }}">
137
- {{ helperText }}
138
- </p>
139
- @endif
140
- </div>
141
-
142
- <script>
143
- function handleInput(event) {
144
- const newValue = event.target.value
145
-
146
- if (onChange) {
147
- onChange(newValue)
148
- }
149
- }
150
-
151
- function toggleVisibility() {
152
- showPassword = !showPassword
153
- // Re-render would be handled by the framework
154
- }
155
- </script>
@@ -1,24 +0,0 @@
1
- <script server>
2
- export const className = $props.className || ''
3
- export const as = $props.as || 'div'
4
- export let isOpen = false
5
-
6
- export function toggle() {
7
- isOpen = !isOpen
8
- }
9
-
10
- export function close() {
11
- isOpen = false
12
- }
13
-
14
- export function open() {
15
- isOpen = true
16
- }
17
-
18
- const baseClasses = 'relative'
19
- const popoverClasses = `${baseClasses} ${className}`.trim()
20
- </script>
21
-
22
- <component :is="{{ as }}" class="{{ popoverClasses }}">
23
- <slot :isOpen="isOpen" :toggle="toggle" :close="close" :open="open" />
24
- </component>
@@ -1,13 +0,0 @@
1
- <script server>
2
- export const value = $props.value
3
- export const onChange = $props.onChange
4
- export const className = $props.className || ''
5
- export const as = $props.as || 'div'
6
-
7
- const baseClasses = 'w-full'
8
- const groupClasses = `${baseClasses} ${className}`.trim()
9
- </script>
10
-
11
- <component :is="{{ as }}" class="{{ groupClasses }}" role="radiogroup">
12
- <slot :value="value" :onChange="onChange" />
13
- </component>