Skip to component content
Navigation087 / 155

Toolbar

Keep actions reachable as space narrows, with optional arrow-key navigation.

Example

Use the arrow keys to move between toolbar actions.

Source
Toolbar.tsxtsx
import { useState } from "react";
import { Button, HStack, Picker, Text, Toggle, Toolbar, VStack } from "@/ohmygui";

const actions = [
  { label: "Save", variant: "primary", message: "Field guide saved." },
  { label: "Discard", variant: "outline", message: "Draft changes discarded." },
  { label: "Copy link", variant: "secondary", message: "Share link copied." },
] as const;

export default function Example() {
  const [message, setMessage] = useState("Use the arrow keys to move between toolbar actions.");
  const [orientation, setOrientation] = useState<"horizontal" | "vertical">("horizontal");
  const [density, setDensity] = useState<"comfortable" | "compact">("comfortable");
  const [material, setMaterial] = useState(false);

  return (
    <VStack gap="md" align="stretch">
      <HStack gap="md" wrap>
        <Picker label="Orientation" value={orientation} onChange={(event) => setOrientation(event.currentTarget.value as typeof orientation)} items={[{ value: "horizontal", label: "Horizontal" }, { value: "vertical", label: "Vertical" }]} />
        <Picker label="Density" value={density} onChange={(event) => setDensity(event.currentTarget.value as typeof density)} items={[{ value: "comfortable", label: "Comfortable" }, { value: "compact", label: "Compact" }]} />
        <Toggle label="Material surface" checked={material} onChange={(event) => setMaterial(event.currentTarget.checked)} />
      </HStack>
      <Toolbar label="Field guide actions" orientation={orientation} density={density} material={material} overflow={<Button variant="outline" onClick={() => setMessage("8 pages · Updated today")}>Details</Button>}>
        {actions.map((action) => <Button key={action.label} variant={action.variant} onClick={() => setMessage(action.message)}>{action.label}</Button>)}
      </Toolbar>
      <Text as="p" role="status" aria-live="polite">{message}</Text>
    </VStack>
  );
}