@ -38,6 +38,53 @@
const partsList = $derived([...compiled.parts.byKebab.values()]);
const events = $derived([...compiled.actions.byName.values()]);
const isEmpty = $derived(value.length === 0);
// Demo dataset for the live search panel.
const components: { name : string ; group : string } [] = [
{ name : 'Accordion' , group : 'Disclosure' } ,
{ name : 'Avatar' , group : 'Media' } ,
{ name : 'Breadcrumb' , group : 'Navigation' } ,
{ name : 'Button' , group : 'Action' } ,
{ name : 'Calendar' , group : 'Forms' } ,
{ name : 'Checkbox' , group : 'Forms' } ,
{ name : 'Collapsible' , group : 'Disclosure' } ,
{ name : 'Color picker' , group : 'Forms' } ,
{ name : 'Combobox' , group : 'Forms' } ,
{ name : 'Date picker' , group : 'Forms' } ,
{ name : 'Dialog' , group : 'Overlay' } ,
{ name : 'Drawer' , group : 'Overlay' } ,
{ name : 'Editable' , group : 'Forms' } ,
{ name : 'Field' , group : 'Forms' } ,
{ name : 'File upload' , group : 'Forms' } ,
{ name : 'Icon' , group : 'Media' } ,
{ name : 'Meter' , group : 'Status' } ,
{ name : 'Number field' , group : 'Forms' } ,
{ name : 'Pagination' , group : 'Navigation' } ,
{ name : 'Popover' , group : 'Overlay' } ,
{ name : 'Progress' , group : 'Status' } ,
{ name : 'Radio group' , group : 'Forms' } ,
{ name : 'Rating group' , group : 'Forms' } ,
{ name : 'Search field' , group : 'Forms' } ,
{ name : 'Select' , group : 'Forms' } ,
{ name : 'Slider' , group : 'Forms' } ,
{ name : 'Switch' , group : 'Forms' } ,
{ name : 'Tabs' , group : 'Disclosure' } ,
{ name : 'Tag group' , group : 'Forms' } ,
{ name : 'Time picker' , group : 'Forms' } ,
{ name : 'Toast' , group : 'Overlay' } ,
{ name : 'Toggle' , group : 'Action' } ,
{ name : 'Toolbar' , group : 'Action' } ,
{ name : 'Tooltip' , group : 'Overlay' }
];
// Filter matches name OR group, case-insensitive.
const results = $derived.by(() => {
const q = value.trim().toLowerCase();
if (!q) return components;
return components.filter(
(c) => c.name.toLowerCase().includes(q) || c.group.toLowerCase().includes(q)
);
});
const variants: SearchFieldVariant[] = ['surface', 'outline', 'ghost'];
const colors: SearchFieldColor[] = [
'primary',
@ -170,6 +217,31 @@
< X size = "1em" decorative / >
< / SearchField.ClearTrigger >
< / SearchField >
<!-- Live result panel — filters the demo dataset by name/group. -->
< ul
class="search-field-results"
role="listbox"
aria-label="Filtered components"
aria-live="polite"
>
{ #if results . length === 0 }
< li class = "search-field-results-empty" >
No matches for < strong > "{ value } "</ strong >
< / li >
{ : else }
{ #each results as item ( item . name )}
< li class = "search-field-result" role = "option" aria-selected = "false" >
< span class = "search-field-result-name" > { item . name } </ span >
< span class = "search-field-result-group" > { item . group } </ span >
< / li >
{ /each }
{ /if }
< / ul >
< div class = "search-field-results-meta" >
< span data-uix-stage-trace-key > results< / span >
{ results . length } / { components . length }
< / div >
< / div >
< / div >
< div data-uix-stage-trace >
@ -561,3 +633,51 @@
< / section >
{ /if }
< / div >
< style >
.search-field-results {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
gap: var(--uix-space-1);
margin-block-start: var(--uix-space-3);
padding: 0;
list-style: none;
max-block-size: 14rem;
overflow-y: auto;
}
.search-field-result {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: var(--uix-space-2);
padding: var(--uix-space-1-5) var(--uix-space-2);
border: 1px solid var(--color-border-subtle);
border-radius: var(--radius-md);
background: var(--color-surface-default);
font-size: var(--uix-text-sm);
}
.search-field-result-name {
color: var(--color-content-primary);
font-weight: 500;
}
.search-field-result-group {
color: var(--color-content-muted);
font-size: var(--uix-text-xs);
}
.search-field-results-empty {
grid-column: 1 / -1;
padding: var(--uix-space-3);
color: var(--color-content-muted);
text-align: center;
font-size: var(--uix-text-sm);
}
.search-field-results-meta {
display: flex;
align-items: center;
gap: var(--uix-space-2);
margin-block-start: var(--uix-space-2);
color: var(--uix-text-muted);
font-family: var(--uix-font-mono);
font-size: var(--uix-text-xs);
}
< / style >