Natural filter

A natural-language search request becomes a typed filter/sort object with editable chips.

Mock· scripted answersNo model runs in a browser, so every answer here is scripted. On a phone it comes from the model.
  • Apple Foundation Models: supported
  • Gemini Nano: supported
  • Llama (not yet supported): not supported
  • A cloud model: supported

Install

npx ondai add natural-filter

Usage

import { NaturalFilter } from '@/components/ondai/natural-filter'
import { z } from 'zod'

const filters = z.object({ cuisine: z.enum(['italian', 'japanese']).optional(), price: z.enum(['$', '$$', '$$$']).optional(), openNow: z.boolean().optional() })

<NaturalFilter schema={filters} presentation="bar" onChange={(f) => setFilter(f)}>
  <RestaurantList filter={filter} />
</NaturalFilter>
  • Chips are editable (tap an enum chip to cycle values) and removable.

Customize

Every AI component takes the same look and customization props, so it fits your app rather than ours.

<NaturalFilter
  variant="pop"
  tint="#FF5A5F"
  size="lg"
  radius={12}
  icons={{ search: Search, clear: null }}
  labels={{ placeholder: '…', thinking: '…' }}
/>
PropWhat it does
variantThe look of the whole component: clean, minimal, glass, pop, candy, metal, shine
sizesm, md, lg; type, rows, icons and keys scale together
tintAny colour; the variant paints its keys, tiles and glow in it
radiusCorner radius of the container
iconsReplace any icon (a lucide component, an element, or null to hide it): search, clear, edit, submit, row, empty, error
labelsEvery visible and spoken string; defaults are exported as naturalFilterLabels: placeholder, thinking, submit, clear, clearFilters, editFilters, sheetTitle, done, any, yes, no, not, tapToChange, remove, emptyTitle, emptyHint, result, results, inputLabel
SlotsDraw a part yourself: renderChip, renderSubmit, renderEmpty, renderFooter
stylesStyle any named part

Variants

PropOptions
presentationbar, sheet, inline
variantclean, minimal, glass, pop, candy, metal, shine
sizesm, md, lg
chipStylesoft, outline

Token budget

Input budget: 600 tokens. One structured call; enums, numbers and booleans refined deterministically.

Fallback

When no provider is ready the component renders the unavailable state (AvailabilityGate copy) and, where a deterministic path exists, keeps working without the model.

Eval score

Fixtures: evals/natural-filter/fixtures.json.

Files

Registry dependencies: button, chip, on-device-badge, sheet, shimmer-text, surface, skeleton

npm dependencies: @ondai/core, @ondai/tokens, expo-haptics, lucide-react-native, react-native-reanimated, zod

On this page