Skip to content

SearchFilterInput

Structured search control where each tag represents a field/operator/value filter.

<SearchFilterInput
config={config}
filters={filters}
onChange={next => setFilters(next)}
/>
<SearchFilterInput
config={config}
filters={filters}
onChange={next => setFilters(next)}
/>
<SearchFilterInput
config={config}
filters={filters}
onChange={next => setFilters(next)}
/>
<div style={{display: 'flex', flexDirection: 'column', gap: 16}}>
<SearchFilterInput
config={config}
filters={smFilters}
label="Small"
onChange={next => setSmFilters(next)}
placeholder="Small..."
size="sm"
/>
<SearchFilterInput
config={config}
filters={mdFilters}
label="Medium"
onChange={next => setMdFilters(next)}
placeholder="Medium..."
size="md"
/>
<SearchFilterInput
config={config}
filters={lgFilters}
label="Large"
onChange={next => setLgFilters(next)}
placeholder="Large..."
size="lg"
/>
</div>
Name containsJohn
<SearchFilterInput
config={config}
filters={[
{
field: 'name',
operator: 'contains',
value: {type: 'string', value: 'John'},
},
]}
isDisabled
onChange={() => {}}
/>
Name containsJohnStatus isActive
<SearchFilterInput
config={config}
filters={[
{
field: 'name',
operator: 'contains',
value: {type: 'string', value: 'John'},
},
{
field: 'status',
operator: 'is',
value: {type: 'enum', value: 'active'},
},
]}
isReadOnly
onChange={() => {}}
/>
42 results
<SearchFilterInput
config={config}
filters={filters}
onChange={next => setFilters(next)}
resultCount={42}
/>
<SearchFilterInput
config={config}
filters={filters}
isLabelHidden={false}
label="Filter users"
onChange={next => setFilters(next)}
/>
<SearchFilterInput
config={config}
filters={filters}
onChange={next => setFilters(next)}
status={{type: 'error', message: 'At least one filter is required'}}
/>
<div style={{maxWidth: 600}}>
<SearchFilterInput
config={config}
filters={filters}
onChange={next => setFilters(next)}
tagOverflowBehavior="unfocusedInline"
/>
</div>
<SearchFilterInput
components={components}
config={config}
filters={filters}
onChange={next => setFilters(next)}
/>
<div style={{display: 'flex', flexDirection: 'column', gap: 16}}>
{timezones.map(timezone => (
<SearchFilterInput
config={config}
filters={filters}
isLabelHidden={false}
key={timezone}
label={timezone}
onChange={() => {}}
timezoneID={timezone}
/>
))}
</div>

Structured search control where each tag represents a field/operator/value filter.

PropTypeDefaultDescription
classNamestringAdditional CSS class names applied to the input wrapper.
componentsSearchFilterInputComponentsPer-value-type component overrides.
config*SearchFilterInputConfigSearchFilterInput field/operator configuration.
data-testidstringTest ID applied to the input wrapper.
endContentReactNodeContent displayed at the end of the input row.
filters*ReadonlyArray<SearchFilterInputFilter>Current filters.
handleRefRef<SearchFilterInputHandle>Imperative focus/blur handle.
hasAutoFocusbooleanfalseWhether to focus the input on mount.
hasClearbooleantrueWhether to show a clear button.
isDisabledbooleanfalseWhether the input is disabled.
isLabelHiddenbooleantrueWhether to visually hide the label.
isReadOnlybooleanfalseWhether filters are read-only.
labelstring'Search'Accessible label.
maxOperatorMenuItemsnumberMaximum number of items shown in the operator dropdown menu. When set, only the first N operators are displayed.
maxTagLengthnumber40Maximum displayed tag value length.
onBlur(event: FocusEvent<HTMLDivElement>) => voidCalled when focus leaves the control.
onChange*( filters: ReadonlyArray<SearchFilterInputFilter>, changeType: SearchFilterInputChangeType, index: number, ) => voidCalled when filters change.
onFocus(event: FocusEvent<HTMLDivElement>) => voidCalled when focus enters the control.
placeholderstring'Search...'Placeholder text.
popoverSaveButtonLabelstring'Apply'Save button label in the edit popover.
refRef<HTMLDivElement>Ref forwarded to the root element.
resultCountnumber | stringResult count displayed at end of row.
size"sm" | "md" | "lg"'md'Visual size.
startIconIconComponentIcon shown before the input.
statusInputStatusValidation status displayed below the input.
styleCSSPropertiesInline styles applied to the input wrapper.
tagOverflowBehavior"none" | "unfocusedInline" | "unfocusedLayer"'none'Controls how tags overflow when the container is too narrow. - 'none': Tags wrap to multiple lines (default). - 'unfocusedInline': Single line with "+ N more" when unfocused; expands inline on focus. - 'unfocusedLayer': Single line with "+ N more" when unfocused; expands as overlay on focus.
timezoneIDstringTimezone ID for date formatting.
PropTypeDefaultDescription
config*InternalSearchFilterInputConfigInternal config lookup helpers.
filter*PartialFilterPartial filter being created or edited.
isReadOnlybooleanfalseWhether controls are read-only.
maxOperatorMenuItemsnumberMaximum number of items shown in the operator dropdown menu.
mode*'create' | 'edit'Editor mode.
onCancel*() => voidCalled when editing is cancelled.
onSave*(filter: SearchFilterInputFilter | null) => voidCalled with a completed filter, or null to delete.
saveButtonLabelstring'Apply'Save button label.

Default tag renderer for a SearchFilterInput filter.

PropTypeDefaultDescription
config*SearchFilterInputConfig
field*SearchFilterInputField
filter*SearchFilterInputFilter
isDisabledboolean
maxLength*number
onClick() => void
onRemove() => void
operator*SearchFilterInputOperator