java.lang.Object
com.vaadin.flow.component.Component
com.vaadin.flow.component.sidenav.SideNav
org.vaadin.addons.componentfactory.sidenavrail.SideNavRail
All Implemented Interfaces:
com.vaadin.flow.component.AttachNotifier, com.vaadin.flow.component.DetachNotifier, com.vaadin.flow.component.HasElement, com.vaadin.flow.component.HasSize, com.vaadin.flow.component.HasStyle, com.vaadin.flow.component.sidenav.HasSideNavItems, Serializable

@CssImport("./side-nav-rail.css") @JsModule("./side-nav-rail.js") public class SideNavRail extends com.vaadin.flow.component.sidenav.SideNav
A SideNav that can be switched into a compact icon-only rail mode and shows a hover popover for items with children. The item tree must be built from SideNavRailItems; addItem(SideNavItem...) rejects a plain SideNavItem with an IllegalArgumentException, because only SideNavRailItem carries the CSS label-wrap and popover-gating wiring.

The component toggles between two visual states:

  • Normal mode — behaves like a standard SideNav.
  • Rail mode — the theme="rail" attribute is set on the root element and bundled CSS collapses the nav to a narrow icon-only column. Inline expansion state is preserved (just visually suppressed) and restored when switching back.

Typical usage inside a layout:


 SideNavRail rail = new SideNavRail();
 rail.addItem(new SideNavRailItem("Dashboard", DashboardView.class, VaadinIcon.DASHBOARD.create()));
 // ...
 Button toggle = new Button("Rail", e -> rail.setRailMode(!rail.isRailMode()));
 

The component does not ship with a toggle button — applications integrate one where it fits their layout. This is intentional: auto-collapse, persistent state, and responsive breakpoint handling are the application's concern.

See Also:
  • Nested Class Summary

    Nested classes/interfaces inherited from class com.vaadin.flow.component.sidenav.SideNav

    com.vaadin.flow.component.sidenav.SideNav.SideNavI18n
  • Constructor Summary

    Constructors
    Constructor
    Description
    Creates an unlabelled rail.
    Creates a rail with a header label.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    addItem(com.vaadin.flow.component.sidenav.SideNavItem... items)
    void
    addItemAsFirst(com.vaadin.flow.component.sidenav.SideNavItem item)
    void
    addItemAtIndex(int index, com.vaadin.flow.component.sidenav.SideNavItem item)
    com.vaadin.flow.shared.Registration
    addRailModeChangedListener(com.vaadin.flow.component.ComponentEventListener<RailModeChangedEvent> listener)
    Registers a listener for RailModeChangedEvent.
    The first match from getActiveViewItems(), or empty if no item matches.
    Returns all rail items whose own path (or any of their path aliases) equals the current view's location.
    The current header mode for popovers.
    int
    The hide delay (ms) after the pointer leaves the target before the popover closes.
    int
    The hover delay (ms) before the popover opens.
    The current popover mode.
    com.vaadin.flow.component.popover.PopoverPosition
    The position the popover opens at relative to its item.
    The current rail-tooltip mode.
    The current RootMatchNested mode.
    boolean
    Whether nested items are rendered only inside the hover popover, never inline below their parent.
    boolean
    Whether the rail currently asks SideNavRailItem to create a popover for a leaf (childless) root item, so the popover can act as a Vaadin-themed tooltip.
    boolean
    Whether each popover renders the small Lumo arrow pointing back at its target item.
    boolean
    Whether the popover header is rendered only while the rail is in rail mode.
    boolean
    Whether the rail is currently in icon-only mode.
    protected void
    onAttach(com.vaadin.flow.component.AttachEvent attachEvent)
     
    protected void
    onDetach(com.vaadin.flow.component.DetachEvent detachEvent)
     
    void
    setChildrenOnlyInPopover(boolean enabled)
    Switches between the standard inline-and-popover layout for nested items (false, default) and a popover-only layout (true).
    void
    setPopoverArrowVisible(boolean visible)
    Sets whether each popover renders the small Lumo arrow pointing back at its target item.
    void
    Sets whether (and how) each popover renders a header identifying the owning item.
    void
    setPopoverHeaderOnlyInRailMode(boolean onlyInRailMode)
    Restricts the popover header to rail mode, or allows it in both modes.
    void
    setPopoverHideDelay(int hideDelayMs)
    Sets the hide delay (ms) after the pointer leaves the target before the popover closes.
    void
    setPopoverHoverDelay(int hoverDelayMs)
    Sets the hover delay (ms) before the popover opens.
    void
    Sets the popover mode.
    void
    setPopoverPosition(com.vaadin.flow.component.popover.PopoverPosition position)
    Sets the popover position.
    void
    setRailMode(boolean railMode)
    Switches the rail between normal mode and icon-only rail mode.
    void
    Controls how root items surface their label while the rail is in rail mode.
    void
    Sets the RootMatchNested mode.
    void
    Switches the rail between normal mode and icon-only rail mode.

    Methods inherited from class com.vaadin.flow.component.sidenav.SideNav

    getI18n, getLabel, isCollapsible, isExpanded, setCollapsible, setExpanded, setI18n, setLabel

    Methods inherited from class com.vaadin.flow.component.Component

    addListener, findAncestor, fireEvent, from, get, getChildren, getElement, getEventBus, getId, getListeners, getLocale, getParent, getTranslation, getTranslation, getTranslation, getTranslation, getTranslation, getTranslation, getUI, hasListener, isAttached, isTemplateMapped, isVisible, onEnabledStateChanged, removeFromParent, scrollIntoView, scrollIntoView, set, setElement, setId, setVisible

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

    Methods inherited from interface com.vaadin.flow.component.AttachNotifier

    addAttachListener

    Methods inherited from interface com.vaadin.flow.component.DetachNotifier

    addDetachListener

    Methods inherited from interface com.vaadin.flow.component.HasElement

    getElement

    Methods inherited from interface com.vaadin.flow.component.sidenav.HasSideNavItems

    getItems, remove, removeAll

    Methods inherited from interface com.vaadin.flow.component.HasSize

    getHeight, getHeightUnit, getMaxHeight, getMaxWidth, getMinHeight, getMinWidth, getWidth, getWidthUnit, setHeight, setHeight, setHeightFull, setMaxHeight, setMaxHeight, setMaxWidth, setMaxWidth, setMinHeight, setMinHeight, setMinWidth, setMinWidth, setSizeFull, setSizeUndefined, setWidth, setWidth, setWidthFull

    Methods inherited from interface com.vaadin.flow.component.HasStyle

    addClassName, addClassNames, getClassName, getClassNames, getStyle, hasClassName, removeClassName, removeClassNames, setClassName, setClassName
  • Constructor Details

    • SideNavRail

      public SideNavRail()
      Creates an unlabelled rail.
    • SideNavRail

      public SideNavRail(String label)
      Creates a rail with a header label. See SideNav.setLabel(String) for the semantics — the label renders above the item list and can be used to group multiple SideNav instances visually.
      Parameters:
      label - the header label rendered above the item list; may be null for an unlabelled rail
  • Method Details

    • onAttach

      protected void onAttach(com.vaadin.flow.component.AttachEvent attachEvent)
      Overrides:
      onAttach in class com.vaadin.flow.component.Component
    • onDetach

      protected void onDetach(com.vaadin.flow.component.DetachEvent detachEvent)
      Overrides:
      onDetach in class com.vaadin.flow.component.Component
    • toggleRailMode

      public void toggleRailMode()
      Switches the rail between normal mode and icon-only rail mode. Fires a RailModeChangedEvent.
    • setRailMode

      public void setRailMode(boolean railMode)
      Switches the rail between normal mode and icon-only rail mode. No-op if the state is unchanged; otherwise fires a RailModeChangedEvent.
      Parameters:
      railMode - true to enter rail mode (icon-only), false to return to normal mode (full-width with labels)
    • isRailMode

      public boolean isRailMode()
      Whether the rail is currently in icon-only mode.
      Returns:
      true if the rail is in rail mode, false in normal mode
    • getPopoverOn

      public PopoverOn getPopoverOn()
      The current popover mode. Default: PopoverOn.ALL_COLLAPSED_ITEMS. See PopoverOn for the full behaviour matrix.
      Returns:
      the active PopoverOn; never null
    • setPopoverOn

      public void setPopoverOn(PopoverOn mode)
      Sets the popover mode. Rewires all child items' popover eligibility immediately so open popovers that are no longer eligible close right away.

      Has no effect on root items with children while setChildrenOnlyInPopover(boolean) is enabled — that mode forces the popover on regardless of this setting.

      Parameters:
      mode - the new PopoverOn; must not be null
      Throws:
      NullPointerException - if mode is null
    • getPopoverHeaderMode

      public PopoverHeaderMode getPopoverHeaderMode()
      The current header mode for popovers. Default: PopoverHeaderMode.LABEL_ONLY. See PopoverHeaderMode for the rendering rules per value.
      Returns:
      the active PopoverHeaderMode; never null
    • setPopoverHeaderMode

      public void setPopoverHeaderMode(PopoverHeaderMode mode)
      Sets whether (and how) each popover renders a header identifying the owning item. Rebuilds the content of all existing popovers so the change is visible immediately.

      The header is rail-mode-only by default — see setPopoverHeaderOnlyInRailMode(boolean) to also show it in normal mode (e.g. together with setChildrenOnlyInPopover(boolean)).

      Parameters:
      mode - the new PopoverHeaderMode; must not be null
      Throws:
      NullPointerException - if mode is null
    • isPopoverHeaderOnlyInRailMode

      public boolean isPopoverHeaderOnlyInRailMode()
      Whether the popover header is rendered only while the rail is in rail mode. Default: true (header is hidden in normal mode, where the item's label is already visible inline). Has no effect while the header mode is PopoverHeaderMode.NONE.
      Returns:
      true if the header is restricted to rail mode, false if it is rendered in both modes
    • setPopoverHeaderOnlyInRailMode

      public void setPopoverHeaderOnlyInRailMode(boolean onlyInRailMode)
      Restricts the popover header to rail mode, or allows it in both modes. Default: true. Useful in combination with setChildrenOnlyInPopover(boolean), where the popover is the only place children appear even in normal mode and an item-identifying header may still be desired.

      Has no visible effect while getPopoverHeaderMode() is PopoverHeaderMode.NONE. Rebuilds the content of all existing popovers so the change is visible immediately.

      Parameters:
      onlyInRailMode - true to render the header only in rail mode, false to render it in both modes
    • getRailTooltipMode

      public RailTooltipMode getRailTooltipMode()
      The current rail-tooltip mode. Default: RailTooltipMode.POPOVER_HEADER. Tooltips are only shown while the rail is in rail mode; see RailTooltipMode for the per-value semantics.
      Returns:
      the active RailTooltipMode; never null
    • setRailTooltipMode

      public void setRailTooltipMode(RailTooltipMode mode)
      Controls how root items surface their label while the rail is in rail mode. Re-applies the tooltip state to every root item immediately. See RailTooltipMode for the per-value semantics.
      Parameters:
      mode - the new RailTooltipMode; must not be null
      Throws:
      NullPointerException - if mode is null
    • isLeafPopoverActive

      public boolean isLeafPopoverActive()
      Whether the rail currently asks SideNavRailItem to create a popover for a leaf (childless) root item, so the popover can act as a Vaadin-themed tooltip. True iff rail mode is active and RailTooltipMode.POPOVER_HEADER is selected.
      Returns:
      true if leaf items should have a popover, false otherwise
    • getPopoverHoverDelay

      public int getPopoverHoverDelay()
      The hover delay (ms) before the popover opens. Default: 200 ms (Lumo-typical).
      Returns:
      the hover delay in milliseconds
    • setPopoverHoverDelay

      public void setPopoverHoverDelay(int hoverDelayMs)
      Sets the hover delay (ms) before the popover opens. Applied to every existing popover immediately. Negative values behave as Vaadin's Popover defines them — the addon does not validate.
      Parameters:
      hoverDelayMs - the new hover delay in milliseconds
    • getPopoverHideDelay

      public int getPopoverHideDelay()
      The hide delay (ms) after the pointer leaves the target before the popover closes. Default: 300 ms (Lumo-typical).
      Returns:
      the hide delay in milliseconds
    • setPopoverHideDelay

      public void setPopoverHideDelay(int hideDelayMs)
      Sets the hide delay (ms) after the pointer leaves the target before the popover closes. Applied to every existing popover immediately.
      Parameters:
      hideDelayMs - the new hide delay in milliseconds
    • getPopoverPosition

      public com.vaadin.flow.component.popover.PopoverPosition getPopoverPosition()
      The position the popover opens at relative to its item. Default: PopoverPosition.END_TOP — top-aligned, to the inline-end of the item (right in an LTR layout). Suitable for a rail pinned to the inline-start edge.
      Returns:
      the active PopoverPosition; never null
    • setPopoverPosition

      public void setPopoverPosition(com.vaadin.flow.component.popover.PopoverPosition position)
      Sets the popover position. Applied to every existing popover immediately.
      Parameters:
      position - the new PopoverPosition; must not be null
      Throws:
      NullPointerException - if position is null
    • isPopoverArrowVisible

      public boolean isPopoverArrowVisible()
      Whether each popover renders the small Lumo arrow pointing back at its target item. Default: true (arrow visible — applies the arrow theme variant of <vaadin-popover>).
      Returns:
      true if the arrow is shown, false if hidden
    • setPopoverArrowVisible

      public void setPopoverArrowVisible(boolean visible)
      Sets whether each popover renders the small Lumo arrow pointing back at its target item. Applied to every existing popover immediately.
      Parameters:
      visible - true to show the arrow (default), false to hide it (cleaner look when popovers are tightly packed against the rail)
    • isChildrenOnlyInPopover

      public boolean isChildrenOnlyInPopover()
      Whether nested items are rendered only inside the hover popover, never inline below their parent. Default: false (children are visible inline and mirrored into the popover — Vaadin's standard behaviour).
      Returns:
      true if inline children are suppressed
    • setChildrenOnlyInPopover

      public void setChildrenOnlyInPopover(boolean enabled)
      Switches between the standard inline-and-popover layout for nested items (false, default) and a popover-only layout (true). When enabled, nested <vaadin-side-nav-item>s are CSS-hidden and the chevron toggle is suppressed, so the only path to a parent's children is the hover popover. Useful for navigation designs that want a flat, non-tree appearance in the rail itself.

      While enabled, this overrides setPopoverOn(PopoverOn): the hover popover is always shown on root items with children (in both rail and normal mode), since it is the only path to their children.

      Vaadin's auto-expand-on-route-match still fires server-side, but has no visual effect while this is on; switching the flag back to false restores the default tree appearance with whatever expanded state the items had accumulated.

      Parameters:
      enabled - true to hide inline children and route everything through the popover, false to use the default layout
    • getRootMatchNested

      public RootMatchNested getRootMatchNested()
      The current RootMatchNested mode. Default: RootMatchNested.ONLY_RAIL. See RootMatchNested for the per-value semantics.
      Returns:
      the active RootMatchNested; never null
    • setRootMatchNested

      public void setRootMatchNested(RootMatchNested mode)
      Sets the RootMatchNested mode. The override is applied (or rolled back) on every root item immediately, snapshotting the original matchNested value the first time it is forced so the user-set value can be restored when the override is disabled again.
      Parameters:
      mode - the new RootMatchNested; must not be null
      Throws:
      NullPointerException - if mode is null
    • getActiveViewItems

      public List<SideNavRailItem> getActiveViewItems()
      Returns all rail items whose own path (or any of their path aliases) equals the current view's location.

      Match semantics:

      • Path equality only. An item's matchNested setting is deliberately ignored — a parent does not become active just because one of its descendants matches the current view. This mirrors the typical use case (breadcrumbs, page titles): callers want the leaf-most item that owns the displayed view.
      • Aliases count. Vaadin's client-side [active] highlight also matches aliases, so server-side answer and visual highlight stay aligned.
      • Real items only. The internal clones used to populate hover popovers live under a separate nested SideNav and are skipped — only items the application actually inserted are returned.
      • DFS pre-order. Multiple matches (e.g. two items wired to the same path, or a path-vs-alias collision) are returned in DFS pre-order so iteration order is deterministic and tied to insertion order.

      The current location is read via UI.getCurrent().getInternals().getActiveViewLocation(), the same value that AfterNavigationEvent.getLocation() surfaces. Returns an empty list when there is no current UI.

      Returns:
      all matching rail items in DFS pre-order; empty if none match
      See Also:
    • getActiveViewItem

      public Optional<SideNavRailItem> getActiveViewItem()
      The first match from getActiveViewItems(), or empty if no item matches. Convenience accessor for the typical single-match case.
      Returns:
      the first matching rail item in DFS pre-order, or empty
    • addRailModeChangedListener

      public com.vaadin.flow.shared.Registration addRailModeChangedListener(com.vaadin.flow.component.ComponentEventListener<RailModeChangedEvent> listener)
      Registers a listener for RailModeChangedEvent. The event fires whenever setRailMode(boolean) actually changes the state (no-ops don't fire).
      Parameters:
      listener - the listener to invoke on each rail-mode transition; must not be null
      Returns:
      a Registration handle that can be used to remove the listener
    • addItem

      public void addItem(com.vaadin.flow.component.sidenav.SideNavItem... items)

      Only accepts SideNavRailItem instances. Passing a plain SideNavItem throws IllegalArgumentException — the label wrap and popover lifecycle depend on SideNavRailItem's overrides and cannot be retrofitted onto a parent-class instance.

      Parameters:
      items - the SideNavRailItem children to append to the rail
      Throws:
      IllegalArgumentException - if any item is not a SideNavRailItem
    • addItemAsFirst

      public void addItemAsFirst(com.vaadin.flow.component.sidenav.SideNavItem item)
      Parameters:
      item - the SideNavRailItem to prepend to the rail
      Throws:
      IllegalArgumentException - if the item is not a SideNavRailItem; see addItem(SideNavItem...)
    • addItemAtIndex

      public void addItemAtIndex(int index, com.vaadin.flow.component.sidenav.SideNavItem item)
      Parameters:
      index - where to insert the item
      item - the SideNavRailItem to insert
      Throws:
      IllegalArgumentException - if the item is not a SideNavRailItem; see addItem(SideNavItem...)