forked from yunsii/use-switch-tabs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.tsx
127 lines (112 loc) · 3.54 KB
/
index.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import React, { useEffect, useRef } from 'react';
import { Tabs, Dropdown, Menu } from 'antd';
import { TabsProps } from 'antd/lib/tabs';
import { MenuProps } from 'antd/lib/menu';
import * as H from 'history-with-query';
import { usePersistFn } from 'ahooks';
import classNames from 'classnames';
import _get from 'lodash/get';
import { history, useLocation } from '@vitjs/runtime';
import useSwitchTabs, { UseSwitchTabsOptions, ActionType } from '../../../../src';
enum CloseTabKey {
Current = 'current',
Others = 'others',
ToRight = 'toRight',
}
export interface RouteTab {
/** tab's title */
tab: React.ReactNode;
key: string;
content: JSX.Element;
closable?: boolean;
/** used to extends tab's properties */
location: Omit<H.Location, 'key'>;
}
export interface RouteTabsProps
extends Omit<UseSwitchTabsOptions, 'location' | 'history'>,
Omit<TabsProps, 'hideAdd' | 'activeKey' | 'onEdit' | 'onChange' | 'children'> {
fixed?: boolean;
}
export default function SwitchTabs(props: RouteTabsProps): JSX.Element {
const { mode, fixed, originalRoutes, setTabName, persistent, children, ...rest } = props;
const location = useLocation();
const actionRef = useRef<ActionType>();
const { tabs, activeKey, handleSwitch, handleRemove, handleRemoveOthers, handRemoveRightTabs } = useSwitchTabs({
children,
originalRoutes,
mode,
persistent,
location,
history,
actionRef,
setTabName,
});
const remove = usePersistFn((key: string) => {
handleRemove(key);
});
const handleTabEdit = usePersistFn((targetKey: string, action: 'add' | 'remove') => {
if (action === 'remove') {
remove(targetKey);
}
});
const handleTabsMenuClick = usePersistFn((tabKey: string): MenuProps['onClick'] => (event) => {
const { key, domEvent } = event;
domEvent.stopPropagation();
if (key === CloseTabKey.Current) {
handleRemove(tabKey);
} else if (key === CloseTabKey.Others) {
handleRemoveOthers(tabKey);
} else if (key === CloseTabKey.ToRight) {
handRemoveRightTabs(tabKey);
}
});
const setMenu = usePersistFn((key: string, index: number) => (
<Menu onClick={handleTabsMenuClick(key)}>
<Menu.Item disabled={tabs.length === 1} key={CloseTabKey.Current}>
closeCurrent
</Menu.Item>
<Menu.Item disabled={tabs.length === 1} key={CloseTabKey.Others}>
closeOthers
</Menu.Item>
<Menu.Item disabled={tabs.length === index + 1} key={CloseTabKey.ToRight}>
closeToRight
</Menu.Item>
</Menu>
));
const setTab = usePersistFn((tab: React.ReactNode, key: string, index: number) => (
<span onContextMenu={(event) => event.preventDefault()}>
<Dropdown overlay={setMenu(key, index)} trigger={['contextMenu']}>
<span>{tab}</span>
</Dropdown>
</span>
));
useEffect(() => {
window.tabsAction = actionRef.current!;
}, [actionRef.current]);
return (
<Tabs
tabPosition='top'
type='editable-card'
tabBarStyle={{ margin: 0 }}
tabBarGutter={0}
animated
className={classNames('route-tabs', { 'page-tabs-fixed': fixed })}
{...rest}
hideAdd
activeKey={activeKey}
onEdit={handleTabEdit as TabsProps['onEdit']}
onChange={handleSwitch}
>
{tabs.map((item, index) => (
<Tabs.TabPane
tab={setTab(item.title, item.key, index)}
key={item.key}
closable={item.closable}
forceRender={_get(persistent, 'force', false)}
>
{item.content}
</Tabs.TabPane>
))}
</Tabs>
);
}