Components
Command palette
A searchable list of commands. Typing narrows it, the arrows and the pointer move the lit command and Enter runs it, all in the browser: nothing is sent until a command runs.
Drawn and behaving as Flux UI's command palette does, measured against its live docs.
Command palette
A Ui.CommandInput over the Ui.CommandItems. A pressed command empties the box and the palette stays where it is.
namespace Rask.Site.Features.UiDocs.Examples;
public sealed partial class CommandExample : Component
{
private string _last = "nothing yet";
protected override Component? Render() =>
Div.Class("flex flex-col items-center gap-4")[
Ui.Command[
Ui.CommandInput.Placeholder("Search..."),
Ui.CommandItems[
Ui.CommandItem.Icon(Ui.IconName.UserPlus).Kbd("⌘A").OnClick(() => { _last = "assigned"; })["Assign to…"],
Ui.CommandItem.Icon(Ui.IconName.DocumentPlus).OnClick(() => { _last = "created a file"; })["Create new file"],
Ui.CommandItem.Icon(Ui.IconName.FolderPlus).Kbd("⌘⇧N").OnClick(() => { _last = "created a project"; })["Create new project"],
Ui.CommandItem.Icon(Ui.IconName.BookOpen).OnClick(() => { _last = "opened the documentation"; })["Documentation"],
Ui.CommandItem.Icon(Ui.IconName.Newspaper).OnClick(() => { _last = "opened the changelog"; })["Changelog"],
Ui.CommandItem.Icon(Ui.IconName.Cog6Tooth).Kbd("⌘,").OnClick(() => { _last = "opened the settings"; })["Settings"]
]
],
Ui.Text[$"Last command: {_last}."]
];
}Last command: nothing yet.
As a modal
A bare Ui.Modal around it, opened by its trigger or from anywhere on the page with ⌘K (Ctrl K off a Mac). Closable puts the close button on the box.
namespace Rask.Site.Features.UiDocs.Examples;
public sealed partial class CommandModalExample : Component
{
private string _last = "nothing yet";
protected override Component? Render() =>
Div.Class("flex flex-col items-center gap-4")[
// ⌘K, or Ctrl K off a Mac, presses the trigger from anywhere on the page.
Ui.ModalTrigger.Name("search").Shortcut("mod+k")[
Ui.Input.Of<string>().As(Ui.InputAs.Button).Placeholder("Search...").Icon(Ui.IconName.MagnifyingGlass).Kbd("⌘K")
],
Ui.Modal.Name("search").Variant(Ui.ModalVariant.Bare)
.Class("my-[12vh] max-h-screen w-full max-w-[30rem] overflow-y-hidden")[
Ui.Command.Class("inline-flex max-h-[76vh] flex-col border-none shadow-lg")[
Ui.CommandInput.Placeholder("Search...").Closable(),
Ui.CommandItems[
Ui.CommandItem.Icon(Ui.IconName.UserPlus).Kbd("⌘A").OnClick(() => { _last = "assigned"; })["Assign to…"],
Ui.CommandItem.Icon(Ui.IconName.DocumentPlus).OnClick(() => { _last = "created a file"; })["Create new file"],
Ui.CommandItem.Icon(Ui.IconName.FolderPlus).Kbd("⌘⇧N").OnClick(() => { _last = "created a project"; })["Create new project"],
Ui.CommandItem.Icon(Ui.IconName.BookOpen).OnClick(() => { _last = "opened the documentation"; })["Documentation"],
Ui.CommandItem.Icon(Ui.IconName.Newspaper).OnClick(() => { _last = "opened the changelog"; })["Changelog"],
Ui.CommandItem.Icon(Ui.IconName.Cog6Tooth).Kbd("⌘,").OnClick(() => { _last = "opened the settings"; })["Settings"]
]
]
],
Ui.Text[$"Last command: {_last}."]
];
}Last command: nothing yet.
Behaviour
In the browser
OnClick is Flux's wire:click: what pressing the command does. Everything else is the browser's, as Flux's custom element keeps it (data-rask-command), and none of it sends the server anything.
When | What happens |
|---|---|
| Focus enters the box | The first command is lit. |
| Typing | Hides the commands that do not contain it, in any case and with any accents, lights the first one left, and shows "No results found" when none is. |
ArrowUp / ArrowDown | Move the lit command, and stop at the ends. |
| The pointer | Lights the command under it. |
Enter | Presses the lit command. |
| A command is pressed | The box empties and nothing else: the palette stays where it is. |
The box and the rows
Ui.CommandInput takes Flux's Icon (the magnifying glass unless set), Placeholder, Clearable and Closable. Flux draws the clear button whether or not it is asked to (measured), so it is there unless Clearable(false), or the box is Closable and not also clearable.
Ui.CommandItem takes Icon, IconVariant (outline unless set) and Kbd, a hint: the page binds the key.
As a modal
Flux's "As a modal" example is a bare Ui.Modal opened by a trigger, and from anywhere on the page by its Shortcut; Closable puts the box's close button on it.
data-rask-shortcut="mod+k" clicks its element when the combination is pressed: mod is ⌘ on a Mac and Ctrl elsewhere, beside ctrl, alt, shift and meta. A shortcut with no modifier does not fire while the reader is typing.
As on Flux's page, the modal opens with focus on nothing inside it (Tab takes it into the box), Escape closes it, and what was typed is still there when it opens again. Flux caps the palette at 480px only while it is handed no class; the modal example's classes take the cap away.
Reference
Ui.Command
The palette: a box to type in over a list of commands, narrowed in the browser.
No steps of its own: what goes inside it is its content.
Ui.CommandInput
The box that narrows the list.
Step | Takes | What it does |
|---|---|---|
.Placeholder(…) | string | What the box says while it is empty. |
.Icon(…) | Ui.IconName — one of 317 names | The icon at the start of the box. A magnifying glass when unset. |
.Clearable() | bool | A button that empties the box while it holds something. On unless false. |
.Closable() | bool | A button that closes the modal the palette is in. |
Ui.CommandItems
The list of commands. It says "No results found" when typing hides them all.
No steps of its own: what goes inside it is its content.
Ui.CommandItem
One command. Its children are its words, which the box matches.
Step | Takes | What it does |
|---|---|---|
.Icon(…) | Ui.IconName — one of 317 names | The icon at the start of the row. |
.IconVariant(…) | Ui.IconVariantOutline Solid Mini Micro Each is a step of its own too, unless an HTML tag has its name. | Which drawing of the icon. Outline when unset. |
.Kbd(…) | string | A shortcut shown at the end of the row: "⌘K". A hint: the page binds the key. |
.OnClick(…) | a handler, with no argument | What pressing the command, or Enter on it, does. |