Omarchy Workspace Settings

block

Monitor and workspace settings with a live tiling preview.

bunx --bun shadcn@latest add yamz8/omarchy-shadcn-registry/omarchy-workspace-settings

Preview

Workspaces
eDP-1 · 2880×1800 · 120 Hz — layout preview for the selected workspace.
Alacritty
focused1
Tiled window
nvim
1
Tiled window
Keep spacing between tiled windows on this monitor.
Give the first window a full-height master column.

Dependencies

registry
button, card, switch, yamz8/omarchy-shadcn-registry/omarchy-settings-row, yamz8/omarchy-shadcn-registry/omarchy-window-frame, yamz8/omarchy-shadcn-registry/omarchy-workspace-switcher

Source

registry/blocks/omarchy-workspace-settings.tsx
"use client"

import * as React from "react"

import { Button } from "@/components/ui/button"
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"
import { Switch } from "@/components/ui/switch"
import { OmarchySettingsRow } from "@/components/ui/omarchy-settings-row"
import { OmarchyWindowFrame } from "@/components/ui/omarchy-window-frame"
import {
  OmarchyWorkspaceSwitcher,
  type OmarchyWorkspace,
} from "@/components/ui/omarchy-workspace-switcher"

type Window = {
  id: string
  title: string
  floating?: boolean
}

const workspaces: readonly OmarchyWorkspace[] = [
  { id: "1", occupied: true },
  { id: "2", occupied: true },
  { id: "3", occupied: true },
  { id: "4" },
  { id: "5" },
]

const windowsByWorkspace: Record<string, readonly Window[]> = {
  "1": [
    { id: "term", title: "Alacritty" },
    { id: "editor", title: "nvim" },
  ],
  "2": [
    { id: "browser", title: "Chromium" },
    { id: "notes", title: "Obsidian", floating: true },
  ],
  "3": [{ id: "music", title: "Spotify" }],
  "4": [],
  "5": [],
}

/**
 * Monitor and workspace settings: pick a workspace, see how its windows tile,
 * and toggle the per-monitor layout options Omarchy exposes.
 */
export function OmarchyWorkspaceSettings() {
  const [workspace, setWorkspace] = React.useState("1")
  const [focused, setFocused] = React.useState("term")
  const [gaps, setGaps] = React.useState(true)
  const [master, setMaster] = React.useState(false)
  const gapsId = React.useId()
  const masterId = React.useId()

  const windows = windowsByWorkspace[workspace] ?? []

  return (
    <Card className="w-full max-w-xl">
      <CardHeader>
        <CardTitle>Workspaces</CardTitle>
        <CardDescription>
          eDP-1 · 2880×1800 · 120 Hz — layout preview for the selected
          workspace.
        </CardDescription>
      </CardHeader>
      <CardContent className="flex flex-col gap-5">
        <OmarchyWorkspaceSwitcher
          workspaces={workspaces}
          value={workspace}
          onValueChange={setWorkspace}
        />

        <div
          className={
            windows.length === 0
              ? "flex min-h-32 items-center justify-center rounded-lg border border-dashed border-border"
              : master
                ? `grid min-h-32 grid-cols-2 ${gaps ? "gap-2" : "gap-px"}`
                : `grid min-h-32 grid-cols-1 sm:grid-cols-2 ${gaps ? "gap-2" : "gap-px"}`
          }
        >
          {windows.length === 0 ? (
            <p className="text-sm text-muted-foreground">Empty workspace</p>
          ) : (
            windows.map((window, index) => (
              <OmarchyWindowFrame
                key={window.id}
                title={window.title}
                workspace={workspace}
                floating={window.floating}
                focused={focused === window.id}
                actions={
                  focused === window.id ? (
                    <span className="font-mono text-[0.625rem] text-primary">
                      focused
                    </span>
                  ) : (
                    <Button
                      variant="ghost"
                      size="xs"
                      onClick={() => setFocused(window.id)}
                    >
                      Focus
                      <span className="sr-only"> {window.title}</span>
                    </Button>
                  )
                }
                className={
                  master && index === 0 && windows.length > 1
                    ? "row-span-2"
                    : undefined
                }
              >
                <span className="text-xs text-muted-foreground">
                  {window.floating ? "Floating window" : "Tiled window"}
                </span>
              </OmarchyWindowFrame>
            ))
          )}
        </div>

        <div className="flex flex-col">
          <OmarchySettingsRow
            label="Window gaps"
            description="Keep spacing between tiled windows on this monitor."
            controlId={gapsId}
          >
            <Switch id={gapsId} checked={gaps} onCheckedChange={setGaps} />
          </OmarchySettingsRow>
          <OmarchySettingsRow
            label="Master layout"
            description="Give the first window a full-height master column."
            controlId={masterId}
          >
            <Switch
              id={masterId}
              checked={master}
              onCheckedChange={setMaster}
            />
          </OmarchySettingsRow>
        </div>
      </CardContent>
    </Card>
  )
}