rename verticalnav to collapsiblemenu

This commit is contained in:
Red Adaya 2024-10-16 09:22:10 +08:00
parent 80aa776850
commit 5ed57ef1e5
4 changed files with 30 additions and 44 deletions

View File

@ -3,35 +3,35 @@
@import "../mixins.less"; @import "../mixins.less";
.verticalnav { .collapsible-menu {
list-style: none; list-style: none;
padding: 0; padding: 0;
} }
.verticalnav-item { .collapsible-menu-item {
padding: 10px; padding: 10px;
cursor: pointer; cursor: pointer;
user-select: none; user-select: none;
padding: 0; padding: 0;
} }
.verticalnav-item-button { .collapsible-menu-item-button {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
width: 100%; width: 100%;
} }
.verticalnav-item-content { .collapsible-menu-item-content {
display: flex; display: flex;
align-items: center; align-items: center;
} }
.verticalnav-item-icon { .collapsible-menu-item-icon {
margin-right: 10px; /* Space between icon and text */ margin-right: 10px; /* Space between icon and text */
} }
.verticalnav-item-text { .collapsible-menu-item-text {
.ellipsis(); .ellipsis();
text-decoration: none; text-decoration: none;
} }
@ -49,7 +49,7 @@
display: none; display: none;
} }
.verticalnav-item-button { .collapsible-menu-item-button {
padding: 10px; padding: 10px;
color: var(--main-text-color); color: var(--main-text-color);
@ -59,6 +59,6 @@
} }
} }
.verticalnav-item-button.clickable:hover { .collapsible-menu-item-button.clickable:hover {
background-color: #f0f0f0; background-color: #f0f0f0;
} }

View File

@ -3,13 +3,11 @@
import { Meta, StoryObj } from "@storybook/react"; import { Meta, StoryObj } from "@storybook/react";
import { Avatar } from "./avatar"; import { Avatar } from "./avatar";
import { VerticalNav } from "./verticalnav"; // Updated import to use VerticalNav import { CollapsibleMenu } from "./collapsiblemenu";
import "./verticalnav.less"; // Updated stylesheet import const meta: Meta<typeof CollapsibleMenu> = {
title: "Elements/CollapsibleMenu",
const meta: Meta<typeof VerticalNav> = { component: CollapsibleMenu,
title: "Elements/VerticalNav", // Updated title to reflect the component name change
component: VerticalNav,
argTypes: { argTypes: {
items: { control: "object" }, items: { control: "object" },
renderItem: { control: false }, renderItem: { control: false },
@ -52,7 +50,6 @@ const nestedItems = [
icon: <i className="fa-sharp fa-solid fa-inbox"></i>, icon: <i className="fa-sharp fa-solid fa-inbox"></i>,
onClick: () => console.log("Inbox clicked"), onClick: () => console.log("Inbox clicked"),
subItems: [ subItems: [
// Updated `children` to `subItems` to match the new type
{ {
label: "Starred", label: "Starred",
icon: <i className="fa-sharp fa-solid fa-star"></i>, icon: <i className="fa-sharp fa-solid fa-star"></i>,
@ -80,7 +77,7 @@ const nestedItems = [
const customRenderItem = ( const customRenderItem = (
item: MenuItem, item: MenuItem,
isOpen: boolean, isOpen: boolean,
handleClick: (e: React.MouseEvent<any>, item: MenuItem, itemKey: string) => void // Updated to pass the correct signature handleClick: (e: React.MouseEvent<any>, item: MenuItem, itemKey: string) => void
) => ( ) => (
<div className="custom-list-item"> <div className="custom-list-item">
<span className="custom-list-item-icon" onClick={(e) => handleClick(e, item, `${item.label}`)}> <span className="custom-list-item-icon" onClick={(e) => handleClick(e, item, `${item.label}`)}>
@ -99,7 +96,7 @@ export const Default: Story = {
}, },
render: (args) => ( render: (args) => (
<Container> <Container>
<VerticalNav {...args} /> <CollapsibleMenu {...args} />
</Container> </Container>
), ),
}; };
@ -110,7 +107,7 @@ export const NestedList: Story = {
}, },
render: (args) => ( render: (args) => (
<Container> <Container>
<VerticalNav {...args} /> <CollapsibleMenu {...args} />
</Container> </Container>
), ),
}; };
@ -122,7 +119,7 @@ export const CustomRender: Story = {
}, },
render: (args) => ( render: (args) => (
<Container> <Container>
<VerticalNav {...args} /> <CollapsibleMenu {...args} />
</Container> </Container>
), ),
}; };
@ -133,7 +130,7 @@ export const WithClickHandlers: Story = {
}, },
render: (args) => ( render: (args) => (
<Container> <Container>
<VerticalNav {...args} /> <CollapsibleMenu {...args} />
</Container> </Container>
), ),
}; };
@ -144,7 +141,7 @@ export const NestedWithClickHandlers: Story = {
}, },
render: (args) => ( render: (args) => (
<Container> <Container>
<VerticalNav {...args} /> <CollapsibleMenu {...args} />
</Container> </Container>
), ),
}; };
@ -171,14 +168,3 @@ const avatarItems = [
onClick: () => console.log("Alice Lambert clicked"), onClick: () => console.log("Alice Lambert clicked"),
}, },
]; ];
export const WithAvatars: Story = {
args: {
items: avatarItems,
},
render: (args) => (
<Container>
<VerticalNav {...args} /> {/* Updated to use VerticalNav */}
</Container>
),
};

View File

@ -3,7 +3,7 @@
import clsx from "clsx"; import clsx from "clsx";
import React, { memo, useState } from "react"; import React, { memo, useState } from "react";
import "./verticalnav.less"; import "./collapsiblemenu.less";
interface VerticalNavProps { interface VerticalNavProps {
items: MenuItem[]; items: MenuItem[];
@ -15,7 +15,7 @@ interface VerticalNavProps {
) => React.ReactNode; ) => React.ReactNode;
} }
const VerticalNav = memo(({ items, className, renderItem }: VerticalNavProps) => { const CollapsibleMenu = memo(({ items, className, renderItem }: VerticalNavProps) => {
const [open, setOpen] = useState<{ [key: string]: boolean }>({}); const [open, setOpen] = useState<{ [key: string]: boolean }>({});
// Helper function to generate a unique key for each item based on its path in the hierarchy // Helper function to generate a unique key for each item based on its path in the hierarchy
@ -34,19 +34,19 @@ const VerticalNav = memo(({ items, className, renderItem }: VerticalNavProps) =>
const hasChildren = item.subItems && item.subItems.length > 0; const hasChildren = item.subItems && item.subItems.length > 0;
return ( return (
<li key={itemKey} className="verticalnav-item"> <li key={itemKey} className="collapsible-menu-item">
{renderItem ? ( {renderItem ? (
renderItem(item, isOpen, (e) => handleClick(e, item, itemKey)) renderItem(item, isOpen, (e) => handleClick(e, item, itemKey))
) : ( ) : (
<div className="verticalnav-item-button" onClick={(e) => handleClick(e, item, itemKey)}> <div className="collapsible-menu-item-button" onClick={(e) => handleClick(e, item, itemKey)}>
<div <div
className={clsx("verticalnav-item-content", { className={clsx("collapsible-menu-item-content", {
"has-children": hasChildren, "has-children": hasChildren,
"is-open": isOpen && hasChildren, "is-open": isOpen && hasChildren,
})} })}
> >
{item.icon && <div className="verticalnav-item-icon">{item.icon}</div>} {item.icon && <div className="collapsible-menu-item-icon">{item.icon}</div>}
<div className="verticalnav-item-text">{item.label}</div> <div className="collapsible-menu-item-text">{item.label}</div>
</div> </div>
{hasChildren && ( {hasChildren && (
<i className={`fa-sharp fa-solid ${isOpen ? "fa-angle-up" : "fa-angle-down"}`}></i> <i className={`fa-sharp fa-solid ${isOpen ? "fa-angle-up" : "fa-angle-down"}`}></i>
@ -65,12 +65,12 @@ const VerticalNav = memo(({ items, className, renderItem }: VerticalNavProps) =>
}; };
return ( return (
<ul className={clsx("verticalnav", className)} role="navigation"> <ul className={clsx("collapsible-menu", className)} role="navigation">
{items.map((item, index) => renderListItem(item, index, "root"))} {items.map((item, index) => renderListItem(item, index, "root"))}
</ul> </ul>
); );
}); });
VerticalNav.displayName = "VerticalNav"; CollapsibleMenu.displayName = "CollapsibleMenu";
export { VerticalNav }; export { CollapsibleMenu };

View File

@ -1,10 +1,10 @@
// Copyright 2024, Command Line Inc. // Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
import { VerticalNav } from "@/app/element/verticalnav"; import { CollapsibleMenu } from "@/app/element/collapsiblemenu";
import "./channels.less"; import "./channels.less";
const Channels = ({ channels }: { channels: MenuItem[] }) => { const Channels = ({ channels }: { channels: MenuItem[] }) => {
return <VerticalNav className="channel-list" items={channels}></VerticalNav>; return <CollapsibleMenu className="channel-list" items={channels}></CollapsibleMenu>;
}; };
export { Channels }; export { Channels };