A sidebar is triggered via React Context. This context is already provided via the VitalityProvider that should be included at the root level of your app.
import { SidebarContext } from "@vitality-ds/components";
Sidebars can be used to surface up useful and relevant information to support the user's current context. As it appears along side the current page content, the sidebar allows users to maintain focus on their current task whilst retrieving additional information that may help successfully perform the task. Examples include patient details for letter writing, appointment information or even app extensions and third party integrations.
A sidebar can contain internal navigation such as tabs and breadcrumbs, however the internal navigation state should be kept simple as the state will not be maintained as broader page navigation changes.
To present the sidebar to the user, you call openSidebar(content)
from the SidebarContext, with content
representing the react component you wish to load.
() => { const { openSidebar, closeSidebar } = React.useContext(SidebarContext); const ExampleContent = () => ( <> <Typography variant="sectionTitle">Admin Notes</Typography> <Typography> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin ut rutrum risus. Suspendisse egestas mi eget enim laoreet, sit amet rhoncus tellus euismod. Integer sodales justo eget dui tempor, porttitor consequat nibh elementum. Nullam lectus lacus, molestie vel auctor eu, hendrerit vel sapien. Vivamus ac cursus risus, id efficitur nunc. Pellentesque ultrices metus sed luctus vestibulum. Vestibulum lacinia egestas est, eget facilisis lectus posuere ac. Integer ut pulvinar tellus. Suspendisse potenti. Vestibulum pulvinar tempus magna. </Typography> </> ); return ( <Stack direction="horizontal"> <Button onClick={() => openSidebar(<ExampleContent />)}>Open</Button> <Button onClick={() => closeSidebar()}>Close</Button> </Stack> ); };
Besides a "close" button, the sidebar itself is intended to be unopinionated of its contents. This leaves the choices about contents and implementation up to the user. Common examples include:
- simple static content – for instance a "how-to" guide.
- asynchonous content with a loading state
- third-party app content and micro frontends (MFEs)
When presented to the user, the sidebar will always appear docked to the right of the viewport and it will shift the app content to the left. You don't need to implement any of the styles for this as the VitalityProvider
which wraps your app will add a margin-right to the app shell when the sidebar is opened.
You can access the state of the sidebar by accessing its context value. A common way to have the certain UI elements respond to the Sidebar being open. Below is an example of how to approach this by using the SidebarContext
to get the isSidebarOpen
prop and conditionally set the style:
() => { const { isSidebarOpen, openSidebar, closeSidebar, TRANSITION_DURATION, SIDEBAR_WIDTH, } = React.useContext(SidebarContext); const handleClick = isSidebarOpen ? closeSidebar : () => openSidebar(<>Content</>); const style = React.useMemo( () => ({ padding: 32, backgroundColor: isSidebarOpen ? "rgb(127 255 212 / 21%)" : "rgb(255 127 80 / 28%)", transition: `all ${TRANSITION_DURATION}ms ease`, marginRight: isSidebarOpen ? SIDEBAR_WIDTH : 0, "--vitality-sidebar-width": isSidebarOpen ? `${SIDEBAR_WIDTH}px` : "0px", }), [isSidebarOpen, TRANSITION_DURATION, SIDEBAR_WIDTH] ); return ( <div style={style}> <Button appearance="primary" onClick={handleClick}> Toggle </Button> </div> ); };
Unlike a Drawer
component, a Sidebar is a global UX pattern that has consistent behaviour throughout a product. Thus, the vertical positioning is set globally. A common reason to use the offset is for instances where you want the app's sidebar to always appear beneath a navigation bar. In that case, you'd set the topOffset
value to the nav's height in pixels.
<VitalityProvider config={{ sidebar: { topOffset: 78 } }}> {children} </VitalityProvider>
On @bp1
and below, the Sidebar will mimic the behaviour of a Drawer
component – partially covering the content underneath.
The below table illustrates the values / methods available when accessing the SidebarContext.