@banegasn/m3-search-bar
v1.1.3
Published
Material Design 3 search bar web component
Maintainers
Readme
@banegasn/m3-search-bar

Material Design 3 Search Bar web component — framework-agnostic, built with Lit.
An accessible M3 Search Bar web component following the Material Design 3 search specifications. Supports leading and trailing content projection for icons, buttons, and avatars. Works in Angular, React, Vue, Svelte, or plain HTML — no build step required.
Features
- Leading and trailing slot support
- Keyboard events (input, submit, clear)
- Form integration
- Accessible with ARIA attributes
- Framework-agnostic custom element
Installation
npm install @banegasn/m3-search-bar
# or
pnpm add @banegasn/m3-search-bar
# or
yarn add @banegasn/m3-search-barCDN Usage (no build step)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>M3 Search Bar Demo</title>
<script type="module" src="https://cdn.jsdelivr.net/npm/@banegasn/m3-search-bar/+esm"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
<style>
body { font-family: Roboto, sans-serif; padding: 32px; background: #fef7ff; max-width: 480px; }
#results { margin-top: 16px; font-size: 14px; color: #49454f; }
</style>
</head>
<body>
<m3-search-bar id="search" placeholder="Search...">
<span slot="leading" class="material-symbols-outlined">search</span>
</m3-search-bar>
<p id="results">Start typing to search...</p>
<script>
const search = document.getElementById('search');
search.addEventListener('search-input', (e) => {
document.getElementById('results').textContent = 'Searching for: ' + e.detail.value;
});
search.addEventListener('search-clear', () => {
document.getElementById('results').textContent = 'Start typing to search...';
});
</script>
</body>
</html>Material Icons Setup
To use Material Icons in your project, include the Material Symbols font in your HTML:
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,[email protected],100..700,0..1,-50..200" />Or via npm:
npm install material-symbolsUsage
Basic Example
<m3-search-bar placeholder="Search..."></m3-search-bar>With Leading Icon
<m3-search-bar placeholder="Search...">
<span slot="leading" class="material-symbols-outlined">search</span>
</m3-search-bar>With Leading and Trailing Content
<m3-search-bar placeholder="Search...">
<!-- Leading: Menu button -->
<m3-button icon-only slot="leading" variant="text" size="small" aria-label="Menu">
<span slot="icon" class="material-symbols-outlined">menu</span>
</m3-button>
<!-- Trailing: Clear button (shown conditionally) -->
<m3-button icon-only slot="trailing" variant="text" aria-label="Clear" @click="${() => searchBar.clear()}">
<span slot="icon" class="material-symbols-outlined">close</span>
</m3-button>
</m3-search-bar>Or with Material Icons directly:
<m3-search-bar placeholder="Search...">
<span slot="leading" class="material-symbols-outlined">search</span>
<span slot="trailing" class="material-symbols-outlined">close</span>
</m3-search-bar>With Avatar in Trailing Slot
<m3-search-bar placeholder="Search users...">
<span slot="leading" class="material-symbols-outlined">search</span>
<img slot="trailing" src="avatar.jpg" alt="User" style="width: 24px; height: 24px; border-radius: 50%;" />
</m3-search-bar>With Multiple Trailing Actions
<m3-search-bar placeholder="Search...">
<span slot="leading" class="material-symbols-outlined">search</span>
<m3-button icon-only slot="trailing" variant="text" aria-label="Filter">
<span slot="icon" class="material-symbols-outlined">tune</span>
</m3-button>
<m3-button icon-only slot="trailing" variant="text" aria-label="More options">
<span slot="icon" class="material-symbols-outlined">more_vert</span>
</m3-button>
</m3-search-bar>With Event Listeners
const searchBar = document.querySelector('m3-search-bar');
searchBar.addEventListener('search-input', (e) => {
console.log('Search value:', e.detail.value);
});
searchBar.addEventListener('search-submit', (e) => {
console.log('Search submitted:', e.detail.value);
});
searchBar.addEventListener('search-clear', () => {
console.log('Search cleared');
});Properties
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| placeholder | string | 'Search' | Placeholder text for the input |
| value | string | '' | Current value of the input |
| disabled | boolean | false | Disables the search bar |
| name | string \| null | null | Name attribute for form submission |
| form | string \| null | null | Form attribute to associate with a form |
| aria-label | string \| null | null | ARIA label for accessibility |
| aria-labelledby | string \| null | null | ARIA labelled by for accessibility |
| maxLength | number \| null | null | Maximum length of input |
| minLength | number \| null | null | Minimum length of input |
| pattern | string \| null | null | Pattern for input validation |
| required | boolean | false | Whether the input is required |
| autocomplete | string \| null | null | Autocomplete attribute |
Slots
| Slot | Description |
|------|-------------|
| leading | Content to display before the input (e.g., search icon, menu button) |
| trailing | Content to display after the input (e.g., clear button, avatar) |
Events
| Event | Detail | Description |
|-------|--------|-------------|
| search-input | { value: string, name: string \| null } | Fired when the input value changes |
| search-submit | { value: string, name: string \| null } | Fired when Enter is pressed |
| search-clear | { name: string \| null } | Fired when the search is cleared (Escape key) |
Methods
| Method | Description |
|-------|-------------|
| focus() | Focuses the search input |
| blur() | Removes focus from the search input |
| clear() | Clears the search input |
| getValue() | Returns the current value |
| setValue(value: string) | Sets the value programmatically |
CSS Custom Properties
| Property | Default | Description |
|----------|---------|-------------|
| --md-search-bar-container-height | 64px | Height of the container |
| --md-search-bar-container-padding | 16px | Padding of the container |
| --md-search-bar-height | 56px | Height of the search bar |
| --md-search-bar-shape | 28px | Border radius of the search bar |
| --md-search-bar-padding-horizontal | 16px | Horizontal padding |
| --md-search-bar-padding-vertical | 12px | Vertical padding |
| --md-search-bar-input-font-size | 16px | Font size of input |
| --md-search-bar-input-line-height | 24px | Line height of input |
| --md-search-bar-icon-size | 24px | Size of icons in slots |
Accessibility
The component follows Material Design 3 accessibility guidelines:
- Proper ARIA attributes
- Keyboard navigation support
- Focus management
- Screen reader compatibility
Resources
License
MIT
