j3w1 / theme

j3w1 / theme4.0.0

j3w1 / command

  • SPEC Overview
  • SPEC Foundations
  • SPEC Components
  • SPEC Patterns
  • SPEC Tokens
  • SPEC Tools
  • SPEC Workbench
  • SPEC Form builder
  • SPEC Task kit
  • SPEC Recipes
  • SPEC Figma bridge
  • SPEC Report an issue
  • SPEC Implement
  • SPEC For agents
  • SPEC Ports
  • SPEC Releases
  • SPEC Specification
  • DEMO Vue application demo

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

Markup
<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

Markup
<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.0
import '@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.

Vue SFC, React, Astro and plain HTML integration →

Copy the complete implementation

npx --package=@j3w1/ui@4.0.0 j3w1-ui copy search-field --out ./vendor/j3w1/search-field

The 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

NameType / signatureMeaning
disabledCustomEventDisable the native controls owned by this instance.
loadingCustomEventMark the primary control busy and prevent duplicate activation.
valueCustomEventForwards value to the primary native control.
requiredCustomEventForwards required to the primary native control.
readonlyCustomEventForwards readonly to the primary native control.
checkedCustomEventForwards checked to the primary native control.

properties

NameType / signatureMeaning
disabledbooleanDelegates disabled state to native children.
namestringNative control name; application form keys remain explicit.
valuestringPrimary native value; assignment does not fabricate user events.
checkedbooleanNative checkbox state.
requiredbooleanNative required constraint.
readOnlybooleanNative readonly property.
formHTMLFormElement | nullOwning native form. Read only.

methods

NameType / signatureMeaning
refresh(): voidReconnect behavior after replacing native child structure.
focus(options?: FocusOptions): voidFocus the first usable native control.
checkValidity(): booleanCheck owned native constraints.
reportValidity(): booleanReport the first invalid owned control.
clear(): voidClear an editable primary input and emit native input/change.

events

NameType / signatureMeaning
j3w1-changeCustomEventNative 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

  • Family: Basic forms
  • Maturity: stable
  • Priority: R1
  • Since: 0.1.0
  • Native control: native <input type="search"> with <label> inside a role="search" landmark; status through role="status" — APG pattern
  • specified
  • demonstrated

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.

PartRoleValueUse
root.bgcolor.surface.inputapproveduse#000000Form-control fill.
root.bordercolor.border.controlapproveduse#c81a1aD-041 owner correction: red control and floating-frame borders, distinct from rose text.
root.bg-hovercolor.interaction.hover.bgapproveduse#1c1010D-041 interaction.hover.bg: color.primitive.modern.hover.
root.border-focuscolor.border.activeobserveduse#e53935Active or focused control border.
root.ringcolor.interaction.focus.ringobserveduse#e539351px dashed focus ring on controls and rows.
root.border-disabledcolor.border.disabledapproveduse#482b2bD-041 border.disabled: color.primitive.modern.divider.
root.bg-disabledcolor.interaction.disabled.bgapproveduse#0d0707D-041 interaction.disabled.bg: color.primitive.modern.panel.
input.textcolor.text.defaultapproveduse#e99499D-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-disabledcolor.text.disabledapproveduse#a3676bD-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
input.placeholdercolor.text.placeholderapproveduse#bd787dD-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
input.caretcolor.code.caretapproveduse#ffa2a7D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
icon.strokecolor.icon.defaultapproveduse#e99499D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
loading.glyphcolor.text.mutedapproveduse#d4868bD-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
clear.textcolor.action.tertiary.textapproveduse#e99499D-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-hovercolor.action.tertiary.hover-bgobserveduse#1c0a09Ghost and icon button hover.
kbd.textcolor.text.mutedapproveduse#d4868bD-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
kbd.bordercolor.border.defaultapproveduse#482b2bD-041 border.default: color.primitive.modern.divider.
label.textcolor.text.brightapproveduse#ffa2a7D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
help.textcolor.text.mutedapproveduse#d4868bD-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
status.textcolor.text.mutedapproveduse#d4868bD-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).

StateDefaultWith shortcut hint
default
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

StateVisualNon-colour channel
default1px color.border.control on color.surface.input; magnifier color.icon.default; text color.text.defaultthe magnifier
hoverbackground → color.interaction.hover.bg; a hovered clear button → color.action.tertiary.hover-bgcursor: text
focus-visibleborder → color.border.active; 1px dashed color.interaction.focus.ring ring at −2px; the hint hidesthe ring
placeholder-shownplaceholder in color.text.placeholder, italic; no clear buttonitalic; clear button absent
filledas default with a value; clear button presentthe clear button
loadingstatic ⋯ in color.text.muted replaces the magnifier; input stays editableglyph; aria-busy
disabledtext and icon color.text.disabled, border color.border.disabled, background color.interaction.disabled.bg; no clear buttondisabled; cursor: not-allowed
no-resultsstatus line “No results for …” in color.text.muted below the help; box unchangedthe 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.

PairStateKindForegroundBackgroundRatioMinResult
search-field default textdefaulttextcolor.text.default #e99499color.surface.input #0000009.164.5pass
search-field default borderdefaultuicolor.border.control #c81a1acolor.surface.input #0000003.623pass
search-field hover texthovertextcolor.text.default #e99499color.interaction.hover.bg #1c10108.104.5pass
search-field hover borderhoveruicolor.border.control #c81a1acolor.interaction.hover.bg #1c10103.203pass
search-field focus-visible textfocus-visibletextcolor.text.default #e99499color.surface.input #0000009.164.5pass
search-field focus-visible borderfocus-visibleuicolor.border.active #e53935color.surface.input #0000004.973pass
search-field focus-visible outlinefocus-visibleuicolor.interaction.focus.ring #e53935color.surface.input #0000004.973pass
search-field placeholder-shown textplaceholder-showntextcolor.text.placeholder #bd787dcolor.surface.input #0000006.154.5pass
search-field placeholder-shown borderplaceholder-shownuicolor.border.control #c81a1acolor.surface.input #0000003.623pass
search-field loading textloadingtextcolor.text.default #e99499color.surface.input #0000009.164.5pass
search-field loading borderloadinguicolor.border.control #c81a1acolor.surface.input #0000003.623pass
search-field no-results textno-resultstextcolor.text.default #e99499color.surface.input #0000009.164.5pass
search-field no-results borderno-resultsuicolor.border.control #c81a1acolor.surface.input #0000003.623pass
magnifier on the input surface—uicolor.icon.default #e99499color.surface.input #0000009.163pass
loading glyph and kbd hint on the input surface—textcolor.text.muted #d4868bcolor.surface.input #0000007.584.5pass
clear glyph on the input surface—textcolor.action.tertiary.text #e99499color.surface.input #0000009.164.5pass
clear glyph on its hover fillhovertextcolor.action.tertiary.text #e99499color.action.tertiary.hover-bg #1c0a098.354.5pass
help and no-results status on the panel surface—textcolor.text.muted #d4868bcolor.surface.default #0d07077.224.5pass
kbd hint edge (decorative)—uicolor.border.default #482b2bcolor.surface.input #0000001.661pass
disabled text (exempt; house floor 3:1)disableduicolor.text.disabled #a3676bcolor.interaction.disabled.bg #0d07074.483pass
disabled border (exempt)disableduicolor.border.disabled #482b2bcolor.interaction.disabled.bg #0d07071.581pass

Keys

KeyAction
Tab / Shift+TabInput, then the clear button when it is visible.
EscapeClears a non-empty value and keeps focus; with an empty value, nothing.
EnterRuns the search when the host does not search as you type.
/ or Ctrl+KFocuses 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