Templates Tab Component
The TemplatesTab component (src/components/TemplatesTab.tsx) provides a focused interface for managing saved response templates within chat applications.
Overview
This component offers template management functionality including creating, viewing, applying, and deleting saved templates. It’s designed to be used as a tab content within a larger tabbed interface or as a standalone template management section.
Key Features
Template Management
- Save current input as a new template with custom title
- Apply existing templates to input field
- Delete templates (when not server-synchronized)
- Template validation and error prevention
User Interface
- Inline template creation form
- Scrollable template list
- Hover effects and visual feedback
- Keyboard shortcuts (Enter to save)
Content Display
- Template title and content preview
- Intelligent content truncation (60 characters)
- Empty state messaging
- Delete button with confirmation prevention
Props Interface
interface TemplatesTabProps {
templates: SavedTemplate[];
currentInputValue: string;
canSaveToServer: boolean;
onApplyTemplate: (template: string) => void;
onSaveTemplate: (title: string, content: string) => void;
onDeleteTemplate: (templateId: string) => void;
}
Data Types
interface SavedTemplate {
id: string;
title: string;
content: string;
}
Implementation Example
// Basic usage
<TemplatesTab
templates={savedTemplates}
currentInputValue={inputText}
canSaveToServer={false}
onApplyTemplate={(template) => setInputValue(template)}
onSaveTemplate={(title, content) => {
const newTemplate = { id: generateId(), title, content };
setSavedTemplates([...savedTemplates, newTemplate]);
}}
onDeleteTemplate={(id) => {
setSavedTemplates(templates.filter(t => t.id !== id));
}}
/>
// With server synchronization
<TemplatesTab
templates={serverTemplates}
currentInputValue={inputText}
canSaveToServer={true}
onApplyTemplate={(template) => setInputValue(template)}
onSaveTemplate={async (title, content) => {
await saveTemplateToServer(title, content);
refreshTemplates();
}}
onDeleteTemplate={(id) => {
// Server templates cannot be deleted
console.log('Server templates are read-only');
}}
/>
Key Functionality
Template Creation
Provides an inline form for creating new templates:
const handleSaveTemplate = () => {
if (currentInputValue.trim() && newTemplateTitle.trim()) {
onSaveTemplate(newTemplateTitle.trim(), currentInputValue.trim());
setNewTemplateTitle('');
setShowSaveTemplate(false);
}
};
Template Application
Click any template to apply its content:
<div
className="px-3 py-2 hover:bg-gray-100 cursor-pointer border-b"
onClick={() => onApplyTemplate(template.content)}
>
<div className="text-sm font-medium">{template.title}</div>
<div className="text-xs text-gray-500 mt-1 truncate">
{template.content.substring(0, 60)}
{template.content.length > 60 ? '...' : ''}
</div>
</div>
Auto-focus Management
Automatically focuses the title input when creating templates:
const toggleTemplateInput = () => {
setShowSaveTemplate(!showSaveTemplate);
if (!showSaveTemplate) {
setTimeout(() => {
const titleInput = document.getElementById('template-title-input');
if (titleInput) {
titleInput.focus();
}
}, 100);
}
};
UI Structure
The component consists of three main sections:
Header Section
<div className="py-2 px-3 border-b flex justify-between items-center">
<h4 className="font-medium">Response Templates</h4>
<Button
variant="ghost"
size="sm"
onClick={toggleTemplateInput}
className="h-7 px-2 text-xs"
disabled={!currentInputValue.trim()}
>
{showSaveTemplate ? 'Cancel' : 'Save Current'}
</Button>
</div>
Template Creation Form (Conditional)
{showSaveTemplate && (
<div className="p-3 border-b">
<input
id="template-title-input"
type="text"
className="w-full p-2 text-sm border rounded mb-2"
placeholder="Template title"
value={newTemplateTitle}
onChange={(e) => setNewTemplateTitle(e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter') {
handleSaveTemplate();
}
}}
/>
<div className="flex justify-end">
<Button
size="sm"
onClick={handleSaveTemplate}
disabled={!newTemplateTitle.trim() || !currentInputValue.trim()}
>
Save Template
</Button>
</div>
</div>
)}
Template List
<ScrollArea className="h-72">
<div className="py-2">
{templates.length === 0 ? (
<div className="px-3 py-4 text-center text-gray-500 text-sm">
No templates saved yet
</div>
) : (
templates.map((template) => (
// Template items with apply and delete functionality
))
)}
</div>
</ScrollArea>
Dependencies
@/components/ui/button- Action buttons@/components/ui/scroll-area- Scrollable contentlucide-react- X icon for delete action
State Management
The component manages internal states:
showSaveTemplate- Controls template creation form visibilitynewTemplateTitle- Stores the title for new templates
Validation and Error Prevention
Input Validation
- Requires both title and content to be non-empty
- Trims whitespace from inputs
- Disables save button when validation fails
Keyboard Shortcuts
- Enter key submits template creation form
- Focus management for better accessibility
Server Integration Modes
Local Mode (canSaveToServer: false)
- Shows delete buttons for all templates
- Templates stored locally
- Full CRUD operations available
Server Mode (canSaveToServer: true)
- Hides delete buttons (read-only mode)
- Templates synchronized with server
- Only read and apply operations available
Accessibility Features
- Proper keyboard navigation
- Auto-focus on template creation
- Clear visual hierarchy
- Semantic HTML structure
- Screen reader friendly labels
Usage Patterns
This component is typically used within:
- Chat interface sidebars
- Template management modals
- Tabbed interfaces (as demonstrated in HistoryTemplatesPopover)
- Settings or preferences panels
The component provides a self-contained template management experience while remaining flexible enough to integrate with various parent components and data sources.