Some checks failed
Pull Request Checks / Code Quality & Security (push) Has been cancelled
Security Audit / Security Vulnerability Audit (push) Has been cancelled
Security Audit / Dependency Review (push) Has been cancelled
Security Audit / CodeQL Security Analysis (push) Has been cancelled
Security Audit / Check Outdated Dependencies (push) Has been cancelled
Introduce a dual-layer component architecture: - `components/ui/` contains raw shadcn/ui primitives (button, badge, input, checkbox, label, skeleton, alert, toggle, toggle-group, input-otp) - `components/atoms/` wraps these primitives with enhanced APIs (loading states, semantic variants, polymorphic props) for backward compatibility Migrated atoms: badge, button, checkbox, input, label, skeleton, view-toggle, error-message, inline-toast, error-state. Legacy backups preserved as .legacy.tsx files for reference. Added barrel export for ui/ and updated components/index.ts. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
53 lines
1.5 KiB
TypeScript
53 lines
1.5 KiB
TypeScript
"use client";
|
|
|
|
import { Squares2X2Icon, ListBulletIcon } from "@heroicons/react/24/outline";
|
|
import { cn } from "@/shared/utils";
|
|
|
|
export type ViewMode = "grid" | "list";
|
|
|
|
interface ViewToggleProps {
|
|
value: ViewMode;
|
|
onChange: (mode: ViewMode) => void;
|
|
className?: string;
|
|
}
|
|
|
|
export function ViewToggle({ value, onChange, className }: ViewToggleProps) {
|
|
return (
|
|
<div
|
|
className={cn(
|
|
"inline-flex items-center rounded-lg border border-border/60 bg-muted/30 p-0.5",
|
|
className
|
|
)}
|
|
>
|
|
<button
|
|
type="button"
|
|
onClick={() => onChange("grid")}
|
|
className={cn(
|
|
"inline-flex items-center justify-center h-7 w-7 rounded-md transition-all duration-200",
|
|
value === "grid"
|
|
? "bg-background text-foreground shadow-sm"
|
|
: "text-muted-foreground hover:text-foreground"
|
|
)}
|
|
aria-label="Grid view"
|
|
aria-pressed={value === "grid"}
|
|
>
|
|
<Squares2X2Icon className="h-3.5 w-3.5" />
|
|
</button>
|
|
<button
|
|
type="button"
|
|
onClick={() => onChange("list")}
|
|
className={cn(
|
|
"inline-flex items-center justify-center h-7 w-7 rounded-md transition-all duration-200",
|
|
value === "list"
|
|
? "bg-background text-foreground shadow-sm"
|
|
: "text-muted-foreground hover:text-foreground"
|
|
)}
|
|
aria-label="List view"
|
|
aria-pressed={value === "list"}
|
|
>
|
|
<ListBulletIcon className="h-3.5 w-3.5" />
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|