import { AnyComponentSchema, JSONValue } from '@open-formulieren/types';
import { IntlShape, MessageDescriptor } from 'react-intl';
import { z } from 'zod';
import { ComponentDefinition } from '../components/designer/types';
import { BuilderContextType } from '../context';
export interface EditFormProps<S> {
    component: S;
}
export interface EditFormDefinition<S> extends React.FC<EditFormProps<S>> {
    defaultValues: S extends AnyComponentSchema ? Omit<S, 'id' | 'type'> : never;
}
export interface EditSchemaArgs {
    intl: IntlShape;
    builderContext: BuilderContextType;
}
export type EditSchema = (args: EditSchemaArgs) => z.ZodFirstPartySchemaTypes;
export interface ComponentPreviewProps<S extends AnyComponentSchema = AnyComponentSchema> {
    component: S;
}
export interface ComparisonValueProps {
    name: string;
    label: React.ReactNode;
    multiple?: boolean;
}
export interface Previews {
    /**
     * The component preview rendered next to the component configuration form.
     *
     * The preview updates live as the component configuration itself is modified through
     * form field interaction.
     */
    panel: React.FC<ComponentPreviewProps> | null;
    /**
     * The component preview rendered in the form designer.
     *
     * The preview updates as the component configuration itself is modified through form
     * field interaction and is saved.
     */
    designer: React.FC<ComponentPreviewProps> | null;
}
export interface FormDesigner {
    /**
     * The label used in the form designer.
     */
    label: MessageDescriptor;
}
export interface BuilderInfo<S extends AnyComponentSchema> {
    title: string;
    icon: string;
    schema: S;
}
type DefaultValueOf<S> = S extends {
    defaultValue?: infer D;
} ? D : never;
export interface ComponentSlot {
    /**
     * Reference to the collection the components belong to.
     *
     * Example: for the columns component this is '[parent component key].[column index]'
     */
    reference: string;
    /**
     * Whether the reference should be used in the data path of children components.
     */
    useReferenceInComponentDataPath?: boolean;
    /**
     * The components in this slot.
     */
    collection: ComponentDefinition[];
}
export interface RegistryEntry<S extends AnyComponentSchema> {
    edit: EditFormDefinition<S>;
    editSchema: EditSchema;
    preview: Previews;
    formDesigner: FormDesigner;
    builderInfo: BuilderInfo<S>;
    isDeprecated?: boolean;
    defaultValue: DefaultValueOf<S> | JSONValue | undefined;
    comparisonValue?: React.FC<ComparisonValueProps>;
    getComponentSlots?: (component: S) => ComponentSlot[];
    holdsData?: boolean;
}
export type Registry = {
    [S in AnyComponentSchema as S['type']]: RegistryEntry<S>;
};
export {};
