io.overcoded.vaadin.panel.Panel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of panel-for-vaadin Show documentation
Show all versions of panel-for-vaadin Show documentation
Configurable panel for Vaadin.
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 {
}
}