mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
hide dropdown when an item is clicked
This commit is contained in:
@@ -40,6 +40,28 @@ export const Test: Story = {
|
||||
setIsDropdownVisible((prev) => !prev);
|
||||
};
|
||||
|
||||
const mapItemsWithClick = (items: any[]) => {
|
||||
return items.map((item) => ({
|
||||
...item,
|
||||
onClick: () => {
|
||||
// Call the original onClick if it exists
|
||||
if (item.onClick) {
|
||||
item.onClick();
|
||||
}
|
||||
// Close the dropdown after an item is clicked
|
||||
setIsDropdownVisible(false);
|
||||
},
|
||||
// Recursively update subItems' onClick handlers
|
||||
subItems: item.subItems ? mapItemsWithClick(item.subItems) : undefined,
|
||||
}));
|
||||
};
|
||||
|
||||
// Modify args to include updated items with the new onClick behavior
|
||||
const modifiedArgs = {
|
||||
...args,
|
||||
items: mapItemsWithClick(args.items),
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={boundaryRef}
|
||||
@@ -60,39 +82,50 @@ export const Test: Story = {
|
||||
Anchor Element
|
||||
</div>
|
||||
</div>
|
||||
{isDropdownVisible && <Dropdown {...args} anchorRef={anchorRef} boundaryRef={boundaryRef} />}
|
||||
{isDropdownVisible && <Dropdown {...modifiedArgs} anchorRef={anchorRef} boundaryRef={boundaryRef} />}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
args: {
|
||||
items: [
|
||||
{ label: "Option 1", onClick: () => null },
|
||||
{ label: "Option 1", onClick: (e) => console.log("Clicked Option 1") },
|
||||
{
|
||||
label: "Option 2",
|
||||
onClick: () => console.log("Clicked Option 2"),
|
||||
onClick: (e) => console.log("Clicked Option 2"),
|
||||
subItems: [
|
||||
{ label: "Option 2 -> 1", onClick: () => null },
|
||||
{ label: "Option 2 -> 2", onClick: () => null },
|
||||
{ label: "Option 2 -> 1", onClick: (e) => console.log("Clicked Option 2 -> 1") },
|
||||
{ label: "Option 2 -> 2", onClick: (e) => console.log("Clicked Option 2 -> 2") },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Option 3",
|
||||
onClick: () => console.log("Clicked Option 3"),
|
||||
onClick: (e) => console.log("Clicked Option 3"),
|
||||
subItems: [
|
||||
{ label: "Option 3 -> 1", onClick: () => null },
|
||||
{ label: "Option 3 -> 2", onClick: () => null },
|
||||
{ label: "Option 3 -> 1", onClick: (e) => console.log("Clicked Option 3 -> 1") },
|
||||
{ label: "Option 3 -> 2", onClick: (e) => console.log("Clicked Option 3 -> 2") },
|
||||
{
|
||||
label: "Option 3 -> 3",
|
||||
onClick: () => console.log("Clicked Option 3"),
|
||||
onClick: (e) => console.log("Clicked Option 3 -> 3"),
|
||||
subItems: [
|
||||
{ label: "Option 3 -> 3 -> 1", onClick: () => null },
|
||||
{ label: "Option 3 -> 3 -> 2", onClick: () => null },
|
||||
{ label: "Option 3 -> 3 -> 1", onClick: (e) => console.log("Clicked Option 3 -> 3 -> 1") },
|
||||
{ label: "Option 3 -> 3 -> 2", onClick: (e) => console.log("Clicked Option 3 -> 3 -> 2") },
|
||||
{ label: "Option 3 -> 3 -> 3", onClick: (e) => console.log("Clicked Option 3 -> 3 -> 3") },
|
||||
{
|
||||
label: "Option 3 -> 3",
|
||||
onClick: () => console.log("Clicked Option 3"),
|
||||
label: "Option 3 -> 3 -> 4",
|
||||
onClick: (e) => console.log("Clicked Option 3 -> 3 -> 4"),
|
||||
subItems: [
|
||||
{ label: "Option 3 -> 3 -> 1", onClick: () => null },
|
||||
{ label: "Option 3 -> 3 -> 2", onClick: () => null },
|
||||
{
|
||||
label: "Option 3 -> 3 -> 4 -> 1",
|
||||
onClick: (e) => console.log("Clicked Option 3 -> 3 -> 4 -> 1"),
|
||||
},
|
||||
{
|
||||
label: "Option 3 -> 3 -> 4 -> 2",
|
||||
onClick: (e) => console.log("Clicked Option 3 -> 3 -> 4 -> 2"),
|
||||
},
|
||||
{
|
||||
label: "Option 3 -> 3 -> 4 -> 3",
|
||||
onClick: (e) => console.log("Clicked Option 3 -> 3 -> 4 -> 3"),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
@@ -101,19 +134,15 @@ export const Test: Story = {
|
||||
},
|
||||
{
|
||||
label: "Option 4",
|
||||
onClick: () => console.log("Clicked Option 3"),
|
||||
onClick: (e) => console.log("Clicked Option 4"),
|
||||
subItems: [
|
||||
{ label: "Option 4 -> 1", onClick: () => null },
|
||||
{ label: "Option 4 -> 2", onClick: () => null },
|
||||
{ label: "Option 4 -> 4", onClick: () => null },
|
||||
{ label: "Option 4 -> 4", onClick: () => null },
|
||||
{ label: "Option 4 -> 5", onClick: () => null },
|
||||
{ label: "Option 4 -> 6", onClick: () => null },
|
||||
{ label: "Option 4 -> 7", onClick: () => null },
|
||||
{ label: "Option 4 -> 8", onClick: () => null },
|
||||
{ label: "Option 4 -> 9", onClick: () => null },
|
||||
{ label: "Option 4 -> 10", onClick: () => null },
|
||||
{ label: "Option 4 -> 11", onClick: () => null },
|
||||
{ label: "Option 4 -> 1", onClick: (e) => console.log("Clicked Option 4 -> 1") },
|
||||
{ label: "Option 4 -> 2", onClick: (e) => console.log("Clicked Option 4 -> 2") },
|
||||
{ label: "Option 4 -> 3", onClick: (e) => console.log("Clicked Option 4 -> 3") },
|
||||
{ label: "Option 4 -> 4", onClick: (e) => console.log("Clicked Option 4 -> 4") },
|
||||
{ label: "Option 4 -> 5", onClick: (e) => console.log("Clicked Option 4 -> 5") },
|
||||
{ label: "Option 4 -> 6", onClick: (e) => console.log("Clicked Option 4 -> 6") },
|
||||
{ label: "Option 4 -> 7", onClick: (e) => console.log("Clicked Option 4 -> 7") },
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -12,16 +12,25 @@ const SubMenu = memo(
|
||||
subMenuPosition,
|
||||
visibleSubMenus,
|
||||
hoveredItems,
|
||||
handleMouseEnterItem,
|
||||
subMenuRefs,
|
||||
handleMouseEnterItem,
|
||||
handleOnClick,
|
||||
}: {
|
||||
subItems: DropdownItem[];
|
||||
parentKey: string;
|
||||
subMenuPosition: any;
|
||||
visibleSubMenus: any;
|
||||
subMenuPosition: {
|
||||
[key: string]: { top: number; left: number; label: string };
|
||||
};
|
||||
visibleSubMenus: { [key: string]: any };
|
||||
hoveredItems: string[];
|
||||
handleMouseEnterItem: any;
|
||||
subMenuRefs: any;
|
||||
subMenuRefs: React.MutableRefObject<{ [key: string]: React.RefObject<HTMLDivElement> }>;
|
||||
handleMouseEnterItem: (
|
||||
event: React.MouseEvent<HTMLDivElement, MouseEvent>,
|
||||
parentKey: string | null,
|
||||
index: number,
|
||||
item: DropdownItem
|
||||
) => void;
|
||||
handleOnClick: (e: React.MouseEvent<HTMLDivElement>, item: DropdownItem) => void;
|
||||
}) => {
|
||||
// Ensure a ref exists for each submenu
|
||||
subItems.forEach((_, idx) => {
|
||||
@@ -54,8 +63,9 @@ const SubMenu = memo(
|
||||
return (
|
||||
<div
|
||||
key={newKey}
|
||||
className={clsx("dropdown-item", { active: isActive })} // Add "active" class if the item or ancestor is hovered
|
||||
className={clsx("dropdown-item", { active: isActive })}
|
||||
onMouseEnter={(event) => handleMouseEnterItem(event, parentKey, idx, item)}
|
||||
onClick={(e) => handleOnClick(e, item)}
|
||||
>
|
||||
{item.label}
|
||||
{item.subItems && <span className="arrow">▶</span>}
|
||||
@@ -65,8 +75,9 @@ const SubMenu = memo(
|
||||
parentKey={newKey}
|
||||
subMenuPosition={subMenuPosition}
|
||||
visibleSubMenus={visibleSubMenus}
|
||||
hoveredItems={hoveredItems} // Pass hoveredItems to submenus
|
||||
hoveredItems={hoveredItems}
|
||||
handleMouseEnterItem={handleMouseEnterItem}
|
||||
handleOnClick={handleOnClick}
|
||||
subMenuRefs={subMenuRefs}
|
||||
/>
|
||||
)}
|
||||
@@ -81,7 +92,7 @@ const SubMenu = memo(
|
||||
|
||||
type DropdownItem = {
|
||||
label: string;
|
||||
onClick?: () => void;
|
||||
onClick?: (e) => void;
|
||||
subItems?: DropdownItem[];
|
||||
};
|
||||
|
||||
@@ -238,6 +249,11 @@ const Dropdown = memo(
|
||||
handleSubMenuPosition(key, itemRect, dropdownRef, item.label);
|
||||
};
|
||||
|
||||
const handleOnClick = (e: React.MouseEvent<HTMLDivElement>, item: DropdownItem) => {
|
||||
e.stopPropagation();
|
||||
item.onClick && item.onClick(e);
|
||||
};
|
||||
|
||||
return ReactDOM.createPortal(
|
||||
<div
|
||||
className={clsx("dropdown", className)}
|
||||
@@ -253,6 +269,7 @@ const Dropdown = memo(
|
||||
key={key}
|
||||
className={clsx("dropdown-item", { active: isActive })} // Highlight hovered items and ancestors
|
||||
onMouseEnter={(event) => handleMouseEnterItem(event, null, index, item)}
|
||||
onClick={(e) => handleOnClick(e, item)}
|
||||
>
|
||||
{item.label}
|
||||
{item.subItems && <span className="arrow">▶</span>}
|
||||
@@ -262,8 +279,9 @@ const Dropdown = memo(
|
||||
parentKey={key}
|
||||
subMenuPosition={subMenuPosition}
|
||||
visibleSubMenus={visibleSubMenus}
|
||||
hoveredItems={hoveredItems} // Pass hoveredItems to submenus
|
||||
hoveredItems={hoveredItems}
|
||||
handleMouseEnterItem={handleMouseEnterItem}
|
||||
handleOnClick={handleOnClick}
|
||||
subMenuRefs={subMenuRefs}
|
||||
/>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user