import { SchemaFieldComponents, VevProps } from '@vev/utils'; import { isFunction } from 'lodash'; import React from 'react'; import { SilkeAlertBanner, SilkeBox, SilkeVariablesWrapper, useExtendedFields, useFormField, } from '..'; import { safeEvalFunction } from './safe-eval'; import { isEvalCallback } from './schema-utils'; import { useSchemaContext } from './silke-schema-context'; import { SilkeDivider } from '../silke-divider'; import ArrayField from './fields/array-field'; import ImageField from './fields/image-field'; import VideoField from './fields/video-field'; import NumberField from './fields/number-field'; import ObjectField from './fields/object-field'; import SelectField from './fields/select-field'; import StringField from './fields/string-field'; import ToggleField from './fields/toggle-field'; import LinkField from './fields/link-field'; import LayoutField from './fields/layout-field'; import IconField from './fields/icon-field'; import EventField from './fields/event-field'; import UploadField from './fields/upload-field'; import AudioField from './fields/audio-field'; import ColorField from './fields/color-field'; import GroupField from './fields/group-field'; import PopoverField from './fields/popover-field'; type SilkeSchemaFieldProps = { field: VevProps; value?: any; noPad?: boolean; isFirst?: boolean; disabled?: boolean; readonly?: boolean; itemIndex?: number; }; const SCHEMA_FIELD_COMPONENTS: Partial = { string: StringField, color: ColorField, number: NumberField, array: ArrayField, image: ImageField, audio: AudioField, video: VideoField, boolean: ToggleField, object: ObjectField, select: SelectField, link: LinkField, layout: LayoutField, icon: IconField, event: EventField, upload: UploadField, group: GroupField, popover: PopoverField, }; export function SilkeSchemaField({ field, value: fieldValue, noPad, isFirst, disabled, readonly, itemIndex, }: SilkeSchemaFieldProps) { const extendedFields = useExtendedFields(); const { value, onChange } = useFormField({ name: field?.name, value: fieldValue }); const context = useSchemaContext(); let Field = (field?.component || SCHEMA_FIELD_COMPONENTS[field?.type]) as any; if (!Field) { const extendedField = extendedFields.find((extField) => extField.type === field?.type); if (extendedField) { Field = extendedField.field; } } if (!field?.name && !['layout', 'divider', 'group', 'popover'].includes(field?.type)) return ( ); if (!field) return null; const getVariableType = (field: VevProps) => { if (field.component) return 'none'; if (field.type === 'number' && (field.options?.display === 'slider' || field.options?.display === 'range-slider')) return 'none'; if (field.type === 'string') return 'text'; return field.type; }; return ( <> {['object', 'divider'].includes(field?.type) && !isFirst && ( )} { if (isEvalCallback(field.onChange)) { value = await safeEvalFunction(field.onChange.value, value, context); } else if (isFunction(field.onChange)) { // @ts-ignore TODO: fix this value = (await field.onChange(value as any, context)) as any; } onChange(value); }} /> ); }