Command dialog
Compose a searchable command surface with Dialog, TextField, and controlled state.
Keep the dialog's open state controlled and let its action collection own dismissal. The search field filters ordinary application data; Dialog supplies modal semantics, focus management, and actions.
import { useMemo, useState } from "react"
import { Button, Dialog, TextField } from "@liquidify/react"
import "@liquidify/react/styles.css"
const commands = ["Open settings", "Create project", "Invite teammate"]
export function CommandDialog() {
const [open, setOpen] = useState(false)
const [query, setQuery] = useState("")
const matches = useMemo(
() => commands.filter((command) => command.toLowerCase().includes(query.toLowerCase())),
[query],
)
return (
<>
<Button onPress={() => setOpen(true)}>Open commands</Button>
<Dialog
title="Commands"
description="Search for an action to run."
open={open}
onOpenChange={setOpen}
actions={[{ id: "close", label: "Close", role: "cancel" }]}
>
<TextField
aria-label="Search commands"
type="search"
placeholder="Type a command"
value={query}
onChange={setQuery}
clearable
/>
<ul aria-live="polite">
{matches.map((command) => <li key={command}>{command}</li>)}
</ul>
</Dialog>
</>
)
}For a command palette that immediately performs each result, render result buttons in the body and close the controlled dialog after the chosen handler completes. Preserve normal list and button semantics rather than making the entire modal a custom keyboard widget.