diff --git a/frontend/app/element/dropdown.less b/frontend/app/element/dropdown.less index d81f79dc..9918916f 100644 --- a/frontend/app/element/dropdown.less +++ b/frontend/app/element/dropdown.less @@ -35,12 +35,4 @@ float: right; } } - - .sub-dropdown { - position: absolute; - top: 0; - left: 100%; - min-width: 100%; - white-space: nowrap; - } } diff --git a/frontend/app/element/dropdown.stories.tsx b/frontend/app/element/dropdown.stories.tsx index cc79cc9e..aeb07568 100644 --- a/frontend/app/element/dropdown.stories.tsx +++ b/frontend/app/element/dropdown.stories.tsx @@ -85,6 +85,14 @@ export const Test: Story = { subItems: [ { label: "Option 3 -> 3 -> 1", onClick: () => null }, { label: "Option 3 -> 3 -> 2", onClick: () => null }, + { + label: "Option 3 -> 3", + onClick: () => console.log("Clicked Option 3"), + subItems: [ + { label: "Option 3 -> 3 -> 1", onClick: () => null }, + { label: "Option 3 -> 3 -> 2", onClick: () => null }, + ], + }, ], }, ], diff --git a/frontend/app/element/dropdown.tsx b/frontend/app/element/dropdown.tsx index 113e0953..0aed4bef 100644 --- a/frontend/app/element/dropdown.tsx +++ b/frontend/app/element/dropdown.tsx @@ -188,11 +188,36 @@ const Dropdown = memo(({ items, anchorRef, boundaryRef, className }: DropdownPro ) => { event.stopPropagation(); + // Build the full key for the current item const key = parentKey ? `${parentKey}-${index}` : `${index}`; setVisibleSubMenus((prev) => { + // Create a copy of the previous state const updatedState = { ...prev }; + + // Ensure the current submenu and its ancestors are visible updatedState[key] = { visible: true, label: item.label }; + + // Extract ancestors of the key (e.g., "2-2-1" -> "2-2" -> "2") + const ancestors = key.split("-").reduce((acc, part, idx) => { + if (idx === 0) return [part]; + return [...acc, `${acc[idx - 1]}-${part}`]; + }, [] as string[]); + + // Mark ancestors visible + ancestors.forEach((ancestorKey) => { + if (updatedState[ancestorKey]) { + updatedState[ancestorKey].visible = true; + } + }); + + // Hide any submenu that is not part of the current hierarchy + for (const pkey in updatedState) { + if (!ancestors.includes(pkey) && pkey !== key) { + updatedState[pkey].visible = false; + } + } + return updatedState; });