Search Field
A search input with clear and search affordances.
Installation
Included in poetry-ui — available as
poetry_search_field
the moment you've installed Poetry,
with no per-component step. To own the source and edit it, copy it into your app:
bin/rails g poetry:add search-field
Default
<%= poetry_search_field(name: "q", label: "Search", placeholder: "Search…", class: "w-72") %>
With value
<%# Non-empty: the clear affordance shows. Escape clears once; the
next Escape reaches the dismissal layer. %>
<%= poetry_search_field(name: "q", label: "Search", value: "design tokens", class: "w-72") %>
API
Poetry::Ui::SearchField::Component — options are
constructor keywords (the poetry_* helper forwards them);
slots are composed inside the block. Generated from the gem's source documentation.
| Option | Type | Details | Description |
|---|---|---|---|
| described_by: | String | aria-describedby on the input - Field hint/error wiring. | |
| disabled: | Boolean | defaults to false |
Disables the input and hides the clear affordance. |
| id: | String | The input's DOM id - what a Field label's for: must reference. | |
| invalid: | Boolean | defaults to false |
aria-invalid on the input - set by Field/FormBuilder from model errors. |
| label: | String | The accessible name (aria-label) for standalone use - or pair with a Label/Field instead. | |
| name: | String | required | The form field name on the search input. |
| placeholder: | String | Hint text shown while the field is empty. | |
| readonly: | Boolean | defaults to false |
The query can be read but not edited; the clear affordance hides. |
| required: | Boolean | defaults to false |
Marks the input required for native constraint validation. |
| value: | String | The pre-filled query; presence unhides the clear affordance. |
Styling
Every part carries a stable data-slot attribute — target
[data-slot=…] from your own CSS to restyle it. State rides
data attributes on the parts below. This contract is verified against rendered DOM in CI.
| Part | Description |
|---|---|
| [data-slot=search-field] | Root - the controller and the emptiness state ride here |
| [data-slot=input-group-addon] | The leading search-glyph cell - InputGroup's addon vocabulary (the NumberField precedent) |
| [data-slot=search-field-group] | The bordered field surface - InputGroup's chrome, focus ring keyed on the control inside |
| [data-slot=input-group-control] | The native <input type=search> - InputGroup's control slot (the themes' focus-ring hook); WebKit's own cancel affordance suppressed |
State attributes
| Part | Attribute | Condition | Values |
|---|---|---|---|
| search-field | data-empty | the input holds no text (server-set, controller-kept; hides the clear affordance) | — |
| input-group-addon | data-align | always - inline-start holds the glyph, inline-end the clear button | inline-start · inline-end |
Wiring
The Stimulus surface each element carries — declared in the component, verified against rendered DOM in CI. Bare actions fire on the element's default event.
| Element | Controller | Wiring |
|---|---|---|
| root | poetry--core--search-field | registers |
| input | poetry--core--search-field | changed on input · keydown on keydown · target input |
| clear | poetry--core--search-field | holdFocus on pointerdown · clear on click · target clear |