vue2-excel-grid 2.3.0 → 2.5.0
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/package.json
CHANGED
|
@@ -556,7 +556,7 @@
|
|
|
556
556
|
class="eg-cell"
|
|
557
557
|
:data-fi="ci"
|
|
558
558
|
:class="getCellClasses(ri, ci)"
|
|
559
|
-
:style="getCellStyle(ri, ci)"
|
|
559
|
+
:style="[getCellStyle(ri, ci), getRowCustomStyle(ri)]"
|
|
560
560
|
@mousedown="onCellMouseDown($event, ri, ci)"
|
|
561
561
|
@mouseover="onCellMouseOver($event, ri, ci)"
|
|
562
562
|
@mouseup="onCellMouseUp"
|
|
@@ -615,7 +615,7 @@
|
|
|
615
615
|
class="eg-cell"
|
|
616
616
|
:data-fi="ci"
|
|
617
617
|
:class="getCellClasses(ri, ci)"
|
|
618
|
-
:style="getCellStyle(ri, ci)"
|
|
618
|
+
:style="[getCellStyle(ri, ci), getRowCustomStyle(ri)]"
|
|
619
619
|
@mousedown="onCellMouseDown($event, ri, ci)"
|
|
620
620
|
@mouseover="onCellMouseOver($event, ri, ci)"
|
|
621
621
|
@mouseup="onCellMouseUp"
|
|
@@ -674,7 +674,7 @@
|
|
|
674
674
|
class="eg-cell"
|
|
675
675
|
:data-fi="col._flatIndex"
|
|
676
676
|
:class="getCellClasses(ri, col._flatIndex)"
|
|
677
|
-
:style="getCellStyle(ri, col._flatIndex)"
|
|
677
|
+
:style="[getCellStyle(ri, col._flatIndex), getRowCustomStyle(ri)]"
|
|
678
678
|
@mousedown="onCellMouseDown($event, ri, col._flatIndex)"
|
|
679
679
|
@mouseover="onCellMouseOver($event, ri, col._flatIndex)"
|
|
680
680
|
@mouseup="onCellMouseUp"
|
|
@@ -792,6 +792,38 @@
|
|
|
792
792
|
|
|
793
793
|
<!-- Resize indicator line -->
|
|
794
794
|
<div v-if="resizing.active" class="eg-resize-line" :style="resizeLineStyle"></div>
|
|
795
|
+
|
|
796
|
+
<!-- Loading overlay (host-driven, e.g. during an async data fetch) -->
|
|
797
|
+
<div v-if="loading" class="eg-loading-overlay">
|
|
798
|
+
<template v-if="columns && columns.length">
|
|
799
|
+
<div class="eg-skeleton">
|
|
800
|
+
<div class="eg-skeleton-row eg-skeleton-row-header" :style="{ height: headerRowHeight + 'px' }">
|
|
801
|
+
<div
|
|
802
|
+
v-for="col in leafCols"
|
|
803
|
+
:key="'sk-h-' + col._flatIndex"
|
|
804
|
+
class="eg-skeleton-block"
|
|
805
|
+
:style="{ width: getColW(col._flatIndex) + 'px' }"
|
|
806
|
+
></div>
|
|
807
|
+
</div>
|
|
808
|
+
<div
|
|
809
|
+
v-for="r in 20"
|
|
810
|
+
:key="'sk-r-' + r"
|
|
811
|
+
class="eg-skeleton-row"
|
|
812
|
+
:style="{ height: _rowH + 'px' }"
|
|
813
|
+
>
|
|
814
|
+
<div
|
|
815
|
+
v-for="col in leafCols"
|
|
816
|
+
:key="'sk-c-' + col._flatIndex"
|
|
817
|
+
class="eg-skeleton-block"
|
|
818
|
+
:style="{ width: getColW(col._flatIndex) + 'px' }"
|
|
819
|
+
></div>
|
|
820
|
+
</div>
|
|
821
|
+
</div>
|
|
822
|
+
</template>
|
|
823
|
+
<template v-else>
|
|
824
|
+
<div class="eg-loading-spinner"></div>
|
|
825
|
+
</template>
|
|
826
|
+
</div>
|
|
795
827
|
</div><!-- end container -->
|
|
796
828
|
|
|
797
829
|
<!-- Import progress overlay -->
|
|
@@ -1314,6 +1346,39 @@ const ExcelGridComponent = {
|
|
|
1314
1346
|
*/
|
|
1315
1347
|
locked: { type: Boolean, default: false },
|
|
1316
1348
|
|
|
1349
|
+
/**
|
|
1350
|
+
* Host-driven loading state (e.g. while an async data fetch is in
|
|
1351
|
+
* flight). When `true`, only the grid body (`.eg-container`) is
|
|
1352
|
+
* covered — the toolbar stays visible and interactive. If `columns`
|
|
1353
|
+
* is non-empty, a shimmering skeleton matching each column's width is
|
|
1354
|
+
* shown; otherwise a plain centered spinner is shown. Purely visual —
|
|
1355
|
+
* doesn't block edits/interaction the way `locked` does (combine both
|
|
1356
|
+
* if that's also needed).
|
|
1357
|
+
* @type {Boolean}
|
|
1358
|
+
* @default false
|
|
1359
|
+
* @example
|
|
1360
|
+
* <excel-grid :columns="columns" v-model="data" :loading="isFetching" />
|
|
1361
|
+
*/
|
|
1362
|
+
loading: { type: Boolean, default: false },
|
|
1363
|
+
|
|
1364
|
+
/**
|
|
1365
|
+
* Data-driven per-row styling: `(row, rowIndex) => styleObject`. The
|
|
1366
|
+
* returned style object is applied to every cell in that row (across
|
|
1367
|
+
* the frozen/scrollable/pinned-right zones alike), giving the row a
|
|
1368
|
+
* continuous horizontal background/style without any host-side CSS.
|
|
1369
|
+
* Selection/active/fill-preview/readonly cell highlighting keeps
|
|
1370
|
+
* winning visually — those already use `!important`, which always
|
|
1371
|
+
* beats a plain (non-`!important`) inline style. Doesn't affect the
|
|
1372
|
+
* row-number header column (mirrors Excel: conditional formatting
|
|
1373
|
+
* colors data cells, not the row gutter). Return `null`/`undefined`
|
|
1374
|
+
* for rows that shouldn't get a custom style.
|
|
1375
|
+
* @type {Function}
|
|
1376
|
+
* @default null
|
|
1377
|
+
* @example
|
|
1378
|
+
* <excel-grid :columns="columns" v-model="data" :row-style="(row) => row.status === 'error' ? { background: '#fde2e2' } : null" />
|
|
1379
|
+
*/
|
|
1380
|
+
rowStyle: { type: Function, default: null },
|
|
1381
|
+
|
|
1317
1382
|
/** Show "Column info" / "Row info" items in the context menu (dev/debug aid). */
|
|
1318
1383
|
devMode: { type: Boolean, default: false },
|
|
1319
1384
|
|
|
@@ -3075,6 +3140,17 @@ const ExcelGridComponent = {
|
|
|
3075
3140
|
return style
|
|
3076
3141
|
},
|
|
3077
3142
|
|
|
3143
|
+
// rowStyle prop — deliberately NOT merged into getCellStyle()'s return value:
|
|
3144
|
+
// that object is cached/shared by (w,h,left) across unrelated rows/cells (see
|
|
3145
|
+
// comment above), so mutating it here would leak one row's style onto every
|
|
3146
|
+
// other cell that happens to share the same cache key. Kept as a second,
|
|
3147
|
+
// uncached :style array entry instead (see template) — cheap, and correctly
|
|
3148
|
+
// reactive to the row's actual data instead of just its geometry.
|
|
3149
|
+
getRowCustomStyle(ri) {
|
|
3150
|
+
if (!this.rowStyle) return null
|
|
3151
|
+
return this.rowStyle(this._dataRaw[ri], ri) || null
|
|
3152
|
+
},
|
|
3153
|
+
|
|
3078
3154
|
getCellClasses(ri, ci) {
|
|
3079
3155
|
const col = this.leafCols[ci]
|
|
3080
3156
|
const active = this.isActiveCell(ri, ci)
|
|
@@ -8007,6 +8083,60 @@ export default ExcelGridComponent
|
|
|
8007
8083
|
to { transform: rotate(360deg); }
|
|
8008
8084
|
}
|
|
8009
8085
|
|
|
8086
|
+
/* ===== LOADING OVERLAY (loading prop) ===== */
|
|
8087
|
+
.eg-loading-overlay {
|
|
8088
|
+
position: absolute;
|
|
8089
|
+
inset: 0;
|
|
8090
|
+
background: var(--eg-color-overlay-bg, var(--eg-color-overlay-bg-default));
|
|
8091
|
+
display: flex;
|
|
8092
|
+
align-items: center;
|
|
8093
|
+
justify-content: center;
|
|
8094
|
+
z-index: 90;
|
|
8095
|
+
overflow: hidden;
|
|
8096
|
+
}
|
|
8097
|
+
.eg-loading-spinner {
|
|
8098
|
+
width: 32px;
|
|
8099
|
+
height: 32px;
|
|
8100
|
+
border: 3px solid var(--eg-color-border-cell, var(--eg-color-border-cell-default));
|
|
8101
|
+
border-top-color: var(--eg-color-accent, var(--eg-color-accent-default));
|
|
8102
|
+
border-radius: 50%;
|
|
8103
|
+
animation: eg-spin 0.8s linear infinite;
|
|
8104
|
+
}
|
|
8105
|
+
.eg-skeleton {
|
|
8106
|
+
width: 100%;
|
|
8107
|
+
height: 100%;
|
|
8108
|
+
overflow: hidden;
|
|
8109
|
+
}
|
|
8110
|
+
.eg-skeleton-row {
|
|
8111
|
+
display: flex;
|
|
8112
|
+
align-items: center;
|
|
8113
|
+
padding: 0 4px;
|
|
8114
|
+
box-sizing: border-box;
|
|
8115
|
+
}
|
|
8116
|
+
.eg-skeleton-row-header {
|
|
8117
|
+
background: var(--eg-color-header-bg, var(--eg-color-header-bg-default));
|
|
8118
|
+
}
|
|
8119
|
+
.eg-skeleton-block {
|
|
8120
|
+
height: 60%;
|
|
8121
|
+
margin: 0 2px;
|
|
8122
|
+
border-radius: var(--eg-radius, var(--eg-radius-default));
|
|
8123
|
+
background: linear-gradient(
|
|
8124
|
+
90deg,
|
|
8125
|
+
var(--eg-color-border-cell, var(--eg-color-border-cell-default)) 25%,
|
|
8126
|
+
var(--eg-color-cell-readonly, var(--eg-color-cell-readonly-default)) 37%,
|
|
8127
|
+
var(--eg-color-border-cell, var(--eg-color-border-cell-default)) 63%
|
|
8128
|
+
);
|
|
8129
|
+
background-size: 400% 100%;
|
|
8130
|
+
animation: eg-skeleton-shimmer 1.4s ease infinite;
|
|
8131
|
+
}
|
|
8132
|
+
@keyframes eg-skeleton-shimmer {
|
|
8133
|
+
0% { background-position: 100% 50%; }
|
|
8134
|
+
100% { background-position: 0 50%; }
|
|
8135
|
+
}
|
|
8136
|
+
@media (prefers-reduced-motion: reduce) {
|
|
8137
|
+
.eg-skeleton-block, .eg-loading-spinner { animation: none; }
|
|
8138
|
+
}
|
|
8139
|
+
|
|
8010
8140
|
/* ===== READONLY CELL ===== */
|
|
8011
8141
|
/* !important throughout: same-specificity as the base .eg-cell / .eg-cell-active /
|
|
8012
8142
|
.eg-cell-selected rules, so which one wins would otherwise depend on source
|