Submatter/apps/web/components/chat/ChatSectionHeader.tsx

126 lines
3.5 KiB
TypeScript
Raw Normal View History

"use client";
import { useState, useEffect, useRef, useCallback } from "react";
import { cn } from "@/lib/utils";
export interface ChatSectionHeaderProps {
title: string;
isExpanded: boolean;
onToggle: () => void;
onAdd?: () => void;
onMore?: () => void;
className?: string;
}
export function ChatSectionHeader({
title,
isExpanded,
onToggle,
onAdd,
onMore,
className = "",
}: ChatSectionHeaderProps) {
const disclosureButtonRef = useRef<HTMLButtonElement>(null);
const handleDisclosureClick = useCallback(() => {
onToggle();
}, [onToggle]);
const handleAddClick = useCallback((e: React.MouseEvent) => {
e.stopPropagation();
onAdd && onAdd();
}, [onAdd]);
const handleMoreClick = useCallback((e: React.MouseEvent) => {
e.stopPropagation();
onMore && onMore();
}, [onMore]);
return (
<div
className={cn(
"flex items-center justify-between py-2 px-3 border-b border-sidebar-border bg-background/30",
"hover:bg-background/5 transition-colors",
className
)}
>
<div className="flex items-center space-x-2">
<button
ref={disclosureButtonRef}
type="button"
onClick={handleDisclosureClick}
className={cn(
"flex items-center justify-center w-6 h-6 rounded",
"hover:bg-accent focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500",
"transition-colors"
)}
aria-expanded={isExpanded}
aria-label={isExpanded ? "Collapse section" : "Expand section"}
>
{isExpanded ? (
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-4 w-4"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M19 9l-7 7-7-7"
/>
</svg>
) : (
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-4 w-4"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M4 6h16M4 12h16M4 18h16"
/>
</svg>
)}
</button>
<span className="font-medium text-sm text-foreground">{title}</span>
</div>
<div className="flex items-center space-x-1">
{onAdd && (
<button
type="button"
onClick={handleAddClick}
className={cn(
"inline-flex items-center px-2 py-0.5 text-xs font-medium rounded",
"text-indigo-600 hover:bg-indigo-600 hover:text-white",
"focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500",
"transition-colors"
)}
>
Add
</button>
)}
{onMore && (
<button
type="button"
onClick={handleMoreClick}
className={cn(
"inline-flex items-center px-2 py-0.5 text-xs font-medium rounded",
"text-gray-500 hover:bg-accent hover:text-foreground",
"focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500",
"transition-colors"
)}
>
⋯
</button>
)}
</div>
</div>
);
}