Command palette
A commercial license is required to use Tailwind Plus Elements.
The <el-command-palette>
component provides a fast, keyboard-friendly way for users to search and select from a predefined list of options. It's typically displayed inside a dialog — often triggered with a Cmd+K
shortcut — making it ideal for building power-user features like global searches.
Component API
<el-command-palette>
The main command component that manages filtering and coordinates with its child components
Attributes | |
name | The form field name for the command when used in forms. |
value | The selected value of the command. Can be read and set programmatically. |
Events | |
change | Dispatched when the active item changes. Detail contains relatedTarget property with the active item or null . |
Methods | |
setFilterCallback(cb) | Allows you to customize the filtering behavior of the command. The callback receives an object with query , node and content properties, and should return a boolean . |
reset() | Resets the command to its initial state. |
<el-command-list>
Contains all the command items and groups. All focusable children will be considered options.
<el-defaults>
Optional container for suggestion items that are shown when the input is empty.
<el-command-group>
Groups related command items together.
<el-no-results>
Optional element shown when no items match the current query.
<el-command-preview>
Optional preview content shown when a specific item is active.
Attributes | |
for | The id of the item this preview content is associated with. |
Examples
Basic example
Use the <el-command-palette>
, <el-command-list>
,<el-no-results>
components, along with a native <button>
and <input>
, to build a command palette:
<button command="show-modal" commandfor="my-command-palette" type="button">
Open command palette
</button>
<el-dialog>
<dialog id="my-command-palette">
<el-command-palette>
<input autofocus placeholder="Search users…" />
<el-command-list>
<a href="/users/1" hidden>Michael Foster</a>
<a href="/users/2" hidden>Dries Vincent</a>
<a href="/users/3" hidden>Lindsay Walton</a>
<a href="/users/4" hidden>Courtney Henry</a>
<a href="/users/5" hidden>Tom Cook</a>
</el-command-list>
<el-no-results hidden>No users found.</el-no-results>
</el-command-palette>
</dialog>
</el-dialog>
Opening and closing
Typically the <el-command-palette>
element is conditionally shown by rendering it within a dialog. See the Dialog documentation for information on how to open and close dialogs.
Using with buttons
When using a <button>
as a command item, the onclick
event will be invoked when it's selected:
<el-command-list>
<button onclick="createProject()" type="button" hidden>Create project</button>
<button onclick="createTask()" type="button" hidden>Create task</button>
<button onclick="createUser()" type="button" hidden>Create user</button>
</el-command-list>
Using with links
When using an <a>
as a command item, the href
attribute will be used to navigate to the link when it's selected:
<el-command-list>
<a href="/users/1" hidden>Michael Foster</a>
<a href="/users/2" hidden>Dries Vincent</a>
<a href="/users/3" hidden>Lindsay Walton</a>
</el-command-list>
Showing option previews
Use the <el-command-preview>
component to show a preview of the active option by connecting it using the for
and id
attributes:
<el-command-palette>
<input autofocus placeholder="Search users…" />
<el-command-list>
<a id="user-1" href="/users/1" hidden>Michael Foster</a>
<a id="user-2" href="/users/2" hidden>Dries Vincent</a>
<a id="user-3" href="/users/3" hidden>Lindsay Walton</a>
<a id="user-4" href="/users/4" hidden>Courtney Henry</a>
<a id="user-5" href="/users/5" hidden>Tom Cook</a>
</el-command-list>
<el-command-preview for="user-1" hidden>
<dl>
<dt>Name</dt>
<dd>Michael Foster</dd>
<dt>Email</dt>
<dd><a href="mailto:michael.foster@example.com">michael.foster@example.com</a></dd>
<dt>Role</dt>
<dd>Product Designer</dd>
</dl>
</el-command-preview>
<el-command-preview for="user-2" hidden>
<dl>
<dt>Name</dt>
<dd>Dries Vincent</dd>
<dt>Email</dt>
<dd><a href="mailto:dries.vincent@example.com">dries.vincent@example.com</a></dd>
<dt>Role</dt>
<dd>Software Engineer</dd>
</dl>
</el-command-preview>
<!-- ... -->
<el-no-results hidden>No users found.</el-no-results>
</el-command-palette>
Showing default commands
Use the <el-defaults>
component to show a list of default commands when the search input is empty:
<el-command-list>
<el-defaults>
<button onclick="createProject()" type="button">Create project</button>
<button onclick="createTask()" type="button">Create task</button>
<button onclick="createUser()" type="button">Create user</button>
</el-defaults>
<!-- ... -->
</el-command-list>
Handling no results
Use the <el-no-results>
component to show a message when no results are found:
<el-command-palette>
<el-command-list>
<!-- ... -->
</el-command-list>
<el-no-results hidden>No results found.</el-no-results>
</el-command-palette>
Grouping related commands
Use the <el-command-group>
component to group related commands together:
<el-command-list>
<el-command-group aria-labelledby="clients-group-label" hidden>
<div id="clients-group-label">Clients</div>
<a href="/clients/1">Workflow Inc.</a>
<a href="/clients/2">Conglomerate Inc.</a>
<a href="/clients/3">Big Ltd.</a>
</el-command-group>
<el-command-group aria-labelledby="projects-group-label" hidden>
<div id="projects-group-label">Projects</div>
<a href="/projects/1">Website redesign</a>
<a href="/projects/2">New iOS app</a>
<a href="/projects/3">New Android app</a>
</el-command-group>
</el-command-list>
Customizing the filter logic
Use the setFilterCallback()
method on the <el-command-palette>
component to customize the filtering behavior:
<script type="module">
function onReady() {
let command = document.getElementById('my-command-palette')
command.setFilterCallback(({ query, node, content }) => {
if (query.startsWith('>')) {
return node.dataset.type === 'client' && content.toLowerCase().includes(query.slice(1).toLowerCase())
}
if (query.startsWith('#')) {
return node.dataset.type === 'project' && content.toLowerCase().includes(query.slice(1).toLowerCase())
}
return content.toLowerCase().includes(query.toLowerCase())
})
}
if (customElements.get('el-command')) {
onReady()
} else {
window.addEventListener('elements:ready', onReady)
}
</script>
<el-command-palette id="my-command-palette">
<input autofocus placeholder="Search users…" />
<el-command-list>
<el-command-group aria-labelledby="clients-group-label" hidden>
<div id="clients-group-label">Clients</div>
<a href="/clients/1" data-type="client">Workflow Inc.</a>
<a href="/clients/2" data-type="client">Conglomerate Inc.</a>
<a href="/clients/3" data-type="client">Big Ltd.</a>
</el-command-group>
<el-command-group aria-labelledby="projects-group-label" hidden>
<div id="projects-group-label">Projects</div>
<a href="/projects/1" data-type="project">Website redesign</a>
<a href="/projects/2" data-type="project">New iOS app</a>
<a href="/projects/3" data-type="project">New Android app</a>
</el-command-group>
</el-command-list>
</el-command-palette>
Additionally, you can also perform the filtering yourself by only rendering the options you want — for example maybe you're filtering the results server-side. In this case, you can completely disable the built-in filtering by updating the setFilterCallback()
method to always return true
:
command.setFilterCallback(() => true)