import {Button, Input, Label} from '@plunk/ui'; import {Plus, Trash2} from 'lucide-react'; import {useState} from 'react'; interface KeyValuePair { id: string; key: string; value: string; } interface KeyValueEditorProps { initialData?: Record | null; onChange?: (data: Record | null) => void; } export function KeyValueEditor({initialData, onChange}: KeyValueEditorProps) { const [pairs, setPairs] = useState(() => { // Initialize state from initialData only once on mount if (initialData && typeof initialData === 'object') { return Object.entries(initialData).map(([key, value], index) => ({ id: `initial-${index}-${Date.now()}`, key, value: String(value), })); } return []; }); // Notify parent of changes based on given pairs const notifyChange = (updatedPairs: KeyValuePair[]) => { if (!onChange) return; // Filter out empty pairs const validPairs = updatedPairs.filter(pair => pair.key.trim() !== ''); if (validPairs.length === 0) { onChange(null); } else { const data = validPairs.reduce( (acc, pair) => { // Try to parse as number or boolean, otherwise keep as string let value: string | number | boolean = pair.value; if (pair.value === 'true') value = true; else if (pair.value === 'false') value = false; else if (!isNaN(Number(pair.value)) && pair.value.trim() !== '') value = Number(pair.value); acc[pair.key] = value; return acc; }, {} as Record, ); onChange(data); } }; const addPair = () => { const newPairs = [...pairs, {id: `new-${Date.now()}`, key: '', value: ''}]; setPairs(newPairs); notifyChange(newPairs); }; const updateKey = (id: string, newKey: string) => { const updated = pairs.map(pair => (pair.id === id ? {...pair, key: newKey} : pair)); setPairs(updated); notifyChange(updated); }; const updateValue = (id: string, newValue: string) => { const updated = pairs.map(pair => (pair.id === id ? {...pair, value: newValue} : pair)); setPairs(updated); notifyChange(updated); }; const removePair = (id: string) => { const updated = pairs.filter(pair => pair.id !== id); setPairs(updated); notifyChange(updated); }; return (
{pairs.length === 0 ? (

No custom fields yet

Click "Add Field" to create custom data fields

) : (
{pairs.map(pair => (
updateKey(pair.id, e.target.value)} className="text-sm" />
updateValue(pair.id, e.target.value)} className="text-sm" />
))}
)}
); }