resolver-egretimp-plus 0.1.29 → 0.1.31
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/h5/index.js +18 -18
- package/dist/web/index.js +128 -128
- package/dist/web/index.js.LICENSE.txt +15 -0
- package/package.json +5 -1
- package/scripts/webpack.config.js +18 -2
- package/src/components/loading/loading.scss +1 -1
- package/src/components/packages-web/CustomComponentTable.jsx +8 -5
- package/src/components/table/index.ts +29 -0
- package/src/components/table/src/composables/use-scrollbar.ts +30 -0
- package/src/components/table/src/config.ts +256 -0
- package/src/components/table/src/filter-panel.vue +260 -0
- package/src/components/table/src/h-helper.ts +34 -0
- package/src/components/table/src/layout-observer.ts +78 -0
- package/src/components/table/src/store/current.ts +85 -0
- package/src/components/table/src/store/expand.ts +76 -0
- package/src/components/table/src/store/helper.ts +74 -0
- package/src/components/table/src/store/index.ts +246 -0
- package/src/components/table/src/store/tree.ts +230 -0
- package/src/components/table/src/store/watcher.ts +543 -0
- package/src/components/table/src/table/defaults.ts +402 -0
- package/src/components/table/src/table/key-render-helper.ts +27 -0
- package/src/components/table/src/table/style-helper.ts +378 -0
- package/src/components/table/src/table/utils-helper.ts +47 -0
- package/src/components/table/src/table-body/defaults.ts +52 -0
- package/src/components/table/src/table-body/events-helper.ts +203 -0
- package/src/components/table/src/table-body/index.ts +119 -0
- package/src/components/table/src/table-body/render-helper.ts +283 -0
- package/src/components/table/src/table-body/styles-helper.ts +164 -0
- package/src/components/table/src/table-column/defaults.ts +237 -0
- package/src/components/table/src/table-column/index.ts +202 -0
- package/src/components/table/src/table-column/render-helper.ts +214 -0
- package/src/components/table/src/table-column/watcher-helper.ts +88 -0
- package/src/components/table/src/table-footer/index.ts +128 -0
- package/src/components/table/src/table-footer/mapState-helper.ts +33 -0
- package/src/components/table/src/table-footer/style-helper.ts +51 -0
- package/src/components/table/src/table-header/event-helper.ts +213 -0
- package/src/components/table/src/table-header/index.ts +244 -0
- package/src/components/table/src/table-header/style.helper.ts +119 -0
- package/src/components/table/src/table-header/utils-helper.ts +94 -0
- package/src/components/table/src/table-layout.ts +259 -0
- package/src/components/table/src/table.vue +389 -0
- package/src/components/table/src/tableColumn.ts +3 -0
- package/src/components/table/src/tokens.ts +5 -0
- package/src/components/table/src/util.ts +521 -0
- package/src/components/table/style/css.ts +5 -0
- package/src/components/table/style/index.ts +5 -0
- package/src/rules/parseCondition.js +3 -0
- package/src/rules/rulesDriver.js +2 -2
- package/tsconfig.json +19 -0
- package/vue-shims.d.ts +4 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import {
|
|
3
|
+
defineComponent,
|
|
4
|
+
getCurrentInstance,
|
|
5
|
+
h,
|
|
6
|
+
inject,
|
|
7
|
+
nextTick,
|
|
8
|
+
onMounted,
|
|
9
|
+
ref,
|
|
10
|
+
} from 'vue'
|
|
11
|
+
import ElCheckbox from 'element-plus/es/components/checkbox/index.mjs'
|
|
12
|
+
import { useNamespace } from 'element-plus/es/hooks/index.mjs'
|
|
13
|
+
import FilterPanel from '../filter-panel.vue'
|
|
14
|
+
import useLayoutObserver from '../layout-observer'
|
|
15
|
+
import { TABLE_INJECTION_KEY } from '../tokens'
|
|
16
|
+
import useEvent from './event-helper'
|
|
17
|
+
import useStyle from './style.helper'
|
|
18
|
+
import useUtils from './utils-helper'
|
|
19
|
+
import type { ComponentInternalInstance, PropType, Ref } from 'vue'
|
|
20
|
+
import type { DefaultRow, Sort } from '../table/defaults'
|
|
21
|
+
import type { Store } from '../store'
|
|
22
|
+
export interface TableHeader extends ComponentInternalInstance {
|
|
23
|
+
state: {
|
|
24
|
+
onColumnsChange
|
|
25
|
+
onScrollableChange
|
|
26
|
+
}
|
|
27
|
+
filterPanels: Ref<unknown>
|
|
28
|
+
}
|
|
29
|
+
export interface TableHeaderProps<T> {
|
|
30
|
+
fixed: string
|
|
31
|
+
store: Store<T>
|
|
32
|
+
border: boolean
|
|
33
|
+
defaultSort: Sort
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default defineComponent({
|
|
37
|
+
name: 'ElTableHeader',
|
|
38
|
+
components: {
|
|
39
|
+
ElCheckbox,
|
|
40
|
+
},
|
|
41
|
+
props: {
|
|
42
|
+
fixed: {
|
|
43
|
+
type: String,
|
|
44
|
+
default: '',
|
|
45
|
+
},
|
|
46
|
+
store: {
|
|
47
|
+
required: true,
|
|
48
|
+
type: Object as PropType<TableHeaderProps<DefaultRow>['store']>,
|
|
49
|
+
},
|
|
50
|
+
border: Boolean,
|
|
51
|
+
defaultSort: {
|
|
52
|
+
type: Object as PropType<TableHeaderProps<DefaultRow>['defaultSort']>,
|
|
53
|
+
default: () => {
|
|
54
|
+
return {
|
|
55
|
+
prop: '',
|
|
56
|
+
order: '',
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
setup(props, { emit }) {
|
|
62
|
+
const instance = getCurrentInstance() as TableHeader
|
|
63
|
+
const parent = inject(TABLE_INJECTION_KEY)
|
|
64
|
+
const ns = useNamespace('table')
|
|
65
|
+
const filterPanels = ref({})
|
|
66
|
+
const { onColumnsChange, onScrollableChange } = useLayoutObserver(parent!)
|
|
67
|
+
onMounted(async () => {
|
|
68
|
+
// Need double await, because updateColumns is executed after nextTick for now
|
|
69
|
+
await nextTick()
|
|
70
|
+
await nextTick()
|
|
71
|
+
const { prop, order } = props.defaultSort
|
|
72
|
+
parent?.store.commit('sort', { prop, order, init: true })
|
|
73
|
+
})
|
|
74
|
+
const {
|
|
75
|
+
handleHeaderClick,
|
|
76
|
+
handleHeaderContextMenu,
|
|
77
|
+
handleMouseDown,
|
|
78
|
+
handleMouseMove,
|
|
79
|
+
handleMouseOut,
|
|
80
|
+
handleSortClick,
|
|
81
|
+
handleFilterClick,
|
|
82
|
+
} = useEvent(props as TableHeaderProps<unknown>, emit)
|
|
83
|
+
const {
|
|
84
|
+
getHeaderRowStyle,
|
|
85
|
+
getHeaderRowClass,
|
|
86
|
+
getHeaderCellStyle,
|
|
87
|
+
getHeaderCellClass,
|
|
88
|
+
} = useStyle(props as TableHeaderProps<unknown>)
|
|
89
|
+
const { isGroup, toggleAllSelection, columnRows } = useUtils(
|
|
90
|
+
props as TableHeaderProps<unknown>
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
instance.state = {
|
|
94
|
+
onColumnsChange,
|
|
95
|
+
onScrollableChange,
|
|
96
|
+
}
|
|
97
|
+
instance.filterPanels = filterPanels
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
ns,
|
|
101
|
+
filterPanels,
|
|
102
|
+
onColumnsChange,
|
|
103
|
+
onScrollableChange,
|
|
104
|
+
columnRows,
|
|
105
|
+
getHeaderRowClass,
|
|
106
|
+
getHeaderRowStyle,
|
|
107
|
+
getHeaderCellClass,
|
|
108
|
+
getHeaderCellStyle,
|
|
109
|
+
handleHeaderClick,
|
|
110
|
+
handleHeaderContextMenu,
|
|
111
|
+
handleMouseDown,
|
|
112
|
+
handleMouseMove,
|
|
113
|
+
handleMouseOut,
|
|
114
|
+
handleSortClick,
|
|
115
|
+
handleFilterClick,
|
|
116
|
+
isGroup,
|
|
117
|
+
toggleAllSelection,
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
render() {
|
|
121
|
+
const {
|
|
122
|
+
ns,
|
|
123
|
+
isGroup,
|
|
124
|
+
columnRows,
|
|
125
|
+
getHeaderCellStyle,
|
|
126
|
+
getHeaderCellClass,
|
|
127
|
+
getHeaderRowClass,
|
|
128
|
+
getHeaderRowStyle,
|
|
129
|
+
handleHeaderClick,
|
|
130
|
+
handleHeaderContextMenu,
|
|
131
|
+
handleMouseDown,
|
|
132
|
+
handleMouseMove,
|
|
133
|
+
handleSortClick,
|
|
134
|
+
handleMouseOut,
|
|
135
|
+
store,
|
|
136
|
+
$parent,
|
|
137
|
+
} = this
|
|
138
|
+
let rowSpan = 1
|
|
139
|
+
return h(
|
|
140
|
+
'thead',
|
|
141
|
+
{
|
|
142
|
+
class: { [ns.is('group')]: isGroup },
|
|
143
|
+
},
|
|
144
|
+
columnRows.map((subColumns, rowIndex) =>
|
|
145
|
+
h(
|
|
146
|
+
'tr',
|
|
147
|
+
{
|
|
148
|
+
class: getHeaderRowClass(rowIndex),
|
|
149
|
+
key: rowIndex,
|
|
150
|
+
style: getHeaderRowStyle(rowIndex),
|
|
151
|
+
},
|
|
152
|
+
subColumns.map((column, cellIndex) => {
|
|
153
|
+
if (column.rowSpan > rowSpan) {
|
|
154
|
+
rowSpan = column.rowSpan
|
|
155
|
+
}
|
|
156
|
+
return h(
|
|
157
|
+
'th',
|
|
158
|
+
{
|
|
159
|
+
class: getHeaderCellClass(
|
|
160
|
+
rowIndex,
|
|
161
|
+
cellIndex,
|
|
162
|
+
subColumns,
|
|
163
|
+
column
|
|
164
|
+
),
|
|
165
|
+
colspan: column.colSpan,
|
|
166
|
+
key: `${column.id}-thead`,
|
|
167
|
+
rowspan: column.rowSpan,
|
|
168
|
+
style: getHeaderCellStyle(
|
|
169
|
+
rowIndex,
|
|
170
|
+
cellIndex,
|
|
171
|
+
subColumns,
|
|
172
|
+
column
|
|
173
|
+
),
|
|
174
|
+
onClick: ($event) => {
|
|
175
|
+
if ($event.currentTarget.classList.contains('noclick')) {
|
|
176
|
+
return
|
|
177
|
+
}
|
|
178
|
+
handleHeaderClick($event, column)
|
|
179
|
+
},
|
|
180
|
+
onContextmenu: ($event) =>
|
|
181
|
+
handleHeaderContextMenu($event, column),
|
|
182
|
+
onMousedown: ($event) => handleMouseDown($event, column),
|
|
183
|
+
onMousemove: ($event) => handleMouseMove($event, column),
|
|
184
|
+
onMouseout: handleMouseOut,
|
|
185
|
+
},
|
|
186
|
+
[
|
|
187
|
+
h(
|
|
188
|
+
'div',
|
|
189
|
+
{
|
|
190
|
+
class: [
|
|
191
|
+
'cell',
|
|
192
|
+
column.filteredValue && column.filteredValue.length > 0
|
|
193
|
+
? 'highlight'
|
|
194
|
+
: '',
|
|
195
|
+
],
|
|
196
|
+
},
|
|
197
|
+
[
|
|
198
|
+
column.renderHeader
|
|
199
|
+
? column.renderHeader({
|
|
200
|
+
column,
|
|
201
|
+
$index: cellIndex,
|
|
202
|
+
store,
|
|
203
|
+
_self: $parent,
|
|
204
|
+
})
|
|
205
|
+
: column.label,
|
|
206
|
+
column.sortable &&
|
|
207
|
+
h(
|
|
208
|
+
'span',
|
|
209
|
+
{
|
|
210
|
+
onClick: ($event) => handleSortClick($event, column),
|
|
211
|
+
class: 'caret-wrapper',
|
|
212
|
+
},
|
|
213
|
+
[
|
|
214
|
+
h('i', {
|
|
215
|
+
onClick: ($event) =>
|
|
216
|
+
handleSortClick($event, column, 'ascending'),
|
|
217
|
+
class: 'sort-caret ascending',
|
|
218
|
+
}),
|
|
219
|
+
h('i', {
|
|
220
|
+
onClick: ($event) =>
|
|
221
|
+
handleSortClick($event, column, 'descending'),
|
|
222
|
+
class: 'sort-caret descending',
|
|
223
|
+
}),
|
|
224
|
+
]
|
|
225
|
+
),
|
|
226
|
+
column.filterable &&
|
|
227
|
+
h(FilterPanel, {
|
|
228
|
+
store,
|
|
229
|
+
placement: column.filterPlacement || 'bottom-start',
|
|
230
|
+
column,
|
|
231
|
+
upDataColumn: (key, value) => {
|
|
232
|
+
column[key] = value
|
|
233
|
+
},
|
|
234
|
+
}),
|
|
235
|
+
]
|
|
236
|
+
),
|
|
237
|
+
]
|
|
238
|
+
)
|
|
239
|
+
})
|
|
240
|
+
)
|
|
241
|
+
)
|
|
242
|
+
)
|
|
243
|
+
},
|
|
244
|
+
})
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { inject } from 'vue'
|
|
2
|
+
import { useNamespace } from 'element-plus/es/hooks/index.mjs'
|
|
3
|
+
import {
|
|
4
|
+
ensurePosition,
|
|
5
|
+
getFixedColumnOffset,
|
|
6
|
+
getFixedColumnsClass,
|
|
7
|
+
} from '../util'
|
|
8
|
+
import { TABLE_INJECTION_KEY } from '../tokens'
|
|
9
|
+
import type { TableColumnCtx } from '../table-column/defaults'
|
|
10
|
+
import type { TableHeaderProps } from '.'
|
|
11
|
+
|
|
12
|
+
function useStyle<T>(props: TableHeaderProps<T>) {
|
|
13
|
+
const parent = inject(TABLE_INJECTION_KEY)
|
|
14
|
+
const ns = useNamespace('table')
|
|
15
|
+
|
|
16
|
+
const getHeaderRowStyle = (rowIndex: number) => {
|
|
17
|
+
const headerRowStyle = parent?.props.headerRowStyle
|
|
18
|
+
if (typeof headerRowStyle === 'function') {
|
|
19
|
+
return headerRowStyle.call(null, { rowIndex })
|
|
20
|
+
}
|
|
21
|
+
return headerRowStyle
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const getHeaderRowClass = (rowIndex: number): string => {
|
|
25
|
+
const classes: string[] = []
|
|
26
|
+
const headerRowClassName = parent?.props.headerRowClassName
|
|
27
|
+
if (typeof headerRowClassName === 'string') {
|
|
28
|
+
classes.push(headerRowClassName)
|
|
29
|
+
} else if (typeof headerRowClassName === 'function') {
|
|
30
|
+
classes.push(headerRowClassName.call(null, { rowIndex }))
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return classes.join(' ')
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const getHeaderCellStyle = (
|
|
37
|
+
rowIndex: number,
|
|
38
|
+
columnIndex: number,
|
|
39
|
+
row: T,
|
|
40
|
+
column: TableColumnCtx<T>
|
|
41
|
+
) => {
|
|
42
|
+
let headerCellStyles = parent?.props.headerCellStyle ?? {}
|
|
43
|
+
if (typeof headerCellStyles === 'function') {
|
|
44
|
+
headerCellStyles = headerCellStyles.call(null, {
|
|
45
|
+
rowIndex,
|
|
46
|
+
columnIndex,
|
|
47
|
+
row,
|
|
48
|
+
column,
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
const fixedStyle = getFixedColumnOffset<T>(
|
|
52
|
+
columnIndex,
|
|
53
|
+
column.fixed,
|
|
54
|
+
props.store,
|
|
55
|
+
row as unknown as TableColumnCtx<T>[]
|
|
56
|
+
)
|
|
57
|
+
ensurePosition(fixedStyle, 'left')
|
|
58
|
+
ensurePosition(fixedStyle, 'right')
|
|
59
|
+
return Object.assign({}, headerCellStyles, fixedStyle)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const getHeaderCellClass = (
|
|
63
|
+
rowIndex: number,
|
|
64
|
+
columnIndex: number,
|
|
65
|
+
row: T,
|
|
66
|
+
column: TableColumnCtx<T>
|
|
67
|
+
) => {
|
|
68
|
+
const fixedClasses = getFixedColumnsClass<T>(
|
|
69
|
+
ns.b(),
|
|
70
|
+
columnIndex,
|
|
71
|
+
column.fixed,
|
|
72
|
+
props.store,
|
|
73
|
+
row as unknown as TableColumnCtx<T>[]
|
|
74
|
+
)
|
|
75
|
+
const classes = [
|
|
76
|
+
column.id,
|
|
77
|
+
column.order,
|
|
78
|
+
column.headerAlign,
|
|
79
|
+
column.className,
|
|
80
|
+
column.labelClassName,
|
|
81
|
+
...fixedClasses,
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
if (!column.children) {
|
|
85
|
+
classes.push('is-leaf')
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (column.sortable) {
|
|
89
|
+
classes.push('is-sortable')
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const headerCellClassName = parent?.props.headerCellClassName
|
|
93
|
+
if (typeof headerCellClassName === 'string') {
|
|
94
|
+
classes.push(headerCellClassName)
|
|
95
|
+
} else if (typeof headerCellClassName === 'function') {
|
|
96
|
+
classes.push(
|
|
97
|
+
headerCellClassName.call(null, {
|
|
98
|
+
rowIndex,
|
|
99
|
+
columnIndex,
|
|
100
|
+
row,
|
|
101
|
+
column,
|
|
102
|
+
})
|
|
103
|
+
)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
classes.push(ns.e('cell'))
|
|
107
|
+
|
|
108
|
+
return classes.filter((className) => Boolean(className)).join(' ')
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
getHeaderRowStyle,
|
|
113
|
+
getHeaderRowClass,
|
|
114
|
+
getHeaderCellStyle,
|
|
115
|
+
getHeaderCellClass,
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export default useStyle
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { computed, inject } from 'vue'
|
|
3
|
+
import { TABLE_INJECTION_KEY } from '../tokens'
|
|
4
|
+
import type { TableColumnCtx } from '../table-column/defaults'
|
|
5
|
+
import type { TableHeaderProps } from '.'
|
|
6
|
+
|
|
7
|
+
const getAllColumns = <T>(
|
|
8
|
+
columns: TableColumnCtx<T>[]
|
|
9
|
+
): TableColumnCtx<T>[] => {
|
|
10
|
+
const result: TableColumnCtx<T>[] = []
|
|
11
|
+
columns.forEach((column) => {
|
|
12
|
+
if (column.children) {
|
|
13
|
+
result.push(column)
|
|
14
|
+
// eslint-disable-next-line prefer-spread
|
|
15
|
+
result.push.apply(result, getAllColumns(column.children))
|
|
16
|
+
} else {
|
|
17
|
+
result.push(column)
|
|
18
|
+
}
|
|
19
|
+
})
|
|
20
|
+
return result
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const convertToRows = <T>(
|
|
24
|
+
originColumns: TableColumnCtx<T>[]
|
|
25
|
+
): TableColumnCtx<T>[] => {
|
|
26
|
+
let maxLevel = 1
|
|
27
|
+
const traverse = (column: TableColumnCtx<T>, parent: TableColumnCtx<T>) => {
|
|
28
|
+
if (parent) {
|
|
29
|
+
column.level = parent.level + 1
|
|
30
|
+
if (maxLevel < column.level) {
|
|
31
|
+
maxLevel = column.level
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (column.children) {
|
|
35
|
+
let colSpan = 0
|
|
36
|
+
column.children.forEach((subColumn) => {
|
|
37
|
+
traverse(subColumn, column)
|
|
38
|
+
colSpan += subColumn.colSpan
|
|
39
|
+
})
|
|
40
|
+
column.colSpan = colSpan
|
|
41
|
+
} else {
|
|
42
|
+
column.colSpan = 1
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
originColumns.forEach((column) => {
|
|
47
|
+
column.level = 1
|
|
48
|
+
traverse(column, undefined)
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
const rows = []
|
|
52
|
+
for (let i = 0; i < maxLevel; i++) {
|
|
53
|
+
rows.push([])
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const allColumns: TableColumnCtx<T>[] = getAllColumns(originColumns)
|
|
57
|
+
|
|
58
|
+
allColumns.forEach((column) => {
|
|
59
|
+
if (!column.children) {
|
|
60
|
+
column.rowSpan = maxLevel - column.level + 1
|
|
61
|
+
} else {
|
|
62
|
+
column.rowSpan = 1
|
|
63
|
+
column.children.forEach((col) => (col.isSubColumn = true))
|
|
64
|
+
}
|
|
65
|
+
rows[column.level - 1].push(column)
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
return rows
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function useUtils<T>(props: TableHeaderProps<T>) {
|
|
72
|
+
const parent = inject(TABLE_INJECTION_KEY)
|
|
73
|
+
const columnRows = computed(() => {
|
|
74
|
+
return convertToRows(props.store.states.originColumns.value)
|
|
75
|
+
})
|
|
76
|
+
const isGroup = computed(() => {
|
|
77
|
+
const result = columnRows.value.length > 1
|
|
78
|
+
if (result && parent) {
|
|
79
|
+
parent.state.isGroup.value = true
|
|
80
|
+
}
|
|
81
|
+
return result
|
|
82
|
+
})
|
|
83
|
+
const toggleAllSelection = (event: Event) => {
|
|
84
|
+
event.stopPropagation()
|
|
85
|
+
parent?.store.commit('toggleAllSelection')
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
isGroup,
|
|
89
|
+
toggleAllSelection,
|
|
90
|
+
columnRows,
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export default useUtils
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { isRef, nextTick, ref } from 'vue'
|
|
3
|
+
import { hasOwn, isClient } from 'element-plus/es/utils/index.mjs'
|
|
4
|
+
import { parseHeight } from './util'
|
|
5
|
+
import type { Ref } from 'vue'
|
|
6
|
+
|
|
7
|
+
import type { TableColumnCtx } from './table-column/defaults'
|
|
8
|
+
import type { TableHeader } from './table-header'
|
|
9
|
+
import type { Table } from './table/defaults'
|
|
10
|
+
import type { Store } from './store'
|
|
11
|
+
class TableLayout<T> {
|
|
12
|
+
observers: TableHeader[]
|
|
13
|
+
table: Table<T>
|
|
14
|
+
store: Store<T>
|
|
15
|
+
columns: TableColumnCtx<T>[]
|
|
16
|
+
fit: boolean
|
|
17
|
+
showHeader: boolean
|
|
18
|
+
|
|
19
|
+
height: Ref<null | number>
|
|
20
|
+
scrollX: Ref<boolean>
|
|
21
|
+
scrollY: Ref<boolean>
|
|
22
|
+
bodyWidth: Ref<null | number>
|
|
23
|
+
fixedWidth: Ref<null | number>
|
|
24
|
+
rightFixedWidth: Ref<null | number>
|
|
25
|
+
tableHeight: Ref<null | number>
|
|
26
|
+
headerHeight: Ref<null | number> // Table Header Height
|
|
27
|
+
appendHeight: Ref<null | number> // Append Slot Height
|
|
28
|
+
footerHeight: Ref<null | number> // Table Footer Height
|
|
29
|
+
gutterWidth: number
|
|
30
|
+
constructor(options: Record<string, any>) {
|
|
31
|
+
this.observers = []
|
|
32
|
+
this.table = null
|
|
33
|
+
this.store = null
|
|
34
|
+
this.columns = []
|
|
35
|
+
this.fit = true
|
|
36
|
+
this.showHeader = true
|
|
37
|
+
this.height = ref(null)
|
|
38
|
+
this.scrollX = ref(false)
|
|
39
|
+
this.scrollY = ref(false)
|
|
40
|
+
this.bodyWidth = ref(null)
|
|
41
|
+
this.fixedWidth = ref(null)
|
|
42
|
+
this.rightFixedWidth = ref(null)
|
|
43
|
+
this.gutterWidth = 0
|
|
44
|
+
for (const name in options) {
|
|
45
|
+
if (hasOwn(options, name)) {
|
|
46
|
+
if (isRef(this[name])) {
|
|
47
|
+
this[name as string].value = options[name]
|
|
48
|
+
} else {
|
|
49
|
+
this[name as string] = options[name]
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (!this.table) {
|
|
54
|
+
throw new Error('Table is required for Table Layout')
|
|
55
|
+
}
|
|
56
|
+
if (!this.store) {
|
|
57
|
+
throw new Error('Store is required for Table Layout')
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
updateScrollY() {
|
|
62
|
+
const height = this.height.value
|
|
63
|
+
/**
|
|
64
|
+
* When the height is not initialized, it is null.
|
|
65
|
+
* After the table is initialized, when the height is not configured, the height is 0.
|
|
66
|
+
*/
|
|
67
|
+
if (height === null) return false
|
|
68
|
+
const scrollBarRef = this.table.refs.scrollBarRef
|
|
69
|
+
if (this.table.vnode.el && scrollBarRef?.wrapRef) {
|
|
70
|
+
let scrollY = true
|
|
71
|
+
const prevScrollY = this.scrollY.value
|
|
72
|
+
scrollY =
|
|
73
|
+
scrollBarRef.wrapRef.scrollHeight > scrollBarRef.wrapRef.clientHeight
|
|
74
|
+
this.scrollY.value = scrollY
|
|
75
|
+
return prevScrollY !== scrollY
|
|
76
|
+
}
|
|
77
|
+
return false
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
setHeight(value: string | number, prop = 'height') {
|
|
81
|
+
if (!isClient) return
|
|
82
|
+
const el = this.table.vnode.el
|
|
83
|
+
value = parseHeight(value)
|
|
84
|
+
this.height.value = Number(value)
|
|
85
|
+
|
|
86
|
+
if (!el && (value || value === 0))
|
|
87
|
+
return nextTick(() => this.setHeight(value, prop))
|
|
88
|
+
|
|
89
|
+
if (typeof value === 'number') {
|
|
90
|
+
el.style[prop] = `${value}px`
|
|
91
|
+
this.updateElsHeight()
|
|
92
|
+
} else if (typeof value === 'string') {
|
|
93
|
+
el.style[prop] = value
|
|
94
|
+
this.updateElsHeight()
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
setMaxHeight(value: string | number) {
|
|
99
|
+
this.setHeight(value, 'max-height')
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
getFlattenColumns(): TableColumnCtx<T>[] {
|
|
103
|
+
const flattenColumns = []
|
|
104
|
+
const columns = this.table.store.states.columns.value
|
|
105
|
+
columns.forEach((column) => {
|
|
106
|
+
if (column.isColumnGroup) {
|
|
107
|
+
// eslint-disable-next-line prefer-spread
|
|
108
|
+
flattenColumns.push.apply(flattenColumns, column.columns)
|
|
109
|
+
} else {
|
|
110
|
+
flattenColumns.push(column)
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
return flattenColumns
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
updateElsHeight() {
|
|
118
|
+
this.updateScrollY()
|
|
119
|
+
this.notifyObservers('scrollable')
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
headerDisplayNone(elm: HTMLElement) {
|
|
123
|
+
if (!elm) return true
|
|
124
|
+
let headerChild = elm
|
|
125
|
+
while (headerChild.tagName !== 'DIV') {
|
|
126
|
+
if (getComputedStyle(headerChild).display === 'none') {
|
|
127
|
+
return true
|
|
128
|
+
}
|
|
129
|
+
headerChild = headerChild.parentElement
|
|
130
|
+
}
|
|
131
|
+
return false
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
updateColumnsWidth() {
|
|
135
|
+
if (!isClient) return
|
|
136
|
+
const fit = this.fit
|
|
137
|
+
const bodyWidth = this.table.vnode.el.clientWidth
|
|
138
|
+
let bodyMinWidth = 0
|
|
139
|
+
|
|
140
|
+
const flattenColumns = this.getFlattenColumns()
|
|
141
|
+
const flexColumns = flattenColumns.filter(
|
|
142
|
+
(column) => typeof column.width !== 'number'
|
|
143
|
+
)
|
|
144
|
+
flattenColumns.forEach((column) => {
|
|
145
|
+
// Clean those columns whose width changed from flex to unflex
|
|
146
|
+
if (typeof column.width === 'number' && column.realWidth)
|
|
147
|
+
column.realWidth = null
|
|
148
|
+
})
|
|
149
|
+
if (flexColumns.length > 0 && fit) {
|
|
150
|
+
flattenColumns.forEach((column) => {
|
|
151
|
+
bodyMinWidth += Number(column.width || column.minWidth || 80)
|
|
152
|
+
})
|
|
153
|
+
if (bodyMinWidth <= bodyWidth) {
|
|
154
|
+
// DON'T HAVE SCROLL BAR
|
|
155
|
+
this.scrollX.value = false
|
|
156
|
+
|
|
157
|
+
const totalFlexWidth = bodyWidth - bodyMinWidth
|
|
158
|
+
|
|
159
|
+
if (flexColumns.length === 1) {
|
|
160
|
+
flexColumns[0].realWidth =
|
|
161
|
+
Number(flexColumns[0].minWidth || 80) + totalFlexWidth
|
|
162
|
+
} else {
|
|
163
|
+
const allColumnsWidth = flexColumns.reduce(
|
|
164
|
+
(prev, column) => prev + Number(column.minWidth || 80),
|
|
165
|
+
0
|
|
166
|
+
)
|
|
167
|
+
const flexWidthPerPixel = totalFlexWidth / allColumnsWidth
|
|
168
|
+
let noneFirstWidth = 0
|
|
169
|
+
|
|
170
|
+
flexColumns.forEach((column, index) => {
|
|
171
|
+
if (index === 0) return
|
|
172
|
+
const flexWidth = Math.floor(
|
|
173
|
+
Number(column.minWidth || 80) * flexWidthPerPixel
|
|
174
|
+
)
|
|
175
|
+
noneFirstWidth += flexWidth
|
|
176
|
+
column.realWidth = Number(column.minWidth || 80) + flexWidth
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
flexColumns[0].realWidth =
|
|
180
|
+
Number(flexColumns[0].minWidth || 80) +
|
|
181
|
+
totalFlexWidth -
|
|
182
|
+
noneFirstWidth
|
|
183
|
+
}
|
|
184
|
+
} else {
|
|
185
|
+
// HAVE HORIZONTAL SCROLL BAR
|
|
186
|
+
this.scrollX.value = true
|
|
187
|
+
flexColumns.forEach((column) => {
|
|
188
|
+
column.realWidth = Number(column.minWidth)
|
|
189
|
+
})
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
this.bodyWidth.value = Math.max(bodyMinWidth, bodyWidth)
|
|
193
|
+
this.table.state.resizeState.value.width = this.bodyWidth.value
|
|
194
|
+
} else {
|
|
195
|
+
flattenColumns.forEach((column) => {
|
|
196
|
+
if (!column.width && !column.minWidth) {
|
|
197
|
+
column.realWidth = 80
|
|
198
|
+
} else {
|
|
199
|
+
column.realWidth = Number(column.width || column.minWidth)
|
|
200
|
+
}
|
|
201
|
+
bodyMinWidth += column.realWidth
|
|
202
|
+
})
|
|
203
|
+
this.scrollX.value = bodyMinWidth > bodyWidth
|
|
204
|
+
|
|
205
|
+
this.bodyWidth.value = bodyMinWidth
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const fixedColumns = this.store.states.fixedColumns.value
|
|
209
|
+
|
|
210
|
+
if (fixedColumns.length > 0) {
|
|
211
|
+
let fixedWidth = 0
|
|
212
|
+
fixedColumns.forEach((column) => {
|
|
213
|
+
fixedWidth += Number(column.realWidth || column.width)
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
this.fixedWidth.value = fixedWidth
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const rightFixedColumns = this.store.states.rightFixedColumns.value
|
|
220
|
+
if (rightFixedColumns.length > 0) {
|
|
221
|
+
let rightFixedWidth = 0
|
|
222
|
+
rightFixedColumns.forEach((column) => {
|
|
223
|
+
rightFixedWidth += Number(column.realWidth || column.width)
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
this.rightFixedWidth.value = rightFixedWidth
|
|
227
|
+
}
|
|
228
|
+
this.notifyObservers('columns')
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
addObserver(observer: TableHeader) {
|
|
232
|
+
this.observers.push(observer)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
removeObserver(observer: TableHeader) {
|
|
236
|
+
const index = this.observers.indexOf(observer)
|
|
237
|
+
if (index !== -1) {
|
|
238
|
+
this.observers.splice(index, 1)
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
notifyObservers(event: string) {
|
|
243
|
+
const observers = this.observers
|
|
244
|
+
observers.forEach((observer) => {
|
|
245
|
+
switch (event) {
|
|
246
|
+
case 'columns':
|
|
247
|
+
observer.state?.onColumnsChange(this)
|
|
248
|
+
break
|
|
249
|
+
case 'scrollable':
|
|
250
|
+
observer.state?.onScrollableChange(this)
|
|
251
|
+
break
|
|
252
|
+
default:
|
|
253
|
+
throw new Error(`Table Layout don't have event ${event}.`)
|
|
254
|
+
}
|
|
255
|
+
})
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export default TableLayout
|