Add collapsible-card-header component to consolidate and improve folding
This commit is contained in:
59
src/components/ui/collapsible-card-header.tsx
Normal file
59
src/components/ui/collapsible-card-header.tsx
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* CollapsibleCardHeader
|
||||
*
|
||||
* Shared header row with a title + chevron toggle, optional children after title/chevron,
|
||||
* and an optional right section for action buttons.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { ChevronDown, ChevronUp } from 'lucide-react';
|
||||
import { CardHeader, CardTitle } from './card';
|
||||
import { cn } from '../../lib/utils';
|
||||
|
||||
interface CollapsibleCardHeaderProps {
|
||||
title: React.ReactNode;
|
||||
isCollapsed: boolean;
|
||||
onToggle: () => void;
|
||||
children?: React.ReactNode;
|
||||
rightSection?: React.ReactNode;
|
||||
className?: string;
|
||||
titleClassName?: string;
|
||||
toggleLabel?: string;
|
||||
}
|
||||
|
||||
const CollapsibleCardHeader: React.FC<CollapsibleCardHeaderProps> = ({
|
||||
title,
|
||||
isCollapsed,
|
||||
onToggle,
|
||||
children,
|
||||
rightSection,
|
||||
className,
|
||||
titleClassName,
|
||||
toggleLabel
|
||||
}) => {
|
||||
const accessibilityProps = toggleLabel ? { title: toggleLabel, 'aria-label': toggleLabel } : {};
|
||||
|
||||
return (
|
||||
<CardHeader className={cn('pb-3', className)}>
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<div className="flex items-center gap-2 flex-wrap flex-1">
|
||||
<button
|
||||
type="button"
|
||||
onClick={onToggle}
|
||||
className="inline-flex items-center gap-2 rounded-md px-1 py-1 -ml-1 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 hover:bg-muted/60 cursor-pointer"
|
||||
aria-expanded={!isCollapsed}
|
||||
{...accessibilityProps}
|
||||
>
|
||||
<CardTitle className={cn('text-lg', titleClassName)}>
|
||||
{title}
|
||||
</CardTitle>
|
||||
{isCollapsed ? <ChevronDown className="h-5 w-5 flex-shrink-0" /> : <ChevronUp className="h-5 w-5 flex-shrink-0" />}
|
||||
</button>
|
||||
{children}
|
||||
</div>
|
||||
{rightSection && <div className="flex items-center gap-2">{rightSection}</div>}
|
||||
</div>
|
||||
</CardHeader>
|
||||
);
|
||||
};
|
||||
|
||||
export default CollapsibleCardHeader;
|
||||
Reference in New Issue
Block a user