Power Search

A search field that mixes free text with structured field: value filter chips (GitHub/Linear-style). Drive it with usePowerSearchConfig — this component is purely a view over that state.

Real use · issue search (select/text/date/boolean/custom fields)

{
  "query": "",
  "terms": [
    {
      "id": "seed-1",
      "field": "status",
      "value": "in-progress"
    }
  ]
}

Using Power Search

Silica ships one design system through three paths. They share a class vocabulary but are not interchangeable — pick the one that matches what you are building.

Plain HTML — CSS classes

The Tailwind v4 plugin. Works in any framework or none — Rails, Django, PHP, Go, a static file. This path ships no JavaScript, so a component that needs interaction is styled but inert.

/* in your CSS */
@import "tailwindcss";
@plugin "@wizeworks/silicaui";

Root class power-search, with 13 modifiers:

  • .power-search
  • .power-search-add
  • .power-search-chip
  • .power-search-chip-field
  • .power-search-chip-remove
  • .power-search-chip-trigger
  • .power-search-field-item
  • .power-search-field-list
  • .power-search-input
  • .power-search-option-list
  • .power-search-value-form
  • .power-search-value-picker
  • .power-search-value-picker-back
  • .power-search-value-picker-label

React

Typed components over those same classes, with behavior and accessibility from Base UI.

npm i @wizeworks/silicaui-react
import { PowerSearch } from "@wizeworks/silicaui-react";

Props

PowerSearchValuePickerProps
PropTypeRequiredDescription
valuestringyes—
onChange(value: string) => voidyes—
onCommit(value: string) => voidyes—
PowerSearchProps
PropTypeRequiredDescription
fieldsPowerSearchFieldDef[]yes—
valuePowerSearchValueyes—
setQuery(query: string) => voidyes—
addTerm(field: string, value: string) => voidyes—
updateTerm(id: string, value: string) => voidyes—
removeTerm(id: string) => voidyes—
placeholderstringno—
disabledbooleanno—
classNamestringno—
"aria-label"stringno—

Source of the demo above

The exact file that renders the examples above, so it can never drift from them. It imports a few of this site’s own layout helpers (../lib/…), so read it for the component calls rather than copying it whole.

Show source
import { PowerSearch, usePowerSearchConfig, Button, type PowerSearchFieldDef } from "@wizeworks/silicaui-react";
import { Section } from "../lib/Section";

const FIELDS: PowerSearchFieldDef[] = [
    {
        key: "status",
        label: "Status",
        type: "select",
        options: [
            { value: "open", label: "Open" },
            { value: "in-progress", label: "In progress" },
            { value: "done", label: "Done" },
        ],
    },
    { key: "assignee", label: "Assignee", type: "text", placeholder: "e.g. ada" },
    { key: "due", label: "Due date", type: "date" },
    { key: "starred", label: "Starred", type: "boolean" },
    {
        key: "priority",
        label: "Priority",
        type: "custom",
        formatValue: (v) => "⭐".repeat(Number(v) || 1),
        render: ({ onCommit }) => (
            <div className="flex gap-1">
                {[1, 2, 3].map((n) => (
                    <Button key={n} size="sm" variant="outline" onClick={() => onCommit(String(n))}>
                        {"⭐".repeat(n)}
                    </Button>
                ))}
            </div>
        ),
    },
];

export function PowerSearchDemo() {
    const search = usePowerSearchConfig({
        fields: FIELDS,
        defaultValue: {
            query: "",
            terms: [{ id: "seed-1", field: "status", value: "in-progress" }],
        },
    });

    return (
        <Section title="Real use · issue search (select/text/date/boolean/custom fields)">
            <div className="max-w-xl">
                <PowerSearch {...search} placeholder="Search issues…" />
                <pre className="mt-3 rounded-field bg-base-200 p-3 text-xs">
                    {JSON.stringify(search.value, null, 2)}
                </pre>
            </div>
        </Section>
    );
}

The full API for Power Search, on every path, is available through the Silica MCP server.