65 lines
2.8 KiB
TypeScript
65 lines
2.8 KiB
TypeScript
import React from 'react';
|
|
import { XMarkIcon } from '@heroicons/react/24/outline';
|
|
|
|
export interface BulkAction {
|
|
label: string;
|
|
icon?: React.ReactNode;
|
|
onClick: () => void;
|
|
variant?: 'danger' | 'primary' | 'secondary';
|
|
}
|
|
|
|
interface BulkActionBarProps {
|
|
selectedCount: number;
|
|
actions: BulkAction[];
|
|
onClearSelection: () => void;
|
|
}
|
|
|
|
/**
|
|
* BulkActionBar Component
|
|
* A floating bar that appears when items are selected in a list/table.
|
|
* Supports light/dark modes and custom actions.
|
|
*/
|
|
export default function BulkActionBar({ selectedCount, actions, onClearSelection }: BulkActionBarProps) {
|
|
if (selectedCount === 0) return null;
|
|
|
|
return (
|
|
<div className="fixed bottom-8 left-1/2 -translate-x-1/2 z-50 animate-in slide-in-from-bottom-10 duration-300">
|
|
<div className="bg-white dark:bg-black border border-zinc-200 dark:border-zinc-900 text-zinc-900 dark:text-white rounded-[32px] px-8 py-4 shadow-[0_20px_50px_rgba(0,0,0,0.1)] dark:shadow-[0_20px_50px_rgba(0,0,0,0.5)] flex items-center gap-8 backdrop-blur-xl">
|
|
<div className="flex items-center gap-3 pr-8 border-r border-zinc-200 dark:border-zinc-900">
|
|
<span className="flex items-center justify-center w-8 h-8 bg-brand-500 rounded-full text-xs font-black text-white">
|
|
{selectedCount}
|
|
</span>
|
|
<span className="text-sm font-bold text-zinc-500 dark:text-zinc-400">Selecionados</span>
|
|
</div>
|
|
|
|
<div className="flex items-center gap-4">
|
|
{actions.map((action, idx) => (
|
|
<button
|
|
key={idx}
|
|
onClick={action.onClick}
|
|
className={`flex items-center gap-2 px-4 py-2 rounded-xl transition-all text-sm font-bold
|
|
${action.variant === 'danger'
|
|
? 'text-rose-500 hover:bg-rose-500/10'
|
|
: action.variant === 'primary'
|
|
? 'text-brand-600 dark:text-brand-400 hover:bg-brand-500/10'
|
|
: 'text-zinc-600 dark:text-zinc-400 hover:bg-zinc-100 dark:hover:bg-zinc-800'
|
|
}`}
|
|
>
|
|
{action.icon}
|
|
{action.label}
|
|
</button>
|
|
))}
|
|
</div>
|
|
|
|
<button
|
|
onClick={onClearSelection}
|
|
className="ml-4 p-2 text-zinc-400 hover:text-zinc-900 dark:hover:text-white transition-colors"
|
|
title="Limpar seleção"
|
|
>
|
|
<XMarkIcon className="w-5 h-5" />
|
|
</button>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|