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 · 4.0.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@4.0.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@4.0.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
Search field 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.
Report an issue with this component
Tokens
Focus a role to inspect its values; follow its link for persistent usage and source details.
| Part | Role | Value | Use |
|---|---|---|---|
root.bg | color.surface.inputapproveduse | #000000 | Form-control fill. |
root.border | color.border.controlapproveduse | #c81a1a | D-041 owner correction: red control and floating-frame borders, distinct from rose text. |
root.bg-hover | color.interaction.hover.bgapproveduse | #1c1010 | D-041 interaction.hover.bg: color.primitive.modern.hover. |
root.border-focus | color.border.activeobserveduse | #e53935 | Active or focused control border. |
root.ring | color.interaction.focus.ringobserveduse | #e53935 | 1px dashed focus ring on controls and rows. |
root.border-disabled | color.border.disabledapproveduse | #482b2b | D-041 border.disabled: color.primitive.modern.divider. |
root.bg-disabled | color.interaction.disabled.bgapproveduse | #0d0707 | D-041 interaction.disabled.bg: color.primitive.modern.panel. |
input.text | color.text.defaultapproveduse | #e99499 | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
input.text-disabled | color.text.disabledapproveduse | #a3676b | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
input.placeholder | color.text.placeholderapproveduse | #bd787d | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
input.caret | color.code.caretapproveduse | #ffa2a7 | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
icon.stroke | color.icon.defaultapproveduse | #e99499 | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
loading.glyph | color.text.mutedapproveduse | #d4868b | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
clear.text | color.action.tertiary.textapproveduse | #e99499 | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
clear.bg-hover | color.action.tertiary.hover-bgobserveduse | #1c0a09 | Ghost and icon button hover. |
kbd.text | color.text.mutedapproveduse | #d4868b | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
kbd.border | color.border.defaultapproveduse | #482b2b | D-041 border.default: color.primitive.modern.divider. |
label.text | color.text.brightapproveduse | #ffa2a7 | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
help.text | color.text.mutedapproveduse | #d4868b | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
status.text | color.text.mutedapproveduse | #d4868b | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
State matrix
Every declared state and combination, statically rendered; the default cell is live. Sizes: compact, comfortable (switch with the density control above).
| State | Default | With shortcut hint |
|---|---|---|
default | Matches names and paths; Escape clears. No results for “site.css”. |
/
Press / anywhere to search. No results for “focus.ring”. |
hover | ||
focus-visible | ||
placeholder-shown | ||
filled | ||
loading | ||
disabled | ||
no-results |
Purpose
Filtering a list or table, or searching a site. A search that suggests as you type is the combobox.
Anatomy
Parts as listed in the anatomy. 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; a hovered clear button → color.action.tertiary.hover-bg | cursor: text |
| focus-visible | border → color.border.active; 1px dashed color.interaction.focus.ring ring at −2px; the hint hides | the ring |
| placeholder-shown | placeholder in color.text.placeholder, italic; no clear button | italic; clear button absent |
| filled | as default with a value; clear button present | the clear button |
| loading | static ⋯ in color.text.muted replaces the magnifier; 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 | status line “No results for …” in color.text.muted below the help; 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-to-clear is native for type="search" in most engines and scripted
where it is not. The host never captures the shortcut while another field has
focus.
Accessibility
A programmatic label is required even when hidden. The status line announces “No results” once, after the query settles, and the result count there too (“12 results”). The clear button is named “Clear
Portability
Hosts that cannot draw the hint omit it and keep the shortcut in the tooltip.
Non-examples
Rounded or pill-shaped boxes. A magnifier button that submits. A spinner while loading. Results announced on every keystroke. “No results” in red or with the ✕ glyph. An always-visible clear button. No label. Disabling by opacity.
Contrast report
21 declared pairs measured on resolved sRGB values with the WCAG 2.x formula; 0 waived (decorative only), 0 failing. A pass is a design target for the named role, not an application-wide conformance claim.
| Pair | State | Kind | Foreground | Background | Ratio | Min | Result |
|---|---|---|---|---|---|---|---|
| search-field default text | default | text | color.text.default #e99499 | color.surface.input #000000 | 9.16 | 4.5 | pass |
| search-field default border | default | ui | color.border.control #c81a1a | color.surface.input #000000 | 3.62 | 3 | pass |
| search-field hover text | hover | text | color.text.default #e99499 | color.interaction.hover.bg #1c1010 | 8.10 | 4.5 | pass |
| search-field hover border | hover | ui | color.border.control #c81a1a | color.interaction.hover.bg #1c1010 | 3.20 | 3 | pass |
| search-field focus-visible text | focus-visible | text | color.text.default #e99499 | color.surface.input #000000 | 9.16 | 4.5 | pass |
| search-field focus-visible border | focus-visible | ui | color.border.active #e53935 | color.surface.input #000000 | 4.97 | 3 | pass |
| search-field focus-visible outline | focus-visible | ui | color.interaction.focus.ring #e53935 | color.surface.input #000000 | 4.97 | 3 | pass |
| search-field placeholder-shown text | placeholder-shown | text | color.text.placeholder #bd787d | color.surface.input #000000 | 6.15 | 4.5 | pass |
| search-field placeholder-shown border | placeholder-shown | ui | color.border.control #c81a1a | color.surface.input #000000 | 3.62 | 3 | pass |
| search-field loading text | loading | text | color.text.default #e99499 | color.surface.input #000000 | 9.16 | 4.5 | pass |
| search-field loading border | loading | ui | color.border.control #c81a1a | color.surface.input #000000 | 3.62 | 3 | pass |
| search-field no-results text | no-results | text | color.text.default #e99499 | color.surface.input #000000 | 9.16 | 4.5 | pass |
| search-field no-results border | no-results | ui | color.border.control #c81a1a | color.surface.input #000000 | 3.62 | 3 | pass |
| magnifier on the input surface | — | ui | color.icon.default #e99499 | color.surface.input #000000 | 9.16 | 3 | pass |
| loading glyph and kbd hint on the input surface | — | text | color.text.muted #d4868b | color.surface.input #000000 | 7.58 | 4.5 | pass |
| clear glyph on the input surface | — | text | color.action.tertiary.text #e99499 | color.surface.input #000000 | 9.16 | 4.5 | pass |
| clear glyph on its hover fill | hover | text | color.action.tertiary.text #e99499 | color.action.tertiary.hover-bg #1c0a09 | 8.35 | 4.5 | pass |
| help and no-results status on the panel surface | — | text | color.text.muted #d4868b | color.surface.default #0d0707 | 7.22 | 4.5 | pass |
| kbd hint edge (decorative) | — | ui | color.border.default #482b2b | color.surface.input #000000 | 1.66 | 1 | pass |
| disabled text (exempt; house floor 3:1) | disabled | ui | color.text.disabled #a3676b | color.interaction.disabled.bg #0d0707 | 4.48 | 3 | pass |
| disabled border (exempt) | disabled | ui | color.border.disabled #482b2b | color.interaction.disabled.bg #0d0707 | 1.58 | 1 | pass |
Keys
| Key | Action |
|---|---|
| Tab / Shift+Tab | Input, then the clear button when it is visible. |
| Escape | Clears a non-empty value and keeps focus; with an empty value, nothing. |
| Enter | Runs the search when the host does not search as you type. |
| / or Ctrl+K | Focuses the field from anywhere on the page when the host binds the shortcut shown in the hint. |
For agents
Component JSON ·Implementation brief ·Build a task kit ·
Related: text-field combobox command-palette toolbar empty-state kbd
Stress fixtures: FX-LONG FX-320 FX-ZOOM-200 FX-I18N FX-RTL FX-RM FX-HC FX-TOUCH FX-DENSITY FX-STATE-MATRIX