HybridMenu for Vaadin 24.9.0

I am including here the corrected code for HMButton and Notification to eliminate the deprecation warning on the use of Label component. Happy Coding !

import java.util.List;

import com.vaadin.flow.component.ClickEvent;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.ComponentEventListener;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.button.Button;

import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.shared.Tooltip;
import com.vaadin.flow.router.RouteConfiguration;

@SuppressWarnings("hiding")
public class HMButton extends Button implements MenuComponent<HMButton> {
	private static final long serialVersionUID = -2388630513509376470L;
    private Class<? extends Component> targetViewClass;
	
	private String navigateTo = null;
	
	private Icon icon = null;
	private Icon otherIcon = null;
	
	public static HMButton get() {
		return new HMButton("");
	}
	
	// Only for the left menu
	// The caption is not displayed in the left menu
	public HMButton(final String caption) {
		build(caption, null, null);
	}
	
	public HMButton(final Icon icon) {
		build(null, icon, null);
	}
	
	// Only for the left menu
	// The caption is not displayed in the left menu
	public HMButton(final String caption, final Icon icon) {
		build(caption, icon, null);
	}
	
	// Only for the left menu
	// The caption is not displayed in the left menu
	public HMButton(final String caption, final ComponentEventListener<ClickEvent<Button>> clickListener) {
		build(caption, null, clickListener);
	}
	
	public HMButton(final Icon icon, final ComponentEventListener<ClickEvent<Button>> clickListener) {
		build(null, icon, clickListener);
	}
	
	// Only for the left menu
	// The caption is not displayed in the top menu
	public HMButton(final String caption, final Icon icon, final ComponentEventListener<ClickEvent<Button>> clickListener) {
		build(caption, icon, clickListener);
	}
	
	private void build(final String caption, final Icon icon, final ComponentEventListener<ClickEvent<Button>> clickListener) {
		withCaption(caption);
		withIcon(icon);
		if (clickListener != null) {
			withClickListener(clickListener);
		}
	}
	
	// Only for the left menu
	// The caption is not displayed in the top menu
	public HMButton withCaption(final String caption) {
		super.setText(caption);
		return this;
	}
	
	public HMButton withStyleName(final String style) {
		getClassNames().add(style);
		return this;
	}
	
	public HMButton withIcon(final Icon icon) {
//		if (this.icon != null) {
			super.setIcon(icon);
//			remove(this.icon);
//			return this.
//		}
		
		this.icon = icon;
		
		if (icon != null) {
			setPrefixComponent(icon);
		}
		
		return this;
	}
	
	public HMButton withIcon(final VaadinIcon icon) {
		return withIcon(icon.create());
	}
	
	public HMButton withClickListener(final ComponentEventListener<ClickEvent<Button>> clickListener) {
		super.addClickListener(clickListener);
		return this;
	}
	
	public HMButton withDescription(final String description) {
		super.getElement().setAttribute("title", description);
		return this;
	}
	
	public <T extends Component> HMButton withNavigateTo(final Class<T> viewClass) {
		withNavigateTo(RouteConfiguration.forSessionScope().getUrl(viewClass));
		return this;
	}
	
	public <T extends Component> HMButton withNavigateTo(final String link) {
		navigateTo = link;
		return this.withClickListener(e -> UI.getCurrent().navigate(navigateTo));
	}
	
	// Only for the left menu
	public HMButton withOtherIcon(final VaadinIcon icon) {
		return withOtherIcon(icon.create());
	}
	
	// Only for the left menu
	public HMButton withOtherIcon(final Icon icon) {
		if (otherIcon != null) {
			otherIcon.getElement().removeFromParent();
		}
		otherIcon = icon;
		otherIcon.getClassNames().add(Styles.buttonOtherIcon);
		setSuffixComponent(icon);
		
		return this;
	}
	
	public HMButton withToolTip(final String toolTip) {
	    if (toolTip != null && !toolTip.isEmpty()) {
	        // Use Tooltip.forComponent() to attach a tooltip to the HMButton
	        Tooltip.forComponent(this).withText(toolTip);
	    } else {
	        removeToolTip();
	    }
	    return this;
	}
	
	public HMButton withToolTip(final int toolTip) {
	    if (toolTip > 0) {
	        withToolTip(String.valueOf(toolTip));
	    } else {
	        removeToolTip();
	    }
	    return this;
	}
	
	
	public HMButton removeToolTip() {
	    Tooltip tooltip = Tooltip.forComponent(this);
	    if (tooltip != null) {
	        tooltip.setOpened(false); // Set the tooltip to be not opened
	        tooltip.withText(""); // Optionally clear the text
	    }
	    return this;
	}
	
	public boolean isActive() {
		return getClassNames().contains(Styles.active);
	}
	
	public HMButton setActive(final boolean active) {
		if (isActive() != active) {
			if (active) {
				getClassNames().add(Styles.active);
			} else {
				getClassNames().remove(Styles.active);
			}
		}
		return this;
	}
	
	public String getNavigateTo() {
		return navigateTo;
	}
	
    public void setTargetViewClass(Class<? extends Component> targetViewClass) {
        this.targetViewClass = targetViewClass;
    }
	
    @Override
    public Class<? extends Component> getTargetViewClass() {
        return targetViewClass;
    }	
	@Override
	public <MenuComponent extends Component> MenuComponent add(final MenuComponent c) {
		return null;
	}

	@Override
	public <MenuComponent extends Component> MenuComponent addAsFirst(final MenuComponent c) {
		return null;
	}

	@Override
	public <MenuComponent extends Component> MenuComponent addAt(final MenuComponent c, final int index) {
		return null;
	}

	@Override
	public int count() {
		return 0;
	}

	@Override
	public <MenuComponent extends Component> HMButton remove(final MenuComponent c) {
		return null;
	}

	@Override
	public List<MenuComponent<?>> getList() {
		return null;
	}
}


import java.util.Date;

import org.ocpsoft.prettytime.PrettyTime;

import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.server.VaadinSession;

public class Notification extends Div {
	private static final long serialVersionUID = 3572068667525046443L;
	
	private MenuConfig menuConfig = VaadinSession.getCurrent().getAttribute(MenuConfig.class);
	
	private Span title = new Span(); // Use Span instead of Label
	private Span timeAgo = new Span(); // Use Span instead of Label
	private Span content = new Span(); // Use Span instead of Label

	private Button removeButton = null;
	
	private VaadinIcon icon = null;
	
	private long created = 0L;
	private long removeDisplayOffset = 0L;
	private long displayTime = menuConfig.getNotificationDisplayTime();
	
	private boolean readed = false;
	
	public static Notification get() {
		return new Notification();
	}
	
	public Notification() {
		created = System.currentTimeMillis();
	}
	
	public Notification withCloseable() {
		removeButton = new Button(menuConfig.getNotificationRemoveIcon().create());
		removeButton.getClassNames().add("button");
		return this;
	}
	
	public Notification withDisplayTime(long displayTime) {
		if (removeDisplayOffset == this.displayTime) {
			removeDisplayOffset = displayTime;
		}
		this.displayTime = displayTime;
		return this;
	}
	
	public long getDisplayTime() {
		return displayTime;
	}
	
	public Notification withAutoRemove() {
		this.removeDisplayOffset = displayTime;
		return this;
	}
	
	public Notification withAutoRemove(long removeDisplayOffset) {
		this.removeDisplayOffset = removeDisplayOffset;
		return this;
	}
	
	public Notification withTitle(String title) {
		this.title.setText(title);
		return this;
	}
	
	public Notification withContent(String content) {
		this.content.setText(content);
		return this;
	}
	
	public Notification withIcon(VaadinIcon icon) {
		this.icon = icon;
		return this;
	}
	
	public boolean isReaded() {
		return readed;
	}
	
	public Notification makeAsReaded() {
		readed = true;
		return this;
	}
	
	public Notification build(NotificationCenter notificationCenter, UI ui) {
		if (icon != null) {
			getClassNames().add("withIcon");
			add(icon.create());
		}
		
		getClassNames().add("notification");
		add(title, timeAgo, content);
		
		title.getClassNames().add("title");
		timeAgo.getClassNames().add("timeAgo");
		content.getClassNames().add("content");
		
		if (removeButton != null) {
			removeButton.addClickListener(e -> notificationCenter.remove(this));
			add(removeButton);
		}
		
		timeAgo.setText(new PrettyTime(ui.getLocale()).format(new Date(created)));
		
		if (removeDisplayOffset > 0L) {
			notificationCenter.runOneAttached(this, () -> notificationCenter.remove(this), removeDisplayOffset);
		}
		return this;
	}
	
	public void update(UI ui) {
		timeAgo.setText(new PrettyTime(ui.getLocale()).format(new Date(created)));
	}
	
	@Override
	public Notification clone() {
		Notification notification = new Notification();
		notification.withContent(content.getText());
		notification.withTitle(title.getText());
		notification.withDisplayTime(displayTime);
		notification.withIcon(icon);
		notification.created = created;
		return notification;
	}
}