@a2simcode/ui 0.0.60 → 0.0.62

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.
@@ -212,11 +212,6 @@ export default {
212
212
  {
213
213
  "name": "TableColumnConfig",
214
214
  "properties": [
215
- {
216
- "name": "label",
217
- "type": "string",
218
- "description": "列的标题"
219
- },
220
215
  {
221
216
  "name": "width",
222
217
  "type": "number",
@@ -319,7 +314,7 @@ export default {
319
314
  },
320
315
  {
321
316
  "name": "config",
322
- "type": "TableColumnConfig & BaseCompConfig",
317
+ "type": "TableColumnCompConfig & {\n /**\n * @zh 列的标题\n */\n label: string\n }",
323
318
  "description": "列配置"
324
319
  },
325
320
  {
@@ -29,6 +29,48 @@
29
29
  </template>
30
30
  </Demo>
31
31
 
32
+ ## Icon 图标
33
+
34
+ 通过列类型 `j-icon` 可以渲染 SVG 图标。支持传入 SVG 字符串或 Iconify 图标名称。
35
+
36
+ <Demo :source-code="tableIconCode">
37
+ <template #source>
38
+ <table-icon />
39
+ </template>
40
+ <template #description>
41
+ 在 `columns` 中设置 `type: 'j-icon'`。数据可以是 SVG 字符串,也可以是 Iconify 图标名称(如 `mdi:home`)。
42
+ 可以通过 `config.size` 设置图标大小,`config.color` 设置图标颜色。
43
+ </template>
44
+ </Demo>
45
+
46
+ ## Link 链接
47
+
48
+ 通过列类型 `link` 可以渲染链接,并支持点击事件。
49
+
50
+ <Demo :source-code="tableLinkCode">
51
+ <template #source>
52
+ <table-link />
53
+ </template>
54
+ <template #description>
55
+ 在 `columns` 中设置 `type: 'link'`。
56
+ 通过 `config.click` 设置点击回调函数,参数为 `{ row, column, e, openLayer }`。
57
+ </template>
58
+ </Demo>
59
+
60
+ ## 自定义布局
61
+
62
+ 通过列配置中的 `customLayout` 属性,可以使用 VTable 的 CustomLayout 功能自定义单元格渲染。
63
+
64
+ <Demo :source-code="tableCustomLayoutCode">
65
+ <template #source>
66
+ <table-custom-layout />
67
+ </template>
68
+ <template #description>
69
+ 在列对象中定义 `customLayout` 函数。该函数接收 `args` 参数,其中包含 `customLayout` 类(VTable.CustomLayout),可用于创建 Group, Text, Image 等布局元素。
70
+ 函数需要返回 `{ rootContainer, renderDefault: false }`。
71
+ </template>
72
+ </Demo>
73
+
32
74
  ## 冻结列
33
75
 
34
76
  通过 `columns` 中的 `config.frozen` 属性设置列的冻结方式,支持 `left`(左侧冻结)和 `right`(右侧冻结)。
@@ -189,6 +231,9 @@
189
231
  <script setup>
190
232
  import TableBasic from '../examples/table/basic.vue'
191
233
  import TableTag from '../examples/table/tag.vue'
234
+ import TableIcon from '../examples/table/icon.vue'
235
+ import TableLink from '../examples/table/link.vue'
236
+ import TableCustomLayout from '../examples/table/custom-layout.vue'
192
237
  import TableFrozenColumn from '../examples/table/frozen-column.vue'
193
238
  import TableHeightMode from '../examples/table/height-mode.vue'
194
239
  import TableTreeColumn from '../examples/table/tree-column.vue'
@@ -204,6 +249,9 @@ import tableApi from './meta/table'
204
249
 
205
250
  import tableBasicCode from '../examples/table/basic.vue?raw'
206
251
  import tableTagCode from '../examples/table/tag.vue?raw'
252
+ import tableIconCode from '../examples/table/icon.vue?raw'
253
+ import tableLinkCode from '../examples/table/link.vue?raw'
254
+ import tableCustomLayoutCode from '../examples/table/custom-layout.vue?raw'
207
255
  import tableFrozenColumnCode from '../examples/table/frozen-column.vue?raw'
208
256
  import tableHeightModeCode from '../examples/table/height-mode.vue?raw'
209
257
  import tableTreeColumnCode from '../examples/table/tree-column.vue?raw'
@@ -0,0 +1,115 @@
1
+ <template>
2
+ <div style="position: relative; width: 100%; height: 400px">
3
+ <j-table :columns="columns" :records="records" />
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ import { ref } from 'vue'
9
+
10
+ const columns = ref([
11
+ {
12
+ id: 'id',
13
+ config: {
14
+ label: 'ID',
15
+ width: 80,
16
+ },
17
+ },
18
+ {
19
+ id: 'info',
20
+ config: {
21
+ label: 'User Info (Custom Layout)',
22
+ width: 250,
23
+ },
24
+ customLayout: (args: any) => {
25
+ const { table, row, col, rect, customLayout } = args
26
+ const { Group, Text, Image } = customLayout
27
+ const record = table.getCellOriginRecord(col, row)
28
+ const { name, avatar, role } = record
29
+
30
+ const container = new Group({
31
+ height: rect.height,
32
+ width: rect.width,
33
+ display: 'flex',
34
+ flexDirection: 'row',
35
+ alignItems: 'center',
36
+ padding: [0, 10],
37
+ })
38
+
39
+ // Avatar
40
+ const image = new Image({
41
+ width: 32,
42
+ height: 32,
43
+ image: avatar,
44
+ cornerRadius: 16,
45
+ marginRight: 10,
46
+ })
47
+ container.add(image)
48
+
49
+ // Text Container
50
+ const textContainer = new Group({
51
+ height: 32,
52
+ width: rect.width - 60,
53
+ display: 'flex',
54
+ flexDirection: 'column',
55
+ justifyContent: 'center',
56
+ })
57
+
58
+ const nameText = new Text({
59
+ text: name,
60
+ fontSize: 14,
61
+ fontFamily: 'sans-serif',
62
+ fill: '#333',
63
+ })
64
+ textContainer.add(nameText)
65
+
66
+ const roleText = new Text({
67
+ text: role,
68
+ fontSize: 12,
69
+ fontFamily: 'sans-serif',
70
+ fill: '#999',
71
+ marginTop: 4,
72
+ })
73
+ textContainer.add(roleText)
74
+
75
+ container.add(textContainer)
76
+
77
+ return {
78
+ rootContainer: container,
79
+ renderDefault: false,
80
+ }
81
+ },
82
+ },
83
+ {
84
+ id: 'status',
85
+ config: {
86
+ label: 'Status',
87
+ width: 100,
88
+ },
89
+ },
90
+ ])
91
+
92
+ const records = ref([
93
+ {
94
+ id: 1,
95
+ name: 'John Doe',
96
+ role: 'Software Engineer',
97
+ avatar: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgdmlld0JveD0iMCAwIDMyIDMyIj48cmVjdCB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIGZpbGw9IiMxNjVkZmYiLz48dGV4dCB4PSIxNiIgeT0iMjEiIGZvbnQtc2l6ZT0iMTYiIGZpbGw9IndoaXRlIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LWZhbWlseT0ic2Fucy1zZXJpZiI+SjwvdGV4dD48L3N2Zz4=',
98
+ status: 'Active',
99
+ },
100
+ {
101
+ id: 2,
102
+ name: 'Jane Smith',
103
+ role: 'Product Manager',
104
+ avatar: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgdmlld0JveD0iMCAwIDMyIDMyIj48cmVjdCB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIGZpbGw9IiMwMGI0MmEiLz48dGV4dCB4PSIxNiIgeT0iMjEiIGZvbnQtc2l6ZT0iMTYiIGZpbGw9IndoaXRlIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LWZhbWlseT0ic2Fucy1zZXJpZiI+SjwvdGV4dD48L3N2Zz4=',
105
+ status: 'Inactive',
106
+ },
107
+ {
108
+ id: 3,
109
+ name: 'Bob Johnson',
110
+ role: 'Designer',
111
+ avatar: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgdmlld0JveD0iMCAwIDMyIDMyIj48cmVjdCB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIGZpbGw9IiNmYmI0MDAiLz48dGV4dCB4PSIxNiIgeT0iMjEiIGZvbnQtc2l6ZT0iMTYiIGZpbGw9IndoaXRlIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LWZhbWlseT0ic2Fucy1zZXJpZiI+QjwvdGV4dD48L3N2Zz4=',
112
+ status: 'Active',
113
+ },
114
+ ])
115
+ </script>
@@ -0,0 +1,85 @@
1
+ <template>
2
+ <div style="position: relative; width: 100%; height: 300px">
3
+ <j-table v-if="iconsReady" :columns="columns" :records="records" />
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ import { getIcon, iconLoaded, loadIcon } from '@iconify/vue'
9
+ import { onBeforeMount, ref } from 'vue'
10
+
11
+ const iconsReady = ref(false)
12
+
13
+ const browsers = [
14
+ { name: 'Chrome', icon: 'logos:chrome' },
15
+ { name: 'Firefox', icon: 'logos:firefox' },
16
+ { name: 'Safari', icon: 'logos:safari' },
17
+ { name: 'Edge', icon: 'logos:microsoft-edge' },
18
+ ]
19
+
20
+ const toSvg = (iconName: string) => {
21
+ const iconData = getIcon(iconName)
22
+ if (!iconData) return ''
23
+ return `<svg viewBox="0 0 ${iconData.width} ${iconData.height}">${iconData.body}</svg>`
24
+ }
25
+
26
+ const records = ref<Record<string, any>[]>([])
27
+
28
+ onBeforeMount(async () => {
29
+ // @ts-ignore
30
+ if (import.meta.env.SSR) {
31
+ iconsReady.value = true
32
+ return
33
+ }
34
+
35
+ const icons = browsers.map((item) => item.icon)
36
+
37
+ await Promise.all(
38
+ icons.map(async (icon) => {
39
+ if (!iconLoaded(icon)) {
40
+ await loadIcon(icon)
41
+ }
42
+ })
43
+ )
44
+
45
+ records.value = browsers.map((item) => {
46
+ return {
47
+ ...item,
48
+ svg: toSvg(item.icon),
49
+ }
50
+ })
51
+
52
+ iconsReady.value = true
53
+ })
54
+
55
+ const columns = ref([
56
+ {
57
+ id: 'name',
58
+ config: {
59
+ label: '浏览器',
60
+ width: 150,
61
+ align: 'left',
62
+ },
63
+ },
64
+ {
65
+ id: 'icon',
66
+ type: 'j-icon',
67
+ config: {
68
+ label: '图标(Iconify)',
69
+ width: 120,
70
+ align: 'center',
71
+ size: 24,
72
+ },
73
+ },
74
+ {
75
+ id: 'svg',
76
+ type: 'j-icon',
77
+ config: {
78
+ label: '图标(SVG)',
79
+ width: 120,
80
+ align: 'center',
81
+ size: 24,
82
+ },
83
+ },
84
+ ])
85
+ </script>
@@ -0,0 +1,66 @@
1
+ <template>
2
+ <div style="position: relative; width: 100%; height: 400px">
3
+ <j-table :columns="columns" :records="records" />
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ import { ref } from 'vue'
9
+ import { ElMessage } from 'element-plus'
10
+
11
+ const columns = ref([
12
+ {
13
+ id: 'name',
14
+ type: 'link',
15
+ config: {
16
+ label: '项目名称',
17
+ width: 'auto',
18
+ align: 'left',
19
+ click: ({ row }: { row: any }) => {
20
+ ElMessage.success(`点击了项目: ${row.name}`)
21
+ },
22
+ },
23
+ },
24
+ {
25
+ id: 'status',
26
+ config: {
27
+ label: '状态',
28
+ width: 'auto',
29
+ align: 'center',
30
+ },
31
+ },
32
+ {
33
+ id: 'owner',
34
+ type: 'link',
35
+ config: {
36
+ label: '负责人',
37
+ width: 'auto',
38
+ align: 'center',
39
+ click: ({ row }: { row: any }) => {
40
+ ElMessage.info(`查看负责人: ${row.owner}`)
41
+ },
42
+ },
43
+ },
44
+ ])
45
+
46
+ const records = ref([
47
+ {
48
+ id: '1',
49
+ name: '项目A',
50
+ status: '进行中',
51
+ owner: '张三',
52
+ },
53
+ {
54
+ id: '2',
55
+ name: '项目B',
56
+ status: '已完成',
57
+ owner: '李四',
58
+ },
59
+ {
60
+ id: '3',
61
+ name: '项目C',
62
+ status: '待审核',
63
+ owner: '王五',
64
+ },
65
+ ])
66
+ </script>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a2simcode/ui",
3
- "version": "0.0.60",
3
+ "version": "0.0.62",
4
4
  "description": "A Vue 3 UI Component Library",
5
5
  "type": "module",
6
6
  "main": "./dist/simcode-ui.umd.js",