Span with number of items attached to Button

Hi!
In this example: https://vaadin.com/docs/latest/components/notification#use-sparingly

You are adding a Span containing number of notifications to a Button:
bellBtn.getElement().appendChild(numberOfNotifications.getElement());

In the javadoc for .getElement() you stated:

If you see a direct call to this method in your applications UI code, you should consider that as a sign that you are probably doing something wrong and you should instead use other methods from your component

And I am wondering how should we tackle this without .getElement() and .append() for those components.
I would like this span to increment/decrement when the number of items changes, respectively to disappear when it is 0.
What do you recommend in this case?

Just use .add

@quintessential-ibex you gonna love this docs page :crazy_face:

I’m a bit confused, Button class does not have an add() method.
Were you thinking about adding both the button and span to a HorizontalLayout? Or adding the button to the span and treating the span as “the button”?

No, I was really expecting the button to have an add method :grimacing: damn that is clunky… the above way with getElement is sadly the way to go for now

I implemented it that way on my side but I got an issue when trying to remove the Span from the Button. The case when there are no more notifications and the Span must disappear.
I don’t see any method on the Button to update the whole list of children Elements.
I was thinking about getting the children with new ArrayList<>(button.getElement().getChildren()) as Elements or new ArrayList<>(notificationsButton.getChildren().toList()) as Components, remove the Span by className, put the list back and refresh the UI.
I also tried to set visibility for the span to false, but seems to break the button on refresh (and sometimes the whole UI).

Just remove the text and themes from the span making it literally invisible

I tried, but I can’t replace it inside the button. If I keep appending Spans I’ll create a memory leak in the long run.

No, not appending - just updating the existing one

And keep its scope at class level?

Yeah

I would probably create a NotificationButton and expose a method to increase / decrease / hide the span within

For context, I have a NotificationButton which opens a Dialog containing a grid with notifications.
I declared both the button and span at class level and attached the span during view + hidden grid refresh. I check the number of notifications using the service and make the span visibility false when it returns 0 and true when > 0 (and set the span value). I have a broadcaster which fires grid refresh events when the repository saves/deletes notifications.
It worked as expected, finally

Thanks for your help!

I think you can use new Button(span), like here: Button | Components | Vaadin Docs

But yes the doc page needs a small update :zipper_mouth_face:

In my case, I used button with a bell icon and Span on top when notifications are available, but thank you tho :slightly_smiling_face:

new Button(span) would add it to the icon slot, which would remove the span from the Screenreader announcement cause the icon slot has aria-hidden

I think I’m using a NativeButton for this, but I don’t remember if it’s coming from the framework or if it’s a custom class

Create a component, hide the getElement usage there, behind a proper API. Like this (made a PR to improve that example): Improvements to Notification examples by mstahv · Pull Request #2851 · vaadin/docs · GitHub