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

io.overcoded.vaadin.panel.Panel Maven / Gradle / Ivy

The newest version!
package io.overcoded.vaadin.panel;

import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.HasSize;
import com.vaadin.flow.component.HasStyle;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.icon.IconFactory;
import com.vaadin.flow.component.orderedlayout.FlexComponent;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.theme.lumo.LumoIcon;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;

import java.util.Objects;
import java.util.Optional;

@Tag("overcoded-panel")
public class Panel extends Component implements HasSize, HasStyle {
    private final Component summaryContainer;
    private final Div contentContainer;
    private final transient PanelConfig config;
    @Getter
    private Component summary;
    @Setter(AccessLevel.PRIVATE)
    private boolean opened;

    public Panel(String summaryText, Component content) {
        this(PanelConfig.builder().build(), summaryText, content);
    }

    public Panel(PanelType type, String summaryText, Component content) {
        this(Objects.requireNonNull(type).getConfig(), summaryText, content);
    }

    public Panel(PanelConfig config, String summaryText, Component content) {
        this.summaryContainer = createSummaryContainer();
        this.contentContainer = new Div();
        this.config = config;

        getElement().appendChild(summaryContainer.getElement().setAttribute("slot", "summary"));
        getElement().appendChild(contentContainer.getElement());

        setSummaryText(summaryText);
        setContent(content);

        configureLayout();
        configureContent();
        configureColoring();
    }

    public void setSummaryText(String summaryText) {
        setSummary(null, summaryText);
    }

    public void setSummary(IconFactory iconFactory, String summaryText) {
        this.summaryContainer.getElement().removeAllChildren();
        if (Objects.nonNull(summaryText)) {
            IconFactory nonNullIconFactory = Optional.ofNullable(iconFactory).orElse(config.getIcon());
            this.summary = createSummary(nonNullIconFactory, summaryText);
            this.summaryContainer.getElement().appendChild(summary.getElement());
        }
    }

    public void setContent(Component content) {
        contentContainer.getElement().removeAllChildren();
        if (content != null) {
            contentContainer.add(content);
        }
    }

    public void addContent(Component... components) {
        this.contentContainer.add(components);
    }

    protected Component createSummaryContainer() {
        return new PanelSummary();
    }

    private Component createSummary(IconFactory iconFactory, String summaryText) {
        HorizontalLayout layout = new HorizontalLayout();
        layout.setWidthFull();
        layout.setSpacing(false);
        layout.setAlignItems(FlexComponent.Alignment.CENTER);
        layout.getParent().ifPresent(component -> component.getElement().getStyle().set("flex-grow", "1"));

        Span title = new Span(Objects.nonNull(summaryText) ? summaryText : "");
        title.addClickListener(event -> toggleContent());
        Icon icon = iconFactory.create();
        icon.getStyle().set("width", config.getIconSize());
        icon.getStyle().set("height", config.getIconSize());

        HorizontalLayout infoBadge = new HorizontalLayout(icon);
        infoBadge.addClickListener(event -> toggleContent());
        infoBadge.setAlignItems(FlexComponent.Alignment.CENTER);
        infoBadge.setSpacing(false);
        infoBadge.getStyle().set("margin-right", config.getIconRightMargin());
        if (Objects.nonNull(config.getPrimaryColor()) && !config.getPrimaryColor().isBlank()) {
            infoBadge.getStyle().set("color", config.getPrimaryColor());
            title.getStyle().set("color", config.getPrimaryColor());
        }
        title.getStyle().set("font-size", config.getTitleFontSize());
        title.getStyle().set("font-weight", config.getTitleFontWeight());

        layout.add(infoBadge, title);
        layout.setFlexGrow(1, title);

        if (config.isCloseable()) {
            Button closeButton = new Button(LumoIcon.CROSS.create(), e -> setVisible(false));
            closeButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
            if (Objects.nonNull(config.getVariant())) {
                closeButton.addThemeVariants(config.getVariant());
            }
            layout.add(closeButton);
        }

        return layout;
    }

    private void configureLayout() {
        getStyle().set("padding", config.getPadding());
        getStyle().set("box-sizing", "border-box");

        setWidth(config.getWidth());
        if (config.isCollapsable()) {
            setOpened(config.isOpened());
        } else {
            setOpened(true);
        }
    }

    private void configureColoring() {
        if (Objects.nonNull(config.getBackgroundColor()) && !config.getBackgroundColor().isBlank()) {
            getStyle().set("background-color", config.getBackgroundColor());
        }
        if (Objects.nonNull(config.getPrimaryColor()) && !config.getPrimaryColor().isBlank()) {
            getStyle().set("border", "1px solid " + config.getPrimaryColor());
        }
        if (Objects.nonNull(config.getBorderRadius()) && !config.getBorderRadius().isBlank()) {
            getStyle().set("border-radius", config.getBorderRadius());
        }
    }

    private void configureContent() {
        if (Objects.nonNull(config.getPrimaryColor()) && !config.getPrimaryColor().isBlank()) {
            contentContainer.getElement().getStyle().set("color", config.getPrimaryColor());
        }
    }

    private void toggleContent() {
        opened = !opened;
        if (config.isCollapsable()) {
            contentContainer.setVisible(opened);
            contentContainer.setHeight(opened ? "auto" : "0px");
        }
    }

    @Tag("overcoded-panel-summary")
    static class PanelSummary extends Component {
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy