Workspace Switcher
Segmented workspace picker for switching between canvas views and operational contexts. Install Workspace Switcher from the VLLNT UI registry with the shadcn CLI.
What it is and when to use
Workspace Switcher is a compact, segmented control for moving between workspaces, canvas views, or operational contexts. It renders each option as a pill inside a radio group, highlighting the active one, and works either controlled or uncontrolled through value and defaultValue props. An onValueChange callback reports selection, and each option can carry a description shown as a tooltip and, on wider screens, inline. Reach for it when users toggle between a handful of top-level contexts rather than navigating a deep menu.
NavigationSegmented workspace picker for switching between canvas views and operational contexts. Part of the navigation family in VLLNT UI, it ships as a machine-readable registry entry — copy the source directly into your app with the shadcn CLI and own it, no runtime dependency on a component library.
Preview
Switch between light and dark to inspect the embedded Storybook preview.
Installation
Add Workspace Switcher to your project with the shadcn CLI. The source lands in your codebase, ready to adapt:
pnpm dlx shadcn@latest add https://ui.vllnt.com/r/workspace-switcher.jsonSource
"use client";
import { useMemo, useState } from "react";
import { cn } from "../../lib/utils";
export type WorkspaceOption = {
description?: string;
id: string;
label: string;
};
export type WorkspaceSwitcherProps = Omit<
React.ComponentPropsWithoutRef<"div">,
"defaultValue" | "onChange"
> & {
defaultValue?: string;
onValueChange?: (value: string) => void;
value?: string;
workspaces: WorkspaceOption[];
};
const WorkspaceSwitcher = ({
className,
defaultValue,
onValueChange,
ref,
value,
workspaces,
...props
}: WorkspaceSwitcherProps & { ref?: React.Ref<HTMLDivElement> }) => {
const fallbackValue = defaultValue ?? workspaces[0]?.id ?? "";
const [internalValue, setInternalValue] = useState(fallbackValue);
const currentValue = value ?? internalValue;
const currentWorkspace = useMemo(
() => workspaces.find((workspace) => workspace.id === currentValue),
[currentValue, workspaces],
);
function handleSelect(nextValue: string) {
if (value === undefined) {
setInternalValue(nextValue);
}
onValueChange?.(nextValue);
}
return (
<div
className={cn(
"inline-flex min-w-0 items-center gap-1 rounded-full border border-border/70 bg-muted/50 p-1",
className,
)}
ref={ref}
role="radiogroup"
{...props}
>
{workspaces.map((workspace) => {
const isActive = workspace.id === currentValue;
return (
<button
aria-checked={isActive}
className={cn(
"rounded-full px-3 py-1.5 text-sm font-medium transition-colors",
isActive
? "bg-background text-foreground shadow-sm"
: "text-muted-foreground hover:text-foreground",
)}
key={workspace.id}
onClick={() => {
handleSelect(workspace.id);
}}
role="radio"
title={workspace.description}
type="button"
>
{workspace.label}
</button>
);
})}
{currentWorkspace?.description ? (
<span className="hidden pl-2 pr-1 text-xs text-muted-foreground md:inline">
{currentWorkspace.description}
</span>
) : null}
</div>
);
};
WorkspaceSwitcher.displayName = "WorkspaceSwitcher";
export { WorkspaceSwitcher };
Stories
Explore every variant and state in the interactive Storybook:
Preview
Switch between light and dark to inspect the embedded Storybook preview.
FAQ
- What is Workspace Switcher?
- Workspace Switcher is a React component that renders a segmented pill control for switching between workspaces, canvas views, or operational contexts. Options are supplied as an array of id and label pairs, and the active one is visually highlighted.
- How do I add Workspace Switcher?
- Run `pnpm dlx shadcn@latest add https://ui.vllnt.com/r/workspace-switcher.json` to install it into your React project via the shadcn CLI, then pass your workspaces array to the WorkspaceSwitcher component.
- Is Workspace Switcher controlled or uncontrolled?
- It works both ways. Pass value with onValueChange for a controlled component, or defaultValue to let it manage its own selection. It renders as an accessible radio group, marking the selected workspace with aria-checked.