vgapp 1.4.9 → 1.5.1
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/app/modules/vgfilepreview/scss/_variables.scss +4 -4
- package/app/modules/vgfiles/js/base.js +9 -7
- package/app/modules/vgfiles/js/vgfiles.js +6 -3
- package/app/modules/vgfiles/scss/_mixins.scss +12 -2
- package/app/modules/vgfiles/scss/vgfiles.scss +1 -1
- package/app/modules/vgtable/js/_sticky-header.js +191 -58
- package/app/modules/vgtable/scss/_sticky-header.scss +28 -21
- package/app/modules/vgtable/scss/vgtable.scss +6 -0
- package/build/vgapp.css +1 -1
- package/build/vgapp.css.map +1 -1
- package/build/vgapp.js +1 -1
- package/build/vgapp.js.map +1 -1
- package/package.json +1 -1
|
@@ -22,11 +22,11 @@ $filepreview-map: (
|
|
|
22
22
|
toggle-size: 24px,
|
|
23
23
|
icon-size: 18px,
|
|
24
24
|
toggle-radius: 999px,
|
|
25
|
-
toggle-bg:
|
|
26
|
-
toggle-color:
|
|
25
|
+
toggle-bg: rgba(0, 0, 0, .12),
|
|
26
|
+
toggle-color: #000000,
|
|
27
27
|
name-line-height: 1.2,
|
|
28
|
-
progress-track:
|
|
29
|
-
progress-fill:
|
|
28
|
+
progress-track: rgba(0, 0, 0, .16),
|
|
29
|
+
progress-fill: rgba(0, 0, 0, .16),
|
|
30
30
|
progress-radius: 6px,
|
|
31
31
|
progress-padding-x: 4px,
|
|
32
32
|
),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Описание: базовая логика выбора, валидации и отображения файлов VGFiles.
|
|
3
|
-
* Возможности: управляет набором файлов, ошибками, списками, статистикой и скрытыми полями формы.
|
|
2
|
+
* Описание: базовая логика выбора, валидации и отображения файлов VGFiles.
|
|
3
|
+
* Возможности: управляет набором файлов, ошибками, списками, кастомными действиями, статистикой и скрытыми полями формы.
|
|
4
4
|
*/
|
|
5
5
|
import BaseModule from "../../base-module";
|
|
6
6
|
import {mergeDeepObject} from "../../../utils/js/functions";
|
|
@@ -422,7 +422,7 @@ class VGFilesBase extends BaseModule {
|
|
|
422
422
|
};
|
|
423
423
|
}
|
|
424
424
|
|
|
425
|
-
_renderUIDropList(files) {
|
|
425
|
+
_renderUIDropList(files) {
|
|
426
426
|
if (!this._nodes.drop) return;
|
|
427
427
|
|
|
428
428
|
let $list = Selectors.find(`.${this._getClass('drop-list')}`, this._nodes.drop);
|
|
@@ -435,9 +435,10 @@ class VGFilesBase extends BaseModule {
|
|
|
435
435
|
const fragment = document.createDocumentFragment();
|
|
436
436
|
|
|
437
437
|
files.forEach((file) => {
|
|
438
|
-
let classes =
|
|
438
|
+
let classes = [...$itemsTemplateClasses];
|
|
439
439
|
|
|
440
|
-
if (this._params.detach) classes.push('with-remove')
|
|
440
|
+
if (this._params.detach) classes.push('with-remove')
|
|
441
|
+
if (this._params.customButtons?.hideOnUploadState) classes.push('hide-custom-buttons-on-upload-state')
|
|
441
442
|
if (this._params.sortable.enabled) classes.push('with-sortable')
|
|
442
443
|
if (this._params.limits.count === 1) {
|
|
443
444
|
classes.push('single');
|
|
@@ -606,12 +607,13 @@ class VGFilesBase extends BaseModule {
|
|
|
606
607
|
return '';
|
|
607
608
|
}
|
|
608
609
|
|
|
609
|
-
_createInfoListItem(file, i, itemsTemplate, itemTemplateClasses, fileKey, signature) {
|
|
610
|
+
_createInfoListItem(file, i, itemsTemplate, itemTemplateClasses, fileKey, signature) {
|
|
610
611
|
let classes = [...itemTemplateClasses];
|
|
611
612
|
|
|
612
613
|
if (this._params.image) classes.push('with-image');
|
|
613
614
|
if (this._params.info) classes.push('with-info');
|
|
614
|
-
if (this._params.detach) classes.push('with-remove')
|
|
615
|
+
if (this._params.detach) classes.push('with-remove')
|
|
616
|
+
if (this._params.customButtons?.hideOnUploadState) classes.push('hide-custom-buttons-on-upload-state')
|
|
615
617
|
if (this._params.sortable.enabled) classes.push('with-sortable');
|
|
616
618
|
const previewPath = this._resolveFilePreviewPath(file);
|
|
617
619
|
const displayName = this._resolveDisplayName(file);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Описание: основной класс выбора, отображения и AJAX-загрузки файлов VGFiles.
|
|
3
|
-
* Возможности: управляет списками и dropzone, прогрессом, удалением, повторной загрузкой и сортировкой.
|
|
3
|
+
* Возможности: управляет списками и dropzone, прогрессом, кастомными действиями, удалением, повторной загрузкой и сортировкой.
|
|
4
4
|
*/
|
|
5
5
|
import VGFilesBase from "./base";
|
|
6
6
|
import FileUploader from "./loader";
|
|
@@ -47,8 +47,11 @@ class VGFiles extends VGFilesBase {
|
|
|
47
47
|
prepend: true,
|
|
48
48
|
replace: true,
|
|
49
49
|
rename: false,
|
|
50
|
-
smartdrop: false,
|
|
51
|
-
|
|
50
|
+
smartdrop: false,
|
|
51
|
+
customButtons: {
|
|
52
|
+
hideOnUploadState: true
|
|
53
|
+
},
|
|
54
|
+
uploads: {
|
|
52
55
|
mode: 'sequential',
|
|
53
56
|
route: '',
|
|
54
57
|
maxParallel: 3,
|
|
@@ -23,8 +23,18 @@
|
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
@mixin vgfiles-state() {
|
|
27
|
-
&.
|
|
26
|
+
@mixin vgfiles-state() {
|
|
27
|
+
&.hide-custom-buttons-on-upload-state {
|
|
28
|
+
&.pending,
|
|
29
|
+
&.loading,
|
|
30
|
+
&.failing {
|
|
31
|
+
.file-actions {
|
|
32
|
+
display: none;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
&.pending {
|
|
28
38
|
> * {
|
|
29
39
|
opacity: .32;
|
|
30
40
|
pointer-events: none;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Описание: разметка Fixed Header с отдельными слоями заголовка и тела VGTable.
|
|
3
|
-
* Возможности: перенос настоящего thead без клона, синхронизация колонок и горизонтальной прокрутки.
|
|
4
|
-
*/
|
|
1
|
+
/**
|
|
2
|
+
* Описание: разметка Fixed Header с отдельными слоями заголовка и тела VGTable.
|
|
3
|
+
* Возможности: перенос настоящего thead без клона, автоматическая синхронизация ширин колонок и горизонтальной прокрутки.
|
|
4
|
+
*/
|
|
5
5
|
|
|
6
6
|
const MODE_CLASSES = ['vg-table-wrapper--sticky-container', 'vg-table-wrapper--sticky-page'];
|
|
7
7
|
const CONTAINER_MODE_CLASSES = ['vg-table-container--sticky-container', 'vg-table-container--sticky-page'];
|
|
@@ -18,18 +18,24 @@ class _stickyHeader {
|
|
|
18
18
|
this._header = null;
|
|
19
19
|
this._headerTable = null;
|
|
20
20
|
this._body = null;
|
|
21
|
-
this._previousClasses = new Map();
|
|
22
|
-
this._previousContainerClasses = new Map();
|
|
23
|
-
this._previousStyles = new Map();
|
|
24
|
-
this.
|
|
25
|
-
this.
|
|
26
|
-
this.
|
|
21
|
+
this._previousClasses = new Map();
|
|
22
|
+
this._previousContainerClasses = new Map();
|
|
23
|
+
this._previousStyles = new Map();
|
|
24
|
+
this._columnWeights = new Map();
|
|
25
|
+
this._hardColumnWidths = new Map();
|
|
26
|
+
this._hasSourceColgroup = false;
|
|
27
|
+
this._resizeObserver = null;
|
|
28
|
+
this._resizeFrame = null;
|
|
29
|
+
this._boundScroll = this._syncScroll.bind(this);
|
|
30
|
+
this._boundResize = this._scheduleRefresh.bind(this);
|
|
31
|
+
this._boundPageScroll = this._syncStickyState.bind(this);
|
|
27
32
|
}
|
|
28
33
|
|
|
29
34
|
init() {
|
|
30
|
-
if (!this._wrapper || !this._container || !this._head) return this;
|
|
31
|
-
|
|
32
|
-
const widths = this._measureColumns();
|
|
35
|
+
if (!this._wrapper || !this._container || !this._head) return this;
|
|
36
|
+
|
|
37
|
+
const widths = this._measureColumns();
|
|
38
|
+
this._rememberColumnGeometry(widths);
|
|
33
39
|
MODE_CLASSES.forEach((className) => this._previousClasses.set(className, this._wrapper.classList.contains(className)));
|
|
34
40
|
CONTAINER_MODE_CLASSES.forEach((className) => this._previousContainerClasses.set(className, this._container.classList.contains(className)));
|
|
35
41
|
STYLE_PROPERTIES.forEach((property) => this._previousStyles.set(property, this._container.style.getPropertyValue(property)));
|
|
@@ -42,13 +48,17 @@ class _stickyHeader {
|
|
|
42
48
|
this._container.style.setProperty('--vg-table-sticky-max-height', this._toCssLength(this._params.maxHeight, '24rem'));
|
|
43
49
|
this._element.setAttribute('data-vg-table-sticky-header', this._params.mode);
|
|
44
50
|
|
|
45
|
-
this._buildLayers(widths);
|
|
46
|
-
this._body.addEventListener('scroll', this._boundScroll, {passive: true});
|
|
47
|
-
if (typeof
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
this._buildLayers(widths);
|
|
52
|
+
this._body.addEventListener('scroll', this._boundScroll, {passive: true});
|
|
53
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
54
|
+
this._resizeObserver = new ResizeObserver(this._boundResize);
|
|
55
|
+
this._resizeObserver.observe(this._container);
|
|
56
|
+
this._resizeObserver.observe(this._body);
|
|
57
|
+
} else if (typeof window !== 'undefined') {
|
|
58
|
+
window.addEventListener('resize', this._boundResize);
|
|
59
|
+
}
|
|
60
|
+
if (this._params.mode === 'page' && typeof window !== 'undefined') window.addEventListener('scroll', this._boundPageScroll, {passive: true});
|
|
61
|
+
this.refresh();
|
|
52
62
|
return this;
|
|
53
63
|
}
|
|
54
64
|
|
|
@@ -68,9 +78,9 @@ class _stickyHeader {
|
|
|
68
78
|
refresh() {
|
|
69
79
|
if (!this._header || !this._headerTable || !this._body) return this;
|
|
70
80
|
|
|
71
|
-
const widths = this.
|
|
72
|
-
this._applyColgroup(this._headerTable, widths);
|
|
73
|
-
this._applyColgroup(this._element, widths);
|
|
81
|
+
const widths = this._resolveLayoutWidths();
|
|
82
|
+
this._applyColgroup(this._headerTable, widths);
|
|
83
|
+
this._applyColgroup(this._element, widths);
|
|
74
84
|
const scrollbar = Math.max(0, this._body.offsetWidth - this._body.clientWidth);
|
|
75
85
|
this._header.style.paddingInlineEnd = `${scrollbar}px`;
|
|
76
86
|
this._header.style.setProperty('--vg-table-sticky-scrollbar-width', `${scrollbar}px`);
|
|
@@ -81,12 +91,17 @@ class _stickyHeader {
|
|
|
81
91
|
return this;
|
|
82
92
|
}
|
|
83
93
|
|
|
84
|
-
dispose() {
|
|
85
|
-
if (this._body) this._body.removeEventListener('scroll', this._boundScroll);
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
94
|
+
dispose() {
|
|
95
|
+
if (this._body) this._body.removeEventListener('scroll', this._boundScroll);
|
|
96
|
+
this._resizeObserver?.disconnect();
|
|
97
|
+
if (this._resizeFrame !== null && typeof cancelAnimationFrame === 'function') {
|
|
98
|
+
cancelAnimationFrame(this._resizeFrame);
|
|
99
|
+
this._resizeFrame = null;
|
|
100
|
+
}
|
|
101
|
+
if (typeof window !== 'undefined') {
|
|
102
|
+
if (!this._resizeObserver) window.removeEventListener('resize', this._boundResize);
|
|
103
|
+
window.removeEventListener('scroll', this._boundPageScroll);
|
|
104
|
+
}
|
|
90
105
|
this._header?.classList.remove('is-stuck');
|
|
91
106
|
if (this._head && this._headerTable?.contains(this._head)) this._element.prepend(this._head);
|
|
92
107
|
this._header?.remove();
|
|
@@ -101,13 +116,25 @@ class _stickyHeader {
|
|
|
101
116
|
CONTAINER_MODE_CLASSES.forEach((className) => {
|
|
102
117
|
this._container.classList.toggle(className, this._previousContainerClasses.get(className) === true);
|
|
103
118
|
});
|
|
104
|
-
STYLE_PROPERTIES.forEach((property) => {
|
|
119
|
+
STYLE_PROPERTIES.forEach((property) => {
|
|
105
120
|
const previous = this._previousStyles.get(property);
|
|
106
121
|
if (previous) this._container.style.setProperty(property, previous);
|
|
107
122
|
else this._container.style.removeProperty(property);
|
|
108
|
-
});
|
|
109
|
-
this._element.removeAttribute('data-vg-table-sticky-header');
|
|
110
|
-
}
|
|
123
|
+
});
|
|
124
|
+
this._element.removeAttribute('data-vg-table-sticky-header');
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
_scheduleRefresh() {
|
|
128
|
+
if (this._resizeFrame !== null) return;
|
|
129
|
+
if (typeof requestAnimationFrame !== 'function') {
|
|
130
|
+
this.refresh();
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
this._resizeFrame = requestAnimationFrame(() => {
|
|
134
|
+
this._resizeFrame = null;
|
|
135
|
+
this.refresh();
|
|
136
|
+
});
|
|
137
|
+
}
|
|
111
138
|
|
|
112
139
|
_buildLayers(widths) {
|
|
113
140
|
this._header = this._element.ownerDocument.createElement('div');
|
|
@@ -131,18 +158,24 @@ class _stickyHeader {
|
|
|
131
158
|
this._body.append(this._element);
|
|
132
159
|
}
|
|
133
160
|
|
|
134
|
-
_measureColumns() {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
const
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
161
|
+
_measureColumns() {
|
|
162
|
+
return this._measureBodyColumns();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
_measureBodyColumns() {
|
|
166
|
+
const headerRow = this._head?.rows[this._head.rows.length - 1];
|
|
167
|
+
const headerWidths = this._measureRow(headerRow);
|
|
168
|
+
const rows = Array.from(this._element.tBodies || []).flatMap((body) => Array.from(body.rows || []));
|
|
169
|
+
for (const row of rows) {
|
|
170
|
+
if (row.hidden || row.hasAttribute('data-vg-table-state-row') || row.hasAttribute('data-vg-table-skeleton') || row.hasAttribute('data-vg-table-skeleton-row')) continue;
|
|
171
|
+
if (row.querySelector('[data-vg-table-state]')) continue;
|
|
172
|
+
const widths = this._measureRow(row);
|
|
173
|
+
if (widths.length === headerWidths.length && widths.some((width) => width > 0)) return widths;
|
|
174
|
+
}
|
|
175
|
+
return headerWidths;
|
|
176
|
+
}
|
|
144
177
|
|
|
145
|
-
_measureRow(row) {
|
|
178
|
+
_measureRow(row) {
|
|
146
179
|
if (!row) return [];
|
|
147
180
|
return Array.from(row.cells).flatMap((cell) => {
|
|
148
181
|
const span = Math.max(1, cell.colSpan || 1);
|
|
@@ -151,22 +184,122 @@ class _stickyHeader {
|
|
|
151
184
|
});
|
|
152
185
|
}
|
|
153
186
|
|
|
154
|
-
_applyColgroup(table, widths) {
|
|
155
|
-
if (!widths.length) return;
|
|
156
|
-
if (table.querySelector(':scope > colgroup:not([data-vg-table-sticky-colgroup])')) return;
|
|
157
|
-
let colgroup = table.querySelector(':scope > colgroup[data-vg-table-sticky-colgroup]');
|
|
187
|
+
_applyColgroup(table, widths) {
|
|
188
|
+
if (!widths.length) return;
|
|
189
|
+
if (table.querySelector(':scope > colgroup:not([data-vg-table-sticky-colgroup])')) return;
|
|
190
|
+
let colgroup = table.querySelector(':scope > colgroup[data-vg-table-sticky-colgroup]');
|
|
158
191
|
if (!colgroup) {
|
|
159
192
|
colgroup = table.ownerDocument.createElement('colgroup');
|
|
160
|
-
colgroup.setAttribute('data-vg-table-sticky-colgroup', '');
|
|
161
|
-
table.prepend(colgroup);
|
|
162
|
-
}
|
|
163
|
-
colgroup.
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
193
|
+
colgroup.setAttribute('data-vg-table-sticky-colgroup', '');
|
|
194
|
+
table.prepend(colgroup);
|
|
195
|
+
}
|
|
196
|
+
while (colgroup.children.length < widths.length) colgroup.append(table.ownerDocument.createElement('col'));
|
|
197
|
+
while (colgroup.children.length > widths.length) colgroup.lastElementChild.remove();
|
|
198
|
+
const headers = this._getHeaders();
|
|
199
|
+
widths.forEach((width, index) => {
|
|
200
|
+
const col = colgroup.children[index];
|
|
201
|
+
if (width > 0) col.style.width = `${width}px`;
|
|
202
|
+
else col.style.removeProperty('width');
|
|
203
|
+
const hidden = headers[index]?.hidden === true;
|
|
204
|
+
col.hidden = hidden;
|
|
205
|
+
col.toggleAttribute('data-vg-table-column-hidden', hidden);
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
_rememberColumnGeometry(widths) {
|
|
210
|
+
const headers = this._getHeaders();
|
|
211
|
+
const sourceCols = Array.from(this._element.querySelector(':scope > colgroup:not([data-vg-table-sticky-colgroup])')?.children || []);
|
|
212
|
+
this._hasSourceColgroup = sourceCols.length > 0;
|
|
213
|
+
headers.forEach((header, index) => {
|
|
214
|
+
const key = this._columnKey(header, index);
|
|
215
|
+
this._columnWeights.set(key, widths[index] > 0 ? widths[index] : 1);
|
|
216
|
+
if (this._hasDeclaredWidth(header) || this._hasDeclaredWidth(sourceCols[index])) {
|
|
217
|
+
this._hardColumnWidths.set(key, widths[index] > 0 ? widths[index] : 0);
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
_resolveLayoutWidths() {
|
|
223
|
+
const headers = this._getHeaders();
|
|
224
|
+
const measured = this._measureBodyColumns();
|
|
225
|
+
if (this._hasSourceColgroup || !headers.length) return measured;
|
|
226
|
+
|
|
227
|
+
const bodyRow = Array.from(this._element.tBodies || [])
|
|
228
|
+
.flatMap((body) => Array.from(body.rows || []))
|
|
229
|
+
.find((row) => !row.hidden && !row.hasAttribute('data-vg-table-state-row'));
|
|
230
|
+
const hard = new Map();
|
|
231
|
+
const flexible = [];
|
|
232
|
+
headers.forEach((header, index) => {
|
|
233
|
+
const key = this._columnKey(header, index);
|
|
234
|
+
const bodyCell = bodyRow?.cells[index];
|
|
235
|
+
if (this._hasDeclaredWidth(header) || this._hasDeclaredWidth(bodyCell) || this._hardColumnWidths.has(key)) {
|
|
236
|
+
const declared = this._readDeclaredPixelWidth(header) || this._readDeclaredPixelWidth(bodyCell);
|
|
237
|
+
const width = declared || this._hardColumnWidths.get(key) || measured[index] || 0;
|
|
238
|
+
this._hardColumnWidths.set(key, width);
|
|
239
|
+
hard.set(index, width);
|
|
240
|
+
} else {
|
|
241
|
+
flexible.push(index);
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
const measuredTotal = measured.reduce((total, width) => total + width, 0);
|
|
246
|
+
const viewport = this._body?.clientWidth || this._container?.clientWidth || measuredTotal;
|
|
247
|
+
const minimum = this._readTableMinimumWidth();
|
|
248
|
+
const target = Math.max(viewport, minimum, 0);
|
|
249
|
+
const hardTotal = Array.from(hard.values()).reduce((total, width) => total + width, 0);
|
|
250
|
+
const available = Math.max(0, target - hardTotal);
|
|
251
|
+
const widths = Array(headers.length).fill(0);
|
|
252
|
+
hard.forEach((width, index) => { widths[index] = width; });
|
|
253
|
+
|
|
254
|
+
if (!flexible.length) return widths;
|
|
255
|
+
const weights = flexible.map((index) => {
|
|
256
|
+
const key = this._columnKey(headers[index], index);
|
|
257
|
+
return this._columnWeights.get(key) || measured[index] || 1;
|
|
258
|
+
});
|
|
259
|
+
const weightTotal = weights.reduce((total, weight) => total + weight, 0) || flexible.length;
|
|
260
|
+
let distributed = 0;
|
|
261
|
+
flexible.forEach((index, position) => {
|
|
262
|
+
const width = position === flexible.length - 1
|
|
263
|
+
? Math.max(0, available - distributed)
|
|
264
|
+
: available * weights[position] / weightTotal;
|
|
265
|
+
widths[index] = width;
|
|
266
|
+
distributed += width;
|
|
267
|
+
});
|
|
268
|
+
return widths;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
_getHeaders() {
|
|
272
|
+
const rows = Array.from(this._head?.rows || []);
|
|
273
|
+
return rows.length ? Array.from(rows.at(-1).cells || []) : [];
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
_columnKey(header, index) {
|
|
277
|
+
return String(header?.getAttribute('data-field') || index).trim();
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
_hasDeclaredWidth(element) {
|
|
281
|
+
if (!element) return false;
|
|
282
|
+
return element.hasAttribute('width')
|
|
283
|
+
|| element.hasAttribute('data-column-width')
|
|
284
|
+
|| Boolean(element.style?.width || element.style?.minWidth || element.style?.maxWidth);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
_readDeclaredPixelWidth(element) {
|
|
288
|
+
if (!element || !this._hasDeclaredWidth(element)) return 0;
|
|
289
|
+
const fixed = element.style?.minWidth && element.style.minWidth === element.style.maxWidth
|
|
290
|
+
? Number.parseFloat(element.style.width || element.style.minWidth)
|
|
291
|
+
: 0;
|
|
292
|
+
if (Number.isFinite(fixed) && fixed > 0) return fixed;
|
|
293
|
+
const measured = element.getBoundingClientRect?.().width || element.offsetWidth || 0;
|
|
294
|
+
return measured > 0 ? measured : 0;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
_readTableMinimumWidth() {
|
|
298
|
+
if (typeof getComputedStyle !== 'function') return 0;
|
|
299
|
+
const value = Number.parseFloat(getComputedStyle(this._element).minWidth || '0');
|
|
300
|
+
return Number.isFinite(value) ? value : 0;
|
|
301
|
+
}
|
|
302
|
+
|
|
170
303
|
_syncScroll() {
|
|
171
304
|
if (this._header && this._body) this._header.scrollLeft = this._body.scrollLeft;
|
|
172
305
|
}
|
|
@@ -23,17 +23,18 @@
|
|
|
23
23
|
border-radius: var(--vg-table-sticky-radius);
|
|
24
24
|
background: var(--vg-table-sticky-bg);
|
|
25
25
|
|
|
26
|
-
.vg-table-header,
|
|
27
|
-
.vg-table-body {
|
|
28
|
-
width: 100%;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
.vg-table-header {
|
|
32
|
-
position: relative;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
border-start-
|
|
26
|
+
.vg-table-header,
|
|
27
|
+
.vg-table-body {
|
|
28
|
+
width: 100%;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.vg-table-header {
|
|
32
|
+
position: relative;
|
|
33
|
+
z-index: var(--vg-table-sticky-z-index);
|
|
34
|
+
overflow: hidden;
|
|
35
|
+
background: var(--vg-table-thead-bg);
|
|
36
|
+
border-start-start-radius: var(--vg-table-sticky-inner-radius);
|
|
37
|
+
border-start-end-radius: var(--vg-table-sticky-inner-radius);
|
|
37
38
|
|
|
38
39
|
&--scrollbar::after {
|
|
39
40
|
content: "";
|
|
@@ -46,11 +47,16 @@
|
|
|
46
47
|
border-bottom: var(--vg-table-sticky-border-width) var(--vg-table-sticky-border-style) var(--vg-table-sticky-border-color);
|
|
47
48
|
background: var(--vg-table-fixed-header-bg, var(--vg-table-thead-bg));
|
|
48
49
|
pointer-events: none;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
.vg-table-
|
|
53
|
-
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.vg-table-body {
|
|
54
|
+
position: relative;
|
|
55
|
+
z-index: 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.vg-table-header__table,
|
|
59
|
+
.vg-table-body > .vg-table {
|
|
54
60
|
width: 100%;
|
|
55
61
|
min-width: 100%;
|
|
56
62
|
table-layout: fixed;
|
|
@@ -114,8 +120,9 @@
|
|
|
114
120
|
}
|
|
115
121
|
}
|
|
116
122
|
|
|
117
|
-
.vg-table-body {
|
|
118
|
-
overflow:
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
123
|
+
.vg-table-body {
|
|
124
|
+
overflow-x: auto;
|
|
125
|
+
overflow-y: hidden;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|