Skip to content
    Style: Wireframe

    Blocks · Marketing

    Search bar

    A short heading and one line in a centred panel, then the search field with its clear button and / shortcut.

    9.6% of the 2,073 sites in The UI Index have a search (200 sites).

    Find a guide

    Search the docs, the changelog and the guides.

    Results for your search

    Both previews render the same markup; the HTML tab below is that markup without a framework.

    Install

    React
    npx shadcn@latest add https://www.themes.dev/ui/r/search-bar.json
    Astro
    npx shadcn@latest add https://www.themes.dev/ui/r/astro/search-bar.json

    Or copy the files below into your project. They need clsx, tailwind-merge and the components they import, and the themes.dev UI theme. The HTML needs only the compiled CSS.

    search-bar.classes.ts
    /** A search bar (ported from the themes' sections/search): a short heading and one line in a centred panel, then
     *  the search field (the free search-field: magnifier, a native search input, a "/" shortcut, a clear button once
     *  there is text). A GET form that works without JavaScript. */
    export const searchBar = {
      root: 'bg-background px-6 py-16 text-foreground',
      frame: 'mx-auto flex w-full max-w-3xl min-w-0 flex-col gap-6 rounded-xl border bg-card p-5 text-card-foreground sm:p-8',
      head: 'flex flex-col gap-2',
      heading: 'text-xl font-semibold tracking-[-0.02em] text-balance',
      lead: 'text-base text-pretty text-muted-foreground',
    };
    
    export type SearchBarContent = {
      /** The panel's short heading. */
      heading: string;
      lead?: string;
      /** The field's accessible name, e.g. "Search the docs". */
      label: string;
      placeholder?: string;
      /** Where the search form goes (GET); it works without JavaScript. */
      action: string;
      /** The query's name. Default: q. */
      name?: string;
      /** The text already in the field. */
      value?: string;
      /** Unique on the page; ids the heading and the field. */
      id: string;
    };
    search-bar.tsx
    import { SearchField } from '@/components/ui/search-field';
    import { cn } from '@/lib/utils';
    import { searchBar as c, type SearchBarContent } from './search-bar.classes';
    
    export type SearchBarProps = SearchBarContent & { className?: string };
    
    /** A search bar: a short heading and one line in a panel, then the search field. */
    export function SearchBar({ heading, lead, label, placeholder, action, name, value, id, className }: SearchBarProps) {
      return (
        <section aria-labelledby={`${id}-title`} className={cn(c.root, className)}>
          <div className={c.frame}>
            <div className={c.head}>
              <h2 id={`${id}-title`} className={c.heading}>{heading}</h2>
              {lead && <p className={c.lead}>{lead}</p>}
            </div>
            <SearchField id={`${id}-q`} label={label} placeholder={placeholder} action={action} name={name} defaultValue={value} />
          </div>
        </section>
      );
    }