sun-card-design 1.1.39 → 1.1.41
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/README.md +121 -114
- package/dist/mobile/sun-card-design-mobile.es25.js +6 -6
- package/dist/mobile/sun-card-design-mobile.es57.js +204 -65
- package/dist/mobile/sun-card-design-mobile.es58.js +47 -81
- package/dist/mobile/sun-card-design-mobile.es59.js +11 -22
- package/dist/mobile/sun-card-design-mobile.es60.js +9 -9
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,114 +1,121 @@
|
|
|
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
|
-
import
|
|
88
|
-
import 'sun-card-
|
|
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
|
-
|
|
1
|
+
# Sun Card Design
|
|
2
|
+
|
|
3
|
+
一个用于卡片设计预览的 Vue 3 组件库,支持 PC 与移动端渲染,提供完整样式与多种基础/表单/图表/媒体组件的预览。
|
|
4
|
+
|
|
5
|
+
## 低代码卡片介绍
|
|
6
|
+
|
|
7
|
+
- sun-card-designer 设计器库
|
|
8
|
+
- sun-card-design 预览库
|
|
9
|
+
|
|
10
|
+
## 特性
|
|
11
|
+
|
|
12
|
+
- 🎯 PC 与移动端双入口:按需引入 `pc`、`mobile` 渲染面板
|
|
13
|
+
- 🎨 自带样式:提供 `sun-card-design/style.css` 一次性引入
|
|
14
|
+
- 🧩 组件丰富:文本、图片、音视频、表单控件、网格、图表等
|
|
15
|
+
|
|
16
|
+
## 安装
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install sun-card-design
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
#### 必备依赖(在你的项目中安装)
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Vue 生态基础
|
|
26
|
+
npm i vue@^3.5.0 vue-router@^4 pinia@^3 ant-design-vue@^4
|
|
27
|
+
|
|
28
|
+
# 设计器库(若使用 sun-card-designer 整包插件)
|
|
29
|
+
npm i sun-card-design
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## 快速开始
|
|
33
|
+
|
|
34
|
+
### 方式一:按平台引入(推荐)
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
// 样式(必需)
|
|
38
|
+
import 'sun-card-design/style.css'
|
|
39
|
+
|
|
40
|
+
// 按平台引入渲染面板
|
|
41
|
+
import PcPanel from 'sun-card-design/pc'
|
|
42
|
+
import MobilePanel from 'sun-card-design/mobile'
|
|
43
|
+
|
|
44
|
+
// Vue 组件中使用
|
|
45
|
+
export default {
|
|
46
|
+
components: { PcPanel, MobilePanel }
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
适合在不同容器中分别渲染 PC 与移动端界面,按需加载更轻量。
|
|
51
|
+
|
|
52
|
+
### 方式二:从根入口具名导入(需要打包器支持 ESM Tree-Shaking)
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import 'sun-card-design/style.css'
|
|
56
|
+
import { PcPanel, MobilePanel } from 'sun-card-design'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
> 根入口导出多个组件,便于二次开发与按需组合;实际打包体积取决于你的打包器摇树优化效果。
|
|
60
|
+
|
|
61
|
+
## 组件概览(部分)
|
|
62
|
+
|
|
63
|
+
- 渲染面板:`PcPanel`、`MobilePanel`
|
|
64
|
+
- 基础组件:`Title`、`Text`、`Button`、`Picture`、`File`、`Video`、`Audio`、`Rate`、`Tag`、`Divider`、`Panorama`、`GenerateImg`
|
|
65
|
+
- 布局组件:`Grid`
|
|
66
|
+
- 表单组件:`Input`、`Select`、`EnterpriseSearch`、`Table`
|
|
67
|
+
- 图表组件:`BarChart`、`BarChart3D`、`PieChart`、`PieChart3D`、`LineChart`
|
|
68
|
+
|
|
69
|
+
> 具体 props/事件请参考源码组件文件,后续会补充详细文档示例。
|
|
70
|
+
|
|
71
|
+
## 使用示例(片段)
|
|
72
|
+
|
|
73
|
+
```vue
|
|
74
|
+
<template>
|
|
75
|
+
<div class="container">
|
|
76
|
+
<div class="pc-wrap">
|
|
77
|
+
<PcPanel :record="record" />
|
|
78
|
+
</div>
|
|
79
|
+
<div class="mb-wrap">
|
|
80
|
+
<MobilePanel :record="record" />
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
</template>
|
|
84
|
+
|
|
85
|
+
<script setup lang="ts">
|
|
86
|
+
import { ref } from 'vue'
|
|
87
|
+
import 'sun-card-design/style.css'
|
|
88
|
+
import PcPanel from 'sun-card-design/pc'
|
|
89
|
+
import MobilePanel from 'sun-card-design/mobile'
|
|
90
|
+
|
|
91
|
+
const record = ref({
|
|
92
|
+
config: {
|
|
93
|
+
background: '#fff',
|
|
94
|
+
borderRadius: 12
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
</script>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## 外部依赖与对等依赖
|
|
101
|
+
|
|
102
|
+
本库将以下依赖标记为 external/peer,不会被打入产物,请在宿主项目中自行安装与提供:
|
|
103
|
+
|
|
104
|
+
- 对等依赖(必装)
|
|
105
|
+
- `vue` ^3.5.0
|
|
106
|
+
- `ant-design-vue` ^4.0.0
|
|
107
|
+
|
|
108
|
+
> 某些组件(如图表/3D/截图)依赖上述库,只有在使用相关组件时才需要安装。
|
|
109
|
+
|
|
110
|
+
## 兼容性
|
|
111
|
+
|
|
112
|
+
- 运行环境:现代浏览器 / Vite、Webpack 等现代打包器
|
|
113
|
+
- 模块格式:ESM(推荐)、UMD(可选,默认没有,减小体积)
|
|
114
|
+
|
|
115
|
+
## 许可证
|
|
116
|
+
|
|
117
|
+
MIT
|
|
118
|
+
|
|
119
|
+
## 作者
|
|
120
|
+
|
|
121
|
+
js-feng@foxmail.com
|
|
@@ -4,7 +4,7 @@ import Text from "./sun-card-design-mobile.es4.js";
|
|
|
4
4
|
import Button from "./sun-card-design-mobile.es5.js";
|
|
5
5
|
import Grid from "./sun-card-design-mobile.es15.js";
|
|
6
6
|
import File from "./sun-card-design-mobile.es7.js";
|
|
7
|
-
import Upload from "./sun-card-design-mobile.
|
|
7
|
+
import Upload from "./sun-card-design-mobile.es57.js";
|
|
8
8
|
import Picture from "./sun-card-design-mobile.es6.js";
|
|
9
9
|
import Tag from "./sun-card-design-mobile.es11.js";
|
|
10
10
|
import Rate from "./sun-card-design-mobile.es10.js";
|
|
@@ -22,11 +22,11 @@ import LineChart from "./sun-card-design-mobile.es24.js";
|
|
|
22
22
|
import BarChart3D from "./sun-card-design-mobile.es21.js";
|
|
23
23
|
import PieChart3D from "./sun-card-design-mobile.es23.js";
|
|
24
24
|
import Panorama from "./sun-card-design-mobile.es13.js";
|
|
25
|
-
import SunIcon from "./sun-card-design-mobile.
|
|
26
|
-
import SingleColumn from "./sun-card-design-mobile.
|
|
27
|
-
import MultipleColumn from "./sun-card-design-mobile.
|
|
28
|
-
import MultipleLine from "./sun-card-design-mobile.
|
|
29
|
-
import GridList from "./sun-card-design-mobile.
|
|
25
|
+
import SunIcon from "./sun-card-design-mobile.es58.js";
|
|
26
|
+
import SingleColumn from "./sun-card-design-mobile.es59.js";
|
|
27
|
+
import MultipleColumn from "./sun-card-design-mobile.es60.js";
|
|
28
|
+
import MultipleLine from "./sun-card-design-mobile.es61.js";
|
|
29
|
+
import GridList from "./sun-card-design-mobile.es62.js";
|
|
30
30
|
/* empty css */
|
|
31
31
|
import _export_sfc from "./sun-card-design-mobile.es28.js";
|
|
32
32
|
const _hoisted_1 = {
|
|
@@ -1,87 +1,226 @@
|
|
|
1
|
-
import { resolveComponent, createElementBlock, openBlock, normalizeStyle, createVNode, withCtx,
|
|
2
|
-
import
|
|
1
|
+
import { ref, computed, resolveComponent, createElementBlock, openBlock, normalizeStyle, createCommentVNode, createVNode, createElementVNode, withModifiers, withCtx, createTextVNode, h, unref, toDisplayString, Fragment, renderList } from "vue";
|
|
2
|
+
import { UploadOutlined } from "@ant-design/icons-vue";
|
|
3
|
+
import { message } from "ant-design-vue";
|
|
3
4
|
/* empty css */
|
|
4
5
|
import _export_sfc from "./sun-card-design-mobile.es28.js";
|
|
6
|
+
const _hoisted_1 = {
|
|
7
|
+
key: 0,
|
|
8
|
+
class: "upload-progress"
|
|
9
|
+
};
|
|
10
|
+
const _hoisted_2 = { class: "progress-text-container" };
|
|
11
|
+
const _hoisted_3 = {
|
|
12
|
+
key: 1,
|
|
13
|
+
class: "file-list"
|
|
14
|
+
};
|
|
15
|
+
const _hoisted_4 = { class: "file-item-name" };
|
|
5
16
|
const _sfc_main = {
|
|
6
|
-
__name: "
|
|
7
|
-
props: ["record"
|
|
8
|
-
|
|
9
|
-
setup(__props, { emit: __emit }) {
|
|
17
|
+
__name: "uploadComp",
|
|
18
|
+
props: ["record"],
|
|
19
|
+
setup(__props) {
|
|
10
20
|
const props = __props;
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
|
|
21
|
+
const fileList = ref([]);
|
|
22
|
+
const uploadControllers = ref(/* @__PURE__ */ new Map());
|
|
23
|
+
const currentUploadingUid = ref(null);
|
|
24
|
+
const isUploading = computed(() => !!currentUploadingUid.value);
|
|
25
|
+
const buttonColor = computed(() => {
|
|
26
|
+
return props.record.options?.style?.buttonColor;
|
|
27
|
+
});
|
|
28
|
+
const buttonSize = computed(() => {
|
|
29
|
+
return props.record.options?.style?.buttonSize;
|
|
30
|
+
});
|
|
31
|
+
const acceptTypes = computed(() => {
|
|
32
|
+
if (!props.record.options?.format || !Array.isArray(props.record.options.format) || props.record.options.format.length === 0) {
|
|
33
|
+
return "";
|
|
34
|
+
}
|
|
35
|
+
const formatMap = {
|
|
36
|
+
pdf: ".pdf",
|
|
37
|
+
word: ".doc,.docx",
|
|
38
|
+
excle: ".xls,.xlsx",
|
|
39
|
+
txt: ".txt",
|
|
40
|
+
ppt: ".ppt,.pptx"
|
|
41
|
+
};
|
|
42
|
+
return props.record.options.format.map((format) => formatMap[format] || `.${format}`).join(",");
|
|
43
|
+
});
|
|
44
|
+
const beforeUpload = (file) => {
|
|
45
|
+
const isValidType = checkFileType(file);
|
|
46
|
+
if (!isValidType) {
|
|
47
|
+
const allowedFormats = props.record.options?.format || [];
|
|
48
|
+
const formatNames = {
|
|
49
|
+
pdf: "PDF",
|
|
50
|
+
word: "Word",
|
|
51
|
+
excle: "Excel",
|
|
52
|
+
txt: "TXT",
|
|
53
|
+
ppt: "PPT"
|
|
54
|
+
};
|
|
55
|
+
const formatText = allowedFormats.map((f) => formatNames[f] || f.toUpperCase()).join("、");
|
|
56
|
+
if (formatText) {
|
|
57
|
+
message.error(`只支持 ${formatText} 格式的文件`);
|
|
58
|
+
} else {
|
|
59
|
+
message.error("请先配置允许的文件格式");
|
|
60
|
+
}
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
return true;
|
|
64
|
+
};
|
|
65
|
+
const checkFileType = (file) => {
|
|
66
|
+
if (!props.record.options?.format || !Array.isArray(props.record.options.format) || props.record.options.format.length === 0) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
const fileName = (file.name || file.fileName || "").toLowerCase();
|
|
70
|
+
if (!fileName) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
const allowedFormats = props.record.options.format;
|
|
74
|
+
const formatExtensions = {
|
|
75
|
+
pdf: [".pdf"],
|
|
76
|
+
word: [".doc", ".docx"],
|
|
77
|
+
excle: [".xls", ".xlsx"],
|
|
78
|
+
txt: [".txt"],
|
|
79
|
+
ppt: [".ppt", ".pptx"]
|
|
80
|
+
};
|
|
81
|
+
const allowedExtensions = allowedFormats.reduce((exts, format) => {
|
|
82
|
+
if (formatExtensions[format]) {
|
|
83
|
+
exts.push(...formatExtensions[format]);
|
|
84
|
+
}
|
|
85
|
+
return exts;
|
|
86
|
+
}, []);
|
|
87
|
+
if (allowedExtensions.length === 0) {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
const isValid = allowedExtensions.some((ext) => fileName.endsWith(ext));
|
|
91
|
+
console.log("文件类型检查:", {
|
|
92
|
+
fileName,
|
|
93
|
+
allowedFormats,
|
|
94
|
+
allowedExtensions,
|
|
95
|
+
isValid
|
|
96
|
+
});
|
|
97
|
+
return isValid;
|
|
14
98
|
};
|
|
15
|
-
const
|
|
16
|
-
|
|
99
|
+
const customRequest = (options) => {
|
|
100
|
+
const { file, onSuccess, onProgress } = options;
|
|
101
|
+
({ uid: file.uid, name: file.name });
|
|
102
|
+
currentUploadingUid.value = file.uid;
|
|
103
|
+
let progress = 0;
|
|
104
|
+
const timer = setInterval(() => {
|
|
105
|
+
progress = Math.min(progress + 8 + Math.random() * 6, 99);
|
|
106
|
+
onProgress({ percent: progress });
|
|
107
|
+
}, 200);
|
|
108
|
+
const doneTimer = setTimeout(() => {
|
|
109
|
+
clearInterval(timer);
|
|
110
|
+
uploadControllers.value.delete(file.uid);
|
|
111
|
+
fileList.value.push({ uid: file.uid, name: file.name });
|
|
112
|
+
message.success("上传成功");
|
|
113
|
+
onSuccess({ url: URL.createObjectURL(file), name: file.name });
|
|
114
|
+
if (currentUploadingUid.value === file.uid) currentUploadingUid.value = null;
|
|
115
|
+
}, 2e3);
|
|
116
|
+
uploadControllers.value.set(file.uid, { timer, doneTimer });
|
|
17
117
|
};
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
118
|
+
const onCancelUpload = () => {
|
|
119
|
+
const uid = currentUploadingUid.value;
|
|
120
|
+
if (!uid) return;
|
|
121
|
+
const ctrl = uploadControllers.value.get(uid);
|
|
122
|
+
if (ctrl) {
|
|
123
|
+
if (ctrl.timer) clearInterval(ctrl.timer);
|
|
124
|
+
if (ctrl.doneTimer) clearTimeout(ctrl.doneTimer);
|
|
125
|
+
uploadControllers.value.delete(uid);
|
|
126
|
+
}
|
|
127
|
+
const item = fileList.value.find((f) => f.uid === uid);
|
|
128
|
+
if (item) {
|
|
129
|
+
item.status = "cancelled";
|
|
130
|
+
item.percent = 0;
|
|
131
|
+
}
|
|
132
|
+
currentUploadingUid.value = null;
|
|
133
|
+
message.info("已取消上传");
|
|
21
134
|
};
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
135
|
+
const removeFile = (uid) => {
|
|
136
|
+
const item = fileList.value.find((f) => f.uid === uid);
|
|
137
|
+
if (item && item.status === "uploading") {
|
|
138
|
+
currentUploadingUid.value = uid;
|
|
139
|
+
onCancelUpload();
|
|
25
140
|
}
|
|
26
|
-
|
|
141
|
+
fileList.value = fileList.value.filter((f) => f.uid !== uid);
|
|
27
142
|
};
|
|
28
|
-
function isGradientColor(color) {
|
|
29
|
-
return /^(linear|radial)-gradient\(.*\)$/.test(color);
|
|
30
|
-
}
|
|
31
143
|
return (_ctx, _cache) => {
|
|
32
|
-
const
|
|
33
|
-
const
|
|
144
|
+
const _component_a_button = resolveComponent("a-button");
|
|
145
|
+
const _component_a_upload = resolveComponent("a-upload");
|
|
34
146
|
return openBlock(), createElementBlock("div", {
|
|
35
|
-
class: "
|
|
36
|
-
style: normalizeStyle({
|
|
147
|
+
class: "upload-comp",
|
|
148
|
+
style: normalizeStyle({ padding: `${props.record.options?.style?.tbPadding || 0}px ${props.record.options?.style?.lrPadding || 0}px` })
|
|
37
149
|
}, [
|
|
38
|
-
|
|
39
|
-
|
|
150
|
+
isUploading.value ? (openBlock(), createElementBlock("div", _hoisted_1, [
|
|
151
|
+
_cache[2] || (_cache[2] = createElementVNode("div", { class: "spinner" }, null, -1)),
|
|
152
|
+
createElementVNode("div", _hoisted_2, [
|
|
153
|
+
_cache[1] || (_cache[1] = createElementVNode("div", { class: "progress-text" }, "文件导入中...", -1)),
|
|
154
|
+
createVNode(_component_a_button, {
|
|
155
|
+
class: "cancel-btn",
|
|
156
|
+
onClick: withModifiers(onCancelUpload, ["stop"]),
|
|
157
|
+
size: "small"
|
|
158
|
+
}, {
|
|
159
|
+
default: withCtx(() => [..._cache[0] || (_cache[0] = [
|
|
160
|
+
createTextVNode("取消", -1)
|
|
161
|
+
])]),
|
|
162
|
+
_: 1
|
|
163
|
+
})
|
|
164
|
+
])
|
|
165
|
+
])) : createCommentVNode("", true),
|
|
166
|
+
createVNode(_component_a_upload, {
|
|
167
|
+
accept: acceptTypes.value,
|
|
168
|
+
multiple: true,
|
|
169
|
+
"before-upload": beforeUpload,
|
|
170
|
+
"custom-request": customRequest,
|
|
171
|
+
"show-upload-list": false,
|
|
172
|
+
disabled: false
|
|
40
173
|
}, {
|
|
41
174
|
default: withCtx(() => [
|
|
42
|
-
(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
return openBlock(), createBlock(FormItem, {
|
|
63
|
-
record: element,
|
|
64
|
-
key: index2,
|
|
65
|
-
recordData: props.recordData,
|
|
66
|
-
columnsIndex: props.columnsIndex,
|
|
67
|
-
onClickEvent: onClick,
|
|
68
|
-
onFileUpdateEvent: onUpdate,
|
|
69
|
-
onClickColumnsEvent: onClickColumns
|
|
70
|
-
}, null, 8, ["record", "recordData", "columnsIndex"]);
|
|
71
|
-
}), 128))
|
|
72
|
-
], 4)
|
|
73
|
-
]),
|
|
74
|
-
_: 2
|
|
75
|
-
}, 1032, ["flex"]);
|
|
76
|
-
}), 128))
|
|
175
|
+
createVNode(_component_a_button, {
|
|
176
|
+
type: "primary",
|
|
177
|
+
style: normalizeStyle({
|
|
178
|
+
backgroundColor: buttonColor.value,
|
|
179
|
+
borderColor: buttonColor.value,
|
|
180
|
+
fontSize: buttonSize.value + "px",
|
|
181
|
+
height: "auto",
|
|
182
|
+
padding: "4px 12px",
|
|
183
|
+
minHeight: "28px"
|
|
184
|
+
}),
|
|
185
|
+
icon: h(unref(UploadOutlined))
|
|
186
|
+
}, {
|
|
187
|
+
icon: withCtx(() => [
|
|
188
|
+
createVNode(unref(UploadOutlined))
|
|
189
|
+
]),
|
|
190
|
+
default: withCtx(() => [
|
|
191
|
+
createTextVNode(" " + toDisplayString(props.record.options?.style?.buttonText), 1)
|
|
192
|
+
]),
|
|
193
|
+
_: 1
|
|
194
|
+
}, 8, ["style", "icon"])
|
|
77
195
|
]),
|
|
78
196
|
_: 1
|
|
79
|
-
}, 8, ["
|
|
197
|
+
}, 8, ["accept"]),
|
|
198
|
+
fileList.value.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_3, [
|
|
199
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(fileList.value, (file) => {
|
|
200
|
+
return openBlock(), createElementBlock("div", {
|
|
201
|
+
class: "file-item",
|
|
202
|
+
key: file.uid
|
|
203
|
+
}, [
|
|
204
|
+
createElementVNode("span", _hoisted_4, toDisplayString(file.name), 1),
|
|
205
|
+
createVNode(_component_a_button, {
|
|
206
|
+
type: "link",
|
|
207
|
+
danger: "",
|
|
208
|
+
size: "small",
|
|
209
|
+
onClick: withModifiers(($event) => removeFile(file.uid), ["stop"])
|
|
210
|
+
}, {
|
|
211
|
+
default: withCtx(() => [..._cache[3] || (_cache[3] = [
|
|
212
|
+
createTextVNode("删除", -1)
|
|
213
|
+
])]),
|
|
214
|
+
_: 1
|
|
215
|
+
}, 8, ["onClick"])
|
|
216
|
+
]);
|
|
217
|
+
}), 128))
|
|
218
|
+
])) : createCommentVNode("", true)
|
|
80
219
|
], 4);
|
|
81
220
|
};
|
|
82
221
|
}
|
|
83
222
|
};
|
|
84
|
-
const
|
|
223
|
+
const Upload = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-4363e2fe"]]);
|
|
85
224
|
export {
|
|
86
|
-
|
|
225
|
+
Upload as default
|
|
87
226
|
};
|
|
@@ -1,98 +1,64 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { markRaw, defineComponent, h, computed, createElementBlock, openBlock, normalizeStyle, createElementVNode, createBlock, resolveDynamicComponent } from "vue";
|
|
2
|
+
import * as Icons from "@ant-design/icons-vue";
|
|
3
|
+
import { customIcon } from "./sun-card-design-mobile.es65.js";
|
|
3
4
|
/* empty css */
|
|
4
5
|
import _export_sfc from "./sun-card-design-mobile.es28.js";
|
|
5
|
-
const _hoisted_1 = ["onClick"];
|
|
6
6
|
const _sfc_main = {
|
|
7
|
-
__name: "
|
|
8
|
-
props: ["record"
|
|
9
|
-
emits: ["clickEvent"
|
|
7
|
+
__name: "sunIconComp",
|
|
8
|
+
props: ["record"],
|
|
9
|
+
emits: ["clickEvent"],
|
|
10
10
|
setup(__props, { emit: __emit }) {
|
|
11
11
|
const props = __props;
|
|
12
12
|
const emit = __emit;
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
const customIconComponents = Object.entries(customIcon || {}).reduce((acc, [key, svg]) => {
|
|
14
|
+
const normalized = svg.replace(/fill="#000000"/gi, 'fill="currentColor"');
|
|
15
|
+
acc[key] = markRaw(
|
|
16
|
+
defineComponent({
|
|
17
|
+
name: `CustomIcon${key}`,
|
|
18
|
+
setup() {
|
|
19
|
+
return () => h("span", { innerHTML: normalized });
|
|
20
|
+
}
|
|
21
|
+
})
|
|
22
|
+
);
|
|
23
|
+
return acc;
|
|
24
|
+
}, {});
|
|
25
|
+
const iconMap = { ...Icons, ...customIconComponents };
|
|
26
|
+
const iconComponent = computed(() => {
|
|
27
|
+
const name = props?.record?.options?.style?.iconName || "CheckCircleOutlined";
|
|
28
|
+
return iconMap[name] || Icons["CheckCircleOutlined"];
|
|
29
|
+
});
|
|
30
|
+
const iconStyle = computed(() => {
|
|
31
|
+
const color = props?.record?.options?.style?.color || "#000000";
|
|
32
|
+
const justifyContent = props?.record?.options?.style?.justifyContent || "flex-start";
|
|
33
|
+
return {
|
|
34
|
+
color,
|
|
35
|
+
display: "flex",
|
|
36
|
+
justifyContent,
|
|
37
|
+
alignItems: "center",
|
|
38
|
+
width: "100%"
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
function onClick() {
|
|
42
|
+
if (props.record.options.clickEvent) {
|
|
43
|
+
emit("clickEvent", props.record);
|
|
16
44
|
}
|
|
17
|
-
return props.columnsIndex;
|
|
18
|
-
};
|
|
19
|
-
const onClick = (record) => {
|
|
20
|
-
emit("clickEvent", record);
|
|
21
|
-
};
|
|
22
|
-
const onUpdate = (record) => {
|
|
23
|
-
emit("fileUpdateEvent", record);
|
|
24
|
-
};
|
|
25
|
-
const onClickColumns = (record) => {
|
|
26
|
-
if (!record.options.clickEvent) return;
|
|
27
|
-
emit("clickColumnsEvent", record);
|
|
28
|
-
};
|
|
29
|
-
const getBackground = () => {
|
|
30
|
-
if (isGradientColor(props.recordData.config.background)) {
|
|
31
|
-
return "none";
|
|
32
|
-
}
|
|
33
|
-
return props.recordData.config.background;
|
|
34
|
-
};
|
|
35
|
-
function isGradientColor(color) {
|
|
36
|
-
return /^(linear|radial)-gradient\(.*\)$/.test(color);
|
|
37
45
|
}
|
|
38
46
|
return (_ctx, _cache) => {
|
|
39
|
-
const _component_a_col = resolveComponent("a-col");
|
|
40
|
-
const _component_a_row = resolveComponent("a-row");
|
|
41
47
|
return openBlock(), createElementBlock("div", {
|
|
42
|
-
class: "main-
|
|
43
|
-
style: normalizeStyle({
|
|
48
|
+
class: "main-icon",
|
|
49
|
+
style: normalizeStyle({ padding: `${props.record.options?.style?.tbPadding || 0}px ${props.record.options?.style?.lrPadding || 0}px` })
|
|
44
50
|
}, [
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
key: index.toString(),
|
|
52
|
-
flex: props.record.columns[index]?.flex,
|
|
53
|
-
span: 24,
|
|
54
|
-
style: normalizeStyle({
|
|
55
|
-
flex: props.record.columns[index]?.flex
|
|
56
|
-
})
|
|
57
|
-
}, {
|
|
58
|
-
default: withCtx(() => [
|
|
59
|
-
createElementVNode("div", {
|
|
60
|
-
class: "box",
|
|
61
|
-
style: normalizeStyle({
|
|
62
|
-
background: props.record.options.style?.background,
|
|
63
|
-
border: props.record.options.style?.borderColor === "none" ? "none" : "1px solid " + (props.record.options.style?.borderColor || "transparent"),
|
|
64
|
-
borderRadius: props.record.options.style?.borderRadius + "px",
|
|
65
|
-
padding: props.record.options.style?.tbPadding + "px " + props.record.options.style?.lrPadding + "px",
|
|
66
|
-
justifyContent: props.record.options.style?.alignItems || "start",
|
|
67
|
-
minHeight: props.record.options.style?.minHeight + "px" || "48px",
|
|
68
|
-
boxShadow: props.record.options.style?.boxShadow || null
|
|
69
|
-
}),
|
|
70
|
-
onClick: ($event) => onClickColumns(item)
|
|
71
|
-
}, [
|
|
72
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(item.list, (element, index2) => {
|
|
73
|
-
return openBlock(), createBlock(FormItem, {
|
|
74
|
-
record: element,
|
|
75
|
-
key: index2,
|
|
76
|
-
recordData: props.recordData,
|
|
77
|
-
columnsIndex: getIndex(item.index),
|
|
78
|
-
onClickEvent: onClick,
|
|
79
|
-
onFileUpdateEvent: onUpdate,
|
|
80
|
-
onClickColumnsEvent: onClickColumns
|
|
81
|
-
}, null, 8, ["record", "recordData", "columnsIndex"]);
|
|
82
|
-
}), 128))
|
|
83
|
-
], 12, _hoisted_1)
|
|
84
|
-
]),
|
|
85
|
-
_: 2
|
|
86
|
-
}, 1032, ["flex", "style"]);
|
|
87
|
-
}), 128))
|
|
88
|
-
]),
|
|
89
|
-
_: 1
|
|
90
|
-
}, 8, ["gutter"])
|
|
51
|
+
createElementVNode("span", {
|
|
52
|
+
style: normalizeStyle(iconStyle.value),
|
|
53
|
+
onClick
|
|
54
|
+
}, [
|
|
55
|
+
(openBlock(), createBlock(resolveDynamicComponent(iconComponent.value), { style: { "height": "18px", "width": "18px" } }))
|
|
56
|
+
], 4)
|
|
91
57
|
], 4);
|
|
92
58
|
};
|
|
93
59
|
}
|
|
94
60
|
};
|
|
95
|
-
const
|
|
61
|
+
const SunIcon = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-4b920fa7"]]);
|
|
96
62
|
export {
|
|
97
|
-
|
|
63
|
+
SunIcon as default
|
|
98
64
|
};
|
|
@@ -1,21 +1,14 @@
|
|
|
1
|
-
import { resolveComponent, createElementBlock, openBlock, normalizeStyle, createVNode, withCtx, Fragment, renderList, createBlock, createElementVNode
|
|
1
|
+
import { resolveComponent, createElementBlock, openBlock, normalizeStyle, createVNode, withCtx, Fragment, renderList, createBlock, createElementVNode } from "vue";
|
|
2
2
|
import FormItem from "./sun-card-design-mobile.es25.js";
|
|
3
3
|
/* empty css */
|
|
4
4
|
import _export_sfc from "./sun-card-design-mobile.es28.js";
|
|
5
|
-
const _hoisted_1 = ["onClick"];
|
|
6
5
|
const _sfc_main = {
|
|
7
|
-
__name: "
|
|
6
|
+
__name: "singleColumn",
|
|
8
7
|
props: ["record", "recordData", "columnsIndex"],
|
|
9
8
|
emits: ["clickEvent", "clickColumnsEvent", "fileUpdateEvent"],
|
|
10
9
|
setup(__props, { emit: __emit }) {
|
|
11
10
|
const props = __props;
|
|
12
11
|
const emit = __emit;
|
|
13
|
-
const getIndex = (index) => {
|
|
14
|
-
if (index !== void 0) {
|
|
15
|
-
return index;
|
|
16
|
-
}
|
|
17
|
-
return props.columnsIndex;
|
|
18
|
-
};
|
|
19
12
|
const onClick = (record) => {
|
|
20
13
|
emit("clickEvent", record);
|
|
21
14
|
};
|
|
@@ -39,7 +32,7 @@ const _sfc_main = {
|
|
|
39
32
|
const _component_a_col = resolveComponent("a-col");
|
|
40
33
|
const _component_a_row = resolveComponent("a-row");
|
|
41
34
|
return openBlock(), createElementBlock("div", {
|
|
42
|
-
class: "main-
|
|
35
|
+
class: "main-singleColumn",
|
|
43
36
|
style: normalizeStyle({ background: getBackground() })
|
|
44
37
|
}, [
|
|
45
38
|
createVNode(_component_a_row, {
|
|
@@ -50,14 +43,11 @@ const _sfc_main = {
|
|
|
50
43
|
return openBlock(), createBlock(_component_a_col, {
|
|
51
44
|
key: index.toString(),
|
|
52
45
|
flex: props.record.columns[index]?.flex,
|
|
53
|
-
span: 24
|
|
54
|
-
style: normalizeStyle({
|
|
55
|
-
flex: _ctx.none
|
|
56
|
-
})
|
|
46
|
+
span: 24
|
|
57
47
|
}, {
|
|
58
48
|
default: withCtx(() => [
|
|
59
49
|
createElementVNode("div", {
|
|
60
|
-
class:
|
|
50
|
+
class: "box",
|
|
61
51
|
style: normalizeStyle({
|
|
62
52
|
background: props.record.options.style?.background,
|
|
63
53
|
border: props.record.options.style?.borderColor === "none" ? "none" : "1px solid " + (props.record.options.style?.borderColor || "transparent"),
|
|
@@ -66,24 +56,23 @@ const _sfc_main = {
|
|
|
66
56
|
justifyContent: props.record.options.style?.alignItems || "start",
|
|
67
57
|
minHeight: props.record.options.style?.minHeight + "px" || "48px",
|
|
68
58
|
boxShadow: props.record.options.style?.boxShadow || null
|
|
69
|
-
})
|
|
70
|
-
onClick: ($event) => onClickColumns(item)
|
|
59
|
+
})
|
|
71
60
|
}, [
|
|
72
61
|
(openBlock(true), createElementBlock(Fragment, null, renderList(item.list, (element, index2) => {
|
|
73
62
|
return openBlock(), createBlock(FormItem, {
|
|
74
63
|
record: element,
|
|
75
64
|
key: index2,
|
|
76
65
|
recordData: props.recordData,
|
|
77
|
-
columnsIndex:
|
|
66
|
+
columnsIndex: props.columnsIndex,
|
|
78
67
|
onClickEvent: onClick,
|
|
79
68
|
onFileUpdateEvent: onUpdate,
|
|
80
69
|
onClickColumnsEvent: onClickColumns
|
|
81
70
|
}, null, 8, ["record", "recordData", "columnsIndex"]);
|
|
82
71
|
}), 128))
|
|
83
|
-
],
|
|
72
|
+
], 4)
|
|
84
73
|
]),
|
|
85
74
|
_: 2
|
|
86
|
-
}, 1032, ["flex"
|
|
75
|
+
}, 1032, ["flex"]);
|
|
87
76
|
}), 128))
|
|
88
77
|
]),
|
|
89
78
|
_: 1
|
|
@@ -92,7 +81,7 @@ const _sfc_main = {
|
|
|
92
81
|
};
|
|
93
82
|
}
|
|
94
83
|
};
|
|
95
|
-
const
|
|
84
|
+
const SingleColumn = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-1fc2bfb4"]]);
|
|
96
85
|
export {
|
|
97
|
-
|
|
86
|
+
SingleColumn as default
|
|
98
87
|
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { resolveComponent, createElementBlock, openBlock, normalizeStyle, createVNode, withCtx, Fragment, renderList, createBlock, createElementVNode
|
|
1
|
+
import { resolveComponent, createElementBlock, openBlock, normalizeStyle, createVNode, withCtx, Fragment, renderList, createBlock, createElementVNode } from "vue";
|
|
2
2
|
import FormItem from "./sun-card-design-mobile.es25.js";
|
|
3
3
|
/* empty css */
|
|
4
4
|
import _export_sfc from "./sun-card-design-mobile.es28.js";
|
|
5
5
|
const _hoisted_1 = ["onClick"];
|
|
6
6
|
const _sfc_main = {
|
|
7
|
-
__name: "
|
|
7
|
+
__name: "multipleColumn",
|
|
8
8
|
props: ["record", "recordData", "columnsIndex"],
|
|
9
9
|
emits: ["clickEvent", "clickColumnsEvent", "fileUpdateEvent"],
|
|
10
10
|
setup(__props, { emit: __emit }) {
|
|
@@ -50,14 +50,14 @@ const _sfc_main = {
|
|
|
50
50
|
return openBlock(), createBlock(_component_a_col, {
|
|
51
51
|
key: index.toString(),
|
|
52
52
|
flex: props.record.columns[index]?.flex,
|
|
53
|
-
span: 24
|
|
53
|
+
span: 24,
|
|
54
54
|
style: normalizeStyle({
|
|
55
|
-
flex:
|
|
55
|
+
flex: props.record.columns[index]?.flex
|
|
56
56
|
})
|
|
57
57
|
}, {
|
|
58
58
|
default: withCtx(() => [
|
|
59
59
|
createElementVNode("div", {
|
|
60
|
-
class:
|
|
60
|
+
class: "box",
|
|
61
61
|
style: normalizeStyle({
|
|
62
62
|
background: props.record.options.style?.background,
|
|
63
63
|
border: props.record.options.style?.borderColor === "none" ? "none" : "1px solid " + (props.record.options.style?.borderColor || "transparent"),
|
|
@@ -80,10 +80,10 @@ const _sfc_main = {
|
|
|
80
80
|
onClickColumnsEvent: onClickColumns
|
|
81
81
|
}, null, 8, ["record", "recordData", "columnsIndex"]);
|
|
82
82
|
}), 128))
|
|
83
|
-
],
|
|
83
|
+
], 12, _hoisted_1)
|
|
84
84
|
]),
|
|
85
85
|
_: 2
|
|
86
|
-
}, 1032, ["flex", "
|
|
86
|
+
}, 1032, ["flex", "style"]);
|
|
87
87
|
}), 128))
|
|
88
88
|
]),
|
|
89
89
|
_: 1
|
|
@@ -92,7 +92,7 @@ const _sfc_main = {
|
|
|
92
92
|
};
|
|
93
93
|
}
|
|
94
94
|
};
|
|
95
|
-
const
|
|
95
|
+
const MultipleColumn = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-20b79e7a"]]);
|
|
96
96
|
export {
|
|
97
|
-
|
|
97
|
+
MultipleColumn as default
|
|
98
98
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sun-card-design",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.41",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Vue3 卡片设计组件库,支持 PC 和移动端预览",
|
|
6
6
|
"keywords": [
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"pc",
|
|
12
12
|
"mobile"
|
|
13
13
|
],
|
|
14
|
-
"author": "your-name <
|
|
14
|
+
"author": "your-name <js-feng@foxmail.com>",
|
|
15
15
|
"license": "MIT",
|
|
16
16
|
"repository": {
|
|
17
17
|
"type": "git",
|