RendererContext
Contexto interno que transporta todas as integrações injetadas pela árvore do FormRenderer. Passe as props ao FormRenderer e o contexto é configurado automaticamente.
useRendererContext
Acessa o contexto em qualquer componente dentro do <FormRenderer>:
import { useRendererContext } from "@schema-forms-data/renderer";
const {
uploadFile,
deleteUploadedFile,
cepLookup,
resolveTermsUploadUrl,
externalData,
fieldResolvers,
validatorMapper,
fieldWarnings,
componentMapper,
} = useRendererContext();
RendererContextValue (interface completa)
interface RendererContextValue {
uploadFile?: (
file: File,
fieldName: string,
onProgress?: (pct: number) => void,
) => Promise<string>;
deleteUploadedFile?: (uploadId: string) => Promise<void>;
cepLookup?: (cep: string, signal?: AbortSignal) => Promise<CepLookupResult>;
resolveTermsUploadUrl?: (uploadId: string) => Promise<string>;
externalData?: Record<string, unknown>;
fieldResolvers?: FieldResolvers;
validatorMapper?: ValidatorMapper;
fieldWarnings?: Record<string, string>;
componentMapper?: ComponentMapper;
paymentMethodOptions?: {
porDia?: PaymentOption[];
todosOsDias?: PaymentOption[];
};
}
ValidatorMapper
Mapa de funções validadoras customizadas por type. Usado em FormField.validate[] e FormField.warn[].
type FieldValidatorFn = (
value: unknown,
allValues: Record<string, unknown>, // todos os valores do step atual
config: FieldValidatorConfig, // { type, message, ...params }
externalData: Record<string, unknown>,
) => string | undefined | Promise<string | undefined>;
type ValidatorMapper = Record<string, FieldValidatorFn>;
Exemplo:
import { FormRenderer } from "@schema-forms-data/renderer";
<FormRenderer
schema={schema}
validatorMapper={{
emailUnico: async (value) => {
const existe = await api.verificarEmail(String(value));
return existe ? 'E-mail já cadastrado' : undefined;
},
senhasIguais: (value, allValues, config) => {
const outro = allValues[config['field'] as string];
return value === outro ? undefined : 'As senhas não conferem';
},
}}
onComplete={...}
/>
Veja Validação para uso completo.
ComponentMapper
Mapa de componentes React por FieldType. Substitui o componente built-in para aquele tipo de campo.
interface FieldComponentProps {
name: string;
control: Control<Record<string, unknown>>;
field: FormField; // já resolvido (após resolveProps + opcoesFromVar)
}
type ComponentMapper = Record<string, React.ComponentType<FieldComponentProps>>;
Exemplo:
import { FieldType } from "@schema-forms-data/core";
import type { FieldComponentProps } from "@schema-forms-data/renderer";
import { Controller } from "react-hook-form";
const MeuTextField: React.FC<FieldComponentProps> = ({ name, control, field }) => (
<Controller
name={name}
control={control}
render={({ field: f, fieldState }) => (
<MeuInput
{...f}
label={field.label}
placeholder={field.placeholder}
disabled={field.isDisabled}
error={fieldState.error?.message}
/>
)}
/>
);
<FormRenderer
schema={schema}
componentMapper={{ [FieldType.TEXTO]: MeuTextField }}
onComplete={...}
/>
Veja Component Mapper para uso completo.
FieldResolvers
Props dinâmicas por campo, resolvidas em tempo de render a partir de externalData ou valores do formulário.
type FieldResolver = (
field: FormField,
formValues: Record<string, unknown>,
externalData: Record<string, unknown>,
) => Partial<FormField>;
type FieldResolvers = Record<string, FieldResolver>;
Exemplo:
<FormRenderer
schema={schema}
fieldResolvers={{
opcoes_camiseta: (field, _values, external) => ({
opcoes: (external['evento.tamanhosCamiseta'] as string[])
?.map(t => ({ valor: t, label: t })) ?? field.opcoes,
}),
forma_pagamento: (_field, values) => ({
isDisabled: values['pagamento_confirmado'] === true,
}),
}}
onComplete={...}
/>
Campos que usam isso precisam ter resolvePropsKey definido no schema correspondendo à chave em fieldResolvers.
CepLookupResult
interface CepLookupResult {
logradouro?: string;
bairro?: string;
cidade?: string;
estado?: string;
erro?: boolean; // true se CEP não encontrado
}
cepLookup padrão
Se cepLookup não for fornecido, DFCepField usa a API ViaCEP pública como fallback.
// Use sua própria API:
<FormRenderer
schema={schema}
cepLookup={async (cep) => {
const res = await fetch(`/api/cep/${cep}`);
return res.json();
}}
onComplete={...}
/>