@aquiferre/ui-kit 0.1.3 → 0.1.4

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.
@@ -3,10 +3,15 @@
3
3
  <table class="table">
4
4
  <thead class="table-header">
5
5
  <tr>
6
+ <th v-if="selectable" class="table-header-cell w-8">
7
+ <input type="checkbox" :checked="allSelected" @change="toggleAll" />
8
+ </th>
6
9
  <th
7
10
  v-for="col in columns"
8
11
  :key="col.key"
9
12
  class="table-header-cell"
13
+ :class="col.width"
14
+ :style="col.align ? `text-align:${col.align}` : undefined"
10
15
  >
11
16
  {{ col.title }}
12
17
  </th>
@@ -14,12 +19,25 @@
14
19
  </thead>
15
20
  <tbody class="table-body">
16
21
  <tr v-if="!loading && data.length === 0">
17
- <td :colspan="columns.length" class="table-empty">
22
+ <td :colspan="colspan" class="table-empty">
18
23
  {{ emptyText }}
19
24
  </td>
20
25
  </tr>
21
- <tr v-for="(row, index) in data" :key="row.id || index" class="table-row">
22
- <td v-for="col in columns" :key="col.key" class="table-cell">
26
+ <tr
27
+ v-for="(row, index) in data"
28
+ :key="row[rowKey] ?? index"
29
+ class="table-row cursor-pointer"
30
+ @click="handleRowClick(row)"
31
+ >
32
+ <td v-if="selectable" class="table-cell" @click.stop>
33
+ <input type="checkbox" :checked="isSelected(row)" @change="toggleRow(row)" />
34
+ </td>
35
+ <td
36
+ v-for="col in columns"
37
+ :key="col.key"
38
+ class="table-cell"
39
+ :class="col.align === 'center' ? 'text-center' : col.align === 'right' ? 'text-right' : undefined"
40
+ >
23
41
  <slot :name="col.key" :row="row" :value="row[col.key]">
24
42
  {{ row[col.key] }}
25
43
  </slot>
@@ -38,15 +56,64 @@
38
56
  </template>
39
57
 
40
58
  <script setup lang="ts">
41
- interface Column {
42
- key: string
43
- title: string
44
- }
59
+ import { computed } from 'vue'
60
+ import type { Column } from '../types'
45
61
 
46
- defineProps<{
62
+ const props = withDefaults(defineProps<{
47
63
  columns: Column[]
48
64
  data: any[]
49
65
  loading?: boolean
50
66
  emptyText?: string
67
+ selectable?: boolean
68
+ selected?: string[]
69
+ rowKey?: string
70
+ }>(), {
71
+ loading: false,
72
+ emptyText: '暂无数据',
73
+ selectable: false,
74
+ selected: () => [],
75
+ rowKey: 'id',
76
+ })
77
+
78
+ const emit = defineEmits<{
79
+ 'update:selected': [ids: string[]]
80
+ 'row-click': [row: any]
51
81
  }>()
82
+
83
+ const colspan = computed(() => props.columns.length + (props.selectable ? 1 : 0))
84
+
85
+ const selectedSet = computed(() => new Set(props.selected))
86
+
87
+ function isSelected(row: any) {
88
+ return selectedSet.value.has(row[props.rowKey])
89
+ }
90
+
91
+ const allSelected = computed(() =>
92
+ props.data.length > 0 && props.data.every(row => selectedSet.value.has(row[props.rowKey]))
93
+ )
94
+
95
+ function toggleAll(e: Event) {
96
+ const checked = (e.target as HTMLInputElement).checked
97
+ if (checked) {
98
+ emit('update:selected', props.data.map(row => row[props.rowKey]))
99
+ } else {
100
+ emit('update:selected', [])
101
+ }
102
+ }
103
+
104
+ function toggleRow(row: any) {
105
+ const id = row[props.rowKey]
106
+ const current = [...props.selected]
107
+ const idx = current.indexOf(id)
108
+ if (idx >= 0) {
109
+ current.splice(idx, 1)
110
+ } else {
111
+ current.push(id)
112
+ }
113
+ emit('update:selected', current)
114
+ }
115
+
116
+ function handleRowClick(row: any) {
117
+ emit('row-click', row)
118
+ }
52
119
  </script>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aquiferre/ui-kit",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "index.ts",
package/types.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  export interface Column {
2
2
  key: string
3
3
  title: string
4
+ width?: string
5
+ align?: 'left' | 'center' | 'right'
4
6
  }
5
7
 
6
8
  export interface MenuItem {