Omarchy Workspace Settings
blockMonitor and workspace settings with a live tiling preview.
bunx --bun shadcn@latest add yamz8/omarchy-shadcn-registry/omarchy-workspace-settingsPreview
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>
)
}