The m3e-search-bar and m3e-search-view components provide a Material 3 expressive
search experience. The search bar offers a prominent entry point for text input, while the search view presents
suggestions, history, and results in contained, docked, or full screen configurations.
import "@m3e/web/search";
This section outlines usage examples and configuration guidance for the components in this package.
Use the m3e-search-bar as the entry point for search. It provides the interactive affordance that
activates search, but does not display results. To present suggestions, history, or results, use
m3e-search-view, which provides a complete search experience.
The m3e-search-bar exposes the following named slots:
leading — Content positioned at the start of the bar, such as an icon or navigation affordance.
input — The input element used to capture search text.trailing — Content aligned to the end of the bar, such as an avatar or overflow menu.
Use the clearable attribute to control whether the bar displays a clear button. When activated,
this button clears the input and emits a clear event.
The following example illustrates typical usage of a m3e-search-bar with a leading icon and the
ability to clear the current search text.
<m3e-search-bar clearable> <m3e-icon name="search" slot="leading"></m3e-icon> <input slot="input" placeholder="Search..." /> </m3e-search-bar>
Use the m3e-search-view to display search suggestions and results. Unlike
m3e-search-bar, which only provides the entry point, the search view presents the results of a
search.
The m3e-search-view exposes the following named slots:
closed-leading — When the view is closed, renders content positioned before the input.closed-trailing — When the view is closed, renders content positioned after the input.open-leading — When the view is open, renders content positioned before the input.open-trailing — When the view is open, renders content after the input.input — Renders the input element used to capture search text.
Use the mode attribute to control how results are presented. Supported values include
fullscreen, docked (default), and auto, which selects the appropriate
mode based on the current viewport breakpoint.
The following example illustrates the docked mode. In this mode, the search view appears as a
surface anchored to the search bar, allowing users to explore results while maintaining context within the
surrounding layout.
<m3e-search-view mode="docked">
<input slot="input" placeholder="Search..." />
<m3e-list>
<m3e-list-item>Result One</m3e-list-item>
<m3e-list-item>Result Two</m3e-list-item>
<m3e-list-item>Result Three</m3e-list-item>
</m3e-list>
</m3e-search-view>
The next example illustrates the fullscreen mode. In this mode, the search view occupies the entire
viewport, creating an immersive, focused search that temporarily replaces the surrounding UI.
<m3e-search-view mode="fullscreen"> <input slot="input" placeholder="Search..." /> <!-- Results omitted for brevity --> </m3e-search-view>
Use the contained attribute to a persistent, filled search container when open.
The following example illustrates use of contained in the docked mode.
<m3e-search-view mode="docked" contained> <input slot="input" placeholder="Search..." /> <!-- Results omitted for brevity --> </m3e-search-view>
The next example illustrates use of contained in the fullscreen mode.
<m3e-search-view mode="fullscreen" contained> <input slot="input" placeholder="Search..." /> <!-- Results omitted for brevity --> </m3e-search-view>
The m3e-search-view emits a query event that can be used to load results. The event
fires under the following conditions:
input receives focus. This can be used to load initial suggestions.input value changes. This can be used to fetch results that match the current term using the
event's detail.term property.
In addition, a clear event is emitted when the user clicks the clear button. This action also
triggers a query event first, followed by clear, reflecting the component's input →
query → clear event sequence.
While its typical to show a search icon, you can use the hide-search-icon attribute to hide it when
a search view is closed.
<m3e-search-view mode="docked" hide-search-icon> <input slot="input" placeholder="Search..." /> <!-- Results omitted for brevity --> </m3e-search-view>
The search bar automatically normalizes its slotted input to ensure correct search semantics across
browsers and assistive technologies. It applies role="searchbox", inputmode="search",
and type="text" when not already specified. Additionally, aria-haspopup="dialog" is
applied to inform assistive technologies that activating the input will open a dialog, allowing screen readers
to anticipate the resulting change in context.
When open, the overlay region of the search view is given ARIA role="dialog" indicating that it is
a dedicated search surface. The dialog is labeled by its header via aria-labelledby, allowing
assistive technologies to announce the search context clearly. aria-modal="true" is used to
indicate only the content in the dialog can be interacted with.
The search view does not automatically announce dynamic updates. Instead, you are responsible for sending short,
textual updates to a dedicatedaria-live="polite" element when search results change. This ensures
assistive technologies receive meaningful feedback without re-announcing the full list of results.
The @m3e/web package uses
JavaScript Modules. To use it directly in a browser without a bundler, use a module script similar to the following.
<script type="module" src="/node_modules/@m3e/web/dist/search.js"></script>
In addition, you must use an import map to include dependencies.
<script type="importmap">
{
"imports": {
"tslib": "https://cdn.jsdelivr.net/npm/tslib@2.8.1/+esm",
"lit": "https://cdn.jsdelivr.net/npm/lit@3.3.0/+esm",
"lit/": "https://cdn.jsdelivr.net/npm/lit@3.3.0/",
"lit-html": "https://cdn.jsdelivr.net/npm/lit-html@3.3.0/+esm",
"lit-html/directive.js": "https://cdn.jsdelivr.net/npm/lit-html@3.3.0/directive.js",
"lit-html/directives/if-defined.js": "https://cdn.jsdelivr.net/npm/lit-html@3.3.0/directives/if-defined.js",
"@lit/reactive-element": "https://cdn.jsdelivr.net/npm/@lit/reactive-element@2.0.4/+esm",
"@lit/reactive-element/": "https://cdn.jsdelivr.net/npm/@lit/reactive-element@2.0.4/",
"@m3e/web/core": "/node_modules/@m3e/web/dist/core.js",
"@m3e/web/core/a11y": "/node_modules/@m3e/web/dist/core-a11y.js",
"@m3e/web/core/anchoring": "/node_modules/@m3e/web/dist/core-anchoring.js",
"@m3e/web/core/bidi": "/node_modules/@m3e/web/dist/core-bidi.js"
"@m3e/web/core/layout": "/node_modules/@m3e/web/dist/core-layout.js"
"@m3e/web/icon-button": "/node_modules/@m3e/web/dist/icon-button.js"
}
}
</script>
For production builds, use the minified files to ensure optimal load performance.
The @m3e/web package includes a
Custom Elements Manifest (custom-elements.json), which documents the properties,
attributes, slots, events and CSS custom properties of each component.
You can explore the API below, or integrate the manifest into your own tooling.