# NiceUI — full source > NiceUI is a free, open-source library of premium React and Tailwind CSS components, blocks and templates. Copy the code or install with the shadcn CLI. MIT licensed, no account required. --- ## Avatar Group Overlapping avatars with initials fallback, hover lift and a +N overflow counter. URL: https://niceui.dev/components/avatar-group Install: `npx shadcn@latest add https://niceui.dev/r/avatar-group.json` File: `components/ui/avatar-group.tsx` ```tsx import * as React from "react"; export interface AvatarGroupProps { people: { name: string; src?: string }[]; max?: number; className?: string; } const initials = (name: string) => name .split(" ") .map((part) => part[0]) .join("") .slice(0, 2) .toUpperCase(); export function AvatarGroup({ people, max = 4, className = "" }: AvatarGroupProps) { const shown = people.slice(0, max); const rest = people.length - shown.length; return (
{shown.map((person, i) => ( {person.src ? {person.name} : initials(person.name)} ))} {rest > 0 && ( +{rest} )}
); } ``` Usage: ```tsx import { AvatarGroup } from "@/components/ui/avatar-group"; const people = ["Ada King", "Mia Jones", "Raj Shah", "Leo Park", "Noa Ito", "Sam Lee"]; export default function Example() { return ({ name }))} max={4} />; } ``` --- ## Badge Compact status labels in neutral, sky and outline variants, with an optional glowing status dot. URL: https://niceui.dev/components/badge Install: `npx shadcn@latest add https://niceui.dev/r/badge.json` File: `components/ui/badge.tsx` ```tsx import * as React from "react"; type Variant = "neutral" | "sky" | "outline"; const variants: Record = { neutral: "bg-white/[.06] text-zinc-300", sky: "border border-sky-300/30 bg-sky-300/10 text-sky-300", outline: "border border-white/15 text-zinc-400", }; export interface BadgeProps extends React.HTMLAttributes { variant?: Variant; dot?: boolean; } export function Badge({ variant = "neutral", dot = false, className = "", children, ...props }: BadgeProps) { return ( {dot && } {children} ); } ``` Usage: ```tsx import { Badge } from "@/components/ui/badge"; export default function Example() { return (
Live Draft Archived
); } ``` --- ## Button A pill-shaped button with primary, outline and ghost variants in three sizes. Accessible focus ring, forwarded ref. URL: https://niceui.dev/components/button Install: `npx shadcn@latest add https://niceui.dev/r/button.json` File: `components/ui/button.tsx` ```tsx import * as React from "react"; type Variant = "primary" | "outline" | "ghost"; type Size = "sm" | "md" | "lg"; const variants: Record = { primary: "bg-sky-300 text-sky-950 shadow-[0_0_0_1px_rgba(125,211,252,.4),0_8px_32px_-8px_rgba(56,189,248,.6)] hover:bg-sky-200", outline: "border border-white/15 text-zinc-100 hover:border-white/30 hover:bg-white/[.03]", ghost: "text-zinc-400 hover:bg-white/5 hover:text-zinc-100", }; const sizes: Record = { sm: "h-8 px-3.5 text-xs", md: "h-10 px-5 text-sm", lg: "h-12 px-6 text-base", }; export interface ButtonProps extends React.ButtonHTMLAttributes { variant?: Variant; size?: Size; } export const Button = React.forwardRef( ({ variant = "primary", size = "md", className = "", ...props }, ref) => ( ); } ``` --- ## Command Palette A ⌘K search palette with live filtering, arrow-key navigation and an Enter action per item. URL: https://niceui.dev/components/command-palette Install: `npx shadcn@latest add https://niceui.dev/r/command-palette.json` File: `components/ui/command-palette.tsx` ```tsx "use client"; import * as React from "react"; export interface CommandItem { label: string; hint?: string; onSelect?: () => void; } export interface CommandPaletteProps { items: CommandItem[]; placeholder?: string; className?: string; } export function CommandPalette({ items, placeholder = "Search…", className = "" }: CommandPaletteProps) { const [query, setQuery] = React.useState(""); const [active, setActive] = React.useState(0); const inputRef = React.useRef(null); const results = items.filter((item) => item.label.toLowerCase().includes(query.toLowerCase())); React.useEffect(() => setActive(0), [query]); React.useEffect(() => { const onKey = (e: KeyboardEvent) => { if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") { e.preventDefault(); inputRef.current?.focus(); } }; window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey); }, []); const onKeyDown = (e: React.KeyboardEvent) => { if (e.key === "ArrowDown") { e.preventDefault(); setActive((i) => Math.min(i + 1, results.length - 1)); } else if (e.key === "ArrowUp") { e.preventDefault(); setActive((i) => Math.max(i - 1, 0)); } else if (e.key === "Enter") { results[active]?.onSelect?.(); } }; return (
setQuery(e.target.value)} onKeyDown={onKeyDown} placeholder={placeholder} className="min-w-0 flex-1 bg-transparent text-sm text-zinc-100 outline-none placeholder:text-zinc-500" /> ⌘K
    {results.length === 0 &&
  • No results
  • } {results.map((item, i) => (
  • setActive(i)} onClick={item.onSelect} className={[ "flex cursor-pointer justify-between rounded-lg px-2.5 py-2 text-[13px] transition-colors", i === active ? "bg-sky-300/10 text-zinc-100" : "text-zinc-400", ].join(" ")} > {item.label} {item.hint && ( {item.hint} )}
  • ))}
); } ``` Usage: ```tsx import { CommandPalette } from "@/components/ui/command-palette"; export default function Example() { return ( ); } ``` --- ## Floating Input A text input whose label floats above the value on focus. Pure CSS peer states, no JavaScript needed for the animation. URL: https://niceui.dev/components/floating-input Install: `npx shadcn@latest add https://niceui.dev/r/floating-input.json` File: `components/ui/floating-input.tsx` ```tsx import * as React from "react"; export interface FloatingInputProps extends Omit, "placeholder"> { label: string; } export const FloatingInput = React.forwardRef( ({ label, id, className = "", ...props }, ref) => { const autoId = React.useId(); const inputId = id ?? autoId; return (
); } ); FloatingInput.displayName = "FloatingInput"; ``` Usage: ```tsx import { FloatingInput } from "@/components/ui/floating-input"; export default function Example() { return ; } ``` --- ## Marquee An infinite, edge-faded horizontal scroller for logos, tags or testimonials. Pauses on hover. URL: https://niceui.dev/components/marquee Install: `npx shadcn@latest add https://niceui.dev/r/marquee.json` File: `components/ui/marquee.tsx` ```tsx import * as React from "react"; export interface MarqueeProps { children: React.ReactNode; duration?: number; pauseOnHover?: boolean; className?: string; } export function Marquee({ children, duration = 24, pauseOnHover = true, className = "" }: MarqueeProps) { return (
{children}
{children}
); } ``` Usage: ```tsx import { Marquee } from "@/components/ui/marquee"; const tags = ["Accordion", "Dialog", "Tooltip", "Sidebar", "Command", "Toast"]; export default function Example() { return ( {tags.map((tag) => ( {tag} ))} ); } ``` --- ## Segmented Control A pill tab switcher with a sliding sky indicator that springs between options. URL: https://niceui.dev/components/segmented-control Install: `npx shadcn@latest add https://niceui.dev/r/segmented-control.json` File: `components/ui/segmented-control.tsx` ```tsx "use client"; import * as React from "react"; export interface SegmentedControlProps { options: string[]; value?: string; defaultValue?: string; onValueChange?: (value: string) => void; className?: string; } export function SegmentedControl({ options, value, defaultValue, onValueChange, className = "", }: SegmentedControlProps) { const [inner, setInner] = React.useState(defaultValue ?? options[0]); const active = value ?? inner; const refs = React.useRef<(HTMLButtonElement | null)[]>([]); const [box, setBox] = React.useState({ left: 0, width: 0 }); React.useLayoutEffect(() => { const el = refs.current[options.indexOf(active)]; if (el) setBox({ left: el.offsetLeft, width: el.offsetWidth }); }, [active, options]); const select = (option: string) => { if (value === undefined) setInner(option); onValueChange?.(option); }; return (
{options.map((option, i) => ( ))}
); } ``` Usage: ```tsx import { SegmentedControl } from "@/components/ui/segmented-control"; export default function Example() { return ; } ``` --- ## Shimmer Button A dark button with a sweeping sky-blue shimmer and a glowing bottom edge. Zero dependencies, keyframes included. URL: https://niceui.dev/components/shimmer-button Install: `npx shadcn@latest add https://niceui.dev/r/shimmer-button.json` File: `components/ui/shimmer-button.tsx` ```tsx import * as React from "react"; export interface ShimmerButtonProps extends React.ButtonHTMLAttributes {} export function ShimmerButton({ children, className = "", ...props }: ShimmerButtonProps) { return ( ); } ``` Usage: ```tsx import { ShimmerButton } from "@/components/ui/shimmer-button"; export default function Example() { return Join the beta; } ``` --- ## Slider A minimal range slider with a sky fill, soft halo thumb and a live value readout. URL: https://niceui.dev/components/slider Install: `npx shadcn@latest add https://niceui.dev/r/slider.json` File: `components/ui/slider.tsx` ```tsx "use client"; import * as React from "react"; export interface SliderProps { label?: string; min?: number; max?: number; step?: number; defaultValue?: number; format?: (value: number) => string; onValueChange?: (value: number) => void; className?: string; } export function Slider({ label, min = 0, max = 100, step = 1, defaultValue = 50, format = (v) => String(v), onValueChange, className = "", }: SliderProps) { const [value, setValue] = React.useState(defaultValue); const pct = ((value - min) / (max - min)) * 100; return (
{label && (
{label} {format(value)}
)} { const next = Number(e.target.value); setValue(next); onValueChange?.(next); }} style={{ background: "linear-gradient(90deg,#7dd3fc " + pct + "%,#1c1e22 " + pct + "%)" }} className={[ "h-1 w-full cursor-pointer appearance-none rounded-full outline-none", "[&::-webkit-slider-thumb]:size-4 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full", "[&::-webkit-slider-thumb]:bg-white [&::-webkit-slider-thumb]:shadow-[0_0_0_4px_rgba(125,211,252,.25)]", "[&::-moz-range-thumb]:size-4 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:border-0 [&::-moz-range-thumb]:bg-white", ].join(" ")} />
); } ``` Usage: ```tsx import { Slider } from "@/components/ui/slider"; export default function Example() { return v + "%"} />; } ``` --- ## Stat Card A KPI card with label, value, delta and an inline sparkline generated from your data points. URL: https://niceui.dev/components/stat-card Install: `npx shadcn@latest add https://niceui.dev/r/stat-card.json` File: `components/ui/stat-card.tsx` ```tsx import * as React from "react"; export interface StatCardProps { label: string; value: string; delta?: string; trend?: number[]; className?: string; } function toPath(points: number[], w = 120, h = 32) { const max = Math.max(...points); const min = Math.min(...points); const range = max - min || 1; return points .map((p, i) => { const x = (i / (points.length - 1)) * w; const y = h - 4 - ((p - min) / range) * (h - 8); return (i === 0 ? "M" : "L") + x.toFixed(1) + " " + y.toFixed(1); }) .join(" "); } export function StatCard({ label, value, delta, trend, className = "" }: StatCardProps) { return (
{label} {delta && {delta}}
{value}
{trend && trend.length > 1 && ( )}
); } ``` Usage: ```tsx import { StatCard } from "@/components/ui/stat-card"; export default function Example() { return ( ); } ``` --- ## Switch An accessible toggle with a springy thumb. Works controlled or uncontrolled and uses role="switch". URL: https://niceui.dev/components/switch Install: `npx shadcn@latest add https://niceui.dev/r/switch.json` File: `components/ui/switch.tsx` ```tsx "use client"; import * as React from "react"; export interface SwitchProps { checked?: boolean; defaultChecked?: boolean; onCheckedChange?: (checked: boolean) => void; disabled?: boolean; label?: string; className?: string; } export function Switch({ checked, defaultChecked = false, onCheckedChange, disabled, label, className = "", }: SwitchProps) { const [inner, setInner] = React.useState(defaultChecked); const on = checked ?? inner; const toggle = () => { if (checked === undefined) setInner(!on); onCheckedChange?.(!on); }; return ( ); } ``` Usage: ```tsx import { Switch } from "@/components/ui/switch"; export default function Example() { return ( ); } ``` --- ## Hero — Horizon A cinematic landing hero with serif-italic accent, dual CTAs and the signature glowing horizon arc. URL: https://niceui.dev/blocks/hero-horizon Install: `npx shadcn@latest add https://niceui.dev/r/hero-horizon.json` File: `components/hero-horizon.tsx` ```tsx import * as React from "react"; export interface HeroHorizonProps { eyebrow?: string; title?: string; accent?: string; rest?: string; description?: string; primary?: { label: string; href: string }; secondary?: { label: string; href: string }; } export function HeroHorizon({ eyebrow = "Now in public beta", title = "Ship faster,", accent = "beautifully", rest = "built.", description = "The platform for teams who care about craft. Everything you need to launch, nothing you do not.", primary = { label: "Get started", href: "#" }, secondary = { label: "Read the docs", href: "#" }, }: HeroHorizonProps) { return (

{eyebrow}

{title}
{accent} {rest}

{description}

); } ``` Usage: ```tsx import { HeroHorizon } from "@/components/hero-horizon"; export default function Page() { return ; } ``` --- ## Pricing — Minimal Three-tier pricing with a monthly/yearly toggle, featured plan glow and checkmark feature lists. URL: https://niceui.dev/blocks/pricing-minimal Install: `npx shadcn@latest add https://niceui.dev/r/pricing-minimal.json` File: `components/pricing-minimal.tsx` ```tsx "use client"; import * as React from "react"; export interface Tier { name: string; monthly: number; yearly: number; description: string; features: string[]; cta: string; featured?: boolean; } const defaultTiers: Tier[] = [ { name: "Starter", monthly: 0, yearly: 0, description: "For side projects.", features: ["3 projects", "Community support", "Basic analytics"], cta: "Start free" }, { name: "Pro", monthly: 24, yearly: 19, description: "For growing products.", features: ["Unlimited projects", "Priority support", "Advanced analytics", "Custom domains"], cta: "Upgrade to Pro", featured: true }, { name: "Team", monthly: 59, yearly: 49, description: "For teams at scale.", features: ["Everything in Pro", "SSO and audit log", "Dedicated manager"], cta: "Contact sales" }, ]; export function PricingMinimal({ tiers = defaultTiers }: { tiers?: Tier[] }) { const [yearly, setYearly] = React.useState(true); return (

Simple, honest pricing.

{["Monthly", "Yearly"].map((label) => { const on = (label === "Yearly") === yearly; return ( ); })}
{tiers.map((tier) => (
{tier.name} {tier.featured && ( Popular )}
${yearly ? tier.yearly : tier.monthly} / mo

{tier.description}

    {tier.features.map((feature) => (
  • {feature}
  • ))}
))}
); } ``` Usage: ```tsx import { PricingMinimal } from "@/components/pricing-minimal"; export default function Page() { return ; } ```