Navigation
Glass Search
A glass search button that opens into a field, as on iOS: the field grows out of the button toward the start and its magnifying glass turns into a close mark. Use it in a header, a toolbar, a tab bar or anywhere else.
Preview
Installation
Install the package once, then import the parts you use into a standalone component.
Install
npm install ngx-vitreo @angular/cdk @floating-ui/domImport
import { GlassSearch, GlassTabBar } from 'ngx-vitreo';
@Component({
imports: [GlassSearch, GlassTabBar],
// ...
})Usage
Usage
<!-- In a header: it opens over the links. -->
<header glassHeader class="docs-search-header" navigationLabel="Example navigation" position="static">
<a glassHeaderBrand href="#music" (click)="$event.preventDefault()">Vitreo Music</a>
<ng-template glassHeaderLinks>
<a href="#listen" (click)="$event.preventDefault()">Listen</a>
<a href="#browse" (click)="$event.preventDefault()">Browse</a>
</ng-template>
<glass-search glassHeaderActions placeholder="Search the catalogue" />
</header>
<!-- Anywhere else: it opens over what lies before it in its container. -->
<div class="docs-search-toolbar">
<h3 class="docs-search-title">Library</h3>
<glass-search placeholder="Search your library" />
</div>
<!-- In a tab bar: the tabs fold away for it. -->
<glass-tabs class="docs-search-demo" [(value)]="tab">
<div class="docs-search-screen">
@if (searching()) {
<glass-panel class="docs-search-results" variant="card">
<p class="docs-search-heading">{{ query() ? 'Top results' : 'Recently played' }}</p>
@for (song of results(); track song) {
<p class="docs-search-row">{{ song }}</p>
} @empty {
<p class="docs-search-row docs-search-empty">No results for “{{ query() }}”</p>
}
</glass-panel>
}
<div [hidden]="searching()">
<glass-tabs-content value="home">Picks for you, fresh every morning.</glass-tabs-content>
<glass-tabs-content value="browse">New releases and editors' playlists.</glass-tabs-content>
<glass-tabs-content value="radio">Live stations from around the world.</glass-tabs-content>
<glass-tabs-content value="library">Everything you've saved.</glass-tabs-content>
</div>
</div>
<glass-tab-bar>
<glass-tabs-list aria-label="Music">
<button glassTabsTrigger value="home">
<svg aria-hidden="true" viewBox="0 0 24 24"><path d="M4.5 10.2 12 4l7.5 6.2V19a1 1 0 0 1-1 1H15v-5.5H9V20H5.5a1 1 0 0 1-1-1z" /></svg>
Home
</button>
<button glassTabsTrigger value="browse">
<svg aria-hidden="true" viewBox="0 0 24 24"><rect x="4" y="4" width="6.6" height="6.6" rx="1.8" /><rect x="13.4" y="4" width="6.6" height="6.6" rx="1.8" /><rect x="4" y="13.4" width="6.6" height="6.6" rx="1.8" /><rect x="13.4" y="13.4" width="6.6" height="6.6" rx="1.8" /></svg>
Browse
</button>
<button glassTabsTrigger value="radio">
<svg aria-hidden="true" viewBox="0 0 24 24"><circle cx="12" cy="12" r="1.9" /><path d="M8.3 15.7a5.2 5.2 0 0 1 0-7.4m7.4 0a5.2 5.2 0 0 1 0 7.4M5.6 18.4a9 9 0 0 1 0-12.8m12.8 0a9 9 0 0 1 0 12.8" /></svg>
Radio
</button>
<button glassTabsTrigger value="library">
<svg aria-hidden="true" viewBox="0 0 24 24"><path d="M5.5 4.5v15M10 4.5v15M14.2 5.2l4.6 14" /></svg>
Library
</button>
</glass-tabs-list>
<glass-search placeholder="Artists, songs and more" [(open)]="searching" [(value)]="query" />
</glass-tab-bar>
</glass-tabs>API reference
GlassSearch
glass-search
| Input | Type | Default | Description |
|---|---|---|---|
[(open)] | boolean | false | Whether the field is out. The button opens and closes it. |
[(value)] | string | '' | The search text. Also works with ngModel and formControl. |
placeholder | string | 'Search' | Shown in the empty field, and the field's accessible name unless fieldLabel is set. |
fieldLabel | string | None | The field's accessible name, when the placeholder alone doesn't say enough. |
buttonLabel / closeLabel / clearLabel | string | 'Search' / 'Close search' / 'Clear search' | Accessible names of the button, closed and open, and of the clear button. |
clearOnClose | boolean | true | Clears the text when the search closes, as cancelling a search does on iOS. |
disabled | boolean | false | Stops the search opening. |
expand | 'cover' | 'inline' | 'cover' | Cover spreads the open field back over what lies before the button in its area, which steps aside, so the layout never moves. Inline widens the search in place, for a container that makes room. A glass-header or glass-tab-bar picks for you. |
area | HTMLElement | the parent | The element an open field covers. In a glass-header it is the bar after the brand. |
buttonVariant | 'primary' | 'prominent' | 'ghost' | 'soft' | 'primary' | The button's look. In a glass-header it is ghost, like the header's other actions. |
(submitted) | string | None | Emits the text when Enter is pressed in the field. Escape closes the search. |
GlassTabBar
glass-tab-bar
| Input | Type | Default | Description |
|---|---|---|---|
content | glass-tabs-list + glass-search | None | Folds the tabs into a circle showing the selected tab's icon while search is open; a press on it closes search. Give each trigger an icon and a label. |