import React from 'react';
import { FieldMeta, MapFromValue, MapToValue, UseFieldProps, ValidateOnConfig } from './useField';
export type FieldEventHandlers = {
    onBlur?: (...args: any[]) => any;
    onChange?: (...args: any[]) => any;
};
export declare function useMergedEventHandlers({ onBlur: onFieldBlur, onChange: onFieldChange }: FieldEventHandlers, { onBlur, onChange }: FieldEventHandlers): {
    onChange: (...args: any[]) => void;
    onBlur: (...args: any[]) => void;
};
export type FieldRenderProps<TValue = any> = UseFieldProps<TValue> & {
    type: string;
    ref?: React.Ref<any>;
};
/**
 * When Field renders an Element, it injects a few props.
 * In the case none DOM elements it also injects `meta`
 */
export type FieldInjectedProps<TValue = any> = FieldRenderProps<TValue> & {
    meta?: FieldMeta;
};
export type FieldProps<TAs extends React.ElementType = any> = {
    /**
     * The Component Input the form should render. You can sepcify a native element such as 'input' or 'select'
     * or provide a Component type class directly. When no type is provided the Field will attempt determine
     * the correct input from the Field's schema. A Field corresponding to a `yup.number()`
     * will render a `type='number'` etc.
     *
     * ```jsx
     * import Form from 'react-formal';
     *
     * function MyDateInput({ meta: _, ...props }) {
     *   return <input {...props} type='datetime-local' />
     * }
     *
     * <Form>
     *   Provide a type directly
     *   <Form.Field
     *     name='dateOfBirth'
     *     type='time'
     *     placeholder='time only'
     *   />
     *
     *   Use a custom Component
     *   (need native 'datetime' support to see it)
     *   <Form.Field
     *     name='dateOfBirth'
     *     as={MyDateInput}
     *   />
     *
     * </Form>
     * ```
     *
     * Custom Inputs should comply with the basic input api contract: set a value via a `value` prop and
     * broadcast changes to that value via an `onChange` handler.
     */
    as?: TAs;
    /**
     * The Field name, which should be path corresponding to a specific form `value` path.
     *
     * ```jsx static
     * // given the form value
     * value = {
     *   name: { first: '' }
     *   languages: ['english', 'spanish']
     * }
     *
     * // the path "name.first" would update the "first" property of the form value
     * <Form.Field name='name.first' />
     *
     * // use indexes for paths that cross arrays
     * <Form.Field name='languages[0]' />
     *
     * ```
     */
    name: string | string;
    /**
     * Configure whether validation occur: onChange, onBlur, or both
     * You can also specify a function that receives the Field `meta` object and returns a configuration map
     * in order to change validation strategies based on validity or other metadata.
     */
    validateOn?: ValidateOnConfig;
    /**
     * Customize how the Field value maps to the overall Form `value`.
     * `mapFromValue` can be a a string property name or a function that returns a
     * value for `name`'d path, allowing you to set commuted values from the Field.
     *
     * ```jsx static
     * <Form.Field
     *   name='name'
     *   mapFromValue={fieldValue => `${fieldValue.first} ${fieldValue.last}`}
     * />
     * ```
     *
     * You can also provide an object hash, mapping paths of the Form `value`
     * to fields in the field value using a string field name, or a function accessor.
     *
     * ```jsx
     * import Form from '@docs/components/FormWithResult';
     * import * as yup from 'yup';
     *
     * const getYear = () => (new Date()).getFullYear()
     *
     * const schema = yup.object({
     *   dateOfBirth: yup.date().required('Required'),
     *   age: yup.number()
     * });
     *
     * <Form
     *   schema={schema}
     *   defaultValue={schema.default()}
     * >
     *   <label>
     *     Date of Birth
     *     <Form.Field
     *       name='dateOfBirth'
     *       mapFromValue={{
     *         'dateOfBirth': event => event.target.value,
     *         'age': ({ target }) => target.valueAsDate ?
     *            getYear() - target.valueAsDate.getFullYear() : null
     *      }}/>
     *   </label>
     *   <label>
     *     Age
     *     <Form.Field name='age' />
     *   </label>
     *
     *   <Form.Submit type='submit'>Submit</Form.Submit>
     * </Form>
     * ```
     */
    mapFromValue?: MapFromValue;
    /**
     * Map the Form value to the Field value. By default
     * the `name` of the Field is used to extract the relevant
     * property from the Form value.
     *
     * ```jsx static
     * <Form.Field
     *   name='location'
     *   type="dropdownlist"
     *   mapToValue={model=> pick(model, 'location', 'locationId')}
     * />
     * ```
     */
    mapToValue?: MapToValue;
    /**
     * The css class added to the Field Input when it fails validation
     */
    errorClass?: string;
    /**
     * Tells the Field to trigger validation for specific paths.
     * Useful when used in conjuction with a `mapFromValue` hash that updates more than one value, or
     * if you want to trigger validation for the parent path as well.
     *
     * > NOTE! This overrides the default behavior of validating the field itself by `name`,
     * include the `name` if you want the field to validate itself.
     *
     * ```jsx static
     * <Form.Field name='name.first' validates="name.last" />
     * <Form.Field name='name' validates={['name', 'surname']} />
     * ```
     */
    validates?: string | string[];
    /**
     * Indicates whether child paths of the current Field
     * affect the active state of the field.
     *
     * ```
     * 'names'
     *   - 'first'
     *   - 'last'
     * ```
     *
     * Are all considered "part" of a field named `'names'` by default. Does not
     * affect which paths are validated, only whether `meta.valid` considers child
     * paths for its state.
     */
    exclusive?: boolean;
    /**
     * Disables validation for the Field.
     */
    noValidate?: boolean;
    /**
     * When children is the traditional react element or nodes, they are
     * passed through as-is to the Field `type` component.
     *
     * ```jsx static
     * <Field type='select'>
     *   <option>red</option>
     *   <option>red</option>
     * </Field>
     * ```
     *
     * When `children` is a function, its called with the processed field
     * props and field meta.
     *
     * **Tip:** you can pass `onChange` and `onBlur` handlers
     * to the `<Field>` component and it will handle merging them with its own injected
     * handlers.
     *
     * ```jsx static
     * <Field name='birthDate'>
     *  {(props, meta) =>
     *    <DataProvider>
     *      <Input {...props} />
     *    </DataProvider>
     *  }
     * </Field>
     * ```
     */
    children?: React.ReactNode | ((fieldProps: FieldRenderProps, meta: FieldMeta) => React.ReactNode);
    /**
     * A value to pass to checkboxs/radios/boolean inputs
     */
    value?: any;
    className?: string;
    /**
     * Instruct the field to not inject the `meta` prop into the input,
     * defaults to `true` when `as` is a non DOM component
     */
    injectMeta?: boolean;
    /** An HTML input type attribute */
    type?: string;
    /** A local onChange handler, will be merged with the injected onChange */
    onChange?: (...args: any[]) => any;
    /** A local onBlur handler, will be merged with the injected onBlur */
    onBlur?: (...args: any[]) => any;
};
export type FieldPropsWithAs<TAs extends React.ElementType> = FieldProps<TAs> & React.RefAttributes<any> & Omit<React.ComponentPropsWithoutRef<TAs>, keyof FieldProps | 'meta' | 'name' | 'value' | 'checked' | 'onChange' | 'onBlur'>;
export declare interface Field<TDefaultControl extends React.ElementType = 'input'> {
    <TAs extends React.ElementType = TDefaultControl>(props: FieldPropsWithAs<TAs>): React.ReactElement | null;
    displayName?: string;
    propTypes?: any;
}
/**
 * @alias Field
 * @memberof Form
 */
declare const _Field: Field;
export default _Field;
