@wzyjs/uis 0.3.32 → 0.3.37
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/inputs/FileUploader/index.d.ts +10 -7
- package/dist/inputs/FileUploader/index.js +14 -19
- package/dist/inputs/FileUploader/utils.d.ts +20 -0
- package/dist/inputs/FileUploader/utils.js +99 -0
- package/dist/inputs/ImageUploader/index.d.ts +9 -0
- package/dist/inputs/ImageUploader/index.js +179 -91
- package/dist/layout/PageBase/index.d.ts +1 -1
- package/dist/layout/PanelPage/index.d.ts +8 -0
- package/dist/layout/PanelPage/index.js +7 -0
- package/dist/layout/index.d.ts +1 -0
- package/dist/layout/index.js +1 -0
- package/dist/web.css +141 -0
- package/package.json +6 -5
|
@@ -1,22 +1,25 @@
|
|
|
1
|
-
import { type ReactElement } from 'react';
|
|
1
|
+
import { type ReactElement, type ReactNode } from 'react';
|
|
2
2
|
import type { UploadProps, UploadFile as AntUploadFile } from 'antd';
|
|
3
|
+
import { type UploadRequestData } from './utils';
|
|
3
4
|
export interface FileUploaderProps {
|
|
4
5
|
value?: AntUploadFile[];
|
|
5
6
|
onChange?: (fileList: AntUploadFile[]) => void;
|
|
6
7
|
mode?: 'file' | 'http';
|
|
7
|
-
accept?:
|
|
8
|
-
multiple?:
|
|
9
|
-
maxCount?:
|
|
8
|
+
accept?: UploadProps['accept'];
|
|
9
|
+
multiple?: UploadProps['multiple'];
|
|
10
|
+
maxCount?: UploadProps['maxCount'];
|
|
10
11
|
trigger?: 'button' | 'dragger' | ReactElement;
|
|
12
|
+
children?: ReactNode;
|
|
13
|
+
className?: UploadProps['className'];
|
|
11
14
|
listType?: UploadProps['listType'];
|
|
12
|
-
beforeUpload?:
|
|
15
|
+
beforeUpload?: UploadProps['beforeUpload'];
|
|
13
16
|
immediateUpload?: boolean;
|
|
14
17
|
action?: string;
|
|
15
|
-
data?:
|
|
18
|
+
data?: UploadRequestData;
|
|
16
19
|
headers?: UploadProps['headers'];
|
|
17
20
|
withCredentials?: boolean;
|
|
18
21
|
disabled?: boolean;
|
|
19
|
-
showUploadList?:
|
|
22
|
+
showUploadList?: UploadProps['showUploadList'];
|
|
20
23
|
onUploadChange?: UploadProps['onChange'];
|
|
21
24
|
}
|
|
22
25
|
export declare const FileUploader: (props: FileUploaderProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useState } from 'react';
|
|
4
|
-
import { Upload, Button
|
|
4
|
+
import { Upload, Button } from 'antd';
|
|
5
5
|
import { UploadOutlined, InboxOutlined } from '@ant-design/icons';
|
|
6
|
+
import { handleUploadBefore } from './utils';
|
|
6
7
|
export const FileUploader = (props) => {
|
|
7
|
-
const { value, onChange, mode = 'file', accept, multiple = true, maxCount, trigger = 'dragger', listType = 'text', beforeUpload, immediateUpload = false, action = '/api/file/upload', data, headers, withCredentials, disabled, showUploadList = trigger === 'dragger', onUploadChange, } = props;
|
|
8
|
+
const { value, onChange, mode = 'file', accept, multiple = true, maxCount, trigger = 'dragger', children, className, listType = 'text', beforeUpload, immediateUpload = false, action = '/api/file/upload', data, headers, withCredentials, disabled, showUploadList = trigger === 'dragger', onUploadChange, } = props;
|
|
8
9
|
const [internalFileList, setInternalFileList] = useState([]);
|
|
9
10
|
const fileList = value || internalFileList;
|
|
10
11
|
const handleChange = (info) => {
|
|
@@ -26,20 +27,13 @@ export const FileUploader = (props) => {
|
|
|
26
27
|
onChange?.(newFileList);
|
|
27
28
|
onUploadChange?.(info);
|
|
28
29
|
};
|
|
29
|
-
const handleBeforeUpload = async (file) => {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
// 2. 立即上传模式
|
|
38
|
-
if (immediateUpload) {
|
|
39
|
-
return true;
|
|
40
|
-
}
|
|
41
|
-
// 3. 非立即上传模式,阻止默认上传行为,但添加到列表
|
|
42
|
-
return false;
|
|
30
|
+
const handleBeforeUpload = async (file, currentFileList) => {
|
|
31
|
+
return await handleUploadBefore({
|
|
32
|
+
beforeUpload,
|
|
33
|
+
file,
|
|
34
|
+
currentFileList,
|
|
35
|
+
immediateUpload,
|
|
36
|
+
});
|
|
43
37
|
};
|
|
44
38
|
const uploadProps = {
|
|
45
39
|
fileList,
|
|
@@ -47,6 +41,7 @@ export const FileUploader = (props) => {
|
|
|
47
41
|
multiple,
|
|
48
42
|
maxCount,
|
|
49
43
|
listType,
|
|
44
|
+
className,
|
|
50
45
|
disabled,
|
|
51
46
|
showUploadList,
|
|
52
47
|
beforeUpload: handleBeforeUpload,
|
|
@@ -70,10 +65,10 @@ export const FileUploader = (props) => {
|
|
|
70
65
|
return _jsx("div", { children: "HTTP \u8F93\u5165\u6A21\u5F0F\u6682\u672A\u652F\u6301" });
|
|
71
66
|
}
|
|
72
67
|
if (trigger === 'button') {
|
|
73
|
-
return (_jsx(Upload, { ...uploadProps, children: _jsx(Button, { type:
|
|
68
|
+
return (_jsx(Upload, { ...uploadProps, children: _jsx(Button, { type: 'primary', icon: _jsx(UploadOutlined, {}), children: "\u4E0A\u4F20\u6587\u4EF6" }) }));
|
|
74
69
|
}
|
|
75
70
|
if (trigger === 'dragger') {
|
|
76
|
-
return (
|
|
71
|
+
return (_jsx(Upload.Dragger, { ...uploadProps, children: children ?? (_jsxs(_Fragment, { children: [_jsx("p", { className: 'ant-upload-drag-icon', children: _jsx(InboxOutlined, {}) }), _jsx("p", { className: 'ant-upload-text', children: "\u70B9\u51FB\u6216\u62D6\u62FD\u6587\u4EF6\u5230\u6B64\u533A\u57DF\u4E0A\u4F20" }), _jsxs("p", { className: 'ant-upload-hint', children: ["\u652F\u6301\u5355\u4E2A\u6216\u6279\u91CF\u4E0A\u4F20", maxCount ? `,最多 ${maxCount} 个文件` : ''] })] })) }));
|
|
77
72
|
}
|
|
78
73
|
return trigger;
|
|
79
74
|
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { UploadFile as AntUploadFile, UploadProps } from 'antd';
|
|
2
|
+
export type UploadRequestData = Record<string, unknown> | ((file: AntUploadFile) => Record<string, unknown>);
|
|
3
|
+
type BeforeUploadFile = Parameters<NonNullable<UploadProps['beforeUpload']>>[0];
|
|
4
|
+
type BeforeUploadFileList = Parameters<NonNullable<UploadProps['beforeUpload']>>[1];
|
|
5
|
+
export declare const createAntUploadFile: (file: File) => AntUploadFile;
|
|
6
|
+
export declare const handleUploadBefore: ({ beforeUpload, file, currentFileList, immediateUpload, }: {
|
|
7
|
+
beforeUpload?: UploadProps["beforeUpload"];
|
|
8
|
+
file: BeforeUploadFile;
|
|
9
|
+
currentFileList: BeforeUploadFileList;
|
|
10
|
+
immediateUpload: boolean;
|
|
11
|
+
}) => Promise<string | boolean>;
|
|
12
|
+
export declare const uploadFileByAction: ({ action, file, data, headers, withCredentials, }: {
|
|
13
|
+
action: string;
|
|
14
|
+
file: File;
|
|
15
|
+
data?: UploadRequestData;
|
|
16
|
+
headers?: UploadProps["headers"];
|
|
17
|
+
withCredentials?: boolean;
|
|
18
|
+
}) => Promise<any>;
|
|
19
|
+
export declare const getUploadedUrl: (response: unknown) => string;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { Upload } from 'antd';
|
|
2
|
+
export const createAntUploadFile = (file) => ({
|
|
3
|
+
uid: `${file.name}_${file.lastModified}`,
|
|
4
|
+
name: file.name,
|
|
5
|
+
size: file.size,
|
|
6
|
+
type: file.type,
|
|
7
|
+
lastModified: file.lastModified,
|
|
8
|
+
lastModifiedDate: new Date(file.lastModified),
|
|
9
|
+
originFileObj: file,
|
|
10
|
+
});
|
|
11
|
+
export const handleUploadBefore = async ({ beforeUpload, file, currentFileList, immediateUpload, }) => {
|
|
12
|
+
if (beforeUpload) {
|
|
13
|
+
const result = await beforeUpload(file, currentFileList);
|
|
14
|
+
if (result === false || result === Upload.LIST_IGNORE) {
|
|
15
|
+
return Upload.LIST_IGNORE;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
if (immediateUpload) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
return false;
|
|
22
|
+
};
|
|
23
|
+
const resolveUploadData = (data, file) => {
|
|
24
|
+
if (!data) {
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
if (typeof data === 'function') {
|
|
28
|
+
return data(createAntUploadFile(file));
|
|
29
|
+
}
|
|
30
|
+
return data;
|
|
31
|
+
};
|
|
32
|
+
const appendFormValue = (formData, key, value) => {
|
|
33
|
+
if (value == null) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (value instanceof Blob) {
|
|
37
|
+
formData.append(key, value);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (typeof value === 'object') {
|
|
41
|
+
formData.append(key, JSON.stringify(value));
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
formData.append(key, String(value));
|
|
45
|
+
};
|
|
46
|
+
const normalizeHeaders = (headers) => {
|
|
47
|
+
if (!headers) {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
const normalizedHeaders = new Headers();
|
|
51
|
+
Object.entries(headers).forEach(([key, value]) => {
|
|
52
|
+
if (value != null) {
|
|
53
|
+
normalizedHeaders.set(key, String(value));
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
return normalizedHeaders;
|
|
57
|
+
};
|
|
58
|
+
const getUploadErrorMessage = async (response) => {
|
|
59
|
+
const contentType = response.headers.get('content-type') || '';
|
|
60
|
+
if (contentType.includes('application/json')) {
|
|
61
|
+
const body = await response.json().catch(() => null);
|
|
62
|
+
if (body && typeof body === 'object' && 'error' in body && typeof body.error === 'string') {
|
|
63
|
+
return body.error;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const text = await response.text().catch(() => '');
|
|
67
|
+
if (text) {
|
|
68
|
+
return text;
|
|
69
|
+
}
|
|
70
|
+
return `上传失败: ${response.status}`;
|
|
71
|
+
};
|
|
72
|
+
export const uploadFileByAction = async ({ action, file, data, headers, withCredentials, }) => {
|
|
73
|
+
const formData = new FormData();
|
|
74
|
+
formData.append('file', file);
|
|
75
|
+
const uploadData = resolveUploadData(data, file);
|
|
76
|
+
Object.entries(uploadData).forEach(([key, value]) => {
|
|
77
|
+
appendFormValue(formData, key, value);
|
|
78
|
+
});
|
|
79
|
+
const response = await fetch(action, {
|
|
80
|
+
method: 'POST',
|
|
81
|
+
body: formData,
|
|
82
|
+
headers: normalizeHeaders(headers),
|
|
83
|
+
credentials: withCredentials ? 'include' : 'same-origin',
|
|
84
|
+
});
|
|
85
|
+
if (!response.ok) {
|
|
86
|
+
throw new Error(await getUploadErrorMessage(response));
|
|
87
|
+
}
|
|
88
|
+
return await response.json();
|
|
89
|
+
};
|
|
90
|
+
export const getUploadedUrl = (response) => {
|
|
91
|
+
if (response
|
|
92
|
+
&& typeof response === 'object'
|
|
93
|
+
&& 'url' in response
|
|
94
|
+
&& typeof response.url === 'string'
|
|
95
|
+
&& response.url) {
|
|
96
|
+
return response.url;
|
|
97
|
+
}
|
|
98
|
+
throw new Error('上传接口返回缺少 url 字段');
|
|
99
|
+
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { UploadProps } from 'antd';
|
|
2
|
+
import { type UploadRequestData } from '../FileUploader/utils';
|
|
1
3
|
interface ImageUploaderProps {
|
|
2
4
|
value?: string[];
|
|
3
5
|
onChange?: (value: string[]) => void;
|
|
@@ -7,6 +9,13 @@ interface ImageUploaderProps {
|
|
|
7
9
|
enableFileSelect?: boolean;
|
|
8
10
|
enablePaste?: boolean;
|
|
9
11
|
enablePasteTip?: boolean;
|
|
12
|
+
beforeUpload?: UploadProps['beforeUpload'];
|
|
13
|
+
immediateUpload?: boolean;
|
|
14
|
+
action?: string;
|
|
15
|
+
data?: UploadRequestData;
|
|
16
|
+
headers?: UploadProps['headers'];
|
|
17
|
+
withCredentials?: boolean;
|
|
18
|
+
onUploadChange?: UploadProps['onChange'];
|
|
10
19
|
}
|
|
11
20
|
export declare const ImageUploader: (props: ImageUploaderProps) => import("react/jsx-runtime").JSX.Element;
|
|
12
21
|
export {};
|
|
@@ -3,60 +3,206 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useEffect, useRef, useState } from 'react';
|
|
4
4
|
import { Alert, Button, Modal, Popover, Space, Typography } from 'antd';
|
|
5
5
|
import { DeleteOutlined, PlusOutlined } from '@ant-design/icons';
|
|
6
|
+
import { createAntUploadFile, getUploadedUrl, handleUploadBefore, uploadFileByAction, } from '../FileUploader/utils';
|
|
7
|
+
const createImageFile = (file, index) => {
|
|
8
|
+
if (file instanceof File) {
|
|
9
|
+
return file;
|
|
10
|
+
}
|
|
11
|
+
return new File([file], `image_${Date.now()}_${index}.png`, {
|
|
12
|
+
type: file.type || 'image/png',
|
|
13
|
+
lastModified: Date.now(),
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
const createPreviewFileList = (images) => {
|
|
17
|
+
return images.map((image, index) => ({
|
|
18
|
+
uid: `${image}_${index}`,
|
|
19
|
+
name: `image_${index + 1}`,
|
|
20
|
+
status: 'done',
|
|
21
|
+
url: image,
|
|
22
|
+
}));
|
|
23
|
+
};
|
|
24
|
+
const readAsDataURL = (file) => {
|
|
25
|
+
return new Promise((resolve, reject) => {
|
|
26
|
+
const reader = new FileReader();
|
|
27
|
+
reader.onloadend = () => resolve(reader.result);
|
|
28
|
+
reader.onerror = () => reject(reader.error || new Error('读取图片失败'));
|
|
29
|
+
reader.readAsDataURL(file);
|
|
30
|
+
});
|
|
31
|
+
};
|
|
6
32
|
export const ImageUploader = (props) => {
|
|
7
|
-
const { value = [], onChange, maxImages = 10, enablePreview = false, enableDragDrop = false, enableFileSelect = false, enablePaste = true, enablePasteTip = false, } = props;
|
|
33
|
+
const { value = [], onChange, maxImages = 10, enablePreview = false, enableDragDrop = false, enableFileSelect = false, enablePaste = true, enablePasteTip = false, beforeUpload, immediateUpload = false, action = '/api/file/upload', data, headers, withCredentials, onUploadChange, } = props;
|
|
8
34
|
const [isDragging, setIsDragging] = useState(false);
|
|
9
35
|
const fileInputRef = useRef(null);
|
|
36
|
+
const compressImage = (file) => {
|
|
37
|
+
return new Promise((resolve) => {
|
|
38
|
+
const originalSize = file.size / 1024;
|
|
39
|
+
const img = new Image();
|
|
40
|
+
img.src = URL.createObjectURL(file);
|
|
41
|
+
img.onload = () => {
|
|
42
|
+
URL.revokeObjectURL(img.src);
|
|
43
|
+
const canvas = document.createElement('canvas');
|
|
44
|
+
let width = img.width;
|
|
45
|
+
let height = img.height;
|
|
46
|
+
const maxWidth = 1200;
|
|
47
|
+
const maxHeight = 1200;
|
|
48
|
+
if (width > maxWidth || height > maxHeight) {
|
|
49
|
+
const ratio = Math.min(maxWidth / width, maxHeight / height);
|
|
50
|
+
width = width * ratio;
|
|
51
|
+
height = height * ratio;
|
|
52
|
+
}
|
|
53
|
+
canvas.width = width;
|
|
54
|
+
canvas.height = height;
|
|
55
|
+
const ctx = canvas.getContext('2d');
|
|
56
|
+
if (!ctx) {
|
|
57
|
+
resolve(file);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
ctx.drawImage(img, 0, 0, width, height);
|
|
61
|
+
canvas.toBlob((blob) => {
|
|
62
|
+
if (!blob) {
|
|
63
|
+
resolve(file);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const compressedSize = blob.size / 1024;
|
|
67
|
+
console.log(`原始图片: ${originalSize.toFixed(2)} KB => ${compressedSize.toFixed(2)} KB`);
|
|
68
|
+
console.log(`压缩到了: ${((compressedSize / originalSize) * 100).toFixed(2)}%`);
|
|
69
|
+
resolve(blob);
|
|
70
|
+
}, 'image/jpeg', 0.8);
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
const triggerUploadChange = (file, images) => {
|
|
75
|
+
onUploadChange?.({
|
|
76
|
+
file,
|
|
77
|
+
fileList: createPreviewFileList(images),
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
const appendImage = (nextImages, image) => {
|
|
81
|
+
if (!nextImages.includes(image)) {
|
|
82
|
+
nextImages.push(image);
|
|
83
|
+
onChange?.(nextImages.slice());
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
const uploadImage = async (file) => {
|
|
87
|
+
const compressed = await compressImage(file);
|
|
88
|
+
const uploadFile = new File([compressed], file.name, {
|
|
89
|
+
type: compressed.type || file.type || 'image/jpeg',
|
|
90
|
+
lastModified: file.lastModified,
|
|
91
|
+
});
|
|
92
|
+
const response = await uploadFileByAction({
|
|
93
|
+
action,
|
|
94
|
+
file: uploadFile,
|
|
95
|
+
data,
|
|
96
|
+
headers,
|
|
97
|
+
withCredentials,
|
|
98
|
+
});
|
|
99
|
+
return {
|
|
100
|
+
response,
|
|
101
|
+
url: getUploadedUrl(response),
|
|
102
|
+
uploadFile,
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
const addFiles = async (files) => {
|
|
106
|
+
const remainCount = maxImages - value.length;
|
|
107
|
+
if (remainCount <= 0) {
|
|
108
|
+
alert(`最多允许上传 ${maxImages} 张图片。`);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const imageFiles = files
|
|
112
|
+
.filter(file => file.type.startsWith('image/'))
|
|
113
|
+
.slice(0, remainCount)
|
|
114
|
+
.map((file, index) => createImageFile(file, index));
|
|
115
|
+
const nextImages = value.slice();
|
|
116
|
+
try {
|
|
117
|
+
for (const file of imageFiles) {
|
|
118
|
+
const beforeResult = await handleUploadBefore({
|
|
119
|
+
beforeUpload,
|
|
120
|
+
file: file,
|
|
121
|
+
currentFileList: imageFiles,
|
|
122
|
+
immediateUpload,
|
|
123
|
+
});
|
|
124
|
+
if (beforeResult !== true && beforeResult !== false) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (immediateUpload) {
|
|
128
|
+
const { response, url, uploadFile } = await uploadImage(file);
|
|
129
|
+
appendImage(nextImages, url);
|
|
130
|
+
triggerUploadChange({
|
|
131
|
+
...createAntUploadFile(uploadFile),
|
|
132
|
+
status: 'done',
|
|
133
|
+
url,
|
|
134
|
+
response,
|
|
135
|
+
}, nextImages);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
const compressed = await compressImage(file);
|
|
139
|
+
const base64String = await readAsDataURL(compressed);
|
|
140
|
+
appendImage(nextImages, base64String);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
console.error('图片处理失败:', error);
|
|
145
|
+
if (immediateUpload) {
|
|
146
|
+
triggerUploadChange({
|
|
147
|
+
uid: '-1',
|
|
148
|
+
name: 'upload-error',
|
|
149
|
+
status: 'error',
|
|
150
|
+
}, nextImages);
|
|
151
|
+
}
|
|
152
|
+
alert(error instanceof Error ? error.message : '图片处理失败,请重试。');
|
|
153
|
+
}
|
|
154
|
+
finally {
|
|
155
|
+
if (fileInputRef.current) {
|
|
156
|
+
fileInputRef.current.value = '';
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
};
|
|
10
160
|
useEffect(() => {
|
|
11
161
|
if (!enablePaste)
|
|
12
162
|
return;
|
|
13
163
|
const handlePaste = (event) => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
convertToBase64(file);
|
|
22
|
-
}
|
|
164
|
+
const items = event.clipboardData?.items || [];
|
|
165
|
+
const files = [];
|
|
166
|
+
for (const item of items) {
|
|
167
|
+
if (item.type.startsWith('image/')) {
|
|
168
|
+
const file = item.getAsFile();
|
|
169
|
+
if (file) {
|
|
170
|
+
files.push(file);
|
|
23
171
|
}
|
|
24
172
|
}
|
|
25
173
|
}
|
|
174
|
+
if (files.length) {
|
|
175
|
+
void addFiles(files);
|
|
176
|
+
}
|
|
26
177
|
};
|
|
27
178
|
document.addEventListener('paste', handlePaste);
|
|
28
179
|
return () => {
|
|
29
180
|
document.removeEventListener('paste', handlePaste);
|
|
30
181
|
};
|
|
31
|
-
}, [value,
|
|
32
|
-
const
|
|
182
|
+
}, [enablePaste, value, beforeUpload, immediateUpload, action, data, headers, withCredentials, onChange, onUploadChange, maxImages]);
|
|
183
|
+
const handleDrop = (e) => {
|
|
33
184
|
if (!enableDragDrop)
|
|
34
185
|
return;
|
|
35
186
|
e.preventDefault();
|
|
36
187
|
e.stopPropagation();
|
|
37
|
-
setIsDragging(
|
|
188
|
+
setIsDragging(false);
|
|
189
|
+
if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
|
|
190
|
+
void addFiles(Array.from(e.dataTransfer.files));
|
|
191
|
+
}
|
|
38
192
|
};
|
|
39
|
-
const
|
|
193
|
+
const handleDragOver = (e) => {
|
|
40
194
|
if (!enableDragDrop)
|
|
41
195
|
return;
|
|
42
196
|
e.preventDefault();
|
|
43
197
|
e.stopPropagation();
|
|
44
|
-
setIsDragging(
|
|
198
|
+
setIsDragging(true);
|
|
45
199
|
};
|
|
46
|
-
const
|
|
200
|
+
const handleDragLeave = (e) => {
|
|
47
201
|
if (!enableDragDrop)
|
|
48
202
|
return;
|
|
49
203
|
e.preventDefault();
|
|
50
204
|
e.stopPropagation();
|
|
51
205
|
setIsDragging(false);
|
|
52
|
-
if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
|
|
53
|
-
const fileList = Array.from(e.dataTransfer.files);
|
|
54
|
-
fileList.forEach((file) => {
|
|
55
|
-
if (file.type.match('image.*')) {
|
|
56
|
-
convertToBase64(file);
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
206
|
};
|
|
61
207
|
const handleClick = () => {
|
|
62
208
|
if (!enableFileSelect)
|
|
@@ -67,89 +213,31 @@ export const ImageUploader = (props) => {
|
|
|
67
213
|
if (!enableFileSelect)
|
|
68
214
|
return;
|
|
69
215
|
if (e.target.files && e.target.files.length > 0) {
|
|
70
|
-
|
|
71
|
-
fileList.forEach((file) => {
|
|
72
|
-
if (file.type.match('image.*')) {
|
|
73
|
-
convertToBase64(file);
|
|
74
|
-
}
|
|
75
|
-
});
|
|
216
|
+
void addFiles(Array.from(e.target.files));
|
|
76
217
|
}
|
|
77
218
|
};
|
|
78
219
|
const handlePasteButton = () => {
|
|
79
220
|
if (!enablePaste)
|
|
80
221
|
return;
|
|
81
222
|
navigator.clipboard.read().then((clipboardItems) => {
|
|
223
|
+
const files = [];
|
|
82
224
|
for (const clipboardItem of clipboardItems) {
|
|
83
225
|
for (const type of clipboardItem.types) {
|
|
84
226
|
if (type.startsWith('image/')) {
|
|
85
|
-
clipboardItem.getType(type)
|
|
86
|
-
convertToBase64(blob);
|
|
87
|
-
});
|
|
227
|
+
files.push(clipboardItem.getType(type));
|
|
88
228
|
}
|
|
89
229
|
}
|
|
90
230
|
}
|
|
231
|
+
return Promise.all(files);
|
|
232
|
+
}).then((files) => {
|
|
233
|
+
if (files.length) {
|
|
234
|
+
void addFiles(files);
|
|
235
|
+
}
|
|
91
236
|
}).catch(error => {
|
|
92
237
|
console.error('读取剪贴板失败:', error);
|
|
93
238
|
alert('读取剪贴板失败。请尝试使用 Ctrl+V 粘贴或手动上传图片。');
|
|
94
239
|
});
|
|
95
240
|
};
|
|
96
|
-
const convertToBase64 = (file) => {
|
|
97
|
-
if (value.length >= maxImages) {
|
|
98
|
-
alert(`最多允许上传 ${maxImages} 张图片。`);
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
compressImage(file).then(compressedFile => {
|
|
102
|
-
const reader = new FileReader();
|
|
103
|
-
reader.onloadend = () => {
|
|
104
|
-
const base64String = reader.result;
|
|
105
|
-
if (!value.includes(base64String)) {
|
|
106
|
-
onChange?.([...value, base64String]);
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
reader.readAsDataURL(compressedFile);
|
|
110
|
-
});
|
|
111
|
-
};
|
|
112
|
-
const compressImage = (file) => {
|
|
113
|
-
return new Promise((resolve) => {
|
|
114
|
-
const originalSize = file.size / 1024;
|
|
115
|
-
const img = new Image();
|
|
116
|
-
img.src = URL.createObjectURL(file);
|
|
117
|
-
img.onload = () => {
|
|
118
|
-
URL.revokeObjectURL(img.src);
|
|
119
|
-
const canvas = document.createElement('canvas');
|
|
120
|
-
let width = img.width;
|
|
121
|
-
let height = img.height;
|
|
122
|
-
// 计算压缩比例,保持宽高比
|
|
123
|
-
const maxWidth = 1200;
|
|
124
|
-
const maxHeight = 1200;
|
|
125
|
-
if (width > maxWidth || height > maxHeight) {
|
|
126
|
-
const ratio = Math.min(maxWidth / width, maxHeight / height);
|
|
127
|
-
width = width * ratio;
|
|
128
|
-
height = height * ratio;
|
|
129
|
-
}
|
|
130
|
-
canvas.width = width;
|
|
131
|
-
canvas.height = height;
|
|
132
|
-
const ctx = canvas.getContext('2d');
|
|
133
|
-
if (!ctx) {
|
|
134
|
-
resolve(file);
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
ctx.drawImage(img, 0, 0, width, height);
|
|
138
|
-
// 转换为blob,压缩质量为0.8
|
|
139
|
-
canvas.toBlob((blob) => {
|
|
140
|
-
if (!blob) {
|
|
141
|
-
resolve(file);
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
// 获取压缩后的图片大小
|
|
145
|
-
const compressedSize = blob.size / 1024;
|
|
146
|
-
console.log(`原始图片: ${originalSize.toFixed(2)} KB => ${compressedSize.toFixed(2)} KB`);
|
|
147
|
-
console.log(`压缩到了: ${((compressedSize / originalSize) * 100).toFixed(2)}%`);
|
|
148
|
-
resolve(blob);
|
|
149
|
-
}, 'image/jpeg', 0.8);
|
|
150
|
-
};
|
|
151
|
-
});
|
|
152
|
-
};
|
|
153
241
|
const handleRemoveImage = (index) => {
|
|
154
242
|
Modal.confirm({
|
|
155
243
|
title: '确认删除',
|
|
@@ -176,7 +264,7 @@ export const ImageUploader = (props) => {
|
|
|
176
264
|
height: 'auto',
|
|
177
265
|
objectFit: 'contain',
|
|
178
266
|
} })), children: imageNode }) }, index));
|
|
179
|
-
}), value.length < maxImages && (_jsxs(Space, { style: { width: '100%' }, children: [enableFileSelect && (_jsxs("div", { className: `border-2 border-dashed rounded flex flex-col items-center justify-center cursor-pointer transition-colors ${isDragging && enableDragDrop ? 'border-blue-500 bg-blue-50' : 'border-gray-300 hover:border-blue-500'}`,
|
|
267
|
+
}), value.length < maxImages && (_jsxs(Space, { style: { width: '100%' }, children: [enableFileSelect && (_jsxs("div", { className: `border-2 border-dashed rounded flex flex-col items-center justify-center cursor-pointer transition-colors ${isDragging && enableDragDrop ? 'border-blue-500 bg-blue-50' : 'border-gray-300 hover:border-blue-500'}`, onDrop: enableDragDrop ? handleDrop : undefined, onClick: handleClick, onDragOver: enableDragDrop ? handleDragOver : undefined, onDragLeave: enableDragDrop ? handleDragLeave : undefined, style: { width: '50px', height: '50px' }, children: [_jsx(PlusOutlined, { style: { fontSize: '24px', color: '#8c8c8c' } }), _jsx(Typography.Text, { type: 'secondary', className: 'm-2', children: "\u4E0A\u4F20" })] })), enablePaste && (_jsxs("div", { style: { width: '50px', height: '50px' }, className: `border-2 border-dashed rounded flex flex-col items-center justify-center cursor-pointer transition-colors ${isDragging ? 'border-blue-500 bg-blue-50' : 'border-gray-300 hover:border-blue-500'}`, onClick: handlePasteButton, children: [_jsx(PlusOutlined, { style: { fontSize: '24px', color: '#8c8c8c' } }), _jsx(Typography.Text, { type: 'secondary', className: 'm-2', children: "\u7C98\u8D34" })] }))] }))] }), enableFileSelect && (_jsx("input", { type: 'file', ref: fileInputRef, onChange: handleFileChange, accept: 'image/*', multiple: true, style: { display: 'none' } })), (enablePasteTip && enablePaste) && (_jsx(Alert, { type: 'info', showIcon: true, title: _jsxs(Typography.Text, { type: 'secondary', children: ["\u63D0\u793A\uFF1A\u60A8\u4E5F\u53EF\u4EE5\u5728\u4EFB\u610F\u4F4D\u7F6E\u6309\u4E0B ", _jsx("kbd", { style: {
|
|
180
268
|
padding: '0.1rem 0.4rem',
|
|
181
269
|
background: '#f5f5f5',
|
|
182
270
|
border: '1px solid #d9d9d9',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { PropsWithChildren, ReactNode } from 'react';
|
|
2
2
|
interface PageBaseProps extends PropsWithChildren {
|
|
3
|
-
title
|
|
3
|
+
title?: ReactNode;
|
|
4
4
|
}
|
|
5
5
|
export declare const PageBase: (props: PageBaseProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
6
|
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
export interface PanelPageProps {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
description?: ReactNode;
|
|
5
|
+
eyebrow: string;
|
|
6
|
+
title: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const PanelPage: (props: PanelPageProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Typography } from 'antd';
|
|
4
|
+
export const PanelPage = (props) => {
|
|
5
|
+
const { children, description, eyebrow, title } = props;
|
|
6
|
+
return (_jsxs("div", { className: 'relative min-h-[calc(100vh-100px)] overflow-hidden bg-[linear-gradient(180deg,_#f8fbff_0%,_#eef4ff_52%,_#f8fafc_100%)] dark:bg-[linear-gradient(180deg,_#0f172a_0%,_#111827_55%,_#0f172a_100%)]', children: [_jsx("div", { className: 'absolute inset-0 bg-[linear-gradient(rgba(148,163,184,0.1)_1px,transparent_1px),linear-gradient(90deg,rgba(148,163,184,0.1)_1px,transparent_1px)] bg-[size:32px_32px] opacity-40 dark:opacity-10' }), _jsx("div", { className: 'relative mx-auto flex min-h-[calc(100vh-100px)] max-w-6xl items-center justify-center px-4 py-8 sm:px-6 lg:px-8', children: _jsxs("div", { className: 'w-full max-w-xl overflow-hidden rounded-lg border border-slate-200/80 bg-white/80 shadow-sm backdrop-blur-sm dark:border-white/10 dark:bg-white/5', children: [_jsxs("div", { className: 'border-b border-slate-200/70 px-6 py-6 dark:border-white/10 sm:px-8', children: [_jsx(Typography.Text, { className: 'text-xs font-semibold uppercase tracking-[0.3em] text-slate-500 dark:text-slate-400', children: eyebrow }), _jsx(Typography.Title, { level: 3, className: '!mb-0 !mt-4 !text-3xl !font-semibold !text-slate-950 dark:!text-slate-50', children: title }), description ? (_jsx("div", { className: 'mt-2 text-sm leading-6 text-slate-500 dark:text-slate-300', children: description })) : null] }), _jsx("div", { className: 'px-4 py-4 sm:px-6 sm:py-6', children: children })] }) })] }));
|
|
7
|
+
};
|
package/dist/layout/index.d.ts
CHANGED
package/dist/layout/index.js
CHANGED
package/dist/web.css
CHANGED
|
@@ -38,12 +38,21 @@
|
|
|
38
38
|
margin-left: auto;
|
|
39
39
|
margin-right: auto
|
|
40
40
|
}
|
|
41
|
+
.\!mb-0 {
|
|
42
|
+
margin-bottom: 0px !important
|
|
43
|
+
}
|
|
44
|
+
.\!mt-4 {
|
|
45
|
+
margin-top: 1rem !important
|
|
46
|
+
}
|
|
41
47
|
.mb-6 {
|
|
42
48
|
margin-bottom: 1.5rem
|
|
43
49
|
}
|
|
44
50
|
.ml-2 {
|
|
45
51
|
margin-left: 0.5rem
|
|
46
52
|
}
|
|
53
|
+
.mt-2 {
|
|
54
|
+
margin-top: 0.5rem
|
|
55
|
+
}
|
|
47
56
|
.mt-auto {
|
|
48
57
|
margin-top: auto
|
|
49
58
|
}
|
|
@@ -68,6 +77,9 @@
|
|
|
68
77
|
.h-screen {
|
|
69
78
|
height: 100vh
|
|
70
79
|
}
|
|
80
|
+
.min-h-\[calc\(100vh-100px\)\] {
|
|
81
|
+
min-height: calc(100vh - 100px)
|
|
82
|
+
}
|
|
71
83
|
.w-16 {
|
|
72
84
|
width: 4rem
|
|
73
85
|
}
|
|
@@ -83,9 +95,15 @@
|
|
|
83
95
|
.w-px {
|
|
84
96
|
width: 1px
|
|
85
97
|
}
|
|
98
|
+
.max-w-6xl {
|
|
99
|
+
max-width: 72rem
|
|
100
|
+
}
|
|
86
101
|
.max-w-7xl {
|
|
87
102
|
max-width: 80rem
|
|
88
103
|
}
|
|
104
|
+
.max-w-xl {
|
|
105
|
+
max-width: 36rem
|
|
106
|
+
}
|
|
89
107
|
.flex-1 {
|
|
90
108
|
flex: 1 1 0%
|
|
91
109
|
}
|
|
@@ -148,12 +166,18 @@
|
|
|
148
166
|
.rounded-full {
|
|
149
167
|
border-radius: 9999px
|
|
150
168
|
}
|
|
169
|
+
.rounded-lg {
|
|
170
|
+
border-radius: 0.5rem
|
|
171
|
+
}
|
|
151
172
|
.border {
|
|
152
173
|
border-width: 1px
|
|
153
174
|
}
|
|
154
175
|
.border-2 {
|
|
155
176
|
border-width: 2px
|
|
156
177
|
}
|
|
178
|
+
.border-b {
|
|
179
|
+
border-bottom-width: 1px
|
|
180
|
+
}
|
|
157
181
|
.border-t {
|
|
158
182
|
border-top-width: 1px
|
|
159
183
|
}
|
|
@@ -175,6 +199,12 @@
|
|
|
175
199
|
--tw-border-opacity: 1;
|
|
176
200
|
border-color: rgb(209 213 219 / var(--tw-border-opacity, 1))
|
|
177
201
|
}
|
|
202
|
+
.border-slate-200\/70 {
|
|
203
|
+
border-color: rgb(226 232 240 / 0.7)
|
|
204
|
+
}
|
|
205
|
+
.border-slate-200\/80 {
|
|
206
|
+
border-color: rgb(226 232 240 / 0.8)
|
|
207
|
+
}
|
|
178
208
|
.\!bg-blue-500 {
|
|
179
209
|
--tw-bg-opacity: 1 !important;
|
|
180
210
|
background-color: rgb(59 130 246 / var(--tw-bg-opacity, 1)) !important
|
|
@@ -198,6 +228,18 @@
|
|
|
198
228
|
--tw-bg-opacity: 1;
|
|
199
229
|
background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1))
|
|
200
230
|
}
|
|
231
|
+
.bg-white\/80 {
|
|
232
|
+
background-color: rgb(255 255 255 / 0.8)
|
|
233
|
+
}
|
|
234
|
+
.bg-\[linear-gradient\(180deg\2c _\#f8fbff_0\%\2c _\#eef4ff_52\%\2c _\#f8fafc_100\%\)\] {
|
|
235
|
+
background-image: linear-gradient(180deg, #f8fbff 0%, #eef4ff 52%, #f8fafc 100%)
|
|
236
|
+
}
|
|
237
|
+
.bg-\[linear-gradient\(rgba\(148\2c 163\2c 184\2c 0\.1\)_1px\2c transparent_1px\)\2c linear-gradient\(90deg\2c rgba\(148\2c 163\2c 184\2c 0\.1\)_1px\2c transparent_1px\)\] {
|
|
238
|
+
background-image: linear-gradient(rgba(148,163,184,0.1) 1px,transparent 1px),linear-gradient(90deg,rgba(148,163,184,0.1) 1px,transparent 1px)
|
|
239
|
+
}
|
|
240
|
+
.bg-\[size\:32px_32px\] {
|
|
241
|
+
background-size: 32px 32px
|
|
242
|
+
}
|
|
201
243
|
.object-contain {
|
|
202
244
|
-o-object-fit: contain;
|
|
203
245
|
object-fit: contain
|
|
@@ -212,16 +254,36 @@
|
|
|
212
254
|
padding-left: 1rem;
|
|
213
255
|
padding-right: 1rem
|
|
214
256
|
}
|
|
257
|
+
.px-6 {
|
|
258
|
+
padding-left: 1.5rem;
|
|
259
|
+
padding-right: 1.5rem
|
|
260
|
+
}
|
|
215
261
|
.py-2 {
|
|
216
262
|
padding-top: 0.5rem;
|
|
217
263
|
padding-bottom: 0.5rem
|
|
218
264
|
}
|
|
265
|
+
.py-4 {
|
|
266
|
+
padding-top: 1rem;
|
|
267
|
+
padding-bottom: 1rem
|
|
268
|
+
}
|
|
269
|
+
.py-6 {
|
|
270
|
+
padding-top: 1.5rem;
|
|
271
|
+
padding-bottom: 1.5rem
|
|
272
|
+
}
|
|
273
|
+
.py-8 {
|
|
274
|
+
padding-top: 2rem;
|
|
275
|
+
padding-bottom: 2rem
|
|
276
|
+
}
|
|
219
277
|
.pr-4 {
|
|
220
278
|
padding-right: 1rem
|
|
221
279
|
}
|
|
222
280
|
.text-center {
|
|
223
281
|
text-align: center
|
|
224
282
|
}
|
|
283
|
+
.\!text-3xl {
|
|
284
|
+
font-size: 1.875rem !important;
|
|
285
|
+
line-height: 2.25rem !important
|
|
286
|
+
}
|
|
225
287
|
.text-2xl {
|
|
226
288
|
font-size: 1.5rem;
|
|
227
289
|
line-height: 2rem
|
|
@@ -246,15 +308,34 @@
|
|
|
246
308
|
font-size: 0.75rem;
|
|
247
309
|
line-height: 1rem
|
|
248
310
|
}
|
|
311
|
+
.\!font-semibold {
|
|
312
|
+
font-weight: 600 !important
|
|
313
|
+
}
|
|
249
314
|
.font-bold {
|
|
250
315
|
font-weight: 700
|
|
251
316
|
}
|
|
252
317
|
.font-medium {
|
|
253
318
|
font-weight: 500
|
|
254
319
|
}
|
|
320
|
+
.font-semibold {
|
|
321
|
+
font-weight: 600
|
|
322
|
+
}
|
|
323
|
+
.uppercase {
|
|
324
|
+
text-transform: uppercase
|
|
325
|
+
}
|
|
326
|
+
.leading-6 {
|
|
327
|
+
line-height: 1.5rem
|
|
328
|
+
}
|
|
255
329
|
.leading-none {
|
|
256
330
|
line-height: 1
|
|
257
331
|
}
|
|
332
|
+
.tracking-\[0\.3em\] {
|
|
333
|
+
letter-spacing: 0.3em
|
|
334
|
+
}
|
|
335
|
+
.\!text-slate-950 {
|
|
336
|
+
--tw-text-opacity: 1 !important;
|
|
337
|
+
color: rgb(2 6 23 / var(--tw-text-opacity, 1)) !important
|
|
338
|
+
}
|
|
258
339
|
.\!text-white {
|
|
259
340
|
--tw-text-opacity: 1 !important;
|
|
260
341
|
color: rgb(255 255 255 / var(--tw-text-opacity, 1)) !important
|
|
@@ -271,6 +352,10 @@
|
|
|
271
352
|
--tw-text-opacity: 1;
|
|
272
353
|
color: rgb(17 24 39 / var(--tw-text-opacity, 1))
|
|
273
354
|
}
|
|
355
|
+
.text-slate-500 {
|
|
356
|
+
--tw-text-opacity: 1;
|
|
357
|
+
color: rgb(100 116 139 / var(--tw-text-opacity, 1))
|
|
358
|
+
}
|
|
274
359
|
.text-white {
|
|
275
360
|
--tw-text-opacity: 1;
|
|
276
361
|
color: rgb(255 255 255 / var(--tw-text-opacity, 1))
|
|
@@ -284,6 +369,14 @@
|
|
|
284
369
|
.opacity-30 {
|
|
285
370
|
opacity: 0.3
|
|
286
371
|
}
|
|
372
|
+
.opacity-40 {
|
|
373
|
+
opacity: 0.4
|
|
374
|
+
}
|
|
375
|
+
.shadow-sm {
|
|
376
|
+
--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
|
377
|
+
--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
|
|
378
|
+
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)
|
|
379
|
+
}
|
|
287
380
|
.outline {
|
|
288
381
|
outline-style: solid
|
|
289
382
|
}
|
|
@@ -307,6 +400,10 @@
|
|
|
307
400
|
.filter {
|
|
308
401
|
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)
|
|
309
402
|
}
|
|
403
|
+
.backdrop-blur-sm {
|
|
404
|
+
--tw-backdrop-blur: blur(4px);
|
|
405
|
+
backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)
|
|
406
|
+
}
|
|
310
407
|
.transition {
|
|
311
408
|
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
|
|
312
409
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
@@ -361,3 +458,47 @@
|
|
|
361
458
|
.focus\:ring-offset-2:focus {
|
|
362
459
|
--tw-ring-offset-width: 2px
|
|
363
460
|
}
|
|
461
|
+
.dark\:border-white\/10:is(.dark *) {
|
|
462
|
+
border-color: rgb(255 255 255 / 0.1)
|
|
463
|
+
}
|
|
464
|
+
.dark\:bg-white\/5:is(.dark *) {
|
|
465
|
+
background-color: rgb(255 255 255 / 0.05)
|
|
466
|
+
}
|
|
467
|
+
.dark\:bg-\[linear-gradient\(180deg\2c _\#0f172a_0\%\2c _\#111827_55\%\2c _\#0f172a_100\%\)\]:is(.dark *) {
|
|
468
|
+
background-image: linear-gradient(180deg, #0f172a 0%, #111827 55%, #0f172a 100%)
|
|
469
|
+
}
|
|
470
|
+
.dark\:\!text-slate-50:is(.dark *) {
|
|
471
|
+
--tw-text-opacity: 1 !important;
|
|
472
|
+
color: rgb(248 250 252 / var(--tw-text-opacity, 1)) !important
|
|
473
|
+
}
|
|
474
|
+
.dark\:text-slate-300:is(.dark *) {
|
|
475
|
+
--tw-text-opacity: 1;
|
|
476
|
+
color: rgb(203 213 225 / var(--tw-text-opacity, 1))
|
|
477
|
+
}
|
|
478
|
+
.dark\:text-slate-400:is(.dark *) {
|
|
479
|
+
--tw-text-opacity: 1;
|
|
480
|
+
color: rgb(148 163 184 / var(--tw-text-opacity, 1))
|
|
481
|
+
}
|
|
482
|
+
.dark\:opacity-10:is(.dark *) {
|
|
483
|
+
opacity: 0.1
|
|
484
|
+
}
|
|
485
|
+
@media (min-width: 640px) {
|
|
486
|
+
.sm\:px-6 {
|
|
487
|
+
padding-left: 1.5rem;
|
|
488
|
+
padding-right: 1.5rem
|
|
489
|
+
}
|
|
490
|
+
.sm\:px-8 {
|
|
491
|
+
padding-left: 2rem;
|
|
492
|
+
padding-right: 2rem
|
|
493
|
+
}
|
|
494
|
+
.sm\:py-6 {
|
|
495
|
+
padding-top: 1.5rem;
|
|
496
|
+
padding-bottom: 1.5rem
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
@media (min-width: 1024px) {
|
|
500
|
+
.lg\:px-8 {
|
|
501
|
+
padding-left: 2rem;
|
|
502
|
+
padding-right: 2rem
|
|
503
|
+
}
|
|
504
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wzyjs/uis",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.37",
|
|
4
4
|
"description": "description",
|
|
5
5
|
"author": "wzy",
|
|
6
6
|
"type": "module",
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"**/*.css"
|
|
10
10
|
],
|
|
11
11
|
"scripts": {
|
|
12
|
-
"build": "rm -rf dist && tsc && rsync -a --include='*/' --include='*.css' --exclude='*' src/ dist/ && postcss ./src/web.css -o ./dist/web.css"
|
|
12
|
+
"build": "rm -rf dist && tsc && rsync -a --include='*/' --include='*.css' --exclude='*' src/ dist/ && postcss ./src/web.css -o ./dist/web.css",
|
|
13
|
+
"typecheck": "tsc --noEmit"
|
|
13
14
|
},
|
|
14
15
|
"files": [
|
|
15
16
|
"dist"
|
|
@@ -35,8 +36,8 @@
|
|
|
35
36
|
"@ant-design/pro-form": "^2.32.0",
|
|
36
37
|
"@ant-design/pro-provider": "^2.16.2",
|
|
37
38
|
"@hello-pangea/dnd": "^18.0.1",
|
|
38
|
-
"@wzyjs/hooks": "0.3.
|
|
39
|
-
"@wzyjs/utils": "0.3.
|
|
39
|
+
"@wzyjs/hooks": "0.3.37",
|
|
40
|
+
"@wzyjs/utils": "0.3.37",
|
|
40
41
|
"@xyflow/react": "^12.5.3",
|
|
41
42
|
"echarts": "^5.4.3",
|
|
42
43
|
"echarts-for-react": "^3.0.2",
|
|
@@ -69,7 +70,7 @@
|
|
|
69
70
|
"postcss-cli": "^11.0.1",
|
|
70
71
|
"tailwindcss": "^3.4.18"
|
|
71
72
|
},
|
|
72
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "66fc9b56ff49d9a725189dbd3360d6987cb9d604",
|
|
73
74
|
"publishConfig": {
|
|
74
75
|
"access": "public"
|
|
75
76
|
}
|