import { Field, FieldConfig } from "./Field"; import type { RenderingContext } from "../../ui/RenderingContext"; import type { Instance } from "../../ui/Instance"; import type { StructuredProp, ResolvePropType } from "../../ui/Prop"; /** * Configuration for Validator widget. * * The value type parameter enables type inference for the onValidate callback: * - Literal values preserve their types * - AccessorChain resolves to T * - Bind/Tpl/Expr resolve to any * - Structured props (objects) have each property resolved individually * * @example * ```typescript * { * if (value.password !== value.confirmPassword) * return "Passwords do not match"; * }} * /> * ``` */ export interface ValidatorConfig extends FieldConfig { /** The value to be validated. Can be a structured object with multiple fields. */ value?: V; /** Custom validation function. */ onValidate?: | string | ((value: ResolvePropType, instance: Instance, validationParams: Record) => unknown); } export class Validator extends Field> { constructor(config?: ValidatorConfig) { super(config); } declareData(...args: Record[]): void { return super.declareData(...args, { value: { structured: true, }, disabled: undefined, }); } isEmpty(data: Record): boolean { return false; } render(context: RenderingContext, instance: Instance, key: string): any { if (!instance.state?.visited || !instance.data.error) return null; return this.renderChildren(context, instance, key); } }