import React, { memo, useCallback, useContext } from 'react' import FlowContext from '../../lib/flowContext' import { BaseNode, BaseNodeContent, BaseNodeFooter, BaseNodeFooterText, BaseNodeHeaderRow, } from './BaseNode' import { Input } from '../ui/input' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../ui/select' import { Switch } from '../ui/switch' import { OutputHandle } from './NodeHandles' import { Variable } from 'lucide-react' type ValueType = 'string' | 'number' | 'boolean' type Props = { id: string data: { value?: string | number | boolean valueType?: ValueType } } const DEFAULT_BY_TYPE: Record = { string: '', number: 0, boolean: false, } function coerceValue(raw: string, valueType: ValueType): string | number | boolean { switch (valueType) { case 'number': { const n = Number(raw) return Number.isNaN(n) ? 0 : n } case 'boolean': return /^(1|true|yes|on)$/i.test(raw.trim()) default: return raw } } export const VariableNode = memo(function VariableNode({ id, data }: Props) { const ctx = useContext(FlowContext) const setNodes = ctx?.setNodes const valueType: ValueType = data?.valueType ?? 'string' const value = data?.value ?? DEFAULT_BY_TYPE[valueType] const displayValue = typeof value === 'string' ? value : String(value) const updateData = useCallback( (updates: { value?: string | number | boolean; valueType?: ValueType }) => { if (!setNodes) return setNodes((nds: any[]) => nds.map((n) => n.id === id ? { ...n, data: { ...n.data, ...updates } } : n ) ) }, [id, setNodes] ) const onTypeChange = useCallback( (nextType: string) => { const type = nextType as ValueType const raw = typeof value === 'boolean' ? (value ? 'true' : 'false') : String(value) const nextValue = coerceValue(raw, type) updateData({ valueType: type, value: nextValue }) }, [value, updateData] ) const onValueChange = useCallback( (e: React.ChangeEvent) => { const raw = e.target.value const nextValue = coerceValue(raw, valueType) updateData({ value: nextValue }) }, [valueType, updateData] ) const onBooleanChange = useCallback( (checked: boolean) => { updateData({ value: checked }) }, [updateData] ) return ( }> } title={id} />
{valueType === 'boolean' ? (
{value ? 'true' : 'false'}
) : ( )}
Use in config: prop: {'${'}{id}{'}'}
) }) VariableNode.displayName = 'VariableNode' export default VariableNode