@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
@@ -6,7 +6,6 @@ export const className = $props.className || ''
6
6
  export const show = $props.show || false
7
7
  export const disabled = $props.disabled || false
8
8
 
9
- // Position classes
10
9
  const positionClasses = {
11
10
  top: 'bottom-full left-1/2 -translate-x-1/2 mb-2',
12
11
  bottom: 'top-full left-1/2 -translate-x-1/2 mt-2',
@@ -14,7 +13,6 @@ const positionClasses = {
14
13
  right: 'left-full top-1/2 -translate-y-1/2 ml-2',
15
14
  }
16
15
 
17
- // Arrow classes
18
16
  const arrowClasses = {
19
17
  top: 'top-full left-1/2 -translate-x-1/2 border-t-gray-900 dark:border-t-gray-700',
20
18
  bottom: 'bottom-full left-1/2 -translate-x-1/2 border-b-gray-900 dark:border-b-gray-700',
@@ -22,55 +20,51 @@ const arrowClasses = {
22
20
  right: 'right-full top-1/2 -translate-y-1/2 border-r-gray-900 dark:border-r-gray-700',
23
21
  }
24
22
 
25
- export const tooltipClasses = `absolute z-50 px-3 py-2 text-sm font-medium text-white bg-gray-900 dark:bg-gray-700 rounded-lg shadow-lg whitespace-nowrap pointer-events-none opacity-0 transition-opacity duration-200 ${positionClasses[position]} ${className}`.trim()
23
+ export const tooltipClasses = `absolute z-50 px-3 py-2 text-sm font-medium text-white bg-gray-900 dark:bg-gray-700 rounded-lg shadow-lg whitespace-nowrap pointer-events-none transition-opacity duration-200 ${positionClasses[position]} ${className}`.trim()
26
24
  export const arrowClass = `absolute w-0 h-0 border-4 border-transparent ${arrowClasses[position]}`.trim()
27
-
28
- let isVisible = show
29
- let timeoutId = null
30
25
  </script>
31
26
 
32
- <div class="relative inline-block {{ disabled ? 'cursor-not-allowed' : '' }}">
33
- <!-- Trigger element (slot) -->
34
- <div
35
- onmouseenter="handleMouseEnter()"
36
- onmouseleave="handleMouseLeave()"
37
- onfocus="handleMouseEnter()"
38
- onblur="handleMouseLeave()"
39
- >
40
- <slot />
41
- </div>
42
-
43
- <!-- Tooltip -->
44
- @if(isVisible && !disabled)
45
- <div
46
- class="{{ tooltipClasses }}"
47
- role="tooltip"
48
- style="opacity: 1"
49
- >
50
- {{ content }}
51
- <div class="{{ arrowClass }}"></div>
52
- </div>
53
- @endif
54
- </div>
55
-
56
- <script>
57
- function handleMouseEnter() {
58
- if (disabled) return
27
+ <script client>
28
+ const delay = {{ delay }}
29
+ const isDisabled = {{ disabled }}
30
+ const isVisible = state({{ show }})
31
+ let timeoutId = null
59
32
 
33
+ function showTooltip() {
34
+ if (isDisabled) return
60
35
  if (delay > 0) {
61
- timeoutId = setTimeout(() => {
62
- isVisible = true
63
- }, delay)
64
- } else {
65
- isVisible = true
36
+ timeoutId = setTimeout(() => isVisible.set(true), delay)
37
+ }
38
+ else {
39
+ isVisible.set(true)
66
40
  }
67
41
  }
68
42
 
69
- function handleMouseLeave() {
43
+ function hideTooltip() {
70
44
  if (timeoutId) {
71
45
  clearTimeout(timeoutId)
72
46
  timeoutId = null
73
47
  }
74
- isVisible = false
48
+ isVisible.set(false)
75
49
  }
76
50
  </script>
51
+
52
+ <div class="relative inline-block {{ disabled ? 'cursor-not-allowed' : '' }}">
53
+ <div
54
+ @mouseenter="showTooltip()"
55
+ @mouseleave="hideTooltip()"
56
+ @focusin="showTooltip()"
57
+ @focusout="hideTooltip()"
58
+ >
59
+ <slot />
60
+ </div>
61
+
62
+ <div
63
+ :show="isVisible() && !{{ disabled }}"
64
+ class="{{ tooltipClasses }}"
65
+ role="tooltip"
66
+ >
67
+ {{ content }}
68
+ <div class="{{ arrowClass }}"></div>
69
+ </div>
70
+ </div>
@@ -7,168 +7,96 @@ export const leave = $props.leave || 'transition-opacity duration-200'
7
7
  export const leaveFrom = $props.leaveFrom || 'opacity-100'
8
8
  export const leaveTo = $props.leaveTo || 'opacity-0'
9
9
  export const appear = $props.appear || false
10
- export const appearFrom = $props.appearFrom || enterFrom
11
- export const appearTo = $props.appearTo || enterTo
12
- export const mode = $props.mode || 'in-out' // 'in-out' | 'out-in' | 'default'
13
10
  export const duration = $props.duration || 300
14
11
  export const delay = $props.delay || 0
15
12
  export const preset = $props.preset || ''
16
- export const onBeforeEnter = $props.onBeforeEnter
17
- export const onEnter = $props.onEnter
18
- export const onAfterEnter = $props.onAfterEnter
19
- export const onBeforeLeave = $props.onBeforeLeave
20
- export const onLeave = $props.onLeave
21
- export const onAfterLeave = $props.onAfterLeave
22
13
  export const className = $props.className || ''
23
14
 
24
- // Preset transitions
25
15
  const presets = {
26
- fade: {
27
- enter: 'transition-opacity',
28
- enterFrom: 'opacity-0',
29
- enterTo: 'opacity-100',
30
- leave: 'transition-opacity',
31
- leaveFrom: 'opacity-100',
32
- leaveTo: 'opacity-0',
33
- },
34
- slide: {
35
- enter: 'transition-transform',
36
- enterFrom: 'translate-y-2',
37
- enterTo: 'translate-y-0',
38
- leave: 'transition-transform',
39
- leaveFrom: 'translate-y-0',
40
- leaveTo: 'translate-y-2',
41
- },
42
- slideLeft: {
43
- enter: 'transition-transform',
44
- enterFrom: 'translate-x-full',
45
- enterTo: 'translate-x-0',
46
- leave: 'transition-transform',
47
- leaveFrom: 'translate-x-0',
48
- leaveTo: '-translate-x-full',
49
- },
50
- slideRight: {
51
- enter: 'transition-transform',
52
- enterFrom: '-translate-x-full',
53
- enterTo: 'translate-x-0',
54
- leave: 'transition-transform',
55
- leaveFrom: 'translate-x-0',
56
- leaveTo: 'translate-x-full',
57
- },
58
- scale: {
59
- enter: 'transition-transform',
60
- enterFrom: 'scale-95',
61
- enterTo: 'scale-100',
62
- leave: 'transition-transform',
63
- leaveFrom: 'scale-100',
64
- leaveTo: 'scale-95',
65
- },
66
- rotate: {
67
- enter: 'transition-transform',
68
- enterFrom: 'rotate-12 scale-95',
69
- enterTo: 'rotate-0 scale-100',
70
- leave: 'transition-transform',
71
- leaveFrom: 'rotate-0 scale-100',
72
- leaveTo: '-rotate-12 scale-95',
73
- },
74
- zoom: {
75
- enter: 'transition-all',
76
- enterFrom: 'scale-0 opacity-0',
77
- enterTo: 'scale-100 opacity-100',
78
- leave: 'transition-all',
79
- leaveFrom: 'scale-100 opacity-100',
80
- leaveTo: 'scale-0 opacity-0',
81
- },
16
+ fade: { enter: 'transition-opacity', enterFrom: 'opacity-0', enterTo: 'opacity-100', leave: 'transition-opacity', leaveFrom: 'opacity-100', leaveTo: 'opacity-0' },
17
+ slide: { enter: 'transition-transform', enterFrom: 'translate-y-2', enterTo: 'translate-y-0', leave: 'transition-transform', leaveFrom: 'translate-y-0', leaveTo: 'translate-y-2' },
18
+ slideLeft: { enter: 'transition-transform', enterFrom: 'translate-x-full', enterTo: 'translate-x-0', leave: 'transition-transform', leaveFrom: 'translate-x-0', leaveTo: '-translate-x-full' },
19
+ slideRight: { enter: 'transition-transform', enterFrom: '-translate-x-full', enterTo: 'translate-x-0', leave: 'transition-transform', leaveFrom: 'translate-x-0', leaveTo: 'translate-x-full' },
20
+ scale: { enter: 'transition-transform', enterFrom: 'scale-95', enterTo: 'scale-100', leave: 'transition-transform', leaveFrom: 'scale-100', leaveTo: 'scale-95' },
21
+ rotate: { enter: 'transition-transform', enterFrom: 'rotate-12 scale-95', enterTo: 'rotate-0 scale-100', leave: 'transition-transform', leaveFrom: 'rotate-0 scale-100', leaveTo: '-rotate-12 scale-95' },
22
+ zoom: { enter: 'transition-all', enterFrom: 'scale-0 opacity-0', enterTo: 'scale-100 opacity-100', leave: 'transition-all', leaveFrom: 'scale-100 opacity-100', leaveTo: 'scale-0 opacity-0' },
82
23
  }
83
24
 
84
- // Apply preset if specified
85
- const presetTransition = preset && presets[preset] ? presets[preset] : {}
86
- const finalEnter = presetTransition.enter || enter
87
- const finalEnterFrom = presetTransition.enterFrom || enterFrom
88
- const finalEnterTo = presetTransition.enterTo || enterTo
89
- const finalLeave = presetTransition.leave || leave
90
- const finalLeaveFrom = presetTransition.leaveFrom || leaveFrom
91
- const finalLeaveTo = presetTransition.leaveTo || leaveTo
25
+ const p = preset && presets[preset] ? presets[preset] : {}
26
+ export const enterClass = p.enter || enter
27
+ export const enterFromClass = p.enterFrom || enterFrom
28
+ export const enterToClass = p.enterTo || enterTo
29
+ export const leaveClass = p.leave || leave
30
+ export const leaveFromClass = p.leaveFrom || leaveFrom
31
+ export const leaveToClass = p.leaveTo || leaveTo
92
32
 
93
- export let isEntering = false
94
- export let isLeaving = false
95
- export let shouldRender = show
96
- export let hasAppeared = false
97
-
98
- const transitionClasses = show
99
- ? isEntering
100
- ? `${finalEnter} ${finalEnterFrom}`
101
- : `${finalEnterTo}`
102
- : isLeaving
103
- ? `${finalLeave} ${finalLeaveFrom}`
104
- : `${finalLeaveTo}`
105
-
106
- const componentClasses = `${transitionClasses} ${className}`.trim()
107
- const durationStyle = `transition-duration: ${duration}ms; transition-delay: ${delay}ms;`
33
+ export const durationStyle = `transition-duration: ${duration}ms; transition-delay: ${delay}ms;`
34
+ export const extraClass = className
108
35
  </script>
109
36
 
110
- @if(shouldRender)
111
- <div class="{{ componentClasses }}" style="{{ durationStyle }}">
112
- <slot />
113
- </div>
114
- @endif
115
-
116
- <script>
117
- // Handle transitions with lifecycle callbacks
118
- if (typeof window !== 'undefined') {
119
- let previousShow = show
120
-
121
- // Watch for show changes
122
- function checkTransition() {
123
- if (show !== previousShow) {
124
- if (show && !shouldRender) {
125
- // Entering
126
- if (onBeforeEnter) onBeforeEnter()
127
-
128
- shouldRender = true
129
- isEntering = true
130
-
131
- setTimeout(() => {
132
- if (onEnter) onEnter()
133
- }, delay)
134
-
135
- setTimeout(() => {
136
- isEntering = false
137
- if (onAfterEnter) onAfterEnter()
138
- }, duration + delay)
139
-
140
- } else if (!show && shouldRender) {
141
- // Leaving
142
- if (onBeforeLeave) onBeforeLeave()
143
-
144
- isLeaving = true
145
-
146
- setTimeout(() => {
147
- if (onLeave) onLeave()
148
- }, delay)
149
-
150
- setTimeout(() => {
151
- isLeaving = false
152
- shouldRender = false
153
- if (onAfterLeave) onAfterLeave()
154
- }, duration + delay)
155
- }
156
-
157
- previousShow = show
158
- }
159
-
160
- requestAnimationFrame(checkTransition)
37
+ <script client>
38
+ const emit = defineEmits()
39
+ const showProp = {{ show }}
40
+ const appear = {{ appear }}
41
+ const duration = {{ duration }}
42
+ const delay = {{ delay }}
43
+ const enterClass = {{ enterClass }}
44
+ const enterFromClass = {{ enterFromClass }}
45
+ const enterToClass = {{ enterToClass }}
46
+ const leaveClass = {{ leaveClass }}
47
+ const leaveFromClass = {{ leaveFromClass }}
48
+ const leaveToClass = {{ leaveToClass }}
49
+ const extraClass = {{ extraClass }}
50
+
51
+ const visible = state(showProp)
52
+ const isEntering = state(appear && showProp)
53
+ const isLeaving = state(false)
54
+ const shouldRender = state(showProp)
55
+
56
+ const transitionClass = derived(() => {
57
+ if (visible()) {
58
+ return isEntering() ? `${enterClass} ${enterFromClass}` : enterToClass
161
59
  }
162
-
163
- requestAnimationFrame(checkTransition)
164
-
165
- // Handle initial appear
166
- if (appear && show && !hasAppeared) {
167
- hasAppeared = true
168
- isEntering = true
60
+ return isLeaving() ? `${leaveClass} ${leaveFromClass}` : leaveToClass
61
+ })
62
+
63
+ const componentClass = derived(() => `${transitionClass()} ${extraClass}`.trim())
64
+
65
+ function setShow(next) {
66
+ if (next === visible()) return
67
+ if (next) {
68
+ emit('beforeEnter')
69
+ shouldRender.set(true)
70
+ visible.set(true)
71
+ isEntering.set(true)
72
+ setTimeout(() => emit('enter'), delay)
169
73
  setTimeout(() => {
170
- isEntering = false
74
+ isEntering.set(false)
75
+ emit('afterEnter')
76
+ }, duration + delay)
77
+ }
78
+ else {
79
+ emit('beforeLeave')
80
+ visible.set(false)
81
+ isLeaving.set(true)
82
+ setTimeout(() => emit('leave'), delay)
83
+ setTimeout(() => {
84
+ isLeaving.set(false)
85
+ shouldRender.set(false)
86
+ emit('afterLeave')
171
87
  }, duration + delay)
172
88
  }
173
89
  }
90
+
91
+ onMount(() => {
92
+ if (appear && showProp) {
93
+ setTimeout(() => isEntering.set(false), duration + delay)
94
+ }
95
+ })
96
+
97
+ defineExpose({ visible, setShow })
174
98
  </script>
99
+
100
+ <div :show="shouldRender()" :class="componentClass()" style="{{ durationStyle }}">
101
+ <slot />
102
+ </div>
@@ -31,10 +31,10 @@ export const aspectRatioClass = aspectRatio === '16/9' ? 'aspect-video' : aspect
31
31
  class="{{ videoClasses }}"
32
32
  src="{{ src }}"
33
33
  poster="{{ poster }}"
34
- controls="{{ controls }}"
35
- autoplay="{{ autoplay }}"
36
- loop="{{ loop }}"
37
- muted="{{ muted }}"
34
+ @if(controls)controls@endif
35
+ @if(autoplay)autoplay@endif
36
+ @if(loop)loop@endif
37
+ @if(muted)muted@endif
38
38
  preload="{{ preload }}"
39
39
  width="{{ width }}"
40
40
  height="{{ height }}"
@@ -3,81 +3,65 @@ export const items = $props.items || []
3
3
  export const itemHeight = $props.itemHeight || 50
4
4
  export const height = $props.height || 400
5
5
  export const overscan = $props.overscan || 3
6
- export const renderItem = $props.renderItem
7
6
  export const className = $props.className || ''
8
7
 
9
- // Calculate visible range
10
- let scrollTop = 0
11
- const visibleCount = Math.ceil(height / itemHeight)
12
- const totalHeight = items.length * itemHeight
8
+ export const totalHeight = items.length * itemHeight
9
+ export const containerClasses = `overflow-auto ${className}`.trim()
10
+ </script>
11
+
12
+ <script client>
13
+ const items = {{ items }}
14
+ const itemHeight = {{ itemHeight }}
15
+ const height = {{ height }}
16
+ const overscan = {{ overscan }}
17
+
18
+ const scrollTop = state(0)
13
19
 
14
- // Calculate start and end indices with overscan
15
- function getVisibleRange() {
16
- const startIndex = Math.max(0, Math.floor(scrollTop / itemHeight) - overscan)
17
- const endIndex = Math.min(items.length - 1, Math.floor((scrollTop + height) / itemHeight) + overscan)
20
+ const visibleRange = derived(() => {
21
+ const top = scrollTop()
22
+ const startIndex = Math.max(0, Math.floor(top / itemHeight) - overscan)
23
+ const endIndex = Math.min(items.length - 1, Math.floor((top + height) / itemHeight) + overscan)
18
24
  return { startIndex, endIndex }
19
- }
25
+ })
20
26
 
21
- const { startIndex, endIndex } = getVisibleRange()
22
- const visibleItems = items.slice(startIndex, endIndex + 1)
23
- const offsetY = startIndex * itemHeight
27
+ const visibleItems = derived(() => {
28
+ const { startIndex, endIndex } = visibleRange()
29
+ return items.slice(startIndex, endIndex + 1).map((item, i) => ({
30
+ item,
31
+ index: startIndex + i,
32
+ top: (startIndex + i) * itemHeight,
33
+ }))
34
+ })
24
35
 
25
- // Handle scroll
26
- function handleScroll(event) {
36
+ let ticking = false
37
+ function onScroll(event) {
27
38
  const target = event.target
28
- scrollTop = target.scrollTop
39
+ if (!ticking) {
40
+ requestAnimationFrame(() => {
41
+ scrollTop.set(target.scrollTop)
42
+ ticking = false
43
+ })
44
+ ticking = true
45
+ }
29
46
  }
30
47
 
31
- export const containerClasses = `overflow-auto ${className}`.trim()
32
- export const innerClasses = `relative`.trim()
33
- export const itemClasses = `absolute left-0 right-0`.trim()
48
+ defineExpose({ scrollTop, scrollTo: (top) => scrollTop.set(top) })
34
49
  </script>
35
50
 
36
51
  <div
37
52
  class="{{ containerClasses }}"
38
53
  style="height: {{ height }}px"
39
- onscroll="handleScroll(event)"
54
+ @scroll="onScroll($event)"
40
55
  >
41
- <div
42
- class="{{ innerClasses }}"
43
- style="height: {{ totalHeight }}px"
44
- >
45
- @foreach(item in visibleItems)
46
- <div
47
- class="{{ itemClasses }}"
48
- style="top: {{ (startIndex + $loop.index) * itemHeight }}px; height: {{ itemHeight }}px"
49
- data-index="{{ startIndex + $loop.index }}"
50
- >
51
- @if(renderItem)
52
- {!! renderItem(item, startIndex + $loop.index) !!}
53
- @else
54
- <slot item="{{ item }}" index="{{ startIndex + $loop.index }}" />
55
- @endif
56
- </div>
57
- @endforeach
56
+ <div class="relative" style="height: {{ totalHeight }}px">
57
+ <div
58
+ :for="entry in visibleItems()"
59
+ :key="entry.index"
60
+ class="absolute left-0 right-0"
61
+ :style="`top: ${entry.top}px; height: {{ itemHeight }}px`"
62
+ :data-index="entry.index"
63
+ >
64
+ <slot :item="entry.item" :index="entry.index" />
65
+ </div>
58
66
  </div>
59
67
  </div>
60
-
61
- <script>
62
- // Re-render on scroll (simplified reactivity)
63
- if (typeof window !== 'undefined') {
64
- let ticking = false
65
-
66
- function updateVisibleItems() {
67
- const range = getVisibleRange()
68
- // Trigger re-render by updating visible range
69
- // In a real implementation, this would update reactive state
70
- ticking = false
71
- }
72
-
73
- const scrollContainer = document.querySelector('.overflow-auto')
74
- if (scrollContainer) {
75
- scrollContainer.addEventListener('scroll', () => {
76
- if (!ticking) {
77
- window.requestAnimationFrame(updateVisibleItems)
78
- ticking = true
79
- }
80
- })
81
- }
82
- }
83
- </script>
@@ -9,45 +9,63 @@ export const striped = $props.striped || false
9
9
  export const hoverable = $props.hoverable ?? true
10
10
  export const className = $props.className || ''
11
11
 
12
- // Calculate visible range
13
- let scrollTop = 0
14
- const visibleCount = Math.ceil((height - headerHeight) / rowHeight)
15
- const totalHeight = data.length * rowHeight
12
+ export const totalHeight = data.length * rowHeight
13
+ export const containerClasses = `border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden ${className}`.trim()
14
+ export const headerClasses = `bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 flex`.trim()
15
+ export const headerCellClasses = `px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider`.trim()
16
+ export const bodyClasses = `overflow-auto bg-white dark:bg-gray-900`.trim()
17
+ export const rowClasses = `absolute left-0 right-0 flex border-b border-gray-200 dark:border-gray-700 ${hoverable ? 'hover:bg-gray-50 dark:hover:bg-gray-800' : ''}`.trim()
18
+ export const cellClasses = `px-6 py-4 text-sm text-gray-900 dark:text-gray-100`.trim()
19
+ </script>
16
20
 
17
- function getVisibleRange() {
18
- const startIndex = Math.max(0, Math.floor(scrollTop / rowHeight) - overscan)
19
- const endIndex = Math.min(data.length - 1, Math.floor((scrollTop + height - headerHeight) / rowHeight) + overscan)
20
- return { startIndex, endIndex }
21
- }
21
+ <script client>
22
+ const data = {{ data }}
23
+ const columns = {{ columns }}
24
+ const rowHeight = {{ rowHeight }}
25
+ const height = {{ height }}
26
+ const headerHeight = {{ headerHeight }}
27
+ const overscan = {{ overscan }}
28
+ const striped = {{ striped }}
22
29
 
23
- const { startIndex, endIndex } = getVisibleRange()
24
- const visibleRows = data.slice(startIndex, endIndex + 1)
25
- const offsetY = startIndex * rowHeight
30
+ const scrollTop = state(0)
26
31
 
27
- function handleScroll(event) {
28
- const target = event.target
29
- scrollTop = target.scrollTop
30
- }
32
+ const visibleRows = derived(() => {
33
+ const top = scrollTop()
34
+ const startIndex = Math.max(0, Math.floor(top / rowHeight) - overscan)
35
+ const endIndex = Math.min(data.length - 1, Math.floor((top + height - headerHeight) / rowHeight) + overscan)
36
+ const out = []
37
+ for (let i = startIndex; i <= endIndex; i++) {
38
+ out.push({
39
+ row: data[i],
40
+ index: i,
41
+ top: i * rowHeight,
42
+ striped: striped && (i % 2 === 1),
43
+ })
44
+ }
45
+ return out
46
+ })
31
47
 
32
- // Get cell value
33
48
  function getCellValue(row, column) {
34
- if (column.render) {
35
- return column.render(row[column.key], row)
36
- }
49
+ if (column.render) return column.render(row[column.key], row)
37
50
  return row[column.key]
38
51
  }
39
52
 
40
- export const containerClasses = `border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden ${className}`.trim()
41
- export const headerClasses = `bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 flex`.trim()
42
- export const headerCellClasses = `px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider`.trim()
43
- export const bodyClasses = `overflow-auto bg-white dark:bg-gray-900`.trim()
44
- export const innerClasses = `relative`.trim()
45
- export const rowClasses = `absolute left-0 right-0 flex border-b border-gray-200 dark:border-gray-700 ${hoverable ? 'hover:bg-gray-50 dark:hover:bg-gray-800' : ''}`.trim()
46
- export const cellClasses = `px-6 py-4 text-sm text-gray-900 dark:text-gray-100`.trim()
53
+ let ticking = false
54
+ function onScroll(event) {
55
+ const target = event.target
56
+ if (!ticking) {
57
+ requestAnimationFrame(() => {
58
+ scrollTop.set(target.scrollTop)
59
+ ticking = false
60
+ })
61
+ ticking = true
62
+ }
63
+ }
64
+
65
+ defineExpose({ scrollTop })
47
66
  </script>
48
67
 
49
68
  <div class="{{ containerClasses }}">
50
- <!-- Header -->
51
69
  <div class="{{ headerClasses }}" style="height: {{ headerHeight }}px">
52
70
  @foreach(column in columns)
53
71
  <div
@@ -59,55 +77,27 @@ export const cellClasses = `px-6 py-4 text-sm text-gray-900 dark:text-gray-100`.
59
77
  @endforeach
60
78
  </div>
61
79
 
62
- <!-- Body -->
63
80
  <div
64
81
  class="{{ bodyClasses }}"
65
82
  style="height: {{ height - headerHeight }}px"
66
- onscroll="handleScroll(event)"
83
+ @scroll="onScroll($event)"
67
84
  >
68
- <div
69
- class="{{ innerClasses }}"
70
- style="height: {{ totalHeight }}px"
71
- >
72
- @foreach(row in visibleRows)
85
+ <div class="relative" style="height: {{ totalHeight }}px">
86
+ <div
87
+ :for="entry in visibleRows()"
88
+ :key="entry.index"
89
+ :class="entry.striped ? '{{ rowClasses }} bg-gray-50 dark:bg-gray-800' : '{{ rowClasses }}'"
90
+ :style="`top: ${entry.top}px; height: {{ rowHeight }}px`"
91
+ :data-index="entry.index"
92
+ >
73
93
  <div
74
- class="{{ rowClasses }} {{ striped && ($loop.index % 2 === 1) ? 'bg-gray-50 dark:bg-gray-800' : '' }}"
75
- style="top: {{ (startIndex + $loop.index) * rowHeight }}px; height: {{ rowHeight }}px"
76
- data-index="{{ startIndex + $loop.index }}"
77
- >
78
- @foreach(column in columns)
79
- <div
80
- class="{{ cellClasses }}"
81
- style="flex: {{ column.width || 1 }}; min-width: {{ column.minWidth || 'auto' }}"
82
- >
83
- {!! getCellValue(row, column) !!}
84
- </div>
85
- @endforeach
86
- </div>
87
- @endforeach
94
+ :for="column in columns"
95
+ :key="column.key"
96
+ class="{{ cellClasses }}"
97
+ :style="`flex: ${column.width || 1}; min-width: ${column.minWidth || 'auto'}`"
98
+ x-html="getCellValue(entry.row, column)"
99
+ ></div>
100
+ </div>
88
101
  </div>
89
102
  </div>
90
103
  </div>
91
-
92
- <script>
93
- // Re-render on scroll (simplified reactivity)
94
- if (typeof window !== 'undefined') {
95
- let ticking = false
96
-
97
- function updateVisibleRows() {
98
- const range = getVisibleRange()
99
- // Trigger re-render
100
- ticking = false
101
- }
102
-
103
- const bodyContainer = document.querySelector('.overflow-auto')
104
- if (bodyContainer) {
105
- bodyContainer.addEventListener('scroll', () => {
106
- if (!ticking) {
107
- window.requestAnimationFrame(updateVisibleRows)
108
- ticking = true
109
- }
110
- })
111
- }
112
- }
113
- </script>