J3W1 / DESIGN SYSTEM
Search field
The text-field box around a native search input with a magnifier, a clear button that appears with a value, an optional shortcut hint, a loading glyph and a no-results status line.
stable · LIGHT DOM · 1.1.0
Visible native controls retain FormData, labels, constraints, disabled fieldsets and reset. No duplicate form-value mechanism is installed.
Live variants
default
Matches names and paths; Escape clears.
No results for “site.css”.
<j3w1-search-field id="example-search-field-default"><div class="search-field" role="search">
<label class="search-field-label" for="example-search-field-default-sf-files">Search files</label>
<div class="search-field-root">
<svg class="search-field-icon" aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="square"><path d="M10.5 10.5L14 14"></path><rect x="2" y="2" width="9" height="9"></rect></svg>
<span class="search-field-loading" aria-hidden="true">⋯</span>
<input class="search-field-input" id="example-search-field-default-sf-files" type="search" value="site.css" placeholder="Name or path" autocomplete="off" aria-describedby="example-search-field-default-sf-files-help example-search-field-default-sf-files-status">
<button class="search-field-clear" type="button" aria-label="Clear search files"><svg aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="square"><path d="M4 4l8 8M12 4l-8 8"></path></svg></button>
</div>
<p class="search-field-help" id="example-search-field-default-sf-files-help">Matches names and paths; Escape clears.</p>
<p class="search-field-status" id="example-search-field-default-sf-files-status" role="status">No results for “site.css”.</p>
</div></j3w1-search-field>with-shortcut
Press / anywhere to search.
No results for “focus.ring”.
<j3w1-search-field id="example-search-field-with-shortcut"><div class="search-field" role="search">
<label class="search-field-label" for="example-search-field-with-shortcut-sf-tokens">Search tokens</label>
<div class="search-field-root">
<svg class="search-field-icon" aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="square"><path d="M10.5 10.5L14 14"></path><rect x="2" y="2" width="9" height="9"></rect></svg>
<span class="search-field-loading" aria-hidden="true">⋯</span>
<input class="search-field-input" id="example-search-field-with-shortcut-sf-tokens" type="search" value="focus.ring" placeholder="Role or value" autocomplete="off" aria-describedby="example-search-field-with-shortcut-sf-tokens-help example-search-field-with-shortcut-sf-tokens-status">
<button class="search-field-clear" type="button" aria-label="Clear search tokens"><svg aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="square"><path d="M4 4l8 8M12 4l-8 8"></path></svg></button>
<kbd class="search-field-kbd" aria-hidden="true">/</kbd>
</div>
<p class="search-field-help" id="example-search-field-with-shortcut-sf-tokens-help">Press / anywhere to search.</p>
<p class="search-field-status" id="example-search-field-with-shortcut-sf-tokens-status" role="status">No results for “focus.ring”.</p>
</div></j3w1-search-field>Install and register
Use the exact version. If npm publication is pending, install the release tarball from the installation guide.
npm install --save-exact @j3w1/ui@1.1.0import '@j3w1/ui/tokens.css';
import '@j3w1/ui/styles/search-field.css';
import '@j3w1/ui/register/search-field';Insert the maintained markup above after loading these imports. Its native children provide accessible names and form behavior; the empty custom tag alone does not create a control.
Copy the complete implementation
npx --package=@j3w1/ui@1.1.0 j3w1-ui copy search-field --out ./vendor/j3w1/search-fieldThe CLI verifies every file before writing and refuses overwrites. Serve the output over HTTP and open index.html. Keep its modules, CSS, tokens and licence notices together.
Public API
attributes
| Name | Type / signature | Meaning |
|---|---|---|
disabled | CustomEvent | Disable the native controls owned by this instance. |
loading | CustomEvent | Mark the primary control busy and prevent duplicate activation. |
value | CustomEvent | Forwards value to the primary native control. |
required | CustomEvent | Forwards required to the primary native control. |
readonly | CustomEvent | Forwards readonly to the primary native control. |
checked | CustomEvent | Forwards checked to the primary native control. |
properties
| Name | Type / signature | Meaning |
|---|---|---|
disabled | boolean | Delegates disabled state to native children. |
name | string | Native control name; application form keys remain explicit. |
value | string | Primary native value; assignment does not fabricate user events. |
checked | boolean | Native checkbox state. |
required | boolean | Native required constraint. |
readOnly | boolean | Native readonly property. |
form | HTMLFormElement | null | Owning native form. Read only. |
methods
| Name | Type / signature | Meaning |
|---|---|---|
refresh | (): void | Reconnect behavior after replacing native child structure. |
focus | (options?: FocusOptions): void | Focus the first usable native control. |
checkValidity | (): boolean | Check owned native constraints. |
reportValidity | (): boolean | Report the first invalid owned control. |
clear | (): void | Clear an editable primary input and emit native input/change. |
events
| Name | Type / signature | Meaning |
|---|---|---|
j3w1-change | CustomEvent | Native change from an owned control, alongside the original native event. |
Dependencies and verification
Registered components: none. Style dependencies: none.
Package presence establishes an available implementation. Actual passes depend on the tested artifact and environment. Read specification execution evidence; read packed-consumer evidence; inspect the complete state matrix.
Full implementation manifest, API and token dependency closure
Canonical specification
Purpose
Filtering a list or table or searching a site. It is the text field’s box with the parts a search needs: an icon that says what the box is for, a clear button, a place for the shortcut that reaches it, a loading glyph while results arrive and a status line when nothing matches. A search that offers suggestions as you type is the combobox component.
Anatomy
Label above (or visually hidden); the box with the magnifier, the input, the clear button and the optional hint; help; the status line. The loading glyph takes the magnifier’s slot so the box never changes size.
States
| State | Visual | Non-colour channel |
|---|---|---|
| default | 1px color.border.control on color.surface.input; magnifier color.icon.default; text color.text.default | the magnifier |
| hover | background → color.interaction.hover.bg; the clear button → color.action.tertiary.hover-bg when hovered | cursor: text |
| focus-visible | border → color.border.active; ring 1px dashed color.interaction.focus.ring at −2px; the hint hides | the ring |
| placeholder-shown | placeholder in color.text.placeholder, italic; no clear button | italic; the clear button is absent |
| filled | as default with a value; the clear button is present | the clear button |
| loading | the static ⋯ glyph in color.text.muted replaces the magnifier; the input stays editable | glyph; aria-busy |
| disabled | text and icon color.text.disabled; border color.border.disabled; background color.interaction.disabled.bg; no clear button | disabled; cursor: not-allowed |
| no-results | the status line “No results for …” in color.text.muted below the help; the box unchanged | the status text; role="status" |
Precedence: disabled > loading > hover; focus-visible is always drawn. A search field is never invalid; an empty result is a status, not an error.
Keyboard
Escape clears a non-empty value and keeps focus, which is native for
type="search" in most engines and scripted where it is not. The clear
button is a separate tab stop only while it is visible. The shortcut in the
hint is bound by the host and never captured while another field has focus.
Accessibility
A programmatic label is required even when hidden. The landmark
role="search" lets users jump to it. The status line is role="status"
so “No results” is announced once, after the query settles, and the result
count is announced there too (“12 results”). The magnifier and hint are
aria-hidden; the clear button is named “Clear
Portability
The text field plus icons and a status line. Hosts hide their own cancel button; hosts that cannot draw the hint omit it and keep the shortcut in the tooltip.
Non-examples
Rounded or pill-shaped search boxes. A magnifier button that submits instead of an icon. A spinner while loading. Results announced on every keystroke. “No results” in red or with the ✕ glyph. A clear button that is always visible. A search field without a label. Disabling by opacity.