import React, { useCallback } from 'react' import { AbstractNodeProps, createAbstractNodeComponent, useAbstractNode, } from '../../lib/abstractNode' import { BaseNode, BaseNodeContent, BaseNodeFooter, BaseNodeHeaderRow, } from '../base/BaseNode' import { NodeMenubar } from '../base/NodeMenubar' import { Input } from '../ui/input' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../ui/select' import { Switch } from '../ui/switch' import { NodeFooterEdgeIndicators } from '../base/NodeFooterEdgeIndicators' import { NodeHeaderTitle } from '../base/NodeHeaderTitle' import { OutputHandle } from '../base/NodeHandles' import { Variable } from 'lucide-react' export type ValueType = 'string' | 'number' | 'boolean' export type VariableNodeData = { value?: string | number | boolean valueType?: ValueType } type Props = AbstractNodeProps 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 } } function VariableNodeComponent({ id, data }: Props) { const { updateData } = useAbstractNode(id, data ?? {}) const valueType: ValueType = data?.valueType ?? 'string' const value = data?.value ?? DEFAULT_BY_TYPE[valueType] const displayValue = typeof value === 'string' ? value : String(value) 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={} />
{valueType === 'boolean' ? (
{value ? 'true' : 'false'}
) : ( )}
{`${valueType.charAt(0).toUpperCase() + valueType.slice(1)} ยท ${displayValue.length ? `${displayValue.length} chars` : 'none'}`}
) } export const VariableNode = createAbstractNodeComponent( 'VariableNode', VariableNodeComponent ) export default VariableNode