jattac.libs.web.overflow-menu 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +178 -0
- package/dist/Data/IOverflowMenuItem.d.ts +5 -0
- package/dist/UI/OverflowMenu.d.ts +10 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +161 -0
- package/dist/index.js.map +1 -0
- package/package.json +63 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Nyingi Maina
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# React Overflow Menu
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/js/jattac.libs.web.overflow-menu)
|
|
4
|
+
|
|
5
|
+
A customizable, animated, and lightweight React overflow menu component built with TypeScript and Framer Motion.
|
|
6
|
+
|
|
7
|
+
This component provides a clean, modern, and accessible overflow menu suitable for any React application, with a focus on great user experience through satisfying micro-interactions.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **Smooth Animations**: Built with Framer Motion for fluid, physics-based animations.
|
|
12
|
+
- **Staggered Item Display**: Menu items animate in with a subtle "waterfall" effect.
|
|
13
|
+
- **Highly Customizable**: Easily change the trigger icon, menu item content, and functionality.
|
|
14
|
+
- **Themable**: Uses CSS variables to allow for deep customization that can match any corporate branding.
|
|
15
|
+
- **Portal Support**: Optionally render the menu in a React Portal to avoid CSS stacking context issues.
|
|
16
|
+
- **Lightweight**: Simple and focused on providing a great overflow menu experience without unnecessary bloat.
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
Install the package and its peer dependencies using npm:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install jattac.libs.web.overflow-menu react react-dom framer-motion
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Getting Started
|
|
27
|
+
|
|
28
|
+
Here's a basic example to get you up and running quickly.
|
|
29
|
+
|
|
30
|
+
```jsx
|
|
31
|
+
import React from 'react';
|
|
32
|
+
import OverflowMenu, { IOverflowMenuItem } from 'jattac.libs.web.overflow-menu';
|
|
33
|
+
|
|
34
|
+
const App = () => {
|
|
35
|
+
const menuItems: IOverflowMenuItem[] = [
|
|
36
|
+
{
|
|
37
|
+
content: 'Edit Profile',
|
|
38
|
+
onClick: () => alert('Editing Profile!'),
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
content: 'View Settings',
|
|
42
|
+
onClick: () => alert('Viewing Settings!'),
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
content: 'Log Out',
|
|
46
|
+
onClick: () => alert('Logging Out!'),
|
|
47
|
+
},
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<div style={{ position: 'relative', display: 'flex', justifyContent: 'flex-end', padding: '2rem' }}>
|
|
52
|
+
<OverflowMenu items={menuItems} />
|
|
53
|
+
</div>
|
|
54
|
+
);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export default App;
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## API and Props
|
|
61
|
+
|
|
62
|
+
The `OverflowMenu` component accepts the following props:
|
|
63
|
+
|
|
64
|
+
| Prop | Type | Required | Default | Description |
|
|
65
|
+
|-------------|-----------------------|----------|---------|------------------------------------------------------------------------------------------------------------|
|
|
66
|
+
| `items` | `IOverflowMenuItem[]` | Yes | - | An array of objects that define the menu items. |
|
|
67
|
+
| `icon` | `ReactNode` | No | `'⋮'` | A custom trigger icon to open the menu. |
|
|
68
|
+
| `className` | `string` | No | `''` | A CSS class to apply to the trigger button for custom styling. |
|
|
69
|
+
| `portal` | `HTMLElement` | No | `null` | A DOM element to render the menu into. Use this to prevent z-index issues with parent containers. |
|
|
70
|
+
|
|
71
|
+
### The `IOverflowMenuItem` Interface
|
|
72
|
+
|
|
73
|
+
Each item in the `items` array must conform to this interface:
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
interface IOverflowMenuItem {
|
|
77
|
+
content: React.ReactNode; // The content to display for the item.
|
|
78
|
+
onClick?: () => void; // Function to call when the item is clicked.
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Advanced Usage
|
|
85
|
+
|
|
86
|
+
### Custom Trigger Icon
|
|
87
|
+
|
|
88
|
+
You can provide any `ReactNode` as the trigger icon. This is great for using a custom SVG or an icon from a library like `react-icons`.
|
|
89
|
+
|
|
90
|
+
```jsx
|
|
91
|
+
import { BsThreeDotsVertical } from 'react-icons/bs';
|
|
92
|
+
|
|
93
|
+
// ...
|
|
94
|
+
<OverflowMenu items={menuItems} icon={<BsThreeDotsVertical size={24} />} />
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Complex Item Content
|
|
98
|
+
|
|
99
|
+
The `content` property of a menu item can be any valid `ReactNode`. This allows you to create rich menu items with icons, styled text, and more.
|
|
100
|
+
|
|
101
|
+
```jsx
|
|
102
|
+
import { FiEdit, FiLogOut } from 'react-icons/fi';
|
|
103
|
+
|
|
104
|
+
const richMenuItems: IOverflowMenuItem[] = [
|
|
105
|
+
{
|
|
106
|
+
content: (
|
|
107
|
+
<span style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
108
|
+
<FiEdit /> Edit Profile
|
|
109
|
+
</span>
|
|
110
|
+
),
|
|
111
|
+
onClick: () => alert('Editing Profile!'),
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
content: (
|
|
115
|
+
<span style={{ display: 'flex', alignItems: 'center', gap: '8px', color: 'red' }}>
|
|
116
|
+
<FiLogOut /> Log Out
|
|
117
|
+
</span>
|
|
118
|
+
),
|
|
119
|
+
onClick: () => alert('Logging Out!'),
|
|
120
|
+
},
|
|
121
|
+
];
|
|
122
|
+
|
|
123
|
+
// ...
|
|
124
|
+
<OverflowMenu items={richMenuItems} />
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Theming and Customization
|
|
130
|
+
|
|
131
|
+
The component can be easily themed by overriding the default CSS variables. The variables are scoped to the `.menuWrapper` class, which is the root of the component.
|
|
132
|
+
|
|
133
|
+
Here are the available variables and their default values:
|
|
134
|
+
|
|
135
|
+
```css
|
|
136
|
+
.your-custom-wrapper-class {
|
|
137
|
+
--ofm-text-color: #024b59;
|
|
138
|
+
--ofm-text-hover-color: #016a80;
|
|
139
|
+
--ofm-bg: rgba(255, 255, 255, 0.75);
|
|
140
|
+
--ofm-bg-blur: 12px;
|
|
141
|
+
--ofm-border-radius: 12px;
|
|
142
|
+
--ofm-item-border-radius: 8px;
|
|
143
|
+
--ofm-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
|
|
144
|
+
--ofm-border: 1px solid rgba(2, 75, 89, 0.15);
|
|
145
|
+
--ofm-item-hover-bg: rgba(2, 75, 89, 0.05);
|
|
146
|
+
--ofm-item-active-bg: rgba(2, 75, 89, 0.1);
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Example: Creating a Dark Theme**
|
|
151
|
+
|
|
152
|
+
To apply a dark theme, create a CSS class that overrides these variables and apply it to a parent element.
|
|
153
|
+
|
|
154
|
+
*Your CSS file:*
|
|
155
|
+
```css
|
|
156
|
+
.dark-theme {
|
|
157
|
+
--ofm-text-color: #e0e0e0;
|
|
158
|
+
--ofm-text-hover-color: #ffffff;
|
|
159
|
+
--ofm-bg: rgba(40, 40, 40, 0.8);
|
|
160
|
+
--ofm-border: 1px solid rgba(255, 255, 255, 0.1);
|
|
161
|
+
--ofm-item-hover-bg: rgba(255, 255, 255, 0.1);
|
|
162
|
+
--ofm-item-active-bg: rgba(255, 255, 255, 0.15);
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
*Your JSX file:*
|
|
167
|
+
```jsx
|
|
168
|
+
import './your-styles.css';
|
|
169
|
+
|
|
170
|
+
// ...
|
|
171
|
+
<div className="dark-theme">
|
|
172
|
+
<OverflowMenu items={menuItems} />
|
|
173
|
+
</div>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## License
|
|
177
|
+
|
|
178
|
+
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React, { ReactNode } from "react";
|
|
2
|
+
import IOverflowMenuItem from "../Data/IOverflowMenuItem";
|
|
3
|
+
interface IProps {
|
|
4
|
+
icon?: ReactNode;
|
|
5
|
+
portal?: HTMLElement;
|
|
6
|
+
className?: string;
|
|
7
|
+
items: IOverflowMenuItem[];
|
|
8
|
+
}
|
|
9
|
+
declare const OverflowMenu: React.FC<IProps>;
|
|
10
|
+
export default OverflowMenu;
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var React = require('react');
|
|
6
|
+
var ReactDOM = require('react-dom');
|
|
7
|
+
var framerMotion = require('framer-motion');
|
|
8
|
+
|
|
9
|
+
function styleInject(css, ref) {
|
|
10
|
+
if ( ref === void 0 ) ref = {};
|
|
11
|
+
var insertAt = ref.insertAt;
|
|
12
|
+
|
|
13
|
+
if (typeof document === 'undefined') { return; }
|
|
14
|
+
|
|
15
|
+
var head = document.head || document.getElementsByTagName('head')[0];
|
|
16
|
+
var style = document.createElement('style');
|
|
17
|
+
style.type = 'text/css';
|
|
18
|
+
|
|
19
|
+
if (insertAt === 'top') {
|
|
20
|
+
if (head.firstChild) {
|
|
21
|
+
head.insertBefore(style, head.firstChild);
|
|
22
|
+
} else {
|
|
23
|
+
head.appendChild(style);
|
|
24
|
+
}
|
|
25
|
+
} else {
|
|
26
|
+
head.appendChild(style);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (style.styleSheet) {
|
|
30
|
+
style.styleSheet.cssText = css;
|
|
31
|
+
} else {
|
|
32
|
+
style.appendChild(document.createTextNode(css));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
var css_248z = ".OverflowMenu-module_menuWrapper__psD7a {\n --ofm-text-color: #024b59;\n --ofm-text-hover-color: #016a80;\n --ofm-bg: rgba(255, 255, 255, 0.75);\n --ofm-bg-blur: 12px;\n --ofm-border-radius: 12px;\n --ofm-item-border-radius: 8px;\n --ofm-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);\n --ofm-border: 1px solid rgba(2, 75, 89, 0.15);\n --ofm-item-hover-bg: rgba(2, 75, 89, 0.05);\n --ofm-item-active-bg: rgba(2, 75, 89, 0.1);\n\n position: relative;\n display: inline-block;\n z-index: 0;\n}\n\n.OverflowMenu-module_trigger__imdPK {\n background: transparent;\n border: none;\n font-size: 1.6rem;\n cursor: pointer;\n color: var(--ofm-text-color);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: color 0.2s ease;\n}\n\n.OverflowMenu-module_trigger__imdPK:hover,\n.OverflowMenu-module_trigger__imdPK:focus {\n color: var(--ofm-text-hover-color);\n outline: none;\n}\n\n/* Light frosted glass menu */\n.OverflowMenu-module_menu__n8uKD {\n background: var(--ofm-bg);\n backdrop-filter: blur(var(--ofm-bg-blur));\n -webkit-backdrop-filter: blur(var(--ofm-bg-blur));\n border-radius: var(--ofm-border-radius);\n box-shadow: var(--ofm-shadow);\n padding: 0.5rem 0.25rem;\n min-width: 180px;\n display: flex;\n flex-direction: column;\n gap: 0.35rem;\n border: var(--ofm-border);\n position: absolute;\n right: 0;\n top: 100%;\n margin-top: 0.5rem;\n z-index: 9999;\n color: var(--ofm-text-color);\n font-weight: 500;\n font-family: \"Segoe UI\", Tahoma, Geneva, Verdana, sans-serif;\n}\n\n/* Menu buttons */\n.OverflowMenu-module_menu__n8uKD button {\n background: transparent;\n border: none;\n padding: 0.6rem 1rem;\n border-radius: var(--ofm-item-border-radius);\n text-align: left;\n color: var(--ofm-text-color);\n font-size: 1rem;\n cursor: pointer;\n transition: background 0.25s ease, transform 0.12s ease;\n user-select: none;\n}\n\n/* Hover highlight with subtle teal shade */\n.OverflowMenu-module_menu__n8uKD button:hover,\n.OverflowMenu-module_menu__n8uKD button:focus {\n background: var(--ofm-item-hover-bg);\n outline: none;\n transform: scale(1.03);\n}\n\n/* Optional: subtle active click effect */\n.OverflowMenu-module_menu__n8uKD button:active {\n transform: scale(0.98);\n background: var(--ofm-item-active-bg);\n}";
|
|
37
|
+
var styles = {"trigger":"OverflowMenu-module_trigger__imdPK","menu":"OverflowMenu-module_menu__n8uKD"};
|
|
38
|
+
styleInject(css_248z);
|
|
39
|
+
|
|
40
|
+
const menuVariants = {
|
|
41
|
+
open: {
|
|
42
|
+
opacity: 1,
|
|
43
|
+
y: 0,
|
|
44
|
+
transition: {
|
|
45
|
+
type: "spring",
|
|
46
|
+
stiffness: 400,
|
|
47
|
+
damping: 40,
|
|
48
|
+
staggerChildren: 0.07,
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
closed: {
|
|
52
|
+
opacity: 0,
|
|
53
|
+
y: -10,
|
|
54
|
+
transition: {
|
|
55
|
+
duration: 0.2,
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
const itemVariants = {
|
|
60
|
+
open: {
|
|
61
|
+
opacity: 1,
|
|
62
|
+
y: 0,
|
|
63
|
+
transition: { type: "spring", stiffness: 300, damping: 24 },
|
|
64
|
+
},
|
|
65
|
+
closed: {
|
|
66
|
+
opacity: 0,
|
|
67
|
+
y: 10,
|
|
68
|
+
transition: { duration: 0.2 },
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
const OverflowMenu = ({ icon = "⋮", portal, className, items, }) => {
|
|
72
|
+
const [open, setOpen] = React.useState(false);
|
|
73
|
+
const triggerRef = React.useRef(null);
|
|
74
|
+
const menuRef = React.useRef(null);
|
|
75
|
+
const [menuPos, setMenuPos] = React.useState({
|
|
76
|
+
top: 0,
|
|
77
|
+
left: 0,
|
|
78
|
+
});
|
|
79
|
+
// Handle closing menu on outside click
|
|
80
|
+
React.useEffect(() => {
|
|
81
|
+
const handleClickOutside = (event) => {
|
|
82
|
+
if (open &&
|
|
83
|
+
triggerRef.current &&
|
|
84
|
+
!triggerRef.current.contains(event.target) &&
|
|
85
|
+
menuRef.current &&
|
|
86
|
+
!menuRef.current.contains(event.target)) {
|
|
87
|
+
setOpen(false);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
91
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
92
|
+
}, [open]);
|
|
93
|
+
// Handle Escape key to close
|
|
94
|
+
React.useEffect(() => {
|
|
95
|
+
if (!open)
|
|
96
|
+
return;
|
|
97
|
+
const handleEsc = (event) => {
|
|
98
|
+
if (event.key === 'Escape') {
|
|
99
|
+
setOpen(false);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
document.addEventListener('keydown', handleEsc);
|
|
103
|
+
return () => document.removeEventListener('keydown', handleEsc);
|
|
104
|
+
}, [open]);
|
|
105
|
+
// Handle positioning and focus management
|
|
106
|
+
React.useLayoutEffect(() => {
|
|
107
|
+
var _a, _b;
|
|
108
|
+
if (open) {
|
|
109
|
+
if (!triggerRef.current || !menuRef.current)
|
|
110
|
+
return;
|
|
111
|
+
// Position menu
|
|
112
|
+
const triggerRect = triggerRef.current.getBoundingClientRect();
|
|
113
|
+
const menuHeight = menuRef.current.offsetHeight;
|
|
114
|
+
const viewportHeight = window.innerHeight;
|
|
115
|
+
let newTop = triggerRect.bottom + window.scrollY + 4; // Default to opening downwards
|
|
116
|
+
// Flip upwards if not enough space below
|
|
117
|
+
if (triggerRect.bottom + menuHeight > viewportHeight) {
|
|
118
|
+
newTop = triggerRect.top + window.scrollY - menuHeight - 4;
|
|
119
|
+
}
|
|
120
|
+
setMenuPos({
|
|
121
|
+
top: newTop,
|
|
122
|
+
left: triggerRect.right + window.scrollX - 160, // Keep existing left logic
|
|
123
|
+
});
|
|
124
|
+
// Focus first item
|
|
125
|
+
const firstItem = (_a = menuRef.current) === null || _a === void 0 ? void 0 : _a.querySelector('[role="menuitem"]');
|
|
126
|
+
firstItem === null || firstItem === void 0 ? void 0 : firstItem.focus();
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
// Return focus to trigger on close
|
|
130
|
+
(_b = triggerRef.current) === null || _b === void 0 ? void 0 : _b.focus();
|
|
131
|
+
}
|
|
132
|
+
}, [open]);
|
|
133
|
+
const handleMenuKeyDown = (e) => {
|
|
134
|
+
var _a, _b;
|
|
135
|
+
if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
|
|
136
|
+
e.preventDefault();
|
|
137
|
+
const items = Array.from((_a = menuRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll('[role="menuitem"]'));
|
|
138
|
+
const activeIndex = items.findIndex((item) => item === document.activeElement);
|
|
139
|
+
let nextIndex = -1;
|
|
140
|
+
if (e.key === 'ArrowDown') {
|
|
141
|
+
nextIndex = (activeIndex + 1) % items.length;
|
|
142
|
+
}
|
|
143
|
+
else if (e.key === 'ArrowUp') {
|
|
144
|
+
nextIndex = (activeIndex - 1 + items.length) % items.length;
|
|
145
|
+
}
|
|
146
|
+
(_b = items[nextIndex]) === null || _b === void 0 ? void 0 : _b.focus();
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
const menuContent = (React.createElement(framerMotion.AnimatePresence, null, open && (React.createElement(framerMotion.motion.div, { ref: menuRef, role: "menu", className: styles.menu, style: { position: "absolute", top: menuPos.top, left: menuPos.left }, variants: menuVariants, initial: "closed", animate: "open", exit: "closed", onKeyDown: handleMenuKeyDown }, items.map((item, index) => (React.createElement(framerMotion.motion.button, { key: index, role: "menuitem", onClick: () => {
|
|
150
|
+
if (item.onClick)
|
|
151
|
+
item.onClick();
|
|
152
|
+
setOpen(false);
|
|
153
|
+
}, variants: itemVariants }, item.content)))))));
|
|
154
|
+
return (React.createElement(React.Fragment, null,
|
|
155
|
+
React.createElement("button", { ref: triggerRef, className: `${styles.trigger} ${className}`, onClick: () => setOpen(!open), "aria-haspopup": "true", "aria-expanded": open },
|
|
156
|
+
React.createElement(framerMotion.motion.div, { animate: { rotate: open ? 90 : 0 }, transition: { type: "spring", stiffness: 400, damping: 40 } }, icon)),
|
|
157
|
+
portal ? ReactDOM.createPortal(menuContent, portal) : menuContent));
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
exports.default = OverflowMenu;
|
|
161
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../node_modules/style-inject/dist/style-inject.es.js","../src/UI/OverflowMenu.tsx"],"sourcesContent":["function styleInject(css, ref) {\n if ( ref === void 0 ) ref = {};\n var insertAt = ref.insertAt;\n\n if (!css || typeof document === 'undefined') { return; }\n\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n\n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild);\n } else {\n head.appendChild(style);\n }\n } else {\n head.appendChild(style);\n }\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n}\n\nexport default styleInject;\n",null],"names":["useState","useRef","useEffect","useLayoutEffect","AnimatePresence","motion"],"mappings":"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","x_google_ignoreList":[0]}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "jattac.libs.web.overflow-menu",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "A customizable and lightweight React overflow menu component with a modern design.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.es.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "rollup -c",
|
|
13
|
+
"watch": "rollup -c -w",
|
|
14
|
+
"lint": "eslint \"./{src,app}/**/*.{ts,tsx}\"",
|
|
15
|
+
"size": "size-limit",
|
|
16
|
+
"prepare": "npm run build"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"react",
|
|
20
|
+
"typescript",
|
|
21
|
+
"menu",
|
|
22
|
+
"overflow-menu",
|
|
23
|
+
"component"
|
|
24
|
+
],
|
|
25
|
+
"author": "Nyingi Maina",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"react": ">=18.2.0",
|
|
29
|
+
"react-dom": ">=18.2.0",
|
|
30
|
+
"framer-motion": ">=11.0.0"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@rollup/plugin-commonjs": "^25.0.7",
|
|
34
|
+
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
35
|
+
"@rollup/plugin-terser": "^0.4.4",
|
|
36
|
+
"@rollup/plugin-typescript": "^11.1.5",
|
|
37
|
+
"@size-limit/preset-small-lib": "^10.0.1",
|
|
38
|
+
"@types/react": "^18.2.33",
|
|
39
|
+
"@types/react-dom": "^18.2.14",
|
|
40
|
+
"@typescript-eslint/eslint-plugin": "^6.9.1",
|
|
41
|
+
"@typescript-eslint/parser": "^6.9.1",
|
|
42
|
+
"eslint": "^8.52.0",
|
|
43
|
+
"eslint-config-prettier": "^9.0.0",
|
|
44
|
+
"eslint-plugin-prettier": "^5.0.1",
|
|
45
|
+
"eslint-plugin-react": "^7.33.2",
|
|
46
|
+
"framer-motion": "^12.23.16",
|
|
47
|
+
"postcss": "^8.4.31",
|
|
48
|
+
"prettier": "^3.0.3",
|
|
49
|
+
"react": "^18.2.0",
|
|
50
|
+
"react-dom": "^18.2.0",
|
|
51
|
+
"rollup": "^4.2.0",
|
|
52
|
+
"rollup-plugin-copy": "^3.5.0",
|
|
53
|
+
"rollup-plugin-delete": "^2.0.0",
|
|
54
|
+
"rollup-plugin-generate-package-json": "^3.2.0",
|
|
55
|
+
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
56
|
+
"rollup-plugin-postcss": "^4.0.2",
|
|
57
|
+
"size-limit": "^10.0.1",
|
|
58
|
+
"typescript": "^5.2.2"
|
|
59
|
+
},
|
|
60
|
+
"dependencies": {
|
|
61
|
+
"tslib": "^2.6.2"
|
|
62
|
+
}
|
|
63
|
+
}
|