You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/src/uix/soma/components/search-field
dev eee0c6b4b1
Add search field provider coverage
5 months ago
..
components remove backward-compat re-export shims 5 months ago
README.md morfo: cross-layer contract + 14 new WAI-ARIA components + Dialog wired 6 months ago
exports.ts morfo: cross-layer contract + 14 new WAI-ARIA components + Dialog wired 6 months ago
index.ts morfo: cross-layer contract + 14 new WAI-ARIA components + Dialog wired 6 months ago
langs.ts morfo: cross-layer contract + 14 new WAI-ARIA components + Dialog wired 6 months ago
search-field-provider.svelte.test.ts Add search field provider coverage 5 months ago
search-field-provider.svelte.ts Drive SearchField root attrs from Soma runtime 5 months ago
types.ts morfo: cross-layer contract + 14 new WAI-ARIA components + Dialog wired 6 months ago

README.md

SearchField

Text input tuned for search: <input type="search" role="searchbox"> with an integrated clear button, Escape-to-clear, Enter-to-submit, and Field.Provider OR-merge for disabled / readonly / required / invalid.

Anatomy

<SearchField.Provider bind:value onSubmit={(v) => runSearch(v)}>
	<SearchField.Input placeholder="Search…" />
	<SearchField.ClearTrigger>×</SearchField.ClearTrigger>
</SearchField.Provider>

Parts

Part Element Description
Provider <div> Root context. Holds value, flags (disabled/readonly/required/invalid).
Input <input> type="search" role="searchbox". Reads OR-merged state from Field.
ClearTrigger <button> Clears the value on click. Hidden via data-empty when value is empty.

Props

Provider

Prop Type Default Description
id string auto DOM id.
value string '' Controlled input value. bind:value supported.
onValueChange (value: string) => void — Fires on every keystroke.
onSubmit (value: string) => void — Fires on Enter in the Input.
onClear () => void — Fires on Escape, ClearTrigger click, or programmatic clear().
clearOnEscape boolean true If false, Escape is a no-op (leave dismissal to the surrounding dialog).
disabled boolean false OR-merged with Field.disabled.
readonly boolean false OR-merged with Field.readonly.
required boolean false OR-merged with Field.required.
invalid boolean false OR-merged with Field.invalid.
placeholder string — Forwarded to the Input element.
aria-label string translated Search Accessible name when no Field.Label is present.

ClearTrigger

Prop Type Default Description
id string auto DOM id.
aria-label string translated Clear search Accessible name.

ARIA

Part Attribute Value
Input role searchbox
Input type search
Input aria-invalid When invalid is true
Input aria-required When required is true
Input aria-labelledby Set by Field.Label when composed inside Field
ClearTrigger type button
ClearTrigger aria-label Translated default unless overridden
ClearTrigger tabindex -1 — not in the tab order (clear via Escape instead)

Data Attributes

Part Attribute Values
Provider data-search-field Always present
Provider data-empty Present when value === ''
Provider data-focused Present while Input has focus
Provider data-disabled Present when disabled (merged)
Provider data-readonly Present when readonly (merged)
Provider data-required Present when required (merged)
Provider data-invalid Present when invalid (merged)
Input data-search-field-input Always present
Input data-empty / data-focused / … Mirrors Provider for direct styling
ClearTrigger data-search-field-clear-trigger Always present
ClearTrigger data-empty Present when value is empty (hook for visibility)

Keyboard

Key Action
Enter Fires onSubmit(value)
Escape Clears the value (when clearOnEscape), fires onClear + onValueChange

i18n

Key English Spanish
label Search Buscar
clear Clear search Borrar búsqueda

Override per-instance via aria-label on Provider / ClearTrigger.

Comparison

Feature Soma Radix Ark UI bits-ui react-aria
Dedicated component ✅ ❌ ❌ ❌ ✅
role="searchbox" ✅ — — — ✅
Integrated ClearTrigger part ✅ — — — ✅
Escape-to-clear ✅ — — — ✅
Enter-to-submit callback ✅ — — — ✅
Field OR-merge (disabled/invalid/…) ✅ — — — ⚠️¹
Translated default aria-label ✅ — — — ❌
data-empty on root for clear visibility ✅ — — — ❌
Debounce prop ❌² — — — ❌

¹ react-aria couples SearchField with its own FieldContext; soma participates in the shared Field.Provider that all form primitives use. ² Debouncing belongs on the consumer: onValueChange → your own debounce(value, 300) hook. No built-in, by design.

Usage

Standalone

<script>
	import { SearchField } from '$soma/components';
	let q = $state('');
</script>

<SearchField.Provider bind:value={q} onSubmit={(v) => goto(`/search?q=${v}`)}>
	<SearchField.Input placeholder="Search posts…" />
	<SearchField.ClearTrigger>×</SearchField.ClearTrigger>
</SearchField.Provider>

Inside a Field (label + helper + error)

<Field.Provider invalid={!!error}>
	<Field.Label>Find a product</Field.Label>
	<Field.Control>
		<SearchField.Provider bind:value>
			<SearchField.Input placeholder="Name, SKU, tag…" />
			<SearchField.ClearTrigger>×</SearchField.ClearTrigger>
		</SearchField.Provider>
	</Field.Control>
	<Field.HelperText>Press Enter to search, Escape to clear.</Field.HelperText>
	{#if error}<Field.ErrorText>{error}</Field.ErrorText>{/if}
</Field.Provider>
<script>
	import { debounce } from '$lib/util';
	let q = $state('');
	const runSearch = debounce((v) => fetchResults(v), 300);
</script>

<SearchField.Provider bind:value={q} onValueChange={runSearch}>
	<SearchField.Input placeholder="Live search…" />
	<SearchField.ClearTrigger>×</SearchField.ClearTrigger>
</SearchField.Provider>

Powered by TurnKey Linux.