SGUI / Development
SearchField
Reusable search with clear action, alias matching, portaled results and keyboard navigation.
Loading examples…
Loading examples…
Examples
Loading examples…
Component documentation
SGUI / Development
Reusable search with clear action, alias matching, portaled results and keyboard navigation.
Loading examples…
Loading examples…
Loading examples…
The standard component owns the input, clear action, alias matching, results dropdown, Arrow/Home/End/Escape keys and native result links or actions. Pick a result to put its label in this example field. Hosts supply data and navigation.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import {SearchField} from '@structured-growth/sg-ui/experimental';
import {Box} from '@structured-growth/sg-ui/primitives';
export default function SearchFieldplaygroundExample() {
const items=[{"id":"design","label":"Design systems","description":"Course library","keywords":["components","UI"]},{"id":"research","label":"User research","description":"Research methods","keywords":["interviews"]},{"id":"engineering","label":"Engineering","description":"Technical courses","keywords":["code"]}];
const [query,setQuery]=useState("");
return (
<>
<ThemeScope density="compact">
<Box style={{inlineSize:'24rem',maxInlineSize:'100%'}}>
<SearchField label={"Find a course"} placeholder={"Search courses or aliases"} description={"Try components or interviews."} descriptionPlacement="above" items={items} value={query} onValueChange={setQuery} onResultSelect={item=>setQuery(item.label)} filter="contains" showResults={true} expandable={false} showClearButton={true} disabled={false} readOnly={false} loading={false} errorMessage={undefined}/>
</Box>
</ThemeScope>
</>
);
}
The standard component owns the input, clear action, alias matching, results dropdown, Arrow/Home/End/Escape keys and native result links or actions. Pick a result to put its label in this example field. Hosts supply data and navigation.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import {SearchField} from '@structured-growth/sg-ui/experimental';
import {Box} from '@structured-growth/sg-ui/primitives';
export default function SearchFieldcompactExample() {
const items=[{"id":"design","label":"Design systems","description":"Course library","keywords":["components","UI"]},{"id":"research","label":"User research","description":"Research methods","keywords":["interviews"]},{"id":"engineering","label":"Engineering","description":"Technical courses","keywords":["code"]}];
const [query,setQuery]=useState("");
return (
<>
<ThemeScope density="compact">
<Box style={{inlineSize:'24rem',maxInlineSize:'100%'}}>
<SearchField label={"Find a course"} placeholder={"Search courses or aliases"} description={"Try components or interviews."} descriptionPlacement="above" items={items} value={query} onValueChange={setQuery} onResultSelect={item=>setQuery(item.label)} filter="contains" showResults={true} expandable={false} showClearButton={true} disabled={false} readOnly={false} loading={false} errorMessage={undefined}/>
</Box>
</ThemeScope>
</>
);
}
The standard component owns the input, clear action, alias matching, results dropdown, Arrow/Home/End/Escape keys and native result links or actions. Pick a result to put its label in this example field. Hosts supply data and navigation.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import {SearchField} from '@structured-growth/sg-ui/experimental';
import {Box} from '@structured-growth/sg-ui/primitives';
export default function SearchFieldcomfortableExample() {
const items=[{"id":"design","label":"Design systems","description":"Course library","keywords":["components","UI"]},{"id":"research","label":"User research","description":"Research methods","keywords":["interviews"]},{"id":"engineering","label":"Engineering","description":"Technical courses","keywords":["code"]}];
const [query,setQuery]=useState("");
return (
<>
<ThemeScope density="comfortable">
<Box style={{inlineSize:'24rem',maxInlineSize:'100%'}}>
<SearchField label={"Find a course"} placeholder={"Search courses or aliases"} description={"Try components or interviews."} descriptionPlacement="above" items={items} value={query} onValueChange={setQuery} onResultSelect={item=>setQuery(item.label)} filter="contains" showResults={true} expandable={false} showClearButton={true} disabled={false} readOnly={false} loading={false} errorMessage={undefined}/>
</Box>
</ThemeScope>
</>
);
}
Host-filtered mode accepts results for the current query. This example filters local data; a production host owns fetching, cancellation and stale-response rejection.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import {SearchField} from '@structured-growth/sg-ui/experimental';
import {Box} from '@structured-growth/sg-ui/primitives';
export default function SearchFieldremoteExample() {
const items=[{"id":"design","label":"Design systems","description":"Course library","keywords":["components","UI"]},{"id":"research","label":"User research","description":"Research methods","keywords":["interviews"]},{"id":"engineering","label":"Engineering","description":"Technical courses","keywords":["code"]}];
const [query,setQuery]=useState("");
return (
<>
<ThemeScope density="compact">
<Box style={{inlineSize:'24rem',maxInlineSize:'100%'}}>
<SearchField label={"Find a course"} placeholder={"Search courses or aliases"} description={"Try components or interviews."} descriptionPlacement="above" items={items.filter(item=>item.label.toLowerCase().includes(query.toLowerCase()))} value={query} onValueChange={setQuery} onResultSelect={item=>setQuery(item.label)} filter="none" showResults={true} expandable={false} showClearButton={true} disabled={false} readOnly={false} loading={false} errorMessage={undefined}/>
</Box>
</ThemeScope>
</>
);
}
The same public component can submit a query while a host renders results elsewhere. Enter or the form button requests a local operation; the host owns the actual search service.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import {SearchField,Button} from '@structured-growth/sg-ui/experimental';
import {Box,Stack,Typography} from '@structured-growth/sg-ui/primitives';
export default function StandaloneSearchExample() {
const [query,setQuery]=useState("");
const [message,setMessage]=useState("");
const submit=(text:string)=>setMessage(text.trim()?`Search requested for “${text.trim()}”.`:'Enter a search term.');
return (
<>
<ThemeScope density="compact">
<Box style={{inlineSize:'24rem',maxInlineSize:'100%'}}>
<form onSubmit={event=>{event.preventDefault();submit(query);}}>
<Stack align="start" gap={3}>
<SearchField label="Search the course library" placeholder="Search courses" name="query" value={query} onValueChange={setQuery} showResults={false} onSearch={submit}/>
<Button type="submit">Search courses</Button>
{message&&<Typography role="status">{message}</Typography>}
</Stack>
</form>
</Box>
</ThemeScope>
</>
);
}
The search icon expands into the standard search bar. Escape or the close action clears this query, collapses the field and returns focus. Reduced motion skips the transition. Hosts own the filtered results.
'use client';
import { useState } from 'react';
import {SearchField} from '@structured-growth/sg-ui/experimental';
export default function ExpandableSearchExample() {
const [query,setQuery]=useState("");
return (
<>
<SearchField aria-label="Search courses" expandable showResults={false} placeholder="Search courses" value={query} onValueChange={setQuery}/>
</>
);
}