# Sidebar Search Field

> Header search on the menu rows' rhythm: leading icon on the rows' 16px axis, text on the 32px axis, and a hover-revealed keystroke chip at the trailing edge.

A shadcn/ui block from the [@fluid](https://www.fluidfunctionalism.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/fluid/sidebar-search-field).

- Page, with a live preview: https://shadcn.exchange/r/fluid/sidebar-search-field
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/fluid/sidebar-search-field-light-d01174df2781ebd0.png
- Registry item: https://www.fluidfunctionalism.com/r/sidebar-search-field.json
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://www.fluidfunctionalism.com/r/sidebar-search-field.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- Registry items: `https://www.fluidfunctionalism.com/r/size-context.json`, `https://www.fluidfunctionalism.com/r/icon-context.json`, `https://www.fluidfunctionalism.com/r/sidebar.json`, `https://www.fluidfunctionalism.com/r/type-scale.json`

## Files

### `registry/blocks/sidebar-app/search-field.tsx`

```tsx
"use client";

import { type ComponentProps } from "react";
import { SidebarInput } from "@/components/ui/sidebar";
import { useSize } from "@/lib/size-context";
import { useIcons } from "@/lib/icon-context";

// ---------------------------------------------------------------------------
// The header's search field, on the menu rows' own rhythm. The leading icon
// sits on the rows' 16px leading axis; pl-8 starts the text on the rows'
// 32px text axis; and the shortcut chip waits at the trailing edge, revealed
// on hover/focus — the placeholder owns the field at rest.
// ---------------------------------------------------------------------------

export interface SidebarSearchFieldProps
  extends Omit<ComponentProps<typeof SidebarInput>, "className"> {
  /** Keystroke shown in the trailing chip. Pass null to drop the chip. */
  shortcut?: string | null;
}

export function SidebarSearchField({
  placeholder = "Search…",
  shortcut = "⌘K",
  ...props
}: SidebarSearchFieldProps) {
  const iconSize = useSize().icon;
  const icons = useIcons();
  const SearchIcon = icons.search;
  return (
    <div className="group/search relative">
      <SearchIcon
        size={iconSize}
        strokeWidth={1.5}
        className="pointer-events-none absolute left-2 top-1/2 -translate-y-1/2 text-muted-foreground"
      />
      <SidebarInput
        placeholder={placeholder}
        aria-label="Search"
        className="pl-8 pr-12"
        {...props}
      />
      {shortcut && (
        <kbd className="pointer-events-none absolute right-2 top-1/2 -translate-y-1/2 font-sans text-[length:var(--fs-micro,11px)] leading-[var(--lh-micro,14px)] text-muted-foreground opacity-0 transition-opacity duration-80 group-hover/search:opacity-100 group-focus-within/search:opacity-100">
          {shortcut}
        </kbd>
      )}
    </div>
  );
}
```
