@fe-free/core 2.2.4 → 2.2.5
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/CHANGELOG.md +8 -0
- package/package.json +2 -2
- package/src/copy/copy.stories.tsx +46 -0
- package/src/copy/index.tsx +44 -0
- package/src/index.ts +1 -0
- package/src/route/index.tsx +69 -0
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fe-free/core",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.5",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"author": "",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"remark-gfm": "^4.0.1",
|
|
40
40
|
"vanilla-jsoneditor": "^0.23.1",
|
|
41
41
|
"zustand": "^4.5.4",
|
|
42
|
-
"@fe-free/tool": "2.2.
|
|
42
|
+
"@fe-free/tool": "2.2.5"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"@ant-design/pro-components": "2.8.9",
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { Copy } from './index';
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof Copy> = {
|
|
5
|
+
title: '@fe-free/core/Copy',
|
|
6
|
+
component: Copy,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export default meta;
|
|
11
|
+
type Story = StoryObj<typeof meta>;
|
|
12
|
+
|
|
13
|
+
// 基础用法
|
|
14
|
+
export const Basic: Story = {
|
|
15
|
+
args: {
|
|
16
|
+
value: '点击复制',
|
|
17
|
+
children: '点击复制',
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const ShowIcon: Story = {
|
|
22
|
+
args: {
|
|
23
|
+
value: 'icon复制',
|
|
24
|
+
showIcon: true,
|
|
25
|
+
children: 'icon复制',
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const HoverIcon: Story = {
|
|
30
|
+
args: {
|
|
31
|
+
value: 'hover复制',
|
|
32
|
+
showIcon: true,
|
|
33
|
+
hoverIcon: true,
|
|
34
|
+
children: 'hover复制',
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const OnCopied: Story = {
|
|
39
|
+
args: {
|
|
40
|
+
value: '点击复制',
|
|
41
|
+
onCopied: () => {
|
|
42
|
+
alert('复制成功');
|
|
43
|
+
},
|
|
44
|
+
children: '点击复制',
|
|
45
|
+
},
|
|
46
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { CopyOutlined } from '@ant-design/icons';
|
|
2
|
+
import { copyToClipboard } from '@fe-free/tool';
|
|
3
|
+
import classNames from 'classnames';
|
|
4
|
+
import React, { useCallback } from 'react';
|
|
5
|
+
|
|
6
|
+
interface CopyProps {
|
|
7
|
+
value: string;
|
|
8
|
+
showIcon?: boolean;
|
|
9
|
+
hoverIcon?: boolean;
|
|
10
|
+
children?: React.ReactNode;
|
|
11
|
+
onCopied?: () => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const Copy: React.FC<CopyProps> = ({ value, showIcon, hoverIcon, children, onCopied }) => {
|
|
15
|
+
const handleCopy = useCallback(async () => {
|
|
16
|
+
await copyToClipboard(value);
|
|
17
|
+
onCopied?.();
|
|
18
|
+
}, [value, onCopied]);
|
|
19
|
+
|
|
20
|
+
if (showIcon || hoverIcon) {
|
|
21
|
+
return (
|
|
22
|
+
<div
|
|
23
|
+
className={classNames('flex gap-1', {
|
|
24
|
+
group: hoverIcon,
|
|
25
|
+
})}
|
|
26
|
+
>
|
|
27
|
+
{children}
|
|
28
|
+
<div
|
|
29
|
+
className={classNames('cursor-pointer text-primary', {
|
|
30
|
+
hidden: hoverIcon,
|
|
31
|
+
'group-hover:block': hoverIcon,
|
|
32
|
+
})}
|
|
33
|
+
onClick={handleCopy}
|
|
34
|
+
>
|
|
35
|
+
<CopyOutlined />
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return <div onClick={handleCopy}>{children}</div>;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export { Copy };
|
package/src/index.ts
CHANGED
|
@@ -30,6 +30,7 @@ export {
|
|
|
30
30
|
} from './form';
|
|
31
31
|
export { Markdown } from './markdown';
|
|
32
32
|
export { PageLayout } from './page_layout';
|
|
33
|
+
export { routeTool } from './route';
|
|
33
34
|
export { Table } from './table';
|
|
34
35
|
export type { TableProps } from './table';
|
|
35
36
|
export { Tree, flatToTreeData } from './tree';
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { NavigateFunction } from 'react-router-dom';
|
|
2
|
+
import { generatePath } from 'react-router-dom';
|
|
3
|
+
|
|
4
|
+
const routeTool = {
|
|
5
|
+
_baseName: '' as string,
|
|
6
|
+
_navigate: null as NavigateFunction | null,
|
|
7
|
+
setNavigate: (navigate: NavigateFunction) => {
|
|
8
|
+
routeTool._navigate = navigate;
|
|
9
|
+
},
|
|
10
|
+
setBaseName: (baseName: string) => {
|
|
11
|
+
routeTool._baseName = baseName;
|
|
12
|
+
},
|
|
13
|
+
getNavigate: () => {
|
|
14
|
+
if (!routeTool._navigate) {
|
|
15
|
+
throw new Error('routeTool need set navigate first');
|
|
16
|
+
}
|
|
17
|
+
return routeTool._navigate;
|
|
18
|
+
},
|
|
19
|
+
setSearchParams: (sp: Record<string, any>) => {
|
|
20
|
+
const url = new URL(window.location.href);
|
|
21
|
+
|
|
22
|
+
const p = new URLSearchParams();
|
|
23
|
+
Object.keys(sp).forEach((key) => {
|
|
24
|
+
const value = sp[key];
|
|
25
|
+
// undefined 不能 set,否则 会出现 ?x=undefined 的情况
|
|
26
|
+
if (value !== undefined) {
|
|
27
|
+
p.set(key, value);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
url.search = p.toString();
|
|
31
|
+
|
|
32
|
+
routeTool.getNavigate()(
|
|
33
|
+
`${url.pathname.replace(routeTool._baseName, '')}${url.search}${url.hash}`,
|
|
34
|
+
);
|
|
35
|
+
},
|
|
36
|
+
changeSearchParams: (sp: Record<string, any>) => {
|
|
37
|
+
const url = new URL(window.location.href);
|
|
38
|
+
|
|
39
|
+
Object.keys(sp).forEach((key) => {
|
|
40
|
+
const value = sp[key];
|
|
41
|
+
if (value !== undefined) {
|
|
42
|
+
url.searchParams.set(key, value);
|
|
43
|
+
} else {
|
|
44
|
+
url.searchParams.delete(key);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
routeTool.getNavigate()(
|
|
49
|
+
`${url.pathname.replace(routeTool._baseName, '')}${url.search}${url.hash}`,
|
|
50
|
+
);
|
|
51
|
+
},
|
|
52
|
+
navigateTo: ({
|
|
53
|
+
path,
|
|
54
|
+
params,
|
|
55
|
+
searchParams,
|
|
56
|
+
}: {
|
|
57
|
+
path: string;
|
|
58
|
+
params?: Record<string, string>;
|
|
59
|
+
searchParams?: Record<string, string>;
|
|
60
|
+
}) => {
|
|
61
|
+
const sp = new URLSearchParams(searchParams);
|
|
62
|
+
|
|
63
|
+
routeTool.getNavigate()(
|
|
64
|
+
`${generatePath(path, params)}${searchParams ? `?${sp.toString()}` : ''}`,
|
|
65
|
+
);
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export { routeTool };
|