2025-10-30 10:03:34 +07:00
|
|
|
---
|
|
|
|
|
layout: layouts/page.njk
|
|
|
|
|
title: Command
|
2025-10-30 19:09:21 +08:00
|
|
|
description: Fast, composable command menu for quick navigation and actions.
|
2025-10-30 10:03:34 +07:00
|
|
|
toc:
|
|
|
|
|
- label: Usage
|
|
|
|
|
id: usage
|
|
|
|
|
- label: Examples
|
|
|
|
|
id: examples
|
|
|
|
|
children:
|
2025-10-30 19:09:21 +08:00
|
|
|
- label: Dialog
|
|
|
|
|
id: example-dialog
|
2025-10-30 10:03:34 +07:00
|
|
|
---
|
|
|
|
|
|
|
|
|
|
{% from "macros/code_preview.njk" import code_preview %}
|
|
|
|
|
{% from "macros/code_block.njk" import code_block %}
|
2025-10-30 19:09:21 +08:00
|
|
|
{% from "command.njk" import command, command_dialog %}
|
2025-10-30 10:03:34 +07:00
|
|
|
|
2025-10-30 19:09:21 +08:00
|
|
|
{% macro command_items(suggestions_id="suggestions", settings_id="settings") %}
|
|
|
|
|
<div role="group" aria-labelledby="{{ suggestions_id }}">
|
|
|
|
|
<span role="heading" id="{{ suggestions_id }}">Suggestions</span>
|
|
|
|
|
<div role="option" data-value="calendar">
|
|
|
|
|
{% lucide "calendar" %}
|
|
|
|
|
<span>Calendar</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div role="option" data-value="search-emoji">
|
|
|
|
|
{% lucide "smile" %}
|
|
|
|
|
<span>Search Emoji</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div role="option" data-value="calculator" aria-disabled="true">
|
|
|
|
|
{% lucide "calculator" %}
|
|
|
|
|
<span>Calculator</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<hr role="separator" />
|
|
|
|
|
<div role="group" aria-labelledby="{{ settings_id }}">
|
|
|
|
|
<span role="heading" id="{{ settings_id }}">Settings</span>
|
|
|
|
|
<div role="option" data-value="profile">
|
|
|
|
|
{% lucide "user" %}
|
|
|
|
|
<span>Profile</span>
|
|
|
|
|
<kbd class="ml-auto text-muted-foreground bg-transparent tracking-widest">⌘P</kbd>
|
|
|
|
|
</div>
|
|
|
|
|
<div role="option" data-value="billing">
|
|
|
|
|
{% lucide "credit-card" %}
|
|
|
|
|
<span>Billing</span>
|
|
|
|
|
<kbd class="ml-auto text-muted-foreground bg-transparent tracking-widest">⌘B</kbd>
|
|
|
|
|
</div>
|
|
|
|
|
<div role="option" data-value="settings">
|
|
|
|
|
{% lucide "settings" %}
|
|
|
|
|
<span>Settings</span>
|
|
|
|
|
<kbd class="ml-auto text-muted-foreground bg-transparent tracking-widest">⌘S</kbd>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{% endmacro %}
|
|
|
|
|
|
|
|
|
|
{% set code_standalone %}
|
2025-10-30 10:03:34 +07:00
|
|
|
{% call command(
|
2025-10-30 19:09:21 +08:00
|
|
|
id="demo-command-standalone",
|
|
|
|
|
main_attrs={ "class": "rounded-lg border shadow-md" }
|
2025-10-30 10:03:34 +07:00
|
|
|
) %}
|
2025-10-30 19:09:21 +08:00
|
|
|
{{ command_items("suggestions", "settings") }}
|
2025-10-30 10:03:34 +07:00
|
|
|
{% endcall %}
|
|
|
|
|
{% endset %}
|
|
|
|
|
|
2025-10-30 19:09:21 +08:00
|
|
|
{{ code_preview("command-standalone", code_standalone | prettyHtml, class=" w-full max-w-[450px]") }}
|
2025-10-30 10:03:34 +07:00
|
|
|
|
|
|
|
|
<h2 id="usage"><a href="#usage">Usage</a></h2>
|
|
|
|
|
|
2025-10-30 19:09:21 +08:00
|
|
|
{{ code_block(code_standalone | prettyHtml, "html") }}
|
2025-10-30 10:03:34 +07:00
|
|
|
|
|
|
|
|
<h2 id="examples"><a href="#examples">Examples</a></h2>
|
|
|
|
|
|
2025-10-30 19:09:21 +08:00
|
|
|
<h3 id="example-dialog"><a href="#example-dialog">Dialog</a></h3>
|
2025-10-30 10:03:34 +07:00
|
|
|
|
|
|
|
|
<section class="prose">
|
2025-10-30 19:09:21 +08:00
|
|
|
<p>Press <kbd>⌘</kbd><kbd>J</kbd></p>
|
2025-10-30 10:03:34 +07:00
|
|
|
</section>
|
|
|
|
|
|
2025-10-30 19:09:21 +08:00
|
|
|
{% set code_dialog %}
|
|
|
|
|
<button
|
|
|
|
|
type="button"
|
|
|
|
|
class="btn-outline"
|
|
|
|
|
onclick="document.getElementById('demo-command-dialog').showModal()"
|
|
|
|
|
>
|
|
|
|
|
Open command menu
|
|
|
|
|
<kbd>⌘ J</kbd>
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
|
|
{% call command_dialog(id="demo-command-dialog") %}
|
|
|
|
|
{{ command_items("cmd-suggestions", "cmd-settings") }}
|
|
|
|
|
{% endcall %}
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
document.addEventListener('keydown', (e) => {
|
|
|
|
|
if ((e.metaKey || e.ctrlKey) && e.key === 'j') {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
const dialog = document.getElementById('demo-command-dialog');
|
|
|
|
|
if (dialog.open) {
|
|
|
|
|
dialog.close();
|
|
|
|
|
} else {
|
|
|
|
|
dialog.showModal();
|
|
|
|
|
dialog.querySelector('header input')?.focus();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const cmdDialog = document.getElementById('demo-command-dialog');
|
|
|
|
|
cmdDialog?.addEventListener('command:select', (e) => {
|
|
|
|
|
console.log('Selected command:', e.detail.value);
|
|
|
|
|
cmdDialog.close();
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
{% endset %}
|
|
|
|
|
|
|
|
|
|
{{ code_preview("command-dialog", code_dialog | prettyHtml) }}
|
|
|
|
|
|
|
|
|
|
<section class="prose">
|
|
|
|
|
<p>To show the command menu in a dialog, use the <code>command_dialog</code> macro.</p>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
{{ code_block(code_dialog | prettyHtml, "html") }}
|