39 lines
1.3 KiB
TypeScript
39 lines
1.3 KiB
TypeScript
import React from 'react';
|
|
import { cn } from '@/lib/utils';
|
|
|
|
export interface ActionItem {
|
|
key: string;
|
|
label: string;
|
|
description: string;
|
|
icon?: React.ReactNode;
|
|
onClick: () => void;
|
|
disabled?: boolean;
|
|
}
|
|
|
|
interface ActionGridProps {
|
|
items: ActionItem[];
|
|
columns?: 1 | 2;
|
|
}
|
|
|
|
export function ActionGrid({ items, columns = 2 }: ActionGridProps) {
|
|
return (
|
|
<div className={cn('grid gap-3', columns === 2 ? 'sm:grid-cols-2' : '')}>
|
|
{items.map((item) => (
|
|
<button
|
|
key={item.key}
|
|
type="button"
|
|
onClick={item.onClick}
|
|
disabled={item.disabled}
|
|
className="group flex flex-col gap-1.5 rounded-2xl border border-slate-200 bg-white p-4 text-left shadow-sm transition duration-200 hover:-translate-y-0.5 hover:border-rose-200 hover:shadow-md focus:outline-none focus:ring-2 focus:ring-rose-300 disabled:cursor-not-allowed disabled:opacity-60 dark:border-white/10 dark:bg-white/5"
|
|
>
|
|
<div className="flex items-center gap-2 text-sm font-semibold text-slate-900 dark:text-white">
|
|
{item.icon ? <span className="text-rose-500 dark:text-rose-200">{item.icon}</span> : null}
|
|
{item.label}
|
|
</div>
|
|
<p className="text-xs text-slate-600 dark:text-slate-400">{item.description}</p>
|
|
</button>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|