How to collapse all other SideNav menus when one is expanded

I have a left navigation area composed of several SideNav components. When one is expanded I want to automatically close all other expanded SideNav menus.

I can’t find a way to do this. there is no click/expand listener on the SideNav component.

Is there a way to achieve this?

You can listen with Element#addPropertyChangeListener to changes of a property. In this case expanded.
This worked for me with client sided click and a server sided SideNavItem#setExpanded.

I created the addItem method to not have duplicated code.

    private SideNav sideNav = new SideNav("Side Nav");

    /* flow skeleton starter */
    public MainView() {

        // create items
        SideNavItem messagesLink = new SideNavItem("Messages", MainView.class, VaadinIcon.ENVELOPE.create());
        messagesLink.addItem(new SideNavItem("Inbox", MainView.class, VaadinIcon.INBOX.create()));
        messagesLink.addItem(new SideNavItem("Sent", MainView.class, VaadinIcon.PAPERPLANE.create()));
        messagesLink.addItem(new SideNavItem("Trash", MainView.class, VaadinIcon.TRASH.create()));
        SideNavItem adminSection = new SideNavItem("Admin");
        adminSection.addItem(new SideNavItem("Users", MainView.class, VaadinIcon.GROUP.create()));
        adminSection.addItem(new SideNavItem("Permissions", MainView.class, VaadinIcon.KEY.create()));
        SideNavItem testSection = new SideNavItem("Test");
        testSection.addItem(new SideNavItem("Test", MainView.class, VaadinIcon.GROUP.create()));
        testSection.addItem(new SideNavItem("Test", MainView.class, VaadinIcon.KEY.create()));

        addItem(messagesLink, adminSection, testSection);
        add(new Button("Expand last item", e -> testSection.setExpanded(true)));

     * add to nav bar and add listener
    private void addItem(SideNavItem... items) {
        for (SideNavItem item : items) {
            // listen to expanded changed on client
            item.getElement().addPropertyChangeListener("expanded", this::collapseItems);

     * handle change
    private void collapseItems(PropertyChangeEvent event) {
        final Element currentlyChangedItem = event.getSource();
        Object newPropValue = event.getValue();
        // collapse only if opened
        if (Boolean.TRUE.equals(newPropValue)) {
            sideNav.getChildren().filter(item -> {
                // do not collapse item that triggered event
                return !item.getElement().equals(currentlyChangedItem) && item instanceof SideNavItem;
            }).forEach(item -> ((SideNavItem) item).setExpanded(false));
1 Like