All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.dominokit.domino.ui.popover.Popover Maven / Gradle / Ivy

There is a newer version: 1.0.139
Show newest version
package org.dominokit.domino.ui.popover;

import elemental2.dom.*;
import org.dominokit.domino.ui.keyboard.KeyboardEvents;
import org.dominokit.domino.ui.modals.ModalBackDrop;
import org.dominokit.domino.ui.style.Elevation;
import org.dominokit.domino.ui.style.Styles;
import org.dominokit.domino.ui.utils.*;
import org.jboss.gwt.elemento.core.EventType;
import org.jboss.gwt.elemento.core.IsElement;

import java.util.ArrayList;
import java.util.List;

import static elemental2.dom.DomGlobal.document;
import static org.dominokit.domino.ui.popover.PopupPosition.TOP;
import static org.jboss.gwt.elemento.core.Elements.div;
import static org.jboss.gwt.elemento.core.Elements.h;

public class Popover extends BaseDominoElement implements Switchable {

    private static List currentVisible = new ArrayList<>();
    private final Text headerText;
    private final HTMLElement targetElement;

    private DominoElement element = DominoElement.of(div()
            .css("popover")
            .attr("role", "tooltip")
            .style("display: block;"))
            .elevate(Elevation.LEVEL_1);
    private DominoElement arrowElement = DominoElement.of(div().css("arrow"));
    private DominoElement headingElement = DominoElement.of(h(3).css("popover-title"));
    private DominoElement contentElement = DominoElement.of(div().css("popover-content"));

    private PopupPosition popupPosition = TOP;

    private boolean visible = false;

    private boolean closeOthers = true;
    private final EventListener showListener;
    private final EventListener closeListener;
    private boolean disabled = false;
    private String positionClass;
    private boolean closeOnEscp = true;
    private boolean closeOnScroll = true;

    private EventListener bodyClosListener = evt -> close();

    public Popover(HTMLElement target, String title, Node content) {
        this.targetElement = target;
        element.appendChild(arrowElement);
        element.appendChild(headingElement);
        element.appendChild(contentElement);
        headerText = TextNode.of(title);
        headingElement.appendChild(headerText);
        contentElement.appendChild(content);
        showListener = evt -> {
            evt.stopPropagation();
            show();
        };
        target.addEventListener(EventType.click.getName(), showListener);
        closeListener = evt -> closeAll();
        document.body.addEventListener(EventType.click.getName(), closeListener);
        element.addEventListener(EventType.click.getName(), Event::stopPropagation);
        ElementUtil.onDetach(targetElement, mutationRecord -> {
            if (visible) {
                close();
            }
            element.remove();
        });
        init(this);

        onDetached(mutationRecord -> {
            document.body.removeEventListener(EventType.keydown.getName(), closeListener);
        });
    }

    @Override
    public Popover show() {
        if (isEnabled()) {
            if (closeOthers) {
                closeOthers();
            }
            open(targetElement);
            element.style().setZIndex(ModalBackDrop.getNextZIndex());
            ModalBackDrop.push(this);
        }

        return this;
    }

    private void closeAll() {
        closeOthers();
    }

    private void closeOthers() {
        ModalBackDrop.closePopovers();
    }

    private void open(HTMLElement target) {
        if (visible) {
            close();
        } else {
            document.body.appendChild(element.element());
            element.style().remove("fade", "in");
            element.style().add("fade", "in");
            popupPosition.position(element.element(), target);
            position(popupPosition);
            visible = true;
            if (closeOnEscp) {
                KeyboardEvents.listenOn(document.body)
                        .onEscape(closeListener);
            }
        }
    }

    public void close() {
        element().remove();
        visible = false;
        document.body.removeEventListener(EventType.keydown.getName(), closeListener);
        ModalBackDrop.popPopOver();
    }

    public void discard() {
        close();
        targetElement.removeEventListener(EventType.click.getName(), showListener);
        document.removeEventListener(EventType.click.getName(), closeListener);
    }

    public static Popover createPicker(HTMLElement target, Node content) {
        Popover popover = new Popover(target, "", content);
        popover.getHeadingElement().style().setDisplay("none");
        popover.getContentElement().style().setProperty("padding", "0px");

        return popover;
    }

    public static Popover createPicker(IsElement target, IsElement content) {
        Popover popover = new Popover(target.element(), "", content.element());
        popover.getHeadingElement().style().setDisplay("none");
        popover.getContentElement().style().setProperty("padding", "0px");

        return popover;
    }

    public static Popover create(HTMLElement target, String title, Node content) {
        return new Popover(target, title, content);
    }

    public static Popover create(HTMLElement target, String title, IsElement content) {
        return new Popover(target, title, content.element());
    }

    public static Popover create(IsElement target, String title, Node content) {
        return new Popover(target.element(), title, content);
    }

    public static Popover create(IsElement target, String title, IsElement content) {
        return new Popover(target.element(), title, content.element());
    }

    public Popover position(PopupPosition position) {
        this.element.style().remove(this.positionClass);
        this.popupPosition = position;
        this.positionClass = position.getDirectionClass();
        this.element.style().add(this.positionClass);

        return this;
    }

    public Popover setCloseOthers(boolean closeOthers) {
        this.closeOthers = closeOthers;
        return this;
    }

    @Override
    public Popover enable() {
        this.disabled = false;
        return this;
    }

    @Override
    public Popover disable() {
        this.disabled = true;
        return this;
    }

    @Override
    public boolean isEnabled() {
        return !disabled;
    }

    public DominoElement getHeadingElement() {
        return headingElement;
    }

    public Popover closeOnEscp(boolean closeOnEscp) {
        this.closeOnEscp = closeOnEscp;
        return this;
    }

    public Popover closeOnScroll(boolean closeOnScroll) {
        this.closeOnScroll = closeOnScroll;
        return this;
    }

    @Override
    public HTMLDivElement element() {
        return element.element();
    }

    public DominoElement getContentElement() {
        return contentElement;
    }

    public Text getHeaderText() {
        return headerText;
    }

    public boolean isCloseOnScroll() {
        return closeOnScroll;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy