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

org.dominokit.domino.ui.tree.Tree Maven / Gradle / Ivy

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

import elemental2.dom.*;
import org.dominokit.domino.ui.icons.Icon;
import org.dominokit.domino.ui.icons.Icons;
import org.dominokit.domino.ui.search.Search;
import org.dominokit.domino.ui.style.ColorScheme;
import org.dominokit.domino.ui.style.Styles;
import org.dominokit.domino.ui.style.Unit;
import org.dominokit.domino.ui.utils.BaseDominoElement;
import org.dominokit.domino.ui.utils.DominoElement;
import org.dominokit.domino.ui.utils.ParentTreeItem;
import org.jboss.elemento.IsElement;

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

import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
import static org.jboss.elemento.Elements.*;

public class Tree extends BaseDominoElement> implements ParentTreeItem>, IsElement {

    private HTMLElement title = span().css("title").element();
    private ToggleTarget toggleTarget = ToggleTarget.ANY;
    private TreeItemFilter> filter = (treeItem, searchToken) -> treeItem.getTitle().toLowerCase().contains(searchToken.toLowerCase());

    private HTMLLIElement header = li()
            .css("header")
            .css("menu-header")
            .add(title)
            .element();

    private HTMLUListElement root = ul()
            .add(header)
            .css("list")
            .element();

    private HTMLDivElement menu = div().style("overflow-x: hidden")
            .css("menu")
            .add(root)
            .element();


    private final int nextLevel = 1;

    private TreeItem activeTreeItem;

    private boolean autoCollapse = true;
    private List> subItems = new ArrayList<>();
    private boolean autoExpandFound;
    private ColorScheme colorScheme;
    private Search search;
    private Icon searchIcon;
    private Icon collapseAllIcon;
    private Icon expandAllIcon;

    private T value;

    private final List> itemsClickListeners = new ArrayList<>();

    public Tree() {
        this("");
    }

    public Tree(String treeTitle) {
        init(this);
        if (isNull(treeTitle) || treeTitle.trim().isEmpty()) {
            DominoElement.of(header)
                    .hide();
        }
        title.textContent = treeTitle;
    }

    public Tree(String treeTitle, T value) {
        this(treeTitle);
        this.value = value;
    }

    public Tree(T value) {
        this("");
        this.value = value;
    }

    public static Tree create(String title) {
        Tree tree = new Tree<>(title);
        return tree;
    }

    public static Tree create() {
        Tree tree = new Tree<>();
        DominoElement.of(tree.header)
                .hide();
        return tree;
    }

    public static  Tree create(String title, T value) {
        Tree tree = new Tree<>(title, value);
        return tree;
    }

    public static  Tree create(T value) {
        Tree tree = new Tree<>(value);
        return tree;
    }

    public Tree appendChild(TreeItem treeItem) {
        root.appendChild(treeItem.element());
        treeItem.setParent(this);
        treeItem.setLevel(nextLevel);
        treeItem.setToggleTarget(this.toggleTarget);
        this.subItems.add(treeItem);
        return this;
    }

    public Tree addSeparator() {
        root.appendChild(li()
                .css("gap")
                .css("separator")
                .add(a())
                .element());
        return this;
    }

    public Tree addGap() {
        root.appendChild(li()
                .css("gap")
                .add(a())
                .element());
        return this;
    }

    public Tree setToggleTarget(ToggleTarget toggleTarget) {
        if (nonNull(toggleTarget)) {
            subItems.forEach(item -> item.setToggleTarget(toggleTarget));
            this.toggleTarget = toggleTarget;
        }
        return this;
    }

    public Tree setColorScheme(ColorScheme colorScheme) {
        if (nonNull(this.colorScheme)) {
            style.remove(colorScheme.color().getBackground());
            DominoElement.of(header).style().remove(this.colorScheme.darker_3().getBackground());
        }
        this.colorScheme = colorScheme;

        style.add(colorScheme.color().getBackground());
        DominoElement.of(header).style().add(this.colorScheme.darker_3().getBackground());

        return this;
    }


    @Override
    public TreeItem getActiveItem() {
        return activeTreeItem;
    }

    @Override
    public void setActiveItem(TreeItem activeItem) {
        setActiveItem(activeItem, false);
    }

    @Override
    public void setActiveItem(TreeItem activeItem, boolean silent) {
        if (nonNull(this.activeTreeItem) && !this.activeTreeItem.equals(activeItem)) {
            this.activeTreeItem.deactivate();
        }

        this.activeTreeItem = activeItem;
        this.activeTreeItem.activate();
        if (!silent) {
            onTreeItemClicked(activeItem);
        }
    }

    public DominoElement getHeader() {
        return DominoElement.of(header);
    }

    public DominoElement getRoot() {
        return DominoElement.of(root);
    }

    public DominoElement getTitle() {
        return DominoElement.of(title);
    }

    public Tree autoHeight() {
        root.style.height = CSSProperties.HeightUnionType.of("calc(100vh - 83px)");
        element().style.height = CSSProperties.HeightUnionType.of("calc(100vh - 70px)");
        return this;
    }

    public Tree autoHeight(int offset) {
        root.style.height = CSSProperties.HeightUnionType.of("calc(100vh - " + offset + 13 + "px)");
        element().style.height = CSSProperties.HeightUnionType.of("calc(100vh - " + offset + "px)");
        return this;
    }

    public Tree enableSearch() {
        search = Search.create(true)
                .styler(style -> style.setHeight(Unit.px.of(40)))
                .onSearch(Tree.this::filter)
                .onClose(this::clearFilter);

        searchIcon = Icons.ALL.search()
                .style()
                .setMarginBottom("0px")
                .setMarginTop("0px")
                .add(Styles.pull_right)
                .setProperty("cursor", "pointer")
                .get();

        this.header.appendChild(search.element());
        this.header.appendChild(searchIcon.element());
        searchIcon.element().addEventListener("click", evt -> search.open());

        return this;
    }

    public Tree enableFolding() {
        collapseAllIcon = Icons.ALL.fullscreen_exit()
                .style()
                .setMarginBottom("0px")
                .setMarginTop("0px")
                .add(Styles.pull_right)
                .setProperty("cursor", "pointer")
                .get();

        collapseAllIcon.element().addEventListener("click", evt -> collapseAll());


        expandAllIcon = Icons.ALL.fullscreen()
                .style()
                .setMarginBottom("0px")
                .setMarginTop("0px")
                .add(Styles.pull_right)
                .setProperty("cursor", "pointer")
                .get();

        expandAllIcon.element().addEventListener("click", evt -> expandAll());

        header.appendChild(expandAllIcon.element());
        header.appendChild(collapseAllIcon.element());
        return this;
    }

    public void expandAll() {
        getSubItems().forEach(TreeItem::expandAll);
    }

    public void collapseAll() {
        getSubItems().forEach(TreeItem::collapseAll);
    }

    public void deactivateAll() {
        getSubItems().forEach(TreeItem::deactivate);
    }

    public Tree autoExpandFound() {
        this.autoExpandFound = true;
        return this;
    }

    @Override
    public boolean isAutoExpandFound() {
        return autoExpandFound;
    }

    public void setAutoExpandFound(boolean autoExpandFound) {
        this.autoExpandFound = autoExpandFound;
    }

    public void clearFilter() {
        subItems.forEach(TreeItem::clearFilter);
    }

    public void filter(String searchToken) {
        subItems.forEach(treeItem -> treeItem.filter(searchToken));
    }

    @Override
    public Tree getTreeRoot() {
        return this;
    }

    public Tree setAutoCollapse(boolean autoCollapse) {
        this.autoCollapse = autoCollapse;
        return this;
    }

    public Tree setTitle(String title) {
        getTitle().setTextContent(title);
        if (getHeader().isHidden()) {
            getHeader().show();
        }
        return this;
    }

    public boolean isAutoCollapse() {
        return autoCollapse;
    }

    @Override
    public List> getSubItems() {
        return new ArrayList<>(subItems);
    }

    public ParentTreeItem expand(boolean expandParent) {
        return this;
    }

    public ParentTreeItem expand() {
        return this;
    }

    @Override
    public Optional> getParent() {
        return Optional.empty();
    }

    @Override
    public void activate() {

    }

    @Override
    public void activate(boolean activateParent) {

    }

    public Search getSearch() {
        return search;
    }

    public Icon getSearchIcon() {
        return searchIcon;
    }

    public Icon getCollapseAllIcon() {
        return collapseAllIcon;
    }

    public Icon getExpandAllIcon() {
        return expandAllIcon;
    }

    public T getValue() {
        return value;
    }

    public void setValue(T value) {
        this.value = value;
    }

    public Tree addItemClickListener(ItemClickListener itemClickListener) {
        this.itemsClickListeners.add(itemClickListener);
        return this;
    }

    public Tree removeItemClickListener(ItemClickListener itemClickListener) {
        this.itemsClickListeners.remove(itemClickListener);
        return this;
    }

    void onTreeItemClicked(TreeItem treeItem) {
        this.itemsClickListeners.forEach(itemClickListener -> itemClickListener.onTreeItemClicked(treeItem));
    }

    public List> getActivePath() {
        List> activeItems = new ArrayList<>();
        TreeItem activeItem = getActiveItem();
        while (nonNull(activeItem)) {
            activeItems.add(activeItem);
            activeItem = activeItem.getActiveItem();
        }

        return activeItems;
    }

    public List getActivePathValues() {
        List activeValues = new ArrayList<>();
        TreeItem activeItem = getActiveItem();
        while (nonNull(activeItem)) {
            activeValues.add(activeItem.getValue());
            activeItem = activeItem.getActiveItem();
        }

        return activeValues;
    }

    @Override
    public void removeItem(TreeItem item) {
        subItems.remove(item);
        item.remove();
    }

    public Tree setFilter(TreeItemFilter> filter) {
        this.filter = filter;
        return this;
    }

    @Override
    public TreeItemFilter> getFilter() {
        return this.filter;
    }

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

    public interface ItemClickListener {
        void onTreeItemClicked(TreeItem treeItem);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy