@akinon/ui-menu 0.4.0 → 1.0.0
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/dist/cjs/index.d.ts +3 -3
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +178 -2
- package/dist/cjs/types.d.ts +296 -0
- package/dist/esm/index.d.ts +3 -3
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +179 -3
- package/dist/esm/types.d.ts +296 -0
- package/package.json +7 -5
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { MenuProps as AntMenuProps } from 'antd';
|
|
2
1
|
import * as React from 'react';
|
|
3
|
-
|
|
4
|
-
export declare const Menu: ({ defaultOpenKeys,
|
|
2
|
+
import type { IMenuProps } from './types';
|
|
3
|
+
export declare const Menu: ({ defaultOpenKeys, ...restMenuProps }: IMenuProps) => React.JSX.Element;
|
|
4
|
+
export type * from './types';
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/cjs/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,UAAU,EAAiB,MAAM,SAAS,CAAC;AAqBzD,eAAO,MAAM,IAAI,0CAA2C,UAAU,sBA0MrE,CAAC;AAEF,mBAAmB,SAAS,CAAC"}
|
package/dist/cjs/index.js
CHANGED
|
@@ -12,10 +12,186 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
12
12
|
};
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
14
|
exports.Menu = void 0;
|
|
15
|
+
const icons_1 = require("@akinon/icons");
|
|
16
|
+
const ui_theme_1 = require("@akinon/ui-theme");
|
|
17
|
+
const cssinjs_1 = require("@ant-design/cssinjs");
|
|
15
18
|
const antd_1 = require("antd");
|
|
16
19
|
const React = require("react");
|
|
20
|
+
/**
|
|
21
|
+
* Menu component for navigation and hierarchical data presentation.
|
|
22
|
+
*
|
|
23
|
+
* The Menu component is designed to provide users with a structured navigation system or a display of hierarchical data.
|
|
24
|
+
* It supports different modes, themes, and configurations, enabling flexibility for various use cases.
|
|
25
|
+
*
|
|
26
|
+
* Features:
|
|
27
|
+
* - Horizontal, vertical, and inline modes for different layouts.
|
|
28
|
+
* - Light and dark themes for visual adaptability.
|
|
29
|
+
* - Submenu nesting with configurable triggers (click or hover).
|
|
30
|
+
* - Multi-select support and custom icons for menu items.
|
|
31
|
+
* - Grouping and dividers for better organization.
|
|
32
|
+
* - Fully customizable behavior with callbacks for item selection, submenu expansion, and more.
|
|
33
|
+
*
|
|
34
|
+
* The Menu component ensures a user-friendly and visually coherent way to navigate complex datasets or application structures.
|
|
35
|
+
*/
|
|
36
|
+
const MAX_DEPTH = 3;
|
|
17
37
|
const Menu = (_a) => {
|
|
18
|
-
var { defaultOpenKeys
|
|
19
|
-
|
|
38
|
+
var { defaultOpenKeys } = _a, restMenuProps = __rest(_a, ["defaultOpenKeys"]);
|
|
39
|
+
const { getPrefixCls, theme } = React.useContext(antd_1.ConfigProvider.ConfigContext);
|
|
40
|
+
const { token, hashId } = (0, ui_theme_1.useToken)();
|
|
41
|
+
const menuToken = token.Menu;
|
|
42
|
+
const prefixWithoutHash = `${getPrefixCls()}-menu`;
|
|
43
|
+
const prefixClsWithoutHash = `.${prefixWithoutHash}`;
|
|
44
|
+
const useStyle = (0, cssinjs_1.useStyleRegister)({
|
|
45
|
+
token: token,
|
|
46
|
+
path: ['Menu'],
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
48
|
+
theme: theme
|
|
49
|
+
}, () => {
|
|
50
|
+
const prefixCls = `:where(.${hashId}).${getPrefixCls()}-menu`;
|
|
51
|
+
return {
|
|
52
|
+
[prefixCls]: {
|
|
53
|
+
minWidth: menuToken.minWidth,
|
|
54
|
+
[`&${prefixClsWithoutHash}-inline-collapsed`]: {
|
|
55
|
+
minWidth: 'unset'
|
|
56
|
+
},
|
|
57
|
+
[`&${prefixClsWithoutHash}-dark`]: {
|
|
58
|
+
[`${prefixClsWithoutHash}-title, ${prefixClsWithoutHash}-submenu-title`]: {
|
|
59
|
+
paddingInlineEnd: '1rem',
|
|
60
|
+
color: menuToken.mainMenuColor,
|
|
61
|
+
fontWeight: menuToken.mainMenuFontWeight
|
|
62
|
+
},
|
|
63
|
+
[`${prefixClsWithoutHash}-item`]: {
|
|
64
|
+
color: menuToken.mainMenuColor,
|
|
65
|
+
fontWeight: menuToken.mainMenuFontWeight
|
|
66
|
+
},
|
|
67
|
+
[`${prefixClsWithoutHash}-sub`]: {
|
|
68
|
+
fontWeight: menuToken.subMenufontWeigth,
|
|
69
|
+
[`${prefixClsWithoutHash}-item`]: {
|
|
70
|
+
color: menuToken.subMenuTitleColor,
|
|
71
|
+
fontWeight: menuToken.subMenufontWeigth
|
|
72
|
+
},
|
|
73
|
+
[`${prefixClsWithoutHash}-submenu`]: {
|
|
74
|
+
[`${prefixClsWithoutHash}-submenu-title`]: {
|
|
75
|
+
color: menuToken.subMenuTitleColor,
|
|
76
|
+
['svg']: {
|
|
77
|
+
position: menuToken.iconPosition,
|
|
78
|
+
marginLeft: menuToken.subMenuTitleIconMargin,
|
|
79
|
+
insetInlineEnd: menuToken.unset
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
[`${prefixClsWithoutHash}-sub`]: {
|
|
83
|
+
[`${prefixClsWithoutHash}-item-selected`]: {
|
|
84
|
+
[`&${prefixClsWithoutHash}-item-only-child`]: {
|
|
85
|
+
['&::after']: {
|
|
86
|
+
background: menuToken.subMenuItemSelectedChildColor
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
[`${prefixClsWithoutHash}-item-only-child`]: {
|
|
91
|
+
['&::after']: {
|
|
92
|
+
width: menuToken.childMenuItemSelectedChildWidth,
|
|
93
|
+
height: menuToken.childMenuItemSelectedChildHeight,
|
|
94
|
+
borderRadius: menuToken.childMenuItemSelectedChildRadius,
|
|
95
|
+
marginLeft: menuToken.childMenuItemSelectedChildMargin,
|
|
96
|
+
opacity: menuToken.childMenuItemSelectedChildOpacity,
|
|
97
|
+
insetBlock: menuToken.unset,
|
|
98
|
+
insetInlineEnd: menuToken.unset,
|
|
99
|
+
transform: menuToken.none,
|
|
100
|
+
background: menuToken.childMenuItemSelectedChildBgColor
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
[`${prefixClsWithoutHash}-item-only-child`]: {
|
|
106
|
+
['&::after']: {
|
|
107
|
+
width: menuToken.subMenuOnlyChildSize,
|
|
108
|
+
height: menuToken.subMenuOnlyChildSize,
|
|
109
|
+
borderRadius: menuToken.subMenuOnlyChildRadius,
|
|
110
|
+
background: menuToken.subMenuOnlyChildBgColor,
|
|
111
|
+
marginLeft: menuToken.subMenuOnlyChildMargin,
|
|
112
|
+
opacity: menuToken.subMenuOnlyChildOpacity,
|
|
113
|
+
insetBlock: menuToken.unset,
|
|
114
|
+
insetInlineEnd: menuToken.unset,
|
|
115
|
+
transform: menuToken.none
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
[`&${prefixClsWithoutHash}-light`]: {
|
|
121
|
+
background: menuToken.lightItemBg,
|
|
122
|
+
[`${prefixClsWithoutHash}-submenu`]: {
|
|
123
|
+
[`svg:first-child`]: {
|
|
124
|
+
color: menuToken.lightItemMainIconColor,
|
|
125
|
+
fill: menuToken.lightItemMainIconColor
|
|
126
|
+
},
|
|
127
|
+
['&-title']: {
|
|
128
|
+
color: menuToken.lightItemMainTitle
|
|
129
|
+
},
|
|
130
|
+
[`${prefixClsWithoutHash}-sub`]: {
|
|
131
|
+
background: menuToken.LightSubItemBg,
|
|
132
|
+
[`${prefixClsWithoutHash}-submenu`]: {
|
|
133
|
+
[`${prefixClsWithoutHash}-submenu-title`]: {
|
|
134
|
+
color: menuToken.lightSubTitleColor,
|
|
135
|
+
['i']: {
|
|
136
|
+
background: menuToken.lightSubIconColor
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
[`${prefixClsWithoutHash}-sub`]: {
|
|
140
|
+
[`${prefixClsWithoutHash}-item-selected`]: {
|
|
141
|
+
[`&${prefixClsWithoutHash}-item-only-child`]: {
|
|
142
|
+
background: menuToken.lightchildItemBg,
|
|
143
|
+
color: menuToken.lightChildItemColor,
|
|
144
|
+
['&::after']: {
|
|
145
|
+
background: menuToken.lightChildItemColor
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
[`${prefixClsWithoutHash}-item-only-child`]: {
|
|
150
|
+
color: menuToken.lightSubTitleColor,
|
|
151
|
+
['&::after']: {
|
|
152
|
+
background: menuToken.lightSubTitleColor
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
[`${prefixClsWithoutHash}-item-only-child`]: {
|
|
158
|
+
color: menuToken.lightSubTitleColor,
|
|
159
|
+
fontWeight: menuToken.subMenufontWeigth,
|
|
160
|
+
['&::after']: {
|
|
161
|
+
background: menuToken.lightSubTitleColor
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
[prefixClsWithoutHash]: {}
|
|
169
|
+
};
|
|
170
|
+
});
|
|
171
|
+
const processMenuItems = (items, depth = 0) => {
|
|
172
|
+
if (!items || depth >= MAX_DEPTH)
|
|
173
|
+
return items;
|
|
174
|
+
return items.map(item => {
|
|
175
|
+
const processedItem = Object.assign({}, item);
|
|
176
|
+
// Process icon if present
|
|
177
|
+
if ('icon' in processedItem && processedItem.icon) {
|
|
178
|
+
processedItem.icon = (React.createElement(icons_1.Icon, { icon: processedItem.icon, size: depth === 0 ? 18 : 10 }));
|
|
179
|
+
}
|
|
180
|
+
// Process submenu items recursively
|
|
181
|
+
if ('children' in processedItem &&
|
|
182
|
+
Array.isArray(processedItem.children)) {
|
|
183
|
+
processedItem.children = processMenuItems(processedItem.children, depth + 1);
|
|
184
|
+
}
|
|
185
|
+
return processedItem;
|
|
186
|
+
});
|
|
187
|
+
};
|
|
188
|
+
const processedItems = processMenuItems(restMenuProps.items);
|
|
189
|
+
const expandIcon = (props) => {
|
|
190
|
+
return (React.createElement(icons_1.Icon, { icon: "chevron_down", size: 14, style: {
|
|
191
|
+
transform: props.isOpen ? 'rotate(180deg)' : 'rotate(0deg)',
|
|
192
|
+
transition: 'transform 0.3s ease-in-out'
|
|
193
|
+
} }));
|
|
194
|
+
};
|
|
195
|
+
return useStyle(React.createElement(antd_1.Menu, Object.assign({ defaultOpenKeys: defaultOpenKeys }, restMenuProps, { items: processedItems, expandIcon: expandIcon })));
|
|
20
196
|
};
|
|
21
197
|
exports.Menu = Menu;
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import { IconName } from '@akinon/icons';
|
|
2
|
+
import { DO_NOT_USE_OR_YOU_WILL_BE_FIRED_INTERNAL_STYLE } from '@akinon/ui-theme';
|
|
3
|
+
import { ReactNode } from 'react';
|
|
4
|
+
|
|
5
|
+
export type TMenuExpandIcon =
|
|
6
|
+
| ReactNode
|
|
7
|
+
| ((props: SubMenuProps & { isSubMenu: boolean }) => ReactNode);
|
|
8
|
+
|
|
9
|
+
export type TMenuMode = 'horizontal' | 'vertical' | 'inline';
|
|
10
|
+
|
|
11
|
+
export type TMenuTheme = 'light' | 'dark';
|
|
12
|
+
|
|
13
|
+
export type TMenuTriggerSubMenuAction = 'click' | 'hover';
|
|
14
|
+
|
|
15
|
+
export type TMenuOnClick = ({
|
|
16
|
+
item,
|
|
17
|
+
key,
|
|
18
|
+
keyPath,
|
|
19
|
+
domEvent
|
|
20
|
+
}: {
|
|
21
|
+
item: ReactNode;
|
|
22
|
+
key: string;
|
|
23
|
+
keyPath: string[];
|
|
24
|
+
domEvent: React.MouseEvent;
|
|
25
|
+
}) => void;
|
|
26
|
+
|
|
27
|
+
export type TMenuOnDeSelect = ({
|
|
28
|
+
item,
|
|
29
|
+
key,
|
|
30
|
+
keyPath,
|
|
31
|
+
selectedKeys,
|
|
32
|
+
domEvent
|
|
33
|
+
}: {
|
|
34
|
+
item: ReactNode;
|
|
35
|
+
key: string;
|
|
36
|
+
keyPath: string[];
|
|
37
|
+
selectedKeys: string[];
|
|
38
|
+
domEvent: React.MouseEvent;
|
|
39
|
+
}) => void;
|
|
40
|
+
|
|
41
|
+
export type TMenuOnOpenChange = (openKeys: string[]) => void;
|
|
42
|
+
|
|
43
|
+
export type TMenuOnSelect = ({
|
|
44
|
+
item,
|
|
45
|
+
key,
|
|
46
|
+
keyPath,
|
|
47
|
+
selectedKeys,
|
|
48
|
+
domEvent
|
|
49
|
+
}: {
|
|
50
|
+
item: ReactNode;
|
|
51
|
+
key: string;
|
|
52
|
+
keyPath: string[];
|
|
53
|
+
selectedKeys: string[];
|
|
54
|
+
domEvent: React.MouseEvent;
|
|
55
|
+
}) => void;
|
|
56
|
+
|
|
57
|
+
export type TMenuItemType =
|
|
58
|
+
| IMenuItemType
|
|
59
|
+
| ISubMenuType
|
|
60
|
+
| IMenuItemGroupType
|
|
61
|
+
| IMenuDividerType;
|
|
62
|
+
|
|
63
|
+
export interface IMenuProps {
|
|
64
|
+
/**
|
|
65
|
+
* Array with the keys of default opened sub menus
|
|
66
|
+
*/
|
|
67
|
+
defaultOpenKeys?: string[];
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Array with the keys of default selected menu items
|
|
71
|
+
*/
|
|
72
|
+
defaultSelectedKeys?: string[];
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Custom expand icon of submenu
|
|
76
|
+
*/
|
|
77
|
+
expandIcon?: TMenuExpandIcon;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Render submenu into DOM before it becomes visible
|
|
81
|
+
*/
|
|
82
|
+
forceSubMenuRender?: boolean;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Specifies the collapsed status when menu is in inline mode
|
|
86
|
+
*/
|
|
87
|
+
inlineCollapsed?: boolean;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Indent (in pixels) of inline menu items on each level
|
|
91
|
+
*/
|
|
92
|
+
inlineIndent?: number;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Menu item content
|
|
96
|
+
*/
|
|
97
|
+
items?: TMenuItemType[];
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Type of menu
|
|
101
|
+
*/
|
|
102
|
+
mode?: TMenuMode;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Allows selection of multiple items
|
|
106
|
+
*/
|
|
107
|
+
multiple?: boolean;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Array with the keys of currently opened sub-menus
|
|
111
|
+
*/
|
|
112
|
+
openKeys?: string[];
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Customized the ellipsis icon when menu is collapsed horizontally
|
|
116
|
+
*/
|
|
117
|
+
overflowedIndicator?: ReactNode;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Allows selecting menu items
|
|
121
|
+
*/
|
|
122
|
+
selectable?: boolean;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Array with the keys of currently selected menu items
|
|
126
|
+
*/
|
|
127
|
+
selectedKeys?: string[];
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Delay time to hide submenu when mouse leaves (in seconds)
|
|
131
|
+
*/
|
|
132
|
+
subMenuCloseDelay?: number;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Delay time to show submenu when mouse enters, (in seconds)
|
|
136
|
+
*/
|
|
137
|
+
subMenuOpenDelay?: number;
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Color theme of the menu
|
|
141
|
+
*/
|
|
142
|
+
theme?: TMenuTheme;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Which action can trigger submenu open/close
|
|
146
|
+
*/
|
|
147
|
+
triggerSubMenuAction?: TMenuTriggerSubMenuAction;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Called when a menu item is clicked
|
|
151
|
+
*/
|
|
152
|
+
onClick?: TMenuOnClick;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Called when a menu item is deselected (multiple mode only)
|
|
156
|
+
*/
|
|
157
|
+
onDeselect?: TMenuOnDeSelect;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Called when sub-menus are opened or closed
|
|
161
|
+
*/
|
|
162
|
+
onOpenChange?: TMenuOnOpenChange;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Called when a menu item is selected
|
|
166
|
+
*/
|
|
167
|
+
onSelect?: TMenuOnSelect;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Never use this prop. Akinon design system does not allow custom styles.
|
|
171
|
+
* @ignore
|
|
172
|
+
*/
|
|
173
|
+
style?: DO_NOT_USE_OR_YOU_WILL_BE_FIRED_INTERNAL_STYLE;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export interface IMenuItemType {
|
|
177
|
+
/**
|
|
178
|
+
* Display the danger style
|
|
179
|
+
* @default false
|
|
180
|
+
*/
|
|
181
|
+
danger?: boolean;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Whether menu item is disabled
|
|
185
|
+
* @default false
|
|
186
|
+
*/
|
|
187
|
+
disabled?: boolean;
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* The extra of the menu item
|
|
191
|
+
*/
|
|
192
|
+
extra?: ReactNode;
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* The icon of the menu item
|
|
196
|
+
*/
|
|
197
|
+
icon?: IconName;
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Unique ID of the menu item
|
|
201
|
+
*/
|
|
202
|
+
key?: string;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Menu label
|
|
206
|
+
*/
|
|
207
|
+
label?: ReactNode;
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Set display title for collapsed item
|
|
211
|
+
*/
|
|
212
|
+
title?: string;
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Sub-menus or sub-menu items
|
|
216
|
+
*/
|
|
217
|
+
children?: TMenuItemType[];
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export interface ISubMenuType {
|
|
221
|
+
/**
|
|
222
|
+
* Sub-menus or sub-menu items
|
|
223
|
+
*/
|
|
224
|
+
children?: TMenuItemType[];
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Whether sub-menu is disabled
|
|
228
|
+
* @default false
|
|
229
|
+
*/
|
|
230
|
+
disabled?: boolean;
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Icon of sub menu
|
|
234
|
+
*/
|
|
235
|
+
icon?: IconName;
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Unique ID of the sub-menu
|
|
239
|
+
*/
|
|
240
|
+
key?: string;
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Menu label
|
|
244
|
+
*/
|
|
245
|
+
label?: ReactNode;
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Sub-menu class name, not working when mode="inline"
|
|
249
|
+
*/
|
|
250
|
+
popupClassName?: string;
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Sub-menu offset, not working when mode="inline"
|
|
254
|
+
*/
|
|
255
|
+
popupOffset?: [number, number];
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Color theme of the SubMenu (inherits from Menu by default)
|
|
259
|
+
*/
|
|
260
|
+
theme?: TMenuTheme;
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Callback executed when the sub-menu title is clicked
|
|
264
|
+
*/
|
|
265
|
+
onTitleClick?: (params: { key: string; domEvent: React.MouseEvent }) => void;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
export interface IMenuItemGroupType {
|
|
269
|
+
/**
|
|
270
|
+
* Must have | Define type as group to make as group
|
|
271
|
+
*/
|
|
272
|
+
type: 'group';
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Sub-menu items
|
|
276
|
+
*/
|
|
277
|
+
children?: IMenuItemType[];
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* The title of the group
|
|
281
|
+
*/
|
|
282
|
+
label?: ReactNode;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export interface IMenuDividerType {
|
|
286
|
+
/**
|
|
287
|
+
* Must have | Need define the type as divider
|
|
288
|
+
*/
|
|
289
|
+
type: 'divider';
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Whether line is dashed
|
|
293
|
+
* @default false
|
|
294
|
+
*/
|
|
295
|
+
dashed?: boolean;
|
|
296
|
+
}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { MenuProps as AntMenuProps } from 'antd';
|
|
2
1
|
import * as React from 'react';
|
|
3
|
-
|
|
4
|
-
export declare const Menu: ({ defaultOpenKeys,
|
|
2
|
+
import type { IMenuProps } from './types';
|
|
3
|
+
export declare const Menu: ({ defaultOpenKeys, ...restMenuProps }: IMenuProps) => React.JSX.Element;
|
|
4
|
+
export type * from './types';
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/esm/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,UAAU,EAAiB,MAAM,SAAS,CAAC;AAqBzD,eAAO,MAAM,IAAI,0CAA2C,UAAU,sBA0MrE,CAAC;AAEF,mBAAmB,SAAS,CAAC"}
|
package/dist/esm/index.js
CHANGED
|
@@ -9,9 +9,185 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
9
9
|
}
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
|
-
import {
|
|
12
|
+
import { Icon } from '@akinon/icons';
|
|
13
|
+
import { useToken } from '@akinon/ui-theme';
|
|
14
|
+
import { useStyleRegister } from '@ant-design/cssinjs';
|
|
15
|
+
import { ConfigProvider, Menu as AntMenu } from 'antd';
|
|
13
16
|
import * as React from 'react';
|
|
17
|
+
/**
|
|
18
|
+
* Menu component for navigation and hierarchical data presentation.
|
|
19
|
+
*
|
|
20
|
+
* The Menu component is designed to provide users with a structured navigation system or a display of hierarchical data.
|
|
21
|
+
* It supports different modes, themes, and configurations, enabling flexibility for various use cases.
|
|
22
|
+
*
|
|
23
|
+
* Features:
|
|
24
|
+
* - Horizontal, vertical, and inline modes for different layouts.
|
|
25
|
+
* - Light and dark themes for visual adaptability.
|
|
26
|
+
* - Submenu nesting with configurable triggers (click or hover).
|
|
27
|
+
* - Multi-select support and custom icons for menu items.
|
|
28
|
+
* - Grouping and dividers for better organization.
|
|
29
|
+
* - Fully customizable behavior with callbacks for item selection, submenu expansion, and more.
|
|
30
|
+
*
|
|
31
|
+
* The Menu component ensures a user-friendly and visually coherent way to navigate complex datasets or application structures.
|
|
32
|
+
*/
|
|
33
|
+
const MAX_DEPTH = 3;
|
|
14
34
|
export const Menu = (_a) => {
|
|
15
|
-
var { defaultOpenKeys
|
|
16
|
-
|
|
35
|
+
var { defaultOpenKeys } = _a, restMenuProps = __rest(_a, ["defaultOpenKeys"]);
|
|
36
|
+
const { getPrefixCls, theme } = React.useContext(ConfigProvider.ConfigContext);
|
|
37
|
+
const { token, hashId } = useToken();
|
|
38
|
+
const menuToken = token.Menu;
|
|
39
|
+
const prefixWithoutHash = `${getPrefixCls()}-menu`;
|
|
40
|
+
const prefixClsWithoutHash = `.${prefixWithoutHash}`;
|
|
41
|
+
const useStyle = useStyleRegister({
|
|
42
|
+
token: token,
|
|
43
|
+
path: ['Menu'],
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
|
+
theme: theme
|
|
46
|
+
}, () => {
|
|
47
|
+
const prefixCls = `:where(.${hashId}).${getPrefixCls()}-menu`;
|
|
48
|
+
return {
|
|
49
|
+
[prefixCls]: {
|
|
50
|
+
minWidth: menuToken.minWidth,
|
|
51
|
+
[`&${prefixClsWithoutHash}-inline-collapsed`]: {
|
|
52
|
+
minWidth: 'unset'
|
|
53
|
+
},
|
|
54
|
+
[`&${prefixClsWithoutHash}-dark`]: {
|
|
55
|
+
[`${prefixClsWithoutHash}-title, ${prefixClsWithoutHash}-submenu-title`]: {
|
|
56
|
+
paddingInlineEnd: '1rem',
|
|
57
|
+
color: menuToken.mainMenuColor,
|
|
58
|
+
fontWeight: menuToken.mainMenuFontWeight
|
|
59
|
+
},
|
|
60
|
+
[`${prefixClsWithoutHash}-item`]: {
|
|
61
|
+
color: menuToken.mainMenuColor,
|
|
62
|
+
fontWeight: menuToken.mainMenuFontWeight
|
|
63
|
+
},
|
|
64
|
+
[`${prefixClsWithoutHash}-sub`]: {
|
|
65
|
+
fontWeight: menuToken.subMenufontWeigth,
|
|
66
|
+
[`${prefixClsWithoutHash}-item`]: {
|
|
67
|
+
color: menuToken.subMenuTitleColor,
|
|
68
|
+
fontWeight: menuToken.subMenufontWeigth
|
|
69
|
+
},
|
|
70
|
+
[`${prefixClsWithoutHash}-submenu`]: {
|
|
71
|
+
[`${prefixClsWithoutHash}-submenu-title`]: {
|
|
72
|
+
color: menuToken.subMenuTitleColor,
|
|
73
|
+
['svg']: {
|
|
74
|
+
position: menuToken.iconPosition,
|
|
75
|
+
marginLeft: menuToken.subMenuTitleIconMargin,
|
|
76
|
+
insetInlineEnd: menuToken.unset
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
[`${prefixClsWithoutHash}-sub`]: {
|
|
80
|
+
[`${prefixClsWithoutHash}-item-selected`]: {
|
|
81
|
+
[`&${prefixClsWithoutHash}-item-only-child`]: {
|
|
82
|
+
['&::after']: {
|
|
83
|
+
background: menuToken.subMenuItemSelectedChildColor
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
[`${prefixClsWithoutHash}-item-only-child`]: {
|
|
88
|
+
['&::after']: {
|
|
89
|
+
width: menuToken.childMenuItemSelectedChildWidth,
|
|
90
|
+
height: menuToken.childMenuItemSelectedChildHeight,
|
|
91
|
+
borderRadius: menuToken.childMenuItemSelectedChildRadius,
|
|
92
|
+
marginLeft: menuToken.childMenuItemSelectedChildMargin,
|
|
93
|
+
opacity: menuToken.childMenuItemSelectedChildOpacity,
|
|
94
|
+
insetBlock: menuToken.unset,
|
|
95
|
+
insetInlineEnd: menuToken.unset,
|
|
96
|
+
transform: menuToken.none,
|
|
97
|
+
background: menuToken.childMenuItemSelectedChildBgColor
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
[`${prefixClsWithoutHash}-item-only-child`]: {
|
|
103
|
+
['&::after']: {
|
|
104
|
+
width: menuToken.subMenuOnlyChildSize,
|
|
105
|
+
height: menuToken.subMenuOnlyChildSize,
|
|
106
|
+
borderRadius: menuToken.subMenuOnlyChildRadius,
|
|
107
|
+
background: menuToken.subMenuOnlyChildBgColor,
|
|
108
|
+
marginLeft: menuToken.subMenuOnlyChildMargin,
|
|
109
|
+
opacity: menuToken.subMenuOnlyChildOpacity,
|
|
110
|
+
insetBlock: menuToken.unset,
|
|
111
|
+
insetInlineEnd: menuToken.unset,
|
|
112
|
+
transform: menuToken.none
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
[`&${prefixClsWithoutHash}-light`]: {
|
|
118
|
+
background: menuToken.lightItemBg,
|
|
119
|
+
[`${prefixClsWithoutHash}-submenu`]: {
|
|
120
|
+
[`svg:first-child`]: {
|
|
121
|
+
color: menuToken.lightItemMainIconColor,
|
|
122
|
+
fill: menuToken.lightItemMainIconColor
|
|
123
|
+
},
|
|
124
|
+
['&-title']: {
|
|
125
|
+
color: menuToken.lightItemMainTitle
|
|
126
|
+
},
|
|
127
|
+
[`${prefixClsWithoutHash}-sub`]: {
|
|
128
|
+
background: menuToken.LightSubItemBg,
|
|
129
|
+
[`${prefixClsWithoutHash}-submenu`]: {
|
|
130
|
+
[`${prefixClsWithoutHash}-submenu-title`]: {
|
|
131
|
+
color: menuToken.lightSubTitleColor,
|
|
132
|
+
['i']: {
|
|
133
|
+
background: menuToken.lightSubIconColor
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
[`${prefixClsWithoutHash}-sub`]: {
|
|
137
|
+
[`${prefixClsWithoutHash}-item-selected`]: {
|
|
138
|
+
[`&${prefixClsWithoutHash}-item-only-child`]: {
|
|
139
|
+
background: menuToken.lightchildItemBg,
|
|
140
|
+
color: menuToken.lightChildItemColor,
|
|
141
|
+
['&::after']: {
|
|
142
|
+
background: menuToken.lightChildItemColor
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
[`${prefixClsWithoutHash}-item-only-child`]: {
|
|
147
|
+
color: menuToken.lightSubTitleColor,
|
|
148
|
+
['&::after']: {
|
|
149
|
+
background: menuToken.lightSubTitleColor
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
[`${prefixClsWithoutHash}-item-only-child`]: {
|
|
155
|
+
color: menuToken.lightSubTitleColor,
|
|
156
|
+
fontWeight: menuToken.subMenufontWeigth,
|
|
157
|
+
['&::after']: {
|
|
158
|
+
background: menuToken.lightSubTitleColor
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
[prefixClsWithoutHash]: {}
|
|
166
|
+
};
|
|
167
|
+
});
|
|
168
|
+
const processMenuItems = (items, depth = 0) => {
|
|
169
|
+
if (!items || depth >= MAX_DEPTH)
|
|
170
|
+
return items;
|
|
171
|
+
return items.map(item => {
|
|
172
|
+
const processedItem = Object.assign({}, item);
|
|
173
|
+
// Process icon if present
|
|
174
|
+
if ('icon' in processedItem && processedItem.icon) {
|
|
175
|
+
processedItem.icon = (React.createElement(Icon, { icon: processedItem.icon, size: depth === 0 ? 18 : 10 }));
|
|
176
|
+
}
|
|
177
|
+
// Process submenu items recursively
|
|
178
|
+
if ('children' in processedItem &&
|
|
179
|
+
Array.isArray(processedItem.children)) {
|
|
180
|
+
processedItem.children = processMenuItems(processedItem.children, depth + 1);
|
|
181
|
+
}
|
|
182
|
+
return processedItem;
|
|
183
|
+
});
|
|
184
|
+
};
|
|
185
|
+
const processedItems = processMenuItems(restMenuProps.items);
|
|
186
|
+
const expandIcon = (props) => {
|
|
187
|
+
return (React.createElement(Icon, { icon: "chevron_down", size: 14, style: {
|
|
188
|
+
transform: props.isOpen ? 'rotate(180deg)' : 'rotate(0deg)',
|
|
189
|
+
transition: 'transform 0.3s ease-in-out'
|
|
190
|
+
} }));
|
|
191
|
+
};
|
|
192
|
+
return useStyle(React.createElement(AntMenu, Object.assign({ defaultOpenKeys: defaultOpenKeys }, restMenuProps, { items: processedItems, expandIcon: expandIcon })));
|
|
17
193
|
};
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import { IconName } from '@akinon/icons';
|
|
2
|
+
import { DO_NOT_USE_OR_YOU_WILL_BE_FIRED_INTERNAL_STYLE } from '@akinon/ui-theme';
|
|
3
|
+
import { ReactNode } from 'react';
|
|
4
|
+
|
|
5
|
+
export type TMenuExpandIcon =
|
|
6
|
+
| ReactNode
|
|
7
|
+
| ((props: SubMenuProps & { isSubMenu: boolean }) => ReactNode);
|
|
8
|
+
|
|
9
|
+
export type TMenuMode = 'horizontal' | 'vertical' | 'inline';
|
|
10
|
+
|
|
11
|
+
export type TMenuTheme = 'light' | 'dark';
|
|
12
|
+
|
|
13
|
+
export type TMenuTriggerSubMenuAction = 'click' | 'hover';
|
|
14
|
+
|
|
15
|
+
export type TMenuOnClick = ({
|
|
16
|
+
item,
|
|
17
|
+
key,
|
|
18
|
+
keyPath,
|
|
19
|
+
domEvent
|
|
20
|
+
}: {
|
|
21
|
+
item: ReactNode;
|
|
22
|
+
key: string;
|
|
23
|
+
keyPath: string[];
|
|
24
|
+
domEvent: React.MouseEvent;
|
|
25
|
+
}) => void;
|
|
26
|
+
|
|
27
|
+
export type TMenuOnDeSelect = ({
|
|
28
|
+
item,
|
|
29
|
+
key,
|
|
30
|
+
keyPath,
|
|
31
|
+
selectedKeys,
|
|
32
|
+
domEvent
|
|
33
|
+
}: {
|
|
34
|
+
item: ReactNode;
|
|
35
|
+
key: string;
|
|
36
|
+
keyPath: string[];
|
|
37
|
+
selectedKeys: string[];
|
|
38
|
+
domEvent: React.MouseEvent;
|
|
39
|
+
}) => void;
|
|
40
|
+
|
|
41
|
+
export type TMenuOnOpenChange = (openKeys: string[]) => void;
|
|
42
|
+
|
|
43
|
+
export type TMenuOnSelect = ({
|
|
44
|
+
item,
|
|
45
|
+
key,
|
|
46
|
+
keyPath,
|
|
47
|
+
selectedKeys,
|
|
48
|
+
domEvent
|
|
49
|
+
}: {
|
|
50
|
+
item: ReactNode;
|
|
51
|
+
key: string;
|
|
52
|
+
keyPath: string[];
|
|
53
|
+
selectedKeys: string[];
|
|
54
|
+
domEvent: React.MouseEvent;
|
|
55
|
+
}) => void;
|
|
56
|
+
|
|
57
|
+
export type TMenuItemType =
|
|
58
|
+
| IMenuItemType
|
|
59
|
+
| ISubMenuType
|
|
60
|
+
| IMenuItemGroupType
|
|
61
|
+
| IMenuDividerType;
|
|
62
|
+
|
|
63
|
+
export interface IMenuProps {
|
|
64
|
+
/**
|
|
65
|
+
* Array with the keys of default opened sub menus
|
|
66
|
+
*/
|
|
67
|
+
defaultOpenKeys?: string[];
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Array with the keys of default selected menu items
|
|
71
|
+
*/
|
|
72
|
+
defaultSelectedKeys?: string[];
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Custom expand icon of submenu
|
|
76
|
+
*/
|
|
77
|
+
expandIcon?: TMenuExpandIcon;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Render submenu into DOM before it becomes visible
|
|
81
|
+
*/
|
|
82
|
+
forceSubMenuRender?: boolean;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Specifies the collapsed status when menu is in inline mode
|
|
86
|
+
*/
|
|
87
|
+
inlineCollapsed?: boolean;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Indent (in pixels) of inline menu items on each level
|
|
91
|
+
*/
|
|
92
|
+
inlineIndent?: number;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Menu item content
|
|
96
|
+
*/
|
|
97
|
+
items?: TMenuItemType[];
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Type of menu
|
|
101
|
+
*/
|
|
102
|
+
mode?: TMenuMode;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Allows selection of multiple items
|
|
106
|
+
*/
|
|
107
|
+
multiple?: boolean;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Array with the keys of currently opened sub-menus
|
|
111
|
+
*/
|
|
112
|
+
openKeys?: string[];
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Customized the ellipsis icon when menu is collapsed horizontally
|
|
116
|
+
*/
|
|
117
|
+
overflowedIndicator?: ReactNode;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Allows selecting menu items
|
|
121
|
+
*/
|
|
122
|
+
selectable?: boolean;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Array with the keys of currently selected menu items
|
|
126
|
+
*/
|
|
127
|
+
selectedKeys?: string[];
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Delay time to hide submenu when mouse leaves (in seconds)
|
|
131
|
+
*/
|
|
132
|
+
subMenuCloseDelay?: number;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Delay time to show submenu when mouse enters, (in seconds)
|
|
136
|
+
*/
|
|
137
|
+
subMenuOpenDelay?: number;
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Color theme of the menu
|
|
141
|
+
*/
|
|
142
|
+
theme?: TMenuTheme;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Which action can trigger submenu open/close
|
|
146
|
+
*/
|
|
147
|
+
triggerSubMenuAction?: TMenuTriggerSubMenuAction;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Called when a menu item is clicked
|
|
151
|
+
*/
|
|
152
|
+
onClick?: TMenuOnClick;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Called when a menu item is deselected (multiple mode only)
|
|
156
|
+
*/
|
|
157
|
+
onDeselect?: TMenuOnDeSelect;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Called when sub-menus are opened or closed
|
|
161
|
+
*/
|
|
162
|
+
onOpenChange?: TMenuOnOpenChange;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Called when a menu item is selected
|
|
166
|
+
*/
|
|
167
|
+
onSelect?: TMenuOnSelect;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Never use this prop. Akinon design system does not allow custom styles.
|
|
171
|
+
* @ignore
|
|
172
|
+
*/
|
|
173
|
+
style?: DO_NOT_USE_OR_YOU_WILL_BE_FIRED_INTERNAL_STYLE;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export interface IMenuItemType {
|
|
177
|
+
/**
|
|
178
|
+
* Display the danger style
|
|
179
|
+
* @default false
|
|
180
|
+
*/
|
|
181
|
+
danger?: boolean;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Whether menu item is disabled
|
|
185
|
+
* @default false
|
|
186
|
+
*/
|
|
187
|
+
disabled?: boolean;
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* The extra of the menu item
|
|
191
|
+
*/
|
|
192
|
+
extra?: ReactNode;
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* The icon of the menu item
|
|
196
|
+
*/
|
|
197
|
+
icon?: IconName;
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Unique ID of the menu item
|
|
201
|
+
*/
|
|
202
|
+
key?: string;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Menu label
|
|
206
|
+
*/
|
|
207
|
+
label?: ReactNode;
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Set display title for collapsed item
|
|
211
|
+
*/
|
|
212
|
+
title?: string;
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Sub-menus or sub-menu items
|
|
216
|
+
*/
|
|
217
|
+
children?: TMenuItemType[];
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export interface ISubMenuType {
|
|
221
|
+
/**
|
|
222
|
+
* Sub-menus or sub-menu items
|
|
223
|
+
*/
|
|
224
|
+
children?: TMenuItemType[];
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Whether sub-menu is disabled
|
|
228
|
+
* @default false
|
|
229
|
+
*/
|
|
230
|
+
disabled?: boolean;
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Icon of sub menu
|
|
234
|
+
*/
|
|
235
|
+
icon?: IconName;
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Unique ID of the sub-menu
|
|
239
|
+
*/
|
|
240
|
+
key?: string;
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Menu label
|
|
244
|
+
*/
|
|
245
|
+
label?: ReactNode;
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Sub-menu class name, not working when mode="inline"
|
|
249
|
+
*/
|
|
250
|
+
popupClassName?: string;
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Sub-menu offset, not working when mode="inline"
|
|
254
|
+
*/
|
|
255
|
+
popupOffset?: [number, number];
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Color theme of the SubMenu (inherits from Menu by default)
|
|
259
|
+
*/
|
|
260
|
+
theme?: TMenuTheme;
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Callback executed when the sub-menu title is clicked
|
|
264
|
+
*/
|
|
265
|
+
onTitleClick?: (params: { key: string; domEvent: React.MouseEvent }) => void;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
export interface IMenuItemGroupType {
|
|
269
|
+
/**
|
|
270
|
+
* Must have | Define type as group to make as group
|
|
271
|
+
*/
|
|
272
|
+
type: 'group';
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Sub-menu items
|
|
276
|
+
*/
|
|
277
|
+
children?: IMenuItemType[];
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* The title of the group
|
|
281
|
+
*/
|
|
282
|
+
label?: ReactNode;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export interface IMenuDividerType {
|
|
286
|
+
/**
|
|
287
|
+
* Must have | Need define the type as divider
|
|
288
|
+
*/
|
|
289
|
+
type: 'divider';
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Whether line is dashed
|
|
293
|
+
* @default false
|
|
294
|
+
*/
|
|
295
|
+
dashed?: boolean;
|
|
296
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akinon/ui-menu",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/esm/index.js",
|
|
@@ -9,14 +9,16 @@
|
|
|
9
9
|
"dist"
|
|
10
10
|
],
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"antd": "5.
|
|
12
|
+
"antd": "5.22.6",
|
|
13
|
+
"@akinon/ui-theme": "1.0.0",
|
|
14
|
+
"@akinon/icons": "1.0.0"
|
|
13
15
|
},
|
|
14
16
|
"devDependencies": {
|
|
15
17
|
"clean-package": "2.2.0",
|
|
16
18
|
"copyfiles": "^2.4.1",
|
|
17
19
|
"rimraf": "^5.0.5",
|
|
18
|
-
"typescript": "
|
|
19
|
-
"@akinon/typescript-config": "0.
|
|
20
|
+
"typescript": "*",
|
|
21
|
+
"@akinon/typescript-config": "1.0.0"
|
|
20
22
|
},
|
|
21
23
|
"peerDependencies": {
|
|
22
24
|
"react": ">=18",
|
|
@@ -36,7 +38,7 @@
|
|
|
36
38
|
"build": "pnpm run build:esm && pnpm run build:commonjs && pnpm run copy:files",
|
|
37
39
|
"build:esm": "tsc --outDir dist/esm",
|
|
38
40
|
"build:commonjs": "tsc --module commonjs --outDir dist/cjs",
|
|
39
|
-
"copy:files": "copyfiles -u 1 src
|
|
41
|
+
"copy:files": "copyfiles -u 1 \"src/**/*.!(ts|tsx)\" dist/esm && copyfiles -u 1 \"src/**/*.!(ts|tsx)\" dist/cjs",
|
|
40
42
|
"clean": "rimraf dist/",
|
|
41
43
|
"typecheck": "tsc --noEmit"
|
|
42
44
|
}
|