@stacksjs/components 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +477 -0
- package/dist/Accordion-x2gjedap.stx +108 -0
- package/dist/Audio-0fk6p9tn.stx +50 -0
- package/dist/Avatar-5m0v0s4x.stx +88 -0
- package/dist/Badge-ynes82vv.stx +70 -0
- package/dist/Breadcrumb-h9n427sk.stx +79 -0
- package/dist/Button-7xtrzn14.stx +89 -0
- package/dist/Calendar-egvx1pma.stx +232 -0
- package/dist/Card-r9w7vy1a.stx +74 -0
- package/dist/Checkbox-m8v46pmx.stx +92 -0
- package/dist/Checkout-vcnnr176.stx +39 -0
- package/dist/CodeBlock-mwex82cm.stx +57 -0
- package/dist/Combobox-npb08vkp.stx +13 -0
- package/dist/ComboboxButton-vcdyq4zw.stx +13 -0
- package/dist/ComboboxInput-c9d2p02m.stx +25 -0
- package/dist/ComboboxOption-7d0h9ash.stx +52 -0
- package/dist/ComboboxOptions-4dtqc0qa.stx +12 -0
- package/dist/CommandPalette-ah00bf8v.stx +39 -0
- package/dist/CommandPaletteItem-2yx0gvtj.stx +32 -0
- package/dist/DefaultPaymentMethod-emw5fg8s.stx +62 -0
- package/dist/Dialog-1w4rz7x0.stx +19 -0
- package/dist/DialogBackdrop-qbm3y5ab.stx +9 -0
- package/dist/DialogDescription-01w5j74b.stx +11 -0
- package/dist/DialogPanel-brsszrrs.stx +16 -0
- package/dist/DialogTitle-3rxhwg21.stx +11 -0
- package/dist/Drawer-yfaz8q7f.stx +137 -0
- package/dist/Dropdown-ng7nx556.stx +24 -0
- package/dist/DropdownButton-vc4zpyrb.stx +23 -0
- package/dist/DropdownItem-z491y23c.stx +43 -0
- package/dist/DropdownItems-7ykf29sj.stx +18 -0
- package/dist/EmailInput-bfshpj92.stx +41 -0
- package/dist/Footer-xdaf02nr.stx +66 -0
- package/dist/Form-z4f7w6r1.stx +209 -0
- package/dist/Hero-9vvp7pxf.stx +25 -0
- package/dist/Image-ktk0451c.stx +197 -0
- package/dist/Installation-33bj4rm7.stx +39 -0
- package/dist/Listbox-xcejcmyc.stx +14 -0
- package/dist/ListboxButton-nx5kmw19.stx +17 -0
- package/dist/ListboxLabel-aky8a73n.stx +11 -0
- package/dist/ListboxOption-6h4hsdz5.stx +57 -0
- package/dist/ListboxOptions-2sacdtm5.stx +16 -0
- package/dist/Login-s2jkvd9y.stx +163 -0
- package/dist/Navigator-tqqdgdkw.stx +138 -0
- package/dist/Notification-sry8egea.stx +71 -0
- package/dist/NumberInput-zm93ddfw.stx +138 -0
- package/dist/Pagination-yza9v4qw.stx +183 -0
- package/dist/PasswordInput-4xnndp5y.stx +155 -0
- package/dist/PaymentMethods-jxba6kek.stx +113 -0
- package/dist/Popover-scbqatjq.stx +24 -0
- package/dist/PopoverButton-rbxhzj4k.stx +23 -0
- package/dist/PopoverPanel-9ng1rm6e.stx +23 -0
- package/dist/Portal-j111yvqp.stx +74 -0
- package/dist/Progress-gbmw3akr.stx +142 -0
- package/dist/Radio-1n9qamv1.stx +81 -0
- package/dist/RadioGroup-12dw2vhk.stx +13 -0
- package/dist/RadioGroupDescription-bjm3mdht.stx +11 -0
- package/dist/RadioGroupLabel-aky8a73n.stx +11 -0
- package/dist/RadioGroupOption-9pcxgwmd.stx +51 -0
- package/dist/SearchInput-g240e2nq.stx +63 -0
- package/dist/Select-p9f94b20.stx +89 -0
- package/dist/Sidebar-gwxw8q38.stx +288 -0
- package/dist/SidebarFooter-887kxret.stx +95 -0
- package/dist/SidebarHeader-qjeyx0hv.stx +100 -0
- package/dist/SidebarItem-4dpwtmb4.stx +118 -0
- package/dist/SidebarSection-kh92fk4m.stx +108 -0
- package/dist/Signup-3nxq5zag.stx +161 -0
- package/dist/Skeleton-g0nx1njm.stx +48 -0
- package/dist/Spinner-w4zj58xp.stx +109 -0
- package/dist/Stepper-rwc5actp.stx +17 -0
- package/dist/StepperStep-h0k657nm.stx +53 -0
- package/dist/SubscriptionCheckout-4cbxdg7w.stx +353 -0
- package/dist/Switch-kjq8qd2p.stx +74 -0
- package/dist/Table-59j9qwp0.stx +14 -0
- package/dist/TableBody-reka2gwv.stx +10 -0
- package/dist/TableCell-j7nh4sgr.stx +10 -0
- package/dist/TableHead-ecbrwpqm.stx +10 -0
- package/dist/TableHeader-jn2shwsv.stx +13 -0
- package/dist/TableRow-xz8rrxhc.stx +11 -0
- package/dist/Tabs-kb6ex6m7.stx +145 -0
- package/dist/Teleport-819cg9zm.stx +101 -0
- package/dist/TextInput-zx9kgr79.stx +146 -0
- package/dist/Textarea-5xvmrb0z.stx +119 -0
- package/dist/Tooltip-5ehqsy49.stx +76 -0
- package/dist/Transition-2j39s044.stx +174 -0
- package/dist/TwoFactorChallenge-2q4gg89m.stx +125 -0
- package/dist/Video-6aq4shh4.stx +45 -0
- package/dist/VirtualList-weh5qtm1.stx +83 -0
- package/dist/VirtualTable-59a1eskc.stx +113 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/composables/index.d.ts +4 -0
- package/dist/composables/index.js +3 -0
- package/dist/composables/useCopyCode.d.ts +19 -0
- package/dist/composables/useDarkMode.d.ts +25 -0
- package/dist/composables/useSEO.d.ts +36 -0
- package/dist/composables/utilities/index.d.ts +5 -0
- package/dist/composables/utilities/useClickOutside.d.ts +28 -0
- package/dist/composables/utilities/useFocusTrap.d.ts +34 -0
- package/dist/composables/utilities/useKeyboard.d.ts +55 -0
- package/dist/composables/utilities/useLocalStorage.d.ts +33 -0
- package/dist/composables/utilities/useMediaQuery.d.ts +64 -0
- package/dist/index.d.ts +86 -0
- package/dist/index.js +19 -0
- package/dist/ui/accordion/index.d.ts +12 -0
- package/dist/ui/audio/index.d.ts +12 -0
- package/dist/ui/auth/index.d.ts +29 -0
- package/dist/ui/avatar/index.d.ts +11 -0
- package/dist/ui/badge/index.d.ts +9 -0
- package/dist/ui/breadcrumb/index.d.ts +13 -0
- package/dist/ui/button/index.d.ts +45 -0
- package/dist/ui/calendar/index.d.ts +13 -0
- package/dist/ui/card/index.d.ts +12 -0
- package/dist/ui/checkbox/index.d.ts +15 -0
- package/dist/ui/combobox/index.d.ts +35 -0
- package/dist/ui/command-palette/index.d.ts +13 -0
- package/dist/ui/dialog/index.d.ts +27 -0
- package/dist/ui/drawer/index.d.ts +8 -0
- package/dist/ui/dropdown/index.d.ts +25 -0
- package/dist/ui/form/index.d.ts +48 -0
- package/dist/ui/image/index.d.ts +21 -0
- package/dist/ui/input/index.d.ts +73 -0
- package/dist/ui/listbox/index.d.ts +34 -0
- package/dist/ui/navigator/index.d.ts +18 -0
- package/dist/ui/notification/index.d.ts +11 -0
- package/dist/ui/pagination/index.d.ts +10 -0
- package/dist/ui/payment/index.d.ts +53 -0
- package/dist/ui/popover/index.d.ts +19 -0
- package/dist/ui/portal/index.d.ts +5 -0
- package/dist/ui/progress/index.d.ts +11 -0
- package/dist/ui/radio/index.d.ts +14 -0
- package/dist/ui/radio-group/index.d.ts +26 -0
- package/dist/ui/select/index.d.ts +19 -0
- package/dist/ui/sidebar/index.d.ts +129 -0
- package/dist/ui/skeleton/index.d.ts +10 -0
- package/dist/ui/spinner/index.d.ts +8 -0
- package/dist/ui/stepper/index.d.ts +17 -0
- package/dist/ui/storage/index.d.ts +40 -0
- package/dist/ui/switch/index.d.ts +9 -0
- package/dist/ui/table/index.d.ts +29 -0
- package/dist/ui/tabs/index.d.ts +14 -0
- package/dist/ui/teleport/index.d.ts +6 -0
- package/dist/ui/textarea/index.d.ts +19 -0
- package/dist/ui/tooltip/index.d.ts +9 -0
- package/dist/ui/transition/index.d.ts +24 -0
- package/dist/ui/video/index.d.ts +15 -0
- package/dist/ui/virtual-list/index.d.ts +9 -0
- package/dist/ui/virtual-table/index.d.ts +19 -0
- package/dist/utils/accessibility.d.ts +285 -0
- package/dist/utils/animation/easing.d.ts +112 -0
- package/dist/utils/animation/helpers.d.ts +119 -0
- package/dist/utils/animation/index.d.ts +3 -0
- package/dist/utils/animation/keyframes.d.ts +334 -0
- package/dist/utils/error-handling.d.ts +182 -0
- package/dist/utils/highlighter.d.ts +27 -0
- package/dist/utils/highlighter.js +2 -0
- package/dist/utils/i18n.d.ts +245 -0
- package/dist/utils/keep-alive.d.ts +171 -0
- package/dist/utils/lazy-loading.d.ts +174 -0
- package/dist/utils/prop-validation.d.ts +106 -0
- package/dist/utils/theme.d.ts +234 -0
- package/package.json +69 -0
- package/src/components/CodeBlock.stx +57 -0
- package/src/components/Footer.stx +66 -0
- package/src/components/Hero.stx +25 -0
- package/src/components/Installation.stx +39 -0
- package/src/components/index.ts +4 -0
- package/src/composables/index.ts +4 -0
- package/src/composables/useCopyCode.ts +73 -0
- package/src/composables/useDarkMode.ts +100 -0
- package/src/composables/useSEO.ts +229 -0
- package/src/composables/utilities/index.ts +7 -0
- package/src/composables/utilities/useClickOutside.ts +72 -0
- package/src/composables/utilities/useFocusTrap.ts +159 -0
- package/src/composables/utilities/useKeyboard.ts +124 -0
- package/src/composables/utilities/useLocalStorage.ts +132 -0
- package/src/composables/utilities/useMediaQuery.ts +118 -0
- package/src/index.ts +99 -0
- package/src/stx.d.ts +4 -0
- package/src/ui/accordion/Accordion.stx +108 -0
- package/src/ui/accordion/index.ts +14 -0
- package/src/ui/audio/Audio.stx +50 -0
- package/src/ui/audio/README.md +42 -0
- package/src/ui/audio/index.ts +13 -0
- package/src/ui/auth/Login.stx +163 -0
- package/src/ui/auth/README.md +145 -0
- package/src/ui/auth/Signup.stx +161 -0
- package/src/ui/auth/TwoFactorChallenge.stx +125 -0
- package/src/ui/auth/index.ts +32 -0
- package/src/ui/avatar/Avatar.stx +88 -0
- package/src/ui/avatar/index.ts +12 -0
- package/src/ui/badge/Badge.stx +70 -0
- package/src/ui/badge/index.ts +10 -0
- package/src/ui/breadcrumb/Breadcrumb.stx +79 -0
- package/src/ui/breadcrumb/index.ts +15 -0
- package/src/ui/button/Button.stx +89 -0
- package/src/ui/button/README.md +100 -0
- package/src/ui/button/index.ts +85 -0
- package/src/ui/calendar/Calendar.stx +232 -0
- package/src/ui/calendar/README.md +254 -0
- package/src/ui/calendar/index.ts +14 -0
- package/src/ui/card/Card.stx +74 -0
- package/src/ui/card/index.ts +13 -0
- package/src/ui/checkbox/Checkbox.stx +92 -0
- package/src/ui/checkbox/index.ts +16 -0
- package/src/ui/combobox/Combobox.stx +13 -0
- package/src/ui/combobox/ComboboxButton.stx +13 -0
- package/src/ui/combobox/ComboboxInput.stx +25 -0
- package/src/ui/combobox/ComboboxOption.stx +52 -0
- package/src/ui/combobox/ComboboxOptions.stx +12 -0
- package/src/ui/combobox/README.md +154 -0
- package/src/ui/combobox/index.ts +40 -0
- package/src/ui/command-palette/CommandPalette.stx +39 -0
- package/src/ui/command-palette/CommandPaletteItem.stx +32 -0
- package/src/ui/command-palette/README.md +42 -0
- package/src/ui/command-palette/index.ts +15 -0
- package/src/ui/dialog/Dialog.stx +19 -0
- package/src/ui/dialog/DialogBackdrop.stx +9 -0
- package/src/ui/dialog/DialogDescription.stx +11 -0
- package/src/ui/dialog/DialogPanel.stx +16 -0
- package/src/ui/dialog/DialogTitle.stx +11 -0
- package/src/ui/dialog/README.md +133 -0
- package/src/ui/dialog/index.ts +32 -0
- package/src/ui/drawer/Drawer.stx +137 -0
- package/src/ui/drawer/README.md +110 -0
- package/src/ui/drawer/index.ts +9 -0
- package/src/ui/dropdown/Dropdown.stx +24 -0
- package/src/ui/dropdown/DropdownButton.stx +23 -0
- package/src/ui/dropdown/DropdownItem.stx +43 -0
- package/src/ui/dropdown/DropdownItems.stx +18 -0
- package/src/ui/dropdown/README.md +142 -0
- package/src/ui/dropdown/index.ts +29 -0
- package/src/ui/form/Form.stx +209 -0
- package/src/ui/form/index.ts +67 -0
- package/src/ui/heatmap/Heatmap.stx +315 -0
- package/src/ui/image/Image.stx +197 -0
- package/src/ui/image/README.md +171 -0
- package/src/ui/image/index.ts +22 -0
- package/src/ui/input/EmailInput.stx +41 -0
- package/src/ui/input/NumberInput.stx +138 -0
- package/src/ui/input/PasswordInput.stx +155 -0
- package/src/ui/input/SearchInput.stx +63 -0
- package/src/ui/input/TextInput.stx +146 -0
- package/src/ui/input/index.ts +180 -0
- package/src/ui/listbox/Listbox.stx +14 -0
- package/src/ui/listbox/ListboxButton.stx +17 -0
- package/src/ui/listbox/ListboxLabel.stx +11 -0
- package/src/ui/listbox/ListboxOption.stx +57 -0
- package/src/ui/listbox/ListboxOptions.stx +16 -0
- package/src/ui/listbox/README.md +143 -0
- package/src/ui/listbox/index.ts +39 -0
- package/src/ui/navigator/Navigator.stx +138 -0
- package/src/ui/navigator/README.md +352 -0
- package/src/ui/navigator/index.ts +20 -0
- package/src/ui/notification/Notification.stx +71 -0
- package/src/ui/notification/README.md +118 -0
- package/src/ui/notification/index.ts +12 -0
- package/src/ui/pagination/Pagination.stx +183 -0
- package/src/ui/pagination/index.ts +11 -0
- package/src/ui/payment/Checkout.stx +39 -0
- package/src/ui/payment/DefaultPaymentMethod.stx +62 -0
- package/src/ui/payment/PaymentMethods.stx +113 -0
- package/src/ui/payment/README.md +427 -0
- package/src/ui/payment/SubscriptionCheckout.stx +353 -0
- package/src/ui/payment/index.ts +59 -0
- package/src/ui/popover/Popover.stx +24 -0
- package/src/ui/popover/PopoverButton.stx +23 -0
- package/src/ui/popover/PopoverPanel.stx +23 -0
- package/src/ui/popover/README.md +95 -0
- package/src/ui/popover/index.ts +22 -0
- package/src/ui/portal/Portal.stx +74 -0
- package/src/ui/portal/index.ts +6 -0
- package/src/ui/progress/Progress.stx +142 -0
- package/src/ui/progress/index.ts +12 -0
- package/src/ui/radio/Radio.stx +81 -0
- package/src/ui/radio/index.ts +15 -0
- package/src/ui/radio-group/README.md +145 -0
- package/src/ui/radio-group/RadioGroup.stx +13 -0
- package/src/ui/radio-group/RadioGroupDescription.stx +11 -0
- package/src/ui/radio-group/RadioGroupLabel.stx +11 -0
- package/src/ui/radio-group/RadioGroupOption.stx +51 -0
- package/src/ui/radio-group/index.ts +30 -0
- package/src/ui/select/README.md +204 -0
- package/src/ui/select/Select.stx +89 -0
- package/src/ui/select/index.ts +21 -0
- package/src/ui/sidebar/Sidebar.stx +288 -0
- package/src/ui/sidebar/SidebarFooter.stx +95 -0
- package/src/ui/sidebar/SidebarHeader.stx +100 -0
- package/src/ui/sidebar/SidebarItem.stx +118 -0
- package/src/ui/sidebar/SidebarSection.stx +108 -0
- package/src/ui/sidebar/index.ts +175 -0
- package/src/ui/skeleton/Skeleton.stx +48 -0
- package/src/ui/skeleton/index.ts +11 -0
- package/src/ui/spinner/Spinner.stx +109 -0
- package/src/ui/spinner/index.ts +9 -0
- package/src/ui/stepper/README.md +36 -0
- package/src/ui/stepper/Stepper.stx +17 -0
- package/src/ui/stepper/StepperStep.stx +53 -0
- package/src/ui/stepper/index.ts +19 -0
- package/src/ui/storage/README.md +193 -0
- package/src/ui/storage/index.ts +347 -0
- package/src/ui/switch/README.md +133 -0
- package/src/ui/switch/Switch.stx +74 -0
- package/src/ui/switch/index.ts +10 -0
- package/src/ui/table/README.md +39 -0
- package/src/ui/table/Table.stx +14 -0
- package/src/ui/table/TableBody.stx +10 -0
- package/src/ui/table/TableCell.stx +10 -0
- package/src/ui/table/TableHead.stx +10 -0
- package/src/ui/table/TableHeader.stx +13 -0
- package/src/ui/table/TableRow.stx +11 -0
- package/src/ui/table/index.ts +35 -0
- package/src/ui/tabs/Tabs.stx +145 -0
- package/src/ui/tabs/index.ts +16 -0
- package/src/ui/teleport/Teleport.stx +101 -0
- package/src/ui/teleport/index.ts +7 -0
- package/src/ui/textarea/Textarea.stx +119 -0
- package/src/ui/textarea/index.ts +20 -0
- package/src/ui/tooltip/Tooltip.stx +76 -0
- package/src/ui/tooltip/index.ts +10 -0
- package/src/ui/transition/README.md +30 -0
- package/src/ui/transition/Transition.stx +174 -0
- package/src/ui/transition/index.ts +25 -0
- package/src/ui/video/README.md +48 -0
- package/src/ui/video/Video.stx +45 -0
- package/src/ui/video/index.ts +16 -0
- package/src/ui/virtual-list/VirtualList.stx +83 -0
- package/src/ui/virtual-list/index.ts +10 -0
- package/src/ui/virtual-table/VirtualTable.stx +113 -0
- package/src/ui/virtual-table/index.ts +21 -0
- package/src/utils/PROP_VALIDATION.md +458 -0
- package/src/utils/THEME_SYSTEM.md +702 -0
- package/src/utils/accessibility.ts +841 -0
- package/src/utils/animation/easing.ts +368 -0
- package/src/utils/animation/helpers.ts +223 -0
- package/src/utils/animation/index.ts +5 -0
- package/src/utils/animation/keyframes.ts +230 -0
- package/src/utils/error-handling.ts +473 -0
- package/src/utils/highlighter.ts +93 -0
- package/src/utils/i18n.ts +634 -0
- package/src/utils/keep-alive.ts +818 -0
- package/src/utils/lazy-loading.ts +530 -0
- package/src/utils/prop-validation.ts +478 -0
- package/src/utils/theme.ts +626 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export const to = $props.to || 'body'
|
|
3
|
+
export const disabled = $props.disabled || false
|
|
4
|
+
export const defer = $props.defer || false
|
|
5
|
+
|
|
6
|
+
let teleportContainer = null
|
|
7
|
+
let teleportId = `teleport-${Math.random().toString(36).substr(2, 9)}`
|
|
8
|
+
|
|
9
|
+
// Teleport content to target
|
|
10
|
+
function teleport() {
|
|
11
|
+
if (typeof window === 'undefined' || disabled)
|
|
12
|
+
return
|
|
13
|
+
|
|
14
|
+
// Get target element
|
|
15
|
+
const targetElement = typeof to === 'string'
|
|
16
|
+
? document.querySelector(to)
|
|
17
|
+
: to
|
|
18
|
+
|
|
19
|
+
if (!targetElement) {
|
|
20
|
+
console.warn(`Teleport target "${to}" not found`)
|
|
21
|
+
return
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Get source element
|
|
25
|
+
const sourceElement = document.getElementById(teleportId)
|
|
26
|
+
if (!sourceElement)
|
|
27
|
+
return
|
|
28
|
+
|
|
29
|
+
// Create teleport container if needed
|
|
30
|
+
if (!teleportContainer) {
|
|
31
|
+
teleportContainer = document.createElement('div')
|
|
32
|
+
teleportContainer.setAttribute('data-teleport-id', teleportId)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Move all child nodes to container
|
|
36
|
+
while (sourceElement.firstChild) {
|
|
37
|
+
teleportContainer.appendChild(sourceElement.firstChild)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Append to target
|
|
41
|
+
targetElement.appendChild(teleportContainer)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Return content back to original location
|
|
45
|
+
function returnContent() {
|
|
46
|
+
if (!teleportContainer || !teleportContainer.parentNode)
|
|
47
|
+
return
|
|
48
|
+
|
|
49
|
+
const sourceElement = document.getElementById(teleportId)
|
|
50
|
+
if (!sourceElement)
|
|
51
|
+
return
|
|
52
|
+
|
|
53
|
+
// Move content back
|
|
54
|
+
while (teleportContainer.firstChild) {
|
|
55
|
+
sourceElement.appendChild(teleportContainer.firstChild)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Remove container
|
|
59
|
+
teleportContainer.parentNode.removeChild(teleportContainer)
|
|
60
|
+
teleportContainer = null
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Initialize teleport
|
|
64
|
+
if (typeof window !== 'undefined') {
|
|
65
|
+
if (defer) {
|
|
66
|
+
// Defer until next tick
|
|
67
|
+
window.addEventListener('DOMContentLoaded', () => {
|
|
68
|
+
setTimeout(teleport, 0)
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
// Immediate
|
|
73
|
+
window.addEventListener('DOMContentLoaded', teleport)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Cleanup on page unload
|
|
77
|
+
window.addEventListener('beforeunload', returnContent)
|
|
78
|
+
}
|
|
79
|
+
</script>
|
|
80
|
+
|
|
81
|
+
@if(disabled)
|
|
82
|
+
<!-- Render in place if disabled -->
|
|
83
|
+
<slot />
|
|
84
|
+
@else
|
|
85
|
+
<!-- Source container -->
|
|
86
|
+
<div id="{{ teleportId }}" data-teleport-source="true">
|
|
87
|
+
<slot />
|
|
88
|
+
</div>
|
|
89
|
+
@endif
|
|
90
|
+
|
|
91
|
+
<script>
|
|
92
|
+
// Trigger teleport after render
|
|
93
|
+
if (typeof window !== 'undefined' && document.readyState === 'complete') {
|
|
94
|
+
if (defer) {
|
|
95
|
+
setTimeout(teleport, 0)
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
teleport()
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
</script>
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export const value = $props.value || ''
|
|
3
|
+
export const onChange = $props.onChange || (() => {})
|
|
4
|
+
export const placeholder = $props.placeholder || ''
|
|
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 leftIcon = $props.leftIcon || ''
|
|
13
|
+
export const rightIcon = $props.rightIcon || ''
|
|
14
|
+
export const clearable = $props.clearable || false
|
|
15
|
+
export const maxLength = $props.maxLength
|
|
16
|
+
export const showCount = $props.showCount || false
|
|
17
|
+
export const className = $props.className || ''
|
|
18
|
+
export const inputClassName = $props.inputClassName || ''
|
|
19
|
+
|
|
20
|
+
// Size classes
|
|
21
|
+
const sizeClasses = {
|
|
22
|
+
sm: 'px-3 py-1.5 text-sm h-8',
|
|
23
|
+
md: 'px-4 py-2 text-base h-10',
|
|
24
|
+
lg: 'px-5 py-3 text-lg h-12',
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Icon size classes
|
|
28
|
+
const iconSizeClasses = {
|
|
29
|
+
sm: 'h-4 w-4',
|
|
30
|
+
md: 'h-5 w-5',
|
|
31
|
+
lg: 'h-6 w-6',
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Base and state classes
|
|
35
|
+
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'
|
|
36
|
+
|
|
37
|
+
const stateClasses = error
|
|
38
|
+
? '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'
|
|
39
|
+
: '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'
|
|
40
|
+
|
|
41
|
+
const disabledClasses = disabled
|
|
42
|
+
? 'opacity-50 cursor-not-allowed bg-gray-50 dark:bg-gray-800'
|
|
43
|
+
: readonly
|
|
44
|
+
? 'bg-gray-50 dark:bg-gray-800 cursor-default'
|
|
45
|
+
: 'bg-white dark:bg-blue-gray-700'
|
|
46
|
+
|
|
47
|
+
const paddingClasses = leftIcon ? 'pl-10' : rightIcon || clearable ? 'pr-10' : ''
|
|
48
|
+
|
|
49
|
+
export const inputClasses = `${baseClasses} ${sizeClasses[size]} ${stateClasses} ${disabledClasses} ${paddingClasses} ${inputClassName}`.trim()
|
|
50
|
+
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()
|
|
51
|
+
export const helperClasses = `mt-2 text-sm ${error ? 'text-red-600 dark:text-red-400' : 'text-gray-500 dark:text-gray-400'}`.trim()
|
|
52
|
+
export const iconClasses = iconSizeClasses[size]
|
|
53
|
+
export const hasValue = value && value.length > 0
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
<div class="w-full {{ className }}">
|
|
57
|
+
@if(label)
|
|
58
|
+
<label for="input-{{ label }}" class="{{ labelClasses }}">
|
|
59
|
+
{{ label }}
|
|
60
|
+
@if(required)
|
|
61
|
+
<span class="text-red-500 ml-1">*</span>
|
|
62
|
+
@endif
|
|
63
|
+
</label>
|
|
64
|
+
@endif
|
|
65
|
+
|
|
66
|
+
<div class="relative">
|
|
67
|
+
@if(leftIcon)
|
|
68
|
+
<!-- Left icon -->
|
|
69
|
+
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
|
|
70
|
+
<span class="{{ iconClasses }} text-gray-400 dark:text-gray-500" innerHTML="{!! leftIcon !!}"></span>
|
|
71
|
+
</div>
|
|
72
|
+
@endif
|
|
73
|
+
|
|
74
|
+
<input
|
|
75
|
+
type="text"
|
|
76
|
+
id="input-{{ label }}"
|
|
77
|
+
class="{{ inputClasses }}"
|
|
78
|
+
value="{{ value }}"
|
|
79
|
+
placeholder="{{ placeholder }}"
|
|
80
|
+
disabled="{{ disabled }}"
|
|
81
|
+
readonly="{{ readonly }}"
|
|
82
|
+
required="{{ required }}"
|
|
83
|
+
@if(maxLength)maxlength="{{ maxLength }}"@endif
|
|
84
|
+
oninput="handleInput(event)"
|
|
85
|
+
aria-invalid="{{ error ? 'true' : 'false' }}"
|
|
86
|
+
@if(helperText)aria-describedby="helper-text"@endif
|
|
87
|
+
/>
|
|
88
|
+
|
|
89
|
+
@if(clearable && hasValue && !disabled && !readonly)
|
|
90
|
+
<!-- Clear button -->
|
|
91
|
+
<div class="absolute inset-y-0 right-0 flex items-center pr-3">
|
|
92
|
+
<button
|
|
93
|
+
type="button"
|
|
94
|
+
onclick="handleClear()"
|
|
95
|
+
class="text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300 focus:outline-none"
|
|
96
|
+
aria-label="Clear input"
|
|
97
|
+
>
|
|
98
|
+
<svg class="{{ iconClasses }}" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
99
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
|
100
|
+
</svg>
|
|
101
|
+
</button>
|
|
102
|
+
</div>
|
|
103
|
+
@else
|
|
104
|
+
@if(rightIcon && !clearable)
|
|
105
|
+
<!-- Right icon -->
|
|
106
|
+
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3">
|
|
107
|
+
<span class="{{ iconClasses }} text-gray-400 dark:text-gray-500" innerHTML="{!! rightIcon !!}"></span>
|
|
108
|
+
</div>
|
|
109
|
+
@endif
|
|
110
|
+
@endif
|
|
111
|
+
</div>
|
|
112
|
+
|
|
113
|
+
@if(helperText || (showCount && maxLength))
|
|
114
|
+
<div class="flex items-center justify-between mt-2">
|
|
115
|
+
@if(helperText)
|
|
116
|
+
<p id="helper-text" class="{{ helperClasses }}">
|
|
117
|
+
{{ helperText }}
|
|
118
|
+
</p>
|
|
119
|
+
@else
|
|
120
|
+
<span></span>
|
|
121
|
+
@endif
|
|
122
|
+
|
|
123
|
+
@if(showCount && maxLength)
|
|
124
|
+
<p class="text-sm text-gray-500 dark:text-gray-400">
|
|
125
|
+
{{ value.length }} / {{ maxLength }}
|
|
126
|
+
</p>
|
|
127
|
+
@endif
|
|
128
|
+
</div>
|
|
129
|
+
@endif
|
|
130
|
+
</div>
|
|
131
|
+
|
|
132
|
+
<script>
|
|
133
|
+
function handleInput(event) {
|
|
134
|
+
const newValue = event.target.value
|
|
135
|
+
|
|
136
|
+
if (onChange) {
|
|
137
|
+
onChange(newValue)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function handleClear() {
|
|
142
|
+
if (onChange) {
|
|
143
|
+
onChange('')
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
</script>
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export const value = $props.value || ''
|
|
3
|
+
export const onChange = $props.onChange || (() => {})
|
|
4
|
+
export const placeholder = $props.placeholder || ''
|
|
5
|
+
export const disabled = $props.disabled || false
|
|
6
|
+
export const readonly = $props.readonly || false
|
|
7
|
+
export const rows = $props.rows || 4
|
|
8
|
+
export const autoResize = $props.autoResize || false
|
|
9
|
+
export const maxRows = $props.maxRows || 10
|
|
10
|
+
export const error = $props.error || false
|
|
11
|
+
export const label = $props.label || ''
|
|
12
|
+
export const helperText = $props.helperText || ''
|
|
13
|
+
export const required = $props.required || false
|
|
14
|
+
export const maxLength = $props.maxLength
|
|
15
|
+
export const showCount = $props.showCount || false
|
|
16
|
+
export const resize = $props.resize || 'vertical' // 'none' | 'vertical' | 'horizontal' | 'both'
|
|
17
|
+
export const className = $props.className || ''
|
|
18
|
+
|
|
19
|
+
// Resize classes
|
|
20
|
+
const resizeClasses = {
|
|
21
|
+
none: 'resize-none',
|
|
22
|
+
vertical: 'resize-y',
|
|
23
|
+
horizontal: 'resize-x',
|
|
24
|
+
both: 'resize',
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Base and state classes
|
|
28
|
+
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 px-4 py-2 text-base dark:bg-blue-gray-700 dark:text-gray-100'
|
|
29
|
+
|
|
30
|
+
const stateClasses = error
|
|
31
|
+
? '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'
|
|
32
|
+
: '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'
|
|
33
|
+
|
|
34
|
+
const disabledClasses = disabled
|
|
35
|
+
? 'opacity-50 cursor-not-allowed bg-gray-50 dark:bg-gray-800'
|
|
36
|
+
: readonly
|
|
37
|
+
? 'bg-gray-50 dark:bg-gray-800 cursor-default'
|
|
38
|
+
: 'bg-white dark:bg-blue-gray-700'
|
|
39
|
+
|
|
40
|
+
export const textareaClasses = `${baseClasses} ${stateClasses} ${disabledClasses} ${resizeClasses[resize]} ${className}`.trim()
|
|
41
|
+
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()
|
|
42
|
+
export const helperClasses = `mt-2 text-sm ${error ? 'text-red-600 dark:text-red-400' : 'text-gray-500 dark:text-gray-400'}`.trim()
|
|
43
|
+
</script>
|
|
44
|
+
|
|
45
|
+
<div class="w-full">
|
|
46
|
+
@if(label)
|
|
47
|
+
<label for="textarea-input" class="{{ labelClasses }}">
|
|
48
|
+
{{ label }}
|
|
49
|
+
@if(required)
|
|
50
|
+
<span class="text-red-500 ml-1">*</span>
|
|
51
|
+
@endif
|
|
52
|
+
</label>
|
|
53
|
+
@endif
|
|
54
|
+
|
|
55
|
+
<textarea
|
|
56
|
+
id="textarea-input"
|
|
57
|
+
class="{{ textareaClasses }}"
|
|
58
|
+
rows="{{ rows }}"
|
|
59
|
+
placeholder="{{ placeholder }}"
|
|
60
|
+
disabled="{{ disabled }}"
|
|
61
|
+
readonly="{{ readonly }}"
|
|
62
|
+
required="{{ required }}"
|
|
63
|
+
@if(maxLength)maxlength="{{ maxLength }}"@endif
|
|
64
|
+
oninput="handleInput(event)"
|
|
65
|
+
aria-invalid="{{ error ? 'true' : 'false' }}"
|
|
66
|
+
@if(helperText)aria-describedby="helper-text"@endif
|
|
67
|
+
>{{ value }}</textarea>
|
|
68
|
+
|
|
69
|
+
@if(helperText || (showCount && maxLength))
|
|
70
|
+
<div class="flex items-center justify-between mt-2">
|
|
71
|
+
@if(helperText)
|
|
72
|
+
<p id="helper-text" class="{{ helperClasses }}">
|
|
73
|
+
{{ helperText }}
|
|
74
|
+
</p>
|
|
75
|
+
@else
|
|
76
|
+
<span></span>
|
|
77
|
+
@endif
|
|
78
|
+
|
|
79
|
+
@if(showCount && maxLength)
|
|
80
|
+
<p class="text-sm text-gray-500 dark:text-gray-400">
|
|
81
|
+
{{ value.length }} / {{ maxLength }}
|
|
82
|
+
</p>
|
|
83
|
+
@endif
|
|
84
|
+
</div>
|
|
85
|
+
@endif
|
|
86
|
+
</div>
|
|
87
|
+
|
|
88
|
+
<script>
|
|
89
|
+
function handleInput(event) {
|
|
90
|
+
const textarea = event.target
|
|
91
|
+
const newValue = textarea.value
|
|
92
|
+
|
|
93
|
+
if (autoResize && typeof window !== 'undefined') {
|
|
94
|
+
// Auto-resize functionality
|
|
95
|
+
textarea.style.height = 'auto'
|
|
96
|
+
const scrollHeight = textarea.scrollHeight
|
|
97
|
+
const lineHeight = parseInt(window.getComputedStyle(textarea).lineHeight)
|
|
98
|
+
const maxHeight = lineHeight * maxRows
|
|
99
|
+
|
|
100
|
+
textarea.style.height = Math.min(scrollHeight, maxHeight) + 'px'
|
|
101
|
+
textarea.style.overflowY = scrollHeight > maxHeight ? 'auto' : 'hidden'
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (onChange) {
|
|
105
|
+
onChange(newValue)
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Initialize auto-resize on mount
|
|
110
|
+
if (autoResize && typeof window !== 'undefined') {
|
|
111
|
+
window.addEventListener('DOMContentLoaded', () => {
|
|
112
|
+
const textarea = document.getElementById('textarea-input')
|
|
113
|
+
if (textarea && value) {
|
|
114
|
+
// Trigger initial resize
|
|
115
|
+
textarea.dispatchEvent(new Event('input'))
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
}
|
|
119
|
+
</script>
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export const content = $props.content || ''
|
|
3
|
+
export const position = $props.position || 'top'
|
|
4
|
+
export const delay = $props.delay || 0
|
|
5
|
+
export const className = $props.className || ''
|
|
6
|
+
export const show = $props.show || false
|
|
7
|
+
export const disabled = $props.disabled || false
|
|
8
|
+
|
|
9
|
+
// Position classes
|
|
10
|
+
const positionClasses = {
|
|
11
|
+
top: 'bottom-full left-1/2 -translate-x-1/2 mb-2',
|
|
12
|
+
bottom: 'top-full left-1/2 -translate-x-1/2 mt-2',
|
|
13
|
+
left: 'right-full top-1/2 -translate-y-1/2 mr-2',
|
|
14
|
+
right: 'left-full top-1/2 -translate-y-1/2 ml-2',
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Arrow classes
|
|
18
|
+
const arrowClasses = {
|
|
19
|
+
top: 'top-full left-1/2 -translate-x-1/2 border-t-gray-900 dark:border-t-gray-700',
|
|
20
|
+
bottom: 'bottom-full left-1/2 -translate-x-1/2 border-b-gray-900 dark:border-b-gray-700',
|
|
21
|
+
left: 'left-full top-1/2 -translate-y-1/2 border-l-gray-900 dark:border-l-gray-700',
|
|
22
|
+
right: 'right-full top-1/2 -translate-y-1/2 border-r-gray-900 dark:border-r-gray-700',
|
|
23
|
+
}
|
|
24
|
+
|
|
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()
|
|
26
|
+
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
|
+
</script>
|
|
31
|
+
|
|
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
|
|
59
|
+
|
|
60
|
+
if (delay > 0) {
|
|
61
|
+
timeoutId = setTimeout(() => {
|
|
62
|
+
isVisible = true
|
|
63
|
+
}, delay)
|
|
64
|
+
} else {
|
|
65
|
+
isVisible = true
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function handleMouseLeave() {
|
|
70
|
+
if (timeoutId) {
|
|
71
|
+
clearTimeout(timeoutId)
|
|
72
|
+
timeoutId = null
|
|
73
|
+
}
|
|
74
|
+
isVisible = false
|
|
75
|
+
}
|
|
76
|
+
</script>
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export const show = $props.show !== false
|
|
3
|
+
export const enter = $props.enter || 'transition-opacity duration-300'
|
|
4
|
+
export const enterFrom = $props.enterFrom || 'opacity-0'
|
|
5
|
+
export const enterTo = $props.enterTo || 'opacity-100'
|
|
6
|
+
export const leave = $props.leave || 'transition-opacity duration-200'
|
|
7
|
+
export const leaveFrom = $props.leaveFrom || 'opacity-100'
|
|
8
|
+
export const leaveTo = $props.leaveTo || 'opacity-0'
|
|
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
|
+
export const duration = $props.duration || 300
|
|
14
|
+
export const delay = $props.delay || 0
|
|
15
|
+
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
|
+
export const className = $props.className || ''
|
|
23
|
+
|
|
24
|
+
// Preset transitions
|
|
25
|
+
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
|
+
},
|
|
82
|
+
}
|
|
83
|
+
|
|
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
|
|
92
|
+
|
|
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;`
|
|
108
|
+
</script>
|
|
109
|
+
|
|
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)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
requestAnimationFrame(checkTransition)
|
|
164
|
+
|
|
165
|
+
// Handle initial appear
|
|
166
|
+
if (appear && show && !hasAppeared) {
|
|
167
|
+
hasAppeared = true
|
|
168
|
+
isEntering = true
|
|
169
|
+
setTimeout(() => {
|
|
170
|
+
isEntering = false
|
|
171
|
+
}, duration + delay)
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
</script>
|