History Templates Popover Component
The HistoryTemplatesPopover component (src/components/HistoryTemplatesPopover.tsx) provides a responsive interface for managing message history and saved templates in the chat interface.
Overview
This component offers a tabbed interface that switches between message history and saved templates, with responsive design that uses a popover on desktop and a drawer on mobile devices.
Key Features
Responsive Design
- Desktop: Uses a popover that appears next to the trigger button
- Mobile: Uses a drawer that slides up from the bottom
- Automatic detection based on
isMobileprop
Message History Tab
- Displays previous chat messages in reverse chronological order (newest first)
- Shows truncated message content (60 characters max)
- Includes timestamps with relative formatting
- Click to apply message to current input
Templates Tab
- Manages saved response templates
- Create new templates from current input
- Apply templates to input field
- Delete templates (when not server-saved)
- Template validation and auto-focus
Props Interface
interface HistoryTemplatesPopoverProps {
messageHistory: MessageHistoryItem[];
templates: SavedTemplate[];
onApplyHistoryMessage: (message: string) => void;
onApplyTemplate: (template: string) => void;
onSaveTemplate: (title: string, content: string) => void;
onDeleteTemplate: (templateId: string) => void;
currentInputValue: string;
canSaveToServer?: boolean;
isMobile?: boolean;
}
Data Types
interface MessageHistoryItem {
text: string;
timestamp: Date;
}
interface SavedTemplate {
id: string;
title: string;
content: string;
}
Implementation Example
// Desktop usage with popover
<HistoryTemplatesPopover
messageHistory={messageHistory}
templates={savedTemplates}
onApplyHistoryMessage={(message) => setInputValue(message)}
onApplyTemplate={(template) => setInputValue(template)}
onSaveTemplate={(title, content) => saveNewTemplate(title, content)}
onDeleteTemplate={(id) => removeTemplate(id)}
currentInputValue={currentInput}
canSaveToServer={false}
isMobile={false}
/>
// Mobile usage with drawer
<HistoryTemplatesPopover
messageHistory={messageHistory}
templates={savedTemplates}
onApplyHistoryMessage={(message) => setInputValue(message)}
onApplyTemplate={(template) => setInputValue(template)}
onSaveTemplate={(title, content) => saveNewTemplate(title, content)}
onDeleteTemplate={(id) => removeTemplate(id)}
currentInputValue={currentInput}
canSaveToServer={false}
isMobile={true}
/>
Key Functionality
Template Creation
The component provides an inline form for creating new templates:
const handleSaveTemplate = () => {
if (currentInputValue.trim() && newTemplateTitle.trim()) {
onSaveTemplate(newTemplateTitle.trim(), currentInputValue.trim());
setNewTemplateTitle('');
setShowSaveTemplate(false);
}
};
Message History Display
Messages are shown with relative timestamps and truncated content:
{messageHistory.slice().reverse().map((msg, idx) => (
<div
key={idx}
className="px-3 py-2 hover:bg-gray-100 cursor-pointer border-b"
onClick={() => onApplyHistoryMessage(msg.text)}
>
<div className="text-sm">
{msg.text.length > 60 ? `${msg.text.substring(0, 60)}...` : msg.text}
</div>
<div className="text-xs text-gray-500 flex items-center mt-1">
<Clock className="h-3 w-3 mr-1" />
{new Date(msg.timestamp).toLocaleTimeString()}
</div>
</div>
))}
UI Components Used
Button- Save, cancel, and trigger actionsPopover&PopoverContent- Desktop overlayDrawer&DrawerContent- Mobile overlayTabs,TabsList,TabsTrigger,TabsContent- Tab interfaceScrollArea- Scrollable content areasAlignLeft,Clock,Xicons from Lucide React
State Management
The component manages several internal states:
showSaveTemplate- Controls template creation form visibilitynewTemplateTitle- Stores the title for new templates- Auto-focus on template title input when form opens
Accessibility Features
- Keyboard navigation support (Enter key to save templates)
- Proper ARIA labels and roles
- Focus management for template creation
- Clear visual hierarchy with proper contrast
Responsive Behavior
Desktop (Popover)
- Fixed width of 320px (
w-80) - Content height of 256px (
h-64) - Positioned relative to trigger button
Mobile (Drawer)
- Full width overlay from bottom
- Content height of 320px (
h-80) - Maximum height of 90vh
- Native mobile scroll behavior
Integration Notes
This component is typically used in chat interfaces where users need quick access to previous messages and saved response templates. It integrates with the main chat input component and requires external state management for messages and templates.
The component handles both local template storage (with delete capability) and server-synchronized templates (read-only mode when canSaveToServer is true).