Reusable navigation patterns used in the CenturyLink Platform.
Make navs used as navigation accessible.
If you are using navs to provide a navigation bar, be sure to add a role="navigation"
to the most logical parent container of the <ul>
, or wrap a <nav>
element around the whole navigation. Do not add the role to the <ul>
itself, as this would prevent it from being announced as an actual list by assistive technologies.
The CenturyLink Platform supports the ability to create sub-accounts, which fall under a parent account. Sub accounts have of the advantage of:
- Hierarchy: user permissions flow down, but not up or sideways
- Billing: sub accounts may be billed separately or to the parent account
- Share Parent Networks: sub accounts may access their parent account's networks, in addition to their own network
- Inheritance: account settings are inherited
If a user has access to multiple accounts, their account context needs to be maintained as they navigate to different platform satellite apps. This component is a means for platform customers to view their current account context, change account context, and maintain that context across CenturyLink Platform satelite apps.
Keyboard Shortcuts
ctl + i
: toggle account switcher open or closed
esc
: close account switcher when open
up, down
: navigate the list of accounts
enter
: change to selected account context
In the iframe below, click the top bar to open the account switcher.
Open Example Page
<account-switcher params="{accounts: accounts, currentAccountAlias: currentAccountAlias}"></account-switcher>
$(function(){
ko.applyBindings({
accounts: [...],
currentAccountAlias: '...'
});
});
The Pane Tree View provides a way to navigate hierarchical entities with expand/collapse and filtering functionality built-in. It begins collapsed in mobile views, with a toggle button to expand. On desktop or tablets views, the pane tree view begins in a vertical orientation on the left side of the viewport. It expects an object of items (e.g. groups and servers, appfog spaces and apps) and a selected item to highlight the selected item in the tree view.
To add a pane tree view to a page, use the custom <pane>...</pane>
html component and apply the bindings. Immediately preceding the <pane>
, use <main><div class="container-fluid">...</div></main>
to wrap the page body content. This will apply proper spacing and margin between the pane and the body content.
The Pane Tree View provides basic functionality. The implementator is responsible for loading data, choosing icons, etc. Please see the
API documentation for more details.
<pane params="{items: items, selectedItemId: selectedItemId}"></pane>
<main>
<div class="container-fluid">
<!--body content of the page-->
</div>
</main>
ko.applyBindings({
items: ko.observableArray([...]),
selectedItemId: ko.observable("QA1WEBSERVER02")
});
Key to a positive customer experience is having a standard header navigation across Platform services. Adopt the page header navigation component for your product to ensure your UI is consistent with the rest of the CenturyLink Platform.
Responsive behavior is built in, so at narrow viewports (portrait tablet or mobile device), the links will collapse into a vertical menu.
<nav class="navbar navbar-static-top">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">
<img src="/img/logo-centurylink.png" alt="CenturyLink" />
</a>
<a class="navbar-service" href="/">Control Portal</a>
</div>
<!-- Support and sign out links -->
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav navbar-right navbar-account">
<li class="dropdown">
<a href="#" role="button"><span class="sr-only">help and support links</span><svg class="cyclops-icon support"><use xlink:href='#icon8-question-circle' /></svg> <svg class="cyclops-icon" aria-hidden="true"><use xlink:href='#icon-caret-down' /></svg></a>
<ul class="dropdown-menu dropdown-menu-right">
<li><a href="#">Open Support Ticket</a></li>
<li><a href="#">Chat with Support</a></li>
<li><a href="https://www.ctl.io/knowledge-base">Knowledge Base</a></li>
<li><a href="https://www.ctl.io/api-docs">API Documentation</a></li>
<li><p class="dropdown-text">1.877.388.4373</p></li>
<li role="separator" class="divider"></li>
<li><a href="#">Submit a Feature Idea</a></li>
</ul>
</li>
<li class="dropdown">
<a href="#" role="button">trent.anderson <svg class="cyclops-icon" aria-hidden="true"><use xlink:href='#icon-caret-down'></svg></a>
<ul class="dropdown-menu dropdown-menu-right">
<li><a href="#">Your Profile</a></li>
<li><a href="#">Sign Out</a></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
An inverse themed alternative page header is also available.
<nav class="navbar navbar-default navbar-static-top">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">
<img src="/https://assets.ctl.io/images/centurylink-logo-white.svg" alt="CenturyLink" />
</a>
<a class="navbar-service" href="/">Control Portal</a>
</div>
<!-- Support and sign out links -->
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav navbar-right navbar-account">
<li class="dropdown">
<a href="#" role="button"><span class="sr-only">help and support links</span><svg class="cyclops-icon support"><use xlink:href='#icon-question-circle' /></svg> <svg class="cyclops-icon" aria-hidden="true"><use xlink:href='#icon-caret-down' /></svg></a>
<ul class="dropdown-menu dropdown-menu-right">
<li><a href="#">Open Support Ticket</a></li>
<li><a href="#">Chat with Support</a></li>
<li><a href="https://www.ctl.io/knowledge-base">Knowledge Base</a></li>
<li><a href="https://www.ctl.io/api-docs">API Documentation</a></li>
<li><p class="dropdown-text">1.877.388.4373</p></li>
<li role="separator" class="divider"></li>
<li><a href="#">Submit a Feature Idea</a></li>
</ul>
</li>
<li class="dropdown">
<a href="#" role="button">trent.anderson <svg class="cyclops-icon" aria-hidden="true"><use xlink:href='#icon-caret-down' /></svg></a>
<ul class="dropdown-menu dropdown-menu-right">
<li><a href="#">Your Profile</a></li>
<li><button>Sign Out</button></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
The <main-nav>
is the primary navigation of a Cyclops-based application. It supports a simple two level system of navigation. For more information see
the API documentation.
Responsive behavior is built in, so at narrow viewports (portrait tablet or mobile device)
the links will collapse into an icon-based menu. At wide viewports, the icon and label will be
adjacent instead of stacked.
In the iframe below, the main-nav is the menu bar on the left (Dashboard, Creat,
Infrastructure, Network…)
Open Example Page
<main-nav role="navigation" params="menus: menus, loading: loading, error: error, selectedItemId: selectedItemId"></main-nav>
$(function(){
ko.applyBindings({
menus: [
{
id: "home",
name: 'Dashboard',
iconId: '#icon-home',
href: '#'
},
{...}
],
self.loading = ko.observable(false);
self.error = ko.observable(false);
self.selectedItemId = ko.observable('infrastructure');
});
});
Persistent Nav Local is used to navigate between pages that fall within the same service. If there are secondary pages in a service, then links to those pages may be shown inside a .dropdown-menu
.
The persisent nav local should be the first element placed inside <main></main>
and be visible at the top of every page throughout your application. To make the nav stick at the top of the browser on page scroll, apply sticky positioning. See an example of this on the sample page.
Up to 768px, the persistent nav local is collapsed into a stacked menu. Greater than 768px, it spans the full width of it's container.
<nav class="navbar navbar-local navbar-local--persistent">
<ul class="nav navbar-nav" data-bind="widget: {name: 'overflowMenu', options: {linkTextAll: 'MENU'}}">
<li class="logo">
<a href="/"><svg class="cyclops-icon">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon-runner"></use>
</svg></a>
</li>
<li class="active"><a href="#">Products</a></li>
<li><a href="#">Manual Jobs</a></li>
<li><a href="#">Schedules</a></li>
<li><a href="#">History</a></li>
<li><a href="#">Settings</a></li>
<li><a href="#">Help</a></li>
</ul>
<div class="navbar-local-right"><a href="#" class="btn btn-primary navbar-btn"><svg class="cyclops-icon"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon-plus-circle"></use></svg><span class="sr-only">create</span> item</a></div>
</nav>
An inverse themed alternative page header is also available.
<nav class="navbar navbar-local navbar-local--persistent navbar-inverse">
<ul class="nav navbar-nav" data-bind="widget: {name: 'overflowMenu', options: {linkTextAll: 'MENU'}}">
<li class="logo">
<a href="/"><svg class="cyclops-icon">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon-runner"></use>
</svg></a>
</li>
<li class="active"><a href="#">Products</a></li>
<li><a href="#">Manual Jobs</a></li>
<li><a href="#">Schedules</a></li>
<li><a href="#">History</a></li>
<li><a href="#">Settings</a></li>
<li><a href="#">Help</a></li>
</ul>
<div class="navbar-local-right"><a href="#" class="btn btn-success navbar-btn"><svg class="cyclops-icon"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon-plus-circle"></use></svg><span class="sr-only">create</span> item</a></div>
</nav>
Nav local is used to jump between pages fall within the same section. If there are secondary pages in a section, then links to those pages are shown inside .dropdown-menu
menus. A bold nav label indicates the currently active page in view.
Up to 768px, the nav local is collapsed into a stacked menu. Greater than 768px, it spans the full width of it's container.
<nav class="navbar navbar-local">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed">
Menu <svg class="cyclops-icon" aria-hidden="true"><use xlink:href='#icon-caret-down' /></svg>
</button>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="#navLocal">Events</a></li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#navLocal" role="button" aria-haspopup="true" aria-expanded="false">Policies <svg class="cyclops-icon" aria-hidden="true"><use xlink:href='#icon-caret-down' /></svg></a>
<ul class="dropdown-menu">
<li class="active"><a href="#navLocal">Alert</a></li>
<li><a href="#navLocal">Suppression</a></li>
</ul>
</li>
<li><a href="#navLocal">Integrations</a></li>
<li class="disabled"><a href="#navLocal">Disabled</a></li>
<li class="active dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#navLocal" role="button" aria-haspopup="true" aria-expanded="false">Settings <svg class="cyclops-icon" aria-hidden="true"><use xlink:href='#icon-caret-down' /></svg></a>
<ul class="dropdown-menu">
<li><a href="#navLocal">Profile</a></li>
<li><a href="#navLocal">Account</a></li>
<li><a href="#navLocal">Billing</a></li>
<li><a href="#navLocal">Notifications</a></li>
<li><a href="#navLocal">SSH Keys</a></li>
</ul>
</li>
</ul>
</div>
</nav>
An inverse themed alternative to nav local is also available.
<nav class="navbar navbar-local navbar-inverse">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed">
Menu <svg class="cyclops-icon" aria-hidden="true"><use xlink:href='#icon-caret-down' /></svg>
</button>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="#navLocal">Events</a></li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#navLocal" role="button" aria-haspopup="true" aria-expanded="false">Policies <svg class="cyclops-icon" aria-hidden="true"><use xlink:href='#icon-caret-down' /></svg></a>
<ul class="dropdown-menu">
<li class="active"><a href="#navLocal">Alert</a></li>
<li><a href="#navLocal">Suppression</a></li>
</ul>
</li>
<li><a href="#navLocal">Integrations</a></li>
<li class="disabled"><a href="#navLocal">Disabled</a></li>
<li class="active dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#navLocal" role="button" aria-haspopup="true" aria-expanded="false">Settings <svg class="cyclops-icon" aria-hidden="true"><use xlink:href='#icon-caret-down' /></svg></a>
<ul class="dropdown-menu">
<li><a href="#navLocal">Profile</a></li>
<li><a href="#navLocal">Account</a></li>
<li><a href="#navLocal">Billing</a></li>
<li><a href="#navLocal">Notifications</a></li>
<li><a href="#navLocal">SSH Keys</a></li>
</ul>
</li>
</ul>
</div>
</nav>
An alternative to Nav Local, .nav-stacked
is designed to to be 100% of the width of its parent grid column. At smaller viewports, each item in the nav will become inline-block
and display in a single wrapping line.
<div class="nav nav-stacked">
<ul class="tabs">
<li class="tab"><a href="#">Home</a></li>
<li class="tab selected"><a href="#">Products</a></li>
<li class="tab"><a href="#">Services</a></li>
<li class="tab"><a href="#">About</a></li>
<li class="tab"><a href="#">Contact</a></li>
</ul>
</div>
Nav Stacked Second Level
A second level maybe added to the Stacked Nav for additional navigation options. However, at small viewports, the second level is not visible. If the second level needs to be visible in all viewport sizes, use the Nav Local pattern instead.
<div class="nav nav-stacked">
<ul class="tabs">
<li class="tab selected">
<a href="#">Products</a>
<ul class="tabs-subnav">
<li><a href="#">Widget</a></li>
<li class="selected"><a href="#">Gizmo</a></li>
<li><a href="#">Snarfblat</a></li>
</ul>
</li>
</ul>
</div>
Nav tabs are useful to display a tabbed set of distinct information related to the main context of the page (e.g. environment variables, logs, and connected services for an Appfog application), but not worth having individual pages. To use, add .nav-tabs
to the .nav
base class.
<ul role="navigation" class="nav nav-tabs">
<li><a href="#">Link</a></li>
<li class="active"><a href="#">Active</a></li>
<li class="disabled"><a href="#">Disabled</a></li>
</ul>
Nav Tabs (w/Overflow)
If you have more tabs than the user has available screen real estate, you
may add an overflow menu to the tab bar.
<ul role="navigation" class="nav nav-tabs" id="my-nav-tabs" data-bind="widget: {name: 'overflowMenu', options: {linkTextAll: 'MENU'}}">
<li><a href="#">Link</a></li>
<li class="active"><a href="#">Active</a></li>
<li class="disabled"><a href="#">Disabled</a></li>
</ul>
<script>
$(function(){
ko.applyBindings({}, $('#my-nav-tabs')[0]);
})
</script>