FilterInput
A config-driven query builder — fields metadata in, an ExprNode tree out of onChange — for filtering a data-dense resource. Reach for a row of Selects instead when three or four facets picked by equality would do; reach for this when the attribute count is high, or the query needs AND/OR, grouping, or operators like between and like. The menus, chips and connectors are internal, so what you own is the field config.
Usage
Examples
FilterInput
With keyboard hint
showKeyboardHint prints the shortcut hint beside the input — worth turning on where filtering is new to the reader, and off where it is routine.
With field groups
fieldGroups sorts the field menu under labelled headers, which is what keeps a fifty-field schema navigable.
With described chip
A field with a description carries it into a tooltip on the chip's first segment, so a committed filter can still explain itself; the operator and value segments keep click-to-edit.
Error empty
error reddens the input as a whole — pair it with an Alert that says what was rejected, since the input itself cannot.
With preset value
Controlled mode: value takes an ExprNode and onChange hands the tree back. The JSON below the input is the story printing that tree, not part of the component.
With multi condition preset
Two conditions joined by AND — what a group node looks like once rendered, connectors included.
Error with value
The error state with a condition already committed: the chip stays editable, so the query can be fixed in place rather than cleared.
With disabled chips
A condition marked disabled is locked — dimmed, no edit, no remove — which is how a drill-down carries its context into the filter without letting the reader drop it.
All chips disabled
With every chip locked, clear-all has nothing to remove, and the input still accepts new conditions on top.
HTTP status code suggestions
A status-code field wired by hand with the createStatusCode* helpers: typing narrows the mask suggestions, 4 to 4XX and 40 to 40X.
HTTP status code by name
status_code is a reserved field name — the DS fills in the same suggestions, input filter, normaliser and validator on its own, and an explicit callback still wins.
Paired field
pairedField captures two steps in one chip — a parameter name, then its value with its own operator — for an attribute that means nothing on its own.
Paired field value is set
is set and is not set on the paired half finish the chip with no second value, which is how you ask whether a key is present at all.
Paired field value descriptions
The value rows carry a muted second line because the bold name is not unique: two request-id rows differ only by their path, and selecting one commits the path.
Paired field preset
The same paired field arriving pre-filled from a controlled value, rendered as the single chip it becomes.
Nested value submenu
Values grouped under section headers, with one row opening a submenu of sub-types: only leaves commit, so the expression never carries a group. A fully selected group collapses to its own label in the chip while a partial one lists the chosen leaves, and typing flattens the tree to matches at any depth.
FilterInputChip
Default
The three segments a chip is made of; inside FilterInput each one is separately clickable, which is how a committed filter gets edited.
With error
error reddens the chip for a value that was rejected. It is presentational only — the expression underneath is unchanged.
With long text
Long text in both segments. The chip caps at 320px; segments size to their content, with the attribute capped at 180px and the value guaranteed 60px minimum. When space is tight, the attribute shrinks first (since the value is what the filter matches on), both truncating with ellipsis rather than one segment collapsing to zero.
With value max width
A field with its own valueMaxWidth (here 500px) lifts the chip's blanket cap and lets the value segment run wide, truncating with an ellipsis only past that width — for long freeform values like parameter-path expressions (AS-1064). The full value is preserved for matching.
Realistic example
The same chip carrying real content, which is where the segment widths actually get tested.
And operator
The AND connector is itself a chip, clickable to change the join. Standalone it reads FilterInput context, so the story wraps it in a no-op provider.
Or operator
The OR connector, same shape — which is why AND/OR needs no separate control.
Combined with and
Two conditions and the connector between them: what the input assembles as each chip commits.
Combined with or
The same pair joined by OR, where the connector is the only difference between two very different queries.
With delete button
onRemove reveals the remove button on hover, so a resting filter row stays quiet.
Error with delete
Error plus remove — a rejected chip has to stay removable, since dropping it is usually the fastest fix.
Interactive delete example
Removing chips one at a time, with the connectors closing up behind them.
Disabled
disabled locks a chip: dimmed, no click, no remove, for a condition the surrounding page owns.
Disabled with on remove
disabled wins over onRemove — no remove button appears, so a locked chip cannot be dropped by accident.
Disabled and interactive mix
Locked and editable chips in one row, which is what a drill-down actually looks like.
Building attribute only
building is the half-made chip shown while a condition is being composed — attribute chosen, operator next.
Building with operator
One step on, waiting for a value.
Building complete
All three segments filled, at the point where the chip commits and stops building.
All states showcase
Every chip state in one frame — the quickest way to check a visual change has not shifted one of them.
Paired
A paired chip carries two triplets separated by a semicolon, for a field whose value means nothing without its key.
Paired with error
The error lands on the half that is wrong — here the required second value — rather than reddening the whole chip.
Paired with long text
The same cap, 380px across two triplets. The base value is held to 90px so it cannot hide its partner, but every other segment keeps its full width, so the second value is the one that gives way.
Composition
Default
The raw backend payload rendered as-is: around fifty fields, a hundred-plus application list, and the paired context-parameter field — the breadth the pattern has to survive.
Suggestions only
With strictValues: false everywhere, option lists become suggestions and any typed value commits, which is how the Attacks page treats the schema. Type checks and explicit validate callbacks still apply.
Simple
Two fields, to show the same component scales down — though at this size a pair of Selects is usually the better answer.
Backend integration
The schema arriving from a fetch: until fields exists there is nothing to filter by, so the input waits behind a placeholder block.
FilterInputFieldMenu
Default
The plain list — every field in the config, label first, whatever its type.
Few fields
A short config, to check the menu does not pad itself out.
Closed
open={false} renders nothing at all — no collapsed shell, no placeholder — so
this frame is deliberately empty. It is the one story with no trigger.
Interactive
Selection wired up, so you can watch which field the menu hands back.
With search
Typing filters the list by label and name, case-insensitively — try “status” or “CWE”.
With recent fields
recentConditions puts the last few filters back at the top, capped at three —
what keeps a fifty-field menu usable day to day. Each row replays the whole
condition, not just the field.
With suggestions
A curated suggestions section, for the handful of fields most people reach for first.
With groups
Fields under labelled group headers, in array order, with anything left out of
every group falling into a trailing headerless section — here, CWE.
With descriptions
Hovering or keyboard-focusing a row opens a popover beside the menu with the description and, where the value format is not obvious, an example. A row with no description opens nothing, and group headers are inert.
With scrollable descriptions
A described list long enough to scroll, for checking the popover keeps up with the cursor and the keyboard.
With recent and suggestions
Both props set, and only Recent renders — the two shortcut sections are mutually exclusive, so suggestions are the fallback for someone with no history rather than a second row of shortcuts.
FilterInputOperatorMenu
String type
A string field: equality, substring matching, set membership, and the two presence checks.
Integer type
Numbers add the comparison operators, which is the usual reason to reach for a query builder at all, with in below the rule as its own group. between is not here — it is date-only.
Float type
Same comparisons as integer, minus in: picking an exact float out of a list is not a real query.
Date type
Dates are the only type that offers between, so a time window is one condition rather than two, and the comparisons read as before and after.
Boolean type
A boolean offers is / is not and the presence checks, and nothing else is worth asking.
Enum type
An enum trades comparison for set membership: is one of / is not one of is the operator that earns its place here.
Interactive
Selection wired up, with the chosen operator echoed beside the trigger.
Keyboard navigation
Arrow keys move, Enter selects, Escape closes — the menu is fully operable without a pointer once the trigger has opened it.