js/src/helpers/table-dropdown.helper.js

Summary

Maintainability
A
0 mins
Test Coverage
import $ from 'external/jquery';
import lodashThrottle from 'lodash/throttle';

/**
 * Simple helper to help displaying Fomantic-UI Dropdown within an atk table.
 * Because atk table use overflow: scroll, Dropdown is not
 * display on top of table.
 *
 * This utility will properly set CSS style for dropdown menu to be displayed correctly.
 */
function showTableDropdown() {
    // getting element composing dropdown
    const $that = $(this);
    const $menu = $(this).find('.menu');
    const position = $that.offset();
    const hasFloating = $that.hasClass('floating');

    /**
     * Check if menu fit below button.
     *
     * @returns {boolean}
     */
    function canFitBelow() {
        return $menu.outerHeight() < $(window).height() - $that[0].getBoundingClientRect().bottom;
    }

    /**
     * Set menu style for displaying at right position.
     */
    function setCssPosition() {
        // console.log(position.top, $that.scrollTop());
        let top = 0;
        let left = 0;
        // check if we need to place menu above or down button
        if (canFitBelow()) {
            top = position.top + $that.outerHeight();
            top = hasFloating ? top + 5 : top;
        } else {
            top = position.top - $menu.height();
            top = hasFloating ? top - 5 : top;
        }
        top -= $(window).scrollTop();
        left = position.left;

        const style = 'position: fixed; z-index: 12; top: 0px; margin-top: ' + top + 'px !important;'
            + ' left: ' + left + 'px !important; width: fit-content !important; height: fit-content; min-width: 12px;';
        $menu.css('cssText', style);
    }

    setCssPosition();
    $(window).on('scroll.atktable', lodashThrottle(setCssPosition, 10));
    $(window).on('resize.atktable', () => {
        $that.dropdown('hide');
    });
}

/**
 * Reset CSS and handler when hiding dropdown.
 */
function hideTableDropdown() {
    // reset positioning
    const $menu = $(this).find('.menu');
    $menu.css('cssText', '');
    $(window).off('scroll.atktable');
    $(window).off('resize.atktable');
}

export default {
    onShow: showTableDropdown,
    onHide: hideTableDropdown,
};