|
1 | 1 | // Copyright 2024, Command Line Inc.
|
2 | 2 | // SPDX-License-Identifier: Apache-2.0
|
3 | 3 |
|
4 |
| -import { type Placement, useDismiss, useFloating, useInteractions } from "@floating-ui/react"; |
| 4 | +import { FloatingPortal, type Placement, useDismiss, useFloating, useInteractions } from "@floating-ui/react"; |
5 | 5 | import clsx from "clsx";
|
6 | 6 | import { createRef, Fragment, memo, ReactNode, useRef, useState } from "react";
|
7 | 7 | import ReactDOM from "react-dom";
|
@@ -141,53 +141,55 @@ const MenuComponent = memo(
|
141 | 141 | </div>
|
142 | 142 |
|
143 | 143 | {isOpen && (
|
144 |
| - <div |
145 |
| - className={clsx("menu", className)} |
146 |
| - ref={refs.setFloating} |
147 |
| - style={floatingStyles} |
148 |
| - {...getFloatingProps()} |
149 |
| - > |
150 |
| - {items.map((item, index) => { |
151 |
| - const key = `${index}`; |
152 |
| - const isActive = hoveredItems.includes(key); |
153 |
| - |
154 |
| - const menuItemProps = { |
155 |
| - className: clsx("menu-item", { active: isActive }), |
156 |
| - onMouseEnter: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => |
157 |
| - handleMouseEnterItem(event, null, index, item), |
158 |
| - onClick: (e: React.MouseEvent<HTMLDivElement>) => handleOnClick(e, item), |
159 |
| - }; |
160 |
| - |
161 |
| - const renderedItem = renderMenuItem ? ( |
162 |
| - renderMenuItem(item, menuItemProps) |
163 |
| - ) : ( |
164 |
| - <div key={key} {...menuItemProps}> |
165 |
| - <span className="label">{item.label}</span> |
166 |
| - {item.subItems && <i className="fa-sharp fa-solid fa-chevron-right"></i>} |
167 |
| - </div> |
168 |
| - ); |
169 |
| - |
170 |
| - return ( |
171 |
| - <Fragment key={key}> |
172 |
| - {renderedItem} |
173 |
| - {visibleSubMenus[key]?.visible && item.subItems && ( |
174 |
| - <SubMenu |
175 |
| - subItems={item.subItems} |
176 |
| - parentKey={key} |
177 |
| - subMenuPosition={subMenuPosition} |
178 |
| - visibleSubMenus={visibleSubMenus} |
179 |
| - hoveredItems={hoveredItems} |
180 |
| - handleMouseEnterItem={handleMouseEnterItem} |
181 |
| - handleOnClick={handleOnClick} |
182 |
| - subMenuRefs={subMenuRefs} |
183 |
| - renderMenu={renderMenu} |
184 |
| - renderMenuItem={renderMenuItem} |
185 |
| - /> |
186 |
| - )} |
187 |
| - </Fragment> |
188 |
| - ); |
189 |
| - })} |
190 |
| - </div> |
| 144 | + <FloatingPortal> |
| 145 | + <div |
| 146 | + className={clsx("menu", className)} |
| 147 | + ref={refs.setFloating} |
| 148 | + style={floatingStyles} |
| 149 | + {...getFloatingProps()} |
| 150 | + > |
| 151 | + {items.map((item, index) => { |
| 152 | + const key = `${index}`; |
| 153 | + const isActive = hoveredItems.includes(key); |
| 154 | + |
| 155 | + const menuItemProps = { |
| 156 | + className: clsx("menu-item", { active: isActive }), |
| 157 | + onMouseEnter: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => |
| 158 | + handleMouseEnterItem(event, null, index, item), |
| 159 | + onClick: (e: React.MouseEvent<HTMLDivElement>) => handleOnClick(e, item), |
| 160 | + }; |
| 161 | + |
| 162 | + const renderedItem = renderMenuItem ? ( |
| 163 | + renderMenuItem(item, menuItemProps) |
| 164 | + ) : ( |
| 165 | + <div key={key} {...menuItemProps}> |
| 166 | + <span className="label">{item.label}</span> |
| 167 | + {item.subItems && <i className="fa-sharp fa-solid fa-chevron-right"></i>} |
| 168 | + </div> |
| 169 | + ); |
| 170 | + |
| 171 | + return ( |
| 172 | + <Fragment key={key}> |
| 173 | + {renderedItem} |
| 174 | + {visibleSubMenus[key]?.visible && item.subItems && ( |
| 175 | + <SubMenu |
| 176 | + subItems={item.subItems} |
| 177 | + parentKey={key} |
| 178 | + subMenuPosition={subMenuPosition} |
| 179 | + visibleSubMenus={visibleSubMenus} |
| 180 | + hoveredItems={hoveredItems} |
| 181 | + handleMouseEnterItem={handleMouseEnterItem} |
| 182 | + handleOnClick={handleOnClick} |
| 183 | + subMenuRefs={subMenuRefs} |
| 184 | + renderMenu={renderMenu} |
| 185 | + renderMenuItem={renderMenuItem} |
| 186 | + /> |
| 187 | + )} |
| 188 | + </Fragment> |
| 189 | + ); |
| 190 | + })} |
| 191 | + </div> |
| 192 | + </FloatingPortal> |
191 | 193 | )}
|
192 | 194 | </>
|
193 | 195 | );
|
|
0 commit comments