Example of Sidebar, where the selected item/section remains expanded and marked #3914
-
Hello all, I have gone through the docs and put together a Sidebar in my nextjs app. The way I have it, is basically a list of the nav items in its own file, for example export const navigationItems = [
{
id: 'item1',
label: 'item1',
href: null,
icon: Icon,
children: [
{
id: 'overview',
label: 'Overview',
href: '/item1/overview',
icon: null
}, And then in the component I render them recursively as shown below. If the item has children, we use .map and add the same Component, until there are no more children. When we reach a leaf, we use Paste's SidebarNavigationItem const SidebarNavItem = ({ item, setActiveItemId, currentActiveItemId }) => {
const hasChildren = item.children && item.children.length > 0;
const iconProps = item.icon ? <item.icon decorative={true}/> : null;
const disclosure = useSidebarNavigationDisclosureState();
if (hasChildren) {
return (
<SidebarNavigationDisclosure >
<SidebarNavigationDisclosureHeadingWrapper>
<SidebarNavigationDisclosureHeading icon={iconProps}>
{item.label}
</SidebarNavigationDisclosureHeading>
</SidebarNavigationDisclosureHeadingWrapper>
<SidebarNavigationDisclosureContent>
{item.children.map((childItem) => (
<SidebarNavItem
key={childItem.id}
item={childItem}
setActiveItemId={setActiveItemId}
/>
))}
</SidebarNavigationDisclosureContent>
</SidebarNavigationDisclosure>
);
}
return (
<SidebarNavigationItem
href={item.href}
onClick={() => {disclosure.toggle();setActiveItemId(item.id)}}
icon={iconProps}
selected = { currentActiveItemId === item.id ? true : false}
>
{item.label}
</SidebarNavigationItem>
);
};
export default SidebarNavItem The behaviour i see is that I can open and reach any node just fine, but when clicked the nav bar completely resets. I am trying to achieve what I see in Paste's site, where when expanded and clicked, it stays there (and the rest of the bar is reset, but not the current path) I have tried to follow examples but I am not sure I have found something that focuses on that behaviour. Sorry - very new to Paste |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 4 replies
-
Disclaimer: This is a very experimental bot using OpenAI's GPT-4. The answers may not be correct, a human will review the answer and update it if necessary. Hello! To achieve the behavior you're describing, where the sidebar maintains its expanded state for the current path while collapsing others, you need to manage the state of each Based on the Paste documentation and your description, here's an approach you can take:
Here's a modified version of your const SidebarNavItem = ({ item, setActiveItemId, currentActiveItemId }) => {
const hasChildren = item.children && item.children.length > 0;
const iconProps = item.icon ? <item.icon decorative={true} /> : null;
// Determine if the current item or any of its children is the active item
const isActiveOrParentOfActiveItem = useMemo(() => {
const isActiveItem = item.id === currentActiveItemId;
const isParentOfActiveItem = item.children?.some(child => child.id === currentActiveItemId);
return isActiveItem || isParentOfActiveItem;
}, [item, currentActiveItemId]);
// Use the state to control the disclosure based on the active item
const disclosure = useSidebarNavigationDisclosureState({visible: isActiveOrParentOfActiveItem});
if (hasChildren) {
return (
<SidebarNavigationDisclosure state={disclosure}>
<SidebarNavigationDisclosureHeadingWrapper>
<SidebarNavigationDisclosureHeading icon={iconProps}>
{item.label}
</SidebarNavigationDisclosureHeading>
</SidebarNavigationDisclosureHeadingWrapper>
<SidebarNavigationDisclosureContent>
{item.children.map((childItem) => (
<SidebarNavItem
key={childItem.id}
item={childItem}
setActiveItemId={setActiveItemId}
currentActiveItemId={currentActiveItemId}
/>
))}
</SidebarNavigationDisclosureContent>
</SidebarNavigationDisclosure>
);
}
return (
<SidebarNavigationItem
href={item.href}
onClick={() => {disclosure.toggle(); setActiveItemId(item.id);}}
icon={iconProps}
selected={currentActiveItemId === item.id}
>
{item.label}
</SidebarNavigationItem>
);
};
export default SidebarNavItem; This example uses For more details on implementing the
Remember, the key to achieving the desired behavior is correctly managing the state of each disclosure to ensure it remains open when it or its children are the active item. I also did a search, and I managed to find these other Discussions that might be similar or related to your question. Give them a read to see if they answer your question. If they do, head back here and update this discussion and mark it as answered, pointing others to the related discussion:
|
Beta Was this translation helpful? Give feedback.
-
Hey @evanTheTerribleWarrior - did following the Paste website's Sidebar code help? |
Beta Was this translation helpful? Give feedback.
-
Ok figured it out. the culprit was here Unless there is anything else you want to point out to me to be aware of, we can close this |
Beta Was this translation helpful? Give feedback.
Ok figured it out. the culprit was here
https://github.com/twilio-labs/paste/blob/main/packages/paste-website/src/components/site-wrapper/sidebar/SidebarAnchor.tsx
I needed to wrap the SidebarNavigationItem with "Link", and now seems to work.
Without Link, it seems that every time i clicked a page, it was basically doing a full refresh and therefore this caused the whole thing to reset.
Unless there is anything else you want to point out to me to be aware of, we can close this