import { Component } from 'react';
import { ComponentType } from 'react';
import { ErrorInfo } from 'react';
import { JSX as JSX_2 } from 'react/jsx-runtime';
import { JSXElementConstructor } from 'react';
import { Key } from 'react';
import { MemoExoticComponent } from 'react';
import { PropsWithChildren } from 'react';
import { ReactElement } from 'react';
import { ReactNode } from 'react';

/**
 * **`ErrorBoundary`**: Wrapper component that lets you display some fallback UI when your application throws an error during rendering. [See demo](https://react-tools.ndria.dev/#/components/ErrorBoundary)
 * @param {Object} props
 * @param {(error:Error, info:ErrorInfo)=>void} [props.onCatch] - function that will be executed on component did catch.
 * @param {ReactNode|((error: Error, info: ErrorInfo, retry: ()=>void)=>ReactNode)|((props: { error: Error, info: ErrorInfo, retry: ()=>void })=>JSX.Element)} [props.fallback] - it is rendered when an error occurred. It can be an element, or a Component or a function. If it is a component or a function, it receive the _error_ the _info_ and the _retry_ function as props. _retry_ function try to rerender.
 * @param {ReactNode} props.children - element to render.
 * @returns {JSX.Element} result - element or fallback.
 */
export declare class ErrorBoundary extends Component<PropsWithChildren<{
    onCatch?: (error: Error, info: ErrorInfo) => void;
    fallback?: ReactNode | ((error: Error, info: ErrorInfo, retry: () => void) => ReactNode) | ((props: {
        error: Error;
        info: ErrorInfo;
        retry: () => void;
    }) => JSX_2.Element);
}>, {
    hasError: boolean;
    error?: Error;
    info?: ErrorInfo;
}> {
    state: {
        hasError: boolean;
        error?: Error;
        info?: ErrorInfo;
    };
    static getDerivedStateFromError(_: Error): {
        hasError: boolean;
        error?: Error;
        info?: ErrorInfo;
    };
    componentDidCatch(error: Error, info: ErrorInfo): void;
    retry(): void;
    render(): string | number | boolean | Iterable<ReactNode> | JSX_2.Element | null | undefined;
}

/**
 * **`For`**: Component to optimize the rendering of a list of elements without need to specify a key value for all elements, and other options. [See demo](https://react-tools.ndria.dev/#/components/For)
 * @param {Object} props - component properties object.
 * @param {Array<T>} props.of - array of elements.
 * @param {(T|S) extends object ? keyof (T|S) | ((item: T|S) => Key) : Key | ((item: T|S) => Key)} [props.elementKey] - if the elements are objects, this prop can be a key of the elements in __of__ prop, or a function with one parameter which type is the type of the elements in __of__ prop and returns a __React.Key__ type, otherwise this prop can be the function described before or a __React.Key__. If it isn't specified, element index in __of__ props will be used as key.
 * @param {(item: T|S, index: number, key: Key) => ReactNode} props.children - it's a function that takes the current item as first argument and optionally a second argument that is the index of current item and a third element that is the key specified in the _elementKey_ prop. Item is the current element of __of__ prop or, if __map__ prop is present, is the current element produces from __map__ prop.
 * @param {ReactNode} [props.fallback] - optional element to render when _of_ prop is an empty array.
 * @param {Parameters<Array<T>["filter"]>[0]} [props.filter] - callback executed to filter _of_ elements.
 * @param {undefined|((...args: Parameters<Parameters<Array<T>["map"]>[0]>) => S)} [props.map] - callback executed to map _of_ elements.
 * @param {true|Parameters<Array<T>["sort"]>[0]} [props.sort] - callback executed to sort _of_ elements or __`true`__ to use native sort.
 * @returns {null|JSX.Element|Array<JSX.Element>} result - elements list, rendered from _of_ prop or _fallback_ if exist, otherwise null.
 */
export declare function For<T>({ of, elementKey, fallback, filter, sort, map, children }: {
    of: Array<T>;
    elementKey?: T extends object ? keyof T | ((item: T) => Key) : Key | ((item: T) => Key);
    children: (item: T, index: number, key: Key) => ReactNode;
    fallback?: ReactNode;
    filter?: Parameters<Array<T>["filter"]>[0];
    sort?: true | Parameters<Array<T>["sort"]>[0];
    map?: undefined;
}): null | JSX.Element | Array<JSX.Element>;

export declare function For<T, S extends T>({ of, elementKey, fallback, filter, sort, map, children }: {
    of: Array<T>;
    elementKey?: S extends object ? keyof S | ((item: S) => Key) : Key | ((item: S) => Key);
    children: (item: S, index: number, key: Key) => ReactNode;
    fallback?: ReactNode;
    filter?: Parameters<Array<T>["filter"]>[0];
    sort?: true | Parameters<Array<T>["sort"]>[0];
    map?: (...args: Parameters<Parameters<Array<T>["map"]>[0]>) => S;
}): null | JSX.Element | Array<JSX.Element>;

export declare namespace For {
    var displayName: string;
}

/**
 * **`ForMemoized`**: Memoized version of _For_ component. [See demo](https://react-tools.ndria.dev/#/components/ForMemoized)
 * @param {Object} props - component properties object.
 * @param {Array<T>} props.of - array of elements.
 * @param {(T|S) extends object ? keyof (T|S) | ((item: T|S) => Key) : Key | ((item: T|S) => Key)} [props.elementKey] - if the elements are objects, this prop can be a key of the elements in __of__ prop, or a function with one parameter which type is the type of the elements in __of__ prop and returns a __React.Key__ type, otherwise this prop can be the function described before or a __React.Key__. If it isn't specified, element index in __of__ props will be used as key.
 * @param {(item: T|S, index: number, key: Key) => ReactNode} props.children - it's a function that takes the current item as first argument and optionally a second argument that is the index of current item and a third element that is the key specified in the _elementKey_ prop. Item is the current element of __of__ prop or, if __map__ prop is present, is the current element produces from __map__ prop.
 * @param {ReactNode} [props.fallback] - optional element to render when _of_ prop is an empty array.
 * @param {Parameters<Array<T>["filter"]>[0]} [props.filter] - callback executed to filter _of_ elements.
 * @param {undefined|((...args: Parameters<Parameters<Array<T>["map"]>[0]>) => S)} [props.map] - callback executed to map _of_ elements.
 * @param {true|Parameters<Array<T>["sort"]>[0]} [props.sort] - callback executed to sort _of_ elements or __`true`__ to use native sort.
 * @returns {null|JSX.Element|Array<JSX.Element>} result - elements list, rendered from _of_ prop or _fallback_ if exist, otherwise null.
 */
export declare const ForMemoized: typeof For;

/**
 * **`LazyComponent`**: Component Wrapper to lazy loading a Component. [See demo](https://react-tools.ndria.dev/#/components/LazyComponent)
 * @param {Object} param - properties to load component.
 * @param {() => Promise<{ [k:string]: T }>} param.factory - function that returns a Promise or another thenable.
 * @param {string} [param.componentName] - name of the of the module to load lazy. If it is missing, and the _load_ execution result not have a default property, the first key in res is returned as result.
 * @param {ReactNode} [object.fallback] - optional element to render when _when_ prop is false.
 * @param {()=>void} [param.beforeLoad] - function that will be executed before loading component .
 * @param {()=>void} [param.afterLoad] - function that will be executed after loading component .
 * @returns {JSX.Element} element
 */
export declare const LazyComponent: <T extends {
    default: ComponentType<unknown>;
} | {
    [k: string]: ComponentType<unknown>;
}>({ factory, componentName, fallback, beforeLoad, afterLoad }: {
    factory: () => Promise<T>;
    componentName?: string;
    fallback?: ReactNode;
    beforeLoad?: () => void;
    afterLoad?: () => void;
}) => JSX_2.Element;

/**
 * **`Show`**: Generic component used to conditional render part of the view: it renders _children_ when the _when_ prop is truthy, otherwise the _fallback_ prop, if it is present, or null. [See demo](https://react-tools.ndria.dev/#/components/Show)
 * @param {PropsWithChildren<{when: T|boolean|undefined|null, fallback?: ReactNode}>} object
 * @param {T|boolean|undefined|null} object.when - boolean indicating if to show _children_ or _fallback_/_null_.
 * @param {ReactNode} [object.fallback] - optional element to render when _when_ prop is false.
 * @param {PropsWithChildren<any>["children"]} [object.children] - optional element to render when _when_ prop is true.
 * @returns {JSX.Element|null} element - the element rendered or null.
 */
export declare function Show<T>({ when, fallback, children }: PropsWithChildren<{
    when: T | boolean | undefined | null;
    fallback?: ReactNode;
}>): JSX_2.Element | null;

/**
 * **`ShowMemoized`**: Memoized version of _Show_ component. [See demo](https://react-tools.ndria.dev/#/components/ShowMemoized)
 * @param {PropsWithChildren<{when: T|boolean|undefined|null, fallback?: ReactNode}>} object
 * @param {T|boolean|undefined|null} object.when - boolean indicating if to show _children_ or _fallback_/_null_.
 * @param {ReactNode} [object.fallback] - optional element to render when _when_ prop is false.
 * @param {PropsWithChildren<any>["children"]} [object.children] - optional element to render when _when_ prop is true.
 * @returns {JSX.Element|null} element - the element rendered or null.
 */
export declare const ShowMemoized: MemoExoticComponent<typeof Show>;

/**
 * **`SwitchCase`**: It works like switch-case construct. It useful for when there are more than 2 mutual exclusive conditions. [See demo](https://react-tools.ndria.dev/#/components/SwitchCase)
 * @param {Object} object - Object with _Switch_ and _Case_ components.
 * @returns {{Switch: (props:{children:ReactElement<CaseProps>|ReactElement<CaseProps>[], fallback?:ReactNode})=>JSX.Element|null, Case: (props:{children:ReactNode, when:booleaan|undefined|null})=>JSX.Element|null}}
 */
export declare const SwitchCase: {
    Switch: ({ children, fallback }: {
        children: ReactElement<PropsWithChildren<{
            when: boolean | null | undefined;
        }>, string | JSXElementConstructor<any>> | ReactElement<PropsWithChildren<{
            when: boolean | null | undefined;
        }>, string | JSXElementConstructor<any>>[];
        fallback?: ReactNode;
    }) => JSX_2.Element | null;
    Case: ({ children, when }: PropsWithChildren<{
        when: boolean | null | undefined;
    }>) => JSX_2.Element | null;
};

/**
 * **`SwitchCaseMemoized`**: Memoized version of _SwitchCase_ component. [See demo](https://react-tools.ndria.dev/#/components/SwitchCaseMemoized)
 * @param {Object} object - Object with _Switch_ and _Case_ components.
 * @returns {{Switch: (props:{children:ReactElement<CaseProps>|ReactElement<CaseProps>[], fallback?:ReactNode})=>JSX.Element|null, Case: (props:{children:ReactNode, when:booleaan|undefined|null})=>JSX.Element|null}}
 */
export declare const SwitchCaseMemoized: {
    Switch: MemoExoticComponent<({ children, fallback }: {
        children: ReactElement<PropsWithChildren<{
            when: boolean | null | undefined;
        }>, string | JSXElementConstructor<any>> | ReactElement<PropsWithChildren<{
            when: boolean | null | undefined;
        }>, string | JSXElementConstructor<any>>[];
        fallback?: ReactNode;
    }) => JSX_2.Element | null>;
    Case: MemoExoticComponent<({ children, when }: PropsWithChildren<{
        when: boolean | null | undefined;
    }>) => JSX_2.Element | null>;
};

export { }
