vue2-excel-grid 2.6.1 → 2.6.3
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
|
@@ -993,6 +993,9 @@ const ROW_HEADER_WIDTH = 50
|
|
|
993
993
|
const DEFAULT_COL_WIDTH = 100
|
|
994
994
|
const OUTLINE_GUTTER = 20
|
|
995
995
|
const FIT_COLUMNS_MIN_WIDTH = 40
|
|
996
|
+
const ROW_LIST_EDGE_PAD = 8 // birinchi/oxirgi qator bilan tepa/pastki border orasidagi bo'sh joy (px)
|
|
997
|
+
const FILL_DRAG_EDGE_ZONE = 24 // px from .eg-scroll-body's edge that triggers continuous auto-scroll while fill-dragging
|
|
998
|
+
const FILL_DRAG_MAX_SPEED = 18 // px/frame, at the very edge (scales down to 0 at the zone's outer boundary)
|
|
996
999
|
|
|
997
1000
|
// Classifies a col.width spec so resolveColWidth() knows how to turn it into a
|
|
998
1001
|
// concrete px number. Plain numbers/px strings resolve instantly with no DOM
|
|
@@ -1873,7 +1876,7 @@ const ExcelGridComponent = {
|
|
|
1873
1876
|
// findVisibleRange() uses binary search against this cached array → O(log n) per scroll.
|
|
1874
1877
|
// Invalidated only when row count, custom heights, or hidden rows change.
|
|
1875
1878
|
cumulativeHeights() {
|
|
1876
|
-
return buildCumulativeHeights(this.totalRows, this._rowH, this.rowHeights, this.hiddenRowSet)
|
|
1879
|
+
return buildCumulativeHeights(this.totalRows, this._rowH, this.rowHeights, this.hiddenRowSet, ROW_LIST_EDGE_PAD, ROW_LIST_EDGE_PAD)
|
|
1877
1880
|
},
|
|
1878
1881
|
|
|
1879
1882
|
// height prop omitted → fit header + filter row + all (visible) rows + footer exactly.
|
|
@@ -2631,6 +2634,14 @@ const ExcelGridComponent = {
|
|
|
2631
2634
|
this._dragScrollRAF = null
|
|
2632
2635
|
this._dragCleanupTimer = null
|
|
2633
2636
|
|
|
2637
|
+
// Fill-handle drag edge auto-scroll (see _updateFillDragAutoScroll) — same
|
|
2638
|
+
// idle-when-0 convention as _dragScrollV/_dragScrollRAF above, just for
|
|
2639
|
+
// both axes since a fill can extend down OR right.
|
|
2640
|
+
this._fillDragScrollV = 0
|
|
2641
|
+
this._fillDragScrollH = 0
|
|
2642
|
+
this._fillDragScrollRAF = null
|
|
2643
|
+
this._fillDragLastEvent = null
|
|
2644
|
+
|
|
2634
2645
|
// localSyncKey — the last `data` reference a version was actually saved
|
|
2635
2646
|
// for. Initialized to the current (mount-time) value so an untouched grid
|
|
2636
2647
|
// that's merely tab-switched away from doesn't spam a "nothing happened"
|
|
@@ -2715,6 +2726,7 @@ const ExcelGridComponent = {
|
|
|
2715
2726
|
clearTimeout(this._widthSyncChainResetTimer)
|
|
2716
2727
|
clearTimeout(this._bufferWriteTimer)
|
|
2717
2728
|
if (this._dragScrollRAF) cancelAnimationFrame(this._dragScrollRAF)
|
|
2729
|
+
if (this._fillDragScrollRAF) cancelAnimationFrame(this._fillDragScrollRAF)
|
|
2718
2730
|
document.removeEventListener('mousemove', this.onGlobalMouseMove)
|
|
2719
2731
|
document.removeEventListener('mouseup', this.onGlobalMouseUp)
|
|
2720
2732
|
document.removeEventListener('keydown', this.onGlobalKeyDown)
|
|
@@ -3449,7 +3461,7 @@ const ExcelGridComponent = {
|
|
|
3449
3461
|
},
|
|
3450
3462
|
|
|
3451
3463
|
getRowGroupBtnStyle(group) {
|
|
3452
|
-
const top = getRowTop(group.startIndex, this._rowH, this.rowHeights) - this.scrollTop
|
|
3464
|
+
const top = getRowTop(group.startIndex, this._rowH, this.rowHeights, ROW_LIST_EDGE_PAD) - this.scrollTop
|
|
3453
3465
|
return {
|
|
3454
3466
|
position: 'absolute',
|
|
3455
3467
|
top: top + 'px',
|
|
@@ -4088,7 +4100,7 @@ const ExcelGridComponent = {
|
|
|
4088
4100
|
scrollToCell(ri, ci) {
|
|
4089
4101
|
const scrollBody = this.$refs.scrollBody
|
|
4090
4102
|
if (!scrollBody) return
|
|
4091
|
-
const rowTop = getRowTop(ri, this._rowH, this.rowHeights)
|
|
4103
|
+
const rowTop = getRowTop(ri, this._rowH, this.rowHeights, ROW_LIST_EDGE_PAD)
|
|
4092
4104
|
const rowBottom = rowTop + this.getRowH(ri)
|
|
4093
4105
|
|
|
4094
4106
|
if (rowTop < scrollBody.scrollTop) scrollBody.scrollTop = rowTop
|
|
@@ -5105,9 +5117,14 @@ const ExcelGridComponent = {
|
|
|
5105
5117
|
this.isMouseDown = false
|
|
5106
5118
|
},
|
|
5107
5119
|
|
|
5108
|
-
|
|
5120
|
+
// Resolves which (row, col) the mouse is currently over, given the
|
|
5121
|
+
// scroll body's CURRENT scrollTop/scrollLeft — called both directly from
|
|
5122
|
+
// mousemove and repeatedly from the edge-auto-scroll rAF loop below (as
|
|
5123
|
+
// scrollTop changes on its own, the row under a STATIONARY cursor changes
|
|
5124
|
+
// with it).
|
|
5125
|
+
_fillDragTargetFromEvent(e) {
|
|
5109
5126
|
const scrollBody = this.$refs.scrollBody
|
|
5110
|
-
if (!scrollBody) return
|
|
5127
|
+
if (!scrollBody) return null
|
|
5111
5128
|
const rect = scrollBody.getBoundingClientRect()
|
|
5112
5129
|
const relY = e.clientY - rect.top + scrollBody.scrollTop
|
|
5113
5130
|
const relX = e.clientX - rect.left + scrollBody.scrollLeft
|
|
@@ -5132,12 +5149,78 @@ const ExcelGridComponent = {
|
|
|
5132
5149
|
if (relX < left) { col = i; break }
|
|
5133
5150
|
col = i
|
|
5134
5151
|
}
|
|
5152
|
+
return { row, col }
|
|
5153
|
+
},
|
|
5154
|
+
|
|
5155
|
+
handleFillDragMove(e) {
|
|
5156
|
+
this._fillDragLastEvent = e
|
|
5157
|
+
const target = this._fillDragTargetFromEvent(e)
|
|
5158
|
+
if (!target) return
|
|
5159
|
+
this.fillDrag.currentRow = target.row
|
|
5160
|
+
this.fillDrag.currentCol = target.col
|
|
5161
|
+
// Covers the common case of a single big mousemove jump landing the
|
|
5162
|
+
// cursor (and its computed target row/col) outside the visible window.
|
|
5163
|
+
this.scrollToCell(target.row, target.col)
|
|
5164
|
+
// Covers the — far more common in practice — case of the cursor
|
|
5165
|
+
// PINNED at the container's edge (it usually can't travel further,
|
|
5166
|
+
// since the grid typically fills its host layout down to that edge):
|
|
5167
|
+
// keep scrolling for as long as it stays there. Same rAF/edge-zone
|
|
5168
|
+
// pattern as _updateDragAutoScroll (column-drag reordering) below.
|
|
5169
|
+
this._updateFillDragAutoScroll(e.clientX, e.clientY)
|
|
5170
|
+
},
|
|
5171
|
+
|
|
5172
|
+
// Edge auto-scroll for fill-handle dragging — vertical AND horizontal
|
|
5173
|
+
// (column-drag's _updateDragAutoScroll is horizontal-only). Speed scales
|
|
5174
|
+
// with how deep into the 24px edge zone the cursor sits.
|
|
5175
|
+
_updateFillDragAutoScroll(clientX, clientY) {
|
|
5176
|
+
const sb = this.$refs.scrollBody
|
|
5177
|
+
if (!sb) { this._fillDragScrollV = 0; this._fillDragScrollH = 0; return }
|
|
5178
|
+
const rect = sb.getBoundingClientRect()
|
|
5179
|
+
const ZONE = FILL_DRAG_EDGE_ZONE
|
|
5180
|
+
|
|
5181
|
+
let v = 0
|
|
5182
|
+
if (clientY < rect.top + ZONE) v = -Math.ceil((rect.top + ZONE - clientY) / 4)
|
|
5183
|
+
else if (clientY > rect.bottom - ZONE) v = Math.ceil((clientY - (rect.bottom - ZONE)) / 4)
|
|
5184
|
+
this._fillDragScrollV = Math.max(-FILL_DRAG_MAX_SPEED, Math.min(FILL_DRAG_MAX_SPEED, v))
|
|
5185
|
+
|
|
5186
|
+
let h = 0
|
|
5187
|
+
if (clientX < rect.left + ZONE) h = -Math.ceil((rect.left + ZONE - clientX) / 4)
|
|
5188
|
+
else if (clientX > rect.right - ZONE) h = Math.ceil((clientX - (rect.right - ZONE)) / 4)
|
|
5189
|
+
this._fillDragScrollH = Math.max(-FILL_DRAG_MAX_SPEED, Math.min(FILL_DRAG_MAX_SPEED, h))
|
|
5190
|
+
|
|
5191
|
+
if ((this._fillDragScrollV !== 0 || this._fillDragScrollH !== 0) && !this._fillDragScrollRAF) {
|
|
5192
|
+
const step = () => {
|
|
5193
|
+
this._fillDragScrollRAF = null
|
|
5194
|
+
if (!this.fillDrag.active) return
|
|
5195
|
+
const body = this.$refs.scrollBody
|
|
5196
|
+
if (body) {
|
|
5197
|
+
if (this._fillDragScrollV) body.scrollTop = Math.max(0, Math.min(body.scrollHeight - body.clientHeight, body.scrollTop + this._fillDragScrollV))
|
|
5198
|
+
if (this._fillDragScrollH) body.scrollLeft = Math.max(0, Math.min(body.scrollWidth - body.clientWidth, body.scrollLeft + this._fillDragScrollH))
|
|
5199
|
+
// The cursor itself hasn't moved, but the content under it has —
|
|
5200
|
+
// re-derive the fill target at the new scroll position.
|
|
5201
|
+
if (this._fillDragLastEvent) {
|
|
5202
|
+
const target = this._fillDragTargetFromEvent(this._fillDragLastEvent)
|
|
5203
|
+
if (target) { this.fillDrag.currentRow = target.row; this.fillDrag.currentCol = target.col }
|
|
5204
|
+
}
|
|
5205
|
+
}
|
|
5206
|
+
if (this._fillDragScrollV !== 0 || this._fillDragScrollH !== 0) this._fillDragScrollRAF = requestAnimationFrame(step)
|
|
5207
|
+
}
|
|
5208
|
+
this._fillDragScrollRAF = requestAnimationFrame(step)
|
|
5209
|
+
}
|
|
5210
|
+
},
|
|
5135
5211
|
|
|
5136
|
-
|
|
5137
|
-
this.
|
|
5212
|
+
_stopFillDragAutoScroll() {
|
|
5213
|
+
this._fillDragScrollV = 0
|
|
5214
|
+
this._fillDragScrollH = 0
|
|
5215
|
+
this._fillDragLastEvent = null
|
|
5216
|
+
if (this._fillDragScrollRAF) {
|
|
5217
|
+
cancelAnimationFrame(this._fillDragScrollRAF)
|
|
5218
|
+
this._fillDragScrollRAF = null
|
|
5219
|
+
}
|
|
5138
5220
|
},
|
|
5139
5221
|
|
|
5140
5222
|
async commitFillDrag() {
|
|
5223
|
+
this._stopFillDragAutoScroll()
|
|
5141
5224
|
if (this.internalLocked) { this.fillDrag.active = false; return }
|
|
5142
5225
|
const src = this.fillDrag.sourceRange
|
|
5143
5226
|
if (!src) { this.fillDrag.active = false; return }
|
|
@@ -75,15 +75,18 @@ export function calcVisibleRows(scrollTop, containerHeight, totalRows, rowHeight
|
|
|
75
75
|
* @param {number} defaultHeight
|
|
76
76
|
* @param {Object} rowHeightsMap - sparse { index: px } overrides
|
|
77
77
|
* @param {Set} hiddenSet - Set of hidden row indices (height = 0)
|
|
78
|
+
* @param {number} padTop - extra px baked into cum[0] (and every entry after it)
|
|
79
|
+
* @param {number} padBottom - extra px baked into the final (total-height) entry only
|
|
78
80
|
* @returns {number[]} length = totalRows + 1
|
|
79
81
|
*/
|
|
80
|
-
export function buildCumulativeHeights(totalRows, defaultHeight, rowHeightsMap = {}, hiddenSet = new Set()) {
|
|
82
|
+
export function buildCumulativeHeights(totalRows, defaultHeight, rowHeightsMap = {}, hiddenSet = new Set(), padTop = 0, padBottom = 0) {
|
|
81
83
|
const cum = new Array(totalRows + 1)
|
|
82
|
-
cum[0] =
|
|
84
|
+
cum[0] = padTop
|
|
83
85
|
for (let i = 0; i < totalRows; i++) {
|
|
84
86
|
const h = hiddenSet.has(i) ? 0 : (rowHeightsMap[i] !== undefined ? rowHeightsMap[i] : defaultHeight)
|
|
85
87
|
cum[i + 1] = cum[i] + h
|
|
86
88
|
}
|
|
89
|
+
cum[totalRows] += padBottom
|
|
87
90
|
return cum
|
|
88
91
|
}
|
|
89
92
|
|
|
@@ -131,9 +134,10 @@ export function findVisibleRange(scrollTop, containerHeight, totalRows, cumulati
|
|
|
131
134
|
|
|
132
135
|
/**
|
|
133
136
|
* Get the top offset of a row
|
|
137
|
+
* @param {number} padTop - extra px offset added on top (see buildCumulativeHeights)
|
|
134
138
|
*/
|
|
135
|
-
export function getRowTop(rowIndex, rowHeight, rowHeights = []) {
|
|
136
|
-
let top =
|
|
139
|
+
export function getRowTop(rowIndex, rowHeight, rowHeights = [], padTop = 0) {
|
|
140
|
+
let top = padTop
|
|
137
141
|
for (let i = 0; i < rowIndex; i++) {
|
|
138
142
|
top += rowHeights[i] !== undefined ? rowHeights[i] : rowHeight
|
|
139
143
|
}
|