@jetlinks-web/components 2.0.1 → 2.0.2-2

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.
@@ -1,320 +1,320 @@
1
- import type {
2
- MenuHeaderRender,
3
- MenuContentRender,
4
- MenuExtraRender,
5
- CollapsedButtonRender,
6
- LogoRender,
7
- WithFalse,
8
- } from '../typings';
9
- import type { SiderProps } from './typings';
10
- import { LayoutSider as Sider, Menu } from 'ant-design-vue';
11
- import BaseMenu, { baseMenuProps } from './BaseMenu';
12
- import { defaultSettingProps } from '../defaultSettings';
13
- import PropTypes from 'ant-design-vue/lib/_util/vue-types';
14
- import type {
15
- CSSProperties,
16
- ExtractPropTypes,
17
- PropType,
18
- FunctionalComponent,
19
- } from 'vue';
20
- import type { VueNode } from 'ant-design-vue/lib/_util/type';
21
- import { AIcon as IconFont } from '../../../';
22
- import { useRouteContext } from '../RouteContext';
23
- import { computed, unref } from 'vue';
24
-
25
- export type PrivateSiderMenuProps = {
26
- matchMenuKeys?: string[];
27
- };
28
-
29
- export const siderMenuProps = {
30
- ...defaultSettingProps,
31
- ...baseMenuProps,
32
- logo: {
33
- type: [Object, String, Function] as PropType<LogoRender>,
34
- default: () => undefined,
35
- },
36
- logoStyle: {
37
- type: Object as PropType<CSSProperties>,
38
- default: () => undefined,
39
- },
40
- siderWidth: PropTypes.number.def(208),
41
- headerHeight: PropTypes.number.def(48),
42
- collapsedWidth: PropTypes.number.def(48),
43
- menuHeaderRender: {
44
- type: [Function, Object, Boolean] as PropType<MenuHeaderRender>,
45
- default: () => undefined,
46
- },
47
- menuContentRender: {
48
- type: [Function, Object, Boolean] as PropType<MenuContentRender>,
49
- default: () => undefined,
50
- },
51
- menuExtraRender: {
52
- type: [Function, Object, Boolean] as PropType<MenuExtraRender>,
53
- default: () => undefined,
54
- },
55
- collapsedButtonRender: {
56
- type: [Function, Object, Boolean] as PropType<CollapsedButtonRender>,
57
- default: () => undefined,
58
- },
59
- breakpoint: {
60
- type: [Object, Boolean] as PropType<SiderProps['breakpoint'] | false>,
61
- default: () => false,
62
- },
63
- splitMenus: PropTypes.looseBool,
64
- fixed: PropTypes.looseBool,
65
- hide: PropTypes.looseBool,
66
- matchMenuKeys: {
67
- type: Array as PropType<string[]>,
68
- default: () => [],
69
- },
70
-
71
- // events
72
- onMenuHeaderClick: PropTypes.func,
73
- onMenuClick: PropTypes.func,
74
- onCollapse: {
75
- type: Function as PropType<(collapsed: boolean) => void>,
76
- },
77
- onOpenKeys: {
78
- type: Function as PropType<(openKeys: WithFalse<string[]>) => void>,
79
- },
80
- onSelect: {
81
- type: Function as PropType<(selectedKeys: WithFalse<string[]>) => void>,
82
- },
83
- };
84
-
85
- export type SiderMenuProps = Partial<ExtractPropTypes<typeof siderMenuProps>>;
86
-
87
- export const defaultRenderLogo = (
88
- logo?: VueNode,
89
- logoStyle?: CSSProperties,
90
- ): VueNode => {
91
- if (!logo) {
92
- return null;
93
- }
94
- if (typeof logo === 'string') {
95
- return <img src={logo} alt="logo" style={logoStyle}/>;
96
- }
97
- if (typeof logo === 'function') {
98
- // @ts-ignore
99
- return logo();
100
- }
101
- return logo;
102
- };
103
-
104
- export const defaultRenderLogoAndTitle = (
105
- props: SiderMenuProps,
106
- renderKey: string | undefined = 'menuHeaderRender',
107
- ): VueNode | null => {
108
- const {
109
- logo = 'http://demo.jetlinks.cn/static/logo.760eb65c.png',
110
- logoStyle,
111
- title,
112
- layout,
113
- } = props;
114
- const renderFunction = (props as Record<string, VueNode>)[renderKey || ''];
115
- if (layout === 'mix' && renderFunction === false) {
116
- return null;
117
- }
118
- const logoDom = defaultRenderLogo(logo, logoStyle);
119
- const titleDom = <h1>{title}</h1>;
120
- if (renderKey === 'menuHeaderRender') {
121
- return null;
122
- }
123
- // call menuHeaderRender
124
- if (typeof renderFunction === 'function') {
125
- // @ts-ignore
126
- return renderFunction(
127
- logoDom,
128
- props.collapsed ? null : titleDom,
129
- props,
130
- );
131
- }
132
- if (Array.isArray(renderFunction)) {
133
- return <>{renderFunction}</>;
134
- }
135
-
136
- return (
137
- <a>
138
- {logoDom}
139
- {props.collapsed ? null : titleDom}
140
- </a>
141
- );
142
- };
143
-
144
- export const defaultRenderCollapsedButton = (collapsed?: boolean): VueNode =>
145
- collapsed ? (
146
- <IconFont type={'MenuUnfoldOutlined'}/>
147
- ) : (
148
- <IconFont type={'MenuFoldOutlined'}/>
149
- );
150
-
151
- const SiderMenu: FunctionalComponent<SiderMenuProps> = (
152
- props: SiderMenuProps,
153
- ) => {
154
- const {
155
- collapsed,
156
- siderWidth,
157
- breakpoint,
158
- collapsedWidth = 48,
159
- menuExtraRender = false,
160
- menuContentRender = false,
161
- collapsedButtonRender = defaultRenderCollapsedButton,
162
- theme,
163
- } = props;
164
-
165
- const context = useRouteContext();
166
- const {getPrefixCls} = context;
167
- const baseClassName = getPrefixCls('sider');
168
- const hasSplitMenu = computed(
169
- () => props.layout === 'mix' && props.splitMenus,
170
- );
171
- const sSideWidth = computed(() =>
172
- props.collapsed ? props.collapsedWidth : props.siderWidth,
173
- );
174
-
175
- const classNames = computed(() => {
176
- return {
177
- [baseClassName]: true,
178
- [`${baseClassName}-fixed`]: context.fixSiderbar,
179
- [`${baseClassName}-${theme}`]: true, // theme !== 'dark'
180
- [`${baseClassName}-layout-${props.layout}`]: props.layout,
181
- };
182
- });
183
-
184
- const handleSelect = ($event: string[]) => {
185
- if (props.onSelect) {
186
- if (unref(hasSplitMenu)) {
187
- props.onSelect([context.selectedKeys[0], ...$event]);
188
- return;
189
- }
190
- props.onSelect($event);
191
- }
192
- };
193
-
194
- const headerDom = defaultRenderLogoAndTitle(props);
195
- const extraDom = menuExtraRender && menuExtraRender(props);
196
-
197
- if (hasSplitMenu.value && unref(context.flatMenuData).length === 0) {
198
- return null;
199
- }
200
-
201
- const defaultMenuDom = (
202
- <BaseMenu
203
- prefixCls={getPrefixCls()}
204
- locale={props.locale || context.locale}
205
- theme={theme}
206
- mode="inline"
207
- menuData={
208
- hasSplitMenu.value ? context.flatMenuData : context.menuData
209
- }
210
- collapsed={props.collapsed}
211
- openKeys={context.openKeys}
212
- selectedKeys={context.selectedKeys}
213
- menuItemRender={props.menuItemRender}
214
- subMenuItemRender={props.subMenuItemRender}
215
- iconfontUrl={props.iconfontUrl}
216
- onClick={props.onMenuClick}
217
- style={{width: '100%'}}
218
- class={`${baseClassName}-menu`}
219
- {...{
220
- 'onUpdate:openKeys': ($event: string[]) =>
221
- props.onOpenKeys && props.onOpenKeys($event),
222
- 'onUpdate:selectedKeys': handleSelect,
223
- }}
224
- />
225
- );
226
-
227
- return (
228
- <>
229
- {context.fixSiderbar && (
230
- <div
231
- style={{
232
- width: `${sSideWidth.value}px`,
233
- overflow: 'hidden',
234
- flex: `0 0 ${sSideWidth.value}px`,
235
- maxWidth: `${sSideWidth.value}px`,
236
- minWidth: `${sSideWidth.value}px`,
237
- transition: `background-color 0.3s, min-width 0.3s, max-width 0.3s cubic-bezier(0.645, 0.045, 0.355, 1)`,
238
- }}
239
- />
240
- )}
241
- <Sider
242
- collapsible
243
- trigger={null}
244
- collapsed={collapsed}
245
- breakpoint={breakpoint || undefined}
246
- onCollapse={(collapse: boolean) => {
247
- props.onCollapse?.(collapse);
248
- }}
249
- collapsedWidth={collapsedWidth}
250
- style={{
251
- overflow: 'hidden',
252
- paddingTop: `${props.headerHeight}px`,
253
- }}
254
- width={siderWidth}
255
- theme={theme}
256
- class={classNames.value}
257
- >
258
- {headerDom && (
259
- <div
260
- class={`${baseClassName}-logo`}
261
- onClick={
262
- props.layout !== 'mix'
263
- ? props.onMenuHeaderClick
264
- : undefined
265
- }
266
- id="logo"
267
- style={props?.logoStyle}
268
- >
269
- {headerDom}
270
- </div>
271
- )}
272
- {extraDom && !props.collapsed && (
273
- <div
274
- class={{
275
- [`${baseClassName}-extra`]: true,
276
- [`${baseClassName}-extra-no-logo`]: !headerDom,
277
- }}
278
- >
279
- {extraDom}
280
- </div>
281
- )}
282
- <div style="flex: 1; overflow: hidden auto;">
283
- {(menuContentRender &&
284
- menuContentRender(props, defaultMenuDom)) ||
285
- defaultMenuDom}
286
- </div>
287
- <div class={`${baseClassName}-links`}>
288
- {collapsedButtonRender !== false ? (
289
- <Menu
290
- class={`${baseClassName}-link-menu`}
291
- inlineIndent={16}
292
- theme={theme}
293
- selectedKeys={[]}
294
- openKeys={[]}
295
- mode="inline"
296
- onClick={() => {
297
- if (props.onCollapse) {
298
- props.onCollapse(!props.collapsed);
299
- }
300
- }}
301
- >
302
- <Menu.Item
303
- key={'collapsed-button'}
304
- class={`${baseClassName}-collapsed-button`}
305
- title={false}
306
- >
307
- {collapsedButtonRender &&
308
- typeof collapsedButtonRender === 'function'
309
- ? collapsedButtonRender(collapsed)
310
- : collapsedButtonRender}
311
- </Menu.Item>
312
- </Menu>
313
- ) : null}
314
- </div>
315
- </Sider>
316
- </>
317
- );
318
- };
319
-
320
- export default SiderMenu;
1
+ import type {
2
+ MenuHeaderRender,
3
+ MenuContentRender,
4
+ MenuExtraRender,
5
+ CollapsedButtonRender,
6
+ LogoRender,
7
+ WithFalse,
8
+ } from '../typings';
9
+ import type { SiderProps } from './typings';
10
+ import { LayoutSider as Sider, Menu } from 'ant-design-vue';
11
+ import BaseMenu, { baseMenuProps } from './BaseMenu';
12
+ import { defaultSettingProps } from '../defaultSettings';
13
+ import PropTypes from 'ant-design-vue/es/_util/vue-types';
14
+ import type {
15
+ CSSProperties,
16
+ ExtractPropTypes,
17
+ PropType,
18
+ FunctionalComponent,
19
+ } from 'vue';
20
+ import type { VueNode } from 'ant-design-vue/es/_util/type';
21
+ import { AIcon as IconFont } from '../../../';
22
+ import { useRouteContext } from '../RouteContext';
23
+ import { computed, unref } from 'vue';
24
+
25
+ export type PrivateSiderMenuProps = {
26
+ matchMenuKeys?: string[];
27
+ };
28
+
29
+ export const siderMenuProps = {
30
+ ...defaultSettingProps,
31
+ ...baseMenuProps,
32
+ logo: {
33
+ type: [Object, String, Function] as PropType<LogoRender>,
34
+ default: () => undefined,
35
+ },
36
+ logoStyle: {
37
+ type: Object as PropType<CSSProperties>,
38
+ default: () => undefined,
39
+ },
40
+ siderWidth: PropTypes.number.def(208),
41
+ headerHeight: PropTypes.number.def(48),
42
+ collapsedWidth: PropTypes.number.def(48),
43
+ menuHeaderRender: {
44
+ type: [Function, Object, Boolean] as PropType<MenuHeaderRender>,
45
+ default: () => undefined,
46
+ },
47
+ menuContentRender: {
48
+ type: [Function, Object, Boolean] as PropType<MenuContentRender>,
49
+ default: () => undefined,
50
+ },
51
+ menuExtraRender: {
52
+ type: [Function, Object, Boolean] as PropType<MenuExtraRender>,
53
+ default: () => undefined,
54
+ },
55
+ collapsedButtonRender: {
56
+ type: [Function, Object, Boolean] as PropType<CollapsedButtonRender>,
57
+ default: () => undefined,
58
+ },
59
+ breakpoint: {
60
+ type: [Object, Boolean] as PropType<SiderProps['breakpoint'] | false>,
61
+ default: () => false,
62
+ },
63
+ splitMenus: PropTypes.looseBool,
64
+ fixed: PropTypes.looseBool,
65
+ hide: PropTypes.looseBool,
66
+ matchMenuKeys: {
67
+ type: Array as PropType<string[]>,
68
+ default: () => [],
69
+ },
70
+
71
+ // events
72
+ onMenuHeaderClick: PropTypes.func,
73
+ onMenuClick: PropTypes.func,
74
+ onCollapse: {
75
+ type: Function as PropType<(collapsed: boolean) => void>,
76
+ },
77
+ onOpenKeys: {
78
+ type: Function as PropType<(openKeys: WithFalse<string[]>) => void>,
79
+ },
80
+ onSelect: {
81
+ type: Function as PropType<(selectedKeys: WithFalse<string[]>) => void>,
82
+ },
83
+ };
84
+
85
+ export type SiderMenuProps = Partial<ExtractPropTypes<typeof siderMenuProps>>;
86
+
87
+ export const defaultRenderLogo = (
88
+ logo?: VueNode,
89
+ logoStyle?: CSSProperties,
90
+ ): VueNode => {
91
+ if (!logo) {
92
+ return null;
93
+ }
94
+ if (typeof logo === 'string') {
95
+ return <img src={logo} alt="logo" style={logoStyle}/>;
96
+ }
97
+ if (typeof logo === 'function') {
98
+ // @ts-ignore
99
+ return logo();
100
+ }
101
+ return logo;
102
+ };
103
+
104
+ export const defaultRenderLogoAndTitle = (
105
+ props: SiderMenuProps,
106
+ renderKey: string | undefined = 'menuHeaderRender',
107
+ ): VueNode | null => {
108
+ const {
109
+ logo = 'http://demo.jetlinks.cn/static/logo.760eb65c.png',
110
+ logoStyle,
111
+ title,
112
+ layout,
113
+ } = props;
114
+ const renderFunction = (props as Record<string, VueNode>)[renderKey || ''];
115
+ if (layout === 'mix' && renderFunction === false) {
116
+ return null;
117
+ }
118
+ const logoDom = defaultRenderLogo(logo, logoStyle);
119
+ const titleDom = <h1>{title}</h1>;
120
+ if (renderKey === 'menuHeaderRender') {
121
+ return null;
122
+ }
123
+ // call menuHeaderRender
124
+ if (typeof renderFunction === 'function') {
125
+ // @ts-ignore
126
+ return renderFunction(
127
+ logoDom,
128
+ props.collapsed ? null : titleDom,
129
+ props,
130
+ );
131
+ }
132
+ if (Array.isArray(renderFunction)) {
133
+ return <>{renderFunction}</>;
134
+ }
135
+
136
+ return (
137
+ <a>
138
+ {logoDom}
139
+ {props.collapsed ? null : titleDom}
140
+ </a>
141
+ );
142
+ };
143
+
144
+ export const defaultRenderCollapsedButton = (collapsed?: boolean): VueNode =>
145
+ collapsed ? (
146
+ <IconFont type={'MenuUnfoldOutlined'}/>
147
+ ) : (
148
+ <IconFont type={'MenuFoldOutlined'}/>
149
+ );
150
+
151
+ const SiderMenu: FunctionalComponent<SiderMenuProps> = (
152
+ props: SiderMenuProps,
153
+ ) => {
154
+ const {
155
+ collapsed,
156
+ siderWidth,
157
+ breakpoint,
158
+ collapsedWidth = 48,
159
+ menuExtraRender = false,
160
+ menuContentRender = false,
161
+ collapsedButtonRender = defaultRenderCollapsedButton,
162
+ theme,
163
+ } = props;
164
+
165
+ const context = useRouteContext();
166
+ const {getPrefixCls} = context;
167
+ const baseClassName = getPrefixCls('sider');
168
+ const hasSplitMenu = computed(
169
+ () => props.layout === 'mix' && props.splitMenus,
170
+ );
171
+ const sSideWidth = computed(() =>
172
+ props.collapsed ? props.collapsedWidth : props.siderWidth,
173
+ );
174
+
175
+ const classNames = computed(() => {
176
+ return {
177
+ [baseClassName]: true,
178
+ [`${baseClassName}-fixed`]: context.fixSiderbar,
179
+ [`${baseClassName}-${theme}`]: true, // theme !== 'dark'
180
+ [`${baseClassName}-layout-${props.layout}`]: props.layout,
181
+ };
182
+ });
183
+
184
+ const handleSelect = ($event: string[]) => {
185
+ if (props.onSelect) {
186
+ if (unref(hasSplitMenu)) {
187
+ props.onSelect([context.selectedKeys[0], ...$event]);
188
+ return;
189
+ }
190
+ props.onSelect($event);
191
+ }
192
+ };
193
+
194
+ const headerDom = defaultRenderLogoAndTitle(props);
195
+ const extraDom = menuExtraRender && menuExtraRender(props);
196
+
197
+ if (hasSplitMenu.value && unref(context.flatMenuData).length === 0) {
198
+ return null;
199
+ }
200
+
201
+ const defaultMenuDom = (
202
+ <BaseMenu
203
+ prefixCls={getPrefixCls()}
204
+ locale={props.locale || context.locale}
205
+ theme={theme}
206
+ mode="inline"
207
+ menuData={
208
+ hasSplitMenu.value ? context.flatMenuData : context.menuData
209
+ }
210
+ collapsed={props.collapsed}
211
+ openKeys={context.openKeys}
212
+ selectedKeys={context.selectedKeys}
213
+ menuItemRender={props.menuItemRender}
214
+ subMenuItemRender={props.subMenuItemRender}
215
+ iconfontUrl={props.iconfontUrl}
216
+ onClick={props.onMenuClick}
217
+ style={{width: '100%'}}
218
+ class={`${baseClassName}-menu`}
219
+ {...{
220
+ 'onUpdate:openKeys': ($event: string[]) =>
221
+ props.onOpenKeys && props.onOpenKeys($event),
222
+ 'onUpdate:selectedKeys': handleSelect,
223
+ }}
224
+ />
225
+ );
226
+
227
+ return (
228
+ <>
229
+ {context.fixSiderbar && (
230
+ <div
231
+ style={{
232
+ width: `${sSideWidth.value}px`,
233
+ overflow: 'hidden',
234
+ flex: `0 0 ${sSideWidth.value}px`,
235
+ maxWidth: `${sSideWidth.value}px`,
236
+ minWidth: `${sSideWidth.value}px`,
237
+ transition: `background-color 0.3s, min-width 0.3s, max-width 0.3s cubic-bezier(0.645, 0.045, 0.355, 1)`,
238
+ }}
239
+ />
240
+ )}
241
+ <Sider
242
+ collapsible
243
+ trigger={null}
244
+ collapsed={collapsed}
245
+ breakpoint={breakpoint || undefined}
246
+ onCollapse={(collapse: boolean) => {
247
+ props.onCollapse?.(collapse);
248
+ }}
249
+ collapsedWidth={collapsedWidth}
250
+ style={{
251
+ overflow: 'hidden',
252
+ paddingTop: `${props.headerHeight}px`,
253
+ }}
254
+ width={siderWidth}
255
+ theme={theme}
256
+ class={classNames.value}
257
+ >
258
+ {headerDom && (
259
+ <div
260
+ class={`${baseClassName}-logo`}
261
+ onClick={
262
+ props.layout !== 'mix'
263
+ ? props.onMenuHeaderClick
264
+ : undefined
265
+ }
266
+ id="logo"
267
+ style={props?.logoStyle}
268
+ >
269
+ {headerDom}
270
+ </div>
271
+ )}
272
+ {extraDom && !props.collapsed && (
273
+ <div
274
+ class={{
275
+ [`${baseClassName}-extra`]: true,
276
+ [`${baseClassName}-extra-no-logo`]: !headerDom,
277
+ }}
278
+ >
279
+ {extraDom}
280
+ </div>
281
+ )}
282
+ <div style="flex: 1; overflow: hidden auto;">
283
+ {(menuContentRender &&
284
+ menuContentRender(props, defaultMenuDom)) ||
285
+ defaultMenuDom}
286
+ </div>
287
+ <div class={`${baseClassName}-links`}>
288
+ {collapsedButtonRender !== false ? (
289
+ <Menu
290
+ class={`${baseClassName}-link-menu`}
291
+ inlineIndent={16}
292
+ theme={theme}
293
+ selectedKeys={[]}
294
+ openKeys={[]}
295
+ mode="inline"
296
+ onClick={() => {
297
+ if (props.onCollapse) {
298
+ props.onCollapse(!props.collapsed);
299
+ }
300
+ }}
301
+ >
302
+ <Menu.Item
303
+ key={'collapsed-button'}
304
+ class={`${baseClassName}-collapsed-button`}
305
+ title={false}
306
+ >
307
+ {collapsedButtonRender &&
308
+ typeof collapsedButtonRender === 'function'
309
+ ? collapsedButtonRender(collapsed)
310
+ : collapsedButtonRender}
311
+ </Menu.Item>
312
+ </Menu>
313
+ ) : null}
314
+ </div>
315
+ </Sider>
316
+ </>
317
+ );
318
+ };
319
+
320
+ export default SiderMenu;