Barazo default frontend barazo.forum
at main 91 lines 2.5 kB view raw
1/** 2 * TopicContentEditor - Write/Preview tabs with markdown editor. 3 * @see specs/prd-web.md Section 4 (Editor Components) 4 */ 5 6'use client' 7 8import { useState } from 'react' 9import { cn } from '@/lib/utils' 10import { MarkdownEditor } from '@/components/markdown-editor' 11import { MarkdownPreview } from '@/components/markdown-preview' 12 13interface TopicContentEditorProps { 14 content: string 15 onChange: (content: string) => void 16 error?: string 17 required?: boolean 18} 19 20export function TopicContentEditor({ 21 content, 22 onChange, 23 error, 24 required, 25}: TopicContentEditorProps) { 26 const [activeTab, setActiveTab] = useState<'write' | 'preview'>('write') 27 28 return ( 29 <div className="space-y-1"> 30 <div role="tablist" aria-label="Editor mode" className="flex gap-1 border-b border-border"> 31 <button 32 type="button" 33 role="tab" 34 id="tab-write" 35 aria-selected={activeTab === 'write'} 36 aria-controls="tabpanel-write" 37 onClick={() => setActiveTab('write')} 38 className={cn( 39 'px-3 py-1.5 text-sm font-medium transition-colors', 40 activeTab === 'write' 41 ? 'border-b-2 border-primary text-foreground' 42 : 'text-muted-foreground hover:text-foreground' 43 )} 44 > 45 Write 46 </button> 47 <button 48 type="button" 49 role="tab" 50 id="tab-preview" 51 aria-selected={activeTab === 'preview'} 52 aria-controls="tabpanel-preview" 53 onClick={() => setActiveTab('preview')} 54 className={cn( 55 'px-3 py-1.5 text-sm font-medium transition-colors', 56 activeTab === 'preview' 57 ? 'border-b-2 border-primary text-foreground' 58 : 'text-muted-foreground hover:text-foreground' 59 )} 60 > 61 Preview 62 </button> 63 </div> 64 65 <div 66 id="tabpanel-write" 67 role="tabpanel" 68 aria-labelledby="tab-write" 69 hidden={activeTab !== 'write'} 70 > 71 <MarkdownEditor 72 value={content} 73 onChange={onChange} 74 id="topic-content" 75 label="Content" 76 required={required} 77 error={error} 78 /> 79 </div> 80 81 <div 82 id="tabpanel-preview" 83 role="tabpanel" 84 aria-labelledby="tab-preview" 85 hidden={activeTab !== 'preview'} 86 > 87 <MarkdownPreview content={content} /> 88 </div> 89 </div> 90 ) 91}