toggleDrop = root => {
    const isAllowed = root.query('GET_ALLOW_DROP');
    const isDisabled = root.query('GET_DISABLED');
    const enabled = isAllowed && !isDisabled;
    if (enabled && !root.ref.hopper) {
        const hopper = createHopper(
            root.element,
            items => {
                // allow quick validation of dropped items
                const beforeDropFile = root.query('GET_BEFORE_DROP_FILE') || (() => true);

                // all items should be validated by all filters as valid
                const dropValidation = root.query('GET_DROP_VALIDATION');
                return dropValidation
                    ? items.every(
                          item =>
                              applyFilters('ALLOW_HOPPER_ITEM', item, {
                                  query: root.query,
                              }).every(result => result === true) && beforeDropFile(item)
                      )
                    : true;
            },
            {
                filterItems: items => {
                    const ignoredFiles = root.query('GET_IGNORED_FILES');
                    return items.filter(item => {
                        if (isFile(item)) {
                            return !ignoredFiles.includes(item.name.toLowerCase());
                        }
                        return true;
                    });
                },
                catchesDropsOnPage: root.query('GET_DROP_ON_PAGE'),
                requiresDropOnElement: root.query('GET_DROP_ON_ELEMENT'),
            }
        );

        hopper.onload = (items, position) => {
            // get item children elements and sort based on list sort
            const list = root.ref.list.childViews[0];
            const visibleChildren = list.childViews.filter(child => child.rect.element.height);
            const children = root
                .query('GET_ACTIVE_ITEMS')
                .map(item => visibleChildren.find(child => child.id === item.id))
                .filter(item => item);

            applyFilterChain('ADD_ITEMS', items, { dispatch: root.dispatch }).then(queue => {
                // these files don't fit so stop here
                if (exceedsMaxFiles(root, queue)) return false;

                // go
                root.dispatch('ADD_ITEMS', {
                    items: queue,
                    index: getDragIndex(root.ref.list, children, position),
                    interactionMethod: InteractionMethod.DROP,
                });
            });

            root.dispatch('DID_DROP', { position });

            root.dispatch('DID_END_DRAG', { position });
        };

        hopper.ondragstart = position => {
            root.dispatch('DID_START_DRAG', { position });
        };

        hopper.ondrag = debounce(position => {
            root.dispatch('DID_DRAG', { position });
        });

        hopper.ondragend = position => {
            root.dispatch('DID_END_DRAG', { position });
        };

        root.ref.hopper = hopper;

        root.ref.drip = root.appendChildView(root.createChildView(drip));
    } else if (!enabled && root.ref.hopper) {
        root.ref.hopper.destroy();
        root.ref.hopper = null;
        root.removeChildView(root.ref.drip);
    }
}
Enable or disable file drop functionality