@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 CHANGED
@@ -1,5 +1,13 @@
1
1
  # @fe-free/core
2
2
 
3
+ ## 2.2.5
4
+
5
+ ### Patch Changes
6
+
7
+ - feat: add copy and route
8
+ - Updated dependencies
9
+ - @fe-free/tool@2.2.5
10
+
3
11
  ## 2.2.4
4
12
 
5
13
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fe-free/core",
3
- "version": "2.2.4",
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.4"
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 };