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,14 @@
|
|
|
1
|
+
# TextGenerateEffect
|
|
2
|
+
|
|
3
|
+
Typewriter-style text reveal that fades in words one by one with an optional blur effect.
|
|
4
|
+
|
|
5
|
+
## Props
|
|
6
|
+
|
|
7
|
+
| Prop | Type | Default | Description |
|
|
8
|
+
|------|------|---------|-------------|
|
|
9
|
+
| `words` | `string` | required | Text to animate (split on spaces) |
|
|
10
|
+
| `filter` | `boolean` | `true` | Enable blur-to-sharp transition |
|
|
11
|
+
| `duration` | `number` | `0.7` | Transition duration per word (seconds) |
|
|
12
|
+
| `delay` | `number` | `0` | Initial delay before animation starts (ms) |
|
|
13
|
+
| `stagger` | `number` | `200` | Delay between each word appearing (ms) |
|
|
14
|
+
| `class` | `string` | — | Additional CSS classes |
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
export interface TextGenerateEffectProps {
|
|
3
|
+
words: string;
|
|
4
|
+
filter?: boolean;
|
|
5
|
+
duration?: number;
|
|
6
|
+
delay?: number;
|
|
7
|
+
stagger?: number;
|
|
8
|
+
class?: string;
|
|
9
|
+
}
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<script lang="ts">
|
|
13
|
+
import { cn } from "../../utils.js";
|
|
14
|
+
import { onMount } from "svelte";
|
|
15
|
+
|
|
16
|
+
let {
|
|
17
|
+
words,
|
|
18
|
+
filter = true,
|
|
19
|
+
duration = 0.7,
|
|
20
|
+
delay = 0,
|
|
21
|
+
stagger = 200,
|
|
22
|
+
class: className,
|
|
23
|
+
}: TextGenerateEffectProps = $props();
|
|
24
|
+
|
|
25
|
+
let wordsArray = $derived(words.split(" "));
|
|
26
|
+
let scopeRef: HTMLDivElement;
|
|
27
|
+
|
|
28
|
+
onMount(() => {
|
|
29
|
+
const spans = scopeRef.querySelectorAll<HTMLSpanElement>("span");
|
|
30
|
+
|
|
31
|
+
const timeout = setTimeout(() => {
|
|
32
|
+
spans.forEach((span, index) => {
|
|
33
|
+
const wordTimeout = setTimeout(() => {
|
|
34
|
+
span.style.opacity = "1";
|
|
35
|
+
span.style.filter = filter ? "blur(0px)" : "none";
|
|
36
|
+
}, index * stagger);
|
|
37
|
+
|
|
38
|
+
// Store timeout ID for cleanup
|
|
39
|
+
(span as HTMLSpanElement & { _tid?: ReturnType<typeof setTimeout> })._tid = wordTimeout;
|
|
40
|
+
});
|
|
41
|
+
}, delay);
|
|
42
|
+
|
|
43
|
+
return () => {
|
|
44
|
+
clearTimeout(timeout);
|
|
45
|
+
spans.forEach((span) => {
|
|
46
|
+
const tid = (span as HTMLSpanElement & { _tid?: ReturnType<typeof setTimeout> })._tid;
|
|
47
|
+
if (tid) clearTimeout(tid);
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
</script>
|
|
52
|
+
|
|
53
|
+
<div class={cn("leading-snug tracking-wide", className)}>
|
|
54
|
+
<div bind:this={scopeRef}>
|
|
55
|
+
{#each wordsArray as word, idx (word + idx)}
|
|
56
|
+
<span
|
|
57
|
+
class="inline-block"
|
|
58
|
+
style="opacity: 0; filter: {filter
|
|
59
|
+
? 'blur(10px)'
|
|
60
|
+
: 'none'}; transition: opacity {duration}s, filter {duration}s;"
|
|
61
|
+
>
|
|
62
|
+
{word}
|
|
63
|
+
</span>
|
|
64
|
+
{/each}
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface TextGenerateEffectProps {
|
|
2
|
+
words: string;
|
|
3
|
+
filter?: boolean;
|
|
4
|
+
duration?: number;
|
|
5
|
+
delay?: number;
|
|
6
|
+
stagger?: number;
|
|
7
|
+
class?: string;
|
|
8
|
+
}
|
|
9
|
+
declare const TextGenerateEffect: import("svelte").Component<TextGenerateEffectProps, {}, "">;
|
|
10
|
+
type TextGenerateEffect = ReturnType<typeof TextGenerateEffect>;
|
|
11
|
+
export default TextGenerateEffect;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from "vitest";
|
|
2
|
+
import { render } from "@testing-library/svelte";
|
|
3
|
+
import TextGenerateEffect from "./TextGenerateEffect.svelte";
|
|
4
|
+
describe("TextGenerateEffect", () => {
|
|
5
|
+
it("renders all words as spans", () => {
|
|
6
|
+
const { container } = render(TextGenerateEffect, {
|
|
7
|
+
props: { words: "hello world test" },
|
|
8
|
+
});
|
|
9
|
+
const spans = container.querySelectorAll("span");
|
|
10
|
+
expect(spans.length).toBe(3);
|
|
11
|
+
});
|
|
12
|
+
it("words start hidden with blur", () => {
|
|
13
|
+
const { container } = render(TextGenerateEffect, {
|
|
14
|
+
props: { words: "fade in" },
|
|
15
|
+
});
|
|
16
|
+
const spans = container.querySelectorAll("span");
|
|
17
|
+
expect(spans[0].style.opacity).toBe("0");
|
|
18
|
+
expect(spans[0].style.filter).toContain("blur(10px)");
|
|
19
|
+
});
|
|
20
|
+
it("words start hidden without blur when filter is false", () => {
|
|
21
|
+
const { container } = render(TextGenerateEffect, {
|
|
22
|
+
props: { words: "no blur", filter: false },
|
|
23
|
+
});
|
|
24
|
+
const spans = container.querySelectorAll("span");
|
|
25
|
+
expect(spans[0].style.opacity).toBe("0");
|
|
26
|
+
expect(spans[0].style.filter).toBe("none");
|
|
27
|
+
});
|
|
28
|
+
it("reveals words after stagger delay", async () => {
|
|
29
|
+
vi.useFakeTimers();
|
|
30
|
+
const { container } = render(TextGenerateEffect, {
|
|
31
|
+
props: { words: "one two three", stagger: 100 },
|
|
32
|
+
});
|
|
33
|
+
const spans = container.querySelectorAll("span");
|
|
34
|
+
// Flush the outer setTimeout(fn, 0) + first word setTimeout(fn, 0)
|
|
35
|
+
await vi.advanceTimersByTimeAsync(1);
|
|
36
|
+
expect(spans[0].style.opacity).toBe("1");
|
|
37
|
+
expect(spans[1].style.opacity).toBe("0");
|
|
38
|
+
// After 100ms — second word
|
|
39
|
+
await vi.advanceTimersByTimeAsync(100);
|
|
40
|
+
expect(spans[1].style.opacity).toBe("1");
|
|
41
|
+
expect(spans[2].style.opacity).toBe("0");
|
|
42
|
+
// After 200ms — third word
|
|
43
|
+
await vi.advanceTimersByTimeAsync(100);
|
|
44
|
+
expect(spans[2].style.opacity).toBe("1");
|
|
45
|
+
vi.useRealTimers();
|
|
46
|
+
});
|
|
47
|
+
it("respects initial delay", async () => {
|
|
48
|
+
vi.useFakeTimers();
|
|
49
|
+
const { container } = render(TextGenerateEffect, {
|
|
50
|
+
props: { words: "delayed text", delay: 500 },
|
|
51
|
+
});
|
|
52
|
+
const spans = container.querySelectorAll("span");
|
|
53
|
+
await vi.advanceTimersByTimeAsync(499);
|
|
54
|
+
expect(spans[0].style.opacity).toBe("0");
|
|
55
|
+
await vi.advanceTimersByTimeAsync(2);
|
|
56
|
+
expect(spans[0].style.opacity).toBe("1");
|
|
57
|
+
vi.useRealTimers();
|
|
58
|
+
});
|
|
59
|
+
it("applies custom class", () => {
|
|
60
|
+
const { container } = render(TextGenerateEffect, {
|
|
61
|
+
props: { words: "styled", class: "my-class" },
|
|
62
|
+
});
|
|
63
|
+
const wrapper = container.firstElementChild;
|
|
64
|
+
expect(wrapper.className).toContain("my-class");
|
|
65
|
+
});
|
|
66
|
+
it("sets custom duration in transition style", () => {
|
|
67
|
+
const { container } = render(TextGenerateEffect, {
|
|
68
|
+
props: { words: "fast", duration: 0.3 },
|
|
69
|
+
});
|
|
70
|
+
const span = container.querySelector("span");
|
|
71
|
+
expect(span.style.transition).toContain("0.3s");
|
|
72
|
+
});
|
|
73
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as TextGenerateEffect } from "./TextGenerateEffect.svelte";
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# TextRevealCard
|
|
2
|
+
|
|
3
|
+
A card that reveals text as the user drags their mouse horizontally. Features animated stars in the background.
|
|
4
|
+
|
|
5
|
+
## Components
|
|
6
|
+
|
|
7
|
+
- `TextRevealCard` — Main card with mouse/touch reveal
|
|
8
|
+
- `TextRevealStars` — Animated floating star dots
|
|
9
|
+
|
|
10
|
+
## Props (TextRevealCard)
|
|
11
|
+
|
|
12
|
+
| Prop | Type | Default | Description |
|
|
13
|
+
| ------------ | -------- | ------- | --------------------------- |
|
|
14
|
+
| `starsCount` | `number` | `130` | Number of star dots |
|
|
15
|
+
| `starsClass` | `string` | `""` | CSS classes for star dots |
|
|
16
|
+
| `class` | `string` | `""` | Additional CSS classes |
|
|
17
|
+
|
|
18
|
+
## Snippets
|
|
19
|
+
|
|
20
|
+
- `children` — Header content above the reveal area
|
|
21
|
+
- `text` — The revealed text (shown on mouse drag)
|
|
22
|
+
- `revealText` — The base text (always visible)
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
```svelte
|
|
27
|
+
<TextRevealCard>
|
|
28
|
+
<p class="text-lg font-bold text-white">Hover to reveal</p>
|
|
29
|
+
{#snippet text()}
|
|
30
|
+
<p class="text-4xl font-bold text-white">Revealed!</p>
|
|
31
|
+
{/snippet}
|
|
32
|
+
{#snippet revealText()}
|
|
33
|
+
<p class="text-4xl font-bold text-white/20">Hidden text</p>
|
|
34
|
+
{/snippet}
|
|
35
|
+
</TextRevealCard>
|
|
36
|
+
```
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { cn } from "../../utils";
|
|
3
|
+
import TextRevealStars from "./TextRevealStars.svelte";
|
|
4
|
+
import type { Snippet } from "svelte";
|
|
5
|
+
import { onMount } from "svelte";
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
class?: string;
|
|
9
|
+
starsCount?: number;
|
|
10
|
+
starsClass?: string;
|
|
11
|
+
children?: Snippet;
|
|
12
|
+
text?: Snippet;
|
|
13
|
+
revealText?: Snippet;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let {
|
|
17
|
+
class: className = "",
|
|
18
|
+
starsCount = 130,
|
|
19
|
+
starsClass = "",
|
|
20
|
+
children,
|
|
21
|
+
text,
|
|
22
|
+
revealText,
|
|
23
|
+
}: Props = $props();
|
|
24
|
+
|
|
25
|
+
let cardRef: HTMLDivElement;
|
|
26
|
+
let widthPercentage = $state(0);
|
|
27
|
+
let isMouseOver = $state(false);
|
|
28
|
+
|
|
29
|
+
let rotateDeg = $derived((widthPercentage - 50) * 0.1);
|
|
30
|
+
|
|
31
|
+
function mouseMoveHandler(event: MouseEvent) {
|
|
32
|
+
event.preventDefault();
|
|
33
|
+
if (cardRef) {
|
|
34
|
+
const rect = cardRef.getBoundingClientRect();
|
|
35
|
+
const relativeX = event.clientX - rect.left;
|
|
36
|
+
widthPercentage = (relativeX / rect.width) * 100;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function mouseLeaveHandler() {
|
|
41
|
+
isMouseOver = false;
|
|
42
|
+
setTimeout(() => {
|
|
43
|
+
if (!isMouseOver) {
|
|
44
|
+
widthPercentage = 0;
|
|
45
|
+
}
|
|
46
|
+
}, 100);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function mouseEnterHandler() {
|
|
50
|
+
isMouseOver = true;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function touchMoveHandler(event: TouchEvent) {
|
|
54
|
+
event.preventDefault();
|
|
55
|
+
if (cardRef) {
|
|
56
|
+
const rect = cardRef.getBoundingClientRect();
|
|
57
|
+
const relativeX = event.touches[0]!.clientX - rect.left;
|
|
58
|
+
widthPercentage = (relativeX / rect.width) * 100;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
</script>
|
|
62
|
+
|
|
63
|
+
<div
|
|
64
|
+
bind:this={cardRef}
|
|
65
|
+
class={cn(
|
|
66
|
+
"relative w-full max-w-[40rem] overflow-hidden rounded-lg border border-white/[0.08] bg-[#1d1c20] p-4 sm:p-6 md:p-8",
|
|
67
|
+
className
|
|
68
|
+
)}
|
|
69
|
+
role="presentation"
|
|
70
|
+
onmouseenter={mouseEnterHandler}
|
|
71
|
+
onmouseleave={mouseLeaveHandler}
|
|
72
|
+
onmousemove={mouseMoveHandler}
|
|
73
|
+
ontouchstart={mouseEnterHandler}
|
|
74
|
+
ontouchend={mouseLeaveHandler}
|
|
75
|
+
ontouchmove={touchMoveHandler}
|
|
76
|
+
>
|
|
77
|
+
{#if children}
|
|
78
|
+
{@render children()}
|
|
79
|
+
{/if}
|
|
80
|
+
|
|
81
|
+
<div class="relative flex h-40 items-center overflow-hidden">
|
|
82
|
+
<!-- Reveal layer -->
|
|
83
|
+
<div
|
|
84
|
+
style="width: 100%; opacity: {widthPercentage > 0 ? 1 : 0}; clip-path: inset(0 {100 -
|
|
85
|
+
widthPercentage}% 0 0); transition: {isMouseOver ? 'none' : 'all 0.4s ease-out'};"
|
|
86
|
+
class="absolute z-20 bg-[#1d1c20] will-change-transform"
|
|
87
|
+
>
|
|
88
|
+
{#if text}
|
|
89
|
+
{@render text()}
|
|
90
|
+
{/if}
|
|
91
|
+
</div>
|
|
92
|
+
|
|
93
|
+
<!-- Reveal line -->
|
|
94
|
+
<div
|
|
95
|
+
style="left: {widthPercentage}%; transform: rotate({rotateDeg}deg); opacity: {widthPercentage >
|
|
96
|
+
0
|
|
97
|
+
? 1
|
|
98
|
+
: 0}; transition: {isMouseOver ? 'none' : 'all 0.4s ease-out'};"
|
|
99
|
+
class="absolute z-50 h-40 w-[8px] bg-gradient-to-b from-transparent via-neutral-800 to-transparent will-change-transform"
|
|
100
|
+
></div>
|
|
101
|
+
|
|
102
|
+
<!-- Background text + stars -->
|
|
103
|
+
<div
|
|
104
|
+
class="overflow-hidden [mask-image:linear-gradient(to_bottom,transparent,white,transparent)]"
|
|
105
|
+
>
|
|
106
|
+
{#if revealText}
|
|
107
|
+
{@render revealText()}
|
|
108
|
+
{/if}
|
|
109
|
+
<TextRevealStars {starsCount} class={starsClass} />
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
2
|
+
interface Props {
|
|
3
|
+
class?: string;
|
|
4
|
+
starsCount?: number;
|
|
5
|
+
starsClass?: string;
|
|
6
|
+
children?: Snippet;
|
|
7
|
+
text?: Snippet;
|
|
8
|
+
revealText?: Snippet;
|
|
9
|
+
}
|
|
10
|
+
declare const TextRevealCard: import("svelte").Component<Props, {}, "">;
|
|
11
|
+
type TextRevealCard = ReturnType<typeof TextRevealCard>;
|
|
12
|
+
export default TextRevealCard;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { render, cleanup } from "@testing-library/svelte";
|
|
2
|
+
import { afterEach, describe, it, expect } from "vitest";
|
|
3
|
+
import TextRevealCard from "./TextRevealCard.svelte";
|
|
4
|
+
describe("TextRevealCard", () => {
|
|
5
|
+
afterEach(cleanup);
|
|
6
|
+
it("renders the component", () => {
|
|
7
|
+
const { container } = render(TextRevealCard);
|
|
8
|
+
const card = container.querySelector(".bg-\\[\\#1d1c20\\]");
|
|
9
|
+
expect(card).toBeInTheDocument();
|
|
10
|
+
});
|
|
11
|
+
it("applies custom class", () => {
|
|
12
|
+
const { container } = render(TextRevealCard, {
|
|
13
|
+
props: { class: "my-reveal" },
|
|
14
|
+
});
|
|
15
|
+
const card = container.firstElementChild;
|
|
16
|
+
expect(card?.className).toContain("my-reveal");
|
|
17
|
+
});
|
|
18
|
+
it("renders reveal line", () => {
|
|
19
|
+
const { container } = render(TextRevealCard);
|
|
20
|
+
const line = container.querySelector(".via-neutral-800");
|
|
21
|
+
expect(line).toBeInTheDocument();
|
|
22
|
+
});
|
|
23
|
+
it("renders stars container", () => {
|
|
24
|
+
const { container } = render(TextRevealCard);
|
|
25
|
+
// Stars are rendered inside the component
|
|
26
|
+
const starsContainer = container.querySelector(".absolute.inset-0");
|
|
27
|
+
expect(starsContainer).toBeInTheDocument();
|
|
28
|
+
});
|
|
29
|
+
it("starts with 0% width", () => {
|
|
30
|
+
const { container } = render(TextRevealCard);
|
|
31
|
+
const revealLayer = container.querySelector(".z-20");
|
|
32
|
+
expect(revealLayer?.style.opacity).toBe("0");
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { cn } from "../../utils";
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
starsCount?: number;
|
|
6
|
+
class?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
let { starsCount = 130, class: className = "" }: Props = $props();
|
|
10
|
+
|
|
11
|
+
interface StarData {
|
|
12
|
+
top: string;
|
|
13
|
+
left: string;
|
|
14
|
+
targetTop: string;
|
|
15
|
+
targetLeft: string;
|
|
16
|
+
opacity: number;
|
|
17
|
+
duration: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function randomMove() {
|
|
21
|
+
return Math.random() * 4 - 2;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function random() {
|
|
25
|
+
return Math.random();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Generate star data reactively based on starsCount
|
|
29
|
+
let stars: StarData[] = $derived(
|
|
30
|
+
Array.from({ length: starsCount }, () => ({
|
|
31
|
+
top: `calc(${random() * 100}% + ${randomMove()}px)`,
|
|
32
|
+
left: `calc(${random() * 100}% + ${randomMove()}px)`,
|
|
33
|
+
targetTop: `calc(${random() * 100}% + ${randomMove()}px)`,
|
|
34
|
+
targetLeft: `calc(${random() * 100}% + ${randomMove()}px)`,
|
|
35
|
+
opacity: random(),
|
|
36
|
+
duration: random() * 10 + 20,
|
|
37
|
+
}))
|
|
38
|
+
);
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<div class="absolute inset-0">
|
|
42
|
+
{#each stars as star}
|
|
43
|
+
<span
|
|
44
|
+
class={cn(
|
|
45
|
+
"star-animate absolute z-[1] inline-block h-0.5 w-0.5 rounded-full bg-white",
|
|
46
|
+
className
|
|
47
|
+
)}
|
|
48
|
+
style="top:{star.top};left:{star.left};--target-top:{star.targetTop};--target-left:{star.targetLeft};--star-opacity:{star.opacity};animation-duration:{star.duration}s;"
|
|
49
|
+
></span>
|
|
50
|
+
{/each}
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<style>
|
|
54
|
+
:global {
|
|
55
|
+
@keyframes star-drift {
|
|
56
|
+
0% {
|
|
57
|
+
opacity: 0;
|
|
58
|
+
transform: scale(1);
|
|
59
|
+
}
|
|
60
|
+
50% {
|
|
61
|
+
opacity: var(--star-opacity, 0.5);
|
|
62
|
+
transform: scale(1.2);
|
|
63
|
+
}
|
|
64
|
+
100% {
|
|
65
|
+
opacity: 0;
|
|
66
|
+
transform: scale(0);
|
|
67
|
+
top: var(--target-top);
|
|
68
|
+
left: var(--target-left);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.star-animate {
|
|
74
|
+
animation: star-drift linear infinite;
|
|
75
|
+
}
|
|
76
|
+
</style>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Timeline
|
|
2
|
+
|
|
3
|
+
A vertical timeline with scroll-driven progress line and sticky labels.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Scroll-driven progress**: Gradient line (purple → blue) grows as user scrolls
|
|
8
|
+
- **Sticky labels**: Item labels stay visible while scrolling through content
|
|
9
|
+
- **Dot indicators**: Visual markers on the timeline line
|
|
10
|
+
- **Responsive**: Labels hidden on mobile, full layout on desktop
|
|
11
|
+
- **ResizeObserver**: Recalculates height on layout changes
|
|
12
|
+
|
|
13
|
+
## Props
|
|
14
|
+
|
|
15
|
+
| Prop | Type | Default | Description |
|
|
16
|
+
|------|------|---------|-------------|
|
|
17
|
+
| `items` | `TimelineItem[]` | `[]` | Timeline entries with `id` and `label` |
|
|
18
|
+
| `title` | `string` | — | Heading text above the timeline |
|
|
19
|
+
| `description` | `string` | — | Subheading text |
|
|
20
|
+
| `class` | `string` | `''` | Additional CSS classes |
|
|
21
|
+
|
|
22
|
+
## Snippets
|
|
23
|
+
|
|
24
|
+
| Snippet | Args | Description |
|
|
25
|
+
|---------|------|-------------|
|
|
26
|
+
| `content` | `(item: TimelineItem)` | Content rendered for each timeline entry |
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
```svelte
|
|
31
|
+
<script>
|
|
32
|
+
import { Timeline } from '$lib/fancy-ui/timeline';
|
|
33
|
+
|
|
34
|
+
const items = [
|
|
35
|
+
{ id: 'step-1', label: '2024' },
|
|
36
|
+
{ id: 'step-2', label: '2023' },
|
|
37
|
+
];
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
<Timeline {items} title="My Journey">
|
|
41
|
+
{#snippet content(item)}
|
|
42
|
+
{#if item.id === 'step-1'}
|
|
43
|
+
<p>First step content</p>
|
|
44
|
+
{:else if item.id === 'step-2'}
|
|
45
|
+
<p>Second step content</p>
|
|
46
|
+
{/if}
|
|
47
|
+
{/snippet}
|
|
48
|
+
</Timeline>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Implementation Notes
|
|
52
|
+
|
|
53
|
+
- Replaced `motion-v` `useScroll` / `useTransform` with a native scroll event listener
|
|
54
|
+
- Replaced Vue named slots (`<slot :name="item.id">`) with a single `content` snippet that receives the item
|
|
55
|
+
- Uses ResizeObserver to keep timeline height in sync
|
|
56
|
+
- Uses theme tokens (`bg-background`, `text-foreground`) instead of hardcoded colors
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
|
|
4
|
+
export interface TimelineItem {
|
|
5
|
+
id: string;
|
|
6
|
+
label: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface TimelineProps {
|
|
10
|
+
/** Timeline entries */
|
|
11
|
+
items?: TimelineItem[];
|
|
12
|
+
/** Heading text */
|
|
13
|
+
title?: string;
|
|
14
|
+
/** Subheading text */
|
|
15
|
+
description?: string;
|
|
16
|
+
/** Additional CSS classes for the outer wrapper */
|
|
17
|
+
class?: string;
|
|
18
|
+
/** Content snippet, called for each item */
|
|
19
|
+
content?: Snippet<[TimelineItem]>;
|
|
20
|
+
}
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<script lang="ts">
|
|
24
|
+
import { cn } from "../../utils.js";
|
|
25
|
+
import { onMount } from "svelte";
|
|
26
|
+
|
|
27
|
+
let { items = [], title, description, class: className, content }: TimelineProps = $props();
|
|
28
|
+
|
|
29
|
+
let timelineRef: HTMLDivElement;
|
|
30
|
+
let timelineHeight = $state(0);
|
|
31
|
+
let scrollProgress = $state(0);
|
|
32
|
+
|
|
33
|
+
let progressHeight = $derived(scrollProgress * timelineHeight);
|
|
34
|
+
let progressOpacity = $derived(Math.min(scrollProgress / 0.1, 1));
|
|
35
|
+
|
|
36
|
+
function updateProgress() {
|
|
37
|
+
if (!timelineRef) return;
|
|
38
|
+
|
|
39
|
+
const rect = timelineRef.getBoundingClientRect();
|
|
40
|
+
const viewportHeight = window.innerHeight;
|
|
41
|
+
|
|
42
|
+
// Start tracking when top of timeline reaches 10% from top of viewport
|
|
43
|
+
const startOffset = viewportHeight * 0.1;
|
|
44
|
+
// End tracking when bottom of timeline reaches 50% of viewport
|
|
45
|
+
const endOffset = viewportHeight * 0.5;
|
|
46
|
+
|
|
47
|
+
const start = rect.top - startOffset;
|
|
48
|
+
const end = rect.bottom - endOffset;
|
|
49
|
+
const total = end - start;
|
|
50
|
+
|
|
51
|
+
if (total <= 0) {
|
|
52
|
+
scrollProgress = 0;
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const progress = -start / total;
|
|
57
|
+
scrollProgress = Math.max(0, Math.min(1, progress));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
onMount(() => {
|
|
61
|
+
if (timelineRef) {
|
|
62
|
+
timelineHeight = timelineRef.getBoundingClientRect().height;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
66
|
+
if (timelineRef) {
|
|
67
|
+
timelineHeight = timelineRef.getBoundingClientRect().height;
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
resizeObserver.observe(timelineRef);
|
|
72
|
+
window.addEventListener("scroll", updateProgress, { passive: true });
|
|
73
|
+
updateProgress();
|
|
74
|
+
|
|
75
|
+
return () => {
|
|
76
|
+
resizeObserver.disconnect();
|
|
77
|
+
window.removeEventListener("scroll", updateProgress);
|
|
78
|
+
};
|
|
79
|
+
});
|
|
80
|
+
</script>
|
|
81
|
+
|
|
82
|
+
<div class={cn("w-full font-sans md:px-10", className)}>
|
|
83
|
+
{#if title || description}
|
|
84
|
+
<div class="mx-auto max-w-7xl px-4 py-20 md:px-8 lg:px-10">
|
|
85
|
+
{#if title}
|
|
86
|
+
<h2 class="text-foreground mb-4 max-w-4xl text-lg md:text-4xl">
|
|
87
|
+
{title}
|
|
88
|
+
</h2>
|
|
89
|
+
{/if}
|
|
90
|
+
{#if description}
|
|
91
|
+
<p class="text-muted-foreground max-w-sm text-sm md:text-base">
|
|
92
|
+
{description}
|
|
93
|
+
</p>
|
|
94
|
+
{/if}
|
|
95
|
+
</div>
|
|
96
|
+
{/if}
|
|
97
|
+
|
|
98
|
+
<div bind:this={timelineRef} class="relative z-0 mx-auto max-w-7xl pb-20">
|
|
99
|
+
{#each items as item, index (`${item.id}-${index}`)}
|
|
100
|
+
<div class="flex justify-start pt-10 md:gap-10 md:pt-40">
|
|
101
|
+
<!-- Sticky label -->
|
|
102
|
+
<div
|
|
103
|
+
class="sticky top-40 z-40 flex max-w-xs flex-col items-center self-start md:w-full md:flex-row lg:max-w-sm"
|
|
104
|
+
>
|
|
105
|
+
<div
|
|
106
|
+
class="bg-background absolute left-3 flex size-10 items-center justify-center rounded-full md:left-3"
|
|
107
|
+
>
|
|
108
|
+
<div
|
|
109
|
+
class="size-4 rounded-full border border-neutral-300 bg-neutral-200 p-2 dark:border-neutral-700 dark:bg-neutral-800"
|
|
110
|
+
/>
|
|
111
|
+
</div>
|
|
112
|
+
<h3
|
|
113
|
+
class="hidden text-xl font-bold text-neutral-500 md:block md:pl-20 md:text-5xl dark:text-neutral-500"
|
|
114
|
+
>
|
|
115
|
+
{item.label}
|
|
116
|
+
</h3>
|
|
117
|
+
</div>
|
|
118
|
+
|
|
119
|
+
<!-- Item content -->
|
|
120
|
+
<div class="w-full pr-4 pl-20 md:pl-4">
|
|
121
|
+
{#if content}
|
|
122
|
+
{@render content(item)}
|
|
123
|
+
{/if}
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
{/each}
|
|
127
|
+
|
|
128
|
+
<!-- Background line -->
|
|
129
|
+
<div
|
|
130
|
+
style:height="{timelineHeight}px"
|
|
131
|
+
class="absolute top-0 left-8 w-[2px] overflow-hidden bg-[linear-gradient(to_bottom,var(--tw-gradient-stops))] from-transparent from-0% via-neutral-200 to-transparent to-[99%] [mask-image:linear-gradient(to_bottom,transparent_0%,black_10%,black_90%,transparent_100%)] md:left-8 dark:via-neutral-700"
|
|
132
|
+
>
|
|
133
|
+
<!-- Animated progress line -->
|
|
134
|
+
<div
|
|
135
|
+
style:height="{progressHeight}px"
|
|
136
|
+
style:opacity={progressOpacity}
|
|
137
|
+
class="absolute inset-x-0 top-0 w-[2px] rounded-full bg-gradient-to-t from-purple-500 from-0% via-blue-500 via-10% to-transparent"
|
|
138
|
+
></div>
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
</div>
|