4.32.2

Navigation (displayed along side of page)

Top-level navigation

Legacy component documentation: <aui-supernav>

Demo

No live demo is available for the side nav because some elements will not show up correctly in the context of this page. Please note the parent div in the code sample which wraps the side nav and main content; your app's HTML must be structured this way, and the parent div must be given class="flex align-items-stretch" for the side nav and other content to display properly.

const navItems = [ { "label": "Home", "dataRef": "aui-supernav.home", "url": "https://home.avalara.com", "icon": "home", }, { "label": "Transactions", "dataRef": "aui-supernav.transactions.menu-trigger", "icon": "credit-card", "menuItems": [ { "label": "AvaTax", "menuItems": [ { "label": "View and edit", "url": "https://admin.avalara.com/transactions", "dataRef": "aui-supernav.avatax.transactionsNavMenuList" }, { "label": "Import", "url": "https://admin.avalara.com/transactions/batch-upload", "dataRef": "aui-supernav.avatax.transactionsNavMenuUpload" } ] } ] }, ]; document.querySelector('aui-sidenav').navItems = navItems; var camInfo = { "id": "00540000002Lg71AAC", "name": "Bob Jones", "phone": "879-289-2798", "email": "bobj@avalara.com", "photoUrl": "https://pbs.twimg.com/profile_images/848637217375481856/G24SPJBe_400x400.jpg", "schedulingUrl": "https://avalara.chilipiper.com/me/Bob-Jones", "isValid": true }; document.querySelector('aui-sidenav').cam = camInfo;

Handling Company Changes

When users change their active company through the company switcher, your application must listen for the s-change-company event and reload any company-specific data. This is critical because the company switcher no longer causes a page refresh.

Basic Event Handling

// Listen for company changes (event bubbles up from aui-sidenav) document.addEventListener('s-change-company', (event) => { const { company, initialLoad } = event.detail; console.log('Company changed to:', company.name, `(${company.companyCode})`); console.log('Company ID:', company.id); console.log('Is initial load:', initialLoad); // Reload company-specific data if (!initialLoad) { // User actively changed the company - reload your data reloadCompanyData(company.id); } else { // Initial load - set up your app with the active company initializeWithCompany(company.id); } });

API

Tag

Name Description
<aui-sidenav> Custom Element, no content

Attributes

Name Value Required Description
active dataRef of a top-level navItem

Sets the active top-level nav item.

companyid String

In the majority of cases, the company ID will be pulled from the aui-context cookie, but this attribute is available for overriding the cookie's value.

accountid String

In the majority of cases, the account ID will be pulled from the aui-context cookie, but this attribute is available for overriding the cookie's value.

hidecompanyswitcher Boolean

When present, the company switcher will be hidden.

hidecontact Boolean

When present, the contact information will be hidden.

cam String

Stringified JSON of cam object, see Guidelines below.

i18n string

A stringified JSON object which defines a list of localized strings. The keys must be one of the string IDs defined below.

Properties

Name Value Required Description
active dataRef of a top-level navItem

Sets the active top-level nav item.

companyId String

In the majority of cases, the company ID will be pulled from the aui-context cookie, but this attribute is available for overriding the cookie's value.

accountId String

In the majority of cases, the account ID will be pulled from the aui-context cookie, but this attribute is available for overriding the cookie's value.

requestCurrentAccessToken Function Function that returns a Promise resolving to {accessToken: "<avalara-ui-access-token>"}.
hideCompanySwitcher Boolean

When present, the company switcher will be hidden.

hideContact Boolean

When present, the contact information will be hidden.

cam JSON

Set this to cam object JSON, see Guidelines below.

i18n object

A JSON object which defines a list of localized strings. The keys must be one of the string IDs defined below.

Events

Name Detail Description
s-navitemsloaded The navItems are available on e.detail

Fired when the navItems are successfully loaded. May be emitted multiple times if getNavigationJson() is called during the user session.

s-change-company The SCompanyChangeEvent object is available on e.detail

Fired when the company switcher sub-component changes the company.

⚠️ Important: Teams must listen for this event and reload any company-specific data. Previously, the company switcher was a separate page that users would navigate to, so navigating back to your page would refresh the data. Now that the company switcher is embedded in the sidenav, there's no page refresh when the company changes, so your application must handle data reloading manually.

The event is fired with initialLoad: true when the component first loads and determines the active company, and initialLoad: false when the user actively changes the company.

Methods

Name Description
getNavigationJson() Call this method to re-fetch JSON from the navigation service and update <aui-sidenav>. Invoking this method is not necessary for the initial navigation fetch/render, only subsequent fetching/rendering for updates during a user session. See guidelines.

Demo

Handling Company Changes

When users change their active company through the company switcher, your React application must listen for the s-change-company event and reload any company-specific data. This is critical because the company switcher no longer causes a page refresh.

Basic Event Handling

// Listen for company changes in React component useEffect(() => { const handleCompanyChange = (event) => { const { company, initialLoad } = event.detail; console.log('Company changed to:', company.name, `(${company.companyCode})`); console.log('Company ID:', company.id); console.log('Is initial load:', initialLoad); // Reload company-specific data if (!initialLoad) { // User actively changed the company - reload your data reloadCompanyData(company.id); } else { // Initial load - set up your app with the active company initializeWithCompany(company.id); } }; document.addEventListener('s-change-company', handleCompanyChange); }, []);

API

Tag

Name
<AuiSidenav>

Props

Name Value Required Description
requestCurrentAccessToken Function Function that returns a Promise resolving to {accessToken: "<avalara-ui-access-token>"}.
navHandler NavHandler function

Function to handle in-app navigation, see Guidelines below.

active dataRef of a top-level navItem

Sets the active top-level nav item.

companyId String

In the majority of cases, the company ID will be pulled from the aui-context cookie, but this attribute is available for overriding the cookie's value.

accountId String

In the majority of cases, the account ID will be pulled from the aui-context cookie, but this attribute is available for overriding the cookie's value.

navItems Nav Items object

SuperCUP apps should never use this property. Instead, they will apply the requestCurrentAccessToken property, which will fetch items from the Web Platform Navigation Service. Other apps should apply a stringified array of nav items, see Guidelines below.

hideCompanySwitcher Boolean

When present, the company switcher will be hidden.

hideContact Boolean

When present, the contact information will be hidden.

onSNavItemsLoaded Function

Handles the s-navitemsloaded event fired when the navItems are successfully loaded. This event may be emitted multiple times if getNavigationJson() is called during the user session.

cam JSON

Set this to cam object JSON. See Guidelines.

i18n object

A JSON object which defines a list of localized strings. The keys must be one of the string IDs defined below.

Methods

Name Description
getNavigationJson() Call this method to re-fetch JSON from the navigation service and update <AuiSupernav>. Invoking this method is not necessary for the initial navigation fetch/render, only subsequent fetching/rendering for navigation updates during a user session. See React-specific guidelines below for more information (as well as main guidelines).

React implementation notes

Using refs to call AuiSidenav method

In order to call the getNavigationJson() method, you must create a ref, assign it to the AuiSidenav component, and then use ref.current to access the method:

    
    const auiSidenavRef = React.createRef(); 
    
    function getNavigationJson() {
      auiSidenavRef.current.getNavigationJson();
    }
    
    return (
      <AuiSidenav ref={auiSidenavRef} />
    )
    
    

Skylab React links

General information about using our React package

Typescript

Exported types

// CAM object provided to component export type CamObject = Record; // User object provided to component export type UserObject = Record; // NavItem object provided (in an array) to component export type NavItem = { label: string; dataRef: string; menuItems?: NavItem[]; url?: string; icon?: string; disabled?: boolean; descriptor?: string; i18nKey?: string; }; // s-navitemsloaded event's e.detail export type SNavItemsLoadedEvent = { navItems: NavItem[]; }; // company object for s-change-company event export type CompanyItem = { id?: number; companyCode: string; name: string; parentCompanyId?: number; isDefault?: boolean; isActive?: boolean; parentCompanyName?: string; }; // s-change-company event's e.detail export type SCompanyChangeEvent = { company: CompanyItem; initialLoad: boolean; };

i18n Strings

ID Description Default value
"sidenav.ariaLabel.nav" The aria-label for the nav element main navigation
"sidenav.ariaLabel.toggleExpand" The aria-label used for the button that horizontally expands the side nav. Expand menu
"sidenav.ariaLabel.toggleCollapse" The aria-label used for the button that horizontally collapses the side nav. Collapse menu

Guidelines

Page layout requirements

In order to display properly, the side nav and main content containers must be wrapped in a parent div which is styled with display: flex and align-items: stretch. See the code sample at the top of this page for an example. In addition, the aui-header accompanying the side nav must be given the sidenavheader attribute in order to be styled correctly.

Providing the access token

Your app must set (via the requestCurrentAccessToken property) a function that returns a Promise resolving to {accessToken: "<avalara-ui-access-token>"}. The access token must have at least 5 seconds of life remaining.

Avalara Identity access tokens are short-lived by default, so it is essential that the requestCurrentAccessToken function either fetch an access token fresh from the server or have knowledge of a particular access token's expiration so it does not deliver a stale access token.

A sample implementation is shown in the Pioneer Demo app

There are two ways to populate the <aui-sidenav> component with nav items:

  1. requestCurrentAccessToken

    SuperCUP apps must provide the requestCurrentAccessToken function to the component. When this function is set, the component will make a request to the Web Platform Navigation Service to fetch the navigation JSON for the customer and render it.

  2. navitems (attribute)/navItems (property)

    Non-SuperCUP apps must provide a formatted array of navItems to the <aui-sidenav> component:

    See API below:

    // each navItem and menuItem must contain either "url" string, "menuItems" array, or true "disabled" boolean // if URL must be masked in disabled item, we recommend including "url" value of "#" // menuItems can extend to 2 levels deep, with product names assigned to "label" // "descriptor" is used in conjunction with "disabled: true" to display a short explanation for the disabled state of the menu item interface NavItem { label: string dataRef: string icon?: string // required for top-level NavItem menuItems?: NavItem[] url?: string disabled?: boolean descriptor?: string }

    or data can be assigned as attribute using stringified array

Customer Account Manager object

The customer's Salesforce account information is retrieved via the OPUS API (see Swagger). That customerAccount object contains a key named camOwned that indicates if the account's cam key contains valid Customer Account Manager data. The value of camOwned should be assigned to the isValid key and passed along with the cam object to the <aui-sidenav> as follows:

const customerAccount = await getCustomerAccountFromOpus(customerId); const modifiedCamObject = customerAccount.cam ? { ...customerAccount.cam, isValid: customerAccount.camOwned } : null; document.querySelector('aui-sidenav').cam = modifiedCamObject;

or data can be assigned as attribute using stringified JSON

If the cam object includes a photoUrl field, the linked image will be displayed in the contact dialog. If no photoUrl is defined or the image fails to load, a default user icon will be displayed instead.

Valid active attribute values

In contrast to the top nav, which permits only a small set of values for the active attribute, any nav item's dataRef can be provided to the side nav as an active value.

Single page apps can optionally provide a navHandler function to manage routing within a single-page application (SPA). On any click of an <a> tag in <aui-sidenav>, the navHandler will be invoked with two arguments: the mouse click event and the value of the href attribute in the associated <a> tag.

The typical implementation will include a conditional to determine if the URL is within the consumer's SPA and invocation of that SPA's router function (e.g. history.push in react-router) if so.

Sample usage is shown below for CUP (admin.avalara.com):

function handleNavigation(nativeMouseEvent, url) { if (url.includes("admin.avalara.com")) { nativeMouseEvent.preventDefault(); mySpaRouterFunction(url); } // nothing need be invoked for the case of a url not in the SPA // the default action will execute and the user will be routed to the new app and the page will be refreshed } document.querySelector('aui-sidenav').navHandler = handleNavigation;

getNavigationJson function

If an event occurs during a user session that impacts the navigation content (e.g. TSA user switches to a different account), invoke the declarative getNavigationJson() method to refresh the navigation data.

Design

Design resources can be found on the Skylab design documentation site: skylab.avalara.com