macbetter

Text and fields

Search Field

Search a list, a board or the whole app.

import { SearchField } from "macbetter/search-field"

export default function Example() {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 12, width: "100%", maxWidth: 280 }}>
      <SearchField aria-label="Search boards" defaultValue="revenue" />
      <SearchField aria-label="Search datasets" placeholder="Search Datasets" />
    </div>
  )
}

When to use it

Use a search field when typing narrows what's on screen or finds something in the app. On macOS, put it at the trailing end of the toolbar; on iOS, at the top of the list it searches. Keep the prompt short: "Search" or "Search Datasets", never a sentence.

Filter as people type when the results are local and fast. When a search costs a request, run it on Return and keep the results where they are until then.

Usage

import { SearchField } from "macbetter/search-field"

SearchField renders the magnifier, a native type="search" input and a clear button. Props go to the input: value, onValueChange, placeholder ("Search" by default) and name. groupClassName styles the field's box.

Sizes

sm fits a dense toolbar or a table's filter row, lg a page whose main job is search.

import { SearchField } from "macbetter/search-field"

export default function Example() {
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 12, width: "100%", maxWidth: 260 }}>
      <SearchField size="sm" aria-label="Filter rows" placeholder="Filter" />
      <SearchField aria-label="Search" />
      <SearchField size="lg" aria-label="Search everything" />
    </div>
  )
}

Platform behavior

  • macOS. A rounded rectangle on the field background with a hairline edge, 28 points tall at md. The accent halo shows while it's focused.
  • iPadOS and iOS. A gray capsule, 36 points tall, with a 16-point magnifier and 17-point text, as in a navigation bar's search.
  • Every platform. The clear button appears with a small spring once there's text, and the browser's own cancel button is hidden so there's only one.

Accessibility

  • The input has the searchbox role and asks touch keyboards for a Search key.
  • Give it an aria-label that says what it searches, like "Search boards". The clear button is named "Clear search"; change it with clearLabel.
  • Clearing returns focus to the input.

API

SearchField

PropTypeDefaultDescription
size"sm" | "md" | "lg""md"Height and type size.
placeholderstring"Search"The prompt.
clearLabelstring"Clear search"The clear button's name.
groupClassNamestring—A class for the box that holds the glyph, input and clear button.
valuestring—The query, for a controlled field.
onValueChange(value, details) => void—Runs on typing and on a clear press (reason clear-press).

Data attributes

AttributeOnValues
data-size.mb-search-fieldsm, md, lg
data-filledBox, input, clearPresent while there's a query
data-disabledBoxPresent when disabled

CSS variables

VariablemacOSiOSWhat it sets
--mb-search-field-height28px36pxHeight at md
--mb-search-field-radius6pxCapsuleCorner radius
--mb-search-field-bgField whiteTertiary fillBackground
--mb-search-field-glyph13px16pxMagnifier size