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 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
+ [![npm version](https://badge.fury.io/js/jattac.libs.web.overflow-menu.svg)](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,5 @@
1
+ import { ReactNode } from "react";
2
+ export default interface IOverflowMenuItem {
3
+ content: ReactNode;
4
+ onClick?: () => void;
5
+ }
@@ -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;
@@ -0,0 +1,4 @@
1
+ import OverflowMenu from './UI/OverflowMenu';
2
+ import IOverflowMenuItem from './Data/IOverflowMenuItem';
3
+ export { IOverflowMenuItem };
4
+ export default OverflowMenu;
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
+ }