VerticalBar
A vertical bar is a flexible container that organizes items vertically.
install | yarn add @clayui/core |
---|---|
version | 3.120.0 |
Example
Introduction
VerticalBar allows rendering a vertical navigation bar positioned fixedly on the right or left side with the Panel that can contain any element referring to the desired action. An item in the vertical bar also does not need to have an equivalent panel, it can be an action button or link to be navigated.
Just like the TreeView component, the VerticalBar is considered a middle-level component instead of a low-level or high-level, it guarantees more flexibility and composition and delivers features that would only be available at high-level with the same synthetic form of an API low-level.
Content
As VerticalBar is middle-level, it allows you to build static or dynamic content if you need to consume data from some service.
The component controls the OOTB state to toggle the visibility of the panels ie you can quickly build with zero-config, either defining static or dynamic content.
<VerticalBar>
<VerticalBar.Content>
<VerticalBar.Panel>Tag</VerticalBar.Panel>
<VerticalBar.Panel>Message</VerticalBar.Panel>
</VerticalBar.Content>
<VerticalBar.Bar>
<VerticalBar.Item>
<Button displayType={null}>
<Icon symbol="tag" />
</Button>
</VerticalBar.Item>
<VerticalBar.Item divider>
<Button displayType={null}>
<Icon symbol="message" />
</Button>
</VerticalBar.Item>
<VerticalBar.Item>
<Button
displayType={null}
onClick={(event) => {
event.preventDefault();
// Dispatch some action
}}
>
<Icon symbol="effects" />
</Button>
</VerticalBar.Item>
</VerticalBar.Bar>
</VerticalBar>
The declaration order is important for the component to know which Panel should be visible when the user clicks on some button on the bar, this can also be configurable if the key
property is set in both components to associate a unique id and create the relationship.
<VerticalBar>
<VerticalBar.Content>
<VerticalBar.Panel key="tag">Tag</VerticalBar.Panel>
</VerticalBar.Content>
<VerticalBar.Bar>
<VerticalBar.Item key="tag">
<Button displayType={null}>
<Icon symbol="tag" />
</Button>
</VerticalBar.Item>
</VerticalBar.Bar>
</VerticalBar>
Static
Declaring components and the list of panels and hard coded items that are not configured by any user or maintained in a data service is considered static content, as in this example:
<VerticalBar>
<VerticalBar.Content>
<VerticalBar.Panel>Tag</VerticalBar.Panel>
<VerticalBar.Panel>Message</VerticalBar.Panel>
<VerticalBar.Panel>Effects</VerticalBar.Panel>
</VerticalBar.Content>
<VerticalBar.Bar>
<VerticalBar.Item>
<Button displayType={null}>
<Icon symbol="tag" />
</Button>
</VerticalBar.Item>
<VerticalBar.Item divider>
<Button displayType={null}>
<Icon symbol="message" />
</Button>
</VerticalBar.Item>
<VerticalBar.Item>
<Button displayType={null}>
<Icon symbol="effects" />
</Button>
</VerticalBar.Item>
</VerticalBar.Bar>
</VerticalBar>
Dynamic
Dynamic content is related when the component is configured through a data source or dynamic collection that can change during the component's lifetime.
To make a component dynamic is only possible by using the properties of items
and converting the children
of the components to render props of <VerticalBar.Content />
and <VerticalBar.Bar />
respectively being the panels and the vertical bar items.
const items = [
{
icon: 'tag',
title: 'Tag',
},
{
divider: true,
icon: 'message',
title: 'Message',
},
{
icon: 'effects',
title: 'Effects',
},
];
return (
<VerticalBar defaultActive="Tag">
<VerticalBar.Content items={items}>
{(item) => (
<VerticalBar.Panel key={item.title}>
{item.title}
</VerticalBar.Panel>
)}
</VerticalBar.Content>
<VerticalBar.Bar items={items}>
{(item) => (
<VerticalBar.Item divider={item.divider} key={item.title}>
<Button displayType={null}>
<Icon symbol={item.icon} />
</Button>
</VerticalBar.Item>
)}
</VerticalBar.Bar>
</VerticalBar>
);
Position
Positioning the VerticalBar on the right or left side is possible by setting the position
property and changing the declaration order of the <VerticalBar.Panel />
and <VerticalBar.Bar />
components.
<VerticalBar position="left">
<VerticalBar.Bar></VerticalBar.Bar>
<VerticalBar.Content></VerticalBar.Content>
</VerticalBar>
Resize
The property resize
in <VerticalBar.Bar />
enables the user to increase or decrease the panel width using the mouse or keyboard. The maximum width can be set using the property panelWidthMax
. It defaults to 500px. The minimum width is set using the property panelWidthMin
and defaults to 280px. The starting width is set using panelWidth
with a default value of 320px.
The property onPanelWidthChange
accepts a callback function that executes when the panelWidth
is updated. The callback function has the value of the panel width as the parameter. It can be used to make updates to other parts of your application, such as pushing body content over as the user resizes the Vertical Bar Panel.
Load lazy panel
The possibility of lazy loading the panel content is a strategy to reduce the application's bundle and load it only when it is used. Implementing in the Vertical Bar is also simple using the React.js support components, with <Suspense />
and React.lazy
.
const TagPanel = React.lazy(() => import('./TagPanel'));
const MessagePanel = React.lazy(() => import('./MessagePanel'));
export const LoadLazyPanel = () => {
const items = [
{
icon: 'tag',
panel: TagPanel,
title: 'Tag',
},
{
divider: true,
icon: 'message',
panel: MessagePanel,
title: 'Message',
},
];
return (
<VerticalBar>
<VerticalBar.Content displayType="light" items={items}>
{({panel: PanelLazy, title}) => (
<VerticalBar.Panel key={title}>
<Suspense fallback={<div>Loading...</div>}>
<PanelLazy />
</Suspense>
</VerticalBar.Panel>
)}
</VerticalBar.Content>
<VerticalBar.Bar displayType="light" items={items}>
{(item) => (
<VerticalBar.Item divider={item.divider} key={item.title}>
<Button displayType={null}>
<Icon symbol={item.icon} />
</Button>
</VerticalBar.Item>
)}
</VerticalBar.Bar>
</VerticalBar>
);
};
You can also use the <ErrorBoundary />
above the <Suspense />
to capture error and render some screen as a fallback, for example, if it was a network error, render a fallback with a retry reload button to fetch component again.
<VerticalBar.Content displayType="light" items={items}>
{({panel: PanelLazy, title}) => (
<VerticalBar.Panel key={title}>
<ErrorBoundary>
<Suspense fallback={<div>Loading...</div>}>
<PanelLazy />
</Suspense>
</ErrorBoundary>
</VerticalBar.Panel>
)}
</VerticalBar.Content>