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,11 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
class?: string;
|
|
3
|
+
reverse?: boolean;
|
|
4
|
+
pauseOnHover?: boolean;
|
|
5
|
+
vertical?: boolean;
|
|
6
|
+
repeat?: number;
|
|
7
|
+
children?: import("svelte").Snippet;
|
|
8
|
+
}
|
|
9
|
+
declare const Marquee: import("svelte").Component<Props, {}, "">;
|
|
10
|
+
type Marquee = ReturnType<typeof Marquee>;
|
|
11
|
+
export default Marquee;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { render, cleanup } from "@testing-library/svelte";
|
|
2
|
+
import { afterEach, describe, it, expect } from "vitest";
|
|
3
|
+
import Marquee from "./Marquee.svelte";
|
|
4
|
+
describe("Marquee", () => {
|
|
5
|
+
afterEach(cleanup);
|
|
6
|
+
it("renders a container div", () => {
|
|
7
|
+
const { container } = render(Marquee);
|
|
8
|
+
const div = container.firstElementChild;
|
|
9
|
+
expect(div).toBeInTheDocument();
|
|
10
|
+
});
|
|
11
|
+
it("has overflow-hidden class", () => {
|
|
12
|
+
const { container } = render(Marquee);
|
|
13
|
+
const div = container.firstElementChild;
|
|
14
|
+
expect(div?.className).toContain("overflow-hidden");
|
|
15
|
+
});
|
|
16
|
+
it("renders default 4 repeat groups", () => {
|
|
17
|
+
const { container } = render(Marquee);
|
|
18
|
+
const groups = container.querySelectorAll(".animate-marquee");
|
|
19
|
+
expect(groups.length).toBe(4);
|
|
20
|
+
});
|
|
21
|
+
it("renders custom repeat count", () => {
|
|
22
|
+
const { container } = render(Marquee, { props: { repeat: 2 } });
|
|
23
|
+
const groups = container.querySelectorAll(".animate-marquee");
|
|
24
|
+
expect(groups.length).toBe(2);
|
|
25
|
+
});
|
|
26
|
+
it("uses vertical animation class when vertical", () => {
|
|
27
|
+
const { container } = render(Marquee, { props: { vertical: true } });
|
|
28
|
+
const groups = container.querySelectorAll(".animate-marquee-vertical");
|
|
29
|
+
expect(groups.length).toBe(4);
|
|
30
|
+
});
|
|
31
|
+
it("uses flex-col when vertical", () => {
|
|
32
|
+
const { container } = render(Marquee, { props: { vertical: true } });
|
|
33
|
+
const div = container.firstElementChild;
|
|
34
|
+
expect(div?.className).toContain("flex-col");
|
|
35
|
+
});
|
|
36
|
+
it("sets animation-direction to reverse when reverse prop is true", () => {
|
|
37
|
+
const { container } = render(Marquee, { props: { reverse: true } });
|
|
38
|
+
const group = container.querySelector(".animate-marquee");
|
|
39
|
+
expect(group?.style.animationDirection).toBe("reverse");
|
|
40
|
+
});
|
|
41
|
+
it("applies custom class names", () => {
|
|
42
|
+
const { container } = render(Marquee, { props: { class: "my-marquee" } });
|
|
43
|
+
const div = container.firstElementChild;
|
|
44
|
+
expect(div?.className).toContain("my-marquee");
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
interface Props {
|
|
3
|
+
img: string;
|
|
4
|
+
name: string;
|
|
5
|
+
username: string;
|
|
6
|
+
body: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
let { img, name, username, body }: Props = $props();
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<figure
|
|
13
|
+
class="relative w-64 cursor-pointer overflow-hidden rounded-xl border border-gray-950/[.1] bg-gray-950/[.01] p-4 hover:bg-gray-950/[.05] dark:border-gray-50/[.1] dark:bg-gray-50/[.10] dark:hover:bg-gray-50/[.15]"
|
|
14
|
+
>
|
|
15
|
+
<div class="flex flex-row items-center gap-2">
|
|
16
|
+
<img src={img} class="rounded-full" width="32" height="32" alt="" />
|
|
17
|
+
<div class="flex flex-col">
|
|
18
|
+
<span class="text-sm font-medium dark:text-white">
|
|
19
|
+
{name}
|
|
20
|
+
</span>
|
|
21
|
+
<p class="text-xs font-medium dark:text-white/40">{username}</p>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
<blockquote class="mt-2 text-sm">{body}</blockquote>
|
|
25
|
+
</figure>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/**
|
|
3
|
+
* Meteors - Animated meteor shower effect
|
|
4
|
+
*
|
|
5
|
+
* Generates N span elements with randomized positions, delays, and durations
|
|
6
|
+
* that animate diagonally across the container.
|
|
7
|
+
*/
|
|
8
|
+
export interface MeteorsProps {
|
|
9
|
+
/** Number of meteors to render */
|
|
10
|
+
count?: number;
|
|
11
|
+
/** Additional CSS classes applied to each meteor */
|
|
12
|
+
class?: string;
|
|
13
|
+
}
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<script lang="ts">
|
|
17
|
+
import { cn } from "../../utils.js";
|
|
18
|
+
|
|
19
|
+
let { count = 20, class: className }: MeteorsProps = $props();
|
|
20
|
+
|
|
21
|
+
const meteors = $derived(
|
|
22
|
+
Array.from({ length: count }, () => ({
|
|
23
|
+
left: `${Math.floor(Math.random() * 800 - 400)}px`,
|
|
24
|
+
animationDelay: `${(Math.random() * 0.6 + 0.2).toFixed(2)}s`,
|
|
25
|
+
animationDuration: `${Math.floor(Math.random() * 8 + 2)}s`,
|
|
26
|
+
}))
|
|
27
|
+
);
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
{#each meteors as meteor, i (i)}
|
|
31
|
+
<span
|
|
32
|
+
class={cn(
|
|
33
|
+
"meteor pointer-events-none absolute top-0 h-0.5 w-0.5 rounded-full bg-slate-500 opacity-0 shadow-[0_0_0_1px_#ffffff10]",
|
|
34
|
+
"before:absolute before:top-1/2 before:h-px before:w-[50px] before:-translate-y-1/2 before:bg-gradient-to-r before:from-slate-500 before:to-transparent before:content-['']",
|
|
35
|
+
className
|
|
36
|
+
)}
|
|
37
|
+
style="left:{meteor.left};animation-delay:{meteor.animationDelay};animation-duration:{meteor.animationDuration}"
|
|
38
|
+
></span>
|
|
39
|
+
{/each}
|
|
40
|
+
|
|
41
|
+
<style>
|
|
42
|
+
@keyframes meteor-fall {
|
|
43
|
+
0% {
|
|
44
|
+
transform: rotate(215deg) translateX(0);
|
|
45
|
+
opacity: 1;
|
|
46
|
+
}
|
|
47
|
+
70% {
|
|
48
|
+
opacity: 1;
|
|
49
|
+
}
|
|
50
|
+
100% {
|
|
51
|
+
transform: rotate(215deg) translateX(-500px);
|
|
52
|
+
opacity: 0;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.meteor {
|
|
57
|
+
animation: meteor-fall 5s linear infinite;
|
|
58
|
+
}
|
|
59
|
+
</style>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Meteors - Animated meteor shower effect
|
|
3
|
+
*
|
|
4
|
+
* Generates N span elements with randomized positions, delays, and durations
|
|
5
|
+
* that animate diagonally across the container.
|
|
6
|
+
*/
|
|
7
|
+
export interface MeteorsProps {
|
|
8
|
+
/** Number of meteors to render */
|
|
9
|
+
count?: number;
|
|
10
|
+
/** Additional CSS classes applied to each meteor */
|
|
11
|
+
class?: string;
|
|
12
|
+
}
|
|
13
|
+
declare const Meteors: import("svelte").Component<MeteorsProps, {}, "">;
|
|
14
|
+
type Meteors = ReturnType<typeof Meteors>;
|
|
15
|
+
export default Meteors;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { render, cleanup } from "@testing-library/svelte";
|
|
2
|
+
import { afterEach, describe, it, expect } from "vitest";
|
|
3
|
+
import Meteors from "./Meteors.svelte";
|
|
4
|
+
describe("Meteors", () => {
|
|
5
|
+
afterEach(cleanup);
|
|
6
|
+
it("renders the default number of meteor spans (20)", () => {
|
|
7
|
+
const { container } = render(Meteors);
|
|
8
|
+
const spans = container.querySelectorAll("span.meteor");
|
|
9
|
+
expect(spans.length).toBe(20);
|
|
10
|
+
});
|
|
11
|
+
it("renders a custom count of meteors", () => {
|
|
12
|
+
const { container } = render(Meteors, { props: { count: 5 } });
|
|
13
|
+
const spans = container.querySelectorAll("span.meteor");
|
|
14
|
+
expect(spans.length).toBe(5);
|
|
15
|
+
});
|
|
16
|
+
it("renders zero meteors when count is 0", () => {
|
|
17
|
+
const { container } = render(Meteors, { props: { count: 0 } });
|
|
18
|
+
const spans = container.querySelectorAll("span.meteor");
|
|
19
|
+
expect(spans.length).toBe(0);
|
|
20
|
+
});
|
|
21
|
+
it("applies custom class names to each meteor", () => {
|
|
22
|
+
const { container } = render(Meteors, {
|
|
23
|
+
props: { count: 3, class: "my-custom-class" },
|
|
24
|
+
});
|
|
25
|
+
const spans = container.querySelectorAll("span.meteor");
|
|
26
|
+
spans.forEach((span) => {
|
|
27
|
+
expect(span.className).toContain("my-custom-class");
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
it("each meteor has a style attribute with left, animation-delay, and animation-duration", () => {
|
|
31
|
+
const { container } = render(Meteors, { props: { count: 3 } });
|
|
32
|
+
const spans = container.querySelectorAll("span.meteor");
|
|
33
|
+
spans.forEach((span) => {
|
|
34
|
+
const style = span.getAttribute("style") ?? "";
|
|
35
|
+
expect(style).toContain("left:");
|
|
36
|
+
expect(style).toContain("animation-delay:");
|
|
37
|
+
expect(style).toContain("animation-duration:");
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
it("preserves base classes when custom class is added", () => {
|
|
41
|
+
const { container } = render(Meteors, {
|
|
42
|
+
props: { count: 1, class: "extra" },
|
|
43
|
+
});
|
|
44
|
+
const span = container.querySelector("span.meteor");
|
|
45
|
+
expect(span.className).toContain("absolute");
|
|
46
|
+
expect(span.className).toContain("rounded-full");
|
|
47
|
+
});
|
|
48
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Meteors
|
|
2
|
+
|
|
3
|
+
Animated meteor shower effect. Generates N span elements with randomized positions, delays, and durations that animate diagonally across the container.
|
|
4
|
+
|
|
5
|
+
## Props
|
|
6
|
+
|
|
7
|
+
| Prop | Type | Default | Description |
|
|
8
|
+
| ------- | -------- | ------- | ------------------------------------ |
|
|
9
|
+
| `count` | `number` | `20` | Number of meteors to render |
|
|
10
|
+
| `class` | `string` | `''` | Additional CSS classes on each meteor |
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
```svelte
|
|
15
|
+
<div class="relative h-64 w-full overflow-hidden bg-black">
|
|
16
|
+
<Meteors count={30} />
|
|
17
|
+
</div>
|
|
18
|
+
```
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* NeonBorder - Dual-color neon glow border effect
|
|
6
|
+
*
|
|
7
|
+
* Two gradient layers with blur and drop-shadow create a bicolor neon effect.
|
|
8
|
+
* Optional rotation animation with half or full coverage.
|
|
9
|
+
*/
|
|
10
|
+
export interface NeonBorderProps {
|
|
11
|
+
/** First neon color */
|
|
12
|
+
color1?: string;
|
|
13
|
+
/** Second neon color */
|
|
14
|
+
color2?: string;
|
|
15
|
+
/** Animation type: none (static), half (50% coverage), full (100% coverage) */
|
|
16
|
+
animationType?: "none" | "half" | "full";
|
|
17
|
+
/** Animation duration in seconds */
|
|
18
|
+
duration?: number;
|
|
19
|
+
/** Additional CSS classes */
|
|
20
|
+
class?: string;
|
|
21
|
+
/** Content */
|
|
22
|
+
children?: Snippet;
|
|
23
|
+
}
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<script lang="ts">
|
|
27
|
+
import { cn } from "../../utils.js";
|
|
28
|
+
|
|
29
|
+
let {
|
|
30
|
+
color1 = "#0496ff",
|
|
31
|
+
color2 = "#ff0a54",
|
|
32
|
+
animationType = "half",
|
|
33
|
+
duration = 6,
|
|
34
|
+
class: className,
|
|
35
|
+
children,
|
|
36
|
+
}: NeonBorderProps = $props();
|
|
37
|
+
|
|
38
|
+
function getWidth(type: "none" | "half" | "full"): number {
|
|
39
|
+
switch (type) {
|
|
40
|
+
case "none":
|
|
41
|
+
return 12;
|
|
42
|
+
case "half":
|
|
43
|
+
return 50;
|
|
44
|
+
case "full":
|
|
45
|
+
return 100;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const styleVars = $derived(
|
|
50
|
+
`--neon-duration: ${duration}s; --neon-color1: ${color1}; --neon-color2: ${color2}; --neon-width: ${getWidth(animationType)}%`
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
const animated = $derived(animationType !== "none");
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
<div
|
|
57
|
+
class={cn(
|
|
58
|
+
"neon-border-container relative z-10 inline-block h-10 w-full max-w-sm overflow-hidden rounded-lg p-px",
|
|
59
|
+
className
|
|
60
|
+
)}
|
|
61
|
+
style={styleVars}
|
|
62
|
+
>
|
|
63
|
+
<div class={cn("neon-layer-one rounded-lg", animated && "neon-animated")}></div>
|
|
64
|
+
<div class={cn("neon-layer-two rounded-lg", animated && "neon-animated")}></div>
|
|
65
|
+
{@render children?.()}
|
|
66
|
+
</div>
|
|
67
|
+
|
|
68
|
+
<style>
|
|
69
|
+
.neon-layer-one {
|
|
70
|
+
position: absolute;
|
|
71
|
+
overflow: hidden;
|
|
72
|
+
width: 100%;
|
|
73
|
+
height: 100%;
|
|
74
|
+
filter: blur(1px) drop-shadow(0 0 12px var(--neon-color1));
|
|
75
|
+
z-index: -1;
|
|
76
|
+
inset: 0;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.neon-layer-one::before {
|
|
80
|
+
content: "";
|
|
81
|
+
position: absolute;
|
|
82
|
+
overflow: hidden;
|
|
83
|
+
top: 0;
|
|
84
|
+
left: 0;
|
|
85
|
+
width: var(--neon-width);
|
|
86
|
+
height: 100%;
|
|
87
|
+
background: linear-gradient(
|
|
88
|
+
135deg,
|
|
89
|
+
var(--neon-color1),
|
|
90
|
+
var(--neon-color1),
|
|
91
|
+
transparent,
|
|
92
|
+
transparent
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.neon-layer-two {
|
|
97
|
+
position: absolute;
|
|
98
|
+
overflow: hidden;
|
|
99
|
+
width: 100%;
|
|
100
|
+
height: 100%;
|
|
101
|
+
filter: blur(1px) drop-shadow(0 0 12px var(--neon-color2));
|
|
102
|
+
z-index: -1;
|
|
103
|
+
inset: 0;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.neon-layer-two::before {
|
|
107
|
+
content: "";
|
|
108
|
+
position: absolute;
|
|
109
|
+
bottom: 0;
|
|
110
|
+
right: 0;
|
|
111
|
+
overflow: hidden;
|
|
112
|
+
width: var(--neon-width);
|
|
113
|
+
height: 100%;
|
|
114
|
+
background: linear-gradient(
|
|
115
|
+
135deg,
|
|
116
|
+
transparent,
|
|
117
|
+
transparent,
|
|
118
|
+
var(--neon-color2),
|
|
119
|
+
var(--neon-color2)
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
@keyframes neon-rotate {
|
|
124
|
+
0% {
|
|
125
|
+
transform: rotate(0deg);
|
|
126
|
+
}
|
|
127
|
+
100% {
|
|
128
|
+
transform: rotate(360deg);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.neon-animated {
|
|
133
|
+
animation: neon-rotate var(--neon-duration) linear infinite;
|
|
134
|
+
}
|
|
135
|
+
</style>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
2
|
+
/**
|
|
3
|
+
* NeonBorder - Dual-color neon glow border effect
|
|
4
|
+
*
|
|
5
|
+
* Two gradient layers with blur and drop-shadow create a bicolor neon effect.
|
|
6
|
+
* Optional rotation animation with half or full coverage.
|
|
7
|
+
*/
|
|
8
|
+
export interface NeonBorderProps {
|
|
9
|
+
/** First neon color */
|
|
10
|
+
color1?: string;
|
|
11
|
+
/** Second neon color */
|
|
12
|
+
color2?: string;
|
|
13
|
+
/** Animation type: none (static), half (50% coverage), full (100% coverage) */
|
|
14
|
+
animationType?: "none" | "half" | "full";
|
|
15
|
+
/** Animation duration in seconds */
|
|
16
|
+
duration?: number;
|
|
17
|
+
/** Additional CSS classes */
|
|
18
|
+
class?: string;
|
|
19
|
+
/** Content */
|
|
20
|
+
children?: Snippet;
|
|
21
|
+
}
|
|
22
|
+
declare const NeonBorder: import("svelte").Component<NeonBorderProps, {}, "">;
|
|
23
|
+
type NeonBorder = ReturnType<typeof NeonBorder>;
|
|
24
|
+
export default NeonBorder;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { render, cleanup } from "@testing-library/svelte";
|
|
2
|
+
import { afterEach, describe, it, expect } from "vitest";
|
|
3
|
+
import NeonBorder from "./NeonBorder.svelte";
|
|
4
|
+
describe("NeonBorder", () => {
|
|
5
|
+
afterEach(cleanup);
|
|
6
|
+
it("renders a container div", () => {
|
|
7
|
+
const { container } = render(NeonBorder);
|
|
8
|
+
const wrapper = container.querySelector(".neon-border-container");
|
|
9
|
+
expect(wrapper).toBeInTheDocument();
|
|
10
|
+
});
|
|
11
|
+
it("renders two neon layer divs", () => {
|
|
12
|
+
const { container } = render(NeonBorder);
|
|
13
|
+
const layerOne = container.querySelector(".neon-layer-one");
|
|
14
|
+
const layerTwo = container.querySelector(".neon-layer-two");
|
|
15
|
+
expect(layerOne).toBeInTheDocument();
|
|
16
|
+
expect(layerTwo).toBeInTheDocument();
|
|
17
|
+
});
|
|
18
|
+
it('applies animation class when animationType is not "none"', () => {
|
|
19
|
+
const { container } = render(NeonBorder, {
|
|
20
|
+
props: { animationType: "half" },
|
|
21
|
+
});
|
|
22
|
+
const layerOne = container.querySelector(".neon-layer-one");
|
|
23
|
+
expect(layerOne?.className).toContain("neon-animated");
|
|
24
|
+
});
|
|
25
|
+
it('does not apply animation class when animationType is "none"', () => {
|
|
26
|
+
const { container } = render(NeonBorder, {
|
|
27
|
+
props: { animationType: "none" },
|
|
28
|
+
});
|
|
29
|
+
const layerOne = container.querySelector(".neon-layer-one");
|
|
30
|
+
expect(layerOne?.className).not.toContain("neon-animated");
|
|
31
|
+
});
|
|
32
|
+
it("sets CSS custom properties from props", () => {
|
|
33
|
+
const { container } = render(NeonBorder, {
|
|
34
|
+
props: { color1: "#ff0000", color2: "#00ff00", duration: 10 },
|
|
35
|
+
});
|
|
36
|
+
const wrapper = container.querySelector(".neon-border-container");
|
|
37
|
+
const style = wrapper.getAttribute("style") ?? "";
|
|
38
|
+
expect(style).toContain("--neon-color1: #ff0000");
|
|
39
|
+
expect(style).toContain("--neon-color2: #00ff00");
|
|
40
|
+
expect(style).toContain("--neon-duration: 10s");
|
|
41
|
+
});
|
|
42
|
+
it("sets neon-width to 50% for half animation type", () => {
|
|
43
|
+
const { container } = render(NeonBorder, {
|
|
44
|
+
props: { animationType: "half" },
|
|
45
|
+
});
|
|
46
|
+
const wrapper = container.querySelector(".neon-border-container");
|
|
47
|
+
const style = wrapper.getAttribute("style") ?? "";
|
|
48
|
+
expect(style).toContain("--neon-width: 50%");
|
|
49
|
+
});
|
|
50
|
+
it("sets neon-width to 100% for full animation type", () => {
|
|
51
|
+
const { container } = render(NeonBorder, {
|
|
52
|
+
props: { animationType: "full" },
|
|
53
|
+
});
|
|
54
|
+
const wrapper = container.querySelector(".neon-border-container");
|
|
55
|
+
const style = wrapper.getAttribute("style") ?? "";
|
|
56
|
+
expect(style).toContain("--neon-width: 100%");
|
|
57
|
+
});
|
|
58
|
+
it("sets neon-width to 12% for none animation type", () => {
|
|
59
|
+
const { container } = render(NeonBorder, {
|
|
60
|
+
props: { animationType: "none" },
|
|
61
|
+
});
|
|
62
|
+
const wrapper = container.querySelector(".neon-border-container");
|
|
63
|
+
const style = wrapper.getAttribute("style") ?? "";
|
|
64
|
+
expect(style).toContain("--neon-width: 12%");
|
|
65
|
+
});
|
|
66
|
+
it("applies custom class names", () => {
|
|
67
|
+
const { container } = render(NeonBorder, {
|
|
68
|
+
props: { class: "custom-neon" },
|
|
69
|
+
});
|
|
70
|
+
const wrapper = container.querySelector(".neon-border-container");
|
|
71
|
+
expect(wrapper?.className).toContain("custom-neon");
|
|
72
|
+
});
|
|
73
|
+
it("preserves base classes when custom class is added", () => {
|
|
74
|
+
const { container } = render(NeonBorder, { props: { class: "extra" } });
|
|
75
|
+
const wrapper = container.querySelector(".neon-border-container");
|
|
76
|
+
expect(wrapper?.className).toContain("relative");
|
|
77
|
+
expect(wrapper?.className).toContain("overflow-hidden");
|
|
78
|
+
expect(wrapper?.className).toContain("rounded-lg");
|
|
79
|
+
});
|
|
80
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# NeonBorder
|
|
2
|
+
|
|
3
|
+
Dual-color neon glow border effect. Two gradient layers with blur and drop-shadow create a bicolor neon effect with optional rotation animation.
|
|
4
|
+
|
|
5
|
+
## Props
|
|
6
|
+
|
|
7
|
+
| Prop | Type | Default | Description |
|
|
8
|
+
| ---------------- | ------------------------------- | ----------- | ---------------------------------- |
|
|
9
|
+
| `color1` | `string` | `'#0496ff'` | First neon color |
|
|
10
|
+
| `color2` | `string` | `'#ff0a54'` | Second neon color |
|
|
11
|
+
| `animationType` | `'none' \| 'half' \| 'full'` | `'half'` | Animation coverage type |
|
|
12
|
+
| `duration` | `number` | `6` | Animation duration in seconds |
|
|
13
|
+
| `class` | `string` | `''` | Additional CSS classes |
|
|
14
|
+
|
|
15
|
+
## Slots
|
|
16
|
+
|
|
17
|
+
- **default** — Content rendered inside the neon border
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```svelte
|
|
22
|
+
<NeonBorder color1="#0496ff" color2="#ff0a54" animationType="half">
|
|
23
|
+
<div class="bg-background rounded-lg px-4 py-2 text-center">
|
|
24
|
+
Neon content
|
|
25
|
+
</div>
|
|
26
|
+
</NeonBorder>
|
|
27
|
+
```
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/**
|
|
3
|
+
* NumberTicker - Animated number counter
|
|
4
|
+
*
|
|
5
|
+
* Animates a number from 0 to `value` (or vice versa) with easing.
|
|
6
|
+
* Triggers when the element enters the viewport via IntersectionObserver.
|
|
7
|
+
* Formatted using Intl.NumberFormat.
|
|
8
|
+
*/
|
|
9
|
+
export interface NumberTickerProps {
|
|
10
|
+
/** Target number to animate to */
|
|
11
|
+
value?: number;
|
|
12
|
+
/** Animation direction: "up" counts 0→value, "down" counts value→0 */
|
|
13
|
+
direction?: "up" | "down";
|
|
14
|
+
/** Animation duration in ms */
|
|
15
|
+
duration?: number;
|
|
16
|
+
/** Delay before animation starts (ms) */
|
|
17
|
+
delay?: number;
|
|
18
|
+
/** Number of decimal places to display */
|
|
19
|
+
decimalPlaces?: number;
|
|
20
|
+
/** Additional CSS classes */
|
|
21
|
+
class?: string;
|
|
22
|
+
}
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<script lang="ts">
|
|
26
|
+
import { cn } from "../../utils.js";
|
|
27
|
+
import { onMount } from "svelte";
|
|
28
|
+
|
|
29
|
+
let {
|
|
30
|
+
value = 0,
|
|
31
|
+
direction = "up",
|
|
32
|
+
duration = 1000,
|
|
33
|
+
delay = 0,
|
|
34
|
+
decimalPlaces = 0,
|
|
35
|
+
class: className,
|
|
36
|
+
}: NumberTickerProps = $props();
|
|
37
|
+
|
|
38
|
+
let spanRef: HTMLSpanElement;
|
|
39
|
+
let initialValue = $derived(direction === "down" ? value : 0);
|
|
40
|
+
let displayValue = $state(0);
|
|
41
|
+
let hasAnimated = false;
|
|
42
|
+
let animationFrameId: number | null = null;
|
|
43
|
+
|
|
44
|
+
// Set initial display value
|
|
45
|
+
$effect(() => {
|
|
46
|
+
if (!hasAnimated) {
|
|
47
|
+
displayValue = initialValue;
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// Easing: easeOutCubic
|
|
52
|
+
function easeOutCubic(t: number): number {
|
|
53
|
+
return 1 - Math.pow(1 - t, 3);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function animate(target: number) {
|
|
57
|
+
const start = displayValue;
|
|
58
|
+
const startTime = performance.now() + delay;
|
|
59
|
+
|
|
60
|
+
function tick(now: number) {
|
|
61
|
+
if (now < startTime) {
|
|
62
|
+
animationFrameId = requestAnimationFrame(tick);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const elapsed = now - startTime;
|
|
66
|
+
const progress = Math.min(elapsed / duration, 1);
|
|
67
|
+
const easedProgress = easeOutCubic(progress);
|
|
68
|
+
|
|
69
|
+
displayValue = start + (target - start) * easedProgress;
|
|
70
|
+
|
|
71
|
+
if (progress < 1) {
|
|
72
|
+
animationFrameId = requestAnimationFrame(tick);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
animationFrameId = requestAnimationFrame(tick);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
let formattedValue = $derived(
|
|
80
|
+
new Intl.NumberFormat("en-US", {
|
|
81
|
+
minimumFractionDigits: decimalPlaces,
|
|
82
|
+
maximumFractionDigits: decimalPlaces,
|
|
83
|
+
}).format(Number(displayValue.toFixed(decimalPlaces)))
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
onMount(() => {
|
|
87
|
+
const observer = new IntersectionObserver(
|
|
88
|
+
(entries) => {
|
|
89
|
+
if (entries[0]?.isIntersecting && !hasAnimated) {
|
|
90
|
+
hasAnimated = true;
|
|
91
|
+
const target = direction === "down" ? 0 : value;
|
|
92
|
+
animate(target);
|
|
93
|
+
observer.disconnect();
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
{ threshold: 0 }
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
observer.observe(spanRef);
|
|
100
|
+
|
|
101
|
+
return () => {
|
|
102
|
+
observer.disconnect();
|
|
103
|
+
if (animationFrameId) cancelAnimationFrame(animationFrameId);
|
|
104
|
+
};
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Re-animate when value prop changes after initial animation
|
|
108
|
+
let animTarget = $derived(direction === "down" ? 0 : value);
|
|
109
|
+
$effect(() => {
|
|
110
|
+
// Access derived to track changes
|
|
111
|
+
const target = animTarget;
|
|
112
|
+
if (hasAnimated) {
|
|
113
|
+
animate(target);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
</script>
|
|
117
|
+
|
|
118
|
+
<span
|
|
119
|
+
bind:this={spanRef}
|
|
120
|
+
class={cn(
|
|
121
|
+
"number-ticker inline-block tracking-wider text-black tabular-nums dark:text-white",
|
|
122
|
+
className
|
|
123
|
+
)}
|
|
124
|
+
>
|
|
125
|
+
{formattedValue}
|
|
126
|
+
</span>
|