Efferd

Workspaces

Component 67

About

a flexible, context-based solution to manage and display multiple workspaces in your app. It uses Radix Popover, supports avatars, search, and customizable rendering—perfect for SaaS dashboards with multi-tenant support.

Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds Workspaces to your project and fits it to your theme.

Code

How Workspaces is used: the demo's code. The component's own source comes with a free account.

Usage.tsx

'use client';

import * as React from 'react';
import {
	Workspaces,
	WorkspaceTrigger,
	WorkspaceContent,
	type Workspace,
} from '@/components/ui/workspaces';
import { Button } from '@/components/ui/button';
import { PlusIcon } from 'lucide-react';
import { StarIcon } from 'lucide-react';
import { SettingsIcon } from 'lucide-react';
// Extended workspace interface for this specific use case
interface MyWorkspace extends Workspace {
	logo: string;
	plan: string;
	slug: string;
	isFavorite?: boolean;

}

const workspaces: MyWorkspace[] = [
	{
		id: '1',
		name: 'Asme Inc.',
		logo: 'https://cdn.21st.dev/assets/mirror/bc/bcc1d61f4fed0e8e24b9b4da38783d3dc8b89fbf680bab0b4c492899b389ada9.png',
		plan: 'Free',
		slug: 'asme',
		isFavorite: true,
	},
	{
		id: '2',
		name: 'Bilux Labs',
		logo: 'https://cdn.21st.dev/assets/mirror/e3/e384379f340a9656b50470215b55a04e83bc4da060a79b2345eeb42cd74d8ce0.png',
		plan: 'Pro',
		slug: 'bilux',
	},
	{
		id: '3',
		name: 'Zentra Ltd.',
		logo: 'https://cdn.21st.dev/assets/mirror/bb/bbf794851f7542ebb90db83ffe8bc488ad3eaded2a60a1467e9a0ad7677a66bc.png',
		plan: 'Team',
		slug: 'zentra',
		isFavorite: true,
	},
	{
		id: '4',
		name: 'Nuvex Group',
		logo: 'https://cdn.21st.dev/assets/mirror/9a/9a8e397bb8799f8bf50c0d5cfe4bc88cc55e1dac0d84a8e97ee37afb88ef360d.png',
		plan: 'Free',
		slug: 'nuvex',
	},
	{
		id: '5',
		name: 'Cortexia',
		logo: 'https://cdn.21st.dev/assets/mirror/d2/d214eb22d429424706b048bb9092bf76d6cd9879400696c90bfd458fd737aecd.png',
		plan: 'Pro',
		slug: 'cortexia',
	},
];

export default function CustomRendering() {
	const [activeWorkspaceId, setActiveWorkspaceId] = React.useState('1');
	const [open, setOpen] = React.useState(false);

	const handleWorkspaceChange = (workspace: MyWorkspace) => {
		setActiveWorkspaceId(workspace.id);
		console.log('Selected workspace:', workspace);
	};

	// Custom workspace renderer with additional info
	const renderWorkspace = (workspace: Workspace, isSelected: boolean) => {
		const ws = workspace as MyWorkspace;
		return (
			<div className="flex min-w-0 flex-1 items-center gap-3">
				<div className="relative">
					<img src={ws.logo} alt={ws.name} className="h-8 w-8 rounded-full" />
					{ws.isFavorite && (
						<StarIcon className="absolute -top-1 -right-1 h-3 w-3 fill-yellow-400 text-yellow-400" />
					)}
				</div>
				<div className="flex min-w-0 flex-1 flex-col items-start">
					<span className="truncate text-sm font-medium">{ws.name}</span>
					<span className="text-muted-foreground text-xs">{ws.plan} Plan</span>
				</div>
				{isSelected && (
					<div className="flex items-center gap-1">
						<span className="text-xs font-medium text-green-600">Active</span>
					</div>
				)}
			</div>
		);
	};

	return (
		<div className="flex min-h-screen items-start justify-center gap-8 px-4 py-18">
				<Workspaces
			workspaces={workspaces}
			selectedWorkspaceId={activeWorkspaceId}
			onWorkspaceChange={handleWorkspaceChange}
			open={open}
			onOpenChange={setOpen}
		>
			<WorkspaceTrigger className="min-w-72 border-2 border-dashed" />
			<WorkspaceContent
				title="Choose Workspace"
				searchable
				renderWorkspace={renderWorkspace}
			>
				<Button
					variant="ghost"
					size="sm"
					className="text-muted-foreground w-full justify-start"
				>
					<PlusIcon className="mr-2 h-4 w-4" />
					Create new workspace
				</Button>
				<Button
					variant="ghost"
					size="sm"
					className="text-muted-foreground w-full justify-start"
				>
					<SettingsIcon className="mr-2 h-4 w-4" />
					Manage workspaces
				</Button>
			</WorkspaceContent>
		</Workspaces>
		</div>
	);
}

Dependencies

More by Efferd

View all
  • Testimonials Columns

    Testimonials Columns

    7.1K
  • Zoom Parallax

    Zoom Parallax

    5.2K
  • Dotted Surface

    Dotted Surface

    3.5K
  • Footer Section

    Footer Section

    2.7K
  • Grid Feature Cards

    Grid Feature Cards

    1.9K
  • Logo Cloud 2

    Logo Cloud 2

    1.6K
  • Header 3

    Header 3

    1.6K
  • Logo Cloud 3

    Logo Cloud 3

    1.5K