https://github.com/sar1008/react-headless-nested-menu
A useful headless component (hook) that gives you all the functions you need to create a multi-level menu using your own components!
https://github.com/sar1008/react-headless-nested-menu
headless-components headless-ui hooks menu multi-level-menu nested-menus typescript
Last synced: about 1 month ago
JSON representation
A useful headless component (hook) that gives you all the functions you need to create a multi-level menu using your own components!
- Host: GitHub
- URL: https://github.com/sar1008/react-headless-nested-menu
- Owner: sar1008
- License: mit
- Created: 2024-03-31T15:46:17.000Z (about 2 years ago)
- Default Branch: master
- Last Pushed: 2024-03-31T15:49:31.000Z (about 2 years ago)
- Last Synced: 2025-03-22T13:12:46.557Z (about 1 year ago)
- Topics: headless-components, headless-ui, hooks, menu, multi-level-menu, nested-menus, typescript
- Language: TypeScript
- Homepage: https://cdes.github.io/react-headless-nested-menu/
- Size: 333 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README

# React Headless Nested Menu
A useful headless component (hook) that gives you all the functions you need to create a multi-level menu using your own components!
### Features
- Only functionality, no need to fight with CSS classes and overrides to customize your menu.
- Created in TypeScript, so you get types out of the box.
- Fully configurable behavior (open on click or hover).

### Installation
```bash
yarn add react-headless-nested-menu
```
### Usage
You can import the generated bundle to use the whole library generated by this starter:
```javascript
import React from "react";
import { useNestedMenu } from "react-headless-nested-menu";
function App() {
const {
getToggleButtonProps,
getMenuProps,
getItemProps,
getOpenTriggerProps,
getCloseTriggerProps,
getMenuOffsetStyles,
isOpen,
isSubMenuOpen,
toggleMenu
} = useNestedMenu({
items
});
const [item, setItem] = useState();
// your custom function to render items
const renderItem = (item: MenuItem) => (
{
event.stopPropagation();
setItem(item);
toggleMenu();
}}
>
{item.label}
{item.subMenu && }
{/* Only show submenu when there's a submenu & it's open */}
{item.subMenu && isSubMenuOpen(item) && renderMenu(item.subMenu, item)}
);
// your custom function to render menus (root menu & sub-menus)
const renderMenu = (items: Items, parentItem?: MenuItem) => (
{items.map((item) => renderItem(item))}
{/* add hit area */}
{parentItem && (
)}
);
return (
{item ? item.label : "Open Menu"}
{isOpen && renderMenu(items)}
);
}
const rootElement = document.getElementById("root");
React.render(, rootElement);
```
## To do
- Improve documentation.
- Add more example.
- Add tests.
- Use popper for positioning menus.
## Examples
- [CodeSandbox: Using Tailwind](https://codesandbox.io/s/react-headless-nested-menu-tailwind-19k83?file=/src/App.tsx)
## Credits
- [typescript-library-starter](https://github.com/alexjoverm/typescript-library-starter)