Omarchy Control Center

block

Appearance and session toggles with live theme switching and desktop shortcuts.

bunx --bun shadcn@latest add yamz8/omarchy-shadcn-registry/omarchy-control-center

Preview

Control center
Appearance and session toggles, with their desktop shortcuts.

Theme

Repaints this page with the selected Omarchy palette.
Tokyo Night

Appearance

Show the status bar across the top of every workspace.
Keep spacing between tiled windows.
Let the background show through unfocused windows.

Session

Lock the session after the idle timeout.
Hold notifications back until silencing is turned off.

Dependencies

registry
card, switch, yamz8/omarchy-shadcn-registry/omarchy-keycap, yamz8/omarchy-shadcn-registry/omarchy-settings-row, yamz8/omarchy-shadcn-registry/omarchy-swatch, yamz8/omarchy-shadcn-registry/use-omarchy-theme, yamz8/omarchy-shadcn-registry/omarchy-palette

Source

registry/blocks/omarchy-control-center.tsx
"use client"

import * as React from "react"

import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"
import { Switch } from "@/components/ui/switch"
import { OmarchyKeycap } from "@/components/ui/omarchy-keycap"
import {
  OmarchySettingsGroup,
  OmarchySettingsRow,
} from "@/components/ui/omarchy-settings-row"
import { OmarchySwatch } from "@/components/ui/omarchy-swatch"
import { useOmarchyTheme } from "@/hooks/use-omarchy-theme"
import { isOmarchyThemeName, OMARCHY_THEMES } from "@/lib/omarchy-palette"

type Toggle = {
  id: string
  label: string
  description: string
  keys: readonly string[]
  initial: boolean
}

const appearanceToggles: readonly Toggle[] = [
  {
    id: "bar",
    label: "Top bar",
    description: "Show the status bar across the top of every workspace.",
    keys: ["Super", "Shift", "Space"],
    initial: true,
  },
  {
    id: "gaps",
    label: "Window gaps",
    description: "Keep spacing between tiled windows.",
    keys: ["Super", "Shift", "Backspace"],
    initial: true,
  },
  {
    id: "transparency",
    label: "Window transparency",
    description: "Let the background show through unfocused windows.",
    keys: ["Super", "Backspace"],
    initial: false,
  },
]

const systemToggles: readonly Toggle[] = [
  {
    id: "idle",
    label: "Lock on idle",
    description: "Lock the session after the idle timeout.",
    keys: ["Super", "Ctrl", "I"],
    initial: true,
  },
  {
    id: "notifications",
    label: "Silence notifications",
    description: "Hold notifications back until silencing is turned off.",
    keys: ["Super", "Ctrl", ","],
    initial: false,
  },
]

function ToggleRow({ toggle }: { toggle: Toggle }) {
  const [checked, setChecked] = React.useState(toggle.initial)
  const id = React.useId()

  return (
    <OmarchySettingsRow
      label={toggle.label}
      description={toggle.description}
      controlId={id}
      keys={
        <span className="flex items-center gap-1">
          {toggle.keys.map((key) => (
            <OmarchyKeycap key={key}>{key}</OmarchyKeycap>
          ))}
        </span>
      }
    >
      <Switch id={id} checked={checked} onCheckedChange={setChecked} />
    </OmarchySettingsRow>
  )
}

/**
 * The Omarchy toggle menu as a web surface. The theme control is live — it
 * repaints this document. The remaining switches are local UI state; they do
 * not reach the desktop.
 */
export function OmarchyControlCenter() {
  const { theme, setTheme } = useOmarchyTheme()
  const themeSelectId = React.useId()

  return (
    <Card className="w-full max-w-lg">
      <CardHeader>
        <CardTitle>Control center</CardTitle>
        <CardDescription>
          Appearance and session toggles, with their desktop shortcuts.
        </CardDescription>
      </CardHeader>
      <CardContent className="flex flex-col gap-6">
        <OmarchySettingsGroup heading="Theme">
          <OmarchySettingsRow
            label="Active theme"
            description="Repaints this page with the selected Omarchy palette."
            controlId={themeSelectId}
          >
            <div className="flex items-center gap-2">
              <OmarchySwatch theme={theme} />
              <select
                id={themeSelectId}
                value={theme}
                onChange={(event) => {
                  if (isOmarchyThemeName(event.target.value)) {
                    setTheme(event.target.value)
                  }
                }}
                className="h-8 rounded-lg border border-input bg-transparent px-2 text-sm outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50"
              >
                {OMARCHY_THEMES.map((option) => (
                  <option key={option.name} value={option.name}>
                    {option.label}
                  </option>
                ))}
              </select>
            </div>
          </OmarchySettingsRow>
        </OmarchySettingsGroup>

        <OmarchySettingsGroup heading="Appearance">
          {appearanceToggles.map((toggle) => (
            <ToggleRow key={toggle.id} toggle={toggle} />
          ))}
        </OmarchySettingsGroup>

        <OmarchySettingsGroup heading="Session">
          {systemToggles.map((toggle) => (
            <ToggleRow key={toggle.id} toggle={toggle} />
          ))}
        </OmarchySettingsGroup>
      </CardContent>
    </Card>
  )
}