import { Button } from "@workspace/ui/components/button"; import { Label } from "@workspace/ui/components/label"; import { Switch } from "@workspace/ui/components/switch"; import { Textarea } from "@workspace/ui/components/textarea"; import { Combobox } from "@workspace/ui/composed/combobox"; import { EnhancedInput, type EnhancedInputProps, } from "@workspace/ui/composed/enhanced-input"; import { cn } from "@workspace/ui/lib/utils"; import { CircleMinusIcon, CirclePlusIcon } from "lucide-react"; import { useEffect, useState } from "react"; interface FieldConfig extends Omit { name: string; type: "text" | "number" | "select" | "time" | "boolean" | "textarea"; options?: { label: string; value: string }[]; // optional per-item visibility function: returns true to show the field for the given item visible?: (item: Record) => boolean; } interface ObjectInputProps { value: T; onChange: (value: T) => void; fields: FieldConfig[]; className?: string; } // eslint-disable-next-line @typescript-eslint/no-explicit-any export function ObjectInput>({ value, onChange, fields, className, }: ObjectInputProps) { const [internalState, setInternalState] = useState(value); useEffect(() => { setInternalState(value); }, [value]); const updateField = (key: keyof T, fieldValue: string | number | boolean) => { const updatedInternalState = { ...internalState, [key]: fieldValue }; setInternalState(updatedInternalState); onChange(updatedInternalState); }; const renderField = (field: FieldConfig) => { // if visible callback exists and returns false for current item, don't render if (field.visible && !field.visible(internalState)) return null; switch (field.type) { case "select": return ( field.options && ( onChange={(fieldValue) => updateField(field.name, fieldValue)} options={field.options} placeholder={field.placeholder} value={internalState[field.name]} /> ) ); case "boolean": return (
updateField(field.name, fieldValue) } /> {field.placeholder && }
); case "textarea": return (
{field.prefix && ( )}