Flashy Card
scrollxui/flashy-cardFreeComponent
Interactive card with smooth animated activation and visual effects.
Live preview
live · rendered by the registry
Rendered by scrollxui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://scrollxui.dev/registry/flashy-card.jsonSource
1'use client';2import React, { useState, useRef, useEffect } from 'react';3import { cn } from '@/lib/utils';45interface FlashyCardProps extends React.HTMLAttributes<HTMLDivElement> {6 children?: React.ReactNode;7 onStateChange?: (isActive: boolean) => void;8 disabled?: boolean;9 iconClassName?: string;10 rippleClassName?: string;11 glareClassName?: string;12 defaultSrc?: string;13 activeSrc?: string;14 activeType?: 'image' | 'video';15}1617interface FlashyCardContentProps {18 children: React.ReactNode;19}2021const FlashyCardDefault: React.FC<FlashyCardContentProps> = ({ children }) => {22 return <>{children}</>;23};2425const FlashyCardActive: React.FC<FlashyCardContentProps> = ({ children }) => {26 return <>{children}</>;27};2829const FlashyCard = React.forwardRef<HTMLDivElement, FlashyCardProps>(30 (31 {32 children,33 className,34 onStateChange,35 disabled = false,36 iconClassName,37 rippleClassName,38 glareClassName,39 defaultSrc,40 activeSrc,41 activeType,42 ...props43 },44 ref,45 ) => {46 const [isSelected, setIsSelected] = useState(false);47 const [isButtonHovered, setIsButtonHovered] = useState(false);48 const [isAnimating, setIsAnimating] = useState(false);49 const [videoReady, setVideoReady] = useState(false);50 const glareRef = useRef<HTMLDivElement>(null);51 const cardRef = useRef<HTMLDivElement>(null);52 const videoRef = useRef<HTMLVideoElement>(null);5354 React.useImperativeHandle(ref, () => cardRef.current as HTMLDivElement);5556 const childArray = React.Children.toArray(children);57 const defaultContentChild = childArray.find(58 (child) =>59 React.isValidElement(child) && child.type === FlashyCardDefault,60 );61 const activeContentChild = childArray.find(62 (child) => React.isValidElement(child) && child.type === FlashyCardActive,63 );6465 const defaultContent =66 defaultContentChild ||67 (defaultSrc && (68 <div className='aspect-4/3 relative'>69 <img70 src={defaultSrc}71 alt='Default content'72 className='w-full h-full object-cover'73 />74 </div>75 ));7677 const isVideo = (src: string) => {78 const videoExtensions = ['.mp4', '.webm', '.ogg', '.mov'];79 return videoExtensions.some((ext) => src.toLowerCase().endsWith(ext));80 };8182 const shouldShowVideo =83 activeType === 'video' ||84 (!activeType && activeSrc && isVideo(activeSrc));8586 useEffect(() => {87// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from scrollxui
All 180 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | scrollxui | Components | Free | 4 deps | |
| Alert Dialogalert-dialog | scrollxui | Components | Free | 7 deps | |
| Animated Buttonanimated-button | scrollxui | Components | Free | 4 deps | |
| Animated Tabsanimated-tabs | scrollxui | Components | Free | 1 dep | |
| Animated Testimonialsanimated-testimonials | scrollxui | Components | Free | 2 deps | |
| Animated TextGenerateanimated-textgenerate | scrollxui | Components | Free | 3 deps | |
| Announcementannouncement | scrollxui | Components | Free | 5 deps | |
| Aspect Ratioaspect-ratio | scrollxui | Components | Free | 1 dep |
