import { useState, useEffect } from 'react'; interface FrontmatterEditorProps { frontmatter: Record; onChange: (frontmatter: Record) => void; className?: string; } export function FrontmatterEditor({ frontmatter, onChange, className = '' }: FrontmatterEditorProps) { const [fields, setFields] = useState>(frontmatter || {}); const [newKey, setNewKey] = useState(''); const [newValue, setNewValue] = useState(''); useEffect(() => { setFields(frontmatter || {}); }, [frontmatter]); const updateField = (key: string, value: any) => { const updated = { ...fields, [key]: value }; setFields(updated); onChange(updated); }; const deleteField = (key: string) => { const updated = { ...fields }; delete updated[key]; setFields(updated); onChange(updated); }; const addField = () => { if (!newKey.trim()) return; const updated = { ...fields, [newKey]: newValue }; setFields(updated); onChange(updated); setNewKey(''); setNewValue(''); }; const inferType = (value: any): string => { if (Array.isArray(value)) return 'array'; if (typeof value === 'boolean') return 'boolean'; if (typeof value === 'number') return 'number'; return 'string'; }; const renderFieldInput = (key: string, value: any) => { const type = inferType(value); switch (type) { case 'boolean': return ( updateField(key, e.target.checked)} className="w-5 h-5 text-amber-600 border-2 border-gray-900 focus:ring-0 focus:ring-offset-0" /> ); case 'array': return ( updateField(key, e.target.value.split(',').map((v) => v.trim()))} className="flex-1 px-3 py-2 border-2 border-gray-900 bg-white font-mono text-sm focus:outline-none focus:ring-2 focus:ring-amber-500" placeholder="comma, separated, values" /> ); case 'number': return ( updateField(key, parseFloat(e.target.value) || 0)} className="flex-1 px-3 py-2 border-2 border-gray-900 bg-white font-mono text-sm focus:outline-none focus:ring-2 focus:ring-amber-500" /> ); default: return ( updateField(key, e.target.value)} className="flex-1 px-3 py-2 border-2 border-gray-900 bg-white font-mono text-sm focus:outline-none focus:ring-2 focus:ring-amber-500" /> ); } }; return (

Frontmatter

YAML Metadata
{Object.keys(fields).length === 0 ? (
No frontmatter fields. Add one below.
) : (
{Object.entries(fields).map(([key, value]) => (
{key}
{renderFieldInput(key, value)}
))}
)}
Add Field
setNewKey(e.target.value)} placeholder="Key (e.g., title)" className="flex-1 px-3 py-2 border-2 border-gray-900 bg-white font-mono text-sm focus:outline-none focus:ring-2 focus:ring-amber-500" onKeyDown={(e) => { if (e.key === 'Enter' && newKey.trim()) { addField(); } }} /> setNewValue(e.target.value)} placeholder="Value" className="flex-1 px-3 py-2 border-2 border-gray-900 bg-white font-mono text-sm focus:outline-none focus:ring-2 focus:ring-amber-500" onKeyDown={(e) => { if (e.key === 'Enter' && newKey.trim()) { addField(); } }} />
); }