fancy-ui-svelte 0.2.1
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/LICENSE +21 -0
- package/README.md +198 -0
- package/dist/fancy-ui/_template/Component.svelte +110 -0
- package/dist/fancy-ui/_template/Component.svelte.d.ts +16 -0
- package/dist/fancy-ui/_template/README.md +279 -0
- package/dist/fancy-ui/_template/index.d.ts +13 -0
- package/dist/fancy-ui/_template/index.js +27 -0
- package/dist/fancy-ui/_template/types.d.ts +53 -0
- package/dist/fancy-ui/_template/types.js +12 -0
- package/dist/fancy-ui/animated-beam/AnimatedBeam.svelte +166 -0
- package/dist/fancy-ui/animated-beam/AnimatedBeam.svelte.d.ts +4 -0
- package/dist/fancy-ui/animated-beam/AnimatedBeam.test.d.ts +1 -0
- package/dist/fancy-ui/animated-beam/AnimatedBeam.test.js +49 -0
- package/dist/fancy-ui/animated-beam/README.md +38 -0
- package/dist/fancy-ui/animated-beam/index.d.ts +2 -0
- package/dist/fancy-ui/animated-beam/index.js +1 -0
- package/dist/fancy-ui/animated-beam/types.d.ts +19 -0
- package/dist/fancy-ui/animated-beam/types.js +1 -0
- package/dist/fancy-ui/animated-testimonials/AnimatedTestimonials.svelte +196 -0
- package/dist/fancy-ui/animated-testimonials/AnimatedTestimonials.svelte.d.ts +29 -0
- package/dist/fancy-ui/animated-testimonials/AnimatedTestimonials.test.d.ts +1 -0
- package/dist/fancy-ui/animated-testimonials/AnimatedTestimonials.test.js +92 -0
- package/dist/fancy-ui/animated-testimonials/index.d.ts +2 -0
- package/dist/fancy-ui/animated-testimonials/index.js +1 -0
- package/dist/fancy-ui/animated-tooltip/AnimatedTooltip.svelte +97 -0
- package/dist/fancy-ui/animated-tooltip/AnimatedTooltip.svelte.d.ts +15 -0
- package/dist/fancy-ui/animated-tooltip/AnimatedTooltip.test.d.ts +1 -0
- package/dist/fancy-ui/animated-tooltip/AnimatedTooltip.test.js +67 -0
- package/dist/fancy-ui/animated-tooltip/index.d.ts +2 -0
- package/dist/fancy-ui/animated-tooltip/index.js +1 -0
- package/dist/fancy-ui/apple-card-carousel/AppleCard.svelte +226 -0
- package/dist/fancy-ui/apple-card-carousel/AppleCard.svelte.d.ts +27 -0
- package/dist/fancy-ui/apple-card-carousel/AppleCardCarousel.svelte +49 -0
- package/dist/fancy-ui/apple-card-carousel/AppleCardCarousel.svelte.d.ts +11 -0
- package/dist/fancy-ui/apple-card-carousel/AppleCardCarousel.test.d.ts +1 -0
- package/dist/fancy-ui/apple-card-carousel/AppleCardCarousel.test.js +85 -0
- package/dist/fancy-ui/apple-card-carousel/index.d.ts +3 -0
- package/dist/fancy-ui/apple-card-carousel/index.js +2 -0
- package/dist/fancy-ui/bento-grid/BentoGrid.svelte +21 -0
- package/dist/fancy-ui/bento-grid/BentoGrid.svelte.d.ts +7 -0
- package/dist/fancy-ui/bento-grid/BentoGridCard.svelte +70 -0
- package/dist/fancy-ui/bento-grid/BentoGridCard.svelte.d.ts +12 -0
- package/dist/fancy-ui/bento-grid/BentoGridItem.svelte +39 -0
- package/dist/fancy-ui/bento-grid/BentoGridItem.svelte.d.ts +10 -0
- package/dist/fancy-ui/bento-grid/README.md +51 -0
- package/dist/fancy-ui/bento-grid/index.d.ts +3 -0
- package/dist/fancy-ui/bento-grid/index.js +3 -0
- package/dist/fancy-ui/bg-falling-stars/FallingStarsBg.svelte +163 -0
- package/dist/fancy-ui/bg-falling-stars/FallingStarsBg.svelte.d.ts +11 -0
- package/dist/fancy-ui/bg-falling-stars/FallingStarsBg.test.d.ts +1 -0
- package/dist/fancy-ui/bg-falling-stars/FallingStarsBg.test.js +50 -0
- package/dist/fancy-ui/bg-falling-stars/README.md +22 -0
- package/dist/fancy-ui/bg-falling-stars/index.d.ts +2 -0
- package/dist/fancy-ui/bg-falling-stars/index.js +1 -0
- package/dist/fancy-ui/bg-stars/README.md +41 -0
- package/dist/fancy-ui/bg-stars/StarsBackground.svelte +205 -0
- package/dist/fancy-ui/bg-stars/StarsBackground.svelte.d.ts +33 -0
- package/dist/fancy-ui/bg-stars/StarsBackground.test.d.ts +1 -0
- package/dist/fancy-ui/bg-stars/StarsBackground.test.js +46 -0
- package/dist/fancy-ui/bg-stars/index.d.ts +1 -0
- package/dist/fancy-ui/bg-stars/index.js +1 -0
- package/dist/fancy-ui/blur-reveal/BlurReveal.svelte +126 -0
- package/dist/fancy-ui/blur-reveal/BlurReveal.svelte.d.ts +18 -0
- package/dist/fancy-ui/blur-reveal/BlurReveal.test.d.ts +1 -0
- package/dist/fancy-ui/blur-reveal/BlurReveal.test.js +47 -0
- package/dist/fancy-ui/blur-reveal/README.md +41 -0
- package/dist/fancy-ui/blur-reveal/index.d.ts +2 -0
- package/dist/fancy-ui/blur-reveal/index.js +2 -0
- package/dist/fancy-ui/book/Book.svelte +89 -0
- package/dist/fancy-ui/book/Book.svelte.d.ts +15 -0
- package/dist/fancy-ui/book/Book.test.d.ts +1 -0
- package/dist/fancy-ui/book/Book.test.js +47 -0
- package/dist/fancy-ui/book/BookDescription.svelte +17 -0
- package/dist/fancy-ui/book/BookDescription.svelte.d.ts +8 -0
- package/dist/fancy-ui/book/BookHeader.svelte +17 -0
- package/dist/fancy-ui/book/BookHeader.svelte.d.ts +8 -0
- package/dist/fancy-ui/book/BookTitle.svelte +17 -0
- package/dist/fancy-ui/book/BookTitle.svelte.d.ts +8 -0
- package/dist/fancy-ui/book/README.md +34 -0
- package/dist/fancy-ui/book/index.d.ts +128 -0
- package/dist/fancy-ui/book/index.js +46 -0
- package/dist/fancy-ui/border-beam/BorderBeam.svelte +85 -0
- package/dist/fancy-ui/border-beam/BorderBeam.svelte.d.ts +27 -0
- package/dist/fancy-ui/border-beam/BorderBeam.test.d.ts +1 -0
- package/dist/fancy-ui/border-beam/BorderBeam.test.js +64 -0
- package/dist/fancy-ui/border-beam/index.d.ts +2 -0
- package/dist/fancy-ui/border-beam/index.js +2 -0
- package/dist/fancy-ui/box-reveal/BoxReveal.svelte +73 -0
- package/dist/fancy-ui/box-reveal/BoxReveal.svelte.d.ts +24 -0
- package/dist/fancy-ui/box-reveal/BoxReveal.test.d.ts +1 -0
- package/dist/fancy-ui/box-reveal/BoxReveal.test.js +66 -0
- package/dist/fancy-ui/box-reveal/README.md +24 -0
- package/dist/fancy-ui/box-reveal/index.d.ts +2 -0
- package/dist/fancy-ui/box-reveal/index.js +2 -0
- package/dist/fancy-ui/card-3d/CardBody.svelte +16 -0
- package/dist/fancy-ui/card-3d/CardBody.svelte.d.ts +7 -0
- package/dist/fancy-ui/card-3d/CardContainer.svelte +53 -0
- package/dist/fancy-ui/card-3d/CardContainer.svelte.d.ts +8 -0
- package/dist/fancy-ui/card-3d/CardItem.svelte +49 -0
- package/dist/fancy-ui/card-3d/CardItem.svelte.d.ts +14 -0
- package/dist/fancy-ui/card-3d/README.md +52 -0
- package/dist/fancy-ui/card-3d/index.d.ts +3 -0
- package/dist/fancy-ui/card-3d/index.js +3 -0
- package/dist/fancy-ui/card-spotlight/CardSpotlight.svelte +59 -0
- package/dist/fancy-ui/card-spotlight/CardSpotlight.svelte.d.ts +11 -0
- package/dist/fancy-ui/card-spotlight/README.md +24 -0
- package/dist/fancy-ui/card-spotlight/index.d.ts +1 -0
- package/dist/fancy-ui/card-spotlight/index.js +1 -0
- package/dist/fancy-ui/colourful-text/ColourfulText.svelte +78 -0
- package/dist/fancy-ui/colourful-text/ColourfulText.svelte.d.ts +22 -0
- package/dist/fancy-ui/colourful-text/ColourfulText.test.d.ts +1 -0
- package/dist/fancy-ui/colourful-text/ColourfulText.test.js +53 -0
- package/dist/fancy-ui/colourful-text/README.md +21 -0
- package/dist/fancy-ui/colourful-text/index.d.ts +2 -0
- package/dist/fancy-ui/colourful-text/index.js +2 -0
- package/dist/fancy-ui/compare/Compare.svelte +304 -0
- package/dist/fancy-ui/compare/Compare.svelte.d.ts +25 -0
- package/dist/fancy-ui/compare/Compare.test.d.ts +1 -0
- package/dist/fancy-ui/compare/Compare.test.js +57 -0
- package/dist/fancy-ui/compare/README.md +97 -0
- package/dist/fancy-ui/compare/StarField.svelte +108 -0
- package/dist/fancy-ui/compare/StarField.svelte.d.ts +7 -0
- package/dist/fancy-ui/compare/index.d.ts +2 -0
- package/dist/fancy-ui/compare/index.js +2 -0
- package/dist/fancy-ui/confetti/Confetti.svelte +60 -0
- package/dist/fancy-ui/confetti/Confetti.svelte.d.ts +14 -0
- package/dist/fancy-ui/confetti/Confetti.test.d.ts +1 -0
- package/dist/fancy-ui/confetti/Confetti.test.js +39 -0
- package/dist/fancy-ui/confetti/ConfettiButton.svelte +41 -0
- package/dist/fancy-ui/confetti/ConfettiButton.svelte.d.ts +9 -0
- package/dist/fancy-ui/confetti/README.md +22 -0
- package/dist/fancy-ui/confetti/index.d.ts +2 -0
- package/dist/fancy-ui/confetti/index.js +2 -0
- package/dist/fancy-ui/container-scroll/ContainerScroll.svelte +82 -0
- package/dist/fancy-ui/container-scroll/ContainerScroll.svelte.d.ts +9 -0
- package/dist/fancy-ui/container-scroll/ContainerScroll.test.d.ts +1 -0
- package/dist/fancy-ui/container-scroll/ContainerScroll.test.js +34 -0
- package/dist/fancy-ui/container-scroll/README.md +28 -0
- package/dist/fancy-ui/container-scroll/index.d.ts +1 -0
- package/dist/fancy-ui/container-scroll/index.js +1 -0
- package/dist/fancy-ui/container-text-flip/ContainerTextFlip.svelte +78 -0
- package/dist/fancy-ui/container-text-flip/ContainerTextFlip.svelte.d.ts +10 -0
- package/dist/fancy-ui/container-text-flip/ContainerTextFlip.test.d.ts +1 -0
- package/dist/fancy-ui/container-text-flip/ContainerTextFlip.test.js +46 -0
- package/dist/fancy-ui/container-text-flip/README.md +22 -0
- package/dist/fancy-ui/container-text-flip/index.d.ts +1 -0
- package/dist/fancy-ui/container-text-flip/index.js +1 -0
- package/dist/fancy-ui/direction-aware-hover/DirectionAwareHover.svelte +232 -0
- package/dist/fancy-ui/direction-aware-hover/DirectionAwareHover.svelte.d.ts +11 -0
- package/dist/fancy-ui/direction-aware-hover/DirectionAwareHover.test.d.ts +1 -0
- package/dist/fancy-ui/direction-aware-hover/DirectionAwareHover.test.js +78 -0
- package/dist/fancy-ui/direction-aware-hover/README.md +47 -0
- package/dist/fancy-ui/direction-aware-hover/index.d.ts +1 -0
- package/dist/fancy-ui/direction-aware-hover/index.js +1 -0
- package/dist/fancy-ui/displacement-text/DisplacementText.svelte +224 -0
- package/dist/fancy-ui/displacement-text/DisplacementText.svelte.d.ts +19 -0
- package/dist/fancy-ui/displacement-text/DisplacementText.test.d.ts +1 -0
- package/dist/fancy-ui/displacement-text/DisplacementText.test.js +144 -0
- package/dist/fancy-ui/displacement-text/index.d.ts +2 -0
- package/dist/fancy-ui/displacement-text/index.js +1 -0
- package/dist/fancy-ui/dock/Dock.svelte +87 -0
- package/dist/fancy-ui/dock/Dock.svelte.d.ts +12 -0
- package/dist/fancy-ui/dock/Dock.test.d.ts +1 -0
- package/dist/fancy-ui/dock/Dock.test.js +51 -0
- package/dist/fancy-ui/dock/DockIcon.svelte +50 -0
- package/dist/fancy-ui/dock/DockIcon.svelte.d.ts +7 -0
- package/dist/fancy-ui/dock/DockSeparator.svelte +21 -0
- package/dist/fancy-ui/dock/DockSeparator.svelte.d.ts +6 -0
- package/dist/fancy-ui/dock/README.md +57 -0
- package/dist/fancy-ui/dock/index.d.ts +4 -0
- package/dist/fancy-ui/dock/index.js +4 -0
- package/dist/fancy-ui/dock/types.d.ts +14 -0
- package/dist/fancy-ui/dock/types.js +1 -0
- package/dist/fancy-ui/flickering-grid/FlickeringGrid.svelte +154 -0
- package/dist/fancy-ui/flickering-grid/FlickeringGrid.svelte.d.ts +27 -0
- package/dist/fancy-ui/flickering-grid/FlickeringGrid.test.d.ts +1 -0
- package/dist/fancy-ui/flickering-grid/FlickeringGrid.test.js +34 -0
- package/dist/fancy-ui/flickering-grid/README.md +24 -0
- package/dist/fancy-ui/flickering-grid/index.d.ts +2 -0
- package/dist/fancy-ui/flickering-grid/index.js +2 -0
- package/dist/fancy-ui/flip-card/FlipCard.svelte +48 -0
- package/dist/fancy-ui/flip-card/FlipCard.svelte.d.ts +10 -0
- package/dist/fancy-ui/flip-card/FlipCard.test.d.ts +1 -0
- package/dist/fancy-ui/flip-card/FlipCard.test.js +36 -0
- package/dist/fancy-ui/flip-card/README.md +26 -0
- package/dist/fancy-ui/flip-card/index.d.ts +1 -0
- package/dist/fancy-ui/flip-card/index.js +1 -0
- package/dist/fancy-ui/flip-words/FlipWords.svelte +135 -0
- package/dist/fancy-ui/flip-words/FlipWords.svelte.d.ts +18 -0
- package/dist/fancy-ui/flip-words/FlipWords.test.d.ts +1 -0
- package/dist/fancy-ui/flip-words/FlipWords.test.js +50 -0
- package/dist/fancy-ui/flip-words/README.md +17 -0
- package/dist/fancy-ui/flip-words/index.d.ts +2 -0
- package/dist/fancy-ui/flip-words/index.js +2 -0
- package/dist/fancy-ui/fluid-cursor/FluidCursor.svelte +1378 -0
- package/dist/fancy-ui/fluid-cursor/FluidCursor.svelte.d.ts +25 -0
- package/dist/fancy-ui/fluid-cursor/FluidCursor.test.d.ts +1 -0
- package/dist/fancy-ui/fluid-cursor/FluidCursor.test.js +41 -0
- package/dist/fancy-ui/fluid-cursor/README.md +34 -0
- package/dist/fancy-ui/fluid-cursor/index.d.ts +1 -0
- package/dist/fancy-ui/fluid-cursor/index.js +1 -0
- package/dist/fancy-ui/focus/Focus.svelte +177 -0
- package/dist/fancy-ui/focus/Focus.svelte.d.ts +12 -0
- package/dist/fancy-ui/focus/Focus.test.d.ts +1 -0
- package/dist/fancy-ui/focus/Focus.test.js +48 -0
- package/dist/fancy-ui/focus/README.md +21 -0
- package/dist/fancy-ui/focus/index.d.ts +1 -0
- package/dist/fancy-ui/focus/index.js +1 -0
- package/dist/fancy-ui/glare-card/GlareCard.svelte +133 -0
- package/dist/fancy-ui/glare-card/GlareCard.svelte.d.ts +8 -0
- package/dist/fancy-ui/glare-card/GlareCard.test.d.ts +1 -0
- package/dist/fancy-ui/glare-card/GlareCard.test.js +40 -0
- package/dist/fancy-ui/glare-card/README.md +24 -0
- package/dist/fancy-ui/glare-card/index.d.ts +1 -0
- package/dist/fancy-ui/glare-card/index.js +1 -0
- package/dist/fancy-ui/glow-border/GlowBorder.svelte +67 -0
- package/dist/fancy-ui/glow-border/GlowBorder.svelte.d.ts +10 -0
- package/dist/fancy-ui/glow-border/GlowBorder.test.d.ts +1 -0
- package/dist/fancy-ui/glow-border/GlowBorder.test.js +57 -0
- package/dist/fancy-ui/glow-border/README.md +54 -0
- package/dist/fancy-ui/glow-border/index.d.ts +1 -0
- package/dist/fancy-ui/glow-border/index.js +1 -0
- package/dist/fancy-ui/glowing-effect/GlowingEffect.svelte +182 -0
- package/dist/fancy-ui/glowing-effect/GlowingEffect.svelte.d.ts +15 -0
- package/dist/fancy-ui/glowing-effect/GlowingEffect.test.d.ts +1 -0
- package/dist/fancy-ui/glowing-effect/GlowingEffect.test.js +68 -0
- package/dist/fancy-ui/glowing-effect/README.md +29 -0
- package/dist/fancy-ui/glowing-effect/index.d.ts +1 -0
- package/dist/fancy-ui/glowing-effect/index.js +1 -0
- package/dist/fancy-ui/gradient-button/GradientButton.svelte +103 -0
- package/dist/fancy-ui/gradient-button/GradientButton.svelte.d.ts +24 -0
- package/dist/fancy-ui/gradient-button/GradientButton.test.d.ts +1 -0
- package/dist/fancy-ui/gradient-button/GradientButton.test.js +65 -0
- package/dist/fancy-ui/gradient-button/README.md +10 -0
- package/dist/fancy-ui/gradient-button/index.d.ts +2 -0
- package/dist/fancy-ui/gradient-button/index.js +2 -0
- package/dist/fancy-ui/hyper-text/HyperText.svelte +112 -0
- package/dist/fancy-ui/hyper-text/HyperText.svelte.d.ts +20 -0
- package/dist/fancy-ui/hyper-text/HyperText.test.d.ts +1 -0
- package/dist/fancy-ui/hyper-text/HyperText.test.js +39 -0
- package/dist/fancy-ui/hyper-text/README.md +19 -0
- package/dist/fancy-ui/hyper-text/index.d.ts +2 -0
- package/dist/fancy-ui/hyper-text/index.js +2 -0
- package/dist/fancy-ui/image-trail-cursor/ImageTrailCursor.svelte +89 -0
- package/dist/fancy-ui/image-trail-cursor/ImageTrailCursor.svelte.d.ts +9 -0
- package/dist/fancy-ui/image-trail-cursor/ImageTrailCursor.test.d.ts +1 -0
- package/dist/fancy-ui/image-trail-cursor/ImageTrailCursor.test.js +60 -0
- package/dist/fancy-ui/image-trail-cursor/README.md +36 -0
- package/dist/fancy-ui/image-trail-cursor/index.d.ts +3 -0
- package/dist/fancy-ui/image-trail-cursor/index.js +1 -0
- package/dist/fancy-ui/image-trail-cursor/trail-variants.d.ts +107 -0
- package/dist/fancy-ui/image-trail-cursor/trail-variants.js +703 -0
- package/dist/fancy-ui/index.d.ts +52 -0
- package/dist/fancy-ui/index.js +64 -0
- package/dist/fancy-ui/interactive-grid-pattern/InteractiveGridPattern.svelte +71 -0
- package/dist/fancy-ui/interactive-grid-pattern/InteractiveGridPattern.svelte.d.ts +15 -0
- package/dist/fancy-ui/interactive-grid-pattern/InteractiveGridPattern.test.d.ts +1 -0
- package/dist/fancy-ui/interactive-grid-pattern/InteractiveGridPattern.test.js +47 -0
- package/dist/fancy-ui/interactive-grid-pattern/README.md +30 -0
- package/dist/fancy-ui/interactive-grid-pattern/index.d.ts +2 -0
- package/dist/fancy-ui/interactive-grid-pattern/index.js +2 -0
- package/dist/fancy-ui/interactive-hover-button/InteractiveHoverButton.svelte +75 -0
- package/dist/fancy-ui/interactive-hover-button/InteractiveHoverButton.svelte.d.ts +14 -0
- package/dist/fancy-ui/interactive-hover-button/InteractiveHoverButton.test.d.ts +1 -0
- package/dist/fancy-ui/interactive-hover-button/InteractiveHoverButton.test.js +64 -0
- package/dist/fancy-ui/interactive-hover-button/README.md +28 -0
- package/dist/fancy-ui/interactive-hover-button/index.d.ts +2 -0
- package/dist/fancy-ui/interactive-hover-button/index.js +2 -0
- package/dist/fancy-ui/letter-pullup/LetterPullup.svelte +58 -0
- package/dist/fancy-ui/letter-pullup/LetterPullup.svelte.d.ts +17 -0
- package/dist/fancy-ui/letter-pullup/LetterPullup.test.d.ts +1 -0
- package/dist/fancy-ui/letter-pullup/LetterPullup.test.js +49 -0
- package/dist/fancy-ui/letter-pullup/README.md +18 -0
- package/dist/fancy-ui/letter-pullup/index.d.ts +2 -0
- package/dist/fancy-ui/letter-pullup/index.js +2 -0
- package/dist/fancy-ui/line-hover-link/LineHoverLink.svelte +450 -0
- package/dist/fancy-ui/line-hover-link/LineHoverLink.svelte.d.ts +35 -0
- package/dist/fancy-ui/line-hover-link/LineHoverLink.test.d.ts +1 -0
- package/dist/fancy-ui/line-hover-link/LineHoverLink.test.js +55 -0
- package/dist/fancy-ui/line-hover-link/index.d.ts +2 -0
- package/dist/fancy-ui/line-hover-link/index.js +1 -0
- package/dist/fancy-ui/line-shadow-text/LineShadowText.svelte +63 -0
- package/dist/fancy-ui/line-shadow-text/LineShadowText.svelte.d.ts +9 -0
- package/dist/fancy-ui/line-shadow-text/LineShadowText.test.d.ts +1 -0
- package/dist/fancy-ui/line-shadow-text/LineShadowText.test.js +59 -0
- package/dist/fancy-ui/line-shadow-text/README.md +12 -0
- package/dist/fancy-ui/line-shadow-text/index.d.ts +2 -0
- package/dist/fancy-ui/line-shadow-text/index.js +1 -0
- package/dist/fancy-ui/liquid-glass/LiquidGlass.svelte +204 -0
- package/dist/fancy-ui/liquid-glass/LiquidGlass.svelte.d.ts +23 -0
- package/dist/fancy-ui/liquid-glass/LiquidGlass.test.d.ts +1 -0
- package/dist/fancy-ui/liquid-glass/LiquidGlass.test.js +48 -0
- package/dist/fancy-ui/liquid-glass/README.md +34 -0
- package/dist/fancy-ui/liquid-glass/index.d.ts +1 -0
- package/dist/fancy-ui/liquid-glass/index.js +1 -0
- package/dist/fancy-ui/logo-cloud/AnimatedLogoCloud.svelte +61 -0
- package/dist/fancy-ui/logo-cloud/AnimatedLogoCloud.svelte.d.ts +15 -0
- package/dist/fancy-ui/logo-cloud/AnimatedLogoCloud.test.d.ts +1 -0
- package/dist/fancy-ui/logo-cloud/AnimatedLogoCloud.test.js +59 -0
- package/dist/fancy-ui/logo-cloud/IconLogoCloud.svelte +31 -0
- package/dist/fancy-ui/logo-cloud/IconLogoCloud.svelte.d.ts +11 -0
- package/dist/fancy-ui/logo-cloud/README.md +41 -0
- package/dist/fancy-ui/logo-cloud/StaticLogoCloud.svelte +31 -0
- package/dist/fancy-ui/logo-cloud/StaticLogoCloud.svelte.d.ts +11 -0
- package/dist/fancy-ui/logo-cloud/index.d.ts +4 -0
- package/dist/fancy-ui/logo-cloud/index.js +4 -0
- package/dist/fancy-ui/marquee/Marquee.svelte +70 -0
- package/dist/fancy-ui/marquee/Marquee.svelte.d.ts +11 -0
- package/dist/fancy-ui/marquee/Marquee.test.d.ts +1 -0
- package/dist/fancy-ui/marquee/Marquee.test.js +46 -0
- package/dist/fancy-ui/marquee/ReviewCard.svelte +25 -0
- package/dist/fancy-ui/marquee/ReviewCard.svelte.d.ts +9 -0
- package/dist/fancy-ui/marquee/index.d.ts +2 -0
- package/dist/fancy-ui/marquee/index.js +2 -0
- package/dist/fancy-ui/meteors/Meteors.svelte +59 -0
- package/dist/fancy-ui/meteors/Meteors.svelte.d.ts +15 -0
- package/dist/fancy-ui/meteors/Meteors.test.d.ts +1 -0
- package/dist/fancy-ui/meteors/Meteors.test.js +48 -0
- package/dist/fancy-ui/meteors/README.md +18 -0
- package/dist/fancy-ui/meteors/index.d.ts +2 -0
- package/dist/fancy-ui/meteors/index.js +2 -0
- package/dist/fancy-ui/neon-border/NeonBorder.svelte +135 -0
- package/dist/fancy-ui/neon-border/NeonBorder.svelte.d.ts +24 -0
- package/dist/fancy-ui/neon-border/NeonBorder.test.d.ts +1 -0
- package/dist/fancy-ui/neon-border/NeonBorder.test.js +80 -0
- package/dist/fancy-ui/neon-border/README.md +27 -0
- package/dist/fancy-ui/neon-border/index.d.ts +2 -0
- package/dist/fancy-ui/neon-border/index.js +2 -0
- package/dist/fancy-ui/number-ticker/NumberTicker.svelte +126 -0
- package/dist/fancy-ui/number-ticker/NumberTicker.svelte.d.ts +24 -0
- package/dist/fancy-ui/number-ticker/NumberTicker.test.d.ts +1 -0
- package/dist/fancy-ui/number-ticker/NumberTicker.test.js +64 -0
- package/dist/fancy-ui/number-ticker/README.md +22 -0
- package/dist/fancy-ui/number-ticker/index.d.ts +2 -0
- package/dist/fancy-ui/number-ticker/index.js +2 -0
- package/dist/fancy-ui/rainbow-button/RainbowButton.svelte +96 -0
- package/dist/fancy-ui/rainbow-button/RainbowButton.svelte.d.ts +18 -0
- package/dist/fancy-ui/rainbow-button/RainbowButton.test.d.ts +1 -0
- package/dist/fancy-ui/rainbow-button/RainbowButton.test.js +51 -0
- package/dist/fancy-ui/rainbow-button/index.d.ts +2 -0
- package/dist/fancy-ui/rainbow-button/index.js +2 -0
- package/dist/fancy-ui/registry.d.ts +72 -0
- package/dist/fancy-ui/registry.js +643 -0
- package/dist/fancy-ui/ripple/README.md +16 -0
- package/dist/fancy-ui/ripple/Ripple.svelte +64 -0
- package/dist/fancy-ui/ripple/Ripple.svelte.d.ts +13 -0
- package/dist/fancy-ui/ripple/Ripple.test.d.ts +1 -0
- package/dist/fancy-ui/ripple/Ripple.test.js +81 -0
- package/dist/fancy-ui/ripple/index.d.ts +1 -0
- package/dist/fancy-ui/ripple/index.js +1 -0
- package/dist/fancy-ui/ripple-button/RippleButton.svelte +111 -0
- package/dist/fancy-ui/ripple-button/RippleButton.svelte.d.ts +15 -0
- package/dist/fancy-ui/ripple-button/RippleButton.test.d.ts +1 -0
- package/dist/fancy-ui/ripple-button/RippleButton.test.js +44 -0
- package/dist/fancy-ui/ripple-button/index.d.ts +2 -0
- package/dist/fancy-ui/ripple-button/index.js +2 -0
- package/dist/fancy-ui/shimmer-button/README.md +10 -0
- package/dist/fancy-ui/shimmer-button/ShimmerButton.svelte +115 -0
- package/dist/fancy-ui/shimmer-button/ShimmerButton.svelte.d.ts +22 -0
- package/dist/fancy-ui/shimmer-button/ShimmerButton.test.d.ts +1 -0
- package/dist/fancy-ui/shimmer-button/ShimmerButton.test.js +69 -0
- package/dist/fancy-ui/shimmer-button/index.d.ts +2 -0
- package/dist/fancy-ui/shimmer-button/index.js +2 -0
- package/dist/fancy-ui/smooth-cursor/README.md +23 -0
- package/dist/fancy-ui/smooth-cursor/SmoothCursor.svelte +224 -0
- package/dist/fancy-ui/smooth-cursor/SmoothCursor.svelte.d.ts +20 -0
- package/dist/fancy-ui/smooth-cursor/index.d.ts +2 -0
- package/dist/fancy-ui/smooth-cursor/index.js +1 -0
- package/dist/fancy-ui/sparkles/README.md +15 -0
- package/dist/fancy-ui/sparkles/Sparkles.svelte +123 -0
- package/dist/fancy-ui/sparkles/Sparkles.svelte.d.ts +12 -0
- package/dist/fancy-ui/sparkles/Sparkles.test.d.ts +1 -0
- package/dist/fancy-ui/sparkles/Sparkles.test.js +66 -0
- package/dist/fancy-ui/sparkles/index.d.ts +1 -0
- package/dist/fancy-ui/sparkles/index.js +1 -0
- package/dist/fancy-ui/sparkles-text/README.md +19 -0
- package/dist/fancy-ui/sparkles-text/SparklesText.svelte +112 -0
- package/dist/fancy-ui/sparkles-text/SparklesText.svelte.d.ts +22 -0
- package/dist/fancy-ui/sparkles-text/SparklesText.test.d.ts +1 -0
- package/dist/fancy-ui/sparkles-text/SparklesText.test.js +54 -0
- package/dist/fancy-ui/sparkles-text/index.d.ts +2 -0
- package/dist/fancy-ui/sparkles-text/index.js +2 -0
- package/dist/fancy-ui/tailwind.css +3 -0
- package/dist/fancy-ui/text-generate-effect/README.md +14 -0
- package/dist/fancy-ui/text-generate-effect/TextGenerateEffect.svelte +66 -0
- package/dist/fancy-ui/text-generate-effect/TextGenerateEffect.svelte.d.ts +11 -0
- package/dist/fancy-ui/text-generate-effect/TextGenerateEffect.test.d.ts +1 -0
- package/dist/fancy-ui/text-generate-effect/TextGenerateEffect.test.js +73 -0
- package/dist/fancy-ui/text-generate-effect/index.d.ts +2 -0
- package/dist/fancy-ui/text-generate-effect/index.js +1 -0
- package/dist/fancy-ui/text-reveal-card/README.md +36 -0
- package/dist/fancy-ui/text-reveal-card/TextRevealCard.svelte +112 -0
- package/dist/fancy-ui/text-reveal-card/TextRevealCard.svelte.d.ts +12 -0
- package/dist/fancy-ui/text-reveal-card/TextRevealCard.test.d.ts +1 -0
- package/dist/fancy-ui/text-reveal-card/TextRevealCard.test.js +34 -0
- package/dist/fancy-ui/text-reveal-card/TextRevealStars.svelte +76 -0
- package/dist/fancy-ui/text-reveal-card/TextRevealStars.svelte.d.ts +7 -0
- package/dist/fancy-ui/text-reveal-card/index.d.ts +2 -0
- package/dist/fancy-ui/text-reveal-card/index.js +2 -0
- package/dist/fancy-ui/timeline/README.md +56 -0
- package/dist/fancy-ui/timeline/Timeline.svelte +141 -0
- package/dist/fancy-ui/timeline/Timeline.svelte.d.ts +20 -0
- package/dist/fancy-ui/timeline/Timeline.test.d.ts +1 -0
- package/dist/fancy-ui/timeline/Timeline.test.js +63 -0
- package/dist/fancy-ui/timeline/index.d.ts +2 -0
- package/dist/fancy-ui/timeline/index.js +2 -0
- package/dist/fancy-ui/tracing-beam/README.md +24 -0
- package/dist/fancy-ui/tracing-beam/TracingBeam.svelte +156 -0
- package/dist/fancy-ui/tracing-beam/TracingBeam.svelte.d.ts +8 -0
- package/dist/fancy-ui/tracing-beam/TracingBeam.test.d.ts +1 -0
- package/dist/fancy-ui/tracing-beam/TracingBeam.test.js +61 -0
- package/dist/fancy-ui/tracing-beam/index.d.ts +1 -0
- package/dist/fancy-ui/tracing-beam/index.js +1 -0
- package/dist/types.d.ts +87 -0
- package/dist/types.js +6 -0
- package/dist/utils.d.ts +12 -0
- package/dist/utils.js +5 -0
- package/package.json +105 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TEMPLATE: types.ts
|
|
3
|
+
*
|
|
4
|
+
* Component-specific type definitions.
|
|
5
|
+
*
|
|
6
|
+
* Instructions:
|
|
7
|
+
* 1. Rename types to match your component (e.g., ComponentNameItem, ComponentNameConfig)
|
|
8
|
+
* 2. Export types that consumers might need
|
|
9
|
+
* 3. Keep internal types unexported
|
|
10
|
+
* 4. Delete this comment block and unused examples when done
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Example: Configuration object for component behavior
|
|
14
|
+
* Rename to [ComponentName]Config
|
|
15
|
+
*/
|
|
16
|
+
export interface ComponentConfig {
|
|
17
|
+
/** Enable feature X */
|
|
18
|
+
enabled?: boolean;
|
|
19
|
+
/** Configuration value */
|
|
20
|
+
value?: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Example: Item type for list/collection components
|
|
24
|
+
* Rename to [ComponentName]Item
|
|
25
|
+
*/
|
|
26
|
+
export interface ComponentItem {
|
|
27
|
+
/** Unique identifier */
|
|
28
|
+
id: string;
|
|
29
|
+
/** Display label */
|
|
30
|
+
label: string;
|
|
31
|
+
/** Optional icon name */
|
|
32
|
+
icon?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Example: State type for components with complex internal state
|
|
36
|
+
* Rename to [ComponentName]State
|
|
37
|
+
*/
|
|
38
|
+
export interface ComponentState {
|
|
39
|
+
/** Current index */
|
|
40
|
+
currentIndex: number;
|
|
41
|
+
/** Whether component is active */
|
|
42
|
+
isActive: boolean;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Example: Event detail for custom component events
|
|
46
|
+
* Rename to [ComponentName]ChangeEvent or similar
|
|
47
|
+
*/
|
|
48
|
+
export interface ComponentChangeEvent {
|
|
49
|
+
/** Previous value */
|
|
50
|
+
previousValue: unknown;
|
|
51
|
+
/** New value */
|
|
52
|
+
newValue: unknown;
|
|
53
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TEMPLATE: types.ts
|
|
3
|
+
*
|
|
4
|
+
* Component-specific type definitions.
|
|
5
|
+
*
|
|
6
|
+
* Instructions:
|
|
7
|
+
* 1. Rename types to match your component (e.g., ComponentNameItem, ComponentNameConfig)
|
|
8
|
+
* 2. Export types that consumers might need
|
|
9
|
+
* 3. Keep internal types unexported
|
|
10
|
+
* 4. Delete this comment block and unused examples when done
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onMount } from "svelte";
|
|
3
|
+
import { cn } from "../../utils";
|
|
4
|
+
import type { AnimatedBeamProps } from "./types";
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
class: className = "",
|
|
8
|
+
containerRef,
|
|
9
|
+
fromRef,
|
|
10
|
+
toRef,
|
|
11
|
+
curvature = 0,
|
|
12
|
+
reverse = false,
|
|
13
|
+
pathColor = "gray",
|
|
14
|
+
pathWidth = 2,
|
|
15
|
+
pathOpacity = 0.2,
|
|
16
|
+
gradientStartColor = "#FFAA40",
|
|
17
|
+
gradientStopColor = "#9C40FF",
|
|
18
|
+
delay = 0,
|
|
19
|
+
duration = Math.random() * 3 + 4,
|
|
20
|
+
startXOffset = 0,
|
|
21
|
+
startYOffset = 0,
|
|
22
|
+
endXOffset = 0,
|
|
23
|
+
endYOffset = 0,
|
|
24
|
+
}: AnimatedBeamProps = $props();
|
|
25
|
+
|
|
26
|
+
// Generate unique ID for gradient
|
|
27
|
+
const id = "beam-" + Math.random().toString(36).substring(2, 10);
|
|
28
|
+
|
|
29
|
+
// Reactive state
|
|
30
|
+
let isVertical = $state(false);
|
|
31
|
+
let isRightToLeft = $state(false);
|
|
32
|
+
let isBottomToTop = $state(false);
|
|
33
|
+
let pathD = $state("");
|
|
34
|
+
let svgDimensions = $state<{ width: number; height: number }>({
|
|
35
|
+
width: 0,
|
|
36
|
+
height: 0,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Derived values for animation
|
|
40
|
+
let x1 = $derived((reverse ? !isRightToLeft : isRightToLeft) ? "90%; -10%;" : "10%; 110%;");
|
|
41
|
+
|
|
42
|
+
let x2 = $derived((reverse ? !isRightToLeft : isRightToLeft) ? "100%; 0%;" : "0%; 100%;");
|
|
43
|
+
|
|
44
|
+
let y1 = $derived((reverse ? !isBottomToTop : isBottomToTop) ? "90%; -10%;" : "10%; 110%;");
|
|
45
|
+
|
|
46
|
+
let y2 = $derived((reverse ? !isBottomToTop : isBottomToTop) ? "100%; 0%;" : "0%; 100%;");
|
|
47
|
+
|
|
48
|
+
let resizeObserver: ResizeObserver | undefined = undefined;
|
|
49
|
+
|
|
50
|
+
// Function to update the path based on the positions of the elements
|
|
51
|
+
function updatePath() {
|
|
52
|
+
if (containerRef && fromRef && toRef) {
|
|
53
|
+
const containerRect = containerRef.getBoundingClientRect();
|
|
54
|
+
const rectA = fromRef.getBoundingClientRect();
|
|
55
|
+
const rectB = toRef.getBoundingClientRect();
|
|
56
|
+
|
|
57
|
+
const svgWidth = containerRect.width;
|
|
58
|
+
const svgHeight = containerRect.height;
|
|
59
|
+
svgDimensions = { width: svgWidth, height: svgHeight };
|
|
60
|
+
|
|
61
|
+
const startX = rectA.left - containerRect.left + rectA.width / 2 + startXOffset;
|
|
62
|
+
const startY = rectA.top - containerRect.top + rectA.height / 2 + startYOffset;
|
|
63
|
+
const endX = rectB.left - containerRect.left + rectB.width / 2 + endXOffset;
|
|
64
|
+
const endY = rectB.top - containerRect.top + rectB.height / 2 + endYOffset;
|
|
65
|
+
|
|
66
|
+
// Check if the light beam is in a vertical direction
|
|
67
|
+
isVertical = Math.abs(endY - startY) > Math.abs(endX - startX);
|
|
68
|
+
|
|
69
|
+
// Determine the animation direction
|
|
70
|
+
isRightToLeft = endX < startX;
|
|
71
|
+
isBottomToTop = endY < startY;
|
|
72
|
+
|
|
73
|
+
const controlY = startY - curvature;
|
|
74
|
+
const d = `M ${startX},${startY} Q ${(startX + endX) / 2},${controlY} ${endX},${endY}`;
|
|
75
|
+
pathD = d;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Setup ResizeObserver on mount
|
|
80
|
+
onMount(() => {
|
|
81
|
+
if (containerRef) {
|
|
82
|
+
resizeObserver = new ResizeObserver(() => {
|
|
83
|
+
updatePath();
|
|
84
|
+
});
|
|
85
|
+
resizeObserver.observe(containerRef);
|
|
86
|
+
|
|
87
|
+
// Initial path calculation
|
|
88
|
+
updatePath();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return () => {
|
|
92
|
+
resizeObserver?.disconnect();
|
|
93
|
+
};
|
|
94
|
+
});
|
|
95
|
+
</script>
|
|
96
|
+
|
|
97
|
+
<svg
|
|
98
|
+
fill="none"
|
|
99
|
+
width={svgDimensions.width}
|
|
100
|
+
height={svgDimensions.height}
|
|
101
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
102
|
+
class={cn("pointer-events-none absolute top-0 left-0 transform-gpu stroke-2", className)}
|
|
103
|
+
viewBox="0 0 {svgDimensions.width} {svgDimensions.height}"
|
|
104
|
+
>
|
|
105
|
+
<path
|
|
106
|
+
d={pathD}
|
|
107
|
+
stroke={pathColor}
|
|
108
|
+
stroke-width={pathWidth}
|
|
109
|
+
stroke-opacity={pathOpacity}
|
|
110
|
+
stroke-linecap="round"
|
|
111
|
+
/>
|
|
112
|
+
<path
|
|
113
|
+
d={pathD}
|
|
114
|
+
stroke-width={pathWidth}
|
|
115
|
+
stroke="url(#{id})"
|
|
116
|
+
stroke-opacity="1"
|
|
117
|
+
stroke-linecap="round"
|
|
118
|
+
/>
|
|
119
|
+
<defs>
|
|
120
|
+
<linearGradient {id} gradientUnits="userSpaceOnUse" x1="0%" x2="0%" y1="0%" y2="0%">
|
|
121
|
+
<stop stop-color={gradientStartColor} stop-opacity="0" />
|
|
122
|
+
<stop stop-color={gradientStartColor} />
|
|
123
|
+
<stop offset="32.5%" stop-color={gradientStopColor} />
|
|
124
|
+
<stop offset="100%" stop-color={gradientStopColor} stop-opacity="0" />
|
|
125
|
+
{#if !isVertical}
|
|
126
|
+
<animate
|
|
127
|
+
attributeName="x1"
|
|
128
|
+
values={x1}
|
|
129
|
+
dur="{duration}s"
|
|
130
|
+
keyTimes="0; 1"
|
|
131
|
+
keySplines="0.16 1 0.3 1"
|
|
132
|
+
calcMode="spline"
|
|
133
|
+
repeatCount="indefinite"
|
|
134
|
+
/>
|
|
135
|
+
<animate
|
|
136
|
+
attributeName="x2"
|
|
137
|
+
values={x2}
|
|
138
|
+
dur="{duration}s"
|
|
139
|
+
keyTimes="0; 1"
|
|
140
|
+
keySplines="0.16 1 0.3 1"
|
|
141
|
+
calcMode="spline"
|
|
142
|
+
repeatCount="indefinite"
|
|
143
|
+
/>
|
|
144
|
+
{:else}
|
|
145
|
+
<animate
|
|
146
|
+
attributeName="y1"
|
|
147
|
+
values={y1}
|
|
148
|
+
dur="{duration}s"
|
|
149
|
+
keyTimes="0; 1"
|
|
150
|
+
keySplines="0.16 1 0.3 1"
|
|
151
|
+
calcMode="spline"
|
|
152
|
+
repeatCount="indefinite"
|
|
153
|
+
/>
|
|
154
|
+
<animate
|
|
155
|
+
attributeName="y2"
|
|
156
|
+
values={y2}
|
|
157
|
+
dur="{duration}s"
|
|
158
|
+
keyTimes="0; 1"
|
|
159
|
+
keySplines="0.16 1 0.3 1"
|
|
160
|
+
calcMode="spline"
|
|
161
|
+
repeatCount="indefinite"
|
|
162
|
+
/>
|
|
163
|
+
{/if}
|
|
164
|
+
</linearGradient>
|
|
165
|
+
</defs>
|
|
166
|
+
</svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { render, cleanup } from "@testing-library/svelte";
|
|
2
|
+
import { afterEach, describe, it, expect } from "vitest";
|
|
3
|
+
import AnimatedBeam from "./AnimatedBeam.svelte";
|
|
4
|
+
const makeProps = (extra = {}) => ({
|
|
5
|
+
containerRef: document.createElement("div"),
|
|
6
|
+
fromRef: document.createElement("div"),
|
|
7
|
+
toRef: document.createElement("div"),
|
|
8
|
+
...extra,
|
|
9
|
+
});
|
|
10
|
+
describe("AnimatedBeam", () => {
|
|
11
|
+
afterEach(cleanup);
|
|
12
|
+
it("renders an svg element", () => {
|
|
13
|
+
const { container } = render(AnimatedBeam, { props: makeProps() });
|
|
14
|
+
const svg = container.querySelector("svg");
|
|
15
|
+
expect(svg).toBeInTheDocument();
|
|
16
|
+
});
|
|
17
|
+
it("svg has pointer-events-none class", () => {
|
|
18
|
+
const { container } = render(AnimatedBeam, { props: makeProps() });
|
|
19
|
+
const svg = container.querySelector("svg");
|
|
20
|
+
expect(svg?.className.baseVal).toContain("pointer-events-none");
|
|
21
|
+
});
|
|
22
|
+
it("renders two path elements", () => {
|
|
23
|
+
const { container } = render(AnimatedBeam, { props: makeProps() });
|
|
24
|
+
const paths = container.querySelectorAll("path");
|
|
25
|
+
expect(paths.length).toBe(2);
|
|
26
|
+
});
|
|
27
|
+
it("renders a linearGradient in defs", () => {
|
|
28
|
+
const { container } = render(AnimatedBeam, { props: makeProps() });
|
|
29
|
+
const gradient = container.querySelector("linearGradient");
|
|
30
|
+
expect(gradient).toBeInTheDocument();
|
|
31
|
+
});
|
|
32
|
+
it("applies custom class names", () => {
|
|
33
|
+
const { container } = render(AnimatedBeam, { props: makeProps({ class: "my-beam" }) });
|
|
34
|
+
const svg = container.querySelector("svg");
|
|
35
|
+
expect(svg?.className.baseVal).toContain("my-beam");
|
|
36
|
+
});
|
|
37
|
+
it("preserves base classes when custom class is added", () => {
|
|
38
|
+
const { container } = render(AnimatedBeam, { props: makeProps({ class: "extra" }) });
|
|
39
|
+
const svg = container.querySelector("svg");
|
|
40
|
+
expect(svg?.className.baseVal).toContain("pointer-events-none");
|
|
41
|
+
expect(svg?.className.baseVal).toContain("absolute");
|
|
42
|
+
expect(svg?.className.baseVal).toContain("transform-gpu");
|
|
43
|
+
});
|
|
44
|
+
it('svg has fill="none" attribute', () => {
|
|
45
|
+
const { container } = render(AnimatedBeam, { props: makeProps() });
|
|
46
|
+
const svg = container.querySelector("svg");
|
|
47
|
+
expect(svg).toHaveAttribute("fill", "none");
|
|
48
|
+
});
|
|
49
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# AnimatedBeam
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Creates animated SVG beams that connect two elements with smooth gradients and customizable curves. Perfect for showing data flow, connections, or relationships between UI elements.
|
|
5
|
+
|
|
6
|
+
## Key Features
|
|
7
|
+
- Dynamic path calculation between elements
|
|
8
|
+
- Responsive to container resizing
|
|
9
|
+
- Customizable curvature for curved beams
|
|
10
|
+
- Animated gradient effect
|
|
11
|
+
- Configurable colors, opacity, and timing
|
|
12
|
+
- Reversible animation direction
|
|
13
|
+
- Position offsets for fine-tuning
|
|
14
|
+
|
|
15
|
+
## Implementation Notes
|
|
16
|
+
|
|
17
|
+
### Vue → Svelte Conversions
|
|
18
|
+
- `ref()` → `$state()`
|
|
19
|
+
- `computed()` → `$derived()`
|
|
20
|
+
- `watchEffect()` → `$effect()` (via `onMount`)
|
|
21
|
+
- Template refs → `bind:this`
|
|
22
|
+
- Props handling with destructuring defaults
|
|
23
|
+
|
|
24
|
+
### Key Differences
|
|
25
|
+
1. **Element References**: Svelte uses `bind:this` instead of Vue's `ref` template attribute
|
|
26
|
+
2. **Lifecycle**: Setup logic moved to `onMount` with cleanup return
|
|
27
|
+
3. **Derived Values**: Functions returning derived values (x1, x2, y1, y2) instead of computed refs
|
|
28
|
+
4. **Conditional Rendering**: Used `{#if}` blocks to ensure refs are defined before rendering beams
|
|
29
|
+
|
|
30
|
+
### Implementation Details
|
|
31
|
+
- ResizeObserver for responsive path updates
|
|
32
|
+
- SVG path calculation using quadratic Bezier curves (Q command)
|
|
33
|
+
- Direction detection for vertical/horizontal beams
|
|
34
|
+
- Unique gradient IDs to prevent conflicts with multiple instances
|
|
35
|
+
|
|
36
|
+
## Demo
|
|
37
|
+
See `/demo/animated-beam` for usage examples.
|
|
38
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as AnimatedBeam } from "./AnimatedBeam.svelte";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface AnimatedBeamProps {
|
|
2
|
+
class?: string;
|
|
3
|
+
containerRef: HTMLElement;
|
|
4
|
+
fromRef: HTMLElement;
|
|
5
|
+
toRef: HTMLElement;
|
|
6
|
+
curvature?: number;
|
|
7
|
+
reverse?: boolean;
|
|
8
|
+
pathColor?: string;
|
|
9
|
+
pathWidth?: number;
|
|
10
|
+
pathOpacity?: number;
|
|
11
|
+
gradientStartColor?: string;
|
|
12
|
+
gradientStopColor?: string;
|
|
13
|
+
delay?: number;
|
|
14
|
+
duration?: number;
|
|
15
|
+
startXOffset?: number;
|
|
16
|
+
startYOffset?: number;
|
|
17
|
+
endXOffset?: number;
|
|
18
|
+
endYOffset?: number;
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/**
|
|
3
|
+
* AnimatedTestimonials - Animated testimonial carousel
|
|
4
|
+
*
|
|
5
|
+
* Cycles through testimonials with smooth slide animations.
|
|
6
|
+
* Supports manual navigation and optional autoplay.
|
|
7
|
+
*/
|
|
8
|
+
export interface Testimonial {
|
|
9
|
+
/** The testimonial quote */
|
|
10
|
+
quote: string;
|
|
11
|
+
/** Author's full name */
|
|
12
|
+
name: string;
|
|
13
|
+
/** Author's title or role */
|
|
14
|
+
designation: string;
|
|
15
|
+
/** URL to author's avatar image */
|
|
16
|
+
src: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface AnimatedTestimonialsProps {
|
|
20
|
+
/** Array of testimonials to display */
|
|
21
|
+
testimonials: Testimonial[];
|
|
22
|
+
/** Auto-advance testimonials */
|
|
23
|
+
autoplay?: boolean;
|
|
24
|
+
/** Interval between auto-advances (ms) */
|
|
25
|
+
interval?: number;
|
|
26
|
+
/** Additional CSS classes */
|
|
27
|
+
class?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Duration must match the CSS transition duration below */
|
|
31
|
+
const TRANSITION_DURATION = 300;
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<script lang="ts">
|
|
35
|
+
import { cn } from "../../utils.js";
|
|
36
|
+
|
|
37
|
+
let {
|
|
38
|
+
testimonials,
|
|
39
|
+
autoplay = false,
|
|
40
|
+
interval = 5000,
|
|
41
|
+
class: className,
|
|
42
|
+
}: AnimatedTestimonialsProps = $props();
|
|
43
|
+
|
|
44
|
+
let activeIndex = $state(0);
|
|
45
|
+
let direction = $state<"next" | "prev">("next");
|
|
46
|
+
let isAnimating = $state(false);
|
|
47
|
+
let isHovered = $state(false);
|
|
48
|
+
|
|
49
|
+
let navigateTimer: ReturnType<typeof setTimeout> | null = null;
|
|
50
|
+
|
|
51
|
+
function navigate(dir: "next" | "prev") {
|
|
52
|
+
if (isAnimating || testimonials.length === 0) return;
|
|
53
|
+
direction = dir;
|
|
54
|
+
isAnimating = true;
|
|
55
|
+
navigateTimer = setTimeout(() => {
|
|
56
|
+
activeIndex =
|
|
57
|
+
dir === "next"
|
|
58
|
+
? (activeIndex + 1) % testimonials.length
|
|
59
|
+
: (activeIndex - 1 + testimonials.length) % testimonials.length;
|
|
60
|
+
isAnimating = false;
|
|
61
|
+
navigateTimer = null;
|
|
62
|
+
}, TRANSITION_DURATION);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Reactive autoplay: restarts whenever autoplay, interval, or hover state changes
|
|
66
|
+
$effect(() => {
|
|
67
|
+
if (!autoplay || isHovered || testimonials.length === 0) return;
|
|
68
|
+
|
|
69
|
+
const timer = setInterval(() => navigate("next"), interval);
|
|
70
|
+
return () => clearInterval(timer);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Cleanup navigate timeout on destroy
|
|
74
|
+
$effect(() => {
|
|
75
|
+
return () => {
|
|
76
|
+
if (navigateTimer) clearTimeout(navigateTimer);
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
let activeTestimonial = $derived(testimonials.length > 0 ? testimonials[activeIndex] : null);
|
|
81
|
+
</script>
|
|
82
|
+
|
|
83
|
+
<div
|
|
84
|
+
class={cn(
|
|
85
|
+
"relative mx-auto max-w-sm px-4 py-20 font-sans antialiased md:max-w-4xl md:px-8 lg:px-12",
|
|
86
|
+
className
|
|
87
|
+
)}
|
|
88
|
+
onmouseenter={() => (isHovered = true)}
|
|
89
|
+
onmouseleave={() => (isHovered = false)}
|
|
90
|
+
role="region"
|
|
91
|
+
aria-label="Testimonials"
|
|
92
|
+
>
|
|
93
|
+
{#if testimonials.length === 0}
|
|
94
|
+
<p class="text-muted-foreground text-center">No testimonials available.</p>
|
|
95
|
+
{:else}
|
|
96
|
+
<div class="relative grid grid-cols-1 gap-20 md:grid-cols-2">
|
|
97
|
+
<!-- Image column -->
|
|
98
|
+
<div class="relative h-80 w-full">
|
|
99
|
+
{#each testimonials as testimonial, index}
|
|
100
|
+
<div
|
|
101
|
+
class={cn(
|
|
102
|
+
"absolute inset-0 h-full w-full origin-bottom rounded-3xl transition-all ease-in-out",
|
|
103
|
+
index === activeIndex
|
|
104
|
+
? "z-20 translate-y-0 scale-100 rotate-0 opacity-100"
|
|
105
|
+
: "z-10 translate-y-4 scale-95 opacity-0",
|
|
106
|
+
index !== activeIndex && direction === "next"
|
|
107
|
+
? "-translate-y-4"
|
|
108
|
+
: index !== activeIndex
|
|
109
|
+
? "translate-y-4"
|
|
110
|
+
: ""
|
|
111
|
+
)}
|
|
112
|
+
style="transition-duration: {TRANSITION_DURATION}ms"
|
|
113
|
+
>
|
|
114
|
+
<img
|
|
115
|
+
src={testimonial.src}
|
|
116
|
+
alt={testimonial.name}
|
|
117
|
+
class="h-full w-full rounded-3xl object-cover object-center"
|
|
118
|
+
draggable="false"
|
|
119
|
+
/>
|
|
120
|
+
</div>
|
|
121
|
+
{/each}
|
|
122
|
+
</div>
|
|
123
|
+
|
|
124
|
+
<!-- Content column -->
|
|
125
|
+
<div class="flex flex-col justify-between py-4">
|
|
126
|
+
<div
|
|
127
|
+
class={cn(
|
|
128
|
+
"ease-in-out",
|
|
129
|
+
isAnimating
|
|
130
|
+
? direction === "next"
|
|
131
|
+
? "translate-y-4 opacity-0"
|
|
132
|
+
: "-translate-y-4 opacity-0"
|
|
133
|
+
: "translate-y-0 opacity-100"
|
|
134
|
+
)}
|
|
135
|
+
style="transition: opacity {TRANSITION_DURATION}ms, transform {TRANSITION_DURATION}ms"
|
|
136
|
+
>
|
|
137
|
+
<p class="text-lg text-gray-500 dark:text-neutral-300" aria-live="polite">
|
|
138
|
+
{activeTestimonial?.quote}
|
|
139
|
+
</p>
|
|
140
|
+
<div class="mt-8">
|
|
141
|
+
<p class="text-base font-bold text-gray-900 dark:text-white">
|
|
142
|
+
{activeTestimonial?.name}
|
|
143
|
+
</p>
|
|
144
|
+
<p class="text-sm text-gray-500 dark:text-neutral-400">
|
|
145
|
+
{activeTestimonial?.designation}
|
|
146
|
+
</p>
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
|
|
150
|
+
<!-- Navigation -->
|
|
151
|
+
<div class="mt-8 flex gap-4">
|
|
152
|
+
<button
|
|
153
|
+
onclick={() => navigate("prev")}
|
|
154
|
+
class="group/button flex h-10 w-10 items-center justify-center rounded-full bg-gray-100 transition-colors hover:bg-gray-200 dark:bg-neutral-800 dark:hover:bg-neutral-700"
|
|
155
|
+
aria-label="Previous testimonial"
|
|
156
|
+
>
|
|
157
|
+
<svg
|
|
158
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
159
|
+
width="20"
|
|
160
|
+
height="20"
|
|
161
|
+
viewBox="0 0 24 24"
|
|
162
|
+
fill="none"
|
|
163
|
+
stroke="currentColor"
|
|
164
|
+
stroke-width="2"
|
|
165
|
+
stroke-linecap="round"
|
|
166
|
+
stroke-linejoin="round"
|
|
167
|
+
class="text-gray-800 transition-transform group-hover/button:-translate-x-0.5 dark:text-neutral-200"
|
|
168
|
+
>
|
|
169
|
+
<path d="m15 18-6-6 6-6" />
|
|
170
|
+
</svg>
|
|
171
|
+
</button>
|
|
172
|
+
<button
|
|
173
|
+
onclick={() => navigate("next")}
|
|
174
|
+
class="group/button flex h-10 w-10 items-center justify-center rounded-full bg-gray-100 transition-colors hover:bg-gray-200 dark:bg-neutral-800 dark:hover:bg-neutral-700"
|
|
175
|
+
aria-label="Next testimonial"
|
|
176
|
+
>
|
|
177
|
+
<svg
|
|
178
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
179
|
+
width="20"
|
|
180
|
+
height="20"
|
|
181
|
+
viewBox="0 0 24 24"
|
|
182
|
+
fill="none"
|
|
183
|
+
stroke="currentColor"
|
|
184
|
+
stroke-width="2"
|
|
185
|
+
stroke-linecap="round"
|
|
186
|
+
stroke-linejoin="round"
|
|
187
|
+
class="text-gray-800 transition-transform group-hover/button:translate-x-0.5 dark:text-neutral-200"
|
|
188
|
+
>
|
|
189
|
+
<path d="m9 18 6-6-6-6" />
|
|
190
|
+
</svg>
|
|
191
|
+
</button>
|
|
192
|
+
</div>
|
|
193
|
+
</div>
|
|
194
|
+
</div>
|
|
195
|
+
{/if}
|
|
196
|
+
</div>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AnimatedTestimonials - Animated testimonial carousel
|
|
3
|
+
*
|
|
4
|
+
* Cycles through testimonials with smooth slide animations.
|
|
5
|
+
* Supports manual navigation and optional autoplay.
|
|
6
|
+
*/
|
|
7
|
+
export interface Testimonial {
|
|
8
|
+
/** The testimonial quote */
|
|
9
|
+
quote: string;
|
|
10
|
+
/** Author's full name */
|
|
11
|
+
name: string;
|
|
12
|
+
/** Author's title or role */
|
|
13
|
+
designation: string;
|
|
14
|
+
/** URL to author's avatar image */
|
|
15
|
+
src: string;
|
|
16
|
+
}
|
|
17
|
+
export interface AnimatedTestimonialsProps {
|
|
18
|
+
/** Array of testimonials to display */
|
|
19
|
+
testimonials: Testimonial[];
|
|
20
|
+
/** Auto-advance testimonials */
|
|
21
|
+
autoplay?: boolean;
|
|
22
|
+
/** Interval between auto-advances (ms) */
|
|
23
|
+
interval?: number;
|
|
24
|
+
/** Additional CSS classes */
|
|
25
|
+
class?: string;
|
|
26
|
+
}
|
|
27
|
+
declare const AnimatedTestimonials: import("svelte").Component<AnimatedTestimonialsProps, {}, "">;
|
|
28
|
+
type AnimatedTestimonials = ReturnType<typeof AnimatedTestimonials>;
|
|
29
|
+
export default AnimatedTestimonials;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { render, cleanup, fireEvent } from "@testing-library/svelte";
|
|
2
|
+
import { afterEach, beforeEach, describe, it, expect, vi } from "vitest";
|
|
3
|
+
import { flushSync } from "svelte";
|
|
4
|
+
import AnimatedTestimonials from "./AnimatedTestimonials.svelte";
|
|
5
|
+
const testimonials = [
|
|
6
|
+
{ quote: "First quote", name: "Alice", designation: "CEO", src: "alice.jpg" },
|
|
7
|
+
{ quote: "Second quote", name: "Bob", designation: "CTO", src: "bob.jpg" },
|
|
8
|
+
{ quote: "Third quote", name: "Carol", designation: "CFO", src: "carol.jpg" },
|
|
9
|
+
];
|
|
10
|
+
describe("AnimatedTestimonials", () => {
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
vi.useFakeTimers();
|
|
13
|
+
});
|
|
14
|
+
afterEach(() => {
|
|
15
|
+
vi.useRealTimers();
|
|
16
|
+
cleanup();
|
|
17
|
+
});
|
|
18
|
+
it("renders the first testimonial initially", () => {
|
|
19
|
+
const { getByText } = render(AnimatedTestimonials, { props: { testimonials } });
|
|
20
|
+
expect(getByText("First quote")).toBeTruthy();
|
|
21
|
+
expect(getByText("Alice")).toBeTruthy();
|
|
22
|
+
expect(getByText("CEO")).toBeTruthy();
|
|
23
|
+
});
|
|
24
|
+
it("shows empty state when testimonials array is empty", () => {
|
|
25
|
+
const { getByText } = render(AnimatedTestimonials, { props: { testimonials: [] } });
|
|
26
|
+
expect(getByText("No testimonials available.")).toBeTruthy();
|
|
27
|
+
});
|
|
28
|
+
it("advances to next testimonial on next button click", () => {
|
|
29
|
+
const { getByLabelText, getByText } = render(AnimatedTestimonials, {
|
|
30
|
+
props: { testimonials },
|
|
31
|
+
});
|
|
32
|
+
fireEvent.click(getByLabelText("Next testimonial"));
|
|
33
|
+
flushSync(() => vi.advanceTimersByTime(300));
|
|
34
|
+
expect(getByText("Second quote")).toBeTruthy();
|
|
35
|
+
expect(getByText("Bob")).toBeTruthy();
|
|
36
|
+
});
|
|
37
|
+
it("goes to previous testimonial on prev button click", () => {
|
|
38
|
+
const { getByLabelText, getByText } = render(AnimatedTestimonials, {
|
|
39
|
+
props: { testimonials },
|
|
40
|
+
});
|
|
41
|
+
// Go to second first
|
|
42
|
+
fireEvent.click(getByLabelText("Next testimonial"));
|
|
43
|
+
flushSync(() => vi.advanceTimersByTime(300));
|
|
44
|
+
// Then go back
|
|
45
|
+
fireEvent.click(getByLabelText("Previous testimonial"));
|
|
46
|
+
flushSync(() => vi.advanceTimersByTime(300));
|
|
47
|
+
expect(getByText("First quote")).toBeTruthy();
|
|
48
|
+
});
|
|
49
|
+
it("wraps around to last testimonial when going prev from first", () => {
|
|
50
|
+
const { getByLabelText, getByText } = render(AnimatedTestimonials, {
|
|
51
|
+
props: { testimonials },
|
|
52
|
+
});
|
|
53
|
+
fireEvent.click(getByLabelText("Previous testimonial"));
|
|
54
|
+
flushSync(() => vi.advanceTimersByTime(300));
|
|
55
|
+
expect(getByText("Third quote")).toBeTruthy();
|
|
56
|
+
});
|
|
57
|
+
it("wraps around to first testimonial when going next from last", () => {
|
|
58
|
+
const { getByLabelText, getByText } = render(AnimatedTestimonials, {
|
|
59
|
+
props: { testimonials },
|
|
60
|
+
});
|
|
61
|
+
fireEvent.click(getByLabelText("Next testimonial"));
|
|
62
|
+
flushSync(() => vi.advanceTimersByTime(300));
|
|
63
|
+
fireEvent.click(getByLabelText("Next testimonial"));
|
|
64
|
+
flushSync(() => vi.advanceTimersByTime(300));
|
|
65
|
+
fireEvent.click(getByLabelText("Next testimonial"));
|
|
66
|
+
flushSync(() => vi.advanceTimersByTime(300));
|
|
67
|
+
expect(getByText("First quote")).toBeTruthy();
|
|
68
|
+
});
|
|
69
|
+
it("auto-advances testimonials when autoplay is enabled", () => {
|
|
70
|
+
const { getByText } = render(AnimatedTestimonials, {
|
|
71
|
+
props: { testimonials, autoplay: true, interval: 3000 },
|
|
72
|
+
});
|
|
73
|
+
expect(getByText("First quote")).toBeTruthy();
|
|
74
|
+
flushSync(() => {
|
|
75
|
+
vi.advanceTimersByTime(3000);
|
|
76
|
+
vi.advanceTimersByTime(300);
|
|
77
|
+
});
|
|
78
|
+
expect(getByText("Second quote")).toBeTruthy();
|
|
79
|
+
});
|
|
80
|
+
it("does not auto-advance when autoplay is false", () => {
|
|
81
|
+
const { getByText } = render(AnimatedTestimonials, {
|
|
82
|
+
props: { testimonials, autoplay: false, interval: 1000 },
|
|
83
|
+
});
|
|
84
|
+
vi.advanceTimersByTime(5000);
|
|
85
|
+
expect(getByText("First quote")).toBeTruthy();
|
|
86
|
+
});
|
|
87
|
+
it("renders navigation buttons", () => {
|
|
88
|
+
const { getByLabelText } = render(AnimatedTestimonials, { props: { testimonials } });
|
|
89
|
+
expect(getByLabelText("Previous testimonial")).toBeTruthy();
|
|
90
|
+
expect(getByLabelText("Next testimonial")).toBeTruthy();
|
|
91
|
+
});
|
|
92
|
+
});
|