/// <reference types="react" />
import React from 'react';
type ReactProps = Object;

type DroppableType =
    string |
    symbol |
    Array<string | symbol> |
    ((props: ReactProps) => string | symbol | Array<string | symbol>);

type DroppableSpec = {
    drop?: (
        props: ReactProps,
        monitor: DroppableMonitor,
        component: React.ReactNode
    ) => null | Object;

    hover?: (
        props: ReactProps,
        monitor: DroppableMonitor,
        component?: React.ReactNode
    ) => void;

    canDrop?: (
        props: ReactProps,
        monitor: DroppableMonitor
    ) => boolean;
};

type DroppableOptions = {
    arePropsEqual?: (Object, Object) => boolean
};

type DroppableConnector = {
    dropTarget: () => (elementOrNode: HTMLElement | React.ReactNode) => React.ReactNode,
}

type Offset = { x: number, y: number };

type DroppableMonitor = {
    canDrag: () => boolean;
    isOver: (options?: { shallow?: boolean }) => boolean;
    getItemType: () => null | DroppableType;
    getItem: () => null | Object;
    getDropResult: () => null | Object;
    didDrop: () => boolean;
    getInitialClientOffset: () => null | Offset;
    getInitialSourceClientOffset: () => null | Offset;
    getClientOffset: () => null | Offset;
    getDifferenceFromInitialOffset: () => null | Offset;
    getSourceClientOffset: () => null | Offset;
}

export interface DroppableProps {
    acceptTypes: DroppableType;
    spec?: DroppableSpec;
    collect?: (connect: DroppableConnector, monitor: DroppableMonitor) => Object;
    options?: DroppableOptions;
    render?: ({ item: Object, canDrop: boolean, isOver: boolean, isDragIn: boolean, isDragOut: boolean, otherDragProps }) => React.ReactNode;
}

export default class Droppable extends React.Component<DroppableProps, any>{
    render(): JSX.Element;
}