Global navigation
Nav components are the building blocks for creating the global navigation bar for your experience.
Full nav example
This is an example of how the navigation components can be used together to create a global navigation system for your product experience that is consistent with other global navigation bars across Pluralsight’s apps.
import { AccountIcon, BrowseIcon NotificationsIcon } from '@pluralsight/ps-design-system-icon'import { layout } from '@pluralsight/ps-design-system-core'import NavBar from '@pluralsight/ps-design-system-navbar'import NavBrand from '@pluralsight/ps-design-system-navbrand'import NavItem from '@pluralsight/ps-design-system-navitem'import NavUser from '@pluralsight/ps-design-system-navuser'import NavCookieBanner from '@pluralsight/ps-design-system-navcookiebanner'import React from 'react'function Example() {return <NavBarbrand={<NavBrand logo={<MyLogo />} wordmark="TITLE" />}items={<><divstyle={{marginRight: layout.spacingXXSmall,display: 'inline-block'}}><NavItem icon={<HomeIcon />}>Home</NavItem></div><divstyle={{display: 'inline-block'}}><NavItem icon={<BrowseIcon />} selected>Browse</NavItem></div></>}onMobileMenuClick={() => alert('mobile click')}user={<NavUsername="Jake"planName="Accenture"onClick={() => alert('user click')}/>}utility={<React.Fragment><divstyle={{marginRight: layout.spacingXXSmall,display: 'inline-block'}}><NavItem icon={<NotificationsIcon />} /></div><divstyle={{display: 'inline-block'}}><NavItem icon={<AccountIcon />} /></div></React.Fragment>}/>}export default Examplefunction MyLogo() {return (<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="24" height="24" fill="url(#logo)" /><defs><linearGradient id="logo" x1="0" y1="0" x2="24" y2="24" gradientUnits="userSpaceOnUse"><stop stopColor="#8A99A8" /><stop offset="1" stopColor="#576675" /></linearGradient></defs></svg>)}
Global navigation guidelines
To ensure consistency when navigating across product experiences with different global navigation:
- Always keep the navigation bar height 56px.
- The navigation bar should be fluid and sticky to the left/top/right edges of the browser viewport. This will happen automatically if you use the app frame component.
- The brand, utility, and user elements should always be in the same place to ensure consistency across products. Brand on the left, utility and user on the right.
- The items visible to a user in the product switcher should be the same across all products.
Nav components
NavBar
The nav bar component is the container of the global navigation. It’s 56px tall and should be fluid and sticky to the left/top/right of the browser viewport.
import { colorsPink, layout } from '@pluralsight/ps-design-system-core'import NavBar from '@pluralsight/ps-design-system-navbar'import React from 'react'function Filler(props) {return (<div className="filler">{props.children}<style jsx>{`.filler {display: flex;align-items: center;justify-content: center;color: ${colorsPink[6]};height: 100%;border: 2px dashed ${colorsPink[6]};padding: 0 ${layout.spacingMedium};}`}</style></div>)}function Example() {return (<NavBarbrand={<Filler>Brand</Filler>}items={<Filler>Items</Filler>}user={<Filler>User</Filler>}utility={<Filler>Utility</Filler>}/>)}export default Example
- Install
npm install @pluralsight/ps-design-system-navbar
- Import
import NavBar from '@pluralsight/ps-design-system-navbar'
Name | Type | Description | Default |
---|---|---|---|
brand | React.ReactNode | global product branding |
|
items | React.ReactNode | top-level nav affordances |
|
onMobileMenuClick | Event => () | displays hamburger menu; called on click |
|
utility | React.ReactNode | top-right affordances next to user |
|
user | React.ReactNode | user profile affordance |
|
NavItem
The nav item component is for creating links to pages or as action triggers. A horizontal variant can be used with or without an icon. The vertical variant always requires an icon. The icon-only variant can also be used for very recognizable icons/actions when a label is unecessary.
import { colorsBackgroundDark, layout } from '@pluralsight/ps-design-system-core'import { HomeIcon } from '@pluralsight/ps-design-system-icon'import NavItem from '@pluralsight/ps-design-system-navitem'import React from 'react'function Example() {return (<div className="example-grid"><NavItem icon={<HomeIcon />} menu={<div>placeholder</div>}>Label</NavItem><NavItem icon={<HomeIcon />}>Label</NavItem><NavItem menu={<div>placeholder</div>}>Label</NavItem><NavItem renderContainer={props => <a href="#" {...props} />}>Label</NavItem><NavItem icon={<HomeIcon />} alignment={NavItem.alignments.vertical}>Label</NavItem><NavItemicon={<HomeIcon />}alignment={NavItem.alignments.vertical}menu={<div>placeholder</div>}>Label</NavItem><NavItem icon={<HomeIcon />} /></div>)}export default Example
To override and brand the NavItem
, use the UNSAFE_stylesFor
prop, like so:
import { colorsGradient } from '@pluralsight/ps-design-system-core'import { HomeIcon } from '@pluralsight/ps-design-system-icon'import NavItem from '@pluralsight/ps-design-system-navitem'import React from 'react'function Example() {return (<NavItemicon={<HomeIcon />}selectedUNSAFE_stylesFor={{'navitem__bar--selected': {background: colorsGradient.flowBackground}}}>Flow Selected</NavItem>)}export default Example
NavItem guidelines
- Be prudent with the nav items and the the number you use. Try to keep it to about about 2-5. Organize the items well, use short yet descriptive labels, and use grouping with dropdown menus if you need more items than will fit.
- Use icon only nav items when the icon clearly represents what the nav item is or does. Use tooltips with icon only nav items.
- Install
npm install @pluralsight/ps-design-system-navitem
- Import
import NavItem from '@pluralsight/ps-design-system-navitem'
Name | Type | Description | Default |
---|---|---|---|
alignment |
| orientation of item elements | horizontal |
children | React.ReactNode | label |
|
renderContainer | (props) => React.ReactNode | render custom link element |
|
icon | React.ReactNode | icon displayed |
|
menu | boolean | toggles render of down caret | false |
selected | boolean | toggles active state | false |
NavBrand
The nav brand component creates a consistent use of branding for the icon and logo of an app. It is intended to always be placed at the left end of the nav bar.
import { colorsBackgroundDark, layout } from '@pluralsight/ps-design-system-core'import { HomeIcon } from '@pluralsight/ps-design-system-icon'import NavBrand from '@pluralsight/ps-design-system-navbrand'import React from 'react'function Example() {return (<div className="example-grid"><NavBrand logo={<MyLogo />} wordmark="TITLE" /></div>)}export default Examplefunction MyLogo() {return (<svgwidth="24"height="24"viewBox="0 0 24 24"fill="none"xmlns="http://www.w3.org/2000/svg"><rect width="24" height="24" fill="url(#logo)" /><defs><linearGradientid="logo"x1="0"y1="0"x2="24"y2="24"gradientUnits="userSpaceOnUse"><stop stopColor="#8A99A8" /><stop offset="1" stopColor="#576675" /></linearGradient></defs></svg>)}
The wordmark
in the NavBrand can be any ReactNode
, including an svg that might be helpful for consistent branding.
import { colorsBackgroundDark, layout } from '@pluralsight/ps-design-system-core'import { HomeIcon } from '@pluralsight/ps-design-system-icon'import NavBrand from '@pluralsight/ps-design-system-navbrand'import React from 'react'function Example() {return (<div className="example-grid"><NavBrand logo={<FlowLogo />} wordmark={<FlowWordmark />} /></div>)}export default Exampleconst FlowLogo: React.FC = () => {return (<svg aria-hidden viewBox="0 0 32 32"><defs><linearGradientid="flow-gradient"x1="46.248"y1="48.2732"x2="-33.2531"y2="-36.1648"gradientUnits="userSpaceOnUse"><stop offset="0.15" stopColor="#27AAE1" /><stop offset="0.2" stopColor="#279FD9" /><stop offset="0.51" stopColor="#2968B2" stopOpacity="0.99" /><stop offset="0.74" stopColor="#2B4699" stopOpacity="0.99" /><stop offset="0.86" stopColor="#2B3990" stopOpacity="0.99" /></linearGradient></defs><pathd="M32 4.62132V0H0V32H32V26.4449H19.9037V23.2955H32V20.2217H25.0533V17.0723H32V7.77073H19.9037V4.62132H32ZM16.5982 4.51729C16.9326 4.50504 17.263 4.59298 17.547 4.76984C17.831 4.94669 18.0557 5.20439 18.1923 5.50986C18.3288 5.81533 18.371 6.15463 18.3133 6.48421C18.2556 6.8138 18.1008 7.11864 17.8686 7.3596C17.6365 7.60057 17.3377 7.76666 17.0104 7.83658C16.6832 7.90649 16.3426 7.87703 16.0323 7.75198C15.7219 7.62693 15.456 7.41199 15.2687 7.13475C15.0814 6.85751 14.9812 6.53062 14.9809 6.19602C14.9765 5.97951 15.0149 5.76427 15.0939 5.56262C15.1729 5.36098 15.2909 5.1769 15.4411 5.02095C15.5913 4.86499 15.7709 4.74022 15.9695 4.6538C16.168 4.56737 16.3817 4.52098 16.5982 4.51729ZM7.68908 12.4192C7.70114 12.1022 7.80614 11.7958 7.99101 11.538C8.17589 11.2803 8.43248 11.0826 8.72885 10.9696C9.02522 10.8565 9.34829 10.8331 9.65786 10.9023C9.96742 10.9715 10.2498 11.1302 10.4699 11.3586C10.6899 11.587 10.838 11.8751 10.8956 12.1871C10.9531 12.499 10.9177 12.821 10.7937 13.1129C10.6697 13.4049 10.4626 13.6539 10.1981 13.829C9.93366 14.0042 9.62354 14.0977 9.30634 14.0979C8.86944 14.0892 8.45383 13.9076 8.15065 13.5929C7.84747 13.2782 7.68148 12.8561 7.68908 12.4192ZM16.5935 26.5489C16.2589 26.5621 15.9281 26.475 15.6435 26.2987C15.3588 26.1225 15.1334 25.8652 14.9961 25.5598C14.8589 25.2544 14.816 24.915 14.8731 24.5851C14.9302 24.2553 15.0847 23.95 15.3166 23.7086C15.5485 23.4671 15.8473 23.3005 16.1746 23.2302C16.502 23.1599 16.8428 23.189 17.1535 23.3139C17.4641 23.4388 17.7303 23.6537 17.9178 23.931C18.1054 24.2083 18.2057 24.5354 18.206 24.8702C18.2136 25.3055 18.0489 25.7262 17.7478 26.0406C17.4466 26.3551 17.0334 26.5378 16.5982 26.5489H16.5935ZM22.5187 20.2217H9.32053V17.0723H22.5234L22.5187 20.2217ZM26.7746 10.8492V13.9939H12.6402V10.8492H26.7746Z"fill="url(#flow-gradient)"/></svg>)}const FlowWordmark: React.FC = () => {return (<svgfill="none"height="32"viewBox="0 0 68 32"width="68"xmlns="http://www.w3.org/2000/svg"><pathclipRule="evenodd"d="m31.9376 16.0914v-.04c-.0051-.9708.1833-1.933.5541-2.8301.3709-.8971.9167-1.7112 1.6056-2.3946s1.5071-1.2225 2.4066-1.58566c.8996-.36316 1.8624-.54313 2.8323-.52937 4.1734 0 7.361 3.21873 7.361 7.30213v.0423c.0054.9711-.1827 1.9334-.5534 2.8308s-.9165 1.7118-1.6055 2.3954c-.6889.6837-1.5072 1.223-2.4069 1.5863s-1.8627.5434-2.8328.5296c-4.1734 0-7.361-3.2188-7.361-7.3068zm10.2012 0v-.04c0-1.6705-1.1008-3.1788-2.8402-3.1788-1.7393 0-2.8003 1.4872-2.8003 3.1365v.0423c0 1.6681 1.1009 3.1788 2.8379 3.1788s2.8026-1.4942 2.8026-3.1388zm-22.8179-7.07773h-11.3209v14.08273h4.5208v-4.6073h6.3095v-3.6628h-6.3165v-1.7903h6.8071zm5.9785 0h-4.5279v14.08273h10.8655v-4.0246h-6.3376zm25.3507.00088h-4.7321l4.4222 14.18135h3.9411l2.3778-7.0014 2.3754 7.0014h3.9411l4.4246-14.18135h-4.657l-1.913 6.75945-2.183-6.79939h-3.9011l-2.183 6.79939z"fill="#fff"fillRule="evenodd"/></svg>)}
NavBrand guidelines
- Use the nav brand component to provide consistency between experiences.
- Install
npm install @pluralsight/ps-design-system-navbrand
- Import
import NavBrand from '@pluralsight/ps-design-system-navbrand'
Name | Type | Description | Default |
---|---|---|---|
href | string | destination url; renders anchor |
|
logo | React.ReactNode | brand logo |
|
onClick | Event => void | click handler |
|
wordmark | React.ReactNode | brand logo |
|
NavUser
The nav user component is for actions & settings related to the user. It is intended to always be placed at the right end of the nav bar. For wider screens, text can be displayed for the user’s name and a meta item (such as a plan name) or only a name. When the screen is narrow, the text will be dropped.
import { colorsBackgroundDark, layout } from '@pluralsight/ps-design-system-core'import NavUser from '@pluralsight/ps-design-system-navuser'import React from 'react'function Example() {return (<div className="example-grid--col-3"><NavUsername="Name"meta="Meta"src="https://en.gravatar.com/userimage/8399312/b15448d840afacd0eb18102baf788255.jpeg"/><NavUsername="Name"src="https://en.gravatar.com/userimage/8399312/b15448d840afacd0eb18102baf788255.jpeg"/><NavUser src="https://en.gravatar.com/userimage/8399312/b15448d840afacd0eb18102baf788255.jpeg" /></div>)}export default Example
- Install
npm install @pluralsight/ps-design-system-navuser
- Import
import NavUser from '@pluralsight/ps-design-system-navuser'
Name | Type | Description | Default |
---|---|---|---|
href | string | destination url; renders anchor |
|
onClick | Event => void | click handler |
|
meta | React.ReactNode | user context |
|
name | React.ReactNode | user name |
|
src | string | user profile image url |
|
NavCookieBanner
The nav cookie banner is common nav element that should be present on the page in order to comply with laws requiring notice that cookies are used in our product. It will be affixed to the bottom/left of the app frame.
import NavCookieBanner from '@pluralsight/ps-design-system-navcookiebanner'import React from 'react'function Example() {return (<div className="example"><NavCookieBanner /><style jsx>{`.example > div {position: static;display: inline-flex;}`}</style></div>)}export default Example
- Install
npm install @pluralsight/ps-design-system-navcookiebanner
- Import
import NavCookieBanner from '@pluralsight/ps-design-system-navcookiebanner'
Name | Type | Description | Default |
---|---|---|---|
cookieOptions | { domain: string, expires: Date, secure: boolean, sameSite: string } | attributes of cookie |
|
message | React.ReactNode | messaging re cookies |
|
privacyUpdatedDate | Date | date of last terms update |
|
Accessibility
WCAG 2.1 AA Compliance
100% axe-core testsManual audit
WAI-ARIA Patterns: Navigation (role), Link, Menu Button