93 lines
2.5 KiB
TypeScript
93 lines
2.5 KiB
TypeScript
'use client';
|
|
|
|
import React from 'react';
|
|
import { Stack } from '@/ui/Stack';
|
|
import { Text } from '@/ui/Text';
|
|
import { Button } from '@/ui/Button';
|
|
import { motion, AnimatePresence } from 'framer-motion';
|
|
|
|
interface BulkActionBarProps {
|
|
selectedCount: number;
|
|
actions: {
|
|
label: string;
|
|
onClick: () => void;
|
|
variant?: 'primary' | 'secondary' | 'danger';
|
|
icon?: React.ReactNode;
|
|
}[];
|
|
onClearSelection: () => void;
|
|
}
|
|
|
|
/**
|
|
* BulkActionBar
|
|
*
|
|
* Floating action bar that appears when items are selected in a table.
|
|
*/
|
|
export function BulkActionBar({
|
|
selectedCount,
|
|
actions,
|
|
onClearSelection
|
|
}: BulkActionBarProps) {
|
|
return (
|
|
<AnimatePresence>
|
|
{selectedCount > 0 && (
|
|
<Stack
|
|
as={motion.div}
|
|
initial={{ y: 100, opacity: 0 }}
|
|
animate={{ y: 0, opacity: 1 }}
|
|
exit={{ y: 100, opacity: 0 }}
|
|
position="fixed"
|
|
bottom="8"
|
|
left="1/2"
|
|
translateX="-1/2"
|
|
zIndex={50}
|
|
bg="bg-surface-charcoal"
|
|
border
|
|
borderColor="border-primary-blue/50"
|
|
rounded="xl"
|
|
shadow="xl"
|
|
px={6}
|
|
py={4}
|
|
bgOpacity={0.9}
|
|
blur="md"
|
|
>
|
|
<Stack direction="row" align="center" gap={8}>
|
|
<Stack direction="row" align="center" gap={3}>
|
|
<Stack bg="bg-primary-blue" rounded="full" px={2} py={0.5}>
|
|
<Text size="xs" weight="bold" color="text-white">
|
|
{selectedCount}
|
|
</Text>
|
|
</Stack>
|
|
<Text size="sm" weight="medium" color="text-white">
|
|
Items Selected
|
|
</Text>
|
|
</Stack>
|
|
|
|
<Stack w="px" h="6" bg="bg-charcoal-outline">{null}</Stack>
|
|
|
|
<Stack direction="row" align="center" gap={3}>
|
|
{actions.map((action) => (
|
|
<Button
|
|
key={action.label}
|
|
size="sm"
|
|
variant={action.variant === 'danger' ? 'secondary' : (action.variant || 'primary')}
|
|
onClick={action.onClick}
|
|
icon={action.icon}
|
|
>
|
|
{action.label}
|
|
</Button>
|
|
))}
|
|
<Button
|
|
size="sm"
|
|
variant="ghost"
|
|
onClick={onClearSelection}
|
|
>
|
|
Cancel
|
|
</Button>
|
|
</Stack>
|
|
</Stack>
|
|
</Stack>
|
|
)}
|
|
</AnimatePresence>
|
|
);
|
|
}
|