Skip to content

BaseMenu ​

An accessible navigation element in the DOM.

This is intended to be used as a "base" to other menus and not to be used on it's own in the DOM.

Constructor ​

Constructs a new BaseMenu.

js
new BaseMenu({
  menuElement,
  menuItemSelector,
  menuLinkSelector,
  submenuItemSelector,
  submenuToggleSelector,
  submenuSelector,
  controllerElement,
  containerElement,
  openClass,
  closeClass,
  transitionClass,
  transitionDuration,
  openDuration,
  closeDuration,
  isTopLevel,
  parentMenu,
  hoverType,
  hoverDelay,
  enterDelay,
  leaveDelay,
  prefix,
  key,
});

The constructor populates the dom, selector, CSS class, and hover related properties. It will not initialize the menu automatically; this is left to the subclasses to evoke.

Parameters ​

ParamTypeDescriptionDefault
optionsobjectThe options for generating the menu.undefined
options.menuElementHTMLElementThe menu element in the DOM.undefined
options.menuItemSelectorstringThe query selector string for menu items."li"
options.menuLinkSelectorstringThe query selector string for menu links."a"
options.submenuItemSelectorstringThe query selector string for menu items containing submenus.li:has(ul)
options.submenuToggleSelectorstringThe query selector string for submenu toggle buttons/links."a"
options.submenuSelectorstringThe query selector string for submenus."ul"
options.controllerElementHTMLElement, nullThe element controlling the menu in the DOM.null
options.containerElementHTMLElement, nullThe element containing the menu in the DOM.null
options.openClassstring, string[], nullThe class to apply when a menu is "open"."show"
options.closeClassstring, string[], nullThe class to apply when a menu is "closed"."hide"
options.transitionClassstring, string[], nullThe class to apply when a menu is transitioning between "open" and "closed" states.transitioning
options.transitionDurationnumberThe duration of the transition between "open" and "closed" states (in milliseconds).250
options.openDurationnumberThe duration of the transition from "closed" to "open" states (in milliseconds). Uses transitionDuration when set to -1.-1
options.closeDurationnumberThe duration of the transition from "open" to "closed" states (in milliseconds). Uses transitionDuration when set to -1.-1
options.isTopLevelbooleanA flag to mark the root menu.false
options.parentMenuBaseMenu, nullThe parent menu to this menu.null
options.hoverTypestringThe type of hoverability a menu has."off"
options.hoverDelaynumberThe delay for opening and closing menus if the menu is hoverable (in milliseconds).250
options.enterDelaynumberThe delay for opening menus if the menu is hoverable (in milliseconds).-1
options.leaveDelaynumberThe delay for closing menus if the menu is hoverable (in milliseconds).-1
options.prefixstring, nullThe prefix for the CSS custom properties."am-"
options.keystring, nullThe key used to generate IDs throughout the menu.null

Initialize ​

Initializes the menu.

js
BaseMenu.initialize();

The following steps will be taken to initialize the menu:

  • Validate that the menu can initialize,
  • Find the root menu of the menu tree if it isn't already set.
  • Populate all DOM elements within the dom.
  • If the current menu is the root menu and has a controller, initialize the controller.
  • Populate the menu elements within the elements.
  • Set the transition duration custom prop for the menu.

Properties ​

_closeChildrenOnBlur protected ​

Whether leaving the menu through the keyboard collapses its submenus. Treeview overrides this value to preserve its expanded branches.

js
BaseMenu._closeChildrenOnBlur; // Default: `true`.

Type ​

boolean

_closeChildrenOnActivation protected ​

Whether activating a navigation link collapses the root menu's submenus. This applies to root links and links inside submenus.

The click reaches the link's own handlers before the menu handles dismissal.

js
BaseMenu._closeChildrenOnActivation; // Default: `true`.

Type ​

boolean

_MenuType protected ​

The class to use when generating submenus.

js
BaseMenu._MenuType; // Default: `BaseMenu`.

Type ​

Class

_MenuItemType protected ​

The class to use when generating menu items.

js
BaseMenu._MenuItemType; // Default: `BaseMenuItem`.

Type ​

Class

_MenuToggleType protected ​

The class to use when generating menu toggles.

js
BaseMenu._MenuToggleType; // Default: `BaseMenuToggle`.

Type ​

Class

_dom protected ​

The DOM elements within the menu.

js
BaseMenu._dom;

Type ​

Object<HTMLElement, HTMLElement[]>

Properties ​

NameTypeDescriptionDefault
menuHTMLElementThe menu element.null
menuItemsHTMLElement[]An array of menu items.[]
submenuItemsHTMLElement[]An array of menu items that also contain submenu elements.[]
submenuTogglesHTMLElement[]An array of menu links that function as submenu toggles.[]
submenusHTMLElement[]An array of submenu elements.[]
controllerHTMLElementThe toggle for this menu.null
containerHTMLElementThe container for this menu.null

_selectors protected ​

The query selectors used by the menu to populate the dom.

js
BaseMenu._selectors;

Type ​

Object<string>

Properties ​

NameTypeDescriptionDefault
menuItemsstringThe query selector for menu items.""
menuLinksstringThe query selector for menu links.""
submenuItemsstringThe query selector for menu items containing submenus.""
submenuTogglesstringThe query selector for menu links that function as submenu toggles.""
submenusstringThe query selector for for submenus.""

_elements protected ​

The declared accessible-menu elements within the menu.

js
BaseMenu._elements;

Type ​

Object<BaseMenu, BaseMenuToggle, BaseMenuItem[], BaseMenuToggle[]

Properties ​

NameTypeDescriptionDefault
menuItemsBaseMenuItem[]An array of menu items.[]
submenuTogglesBaseMenuToggle[]An array of menu toggles.[]
controllerBaseMenuToggle, nullA menu toggle that controls this menu.null
parentMenuBaseMenu, nullThe parent menu.null
rootMenuBaseMenu, nullThe root menu of the menu tree.null

_openClass protected ​

The class(es) to apply when the menu is open.

js
BaseMenu._openClass; // Default: `"show"`.

Type ​

string, string[]

_closeClass protected ​

The class(es) to apply when the menu is closed.

js
BaseMenu._closeClass; // Default: `"hide"`.

Type ​

string, string[]

_transitionClass protected ​

The class(es) to apply when the menu is transitioning between states.

js
BaseMenu._transitionClass; // Default: `"transitioning`"

Type ​

string, string[]

_transitionDuration protected ​

The duration time (in milliseconds) for the transition between open and closed states.

js
BaseMenu._transitionDuration; // Default: `250`.

Type ​

number

_openDuration protected ​

The duration time (in milliseconds) for the transition from closed to open states.

js
BaseMenu._openDuration; // Default: `-1`.

Type ​

number

_closeDuration protected ​

The duration time (in milliseconds) for the transition from open to closed states.

js
BaseMenu._closeDuration; // Default: `-1`.

Type ​

number

_root protected ​

A flag marking the root menu.

js
BaseMenu._root; // Default: `true`.

Type ​

boolean

_currentChild protected ​

The index of the currently selected menu item in the menu.

js
BaseMenu._currentChild; // Default: `0`.

Type ​

number

_focusState protected ​

The current state of the menu's focus.

js
BaseMenu._focusState; // Default: `"none"`.

Available states are: "none", "self", and "child".

Type ​

string

_currentEvent protected ​

The last event triggered on the menu.

js
BaseMenu._currentEvent; // Default: `"none"`.

Available events are: "none", "mouse", "keyboard", and "character".

Type ​

string

_hoverType protected ​

The type of hoverability for the menu.

js
BaseMenu._hoverType; // Default: `"off"`.

Available types are: "off", "on", and "dynamic".

You can read more about supported hover types in the docs.

Type ​

string

_hoverDelay protected ​

The delay time (in milliseconds) used for pointerenter/pointerleave events to take place.

js
BaseMenu._hoverDelay; // Default: `250`.

Type ​

number

_enterDelay protected ​

The delay time (in milliseconds) used for pointerenter events to take place.

js
BaseMenu._enterDelay; // Default: `-1`.

Type ​

number

_leaveDelay protected ​

The delay time (in milliseconds) used for pointerleave events to take place.

js
BaseMenu._leaveDelay; // Default: `-1`.

Type ​

number

_prefix protected ​

The prefix for the CSS custom properties.

js
BaseMenu._prefix; // Default: `"am-"`.

_hoverTimeout protected ​

A variable to hold the hover timeout function.

js
BaseMenu._hoverTimeout; // Default: `null`.

Type ​

Function

_hasOpened protected ​

A flag to check if the menu can dynamically hover based on if a menu has been opened already.

js
BaseMenu._hasOpened; // Default: `false`.

Type ​

boolean

_key protected ​

The key used to generate IDs throughout the menu.

js
BaseMenu._key; // Default: `""`.

Type ​

string

_errors protected ​

An array of error messages generated by the menu.

js
BaseMenu._errors; // Default: `[]`.

Type ​

string[]

Getters and Setters ​

dom readonly ​

The DOM elements within the menu.

js
BaseMenu.dom;

See _dom for more information.

selectors readonly ​

The query selectors used by the menu to populate the dom.

js
BaseMenu.selectors;

See _selectors for more information.

elements readonly ​

The declared accessible-menu elements within the menu.

js
BaseMenu.elements;

See _elements for more information.

isTopLevel readonly ​

The flag marking the root menu.

js
BaseMenu.isTopLevel;

See _root for more information.

key readonly ​

The key used to generate IDs throughout the menu.

js
BaseMenu.key;

This functions differently for root vs. submenus. Submenus will always inherit their parent menu's key suffixed with thier position.

See _key for more information.

openClass ​

The class(es) to apply when the menu is open.

js
BaseMenu.openClass;
js
BaseMenu.openClass = "show";

This functions differently for root vs. submenus. Submenus will always inherit their root menu's open class(es).

See _openClass for more information.

closeClass ​

The class(es) to apply when the menu is closed.

js
BaseMenu.closeClass;
js
BaseMenu.closeClass = "hide";

This functions differently for root vs. submenus. Submenus will always inherit their root menu's close class(es).

See _closeClass for more information.

transitionClass ​

The class(es) to apply when the menu is transitioning between open and closed.

js
BaseMenu.transitionClass;
js
BaseMenu.transitionClass = "transitioning";

This functions differently for root vs. submenus. Submenus will always inherit their root menu's transition class(es).

See _transitionClass for more information.

transitionDuration ​

The duration time (in milliseconds) for the transition between open and closed states.

js
BaseMenu.transitionDuration;
js
BaseMenu.transitionDuration = 250;

This functions differently for root vs. submenus. Submenus will always inherit their root menu's transition duration.

Setting this value will also update the --am-transition-duration CSS custom property on the menu and its descendants.

See _transitionDuration for more information.

openDuration ​

The duration time (in milliseconds) for the transition from closed to open states.

js
BaseMenu.openDuration;
js
BaseMenu.openDuration = 250;

This functions differently for root vs. submenus. Submenus will always inherit their root menu's open duration. A root openDuration of -1 uses transitionDuration.

Setting this value will also update the --am-open-transition-duration CSS custom property on the menu and its descendants.

See _openDuration for more information.

closeDuration ​

The duration time (in milliseconds) for the transition from open to closed states.

js
BaseMenu.closeDuration;
js
BaseMenu.closeDuration = 250;

This functions differently for root vs. submenus. Submenus will always inherit their root menu's close duration. A root closeDuration of -1 uses transitionDuration.

Setting this value will also update the --am-close-transition-duration CSS custom property on the menu and its descendants.

See _closeDuration for more information.

currentChild ​

The index of the currently selected menu item in the menu.

js
BaseMenu.currentChild;
js
BaseMenu.currentChild = 0;

Attempting to set the current child to a value less than -1 will set the current child to -1.

Attempting to set the current child to a value greater than or equal to the number of menu items will set the current child to the index of the last menu item in the menu.

If the current menu has a parent menu and the menu's current event is "mouse", The parent menu will have it's current child updated as well to help with transitioning between mouse and keyboard naviation.

See _currentChild for more information.

focusState ​

The current state of the menu's focus.

js
BaseMenu.focusState;
js
BaseMenu.focusState = "self";

Available states are: "none", "self", and "child".

If the menu has submenus, setting the focus state to "none" or "self" will update all child menus to have the focus state of "none".

If the menu has a parent menu, setting the focus state to "self" or "child" will update all parent menus to have the focus state of "child".

See _focusState for more information.

currentEvent ​

The last event triggered on the menu.

js
BaseMenu.currentEvent;
js
BaseMenu.currentEvent = "mouse";

Available events are: "none", "mouse", "keyboard", and "character".

See _currentEvent for more information.

currentMenuItem readonly ​

The currently selected menu item.

js
BaseMenu.currentMenuItem;

hoverType ​

The type of hoverability for the menu.

js
BaseMenu.hoverType;
js
BaseMenu.hoverType = "off";

Available types are: "off", "on", and "dynamic".

This functions differently for root vs. submenus. Submenus will always inherit their root menu's hoverability.

See _hoverType for more information.

hoverDelay ​

The delay time (in milliseconds) used for pointerenter/pointerleave events to take place.

js
BaseMenu.hoverDelay;
js
BaseMenu.hoverDelay = 250;

This functions differently for root vs. submenus. Submenus will always inherit their root menu's hover delay.

See _hoverDelay for more information.

enterDelay ​

The delay time (in milliseconds) used for pointerenter events to take place.

js
BaseMenu.enterDelay;
js
BaseMenu.enterDelay = 250;

If enterDelay is set to -1, the hoverDelay value will be used instead.

This functions differently for root vs. submenus. Submenus will always inherit their root menu's enter delay.

See _enterDelay for more information.

leaveDelay ​

The delay time (in milliseconds) used for pointerleave events to take place.

js
BaseMenu.leaveDelay;
js
BaseMenu.leaveDelay = 250;

If leaveDelay is set to -1, the hoverDelay value will be used instead.

This functions differently for root vs. submenus. Submenus will always inherit their root menu's leave delay.

See _leaveDelay for more information.

prefix ​

The prefix for the CSS custom properties.

js
BaseMenu.prefix;
js
BaseMenu.prefix = "am-";

This functions differently for root vs. submenus. Submenus will always inherit their root menu's prefix.

See _prefix for more information.

shouldFocus readonly ​

A flag to check if the menu's focus methods should actually move the focus in the DOM.

js
BaseMenu.shouldFocus;

This will be false unless any of the following criteria are met:

  • The menu's current event is "keyboard".
  • The menu's current event is "character".
  • The menu's current event is "mouse" and the menu's hover type is "dynamic".

hasOpened ​

A flag to check if the menu can dynamically hover.

js
BaseMenu.hasOpened;
js
BaseMenu.hasOpened = true;

This functions differently for root vs. submenus. Submenus will always inherit their root menu's hasOpened.

See _hasOpened for more information.

errors readonly ​

An array of error messages generated by the menu.

js
BaseMenu.errors;

See _errors for more information.

Methods ​

_validate protected ​

Validates all aspects of the menu to ensure proper functionality.

js
BaseMenu._validate();

Returns ​

TypeDescription
booleanThe result of the validation.

_setDOMElementType protected ​

Sets DOM elements within the menu.

js
BaseMenu._setDOMElementType(elementType, base, overwrite);

Elements that are not stored inside an array cannot be set through this method.

Parameters ​

ParamTypeDescriptionDefault
elementTypestringThe type of element to populate.undefined
baseHTMLElementThe element used as the base for the querySelect.this.dom.menu
overwritebooleanA flag to set if the existing elements will be overwritten.true

_resetDOMElementType protected ​

Resets DOM elements within the menu.

js
BaseMenu._resetDOMElementType(elementType);

Elements that are not stored inside an array cannot be reset through this method.

Parameters ​

ParamTypeDescriptionDefault
elementTypestringThe type of element to clear.undefined

_setDOMElements protected ​

Sets all DOM elements within the menu.

js
BaseMenu._setDOMElements();

Utilizes _setDOMElementType and _resetDOMElementType.

_generateKey ​

Generates a key for the menu.

js
BaseMenu._generateKey(regenerate);

Parameters ​

ParamTypeDescriptionDefault
regeneratebooleanA flag to determine if the key should be regenerated.false

_setIds protected ​

Sets the IDs of the menu and it's elements if they do not already exist.

js
BaseMenu._setIds();

The generated IDs use the key and follow the format:

  • menu: menu-${key},
  • container: menu-container-${key},
  • controller: menu-controller-${key},

_findRootMenu protected ​

Finds the root menu element.

js
BaseMenu._findRootMenu(menu);

Parameters ​

ParamTypeDescriptionDefault
menuBaseMenuThe menu to check.undefined

_createChildElements protected ​

Creates and initializes all menu items and submenus.

js
BaseMenu._createChildMenu();

_clearTimeout protected ​

Clears the hover timeout.

js
BaseMenu._clearTimeout();

_setTimeout protected ​

Sets the hover timeout.

js
BaseMenu._setTimeout(callback, delay);

Parameters ​

ParamTypeDescriptionDefault
callbackFunctionThe callback function to execute.undefined
delaynumberThe delay time in milliseconds.undefined

_handleFocus protected ​

Handles focus events throughout the menu for proper menu use.

js
BaseMenu._handleFocus();
  • Adds a focus listener to every menu item so when it gains focus, it will set the item's containing menu's focus state to "self" and select the item. Each ancestor menu selects the item that owns the focused submenu without moving focus.
  • Adds a focusout listener to clear the menu's focus state when keyboard focus leaves it. If _closeChildrenOnBlur is true, also collapses its submenus.

_handleClick ​

Handles click events throughout the menu for proper use.

js
BaseMenu._handleClick();

This method will do the following:

  • Adds a click listener to every menu item that will blur all menu items in the entire menu structure (starting at the root menu) and then properly focus the clicked item.
  • Adds a click listener to every submenu item that will properly toggle the submenu open/closed.
  • If _closeChildrenOnActivation is true, adds a bubbling click listener to the menu that calls the root menu's closeChildren method after a navigation link's own click handlers run.
  • Adds a click listener to the menu's controller (if the menu is the root menu) so when it is clicked it will properly toggle open/closed.

_handleHover protected ​

Handles hover events throughout the menu for proper use.

js
BaseMenu._handleHover();

Adds pointerenter listeners to all menu items and pointerleave listeners to all submenu items which function differently depending on the menu's hover type.

Before executing anything, the event is checked to make sure the event wasn't triggered by a pen or touch.

This method will add the following behaviour:

Hover Type "on" ​

  • When a pointerenter event triggers on any menu item the menu's current child value will change to that menu item.
  • When a pointerenter event triggers on a submenu item the preview method for the submenu item's toggle will be called.
  • When a pointerleave event triggers on an open submenu item the close method for the submenu item's toggle will be called after a delay set by the menu's hover delay.

Hover Type "dynamic" ​

  • When a pointerenter event triggers on any menu item the menu's current child value will change to that menu item.
  • When a pointerenter event triggers on any menu item, and the menu's focus state is not "none", the menu item will be focused.
  • When a pointerenter event triggers on a submenu item, and a submenu is already open, the preview method for the submenu item's toggle will be called.
  • When a pointerenter event triggers on a non-submenu item, and a submenu is already open, the closeChildren method for the menu will be called.
  • When a pointerenter event triggers on a submenu item, and no submenu is open, no submenu-specific methods will be called.
  • When a pointerleave event triggers on an open submenu item that is not a root-level submenu item the close method for the submenu item's toggle will be called and the submenu item will be focused after a delay set by the menu's hover delay.
  • When a pointerleave event triggers on an open submenu item that is a root-level submenu item no submenu-specific methods will be called.

Hover Type "off" ​

All pointerenter and pointerleave events are ignored.

_handleKeydown protected ​

Handles keydown events throughout the menu for proper menu use.

js
BaseMenu._handleKeydown();

This method exists to assist the _handleKeyup method.

This method will do the following:

  • Adds a keydown listener to the menu's controller (if the menu is the root menu).
    • Blocks propagation on "Space", "Enter", and "Escape" keys.

_handleKeyup protected ​

Handles keyup events throughout the menu for proper menu use.

js
BaseMenu._handleKeyup();

This method will do the following:

  • Adds a keyup listener to the menu's controller (if the menu is the root menu).
    • Toggles the menu when the user hits "Space" or "Enter".

_setTransitionDuration protected ​

Sets the transition duration of the menu as a CSS custom property.

js
BaseMenu._setTransitionDuration();

The custom properties are:

  • --am-transition-duration,
  • --am-open-transition-duration, and
  • --am-close-transition-duration.

The prefix of am- can be changed by setting the menu's prefix value.

focus public ​

Focus the menu.

js
BaseMenu.focus();

Sets the menu's focus state to "self" and focusses the menu if the menu's shouldFocus value is true.

blur public ​

Unfocus the menu.

js
BaseMenu.blur();

Sets the menu's focus state to "none" and blurs the menu if the menu's shouldFocus value is true.

focusCurrentChild public ​

Focuses the menu's current child.

js
BaseMenu.focusCurrentChild();

focusChild public ​

Focuses the menu's child at a given index.

js
BaseMenu.focusChild(index);

Parameters ​

ParamTypeDescriptionDefault
indexnumberThe index of the child to focus.undefined

The index is required and must be a finite integer. It follows currentChild's clamping rules. An index of -1 clears the current child without focusing another item. Invalid types throw a TypeError; fractions, NaN, and infinities throw a RangeError. Validation happens before the current item is blurred or selection changes.

focusFirstChild public ​

Focus the menu's first child.

js
BaseMenu.focusFirstChild();

focusLastChild public ​

Focus the menu's last child.

js
BaseMenu.focusLastChild();

focusNextChild public ​

Focus the menu's next child.

js
BaseMenu.focusNextChild();

focusPreviousChild public ​

Focus the menu's previous child.

js
BaseMenu.focusPreviousChild();

blurCurrentChild public ​

Blurs the menu's current child.

js
BaseMenu.blurCurrentChild();

focusController public ​

Focus the menu's controller.

js
BaseMenu.focusController();

focusContainer public ​

Focus the menu's container.

js
BaseMenu.focusContainer();

closeChildren public ​

Close all submenu children.

js
BaseMenu.closeChildren();

blurChildren public ​

Blurs all children and submenu's children.

js
BaseMenu.blurChildren();