# SmoothUI Component Catalog > For structured JSON data, see: https://smoothui.dev/llms-components.json ## Components (57) - agent-avatar: Canvas-based generative pixel avatar for AI agents, unique per seed. [ai] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/agent-avatar.json - ai-branch: An interactive AI branch component for displaying conversation flows. [ai] (complex) — install: npx shadcn@latest add https://smoothui.dev/r/ai-branch.json - ai-input: A AiInput component for SmoothUI. [ai] (complex) — install: npx shadcn@latest add https://smoothui.dev/r/ai-input.json - animated-avatar-group: Stack of overlapping avatars with smooth expand/collapse animation [data-display] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/animated-avatar-group.json - animated-input: A AnimatedInput component for SmoothUI. [basic-ui] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/animated-input.json - animated-o-t-p-input: A AnimatedOTPInput component for SmoothUI. [basic-ui] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/animated-o-t-p-input.json - animated-progress-bar: A AnimatedProgressBar component for SmoothUI. [basic-ui] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/animated-progress-bar.json - animated-tabs: Animated tabs component with sliding indicator [basic-ui] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/animated-tabs.json - animated-tags: A AnimatedTags component for SmoothUI. [basic-ui] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/animated-tags.json - animated-toggle: Animated toggle switch with morph and icon variants [basic-ui] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/animated-toggle.json - animated-tooltip: Spring-animated tooltip with multiple placement options [basic-ui] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/animated-tooltip.json - app-download-stack: A AppDownloadStack component for SmoothUI. [other] (complex) — install: npx shadcn@latest add https://smoothui.dev/r/app-download-stack.json - apple-invites: A AppleInvites component for SmoothUI. [other] (complex) — install: npx shadcn@latest add https://smoothui.dev/r/apple-invites.json - basic-accordion: A BasicAccordion component for SmoothUI. [basic-ui] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/basic-accordion.json - basic-dropdown: A BasicDropdown component for SmoothUI. [basic-ui] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/basic-dropdown.json - basic-modal: A BasicModal component for SmoothUI. [basic-ui] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/basic-modal.json - basic-toast: A BasicToast component for SmoothUI. [feedback] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/basic-toast.json - book: A 3D CSS book component with perspective transforms and hover animation [other] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/book.json - button-copy: A ButtonCopy component for SmoothUI. [button] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/button-copy.json - clip-corners-button: A ClipCornersButton component for SmoothUI. [button] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/clip-corners-button.json - contribution-graph: A ContributionGraph component for SmoothUI. [data-display] (complex) — install: npx shadcn@latest add https://smoothui.dev/r/contribution-graph.json - cursor-follow: A CursorFollow component for SmoothUI. [other] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/cursor-follow.json - dot-morph-button: A DotMorphButton component for SmoothUI. [button] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/dot-morph-button.json - dynamic-island: A DynamicIsland component for SmoothUI. [other] (complex) — install: npx shadcn@latest add https://smoothui.dev/r/dynamic-island.json - expandable-cards: A ExpandableCards component for SmoothUI. [layout] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/expandable-cards.json - exposure-slider: iOS-style exposure slider with draggable ticker and progress ring [other] (complex) — install: npx shadcn@latest add https://smoothui.dev/r/exposure-slider.json - figma-comment: A FigmaComment component for SmoothUI. [other] (complex) — install: npx shadcn@latest add https://smoothui.dev/r/figma-comment.json - github-stars-animation: A GitHubStarsAnimation component for SmoothUI. [data-display] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/github-stars-animation.json - glow-hover-card: A GlowHoverCards component for SmoothUI. [layout] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/glow-hover-card.json - gooey-popover: A GooeyPopover component for SmoothUI. [other] (complex) — install: npx shadcn@latest add https://smoothui.dev/r/gooey-popover.json - grid-loader: 3x3 grid-based loading animation with preset patterns [feedback] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/grid-loader.json - image-metadata-preview: A ImageMetadataPreview component for SmoothUI. [data-display] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/image-metadata-preview.json - infinite-slider: A InfiniteSlider component for SmoothUI. [other] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/infinite-slider.json - interactive-image-selector: A InteractiveImageSelector component for SmoothUI. [other] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/interactive-image-selector.json - job-listing-component: A JobListingComponent component for SmoothUI. [layout] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/job-listing-component.json - magnetic-button: Button that subtly follows the cursor with magnetic effect [button] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/magnetic-button.json - notification-badge: Animated notification badge with count and status variants [basic-ui] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/notification-badge.json - number-flow: A NumberFlow component for SmoothUI. [data-display] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/number-flow.json - phototab: A Phototab component for SmoothUI. [other] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/phototab.json - power-off-slide: A PowerOffSlide component for SmoothUI. [other] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/power-off-slide.json - price-flow: A PriceFlow component for SmoothUI. [data-display] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/price-flow.json - reveal-text: A RevealText component for SmoothUI. [text] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/reveal-text.json - reviews-carousel: A ReviewsCarousel component for SmoothUI. [data-display] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/reviews-carousel.json - rich-popover: A RichPopover component for SmoothUI. [basic-ui] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/rich-popover.json - scramble-hover: A ScrambleHover component for SmoothUI. [text] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/scramble-hover.json - scroll-reveal-paragraph: A ScrollRevealParagraph component for SmoothUI. [text] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/scroll-reveal-paragraph.json - scrollable-card-stack: A ScrollableCardStack component for SmoothUI. [layout] (complex) — install: npx shadcn@latest add https://smoothui.dev/r/scrollable-card-stack.json - scrubber: Design-tool style scrubber slider with animated thumb and built-in label [basic-ui] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/scrubber.json - searchable-dropdown: A SearchableDropdown component for SmoothUI. [basic-ui] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/searchable-dropdown.json - siri-orb: A beautiful animated orb component inspired by Siri's visual design. [ai] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/siri-orb.json - skeleton-loader: Animated skeleton loading placeholders [basic-ui] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/skeleton-loader.json - social-selector: A SocialSelector component for SmoothUI. [other] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/social-selector.json - switchboard-card: A SwitchboardCard component with light grid illustration for SmoothUI. [other] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/switchboard-card.json - tweet-card: A beautiful tweet card component for displaying Twitter/X posts. [data-display] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/tweet-card.json - typewriter-text: A TypewriterText component for SmoothUI. [text] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/typewriter-text.json - user-account-avatar: A UserAccountAvatar component for SmoothUI. [other] (complex) — install: npx shadcn@latest add https://smoothui.dev/r/user-account-avatar.json - wave-text: A WaveText component for SmoothUI. [text] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/wave-text.json ## Blocks (26) - faq-1: FAQ grid block with categorized tabs and icons [layout] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/faq-1.json - faq-2: FAQ accordion block with expandable questions [layout] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/faq-2.json - faq-3: Searchable FAQ section with filter animations [layout] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/faq-3.json - faq-4: Categorized FAQ section with tab navigation [layout] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/faq-4.json - footer-1: Simple footer block with links and social icons [layout] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/footer-1.json - footer-2: Complex footer block with newsletter and extended links [layout] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/footer-2.json - footer-3: Mega footer with newsletter and social links [layout] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/footer-3.json - footer-4: Minimal single-row footer [layout] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/footer-4.json - header-1: Modern header block with navigation and mobile menu [layout] (complex) — install: npx shadcn@latest add https://smoothui.dev/r/header-1.json - header-2: Premium header block with gradient logo and smooth animations [layout] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/header-2.json - header-3: Premium header block with gradient logo and smooth animations [layout] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/header-3.json - header-4: Interactive 3D grid hero header inspired by rauno.me 2024 [layout] (complex) — install: npx shadcn@latest add https://smoothui.dev/r/header-4.json - logo-cloud-1: Simple logo cloud block with grid layout [layout] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/logo-cloud-1.json - logo-cloud-2: Animated logo cloud block with infinite scroll [layout] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/logo-cloud-2.json - logo-cloud-3: Infinite scrolling logo marquee [layout] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/logo-cloud-3.json - logo-cloud-4: Interactive logo grid with hover effects [layout] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/logo-cloud-4.json - pricing-1: Simple pricing block with single plan [layout] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/pricing-1.json - pricing-2: Modern pricing block with three tiers [layout] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/pricing-2.json - pricing-3: Creative pricing block with two plans [layout] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/pricing-3.json - stats-1: Grid stats section block with hover effects [layout] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/stats-1.json - stats-2: Cards stats section block with icons and trends [layout] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/stats-2.json - team-1: Grid team section block with hover effects [layout] (simple) — install: npx shadcn@latest add https://smoothui.dev/r/team-1.json - team-2: Carousel team section block with auto-play [layout] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/team-2.json - testimonials-1: Simple testimonials block with auto-rotating cards [layout] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/testimonials-1.json - testimonials-2: Grid testimonials block with navigation arrows [layout] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/testimonials-2.json - testimonials-3: Star testimonials block with grid layout [layout] (moderate) — install: npx shadcn@latest add https://smoothui.dev/r/testimonials-3.json --- # FAQs Blocks (/docs/blocks/faqs) # FAQs Blocks FAQ blocks help answer common questions and provide helpful information to your users. ## FAQ Grid A categorized FAQ section with tabs, icons, and animated transitions between categories. ### Installation ## FAQ Accordion An expandable accordion-style FAQ section with smooth animations and clean design. ### Installation ## FAQ Searchable A searchable FAQ section with real-time filtering and animated results. ### Installation ## FAQ Categorized A categorized FAQ section with animated tab navigation to switch between topics. ### Installation # Footer Blocks (/docs/blocks/footer) # Footer Blocks Footer blocks provide essential navigation, links, and company information for your website. ## Footer Simple A clean footer with company info, organized link sections, and social media icons. ### Installation ## Footer Complex A comprehensive footer with newsletter subscription, extended link sections, and additional social media options. ### Installation ## Footer Mega A comprehensive mega footer with multiple link columns, newsletter signup, and social media links. ### Installation ## Footer Minimal A clean, minimal single-row footer with logo, essential links, and social icons. ### Installation # Hero Blocks (/docs/blocks/hero) # Hero Blocks Hero blocks are eye-catching landing sections designed to grab attention and communicate your value proposition effectively. ## Hero Grid A modern hero section with an interactive animated grid background and smooth text animations. ### Installation ## Hero Product A premium product hero section with badge, animated headings, and product image showcase. ### Installation ## Hero Block 3 Coming soon - another beautiful hero block variation. ### Installation ## Hero Grid 3D An interactive 3D grid hero section inspired by rauno.me 2024. Features a perspective-transformed grid with customizable hover colors that respond to user interaction. ### Installation # UI Blocks (/docs/blocks) ## Basic Information About Blocks Copy the component code directly from any block page, or import from the package: ```tsx import { Header1, Pricing1, Testimonials1 } from "@repo/smoothui/blocks"; export default function LandingPage() { return ( <> ); } ``` ## Customization All blocks use Tailwind CSS and can be customized via: * Tailwind utility classes * CSS variables for theming * Component props for behavior Replace placeholder content and adjust colors, spacing, and animations to match your brand. # Logo Clouds Blocks (/docs/blocks/logo-clouds) # Logo Clouds Blocks Logo clouds blocks showcase your partners and customers with beautiful layouts and smooth animations. ## Logo Cloud Simple A clean grid layout for displaying company logos with hover effects and customizable count. ### Installation ## Logo Cloud Animated An infinite scrolling logo cloud with smooth animations and hover interactions, perfect for showcasing multiple partners. ### Installation ## Logo Marquee An infinite scrolling logo marquee that smoothly loops. Pauses on hover for closer inspection. ### Installation ## Logo Grid An interactive logo grid where logos come to life on hover with colorization and lift effects. ### Installation # Pricing Blocks (/docs/blocks/pricing) # Pricing Blocks Pricing blocks showcase your pricing plans with animated transitions and beautiful layouts. ## Pricing Simple A clean single-tier pricing section with animated price transitions and annual/monthly toggle. ### Installation ## Pricing Modern A modern three-tier pricing section with featured plan highlighting and gradient accents. ### Installation ## Pricing Creative A creative two-plan pricing section inspired by Vercel, perfect for SaaS products. ### Installation # Stats Blocks (/docs/blocks/stats) # Stats Blocks Stats blocks showcase key metrics and numbers with beautiful animations and layouts. ## Stats Grid A clean grid layout with hover effects and scale animations for displaying your key statistics. ### Installation ## Stats Cards Enhanced stats cards with icons, trend indicators, and gradient hover effects. ### Installation # Team Sections Blocks (/docs/blocks/team-sections) # Team Sections Blocks Team sections blocks showcase your team members with beautiful layouts and smooth animations. ## Team Grid A responsive grid layout with hover effects and smooth animations for displaying team members. ### Installation ## Team Carousel An interactive carousel with auto-play functionality and navigation arrows for showcasing your team. ### Installation # Testimonial Blocks (/docs/blocks/testimonial) # Testimonial Blocks Testimonial blocks are eye-catching landing sections designed to showcase customer feedback, reviews, and testimonials effectively. ## Testimonials Simple A modern testimonials section with auto-rotating cards, smooth transitions, and progress indicators. ### Installation ## Testimonials Grid A premium testimonials section with navigation arrows, animated word reveals, and beautiful card layouts. ### Installation ## Testimonials Stars A grid-based testimonials section with star ratings, hover effects, and staggered animations. ### Installation # Community (/docs/community) ## Join the SmoothUI Community SmoothUI is built by and for the community. Whether you have an idea for a new component, want to show off what you have built, or just want to connect with fellow developers, there is a place for you.
## Get Involved Learn how to submit a well-structured component request via GitHub Discussions. See what others have built with SmoothUI and submit your own project. Join the conversation, ask questions, and share ideas with the community. Want to contribute code? Read the contributing guide to get started. # Request a Component (/docs/community/request) ## How to Request a Component We love hearing from the community! If there is an animated component you would like to see in SmoothUI, you can submit a request through GitHub Discussions or by opening a GitHub Issue using our component request template. **GitHub Discussions** is great for open-ended ideas and gathering community feedback. **GitHub Issues** with our component request template is better for well-defined component proposals ready for implementation. ## Writing a Good Request A well-structured request helps us understand your needs and prioritize effectively. Here is what to include:
### Component Name Give your component a clear, descriptive name. Think about what it does or how it looks. > **Example:** "Magnetic Dock" or "Animated Tabs with Sliding Indicator"
### Description Explain what the component does, how it behaves, and what makes it unique. Be specific about the animations and interactions you envision.
### Use Case Describe the real-world scenario where this component would be useful. This helps us understand the value and prioritize accordingly.
### Inspiration or Reference If you have seen something similar on another website or in another library, share a link. Visual references are incredibly helpful. Screenshots, videos, or CodePen links are all welcome.
### Priority Level Let us know how important this component is to your workflow: | Priority | Description | | ------------------ | ---------------------------------------------------------------------- | | **Nice to have** | Would be a cool addition, but not blocking anything | | **Would be great** | Would significantly improve your project | | **Critical** | You need this component for a project and there is no good alternative |
## Submit Your Request Start a discussion to propose your idea and get community feedback. Great for brainstorming and open-ended ideas. Use our structured template to submit a well-defined component request ready for implementation. ## What Happens Next After you submit a request: 1. **Community feedback** — Other users can upvote and comment on your request. Requests with more community interest get prioritized. 2. **Triage** — Maintainers review requests regularly and label them for tracking. 3. **Implementation** — Accepted components are added to the roadmap and implemented. 4. **Release** — Once built and tested, the component ships in the next release and appears in the docs. Upvote existing requests that you would also like to see. Community interest is one of the strongest signals for prioritization. # Showcase (/docs/community/showcase) ## Community Showcase See what developers around the world are building with SmoothUI. From personal portfolios to production applications, these projects showcase the creative possibilities of smooth, animated interfaces. This showcase is just getting started. We would love to feature your project here! Submit your project below and help inspire the community. ## Submit Your Project Built something with SmoothUI? We want to see it! Share your project with the community through GitHub Discussions. ### What to Include When submitting your project, please provide: * **Project name** — The name of your project or website * **URL** — A live link where others can see it in action * **Screenshot** — A screenshot or preview image of your project * **Description** — A brief description of the project and which SmoothUI components you used * **Tech stack** — The frameworks and tools you used alongside SmoothUI Share your project in the "Show and Tell" category. Include a screenshot, link, and description of the SmoothUI components you used. ## Featured Projects No projects featured yet. Yours could be the first! Submit your project through GitHub Discussions and we will add it here. # Accordion (/docs/components/accordion) ## Features * Collapsible content sections * Keyboard navigation support * Customizable styling * Single or multiple item selection * Smooth animations * Built on Radix UI Accordion ## Accessibility ### Keyboard Interactions | Key | Description | | ----------------- | ------------------------------------------------- | | `Tab` | Moves focus to the next accordion header button | | `Enter` / `Space` | Toggles the focused accordion item open or closed | ### ARIA Attributes | Attribute | Element | Purpose | | ----------------- | -------------- | ----------------------------------------------------------- | | `aria-expanded` | Header button | Indicates whether the associated section is open or closed | | `aria-controls` | Header button | References the `id` of the collapsible content region | | `aria-labelledby` | Content region | References the `id` of the header button that controls it | | `role="region"` | Content panel | Identifies the expandable content area as a landmark region | ### Screen Reader * Each header button announces its expanded or collapsed state * Content regions are associated with their header via `aria-labelledby` ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, expand/collapse and chevron rotation animations are disabled instantly. ## Props # Agent Avatar (/docs/components/agent-avatar) ## Features * Deterministic pixel patterns generated from a seed string * Animated color oscillation with per-pixel phase offsets * Retina-ready with `devicePixelRatio` scaling * Circular clipping with outer glow * Respects `prefers-reduced-motion` ## Accessibility ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `window.matchMedia`. When reduced motion is preferred, canvas animations are stopped and a single static frame is rendered instead. ### ARIA The `` element includes `role="img"` and an `aria-label` derived from the `seed` prop, ensuring screen readers announce the avatar meaningfully. ## Props # AI Branch (/docs/components/ai-branch) ## Features * Smooth animated transitions * Interactive branch elements * Customizable animations * Responsive design * Built with Framer Motion * AI-themed visual elements ## Accessibility ### Keyboard Interactions | Key | Description | | ----- | --------------------------------------------------------- | | Click | Navigate between branches using the previous/next buttons | ### ARIA Attributes | Attribute | Element | Purpose | | ------------------------------ | ------------------ | ------------------------------------------------- | | `aria-label="Previous branch"` | Previous button | Identifies the previous branch navigation button | | `aria-label="Next branch"` | Next button | Identifies the next branch navigation button | | `aria-label="Copy message"` | Copy button | Identifies the copy action button | | `aria-label="Edit message"` | Edit button | Identifies the edit action button | | `type="button"` | All buttons | Prevents implicit form submission | | `disabled` | Navigation buttons | Disables navigation when there is only one branch | ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, branch transition animations are disabled and all button scale effects are removed. ## Props # AI Input (/docs/components/ai-input) ## Features * Supports commands and inline hints * Keyboard shortcuts and focus states * Clear/submit actions built-in * Smooth micro-interactions * Accessible and themable ## Accessibility ### Keyboard Interactions | Key | Description | | ------------- | ---------------------------------------------------- | | `Escape` | Closes the feedback textarea and returns to the dock | | `Cmd + Enter` | Submits the feedback form | ### Screen Reader * The submit shortcut is visually indicated with `` elements showing the key combination ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, all morph, fade, and layout animations are disabled instantly. # Animated Avatar Group (/docs/components/animated-avatar-group) ## Features * Overlapping avatar stack with smooth expand animation * Staggered spring animations on hover * Configurable max visible count with "+N" indicator * Adjustable size and overlap * Hover device detection * Respects reduced motion preferences * Optional link support per avatar ## Accessibility ### ARIA Attributes | Attribute | Element | Purpose | | --------------------------- | ------------ | -------------------------------------------------------- | | `role="group"` | Container | Groups the avatars semantically | | `aria-label="Avatar group"` | Container | Labels the avatar group for screen readers | | `aria-label` | Avatar links | Uses the avatar's `alt` text to label each linked avatar | ### Screen Reader * Each avatar image includes an `alt` attribute from the `AvatarData` configuration. * Linked avatars include `rel="noopener"` for security. * The "+N" overflow indicator conveys the number of hidden avatars. ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, all spring animations, scale effects, and stagger delays are disabled. The component also detects hover-capable devices and only applies hover animations on pointer-fine devices. ## Props # Animated Input (/docs/components/animated-input) ## Features * Smooth focus animations * Floating label support * Visual feedback on interaction * Customizable animation timing * Built with Framer Motion * Accessible form input ## Accessibility ### ARIA Attributes | Attribute | Element | Purpose | | -------------------- | -------------- | --------------------------------------------------- | | `aria-label` | Input | Provides an accessible name matching the label text | | `aria-hidden="true"` | Icon container | Hides the decorative icon from screen readers | ### Screen Reader * The floating label is programmatically associated with the input via `htmlFor` and `id` * The `aria-label` attribute provides an accessible name for assistive technologies ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the floating label transitions are applied instantly without animation. ## Props # Animated OTP Input (/docs/components/animated-o-t-p-input) ## Features * Auto-advance and backspace support * Animated focus and validation * Masking options * Accessible and mobile-friendly ## Accessibility ### Keyboard Interactions | Key | Description | | ----------- | -------------------------------------------------------------- | | `0-9` | Enters a digit and auto-advances to the next slot | | `Backspace` | Deletes the current digit and moves focus to the previous slot | | `Tab` | Moves focus to/from the OTP input | ### ARIA Attributes | Attribute | Element | Purpose | | ------------------ | --------- | ------------------------------------------------------------------- | | `aria-label` | OTP input | Provides an accessible name (defaults to "One-time password input") | | `aria-describedby` | OTP input | References an optional description element for additional context | ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, slot entrance animations, digit flip transitions, and the blinking caret are all disabled. ## Props # Animated Progress Bar (/docs/components/animated-progress-bar) ## Features * Smooth progress animations * Customizable colors and styling * Multiple animation types * Built with Framer Motion * Responsive design * Accessibility support ## Accessibility ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the progress bar value changes instantly without animation. ## Props # Animated Tabs (/docs/components/animated-tabs) ## Features * Three variants: underline, pill, and segment * Smooth sliding indicator animation * Controlled and uncontrolled modes * Support for icons in tabs * Full keyboard navigation * Accessible with proper ARIA attributes * Respects reduced motion preferences ## Accessibility ### Keyboard Interactions | Key | Description | | ------------- | ------------------------------------------------------------- | | `Arrow Right` | Moves focus and selection to the next tab (wraps to first) | | `Arrow Left` | Moves focus and selection to the previous tab (wraps to last) | | `Home` | Moves focus and selection to the first tab | | `End` | Moves focus and selection to the last tab | ### ARIA Attributes | Attribute | Element | Purpose | | ------------------- | ---------- | --------------------------------------------------------------- | | `role="tablist"` | Container | Identifies the tab group as a tablist | | `aria-label="Tabs"` | Container | Provides an accessible name for the tablist | | `role="tab"` | Tab button | Identifies each button as a tab | | `aria-selected` | Tab button | Indicates which tab is currently active | | `tabindex` | Tab button | Uses roving tabindex: active tab is `0`, inactive tabs are `-1` | ### Screen Reader * Only the active tab is in the tab order; arrow keys navigate between tabs * Each tab announces its selected state via `aria-selected` ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the sliding indicator animation between tabs is disabled instantly. ## Props # Animated Tags (/docs/components/animated-tags) ## Features * Smooth tag animations * Interactive hover effects * Customizable tag styling * Built with Framer Motion * Responsive layout * Add/remove animations ## Accessibility ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, tag add/remove slide and blur animations are disabled, and tags appear/disappear instantly. ## Props # Animated Toggle (/docs/components/animated-toggle) ## Features * Three variants: default (smooth sliding), morph (shape changes during travel), and icon (transitions between icons) * Three sizes: sm, md, and lg * Controlled and uncontrolled modes * Smooth spring animations with Motion * Icon variant supports custom icons with crossfade and scale transitions * Morph variant animates borderRadius during travel * Full keyboard accessibility (Space/Enter to toggle) * Proper ARIA attributes with role="switch" and aria-checked * Respects reduced motion preferences * Disabled state support ## Accessibility ### Keyboard Interactions | Key | Description | | ------- | ------------------------- | | `Space` | Toggles the switch on/off | | `Enter` | Toggles the switch on/off | ### ARIA Attributes | Attribute | Element | Purpose | | --------------- | ------- | ------------------------------------------------ | | `role="switch"` | Button | Identifies the element as a toggle switch | | `aria-checked` | Button | Reflects the current on/off state | | `aria-label` | Button | Provides an accessible name via the `label` prop | | `disabled` | Button | Indicates when the toggle is non-interactive | ### Screen Reader * The `role="switch"` with `aria-checked` communicates the toggle state to assistive technologies. * Focus is visually indicated with a focus-visible ring style. ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, all spring animations, icon transitions, and morph effects are disabled instantly. ## Props # Animated Tooltip (/docs/components/animated-tooltip) ## Features * Four placement options (top, bottom, left, right) * Spring-animated enter/exit transitions * Keyboard accessible with Escape to dismiss * Hover device detection * Respects reduced motion preferences * Arrow indicator pointing to trigger * Supports rich content via ReactNode * Optional show delay ## Accessibility ### Keyboard Interactions | Key | Description | | -------- | ------------------------------------------------- | | `Escape` | Dismisses the tooltip when focused | | `Tab` | Focus/blur on the trigger shows/hides the tooltip | ### ARIA Attributes | Attribute | Element | Purpose | | -------------------- | --------------- | ------------------------------------------------------------ | | `role="tooltip"` | Tooltip content | Identifies the element as a tooltip | | `aria-describedby` | Trigger wrapper | Associates the trigger with the tooltip content when visible | | `aria-hidden="true"` | Arrow element | Hides the decorative arrow from screen readers | ### Screen Reader * The tooltip content is linked to the trigger via `aria-describedby` using a unique `useId`-generated ID, so screen readers announce the tooltip text when the trigger is focused. ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the tooltip appears and disappears instantly without spring or slide animations. ## Props # App Download Stack (/docs/components/app-download-stack) ## Features * iOS/Android store badges * Subtle entrance animations * Flexible layout and copy * Responsive and accessible ## Accessibility ### ARIA Attributes | Attribute | Element | Purpose | | ----------------------------------- | --------------- | ------------------------------------------------------ | | `aria-label="Expand app selection"` | Stack button | Labels the collapsed stack trigger for screen readers | | `type="button"` | All buttons | Prevents implicit form submission | | `disabled` | Download button | Disables the download button when no apps are selected | ### Screen Reader * Each app icon includes an `alt` attribute with the app name (e.g., "GitHub Logo"). * The checkmark SVG includes a `title` element for accessibility. * The selected count is displayed visually for sighted users. ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, floating animations, stacked rotation effects, hover interactions, layout animations, and the download shine effect are all disabled. ## Props # Apple Invites (/docs/components/apple-invites) ## Features * Animated add/remove of invitees * Drag and reorder friendly * Presence transitions * Keyboard and screen reader support ## Accessibility ### Screen Reader * Event card images include `alt` text derived from the event title. * Participant avatar images include descriptive `alt` text (e.g., "Participant 1"). ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, card transition spring animations are replaced with instant duration-zero transitions. ## Props # Basic Dropdown (/docs/components/basic-dropdown) ## Features * Toggleable menu with keyboard navigation * Customizable label and items with optional icons * `onChange` callback with selected item * Compact, accessible, and easy to style * Works with any React content ## Accessibility ### Keyboard Interactions | Key | Description | | ----------------- | ---------------------------------------------------------------------------------- | | `Enter` / `Space` | Opens the dropdown when the trigger button is focused, or selects the focused item | | `Escape` | Closes the dropdown and returns focus to the trigger button | | `Arrow Down` | Moves focus to the next item (wraps to first) | | `Arrow Up` | Moves focus to the previous item (wraps to last) | | `Home` | Moves focus to the first item | | `End` | Moves focus to the last item | ### ARIA Attributes | Attribute | Element | Purpose | | ------------------------- | -------------- | ------------------------------------------------------------- | | `aria-expanded` | Trigger button | Indicates whether the dropdown is open or closed | | `aria-haspopup="listbox"` | Trigger button | Indicates the button opens a listbox | | `aria-label` | Trigger button | Provides an accessible name including the selected item label | | `role="option"` | List item | Identifies each item as a selectable option | | `aria-selected` | List item | Indicates the currently selected or focused item | | `aria-label` | Item button | Provides an accessible name for each option | ### Screen Reader * The trigger button announces its expanded/collapsed state and the currently selected value * Each option announces its label and selected state * A checkmark icon includes a `` element for screen readers ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, dropdown open/close, item slide-in, and chevron rotation animations are disabled instantly. ## Props <AutoTypeTable path="../../packages/smoothui/components/basic-dropdown/index.tsx" name="BasicDropdownProps" /> # Basic Modal (/docs/components/basic-modal) ## Features * Controlled `isOpen` and `onClose` props * Title slot and fully custom body content * Size options for common layouts * Focus trap friendly and accessible structure * Composable action area ## Accessibility ### Keyboard Interactions | Key | Description | | ------------- | --------------------------------------------------------------------------- | | `Escape` | Closes the modal | | `Tab` | Cycles focus through focusable elements within the modal (focus is trapped) | | `Shift + Tab` | Cycles focus backward through focusable elements within the modal | ### ARIA Attributes | Attribute | Element | Purpose | | -------------------------- | --------------- | ------------------------------------------------------------ | | `role="dialog"` | Modal container | Identifies the element as a dialog | | `aria-modal="true"` | Modal container | Indicates the dialog is modal and content behind it is inert | | `aria-labelledby` | Modal container | References the modal title for an accessible name | | `aria-label="Close modal"` | Close button | Provides an accessible name for the close button | | `aria-hidden="true"` | Close icon (X) | Hides the decorative icon from screen readers | ### Screen Reader * Focus moves to the close button when the modal opens * Focus is trapped within the modal while open * Focus returns to the previously focused element when the modal closes * The modal title is announced via `aria-labelledby` ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, backdrop fade, modal scale/slide entrance, and close button hover animations are disabled instantly. ## Props <AutoTypeTable path="../../packages/smoothui/components/basic-modal/index.tsx" name="BasicModalProps" /> # Basic Toast (/docs/components/basic-toast) ## Features * Support for success, error, warning, and info types * Configurable message, duration, and manual close * Portals-friendly and stackable design * Minimal styles for easy theming * Accessible announcements ## Accessibility ### Screen Reader * Each toast type (success, error, warning, info) displays a corresponding icon with semantic color for visual distinction * The close button allows manual dismissal of the notification ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the slide-in entrance and exit animations are disabled instantly. ## Props <AutoTypeTable path="../../packages/smoothui/components/basic-toast/index.tsx" name="ToastProps" /> # Book (/docs/components/book) ## Features * 3D perspective with realistic depth and page edges * Hover rotation with scale effect (on pointer devices) * Two variants: `stripe` (color band + white body) and `simple` (full-color cover) * Customizable cover color and text color * Configurable width * Optional illustration and logo slots * Respects reduced motion preferences ## Accessibility ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the hover rotation and scale transition are disabled, and the book renders in its static resting state. ### ARIA Decorative elements such as the spine binding overlays, page edges, and back cover are marked with `aria-hidden` to prevent screen readers from announcing visual-only content. ## Props <AutoTypeTable path="../../packages/smoothui/components/book/index.tsx" name="BookProps" /> # Button Copy (/docs/components/button-copy) ## Features * One-click copy with success state * Optional tooltip and label * Accessible with aria-live * Themable and lightweight ## Accessibility ### ARIA Attributes | Attribute | Element | Purpose | | -------------------- | ------- | ----------------------------------------------------------------------------------- | | `aria-label` | Button | Dynamically updates to reflect the current state: "Copy", "Copying...", or "Copied" | | `aria-live="polite"` | Button | Announces state changes to screen readers without interrupting current speech | ### Screen Reader * State transitions (idle, loading, success) are announced via the `aria-live="polite"` region * The button is automatically disabled during loading and success states to prevent double-clicks ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the icon swap blur and slide animations are disabled instantly. ## Props <AutoTypeTable path="../../packages/smoothui/components/button-copy/index.tsx" name="ButtonCopyProps" /> # Clip Corners Button (/docs/components/clip-corners-button) ## Features * Unique clipped-corners style * Hover/press micro-interactions * Works with icons and labels * Easy theming ## Accessibility ### ARIA Attributes | Attribute | Element | Purpose | | ------------ | ----------- | --------------------------------------------------------------------- | | `aria-label` | Corner SVGs | Each decorative corner triangle has an accessible label and `<title>` | ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the corner triangle hover animations are disabled. The component also detects hover-capable devices and disables hover animations on touch devices. ## Props <AutoTypeTable path="../../packages/smoothui/components/clip-corners-button/index.tsx" name="ClipCornersButtonProps" /> # Contribution Graph (/docs/components/contribution-graph) ## Features * Heatmap cells with tooltips * Animations on load and hover * Custom color scales * Responsive grid ## Accessibility ### ARIA Attributes | Attribute | Element | Purpose | | ----------------- | ----------- | ---------------------------------------------------------------------- | | `caption.sr-only` | Table | Provides a screen-reader-only caption: "Contribution Graph for year" | | `title` | Table cells | Native tooltip with formatted date and contribution count for each day | ### Screen Reader * The component renders as a semantic `table` with `thead`, `tbody`, `caption`, and `td` elements. * Month headers are rendered as table column headers. * Day labels (Sun, Mon, etc.) are displayed in row header cells. * Each day cell includes a `title` attribute with the full date and contribution count. ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the tooltip scale/opacity animation is disabled and appears instantly. ## Props <AutoTypeTable path="../../packages/smoothui/components/contribution-graph/index.tsx" name="ContributionGraphProps" /> # Cursor Follow (/docs/components/cursor-follow) ## Features * Tracks pointer with spring animation * Blend/blur styling options * Performance-aware updates * Easy theming ## Accessibility ### ARIA Attributes | Attribute | Element | Purpose | | -------------------- | --------- | --------------------------------------------------------- | | `role="application"` | Container | Indicates the region is an interactive application widget | | `tabIndex={0}` | Container | Makes the container focusable for keyboard/focus events | ### Screen Reader * The component listens to `onFocus` and `onBlur` events in addition to mouse events, allowing `data-cursor-text` content to be triggered by focus. * The cursor bubble itself is purely decorative and uses `pointer-events: none`, so it does not interfere with assistive technology. ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the cursor bubble appears instantly without scale or opacity entrance animations. The spring-based position tracking still operates via motion values. ## Props <AutoTypeTable path="../../packages/smoothui/components/cursor-follow/index.tsx" name="CursorFollowProps" /> # Dot Morph Button (/docs/components/dot-morph-button) ## Features * Morphing dot animations * States: idle, loading, success * Keyboard and ARIA support * Easy to theme ## Accessibility ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the dot morph hover animation is disabled. The component also detects hover-capable devices and disables the hover effect on touch devices. ## Props <AutoTypeTable path="../../packages/smoothui/components/dot-morph-button/index.tsx" name="DotMorphButtonProps" /> # Dynamic Island (/docs/components/dynamic-island) ## Features * Expand/collapse with spring motion * Queue multiple messages * Supports icons and actions * Accessible announcements ## Accessibility ### ARIA Attributes | Attribute | Element | Purpose | | ------------ | ------------ | ---------------------------------------------------------- | | `aria-label` | View buttons | Describes each view option (e.g., "idle", "ring", "timer") | ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the spring layout transitions and content blur/scale entrance animations are disabled. ## Props <AutoTypeTable path="../../packages/smoothui/components/dynamic-island/index.tsx" name="DynamicIslandProps" /> # Expandable Cards (/docs/components/expandable-cards) ## Features * Expand/collapse with animated layout * Keyboard navigable and accessible * Grid or list layouts supported * Easy theming ## Accessibility ### Keyboard Interactions | Key | Description | | ------- | ------------------------------------------- | | `Enter` | Toggles expand/collapse on the focused card | | `Space` | Toggles expand/collapse on the focused card | | `Tab` | Moves focus between cards | ### ARIA Attributes | Attribute | Element | Purpose | | --------------- | -------------- | --------------------------------------------------------- | | `role="button"` | Card container | Indicates the card is an interactive element | | `aria-label` | Card container | Describes the card title and its expanded/collapsed state | | `aria-selected` | Card container | Indicates which card is currently expanded | | `tabIndex={0}` | Card container | Makes each card focusable | ### Screen Reader * Each card announces its title and whether it is expanded (e.g., "Nature card, expanded"). * The play button inside each card has a descriptive `aria-label` (e.g., "Play video: Nature"). ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, expand/collapse width transitions and content blur animations are disabled. ## Props <AutoTypeTable path="../../packages/smoothui/components/expandable-cards/index.tsx" name="ExpandableCardsProps" /> # Exposure Slider (/docs/components/exposure-slider) ## Features * Draggable ticker with spring-physics snap behavior * Animated notch marks with proximity-based height and opacity * Circular SVG progress ring showing positive/negative values * Edge fade gradient for depth effect * Configurable min/max range and step size * onChange callback for value tracking * Respects reduced motion preferences ## Accessibility ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the spring smoothing on the drag offset is bypassed and the raw motion value is used directly for instant visual feedback. ## Props <AutoTypeTable path="../../packages/smoothui/components/exposure-slider/index.tsx" name="ExposureSliderProps" /> # Figma Comment (/docs/components/figma-comment) ## Features * Smooth spring animations for expand/collapse * Click outside to close functionality * Customizable width and content * Notification indicator support * Responsive height measurement * Accessible with reduced motion support ## Accessibility ### Screen Reader * The avatar uses an `AvatarImage` with an `alt` attribute and an `AvatarFallback` showing the author's initial. * The click-outside handler allows dismissing the comment by interacting elsewhere. ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the expand/collapse spring animations and content blur transitions are disabled, and the container resizes instantly. ## Props <AutoTypeTable path="../../packages/smoothui/components/figma-comment/index.tsx" name="FigmaCommentProps" /> # GitHub Stars Animation (/docs/components/github-stars-animation) ## Features * Animated countdown from 0 to star count * Displays avatars of users who starred the repository * Staggered entrance animations for avatars * Fetches data from GitHub API or custom endpoint * Supports both client-side and server-side data fetching * Loading and error states * Perfect for hero sections and landing pages ## Accessibility ### Screen Reader * Each stargazer avatar link has an `aria-label` with the username for screen readers. * Avatar images include descriptive `alt` text. * The star count is displayed as plain text, readable by screen readers. * External profile links open in new tabs with secure `rel` attributes. ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the countdown animation is skipped (the final count is shown instantly), avatar entrance animations are disabled, and scale effects on hover are removed. ## Props <AutoTypeTable path="../../packages/smoothui/components/github-stars-animation/index.tsx" name="GitHubStarsAnimationProps" /> # Glow Hover Cards (/docs/components/glow-hover-card) ## Features * Cursor-following glow effect using CSS mask-image * Customizable color themes per card (HSL) * Smooth animations and transitions * Accessible with reduced motion support * Performant GPU-accelerated effects ## Accessibility ### ARIA Attributes | Attribute | Element | Purpose | | -------------------- | ------------ | ------------------------------------------------------------- | | `aria-hidden="true"` | Glow overlay | Hides the decorative glow overlay from assistive technologies | ### Screen Reader * The glow overlay is marked as `aria-hidden` and uses `pointer-events: none`, ensuring it does not interfere with screen readers or interaction. * The original card elements remain fully accessible. ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the entire glow overlay is not rendered, pointer tracking is disabled, and no `will-change` hints are applied. ## Props <AutoTypeTable path="../../packages/smoothui/components/glow-hover-card/index.tsx" name="GlowHoverCardsProps" /> <AutoTypeTable path="../../packages/smoothui/components/glow-hover-card/index.tsx" name="GlowHoverCardItem" /> <AutoTypeTable path="../../packages/smoothui/components/glow-hover-card/index.tsx" name="GlowHoverCardTheme" /> # Gooey Popover (/docs/components/gooey-popover) ## Features * SVG goo filter creates viscous liquid morphing effect * GSAP-powered animations for precise, smooth open/close transitions * Controlled and uncontrolled modes * Configurable trigger size, content width, speed, and placement side * Click outside and Escape key to close * Accessible with ARIA attributes and keyboard support * Reduced motion support (skips goo filter, instant state changes) ## Accessibility ### Keyboard Interactions | Key | Description | | -------- | ---------------------------- | | `Escape` | Closes the popover when open | ### ARIA Attributes | Attribute | Element | Purpose | | ------------------------ | ------------------------------------------- | ------------------------------------------------------------- | | `aria-expanded` | Trigger button | Indicates whether the popover is open or closed | | `aria-haspopup="dialog"` | Trigger button | Indicates the button opens a dialog-style popover | | `role="dialog"` | Content panel | Identifies the popover content as a dialog | | `aria-hidden="true"` | SVG filter, filtered layer, measurement div | Hides decorative and measurement elements from screen readers | ### Reduced Motion This component respects the `prefers-reduced-motion` media query via a manual `matchMedia` listener (it uses GSAP instead of Motion's `useReducedMotion`). When reduced motion is preferred, the goo filter layer is skipped entirely and the popover content appears/disappears instantly. ## Props <AutoTypeTable path="../../packages/smoothui/components/gooey-popover/index.tsx" name="GooeyPopoverProps" /> # Grid Loader (/docs/components/grid-loader) ## Features * 60+ preset patterns: solo, lines, waves, corners, shapes, stripes, spirals, and more * Three animation modes: pulse, sequence, stagger * Five color presets plus custom CSS color support * Four size presets plus custom pixel values * Glow effect that scales with size * Respects reduced motion preferences * Accessible with proper ARIA attributes ## Accessibility ### ARIA Attributes | Attribute | Element | Purpose | | ---------------------- | ---------------- | ------------------------------------------------- | | `aria-label="Loading"` | `output` element | Communicates the loading status to screen readers | ### Screen Reader * The component uses the semantic `output` HTML element, which has an implicit `role="status"` with `aria-live="polite"`, making it announce loading status to assistive technologies. ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred (or when the `static` prop is set), all pulse, stagger, and sequence animations are disabled and cells are displayed statically with their glow effect. ## Props <AutoTypeTable path="../../packages/smoothui/components/grid-loader/index.tsx" name="GridLoaderProps" /> ## Animation Modes ### Pulse (default) All active cells glow together in a breathing animation: ```tsx <GridLoader pattern="plus-hollow" mode="pulse" /> ``` ### Stagger Active cells reveal one-by-one in reading order: ```tsx <GridLoader pattern="frame" mode="stagger" /> ``` ### Sequence Cycles through an array of patterns: ```tsx <GridLoader mode="sequence" sequence={["corners-only", "cross", "frame"]} /> ``` ## Preset Patterns ### Solo (single cell) `solo-center`, `solo-tl`, `solo-tr`, `solo-bl`, `solo-br` ### Lines `line-h-top`, `line-h-mid`, `line-h-bot`, `line-v-left`, `line-v-mid`, `line-v-right`, `line-diag-1`, `line-diag-2` ### Waves `wave-lr`, `wave-rl`, `wave-tb`, `wave-bt` ### Diagonal Quadrants `diagonal-tl`, `diagonal-tr`, `diagonal-bl`, `diagonal-br` ### Corners `corners-only`, `corners-sync`, `corners` ### Plus & Cross `plus-hollow`, `plus-full`, `cross` ### Shapes `x-shape`, `diamond`, `checkerboard` ### L-shapes `L-tl`, `L-tr`, `L-bl`, `L-br` ### T-shapes `T-top`, `T-bot`, `T-left`, `T-right` ### Stripes `stripes-h`, `stripes-v`, `rows-alt` ### Spirals `spiral-cw`, `spiral-ccw` ### Snake `snake`, `snake-rev` ### Rain `rain`, `rain-rev` ### Duo `duo-h`, `duo-v`, `duo-diag` ### Frame & Border `frame`, `frame-sync`, `border`, `ripple-out`, `ripple-in` ### Effects `waterfall`, `breathing`, `heartbeat`, `twinkle`, `sparkle`, `chaos` ### Edge `edge-cw` ### Sparse `sparse-1`, `sparse-2`, `sparse-3` ## Custom Patterns Pass a 3x3 matrix of 0s and 1s for custom patterns: ```tsx <GridLoader pattern={[ [1, 0, 1], [0, 1, 0], [1, 0, 1], ]} /> ``` ## Colors Five preset colors: `white`, `red`, `blue`, `green`, `amber` Or pass any CSS color value: ```tsx <GridLoader color="#a855f7" /> <GridLoader color="rgb(168, 85, 247)" /> ``` ## Sizes Four preset sizes: `sm` (24px), `md` (32px), `lg` (48px), `xl` (64px) Or pass a number for exact pixel value: ```tsx <GridLoader size={40} /> ``` # Image Metadata Preview (/docs/components/image-metadata-preview) ## Features * On-hover metadata panel * Smooth entrance animations * Custom fields and layout * Works with static or dynamic data ## Accessibility ### ARIA Attributes | Attribute | Element | Purpose | | -------------------- | ------------------------------------- | ------------------------------------------------- | | `aria-label` | Share button | Provides accessible name "Share" | | `aria-label` | Open button | Provides accessible name "Open Metadata Preview" | | `aria-label` | Close button | Provides accessible name "Close metadata preview" | | `aria-hidden="true"` | Icon SVGs (Share, ChevronUp, CircleX) | Hides decorative icons from screen readers | ### Screen Reader * All interactive buttons have descriptive `aria-label` attributes. * The metadata table uses semantic `<table>`, `<tbody>`, `<tr>`, and `<td>` elements for structured data. * Buttons have visible focus rings via `focus-visible:ring-2` and minimum touch target sizes (`min-h-[44px]`, `min-w-[44px]`). ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the image lift animation, metadata panel entrance blur/spring, and the open/close button blur transitions are all disabled. ## Props <AutoTypeTable path="../../packages/smoothui/components/image-metadata-preview/index.tsx" name="ImageMetadataPreviewProps" /> # UI Components (/docs/components) <GalleryPage /> # Infinite Slider (/docs/components/infinite-slider) ## Features * Smooth infinite scrolling animation * Customizable speed and gap * Pause on hover support * Horizontal and vertical directions * Reverse direction option * Seamless loop without jumps ## Accessibility ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the scrolling animation is stopped and the translation is reset to 0, displaying the content statically. ## Props <AutoTypeTable path="../../packages/smoothui/components/infinite-slider/index.tsx" name="InfiniteSliderProps" /> # Interactive Image Selector (/docs/components/interactive-image-selector) ## Features * Toggle selection with keyboard and pointer * Animated selection ring and scales * Custom renderers and captions * Responsive grid ## Accessibility ### ARIA Attributes | Attribute | Element | Purpose | | ------------ | -------------------- | ------------------------------------------ | | `aria-label` | Reset button | Provides accessible name "Reset selection" | | `aria-label` | Select/Cancel button | Dynamically describes current action | ### Screen Reader * Each gallery image has an `alt` attribute (e.g., "Gallery item 1"). * The selection count is displayed as visible text in the action bar. * The Share and Delete buttons use icon-only presentation without accessible labels. ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, shake and slide-in animations are disabled. ## Props <AutoTypeTable path="../../packages/smoothui/components/interactive-image-selector/index.tsx" name="InteractiveImageSelectorProps" /> # Job Listing Component (/docs/components/job-listing-component) ## Features * Animated card entrance and hover * Filter/tags friendly layout * Accessible focus states * Responsive grid/list views ## Accessibility ### Keyboard Interactions | Key | Description | | -------- | -------------------------------------- | | `Escape` | Closes the expanded job detail overlay | ### Screen Reader * Job cards use layout animations via `layoutId` for smooth shared element transitions. * The expanded detail view uses a click-outside handler to dismiss, and `Escape` key support for keyboard users. * SVG logo icons (Resend, Turso, Supabase) include `title` elements for screen reader identification. ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, layout animations and `layoutId` transitions are disabled, backdrop opacity animations are instant, and tap scale effects are removed. ## Props <AutoTypeTable path="../../packages/smoothui/components/job-listing-component/index.tsx" name="JobListingComponentProps" /> # Magnetic Button (/docs/components/magnetic-button) ## Features * Cursor-following magnetic effect * Configurable strength and activation radius * Spring physics for natural movement * Respects reduced motion preferences * Touch device detection (effect disabled on touch) * Disabled state support * Polymorphic with `asChild` prop * GPU-accelerated transforms ## Accessibility ### ARIA Attributes | Attribute | Element | Purpose | | --------------------- | ----------- | ---------------------------------------------------------------------------- | | `role="presentation"` | Wrapper div | Indicates the outer mouse-tracking wrapper is decorative and not interactive | ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the magnetic cursor-following effect is completely disabled. The component also detects hover-capable devices and disables the effect on touch devices. When the `disabled` prop is set, the magnetic effect is also disabled. ## Props <AutoTypeTable path="../../packages/smoothui/components/magnetic-button/index.tsx" name="MagneticButtonProps" /> ## Usage ```tsx import MagneticButton from "@/components/magnetic-button"; export default function Example() { return ( <MagneticButton strength={0.3} radius={150}> Hover near me </MagneticButton> ); } ``` ## Examples ### Default ```tsx <MagneticButton>Click me</MagneticButton> ``` ### Custom Strength Increase the magnetic pull strength (0-1): ```tsx <MagneticButton strength={0.5}>Strong magnetic effect</MagneticButton> ``` ### Custom Radius Adjust the activation radius in pixels: ```tsx <MagneticButton radius={200}>Large activation area</MagneticButton> ``` ### Custom Spring Config Fine-tune the spring animation: ```tsx <MagneticButton springConfig={{ duration: 0.6, bounce: 0.2 }}> Bouncy </MagneticButton> ``` ### As Child (Polymorphic) Use with any component using `asChild`: ```tsx <MagneticButton asChild> <a href="/docs">Go to Docs</a> </MagneticButton> ``` # Notification Badge (/docs/components/notification-badge) ## Features * Three variants: dot (simple indicator), count (number badge), status (presence indicator) * Animated count changes with scale pop effect * Ping animation for attention-grabbing alerts * Status colors for user presence: online (green), offline (gray), busy (red), away (yellow) * Flexible positioning in all four corners * Wraps any element as children * Respects reduced motion preferences * Accessible with proper ARIA attributes ## Accessibility ### ARIA Attributes | Attribute | Element | Purpose | | -------------------- | --------- | --------------------------------------------------------------- | | `aria-hidden="true"` | Ping span | Hides the decorative ping animation from assistive technologies | ### Screen Reader * The badge count is rendered as plain text, readable by screen readers. * The component wraps children in a `span` with `relative inline-flex` positioning, preserving the semantic meaning of the wrapped element. ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, entrance/exit scale animations are disabled, the animated count transitions appear instantly, and the ping animation is not rendered. ## Props <AutoTypeTable path="../../packages/smoothui/components/notification-badge/index.tsx" name="NotificationBadgeProps" /> # Number Flow (/docs/components/number-flow) ## Features * Smooth counting animations * Locale-aware formatting * Easing and duration controls * Accessible labels ## Accessibility ### Reduced Motion This component does not currently support the `prefers-reduced-motion` media query. Digit slide animations will play regardless of user preference. ### ARIA The increment and decrement buttons include descriptive `aria-label` attributes (`"Increase number"` and `"Decrease number"`). Buttons are properly disabled at the `min` and `max` boundaries via the `disabled` attribute. ### Keyboard The controls use native `<button>` elements with `type="button"`, so they are focusable and operable via keyboard (Enter and Space) without additional handling. ## Props <AutoTypeTable path="../../packages/smoothui/components/number-flow/index.tsx" name="NumberFlowProps" /> # Phototab (/docs/components/phototab) ## Features * Tab and swipe transitions * Lazy image loading friendly * Keyboard and ARIA tabs * Responsive grid ## Accessibility ### ARIA Attributes | Attribute | Element | Purpose | | ------------ | ---------------- | ------------------------------------------- | | `aria-label` | Tab list | Provides an accessible name "Phototab Tabs" | | `aria-label` | Each tab trigger | Describes the tab name | ### Screen Reader * Built on Radix UI's Tabs primitives, which provide built-in `role="tablist"`, `role="tab"`, and `role="tabpanel"` semantics with automatic `aria-selected` state management. * Each tab trigger includes a visually hidden `<span className="sr-only">` with the tab name. * Tab images have `alt` attributes matching the tab name. ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the hover background pill animation uses instant transitions instead of spring physics. ## Props <AutoTypeTable path="../../packages/smoothui/components/phototab/index.tsx" name="PhototabProps" /> # Power Off Slide (/docs/components/power-off-slide) ## Features * Drag to confirm interaction * Spring physics and rubber-banding * Accessible labels and states * Theming options ## Accessibility ### ARIA Attributes | Attribute | Element | Purpose | | --------------- | ----------- | ----------------------------------------------- | | `aria-disabled` | Drag handle | Indicates when the slider is disabled | | `tabIndex={0}` | Drag handle | Makes the handle focusable when not disabled | | `tabIndex={-1}` | Drag handle | Removes the handle from tab order when disabled | ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the drag interaction is disabled (`drag={false}`), the shimmer text animation stops, and the handle uses instant transitions. ## Props <AutoTypeTable path="../../packages/smoothui/components/power-off-slide/index.tsx" name="PowerOffSlideProps" /> # Price Flow (/docs/components/price-flow) ## Features * Smooth number swaps for pricing * Works with monthly/annual toggles * Locale formatting * Accessible labeling ## Accessibility ### Reduced Motion This component does not currently support the `prefers-reduced-motion` media query. Digit slide animations will play regardless of user preference. ## Props <AutoTypeTable path="../../packages/smoothui/components/price-flow/index.tsx" name="PriceFlowProps" /> # Reveal Text (/docs/components/reveal-text) ## Features * Enter animations from up, down, left, or right * Character or word stagger options * Delay and duration controls * Built with Framer Motion * Accessible and performant ## Accessibility ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the text is displayed immediately at full opacity without any directional slide animation. ## Props <AutoTypeTable path="../../packages/smoothui/components/reveal-text/index.tsx" name="RevealTextProps" /> # Reviews Carousel (/docs/components/reviews-carousel) ## Features * Smooth spring-based animations for card transitions * Keyboard navigation (Arrow keys) * Auto-play support with configurable interval * Customizable indicators and navigation buttons * Respects `prefers-reduced-motion` for accessibility * Stack-based card layout with depth effect * Blur and opacity effects for inactive cards ## Accessibility ### Keyboard Interactions | Key | Description | | ------------ | ------------------------------- | | `ArrowLeft` | Navigate to the previous review | | `ArrowRight` | Navigate to the next review | ### ARIA Attributes | Attribute | Element | Purpose | | --------------- | ------------------ | --------------------------------------------------------------- | | `aria-label` | Navigation buttons | Labels for "Anterior" (previous) and "Siguiente" (next) buttons | | `aria-label` | Indicator buttons | Labels each indicator with its position number | | `type="button"` | All buttons | Prevents implicit form submission | | `disabled` | Navigation buttons | Disables previous/next when at the bounds | ### Screen Reader * Reviews use semantic `figure` and `figcaption` elements with `blockquote` for proper review structure. * Navigation state is communicated through disabled button states. ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, card scale, vertical offset, blur, and opacity transitions use instant `0ms` durations instead of spring animations. ## Props <AutoTypeTable path="../../packages/smoothui/components/reviews-carousel/index.tsx" name="ReviewsCarouselProps" /> # Rich Popover (/docs/components/rich-popover) ## Features * Animated entrance and smart positioning * Supports media, lists, actions * Keyboard and screen reader support * Theming and sizes ## Accessibility ### ARIA Attributes | Attribute | Element | Purpose | | ------------------- | ---------------- | -------------------------------------------------- | | `aria-label` | YouTube SVG icon | Provides an accessible name "YouTube" for the icon | | `role="img"` | YouTube SVG icon | Identifies the SVG as an image | | `focusable="false"` | YouTube SVG icon | Prevents the decorative icon from receiving focus | ### Screen Reader * The popover is built on Radix UI's Popover primitives, which provide built-in focus management and ARIA dialog semantics. * External links use `rel="noopener noreferrer"` and include an external link icon for visual indication. ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the popover content appears and disappears instantly without scale, slide, or blur animations. ## Props <AutoTypeTable path="../../packages/smoothui/components/rich-popover/index.tsx" name="RichTooltipProps" /> # Scramble Hover (/docs/components/scramble-hover) ## Features * Character scrambling on hover with duration and speed controls * Works with headings and inline text * Smooth and performant * Built with Framer Motion * Accessible fallbacks ## Accessibility ### Reduced Motion Respects the `prefers-reduced-motion` media query. When enabled, the scramble animation is fully disabled and the original text is always shown. ### Keyboard Support The component renders as a `<button>` element with `type="button"`, making it natively focusable and keyboard-accessible. The scramble effect triggers on focus and clears on blur. ### Hover Device Detection Detects whether the user's device supports hover via the `(hover: hover) and (pointer: fine)` media query. On touch devices, hover-based animations are disabled to avoid stuck states. ## Props <AutoTypeTable path="../../packages/smoothui/components/scramble-hover/index.tsx" name="ScrambleHoverProps" /> # Scroll Reveal Paragraph (/docs/components/scroll-reveal-paragraph) ## Features * Reveal on scroll with smooth fade and translate * Per-paragraph stagger for long-form content * Configurable thresholds and offsets * Built with Framer Motion + Intersection Observer * Accessible and performant ## Accessibility ### Screen Reader * The component renders as a semantic `p` element, preserving paragraph structure for assistive technologies. * Each word is wrapped in a `span` for animation purposes, but the text content remains fully readable. ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, all words are displayed at full opacity immediately without the scroll-driven reveal effect. The ghost text overlay used for the reveal effect is also hidden. ## Props <AutoTypeTable path="../../packages/smoothui/components/scroll-reveal-paragraph/index.tsx" name="ScrollRevealParagraphProps" /> # Scrollable Card Stack (/docs/components/scrollable-card-stack) ## Features * Stacked, snap-scrolling layout * Parallax and reveal motion * Keyboard and touch friendly * Theming options ## Accessibility ### Keyboard Interactions | Key | Description | | -------------------------- | ------------------------------ | | `ArrowUp` / `ArrowLeft` | Navigates to the previous card | | `ArrowDown` / `ArrowRight` | Navigates to the next card | | `Home` | Jumps to the first card | | `End` | Jumps to the last card | ### ARIA Attributes | Attribute | Element | Purpose | | -------------------- | ---------------- | -------------------------------------------------------------- | | `aria-label` | Section | Provides an accessible name "Scrollable card stack" | | `aria-live="polite"` | Section | Announces card changes to screen readers | | `aria-atomic="true"` | Section | Ensures the full announcement is read together | | `role="application"` | Container | Indicates custom keyboard interaction model | | `role="tablist"` | Navigation dots | Groups the dot indicators as a tab list | | `role="tab"` | Each dot | Identifies each dot as a tab control | | `aria-selected` | Each dot | Indicates the active card indicator | | `aria-label` | Each dot | Describes position (e.g., "Go to card 1 of 5") | | `aria-hidden` | Non-active cards | Hides stacked cards behind the current one from screen readers | | `aria-label` | Profile link | Describes the link action (e.g., "View John's profile") | ### Screen Reader * A live region announces the current card position (e.g., "Card 1 of 5 selected. Use arrow keys to navigate one card at a time, or click the dots below."). * Non-active cards are marked `aria-hidden` so only the visible card is announced. ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, card scale/translate animations, blur effects, and hover scale transitions are all disabled. ## Props <AutoTypeTable path="../../packages/smoothui/components/scrollable-card-stack/index.tsx" name="ScrollableCardStackProps" /> # Scrubber (/docs/components/scrubber) ## Features * Dark, self-contained slider with built-in label and value display * Animated thumb that appears on hover and drag with spring physics * Subtle scrub indicator for position feedback at rest * Configurable tick marks for visual reference * Keyboard accessible (arrow keys, Home, End) * Supports controlled and uncontrolled usage * Respects `prefers-reduced-motion` ## Accessibility ### Keyboard Interactions | Key | Description | | ------------------------- | ------------------------------- | | `ArrowRight` / `ArrowUp` | Increases the value by one step | | `ArrowLeft` / `ArrowDown` | Decreases the value by one step | | `Home` | Sets the value to the minimum | | `End` | Sets the value to the maximum | ### ARIA Attributes | Attribute | Element | Purpose | | --------------- | ------------- | --------------------------------------------------- | | `role="slider"` | Track element | Identifies the component as a slider | | `aria-label` | Track element | Provides an accessible name (uses the `label` prop) | | `aria-valuemin` | Track element | Communicates the minimum value | | `aria-valuemax` | Track element | Communicates the maximum value | | `aria-valuenow` | Track element | Communicates the current value | | `tabIndex={0}` | Track element | Makes the slider focusable | ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the thumb capsule animation uses instant transitions instead of spring physics. ## Props <AutoTypeTable path="../../packages/smoothui/components/scrubber/index.tsx" name="ScrubberProps" /> # Searchable Dropdown (/docs/components/searchable-dropdown) ## Features * Real-time search filtering with smooth transitions * Support for item descriptions and icons * Keyboard navigation (Escape to close) * Animated clear button for search input * Staggered animation for filtered results * Empty state message when no results found * Click outside to close * Fully accessible and customizable ## Accessibility ### Keyboard Interactions | Key | Description | | ----------------- | ---------------------------------------------------------------------------------- | | `Enter` / `Space` | Opens the dropdown when the trigger button is focused, or selects the focused item | | `Escape` | Closes the dropdown, clears the search, and returns focus to the trigger button | | `Arrow Down` | Moves focus to the next filtered item (wraps to first) | | `Arrow Up` | Moves focus to the previous filtered item (wraps to last) | | `Home` | Moves focus to the first filtered item | | `End` | Moves focus to the last filtered item | ### ARIA Attributes | Attribute | Element | Purpose | | --------------------------- | -------------- | ------------------------------------------------------------- | | `aria-expanded` | Trigger button | Indicates whether the dropdown is open or closed | | `aria-haspopup="listbox"` | Trigger button | Indicates the button opens a listbox | | `aria-label` | Trigger button | Provides an accessible name including the selected item label | | `role="combobox"` | Search input | Identifies the search field as a combobox | | `aria-autocomplete="list"` | Search input | Indicates the input provides list-based autocomplete | | `aria-controls` | Search input | References the `id` of the dropdown items list | | `aria-expanded` | Search input | Indicates the dropdown state within the combobox | | `aria-label` | Search input | Provides an accessible name for the search field | | `role="option"` | List item | Identifies each item as a selectable option | | `aria-selected` | List item | Indicates the currently selected or focused item | | `aria-label="Clear search"` | Clear button | Provides an accessible name for the search clear action | ### Screen Reader * The trigger button announces its expanded/collapsed state and the currently selected value * Each option announces its label, optional description, and selected state * A checkmark icon includes a `<title>` element for screen readers * The clear search button is announced with its label ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, dropdown open/close, search field slide-in, item stagger, and chevron rotation animations are disabled instantly. ## Props <AutoTypeTable path="../../packages/smoothui/components/searchable-dropdown/index.tsx" name="SearchableDropdownProps" /> ## Item Props Each item in the dropdown can have the following properties: | Property | Type | Description | | ------------- | ------------------ | ----------------------------------------- | | `id` | `string \| number` | Unique identifier for the item | | `label` | `string` | Display text for the item | | `icon` | `React.ReactNode` | Optional icon to display before the label | | `description` | `string` | Optional description text below the label | # Siri Orb (/docs/components/siri-orb) ## Features * Animated waves and glow * Reacts to input levels * Smooth looping * Easy to style ## Accessibility ### Reduced Motion Respects the `prefers-reduced-motion` media query via a CSS `@media` rule. When enabled, the orb's rotation animation is paused and displays a static gradient. This is a purely decorative component with no interactive or semantic content. ## Props <AutoTypeTable path="../../packages/smoothui/components/siri-orb/index.tsx" name="SiriOrbProps" /> # Skeleton (/docs/components/skeleton-loader) ## Features * **Auto-adaptive**: Wrap any component and skeleton matches its exact shape * Uses Tailwind's `animate-pulse` for smooth animation * Toggle between loading/loaded states with `loading` prop * Works with any component structure * Accessible with ARIA attributes ## Accessibility ### ARIA Attributes * Sets `aria-busy="true"` on the container while loading, signaling to assistive technologies that content is being loaded. * Uses `aria-live="polite"` so screen readers announce when content finishes loading. * Marks the pulse overlay with `aria-hidden="true"` to hide decorative elements from the accessibility tree. ### Reduced Motion Uses Tailwind's `animate-pulse` for the shimmer effect. Tailwind respects the `prefers-reduced-motion` media query at the CSS level, but the component does not include an explicit JavaScript-level `useReducedMotion` check. ## Props <AutoTypeTable path="../../packages/smoothui/components/skeleton-loader/index.tsx" name="SkeletonProps" /> ## Usage ### Wrap your UI Simply wrap your component - the skeleton will match its exact dimensions: ```tsx <Skeleton loading={isLoading}> <UserCard user={user} /> </Skeleton> ``` ### Basic blocks Use without children for simple skeleton shapes: ```tsx <div className="flex items-center gap-4"> <Skeleton className="size-12 rounded-full" /> <div className="space-y-2"> <Skeleton className="h-4 w-[200px]" /> <Skeleton className="h-4 w-[160px]" /> </div> </div> ``` # Social Selector (/docs/components/social-selector) ## Features * Animated select/deselect * Icon and label variants * Keyboard and screen reader support * Responsive layout ## Accessibility ### ARIA Attributes | Attribute | Element | Purpose | | ------------ | ---------------- | ------------------------------------------------ | | `aria-label` | Platform buttons | Describes the action (e.g., "Select X platform") | ### Screen Reader * Each platform icon button contains a visually hidden `<span className="sr-only">` with the platform name. * SVG icons include `<title>` elements (e.g., "X icon", "Bluesky icon", "Threads icon"). * External links use `rel="noopener noreferrer"` for security. ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, the background pill sliding animation and the domain text blur/slide transitions are disabled. ## Props <AutoTypeTable path="../../packages/smoothui/components/social-selector/index.tsx" name="SocialSelectorProps" /> # Switchboard Card (/docs/components/switchboard-card) ## Features * Animated light grid with configurable dimensions * Three light states: off, medium, high (all use brand color) * Word pattern support - automatically generates patterns for short words (e.g., "NEXT", "REACT", "VUE") * Custom pattern support via array of light indices * Random light generation for dynamic effects * Next.js-style variant with dark gradient background * Smooth transitions and animations * Fully customizable grid layout ## Accessibility ### ARIA Attributes * When rendered as a link (`href` prop) or button (`onButtonClick` prop), the wrapper includes `aria-label` set to the card's `title` for screen reader context. * Focus-visible ring styles (`focus-visible:ring-2`) provide clear keyboard focus indication on interactive card variants. ### Reduced Motion The light grid uses CSS transitions (`opacity` and `transform`) with configurable `transitionDuration`. There is no explicit `prefers-reduced-motion` check at the JavaScript or CSS level. The animations are subtle opacity/scale transitions rather than layout-shifting motion. ## Props <AutoTypeTable path="../../packages/smoothui/components/switchboard-card/index.tsx" name="SwitchboardCardProps" /> <AutoTypeTable path="../../packages/smoothui/components/switchboard-card/index.tsx" name="LightState" /> ## Usage ### Basic Usage ```tsx import SwitchboardCard from "@repo/smoothui/components/switchboard-card"; <SwitchboardCard title="Next.js 16" subtitle="The power of full-stack to the frontend." variant="next" /> ``` ### With Grid Pattern (Simplest) The easiest way to customize is to pass a grid pattern directly. You can use either: * A 2D array `[rows][columns]` where each cell is `0` (off) or `1` (high) * A flat array of length `columns * rows` where each element is `0` (off) or `1` (high) ```tsx // Using 2D array [5 rows][18 columns] const nextPattern = [ [1,1,0,0,0,0,0,1,1,1,0,0,0,1,1,1,1,1], // Row 0 [1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0], // Row 1 [1,0,0,1,0,0,0,1,1,1,0,0,0,0,0,0,1,0], // Row 2 [1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0], // Row 3 [1,1,1,1,1,0,0,1,1,1,0,0,0,1,1,1,1,1], // Row 4 ]; <SwitchboardCard title="Custom Pattern" subtitle="Define your own pattern." gridPattern={nextPattern} columns={18} rows={5} /> // Or using flat array const flatPattern = Array(90).fill(0).map((_, i) => { // Your logic to determine which lights should be on return i % 10 === 0 ? 1 : 0; }); <SwitchboardCard title="Custom Pattern" subtitle="Using flat array." gridPattern={flatPattern} columns={18} rows={5} /> ``` ### With Word Pattern The easiest way to display a word is to use the `word` prop. The component will automatically generate the pattern: ```tsx <SwitchboardCard title="Next.js 16" subtitle="The power of full-stack to the frontend." word="NEXT" columns={18} rows={5} /> ``` Supported letters: N, E, X, T, R, A, C, V, U (more can be added) ### With Custom Pattern For full control, you can define custom light patterns by passing an array of light indices: ```tsx const customPattern = [15, 19, 26, 29, 34, 55, 60, 70, 74, 83]; <SwitchboardCard title="Custom Pattern" subtitle="Display a custom light pattern." pattern={customPattern} columns={18} rows={5} /> ``` ### Random Lights For a dynamic effect, use `randomLights`: ```tsx <SwitchboardCard title="React 19" subtitle="Latest features and improvements." randomLights columns={18} rows={5} /> ``` ### Interactive Card Make the card clickable with `href` or `onButtonClick`: ```tsx <SwitchboardCard title="Documentation" subtitle="Read the full documentation." href="/docs" variant="next" /> ``` # Tweet Card (/docs/components/tweet-card) ## Features * Beautiful tweet card design with full-width images * Hover-activated external link button positioned at bottom-right * Support for tweets with images, videos, and text * Server-side and client-side rendering options * Loading and error states included * Fully customizable styling * Configurable user info position (top or bottom) * Customizable avatar rounded style * Accessible with proper ARIA labels * Consistent 24px padding on all sides ## Accessibility ### Semantic HTML Uses `<article>` as the root element and `<blockquote>` for tweet text, providing meaningful document structure for assistive technologies. ### ARIA Attributes * The external link button includes `aria-label="Open tweet in new tab"` for screen reader context. * Decorative SVG icons use `aria-hidden="true"` to hide them from the accessibility tree. * All external links include `rel="noreferrer"` or `rel="noopener noreferrer"` for security. ### Reduced Motion The hover-activated link button uses Tailwind's `motion-safe:hover:scale-110` utility, which automatically disables the scale animation when `prefers-reduced-motion` is enabled. There is no additional JavaScript-level `useReducedMotion` check, as animations are CSS-only. ## Props <AutoTypeTable path="../../packages/smoothui/components/tweet-card/client.tsx" name="ClientTweetCardProps" /> ## Usage ### Client-Side (Recommended) Use `ClientTweetCard` for client-side rendering: ```tsx import { ClientTweetCard, TweetSkeleton } from "@repo/smoothui/components"; export function MyComponent() { return ( <ClientTweetCard id="1944804313156419771" fallback={<TweetSkeleton />} /> ); } ``` ### Server-Side Use `TweetCard` for server-side rendering: ```tsx import { TweetCard } from "@repo/smoothui/components"; export default async function MyPage() { return ( <TweetCard id="1944804313156419771" /> ); } ``` ## Configuration Options ### User Info Position Control where the user information (avatar and name) appears in the card: ```tsx // User info at bottom (default) <ClientTweetCard id="1944804313156419771" userInfoPosition="bottom" fallback={<TweetSkeleton />} /> // User info at top <ClientTweetCard id="1944804313156419771" userInfoPosition="top" fallback={<TweetSkeleton />} /> ``` ### Avatar Rounded Style Customize the avatar's border radius: ```tsx // Rounded corners (default) <ClientTweetCard id="1944804313156419771" avatarRounded="rounded" fallback={<TweetSkeleton />} /> // Fully rounded (circle) <ClientTweetCard id="1944804313156419771" avatarRounded="rounded-full" fallback={<TweetSkeleton />} /> // Large rounded corners <ClientTweetCard id="1944804313156419771" avatarRounded="rounded-lg" fallback={<TweetSkeleton />} /> // Medium rounded corners <ClientTweetCard id="1944804313156419771" avatarRounded="rounded-md" fallback={<TweetSkeleton />} /> ``` ### Combined Configuration Use both props together for different layouts: ```tsx // Top position with circular avatar <ClientTweetCard id="1944804313156419771" userInfoPosition="top" avatarRounded="rounded-full" fallback={<TweetSkeleton />} /> // Bottom position with large rounded corners <ClientTweetCard id="1944804313156419771" userInfoPosition="bottom" avatarRounded="rounded-lg" fallback={<TweetSkeleton />} /> ``` ## Examples ### Default Configuration Default layout with user info at bottom and rounded avatar: ```tsx <ClientTweetCard id="1944804313156419771" fallback={<TweetSkeleton />} /> ``` ### User Info at Top Display user information at the top of the card: ```tsx <ClientTweetCard id="1944804313156419771" userInfoPosition="top" fallback={<TweetSkeleton />} /> ``` ### Circular Avatar Use a fully rounded (circular) avatar: ```tsx <ClientTweetCard id="1944804313156419771" avatarRounded="rounded-full" fallback={<TweetSkeleton />} /> ``` ### Top Position with Circular Avatar Combine top position with circular avatar: ```tsx <ClientTweetCard id="1944804313156419771" userInfoPosition="top" avatarRounded="rounded-full" fallback={<TweetSkeleton />} /> ``` ## Grid Layout Display multiple tweets in a grid with different configurations: ```tsx import { ClientTweetCard, TweetSkeleton } from "@repo/smoothui/components"; export function TweetGrid() { return ( <div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3"> <ClientTweetCard id="1944804313156419771" fallback={<TweetSkeleton />} /> <ClientTweetCard id="2010439383795810775" userInfoPosition="top" avatarRounded="rounded-full" fallback={<TweetSkeleton />} /> <ClientTweetCard id="1785225558818771172" avatarRounded="rounded-lg" fallback={<TweetSkeleton />} /> </div> ); } ``` # Typewriter Text (/docs/components/typewriter-text) ## Features * Progressive character reveal with configurable speed * Optional looping with pauses * Works with headings, paragraphs, and inline text * Built with Framer Motion * Accessible and performant ## Accessibility ### Reduced Motion Respects the `prefers-reduced-motion` media query via a custom `useReducedMotion` hook. When enabled, the full text is displayed immediately without the character-by-character reveal animation. ## Props <AutoTypeTable path="../../packages/smoothui/components/typewriter-text/index.tsx" name="TypewriterTextProps" /> # User Account Avatar (/docs/components/user-account-avatar) ## Features * Image with fallback support * Multiple sizes * Customizable fallback text * Group avatars support * Status indicators * Built on Radix UI Avatar ## Accessibility ### Keyboard Interactions | Key | Description | | ----------------- | --------------------------------------------------- | | `Enter` / `Space` | Toggle the "Edit Profile" or "Last Orders" sections | ### ARIA Attributes | Attribute | Element | Purpose | | ------------------------- | ----------------- | ------------------------------------------------- | | `aria-label="View Order"` | View order button | Labels the order detail button for screen readers | | `htmlFor` | Form labels | Associates labels with their form inputs | | `type="button"` | All buttons | Prevents implicit form submission | | `type="submit"` | Save button | Submits the profile edit form | ### Screen Reader * The popover is built on Radix UI Popover, which manages focus trapping, return focus, and escape-to-close automatically. * Form inputs include proper `label` elements linked via `htmlFor`/`id` attributes. * Section toggle buttons include keyboard event handlers (`onKeyDown`) for `Enter` and `Space` keys. * The avatar image includes an `alt="User Avatar"` attribute. ### Reduced Motion This component respects the `prefers-reduced-motion` media query via `useReducedMotion` from Motion. When reduced motion is preferred, section expand/collapse animations, progress bar animations, and height transitions are all disabled instantly. ## Props <AutoTypeTable path="../../packages/smoothui/components/user-account-avatar/index.tsx" name="UserAccountAvatarProps" /> # Wave Text (/docs/components/wave-text) ## Features * Smooth continuous wave animation across text * Customizable amplitude, duration, and stagger delay * Natural bounce effect with custom easing * GPU-accelerated for optimal performance * Lightweight and easy to use * Built with Motion ## Accessibility ### Reduced Motion Uses `useReducedMotion` from `motion/react`. When enabled, the wave animation is fully disabled — characters render statically with no vertical movement and `duration: 0` transitions. ## Props <AutoTypeTable path="../../packages/smoothui/components/wave-text/index.tsx" name="WaveTextProps" /> ## Usage ```tsx import WaveText from "@repo/smoothui/components/wave-text"; // Basic usage <WaveText>Hello World</WaveText> // Customized wave <WaveText amplitude={12} duration={1.0} staggerDelay={0.04}> SmoothUI Components </WaveText> ``` ## Examples ### Large Bold Text ```tsx <div className="font-bold text-3xl"> <WaveText amplitude={12} duration={1.0} staggerDelay={0.04}> SmoothUI Components </WaveText> </div> ``` ### Subtle Wave ```tsx <WaveText amplitude={6} duration={1.4} staggerDelay={0.06}> Smooth wave animations for your text! </WaveText> ``` # AI Integration (/docs/guides/ai-integration) # AI Integration <BodyText> SmoothUI is designed from the ground up for AI-assisted development. Whether you are an AI agent selecting components programmatically, or a developer using AI coding tools, SmoothUI provides first-class integration paths. </BodyText> <Divider orientation="horizontal" className="relative" /> ## Quick Start <BodyText> Choose the integration that fits your workflow: </BodyText> | You are... | What to use | Setup | | --------------------------------------------- | ------------------------ | ------------------------------------------ | | **AI coding agent** (Claude, Cursor, Copilot) | MCP Server | `npx shadcn@latest mcp init` | | **Building custom tooling** | REST API | Call `https://smoothui.dev/api/v1/...` | | **LLM / RAG pipeline** | Machine-readable catalog | Fetch `https://smoothui.dev/llms-full.txt` | <Divider orientation="horizontal" className="relative" /> ## For AI Agents <BodyText> AI agents can discover, search, and install SmoothUI components through multiple channels. </BodyText> ### MCP Server (Recommended) <BodyText> The fastest way to give an AI assistant full access to SmoothUI. The shadcn MCP server works out of the box with SmoothUI's registry. </BodyText> <Tabs items={['Claude Code', 'Cursor', 'VS Code']} defaultIndex={0}> <Tab value="Claude Code"> ```shell title="Terminal" npx shadcn@latest mcp init --client claude ``` </Tab> <Tab value="Cursor"> ```shell title="Terminal" npx shadcn@latest mcp init --client cursor ``` </Tab> <Tab value="VS Code"> ```shell title="Terminal" npx shadcn@latest mcp init --client vscode ``` </Tab> </Tabs> <BodyText> Once configured, your AI assistant can discover, search, and install any SmoothUI component. See the full [MCP Server guide](/docs/guides/mcp) for detailed setup and example prompts. </BodyText> ### REST API <BodyText> For agents that need structured JSON data, SmoothUI provides a public REST API with no authentication required. </BodyText> ```bash title="Discover components" curl "https://smoothui.dev/api/v1/suggest?need=animated+tab+navigation" ``` ```bash title="Get component source" curl "https://smoothui.dev/api/v1/components/animated-tabs?include=source" ``` <BodyText> **Key endpoints:** </BodyText> | Endpoint | Purpose | | ------------------------------------- | -------------------------------------- | | `GET /api/v1/components` | List all components with filtering | | `GET /api/v1/components/{name}` | Get component details and source | | `GET /api/v1/components/search?q=...` | Keyword search | | `GET /api/v1/suggest?need=...` | Natural-language component suggestions | | `GET /api/v1/blocks` | List pre-built page sections | | `GET /openapi.json` | Full OpenAPI 3.1 specification | <BodyText> See the full [REST API reference](/docs/guides/api) for query parameters, response schemas, and error handling. </BodyText> ### Machine-Readable Catalog <BodyText> For LLM context windows and RAG pipelines, SmoothUI provides machine-readable component catalogs following the `llms.txt` convention: </BodyText> | URL | Description | | -------------------------------------------------------------------- | -------------------------------------------------- | | [`/llms.txt`](https://smoothui.dev/llms.txt) | Compact overview of all components | | [`/llms-full.txt`](https://smoothui.dev/llms-full.txt) | Full catalog with metadata, props, and usage hints | | [`/llms-components.json`](https://smoothui.dev/llms-components.json) | Structured JSON catalog for programmatic use | <Divider orientation="horizontal" className="relative" /> ## Agent Workflow <BodyText> Here is the recommended workflow for AI agents integrating SmoothUI components: </BodyText> 1. **Discover** — Use `/api/v1/suggest?need=...` or the MCP server to find relevant components based on what the user needs. 2. **Inspect** — Fetch full metadata and source with `/api/v1/components/{name}?include=source` to understand props and usage. 3. **Install** — Use the `installCommand` from the metadata: `npx shadcn@latest add @smoothui/{name}`. 4. **Integrate** — Use `compositionHints` and the source code to wire the component into the project correctly. <Divider orientation="horizontal" className="relative" /> ## Learn More <Cards className="md:grid-cols-3"> <Card title="MCP Server" href="/docs/guides/mcp"> Full MCP setup guide with example prompts for Claude, Cursor, and VS Code. </Card> <Card title="REST API" href="/docs/guides/api"> Complete API reference with endpoints, parameters, and response schemas. </Card> <Card title="Installation" href="/docs/guides/installation"> Get started with SmoothUI in your project. </Card> </Cards> # Animated React Components (/docs/guides/animated-components) import { Accordion, Accordions } from 'fumadocs-ui/components/accordion'; ## Motion & GSAP-Powered React Components SmoothUI provides a comprehensive collection of **animated React components** powered by [Motion](https://motion.dev) (formerly Framer Motion) and [GSAP](https://gsap.com). Every component is designed with smooth, performant animations that enhance user experience without sacrificing accessibility. <div className="grid gap-4 md:grid-cols-3"> <FeatureCardHover title="50+ Components" description="Buttons, cards, inputs, text effects, and more - all with built-in animations." gradient="from-purple-400 via-pink-400 to-orange-400" /> <FeatureCardHover title="Spring Physics" description="Natural, fluid animations using spring physics for realistic motion." gradient="from-blue-400 via-purple-400 to-pink-400" /> <FeatureCardHover title="Reduced Motion" description="Automatic accessibility support for users who prefer reduced motion." gradient="from-green-400 via-blue-400 to-purple-400" /> </div> ## Animation Categories ### Text Animations Create engaging text effects that capture attention: | Component | Animation Type | Use Case | | --------------------------------------------------- | --------------------- | ---------------------------- | | [Typewriter Text](/docs/components/typewriter-text) | Character reveal | Hero sections, AI interfaces | | [Scramble Hover](/docs/components/scramble-hover) | Matrix-style scramble | Navigation, headings | | [Wave Text](/docs/components/wave-text) | Wave motion | Decorative headings | | [Reveal Text](/docs/components/reveal-text) | Directional reveal | Page transitions | ### Interactive Cards Cards with smooth expand, hover, and transition animations: | Component | Animation Type | Use Case | | --------------------------------------------------------------- | --------------------- | ---------------------- | | [Expandable Cards](/docs/components/expandable-cards) | Layout animation | Portfolios, galleries | | [Glow Hover Card](/docs/components/glow-hover-card) | Cursor-following glow | Feature highlights | | [Scrollable Card Stack](/docs/components/scrollable-card-stack) | Parallax reveal | Testimonials, profiles | ### Button Animations Buttons with satisfying micro-interactions: | Component | Animation Type | Use Case | | ----------------------------------------------------------- | ----------------- | ---------------- | | [Magnetic Button](/docs/components/magnetic-button) | Cursor attraction | CTAs, navigation | | [Button Copy](/docs/components/button-copy) | Success feedback | Code snippets | | [Clip Corners Button](/docs/components/clip-corners-button) | Corner animation | Unique CTAs | ### Form Inputs Inputs with smooth focus and validation animations: | Component | Animation Type | Use Case | | --------------------------------------------------------- | --------------- | ------------------ | | [Animated Input](/docs/components/animated-input) | Floating label | Forms, search | | [Animated OTP Input](/docs/components/animated-otp-input) | Digit animation | Verification flows | ### Notification Components Animated feedback and notification elements: | Component | Animation Type | Use Case | | ------------------------------------------------- | --------------- | --------------------- | | [Dynamic Island](/docs/components/dynamic-island) | Expand/collapse | Notifications, status | | [Basic Toast](/docs/components/basic-toast) | Slide animation | Alerts, confirmations | ## Why Motion & GSAP? ### Performance Optimized All animations use GPU-accelerated transforms (`transform` and `opacity`) for smooth 60fps performance. No layout thrashing or paint operations. ### Accessibility First Every component respects the `prefers-reduced-motion` media query. Users who are sensitive to motion see instant transitions instead of animations. ```tsx // Built into every component const shouldReduceMotion = useReducedMotion(); ``` ### Natural Feel Animations use spring physics with carefully tuned parameters for natural, fluid motion that feels right: ```tsx transition={{ type: "spring", duration: 0.25, bounce: 0.1 }} ``` ## Getting Started Install any animated component using the shadcn CLI: ```bash npx shadcn@latest add @smoothui/expandable-cards ``` Or browse all components: <Cards> <Card href="/docs/components" title="All Components"> Explore the complete collection of 50+ animated components. </Card> <Card href="/docs/guides/installation" title="Installation"> Set up SmoothUI in your React or Next.js project. </Card> </Cards> ## Frequently Asked Questions <Accordions> <Accordion id="motion-required" title="Do I need to know Motion or GSAP?"> No! All animations are built-in and work out of the box. You can use components without writing any animation code. For customization, basic Motion or GSAP knowledge helps but isn't required. </Accordion> <Accordion id="bundle-size" title="How do animations affect bundle size?"> Motion and GSAP are the animation dependencies. Components are tree-shakeable, so you only ship the code you use. Most components use Motion, while some use GSAP for advanced effects like the Gooey Popover. </Accordion> <Accordion id="ssr-support" title="Do animations work with Next.js SSR?"> Yes! All components are designed for Next.js App Router and work with Server Components. Client-side animations hydrate smoothly without layout shift. </Accordion> <Accordion id="custom-animations" title="Can I customize the animations?"> Absolutely. Since you own the code (copied into your project), you can modify any animation parameters - duration, easing, spring physics, and more. </Accordion> </Accordions> # Animation Best Practices (/docs/guides/animation-best-practices) import { Accordion, Accordions } from 'fumadocs-ui/components/accordion'; ## Why Animation Matters Animation isn't just decoration—it's a fundamental part of user experience. Well-crafted animations: * **Guide attention** to important elements and changes * **Provide feedback** that actions were registered * **Create continuity** between UI states * **Reduce cognitive load** by showing relationships between elements * **Delight users** with polished, professional interactions Studies show that appropriate animation can increase user engagement by up to 400% and significantly improve perceived performance, even when actual load times remain the same. <FeatureCard title="The SmoothUI Philosophy" variant="info"> Every SmoothUI component follows these principles. Animations are fast (200-300ms), purposeful, and always respect user preferences for reduced motion. </FeatureCard> *** ## Core Animation Principles ### Duration & Timing The most common mistake is making animations too slow. Users perceive interfaces as sluggish when animations exceed 300-400ms. | Animation Type | Recommended Duration | | ------------------------------------- | -------------------- | | Micro-interactions (hover, focus) | 100-200ms | | Standard transitions (show/hide) | 200-300ms | | Complex animations (page transitions) | 300-400ms | | Decorative/ambient | Up to 1000ms | ```tsx // Good: Fast, snappy interaction transition={{ duration: 0.2 }} // Bad: Feels sluggish transition={{ duration: 0.8 }} ``` ### Easing Functions Easing determines how an animation accelerates and decelerates. The right easing makes motion feel natural. | Easing | Use Case | CSS/Motion Value | | --------------- | ---------------------- | -------------------------------------- | | **ease-out** | Elements entering | `cubic-bezier(0.23, 1, 0.32, 1)` | | **ease-in-out** | Elements moving | `cubic-bezier(0.645, 0.045, 0.355, 1)` | | **ease** | Hover/color changes | `ease` (built-in) | | **spring** | Natural, bouncy motion | `type: "spring"` | ```tsx // Natural spring animation (recommended for most cases) transition={{ type: "spring", duration: 0.25, bounce: 0.1 // Keep low for UI (0.1-0.2) }} // Cubic bezier for precise control transition={{ duration: 0.2, ease: [0.23, 1, 0.32, 1] // ease-out }} ``` <FeatureCard title="Avoid ease-in" variant="warning"> Never use `ease-in` for UI animations—it starts slow and feels unresponsive. Users expect immediate feedback when they interact. </FeatureCard> ### Transform vs Layout Properties This is critical for performance. Only animate **transform** and **opacity**—these are GPU-accelerated and don't trigger layout recalculations. ```tsx // GOOD: GPU-accelerated, smooth 60fps animate={{ opacity: 1, scale: 1, x: 0, y: 0 }} // BAD: Triggers layout, causes jank animate={{ width: 200, height: 100, marginLeft: 20 }} ``` | Property | Performance | Use Instead | | -------------------------------- | ----------- | ------------------------------ | | `width`, `height` | Poor | `scale` or `scaleX`/`scaleY` | | `top`, `left`, `right`, `bottom` | Poor | `x`, `y` (transform) | | `margin`, `padding` | Poor | `x`, `y` with fixed dimensions | | `opacity` | Excellent | Use freely | | `transform` | Excellent | Use freely | *** ## Motion Library Essentials SmoothUI uses [Motion](https://motion.dev) (formerly Framer Motion) for animations. Here are the key concepts. ### Spring Physics Spring animations feel more natural than duration-based animations because they simulate real-world physics. ```tsx import { motion } from "motion/react"; <motion.div animate={{ scale: 1 }} initial={{ scale: 0.9 }} transition={{ type: "spring", stiffness: 300, // Higher = snappier damping: 20, // Higher = less bouncy mass: 1 // Higher = more momentum }} /> ``` **Simplified spring syntax** (recommended): ```tsx transition={{ type: "spring", duration: 0.25, // Approximate duration bounce: 0.1 // 0 = no bounce, 1 = very bouncy }} ``` ### Variants Variants let you define animation states and orchestrate complex animations: ```tsx const containerVariants = { hidden: { opacity: 0 }, visible: { opacity: 1, transition: { staggerChildren: 0.1 // Animate children sequentially } } }; const itemVariants = { hidden: { opacity: 0, y: 20 }, visible: { opacity: 1, y: 0 } }; <motion.ul variants={containerVariants} initial="hidden" animate="visible"> {items.map(item => ( <motion.li key={item.id} variants={itemVariants}> {item.name} </motion.li> ))} </motion.ul> ``` ### Layout Animations Motion's `layout` prop automatically animates layout changes: ```tsx // Automatically animates position/size changes <motion.div layout> {isExpanded ? <ExpandedContent /> : <CollapsedContent />} </motion.div> // Smooth shared element transitions <motion.div layoutId="shared-element"> {/* This element animates between positions */} </motion.div> ``` ### AnimatePresence For enter/exit animations, wrap components in `AnimatePresence`: ```tsx import { AnimatePresence, motion } from "motion/react"; <AnimatePresence> {isVisible && ( <motion.div initial={{ opacity: 0, y: -10 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: -10 }} > Content that animates in and out </motion.div> )} </AnimatePresence> ``` *** ## Performance Optimization ### GPU-Accelerated Properties Always prefer these properties for smooth 60fps animations: ```tsx // These run on the GPU (compositor thread) transform: translateX(), translateY(), scale(), rotate() opacity // These trigger layout/paint (main thread) - AVOID width, height, top, left, margin, padding, border ``` ### Avoiding Layout Thrash Layout thrash occurs when you read and write to the DOM in quick succession: ```tsx // BAD: Forces synchronous layout elements.forEach(el => { const height = el.offsetHeight; // READ el.style.height = height + 10; // WRITE }); // GOOD: Batch reads, then writes const heights = elements.map(el => el.offsetHeight); // All READs elements.forEach((el, i) => { el.style.height = heights[i] + 10; // All WRITEs }); ``` ### will-change Hint Use sparingly to hint browser optimization: ```css .animated-element { will-change: transform, opacity; } ``` <FeatureCard title="Don't Overuse will-change" variant="warning"> Only apply `will-change` to elements that will actually animate. Overuse consumes memory and can hurt performance. </FeatureCard> ### When to Use CSS vs JavaScript Animations | Use CSS | Use JavaScript (Motion) | | -------------------------- | -------------------------------- | | Simple hover effects | Complex choreographed animations | | State transitions | Physics-based motion | | Keyframe animations | Gesture-driven animations | | Performance-critical loops | Dynamic, data-driven animations | *** ## Accessibility Guidelines ### Respecting Reduced Motion Always check `prefers-reduced-motion`. Users enable this for medical reasons (vestibular disorders, motion sickness) or personal preference. ```tsx import { useReducedMotion } from "motion/react"; function AnimatedComponent() { const shouldReduceMotion = useReducedMotion(); return ( <motion.div animate={ shouldReduceMotion ? { opacity: 1 } // Minimal animation : { opacity: 1, y: 0, scale: 1 } // Full animation } initial={ shouldReduceMotion ? { opacity: 0 } : { opacity: 0, y: 20, scale: 0.95 } } transition={ shouldReduceMotion ? { duration: 0 } // Instant : { type: "spring", duration: 0.25, bounce: 0.1 } } /> ); } ``` <FeatureCard title="SmoothUI Accessibility" variant="info"> Every SmoothUI component includes `useReducedMotion` support. Animations are automatically disabled or minimized for users who prefer reduced motion. </FeatureCard> ### Motion Sensitivity Guidelines Even for users without reduced motion enabled: * **Avoid large-scale motion** (full-screen transitions, parallax) * **Limit simultaneous animations** (no more than 2-3 elements animating at once) * **Keep animations brief** (under 300ms for most interactions) * **Avoid infinite loops** (or provide controls to pause) ### Focus Management When animating elements that affect focus: ```tsx // Ensure focus moves appropriately after animation <motion.dialog onAnimationComplete={() => { if (isOpen) { firstFocusableElement.current?.focus(); } }} > ``` *** ## Common Patterns ### Enter/Exit Animations ```tsx // Fade + slide up (most common) const fadeSlideUp = { initial: { opacity: 0, y: 10 }, animate: { opacity: 1, y: 0 }, exit: { opacity: 0, y: -10 }, transition: { duration: 0.2 } }; // Scale + fade (for modals, popovers) const scaleFade = { initial: { opacity: 0, scale: 0.95 }, animate: { opacity: 1, scale: 1 }, exit: { opacity: 0, scale: 0.95 }, transition: { type: "spring", duration: 0.25, bounce: 0.1 } }; ``` ### Hover Effects ```tsx <motion.button whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }} transition={{ type: "spring", stiffness: 400, damping: 17 }} > Click me </motion.button> ``` ### Staggered Lists ```tsx <motion.ul initial="hidden" animate="visible" variants={{ visible: { transition: { staggerChildren: 0.05 } } }} > {items.map(item => ( <motion.li key={item.id} variants={{ hidden: { opacity: 0, x: -20 }, visible: { opacity: 1, x: 0 } }} > {item.name} </motion.li> ))} </motion.ul> ``` ### Scroll-Triggered Animations ```tsx import { useInView, motion } from "motion/react"; function ScrollReveal({ children }) { const ref = useRef(null); const isInView = useInView(ref, { once: true, margin: "-100px" }); return ( <motion.div ref={ref} animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 20 }} transition={{ duration: 0.5 }} > {children} </motion.div> ); } ``` *** ## Anti-Patterns to Avoid <div className="fd-steps"> <div className="fd-step"> ### Overanimating Not everything needs to animate. Too much motion is distracting and exhausting. ```tsx // BAD: Everything bounces and wiggles <motion.div animate={{ rotate: [0, 5, -5, 0] }} /> <motion.span animate={{ scale: [1, 1.1, 1] }} /> <motion.p animate={{ opacity: [1, 0.8, 1] }} /> // GOOD: Purposeful, minimal animation <motion.button whileHover={{ scale: 1.02 }} /> ``` </div> <div className="fd-step"> ### Slow Animations Animations over 300ms feel sluggish. Users shouldn't wait for your UI. ```tsx // BAD: Too slow transition={{ duration: 0.8 }} // GOOD: Snappy transition={{ duration: 0.2 }} ``` </div> <div className="fd-step"> ### Competing Animations Multiple elements animating simultaneously creates visual chaos. ```tsx // BAD: Everything animates at once {items.map(item => ( <motion.div animate={{ scale: 1.1 }} /> ))} // GOOD: Stagger or animate one at a time variants={{ visible: { transition: { staggerChildren: 0.05 } } }} ``` </div> <div className="fd-step"> ### Animation Without Purpose Every animation should serve a function: feedback, guidance, or continuity. ```tsx // BAD: Spinning logo for no reason <motion.img animate={{ rotate: 360 }} transition={{ repeat: Infinity }} /> // GOOD: Spinner indicates loading state {isLoading && <motion.div animate={{ rotate: 360 }} />} ``` </div> <div className="fd-step"> ### Ignoring Reduced Motion Always implement reduced motion support. It's an accessibility requirement. ```tsx // BAD: No reduced motion check animate={{ x: 100, rotate: 360 }} // GOOD: Respects user preference animate={shouldReduceMotion ? { opacity: 1 } : { x: 100, rotate: 360 }} ``` *** </div> </div> ## Quick Reference ### Recommended Defaults ```tsx // Standard UI animation transition={{ type: "spring", duration: 0.25, bounce: 0.1 }} // Hover/tap feedback transition={{ type: "spring", stiffness: 400, damping: 17 }} // Enter/exit transition={{ duration: 0.2, ease: [0.23, 1, 0.32, 1] }} ``` ### Checklist for New Animations * [ ] Duration under 300ms for interactions * [ ] Only animating transform/opacity * [ ] `useReducedMotion` implemented * [ ] Purposeful (not decorative) * [ ] Tested on low-end devices *** ## Further Reading <Cards> <Card href="/docs/guides/animated-components" title="Animated Components"> Browse all 50+ animated components in SmoothUI. </Card> <Card href="/docs/guides/design-principles" title="Design Principles"> Learn about SmoothUI's design philosophy and patterns. </Card> <Card href="https://motion.dev/docs" title="Motion Documentation"> Official Motion (Framer Motion) documentation. </Card> </Cards> # REST API (/docs/guides/api) # REST API <BodyText> SmoothUI exposes a public REST API that lets you discover, search, and retrieve component metadata and source code programmatically. The API is designed for both human developers building tooling and AI agents that need structured component data. </BodyText> <Divider orientation="horizontal" className="relative" /> ## Overview <BodyText> **Base URL:** `https://smoothui.dev/api/v1` </BodyText> <BodyText> **Authentication:** None required. The API is fully public. </BodyText> <BodyText> **CORS:** All endpoints include `Access-Control-Allow-Origin: *` headers, so you can call them from any origin. </BodyText> <BodyText> **Format:** All responses are JSON. Errors follow a consistent `{"error": "...", "status": 400}` envelope. </BodyText> <BodyText> **OpenAPI Spec:** A full OpenAPI 3.1 specification is available at [`/openapi.json`](https://smoothui.dev/openapi.json). </BodyText> <Divider orientation="horizontal" className="relative" /> ## Endpoints ### List Components <BodyText> Returns a paginated list of all SmoothUI components. Supports filtering by category, complexity, animation type, and tag. </BodyText> ```bash title="Request" curl "https://smoothui.dev/api/v1/components?category=navigation&pageSize=10" ``` <BodyText> **Query parameters:** </BodyText> | Parameter | Type | Default | Description | | --------------- | ------- | ------- | ------------------------------------------------------------------------------------------------------------------- | | `category` | string | - | Filter by category: `basic-ui`, `button`, `text`, `ai`, `layout`, `feedback`, `data-display`, `navigation`, `other` | | `complexity` | string | - | Filter by complexity: `simple`, `moderate`, `complex` | | `animationType` | string | - | Filter by animation: `spring`, `tween`, `gesture`, `scroll`, `none` | | `tag` | string | - | Filter by tag (case-insensitive exact match) | | `page` | integer | `1` | Page number (1-based) | | `pageSize` | integer | `50` | Items per page (max 100) | ```json title="Response" { "data": [ { "name": "animated-tabs", "displayName": "AnimatedTabs", "description": "Tab navigation with smooth spring-based transitions.", "category": "navigation", "tags": ["animation", "tabs", "navigation"], "useCases": ["Tab navigation with smooth transitions"], "compositionHints": ["Combine with animated-tooltip for rich tab headers"], "complexity": "moderate", "animationType": "spring", "dependencies": ["motion"], "registryDependencies": [], "hasReducedMotion": true, "propsCount": 5, "installCommand": "npx shadcn@latest add @smoothui/animated-tabs", "docUrl": "https://smoothui.dev/docs/components/animated-tabs", "registryUrl": "https://smoothui.dev/r/animated-tabs.json" } ], "total": 84, "page": 1, "pageSize": 10, "totalPages": 9 } ``` <Divider orientation="horizontal" className="relative" /> ### Get Component Details <BodyText> Returns full metadata for a single component. Add `?include=source` to also retrieve the raw source code. </BodyText> ```bash title="Request" curl "https://smoothui.dev/api/v1/components/animated-tabs" ``` ```bash title="Request (with source code)" curl "https://smoothui.dev/api/v1/components/animated-tabs?include=source" ``` ```json title="Response" { "component": { "name": "animated-tabs", "displayName": "AnimatedTabs", "description": "Tab navigation with smooth spring-based transitions.", "category": "navigation", "tags": ["animation", "tabs", "navigation"], "complexity": "moderate", "animationType": "spring", "installCommand": "npx shadcn@latest add @smoothui/animated-tabs", "docUrl": "https://smoothui.dev/docs/components/animated-tabs", "registryUrl": "https://smoothui.dev/r/animated-tabs.json" }, "source": "// --- index.tsx ---\n\"use client\";\nimport { motion } from ..." } ``` <BodyText> Returns `404` if the component name does not exist. </BodyText> <Divider orientation="horizontal" className="relative" /> ### Search Components <BodyText> Keyword-based relevance search across component names, descriptions, tags, use cases, and categories. At least one of `q`, `category`, or `tags` is required. </BodyText> ```bash title="Request" curl "https://smoothui.dev/api/v1/components/search?q=modal+dialog" ``` <BodyText> **Query parameters:** </BodyText> | Parameter | Type | Required | Description | | ---------- | ------ | -------- | ---------------------------------------------- | | `q` | string | No\* | Search query | | `category` | string | No\* | Pre-filter by category | | `tags` | string | No\* | Comma-separated required tags (all must match) | <BodyText> \*At least one parameter is required. </BodyText> ```json title="Response" { "data": [ { "name": "basic-modal", "displayName": "BasicModal", "description": "Accessible modal dialog with smooth enter/exit animations.", "category": "feedback", "tags": ["modal", "dialog", "overlay"], "relevanceScore": 12 } ], "total": 3, "query": "modal dialog", "filters": {} } ``` <BodyText> Results are ranked by relevance score (higher is better). Exact name matches score highest, followed by tag matches, use case matches, description matches, and category matches. </BodyText> <Divider orientation="horizontal" className="relative" /> ### List Blocks <BodyText> Returns a paginated list of pre-built page sections (blocks). Supports filtering by block type and tag. </BodyText> ```bash title="Request" curl "https://smoothui.dev/api/v1/blocks?blockType=hero" ``` <BodyText> **Query parameters:** </BodyText> | Parameter | Type | Default | Description | | ----------- | ------- | ------- | ------------------------------------------------------------------------------------------------- | | `blockType` | string | - | Filter by type: `hero`, `features`, `pricing`, `testimonials`, `cta`, `footer`, `header`, `other` | | `tag` | string | - | Filter by tag (case-insensitive exact match) | | `page` | integer | `1` | Page number | | `pageSize` | integer | `50` | Items per page (max 100) | ```json title="Response" { "data": [ { "name": "hero-section", "displayName": "HeroSection", "description": "Animated hero section with gradient text and CTA buttons.", "blockType": "hero", "components": ["animated-gradient-text", "magnetic-button"], "category": "layout", "tags": ["hero", "landing-page"], "complexity": "moderate", "animationType": "spring", "installCommand": "npx shadcn@latest add @smoothui/hero-section" } ], "total": 5, "page": 1, "pageSize": 50, "totalPages": 1 } ``` <Divider orientation="horizontal" className="relative" /> ### Get Block Details <BodyText> Returns full metadata for a single block. Add `?include=source` for raw source code. </BodyText> ```bash title="Request" curl "https://smoothui.dev/api/v1/blocks/hero-section?include=source" ``` <BodyText> Returns `404` if the block name does not exist. </BodyText> <Divider orientation="horizontal" className="relative" /> ### Suggest Components <BodyText> Given a natural-language description of what you need, returns the top 10 most relevant components and blocks. This endpoint is particularly useful for AI agents selecting components based on a user's request. </BodyText> ```bash title="Request" curl "https://smoothui.dev/api/v1/suggest?need=animated+tab+navigation" ``` | Parameter | Type | Required | Description | | --------- | ------ | -------- | --------------------------------------------- | | `need` | string | Yes | Natural-language description of what you need | ```json title="Response" { "need": "animated tab navigation", "suggestions": [ { "type": "component", "name": "animated-tabs", "displayName": "AnimatedTabs", "description": "Tab navigation with smooth spring-based transitions.", "category": "navigation", "relevanceScore": 21, "installCommand": "npx shadcn@latest add @smoothui/animated-tabs", "docUrl": "https://smoothui.dev/docs/components/animated-tabs", "registryUrl": "https://smoothui.dev/r/animated-tabs.json" } ], "total": 1 } ``` <BodyText> Suggestions include both components and blocks, distinguished by the `type` field. Results are ranked by keyword relevance. </BodyText> <Divider orientation="horizontal" className="relative" /> ## Error Handling <BodyText> All error responses use a consistent JSON envelope: </BodyText> ```json title="Error response" { "error": "Component \"unknown\" not found", "status": 404 } ``` <BodyText> Common status codes: </BodyText> | Status | Meaning | | ------ | ------------------------------------------- | | `200` | Success | | `400` | Bad request (missing or invalid parameters) | | `404` | Resource not found | <Divider orientation="horizontal" className="relative" /> ## For AI Agents <BodyText> If you are building an AI agent or coding assistant that works with SmoothUI, here is the recommended workflow: </BodyText> 1. **Discovery** -- Use `/api/v1/suggest?need=...` with the user's natural-language request to find relevant components. 2. **Detail** -- Fetch full metadata and source with `/api/v1/components/{name}?include=source`. 3. **Install** -- Use the `installCommand` field from the metadata to install the component. 4. **Integrate** -- Use the source code and `compositionHints` to wire the component into the user's project. <BodyText> You can also fetch the full [OpenAPI specification](https://smoothui.dev/openapi.json) for automated client generation or tool registration. </BodyText> <BodyText> For MCP-based integration with AI coding assistants, see the [MCP Server](/docs/guides/mcp) guide. </BodyText> # Astro Integration (/docs/guides/astro) import { Accordion, Accordions } from 'fumadocs-ui/components/accordion'; ## Overview <BodyText> Astro's [islands architecture](https://docs.astro.build/en/concepts/islands/) lets you use SmoothUI React components as interactive islands within your static Astro pages. Each SmoothUI component hydrates independently, giving you smooth animations with minimal JavaScript overhead. </BodyText> <FeatureCard title="How It Works" variant="info"> SmoothUI components are standard React components. Astro renders them server-side and hydrates them on the client using directives like `client:load` and `client:visible`. No modifications to the components are needed. </FeatureCard> <Divider orientation="horizontal" className="relative" /> ## Prerequisites <BodyText> Before getting started, make sure you have the following: </BodyText> | Requirement | Minimum Version | Purpose | | ------------------------------------------------------------------------------ | --------------- | --------------------------- | | [Node.js](https://nodejs.org) | 18+ | Runtime | | [Astro](https://astro.build) | 4.0+ | Framework | | [@astrojs/react](https://docs.astro.build/en/guides/integrations-guide/react/) | 4.0+ | React integration for Astro | | [Tailwind CSS](https://tailwindcss.com) | 4.0+ | Styling | | [Motion](https://motion.dev) | 12.0+ | Animations (Framer Motion) | <Divider orientation="horizontal" className="relative" /> ## Project Setup <div className="fd-steps"> <div className="fd-step"> ### Create a New Astro Project <BodyText> If you're starting from scratch, create a new Astro project: </BodyText> <PackageManagerTabs pnpm="pnpm create astro@latest my-smoothui-app" npm="npm create astro@latest my-smoothui-app" yarn="yarn create astro my-smoothui-app" bun="bunx create-astro@latest my-smoothui-app" /> </div> <div className="fd-step"> ### Add the React Integration <BodyText> SmoothUI components are React components, so you need `@astrojs/react`: </BodyText> <PackageManagerTabs pnpm="pnpm astro add react" npm="npx astro add react" yarn="yarn astro add react" bun="bunx astro add react" /> <BodyText> This automatically updates your `astro.config.mjs{:js}` to include the React integration: </BodyText> ```js title="astro.config.mjs" import { defineConfig } from "astro/config"; import react from "@astrojs/react"; export default defineConfig({ integrations: [react()], }); ``` </div> <div className="fd-step"> ### Set Up Tailwind CSS 4 <BodyText> Install Tailwind CSS and the Astro integration: </BodyText> <PackageManagerTabs pnpm="pnpm astro add tailwind && pnpm add tailwindcss @tailwindcss/vite" npm="npx astro add tailwind && npm install tailwindcss @tailwindcss/vite" yarn="yarn astro add tailwind && yarn add tailwindcss @tailwindcss/vite" bun="bunx astro add tailwind && bun add tailwindcss @tailwindcss/vite" /> <BodyText> Add the Tailwind CSS Vite plugin to your Astro config: </BodyText> ```js title="astro.config.mjs" import { defineConfig } from "astro/config"; import react from "@astrojs/react"; import tailwindcss from "@tailwindcss/vite"; export default defineConfig({ integrations: [react()], vite: { plugins: [tailwindcss()], }, }); ``` <BodyText> Create your main CSS file and import Tailwind: </BodyText> ```css title="src/styles/global.css" @import "tailwindcss"; ``` <BodyText> Import the stylesheet in your layout: </BodyText> ```astro title="src/layouts/Layout.astro" --- interface Props { title: string; } const { title } = Astro.props; --- <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>{title} ```
### Install Motion SmoothUI animations are powered by Motion (Framer Motion). Install it as a dependency:
### Configure Path Aliases SmoothUI components use the `@/{:js}` path alias. Add it to your `tsconfig.json{:js}`: ```json title="tsconfig.json" { "extends": "astro/tsconfigs/strict", "compilerOptions": { "baseUrl": ".", "paths": { "@/*": ["./src/*"] } } } ```
## Installing SmoothUI Components ### Using the SmoothUI CLI ### Using the shadcn CLI If this is your first time using the shadcn CLI in an Astro project, it will prompt you to create a `components.json{:js}` file. Accept the defaults — the CLI auto-detects Astro projects and configures paths accordingly. ## Client Directives Astro components are static by default. To make SmoothUI components interactive, you need to add a [client directive](https://docs.astro.build/en/reference/directives-reference/#client-directives) that tells Astro when to hydrate the component. | Directive | When It Hydrates | Best For | | ----------------------------- | ------------------------------------ | ------------------------------------------------ | | `client:load{:astro}` | Immediately on page load | Above-the-fold components, critical interactions | | `client:visible{:astro}` | When the component scrolls into view | Below-the-fold components, cards, animations | | `client:idle{:astro}` | When the browser is idle | Non-critical UI, background animations | | `client:only="react"{:astro}` | Client-only, no SSR | Components that use browser APIs on mount | Use `client:visible{:astro}` for most SmoothUI components — it gives the best performance since components only hydrate when the user can see them. Use `client:load{:astro}` for hero sections or components that must be interactive immediately. ## Using Components in Astro Pages Here is a complete example of using a SmoothUI component in an Astro page: ```astro title="src/pages/index.astro" --- import Layout from "../layouts/Layout.astro"; import { SiriOrb } from "@/components/smoothui/ui/SiriOrb"; ---

SmoothUI in Astro

``` ### Using Multiple Components ```astro title="src/pages/demo.astro" --- import Layout from "../layouts/Layout.astro"; import { MagneticButton } from "@/components/smoothui/ui/MagneticButton"; import { ExpandableCards } from "@/components/smoothui/ui/ExpandableCards"; import { TypewriterText } from "@/components/smoothui/ui/TypewriterText"; ---
Get Started
``` ## Motion in Astro Islands Motion (Framer Motion) works seamlessly inside Astro islands. Since each island is a fully hydrated React component, all animation features are available — spring physics, layout animations, gestures, and `AnimatePresence{:tsx}`. If you create custom animated components alongside SmoothUI, follow the same pattern: ```tsx title="src/components/FadeIn.tsx" "use client"; import { motion, useReducedMotion } from "motion/react"; import type { ReactNode } from "react"; export type FadeInProps = { children: ReactNode; }; const FadeIn = ({ children }: FadeInProps) => { const shouldReduceMotion = useReducedMotion(); return ( {children} ); }; export default FadeIn; ``` ```astro title="src/pages/index.astro" --- import FadeIn from "../components/FadeIn"; ---

This content fades in when scrolled into view.

``` The `"use client"{:tsx}` directive at the top of React component files is a Next.js convention. Astro ignores it, so it does no harm — and it keeps your components compatible with both frameworks. ## Troubleshooting Make sure you added a client directive (`client:load{:astro}`, `client:visible{:astro}`, etc.) to the component. Without a client directive, Astro renders the component as static HTML with no JavaScript, so animations won't run. Verify that your `global.css{:css}` includes `@import "tailwindcss"{:css}` and that it's imported in your layout. Also check that the Tailwind Vite plugin is configured in `astro.config.mjs{:js}`. If a component relies on browser-only APIs (like `window{:js}` or `localStorage{:js}`) during initial render, use `client:only="react"{:astro}` instead of `client:load{:astro}`. This skips server-side rendering entirely for that component. Motion works well with SSR by default. If you see warnings about `useLayoutEffect{:tsx}`, it's usually harmless. For components that heavily depend on browser measurements, use `client:only="react"{:astro}`. ## Next Steps Learn about all available installation methods including the SmoothUI CLI and shadcn registry. Explore the complete collection of 50+ animated React components. Master animation performance, accessibility, and timing guidelines. The simplest setup for using SmoothUI in a client-side React app. Full-stack SSR setup with Remix and React Router v7. Type-safe full-stack React with streaming SSR. # Changelog (/docs/guides/changelog) ## 3.1.0 ### New Components * Added **Magnetic Button** component with cursor-following magnetic effect and shadcn-style button variants * Added **Notification Badge** component with dot, count, and status variants * Added **Skeleton Loader** component with shimmer, pulse, and wave animation variants * Added **Animated Tabs** component with underline, pill, and segment style variants * Added **Animated Toggle** component with morph and icon transition variants ### New Blocks * Added **FAQ 3** block with searchable questions and filter animations * Added **FAQ 4** block with categorized questions and tab navigation * Added **Footer 3** mega footer block with newsletter signup * Added **Footer 4** minimal single-row footer block * Added **Logo Cloud 3** block with infinite marquee and pause on hover * Added **Logo Cloud 4** block with interactive grid and hover effects ## 3.0.6 * Enhanced accessibility and keyboard navigation across all input components * Added motion reduction support (`prefers-reduced-motion`) across components * Integrated motion reduction in AI Branch component ## 3.0.5 * Added **TweetCard** component for displaying Twitter/X posts with media support * Enhanced TweetCard security with DOMPurify sanitization ## 3.0.4 * Added **SwitchboardCard** component with animated light grid effect * Added **Header 4** block with interactive 3D grid hero section * Enhanced dropdown components with portal rendering and position handling ## 3.0.3 * Added **Searchable Dropdown** component with search filtering and keyboard navigation * Improved Wave Text animation performance ## 3.0.2 * Added GlowHover component with cursor-following glow effect - generic and reusable component that works with any React element (cards, buttons, etc.) * Added InfiniteSlider component for smooth, infinite scrolling with customizable speed and direction * Added ReviewsCarousel component for displaying testimonials with smooth animations and keyboard navigation * Enhanced AppleInvites component with responsive sizing and styling support * Improved RSS feed processing for blocks with better categorization and date extraction * Optimized image loading across components with enhanced getImageKitUrl options * Refactored ScrollableCardStack component to use images instead of videos for better performance * Fixed GitHub Stars Animation component issues ## 3.0.1 * Added RSS feed integration using @wandry/analytics-sdk for component registry updates * Fixed Safari rendering bug in Siri Orb component with improved mask-radius handling * Created dedicated sponsors page with tier-based sections (Velocity, Supporters, Own Projects) * Enhanced sponsor display components with rotation and empty state handling ## 3.0.0 * Complete monorepo restructure with improved organization and maintainability * Migrated to Next.js 16 with latest features and performance improvements * Integrated Fumadocs for better documentation experience * Added Ultracite for enhanced code quality and tooling * Implemented Biome for fast linting and formatting * Improved build system and package management * Enhanced developer experience with better TypeScript configuration * Updated all dependencies to latest stable versions ## 2.9.0 * New Logo Clouds, Stats, Team, Footer, and FAQs blocks sections * Enhanced sidebar filter system with All, Components, and Blocks categories * Improved navigation with conditional sidebar content * Better content organization separating components from blocks ## 2.8.0 * New comprehensive search system with keyboard shortcuts and real-time results * Advanced tag-based component discovery with categorized organization * New tag pages with related components and category information * Enhanced component search dialog with popular tags and smart suggestions ## 2.7.0 * Full compatibility with shadcn CLI v3 namespace system * New registry system with automatic dependency management * MCP (Model Context Protocol) support for AI assistants * Enhanced documentation with comprehensive installation guides ## 2.6.0 * New AI section with AI-powered components * New components: AI Input, AI Branch, Scrollable Card Stack, Rich Popover * New AI menu in the landing page navigation ## 2.0.0 * New Design System and website look * New mascot called Smoothy * Props documentation * Color switcher * Refine shadcn/ui installation ## 1.0.0 * Initial release of SmoothUI * Core component library with React and Framer Motion * Basic documentation and examples * CLI tool for component installation # Design Principles (/docs/guides/design-principles) ## Design Philosophy SmoothUI is built on the principles of simplicity, accessibility, and performance. Each component is designed to be beautiful by default while remaining highly customizable.
## Color System SmoothUI uses a carefully crafted color system based on OKLCH color space for better color consistency and accessibility. The system includes both light and dark variants. ### Brand Colors
oklch(0.72 0.2 352.53)
oklch(0.66 0.21 354.31)
### Neutral Colors The neutral color palette provides a range of grays that work well in both light and dark modes.

50

100

200

300

400

500

600

700

800

900

950

1000

## Design System CSS Add this CSS to your global styles to enable the full SmoothUI design system:
Expand CSS
```css title="global.css" @import "tailwindcss"; @import "tw-animate-css"; @custom-variant dark (&:is(.dark *)); @theme inline { --color-brand: var(--color-brand); --color-brand-secondary: var(--color-brand-secondary); --color-smooth-50: var(--color-smooth-50); --color-smooth-100: var(--color-smooth-100); --color-smooth-200: var(--color-smooth-200); --color-smooth-300: var(--color-smooth-300); --color-smooth-400: var(--color-smooth-400); --color-smooth-500: var(--color-smooth-500); --color-smooth-600: var(--color-smooth-600); --color-smooth-700: var(--color-smooth-700); --color-smooth-800: var(--color-smooth-800); --color-smooth-900: var(--color-smooth-900); --color-smooth-950: var(--color-smooth-950); --color-smooth-1000: var(--color-smooth-1000); --color-border: var(--color-smooth-500); --color-sidebar-ring: var(--color-brand); --color-sidebar-border: var(--color-smooth-400); --color-sidebar-accent-foreground: var(--color-smooth-900); --color-sidebar-accent: var(--sidebar-accent); --color-sidebar-primary-foreground: var(--color-smooth-1000); --color-sidebar-primary: var(--color-brand); --color-sidebar-foreground: var(--color-smooth-1000); --color-sidebar: var(--color-smooth-100); --color-ring: var(--color-brand); --color-input: var(--color-smooth-400); --color-destructive: var(--destructive); --color-accent-foreground: var(--color-smooth-1000); --color-accent: var(--color-brand); --color-muted-foreground: var(--color-smooth-800); --color-muted: var(--color-smooth-200); --color-background: var(--color-smooth-50); --color-foreground: var(--color-smooth-1000); --color-primary: var(--color-smooth-100); --color-primary-foreground: var(--color-smooth-950); --color-secondary: var(--color-smooth-200); --color-secondary-foreground: var(--color-smooth-900); --color-popover-foreground: var(--color-smooth-1000); --color-popover: var(--color-smooth-50); --color-card-foreground: var(--color-smooth-1000); --color-card: var(--color-smooth-100); --radius-sm: calc(var(--radius) - 4px); --radius-md: calc(var(--radius) - 2px); --radius-lg: var(--radius); --radius-xl: calc(var(--radius) + 4px); } :root { --color-brand: oklch(0.72 0.2 352.53); --color-brand-secondary: oklch(0.66 0.21 354.31); --color-smooth-50: oklch(99.11% 0 0); --color-smooth-100: oklch(97.91% 0 0); --color-smooth-200: oklch(96.42% 0 0); --color-smooth-300: oklch(94.61% 0 0); --color-smooth-400: oklch(93.1% 0 0); --color-smooth-500: oklch(91.28% 0 0); --color-smooth-600: oklch(89.14% 0 0); --color-smooth-700: oklch(82.97% 0 0); --color-smooth-800: oklch(65% 0 0); --color-smooth-900: oklch(61.67% 0 0); --color-smooth-950: oklch(54.17% 0 0); --color-smooth-1000: oklch(20.46% 0 0); --border: var(--color-smooth-300); --text-primary: var(--color-smooth-200); --text-quaternary: var(--color-smooth-1000); --radius: 0.625rem; } .dark { --color-smooth-50: oklch(20.02% 0 0); --color-smooth-100: oklch(22.64% 0 0); --color-smooth-200: oklch(25.62% 0 0); --color-smooth-300: oklch(27.68% 0 0); --color-smooth-400: oklch(30.12% 0 0); --color-smooth-500: oklch(32.5% 0 0); --color-smooth-600: oklch(36.39% 0 0); --color-smooth-700: oklch(43.13% 0 0); --color-smooth-800: oklch(54.52% 0 0); --color-smooth-900: oklch(59.31% 0 0); --color-smooth-950: oklch(70.58% 0 0); --color-smooth-1000: oklch(94.61% 0 0); --border: var(--color-smooth-300); --text-primary: var(--color-smooth-200); --text-quaternary: var(--color-smooth-1000); } /* Component NumberFlow */ @layer utilities { .slide-in-up { animation: slideInUp 0.3s forwards; } .slide-out-up { animation: slideOutUp 0.3s forwards; } .slide-in-down { animation: slideInDown 0.3s forwards; } .slide-out-down { animation: slideOutDown 0.3s forwards; } @keyframes slideInUp { from { transform: translateY(50px); filter: blur(5px); } to { transform: translateY(0px); filter: blur(0px); } } @keyframes slideOutUp { from { transform: translateY(0px); filter: blur(0px); } to { transform: translateY(-50px); filter: blur(5px); } } @keyframes slideInDown { from { transform: translateY(-50px); filter: blur(5px); } to { transform: translateY(0px); filter: blur(0px); } } @keyframes slideOutDown { from { transform: translateY(0px); filter: blur(0px); } to { transform: translateY(50px); filter: blur(5px); } } } /* Component PowerOffSlide */ @layer utilities { .loading-shimmer { text-fill-color: transparent; -webkit-text-fill-color: transparent; animation-delay: 0.5s; animation-duration: 3s; animation-iteration-count: infinite; animation-name: loading-shimmer; background: var(--text-quaternary) gradient( linear, 100% 0, 0 0, from(var(--text-quaternary)), color-stop(0.5, var(--text-primary)), to(var(--text-quaternary)) ); background: var(--text-quaternary) -webkit-gradient( linear, 100% 0, 0 0, from(var(--text-quaternary)), color-stop(0.5, var(--text-primary)), to(var(--text-quaternary)) ); background-clip: text; -webkit-background-clip: text; background-repeat: no-repeat; background-size: 50% 200%; display: inline-block; } .loading-shimmer { background-position: -100% top; } .loading-shimmer:hover { -webkit-text-fill-color: var(--text-quaternary); animation: none; background: transparent; } @keyframes loading-shimmer { 0% { background-position: -100% top; } to { background-position: 250% top; } } } /* Component AppleInvites */ @layer utilities { .gradient-mask-t-0 { -webkit-mask-image: linear-gradient(#0000, #000); mask-image: linear-gradient(#0000, #000); } } ```
## Customization SmoothUI components are highly customizable. Here are the main ways to customize them: Override CSS variables to customize colors, spacing, and other design tokens globally. Use Tailwind utility classes to customize individual components or create variants. Many components accept props for customization like size, variant, and color options. # React Hooks (/docs/guides/hooks) ## Overview SmoothUI provides utility hooks that help you build responsive, device-aware components. These hooks are designed for performance and work seamlessly with Server-Side Rendering (SSR). *** ## useIsMobile Detects whether the current viewport is mobile-sized. Returns a boolean that updates in real-time as the viewport changes. ### Installation ```bash npx shadcn@latest add @smoothui/use-mobile ``` Or copy the hook directly: ```tsx import * as React from "react"; const MOBILE_BREAKPOINT = 768; export function useIsMobile() { const [isMobile, setIsMobile] = React.useState( undefined ); React.useEffect(() => { const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`); const onChange = () => { setIsMobile(window.innerWidth < MOBILE_BREAKPOINT); }; mql.addEventListener("change", onChange); setIsMobile(window.innerWidth < MOBILE_BREAKPOINT); return () => mql.removeEventListener("change", onChange); }, []); return !!isMobile; } ``` ### Usage ```tsx import { useIsMobile } from "@/hooks/use-mobile"; function ResponsiveComponent() { const isMobile = useIsMobile(); return (
{isMobile ? ( ) : ( )}
); } ``` ### Parameters This hook takes no parameters. The mobile breakpoint is set to **768px** by default. ### Returns | Value | Type | Description | | ---------- | --------- | ------------------------------------------- | | `isMobile` | `boolean` | `true` if viewport width is less than 768px | ### Features * **SSR Safe**: Returns `false` during server-side rendering (no hydration mismatch) * **Real-time Updates**: Responds to viewport changes via `matchMedia` listener * **Performance Optimized**: Uses `matchMedia` instead of resize events for better performance * **Memory Safe**: Properly cleans up event listeners on unmount ### Common Use Cases #### Conditional Rendering ```tsx function Header() { const isMobile = useIsMobile(); return (
{isMobile ? : }
); } ``` #### Responsive Animations ```tsx import { motion } from "motion/react"; import { useIsMobile } from "@/hooks/use-mobile"; function AnimatedCard() { const isMobile = useIsMobile(); return ( Card content ); } ``` #### Responsive Grid ```tsx function ProductGrid({ products }) { const isMobile = useIsMobile(); const columns = isMobile ? 1 : 3; return (
{products.map(product => ( ))}
); } ``` ### SSR Considerations The hook returns `false` on the initial server render, then updates on the client. If you need to avoid layout shift, consider: ```tsx function ResponsiveLayout() { const isMobile = useIsMobile(); const [mounted, setMounted] = React.useState(false); React.useEffect(() => { setMounted(true); }, []); // Show a loading state or neutral layout until mounted if (!mounted) { return ; } return isMobile ? : ; } ``` ### Customizing the Breakpoint If you need a different breakpoint, create a modified version: ```tsx const TABLET_BREAKPOINT = 1024; export function useIsTablet() { const [isTablet, setIsTablet] = React.useState( undefined ); React.useEffect(() => { const mql = window.matchMedia(`(max-width: ${TABLET_BREAKPOINT - 1}px)`); const onChange = () => { setIsTablet(window.innerWidth < TABLET_BREAKPOINT); }; mql.addEventListener("change", onChange); setIsTablet(window.innerWidth < TABLET_BREAKPOINT); return () => mql.removeEventListener("change", onChange); }, []); return !!isTablet; } ``` *** ## Best Practices ### Prefer CSS for Simple Responsive Layouts For simple responsive styling, CSS media queries are more performant than JavaScript: ```tsx // Prefer CSS when possible
// Use hooks for complex logic or conditional rendering const isMobile = useIsMobile(); if (isMobile) return ; ``` ### Avoid Excessive Re-renders The hook only triggers re-renders when crossing the breakpoint threshold, not on every resize event. ### Test Across Devices Always test responsive behavior on actual devices, not just browser dev tools resizing. *** ## Related Explore utility functions like cn() for class merging. Learn how to create performant, accessible animations. # Introduction (/docs/guides) import { Accordion, Accordions } from 'fumadocs-ui/components/accordion'; ## What is SmoothUI? SmoothUI is a modern component library that brings together the best of React, Tailwind CSS, [Motion](https://motion.dev), and [GSAP](https://gsap.com) to create beautiful, accessible, and performant user interfaces. Each component is carefully crafted with smooth animations and thoughtful design principles.
## Key Features * **shadcn CLI Compatible**: Install components using the familiar shadcn CLI * **MCP Support**: AI assistants can discover and install components automatically * **TypeScript First**: Full type safety with comprehensive TypeScript support * **Accessible by Default**: Built with accessibility best practices * **Dark Mode Support**: All components work seamlessly in light and dark themes * **Customizable**: Easy to customize with Tailwind CSS classes * **Performance Optimized**: Built with performance in mind using modern React patterns ## Get Started Learn how to install SmoothUI components using shadcn CLI or manual installation methods. Explore all available components with live demos and documentation. ## Frequently Asked Questions Yes! SmoothUI is completely free and open source. You can use it in personal and commercial projects. No! All animations are built-in. You can use components without any Motion or GSAP knowledge. Absolutely! All components are built with Tailwind CSS and can be customized using standard Tailwind classes. Yes! SmoothUI works with any React framework including Next.js, Vite, Create React App, and more. ## Contributing We welcome contributions to SmoothUI! Whether you want to add new components, improve existing ones, or fix bugs, your contributions help make SmoothUI better for everyone. * Fork the repository on GitHub * Create a new branch for your feature or bug fix * Make your changes and test them thoroughly * Submit a pull request with a clear description Check out our [contributing guide](https://github.com/educlopez/smoothui/blob/main/CONTRIBUTING.md) for more detailed information. # Installation (/docs/guides/installation) SmoothUI works with any React-compatible framework. Check out the dedicated setup guides: * **[Vite + React](/docs/guides/vite)** — The simplest setup for client-side React apps * **[Astro](/docs/guides/astro)** — Islands architecture with selective hydration * **[Remix](/docs/guides/remix)** — Full-stack SSR with React Router v7 * **[TanStack Start](/docs/guides/tanstack-start)** — Type-safe full-stack with streaming SSR ## Installation (SmoothUI CLI) The SmoothUI CLI provides an interactive way to browse and install components with automatic dependency resolution. ### Add Components ### Add Multiple Components ### Interactive Mode ### List Available Components Run the add command without arguments to launch an interactive picker. Search and browse components by category, then select multiple components to install at once. *** ## Installation (shadcn Registry) SmoothUI is an official shadcn registry, so you can install components directly without any configuration. Just use the `@smoothui{:js}` namespace. Since SmoothUI is an official registry, you don't need to add anything to your `components.json{:js}` file. Just install components directly! ### Install Components Install SmoothUI components using the shadcn CLI with the `@smoothui{:js}` namespace: ### Install Multiple Components ### Use Components Import and use the installed components in your React application: ```tsx import { SiriOrb } from "@/components/smoothui/ui/SiriOrb" import { RichPopover } from "@/components/smoothui/ui/RichPopover" export default function App() { return (
) } ``` # MCP Server (/docs/guides/mcp) # MCP Server MCP support for registry developers - Enable AI assistants to discover and use SmoothUI components. The **shadcn MCP server** works out of the box with any shadcn-compatible registry. You do not need to do anything special to enable MCP support for your SmoothUI registry. ## Prerequisites The MCP server works by requesting your registry index. Make sure you have a registry item file at the root of your registry named `registry.json{:js}`. For example, if your registry is hosted at `https://smoothui.dev/r/[name].json{:js}`, you should have a file at `https://smoothui.dev/r/registry.json{:js}`. This file must be a valid JSON file that conforms to the registry schema. ## Configuring MCP Ask your registry consumers to configure your registry in their `components.json{:js}` file and install the shadcn MCP server:
**Configure your registry** in your `components.json{:js}` file: ```json title="components.json" { "registries": { // [!code highlight] "@smoothui": "https://smoothui.dev/r/{name}.json" } } ``` **Run the following command** in your project: ```shell title="Terminal" pnpm dlx shadcn@latest mcp init --client claude ``` ```shell title="Terminal" npx shadcn@latest mcp init --client claude ``` ```shell title="Terminal" yarn dlx shadcn@latest mcp init --client claude ``` ```shell title="Terminal" bunx shadcn@latest mcp init --client claude ``` **Restart Claude Code** and try the following prompts: * Show me the components in the smoothui registry * Create a landing page using items from the smoothui registry * Install the SiriOrb component from smoothui **Note:** You can use `/mcp{:js}` command in Claude Code to debug the MCP server.
**Configure your registry** in your `components.json{:js}` file: ```json title="components.json" { "registries": { // [!code highlight] "@smoothui": "https://smoothui.dev/r/{name}.json" } } ``` **Run the following command** in your project: ```shell title="Terminal" pnpm dlx shadcn@latest mcp init --client cursor ``` ```shell title="Terminal" npx shadcn@latest mcp init --client cursor ``` ```shell title="Terminal" yarn dlx shadcn@latest mcp init --client cursor ``` ```shell title="Terminal" bunx shadcn@latest mcp init --client cursor ``` Open **Cursor Settings** and **Enable the MCP server** for shadcn. Then try the following prompts: * Show me the components in the smoothui registry * Create a landing page using items from the smoothui registry * Install the SiriOrb component from smoothui
**Configure your registry** in your `components.json{:js}` file: ```json title="components.json" { "registries": { // [!code highlight] "@smoothui": "https://smoothui.dev/r/{name}.json" } } ``` **Run the following command** in your project: ```shell title="Terminal" pnpm dlx shadcn@latest mcp init --client vscode ``` ```shell title="Terminal" npx shadcn@latest mcp init --client vscode ``` ```shell title="Terminal" yarn dlx shadcn@latest mcp init --client vscode ``` ```shell title="Terminal" bunx shadcn@latest mcp init --client vscode ``` Open `.vscode/mcp.json{:js}` and click **Start** next to the shadcn server. Then try the following prompts with GitHub Copilot: * Show me the components in the smoothui registry * Create a landing page using items from the smoothui registry * Install the SiriOrb component from smoothui
## Example Prompts Once MCP is configured, you can use these prompts with your AI assistant:

Component Discovery

  • “Show me all available components in the smoothui registry”
  • “What animation components are available in smoothui?”
  • “List all interactive components from smoothui”

Component Installation

  • “Install the SiriOrb component from smoothui”
  • “Add the RichPopover component to my project”
  • “Install multiple components: SiriOrb, AnimatedInput, and ScrollableCardStack”

Component Usage

  • “Create a landing page using the SiriOrb component”
  • “Show me how to use the ScrollableCardStack component”
  • “Build a dashboard with smoothui components”
## Learn More Full overview of all AI integration options — MCP, REST API, and machine-readable catalogs. Complete API reference for programmatic access to the component catalog. You can also read more about the shadcn MCP protocol in the shadcn MCP documentation. # Remix (/docs/guides/remix) import { Accordion, Accordions } from 'fumadocs-ui/components/accordion'; ## Overview [Remix](https://remix.run) is a full-stack React framework focused on web standards and progressive enhancement. As of v2, Remix has evolved into the framework mode of [React Router v7](https://reactrouter.com), bringing the same SSR-first architecture with a streamlined API. SmoothUI components work seamlessly in both Remix and React Router v7 projects. SmoothUI components are standard React client components. Remix renders them on the server and hydrates them on the client. The `"use client"{:tsx}` directive ensures components with animations and browser APIs hydrate correctly. No special wrappers are needed for most components. ## Prerequisites Before getting started, make sure you have the following: | Requirement | Minimum Version | Purpose | | -------------------------------------------------------------------- | --------------- | -------------------------- | | [Node.js](https://nodejs.org) | 18+ | Runtime | | [Remix](https://remix.run) / [React Router](https://reactrouter.com) | 2.0+ / 7.0+ | Framework | | [React](https://react.dev) | 19.0+ | UI library | | [Tailwind CSS](https://tailwindcss.com) | 4.0+ | Styling | | [Motion](https://motion.dev) | 12.0+ | Animations (Framer Motion) | Remix has merged into React Router v7. If you're starting a new project, use `create react-router{:bash}`. Existing Remix v2 projects can upgrade to React Router v7 — see the [migration guide](https://reactrouter.com/upgrading/remix). Both setups work identically with SmoothUI. ## Project Setup
### Create a New Project If you're starting from scratch, create a new React Router v7 project (the successor to Remix): Then install dependencies:
### Set Up Tailwind CSS 4 Remix and React Router v7 use Vite under the hood, so Tailwind CSS 4 setup uses the Vite plugin: Add the Tailwind CSS Vite plugin to your Vite config: ```ts title="vite.config.ts" import { reactRouter } from "@react-router/dev/vite"; import { defineConfig } from "vite"; import tailwindcss from "@tailwindcss/vite"; import tsconfigPaths from "vite-tsconfig-paths"; export default defineConfig({ plugins: [tailwindcss(), reactRouter(), tsconfigPaths()], }); ``` Update your main CSS file with the Tailwind import: ```css title="app/app.css" @import "tailwindcss"; ```
### Install Motion SmoothUI animations are powered by Motion (Framer Motion). Install it as a dependency:
### Configure Path Aliases SmoothUI components use the `@/{:ts}` path alias. React Router v7 projects typically use `vite-tsconfig-paths{:ts}` to resolve paths from `tsconfig.json{:json}` automatically. Make sure your tsconfig includes the alias: ```json title="tsconfig.json" { "compilerOptions": { "baseUrl": ".", "paths": { "@/*": ["./app/*"] } } } ``` React Router v7 projects include `vite-tsconfig-paths{:ts}` by default, which reads your `tsconfig.json{:json}` paths and applies them as Vite aliases. You only need to configure paths in one place — your tsconfig.
## Installing SmoothUI Components ### Using the SmoothUI CLI ### Using the shadcn CLI If this is your first time using the shadcn CLI in a Remix / React Router project, it will prompt you to create a `components.json{:json}` file. Accept the defaults — the CLI auto-detects the project structure and configures paths accordingly. ## SSR Considerations Remix and React Router v7 render components on the server first, then hydrate them on the client. Here's what you need to know when using SmoothUI components in an SSR environment: | Concern | How SmoothUI Handles It | | ------------------------ | ---------------------------------------------------------------------------------------------------- | | `"use client"` directive | SmoothUI components include this directive. Remix respects it for client-side hydration. | | Motion SSR | Motion handles SSR gracefully — animations simply start after hydration. No special config needed. | | Browser APIs | Components that use `window{:ts}` or `localStorage{:ts}` during render need a `ClientOnly` wrapper. | | Hydration mismatches | Rare with SmoothUI. If seen, ensure no random values are generated during SSR (see Troubleshooting). | ### The ClientOnly Pattern If you use a SmoothUI component that relies on browser measurements during initial render, wrap it with a `ClientOnly` helper: ```tsx title="app/components/client-only.tsx" "use client"; import { type ReactNode, useEffect, useState } from "react"; export type ClientOnlyProps = { children: ReactNode; fallback?: ReactNode; }; const ClientOnly = ({ children, fallback = null }: ClientOnlyProps) => { const [mounted, setMounted] = useState(false); useEffect(() => { setMounted(true); }, []); return mounted ? children : fallback; }; export default ClientOnly; ``` ```tsx title="app/routes/home.tsx" import ClientOnly from "@/components/client-only"; import { SiriOrb } from "@/components/smoothui/ui/SiriOrb"; const Home = () => { return ( }> ); }; export default Home; ``` The majority of SmoothUI components work fine with SSR out of the box. Only use `ClientOnly` for components that access browser-only APIs like `window.matchMedia{:ts}` or `ResizeObserver{:ts}` during their initial render. ## Using Components in Routes Here is a complete example of using SmoothUI components in a Remix / React Router v7 route: ```tsx title="app/routes/home.tsx" import { SiriOrb } from "@/components/smoothui/ui/SiriOrb"; import { MagneticButton } from "@/components/smoothui/ui/MagneticButton"; const Home = () => { return (

SmoothUI + Remix

Get Started
); }; export default Home; ``` ### Custom Animated Components If you create custom animated components alongside SmoothUI, follow the same pattern: ```tsx title="app/components/FadeIn.tsx" "use client"; import { motion, useReducedMotion } from "motion/react"; import type { ReactNode } from "react"; export type FadeInProps = { children: ReactNode; }; const FadeIn = ({ children }: FadeInProps) => { const shouldReduceMotion = useReducedMotion(); return ( {children} ); }; export default FadeIn; ``` ## Troubleshooting Hydration mismatches occur when the server-rendered HTML differs from what the client renders. Common causes: using `Math.random(){:ts}`, `Date.now(){:ts}`, or browser APIs during render. Use the `ClientOnly` pattern shown above for components that depend on browser-only values. If you see `useLayoutEffect{:tsx}` warnings in your server logs, they're harmless — Motion uses `useLayoutEffect{:tsx}` for performance, and React warns when it's called during SSR. The animations will work correctly after hydration. To suppress the warning, you can use `client:only` or the `ClientOnly` wrapper. Verify that `@tailwindcss/vite{:ts}` is included in your `vite.config.ts{:ts}` plugins array and that your `app/app.css{:css}` (or `app/root.css{:css}`) contains `@import "tailwindcss"{:css}`. Also check that the CSS file is imported in your root route. When using `ClientOnly`, provide a `fallback{:tsx}` with the same dimensions as the component to prevent layout shifts. For example: `}>{:tsx}`. ## Next Steps Learn about all available installation methods including the SmoothUI CLI and shadcn registry. Explore the complete collection of 50+ animated React components. Master animation performance, accessibility, and timing guidelines. The simplest setup for using SmoothUI in a client-side React app. # SmoothUI vs shadcn/ui (/docs/guides/shadcn-alternative) import { Accordion, Accordions } from 'fumadocs-ui/components/accordion'; ## The Best of Both Worlds SmoothUI isn't a replacement for shadcn/ui - it's the perfect companion. While shadcn/ui excels at providing solid, accessible base components, SmoothUI extends the ecosystem with **animated, interactive components** that bring your interfaces to life.
## Why Choose SmoothUI? ### Smooth Motion Animations Every SmoothUI component is built with **[Motion](https://motion.dev)** and **[GSAP](https://gsap.com)** animations that feel natural and polished. No more wrestling with CSS keyframes or animation libraries - animations are built-in and optimized for performance. ```tsx // Just import and use - animations included import { ExpandableCards } from "@/components/ui/expandable-cards" ``` ### Same Workflow, Added Motion If you're familiar with shadcn/ui, you'll feel right at home. SmoothUI uses the **same CLI installation pattern**: ```bash npx shadcn@latest add @smoothui/expandable-cards ``` Components are copied into your project, giving you full ownership and customization control. ### Built for Modern React SmoothUI components follow React best practices: * **Server Components compatible** - Works with Next.js App Router * **TypeScript first** - Full type definitions included * **Tailwind CSS v4** - Uses the latest Tailwind features * **Accessibility** - Respects `prefers-reduced-motion` ## Feature Comparison | Feature | shadcn/ui | SmoothUI | | ------------------- | ------------ | ------------ | | Static Components | Excellent | Good | | Animated Components | Limited | Excellent | | Motion Animations | Manual setup | Built-in | | Installation | shadcn CLI | shadcn CLI | | Customization | Full control | Full control | | TypeScript | Yes | Yes | | Tailwind CSS | v3/v4 | v4 | | Dark Mode | Yes | Yes | | Accessibility | Excellent | Good | | Component Count | 40+ | 50+ | ## When to Use Each ### Use shadcn/ui for: * Form inputs, selects, and form validation * Modal dialogs and alert dialogs * Navigation menus and dropdowns * Data tables and pagination * Basic buttons and badges ### Use SmoothUI for: * Animated card layouts and expandable cards * Smooth hover effects and micro-interactions * Dynamic content transitions * Interactive showcases and galleries * Animated text effects (typewriter, wave, scramble) * Loading states with motion ## Working Together The best approach is using both libraries together. Here's a typical setup: ```tsx // shadcn/ui for the form structure import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Dialog, DialogContent } from "@/components/ui/dialog" // SmoothUI for animated elements import { AnimatedInput } from "@/components/ui/animated-input" import { ScrambleHover } from "@/components/ui/scramble-hover" import { ExpandableCards } from "@/components/ui/expandable-cards" ``` Both libraries use the same folder structure (`components/ui/`) and Tailwind CSS foundation, making them seamlessly compatible. ## Get Started Set up SmoothUI in your project alongside shadcn/ui. Explore 50+ animated components ready to use. ## Frequently Asked Questions No! SmoothUI is designed to complement shadcn/ui, not replace it. Use shadcn/ui for forms and foundational UI, and add SmoothUI components when you need animations and interactivity. Absolutely! Both libraries use the same installation pattern and folder structure. They work together seamlessly in the same project. Minimal. If you're familiar with shadcn/ui, you already know the workflow. SmoothUI components follow the same patterns - just with added animations. SmoothUI animations are built with Motion and GSAP, optimized for performance. They use GPU-accelerated transforms and respect the user's reduced motion preferences for accessibility. # Sponsors (/docs/guides/sponsors) # TanStack Start (/docs/guides/tanstack-start) import { Accordion, Accordions } from 'fumadocs-ui/components/accordion'; ## Overview [TanStack Start](https://tanstack.com/start) is a modern full-stack React framework built on [Vinxi](https://vinxi.vercel.app) (a Vite-based server toolkit) and [TanStack Router](https://tanstack.com/router). It provides type-safe routing, streaming SSR, and server functions out of the box. SmoothUI components integrate smoothly with TanStack Start's architecture. TanStack Start uses Vite under the hood via Vinxi, so SmoothUI components work the same way as in any Vite-based project. Components are server-rendered and hydrated on the client. The `"use client"{:tsx}` directive ensures animations activate after hydration. TanStack Start is a newer framework that is evolving quickly. The setup steps below reflect the current stable release. Check the [official docs](https://tanstack.com/start/latest/docs/framework/react/overview) for the latest changes. ## Prerequisites Before getting started, make sure you have the following: | Requirement | Minimum Version | Purpose | | -------------------------------------------- | --------------- | -------------------------- | | [Node.js](https://nodejs.org) | 18+ | Runtime | | [TanStack Start](https://tanstack.com/start) | 1.0+ | Framework | | [React](https://react.dev) | 19.0+ | UI library | | [Tailwind CSS](https://tailwindcss.com) | 4.0+ | Styling | | [Motion](https://motion.dev) | 12.0+ | Animations (Framer Motion) | ## Project Setup
### Create a New TanStack Start Project If you're starting from scratch, create a new TanStack Start project: Then install dependencies:
### Set Up Tailwind CSS 4 TanStack Start uses Vinxi, which is built on Vite. Install Tailwind CSS and the Vite plugin: Add the Tailwind CSS Vite plugin to your app config: ```ts title="app.config.ts" import { defineConfig } from "@tanstack/react-start/config"; import tailwindcss from "@tailwindcss/vite"; export default defineConfig({ vite: { plugins: () => [tailwindcss()], }, }); ``` Create or update your main CSS file with the Tailwind import: ```css title="app/styles/app.css" @import "tailwindcss"; ``` Import the stylesheet in your root route (typically `app/routes/__root.tsx{:tsx}`): ```tsx title="app/routes/__root.tsx" import { createRootRoute, Outlet } from "@tanstack/react-router"; import appCss from "@/styles/app.css?url"; export const Route = createRootRoute({ head: () => ({ links: [{ rel: "stylesheet", href: appCss }], }), component: RootComponent, }); function RootComponent() { return ( ); } ```
### Install Motion SmoothUI animations are powered by Motion (Framer Motion). Install it as a dependency:
### Configure Path Aliases SmoothUI components use the `@/{:ts}` path alias. Configure it in your `tsconfig.json{:json}`: ```json title="tsconfig.json" { "compilerOptions": { "baseUrl": ".", "paths": { "@/*": ["./app/*"] } } } ``` TanStack Start resolves TypeScript paths automatically via Vinxi's Vite integration. If path aliases don't resolve at runtime, add `vite-tsconfig-paths{:ts}` to your app config: ```ts title="app.config.ts" import { defineConfig } from "@tanstack/react-start/config"; import tailwindcss from "@tailwindcss/vite"; import tsconfigPaths from "vite-tsconfig-paths"; export default defineConfig({ vite: { plugins: () => [tailwindcss(), tsconfigPaths()], }, }); ```
## Installing SmoothUI Components ### Using the SmoothUI CLI ### Using the shadcn CLI If this is your first time using the shadcn CLI in a TanStack Start project, it will prompt you to create a `components.json{:json}` file. Configure the `aliases.components{:json}` path to match your project structure (typically `@/components{:json}`). ## SSR & Streaming TanStack Start supports streaming SSR by default, which means components render progressively on the server. Here's what you need to know when using SmoothUI components: | Concern | How SmoothUI Handles It | | ------------------------ | ------------------------------------------------------------------------------------------------- | | `"use client"` directive | SmoothUI components include this directive. TanStack Start respects it for client-side hydration. | | Motion SSR | Motion handles SSR gracefully — animations start after hydration. No special config needed. | | Streaming compatibility | SmoothUI components work with streaming SSR. Animations start as each component hydrates. | | Browser APIs | Components using `window{:ts}` or `ResizeObserver{:ts}` during render need a client-only guard. | ### Client-Only Components For the rare component that needs browser APIs during initial render, use a mounted check: ```tsx title="app/components/client-only.tsx" "use client"; import { type ReactNode, useEffect, useState } from "react"; export type ClientOnlyProps = { children: ReactNode; fallback?: ReactNode; }; const ClientOnly = ({ children, fallback = null }: ClientOnlyProps) => { const [mounted, setMounted] = useState(false); useEffect(() => { setMounted(true); }, []); return mounted ? children : fallback; }; export default ClientOnly; ``` ## Using Components in Routes Here is a complete example of using SmoothUI components in a TanStack Start route: ```tsx title="app/routes/index.tsx" import { createFileRoute } from "@tanstack/react-router"; import { SiriOrb } from "@/components/smoothui/ui/SiriOrb"; import { MagneticButton } from "@/components/smoothui/ui/MagneticButton"; export const Route = createFileRoute("/")({ component: Home, }); function Home() { return (

SmoothUI + TanStack Start

Get Started
); } ``` ### Custom Animated Components If you create custom animated components alongside SmoothUI, follow the same pattern: ```tsx title="app/components/FadeIn.tsx" "use client"; import { motion, useReducedMotion } from "motion/react"; import type { ReactNode } from "react"; export type FadeInProps = { children: ReactNode; }; const FadeIn = ({ children }: FadeInProps) => { const shouldReduceMotion = useReducedMotion(); return ( {children} ); }; export default FadeIn; ``` ## Troubleshooting Verify that `@tailwindcss/vite{:ts}` is included in your `app.config.ts{:ts}` Vite plugins, and that your CSS file contains `@import "tailwindcss"{:css}`. Also check that the stylesheet is linked in your root route's `head{:tsx}` function. TanStack Start uses Vinxi (Vite-based), which should resolve TypeScript paths. If aliases don't work, add `vite-tsconfig-paths{:ts}` to your `app.config.ts{:ts}` Vite plugins as shown in the setup section. Hydration mismatches occur when server-rendered HTML differs from client output. Avoid using `Math.random(){:ts}`, `Date.now(){:ts}`, or browser APIs during render. For components that depend on client-only values, use the `ClientOnly` wrapper pattern. With streaming SSR, components hydrate progressively. Animations using `initial{:tsx}` and `animate{:tsx}` props will play as each component hydrates — this is the expected behavior. If you want animations to trigger on scroll instead, use Motion's `whileInView{:tsx}` prop. ## Next Steps Learn about all available installation methods including the SmoothUI CLI and shadcn registry. Explore the complete collection of 50+ animated React components. Master animation performance, accessibility, and timing guidelines. Full-stack SSR setup with Remix and React Router v7. # Utility Functions (/docs/guides/utilities) ## Overview SmoothUI provides utility functions that simplify common patterns in React development. These utilities are used throughout the component library and are available for your own components. *** ## cn() - Class Name Utility The `cn()` function merges class names intelligently, combining the power of [clsx](https://github.com/lukeed/clsx) for conditional classes and [tailwind-merge](https://github.com/dcastil/tailwind-merge) for resolving Tailwind CSS conflicts. ### Installation The `cn()` utility is included with any SmoothUI component installation. You can also install it directly: ```bash pnpm add clsx tailwind-merge ``` Then create the utility: ```tsx // lib/utils.ts import { type ClassValue, clsx } from "clsx"; import { twMerge } from "tailwind-merge"; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); } ``` ### Usage ```tsx import { cn } from "@/lib/utils"; function Button({ className, variant, ...props }) { return (