vue2-excel-grid 2.0.2 → 2.1.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/dist/vue2-excel-grid.esm.js +788 -507
- package/dist/vue2-excel-grid.umd.js +2 -2
- package/package.json +1 -1
- package/src/components/ExcelGrid.vue +112 -0
package/package.json
CHANGED
|
@@ -3667,6 +3667,17 @@ const ExcelGridComponent = {
|
|
|
3667
3667
|
return
|
|
3668
3668
|
}
|
|
3669
3669
|
|
|
3670
|
+
if (key === 'd' && (e.ctrlKey || e.metaKey)) {
|
|
3671
|
+
e.preventDefault()
|
|
3672
|
+
this.fillDown()
|
|
3673
|
+
return
|
|
3674
|
+
}
|
|
3675
|
+
if (key === 'r' && (e.ctrlKey || e.metaKey)) {
|
|
3676
|
+
e.preventDefault()
|
|
3677
|
+
this.fillRight()
|
|
3678
|
+
return
|
|
3679
|
+
}
|
|
3680
|
+
|
|
3670
3681
|
if (key === 'Delete' || key === 'Backspace') {
|
|
3671
3682
|
e.preventDefault()
|
|
3672
3683
|
this.clearSelection()
|
|
@@ -5051,6 +5062,107 @@ const ExcelGridComponent = {
|
|
|
5051
5062
|
if (skipped.length > 0) this._emitBulkValidationError(skipped, false)
|
|
5052
5063
|
},
|
|
5053
5064
|
|
|
5065
|
+
// =========================================================
|
|
5066
|
+
// Ctrl+D / Ctrl+R — Excel's standard fill-down/fill-right (3.96)
|
|
5067
|
+
// =========================================================
|
|
5068
|
+
// Plain copy, NOT the fill-handle's series continuation (generateFillValues,
|
|
5069
|
+
// 1,2,3->4,5,6) — matches real Excel: Ctrl+D/Ctrl+R just duplicates a row/
|
|
5070
|
+
// column's values, it never extrapolates a pattern.
|
|
5071
|
+
async _fillAxis(direction) {
|
|
5072
|
+
if (this.internalLocked) return
|
|
5073
|
+
if (!this.selectionRanges.length) return
|
|
5074
|
+
const oldData = this.data
|
|
5075
|
+
const newData = oldData.slice()
|
|
5076
|
+
const skipped = []
|
|
5077
|
+
const appliedRanges = []
|
|
5078
|
+
|
|
5079
|
+
for (const range of this.selectionRanges) {
|
|
5080
|
+
const r = normalizeRange(range)
|
|
5081
|
+
if (direction === 'down') {
|
|
5082
|
+
let srcRow, firstTargetRow, lastTargetRow
|
|
5083
|
+
if (r.startRow === r.endRow) {
|
|
5084
|
+
// Single-row selection: Excel fills from the row directly above.
|
|
5085
|
+
srcRow = r.startRow - 1
|
|
5086
|
+
if (srcRow < 0) continue
|
|
5087
|
+
firstTargetRow = r.startRow
|
|
5088
|
+
lastTargetRow = r.startRow
|
|
5089
|
+
} else {
|
|
5090
|
+
srcRow = r.startRow
|
|
5091
|
+
firstTargetRow = r.startRow + 1
|
|
5092
|
+
lastTargetRow = r.endRow
|
|
5093
|
+
}
|
|
5094
|
+
for (let ci = r.startCol; ci <= r.endCol; ci++) {
|
|
5095
|
+
const col = this.leafCols[ci]
|
|
5096
|
+
if (!col) continue
|
|
5097
|
+
const srcVal = oldData[srcRow] ? oldData[srcRow][col.key] : ''
|
|
5098
|
+
for (let ri = firstTargetRow; ri <= lastTargetRow; ri++) {
|
|
5099
|
+
if (!this.isCellEditable(ri, ci)) continue
|
|
5100
|
+
const v = this._coerceCellValue(ci, this._applyColMask(ci, srcVal))
|
|
5101
|
+
if (!this.isCellValueValid(ri, ci, v)) { skipped.push({ row: ri, col: ci, value: v }); continue }
|
|
5102
|
+
if (newData[ri] === oldData[ri]) newData[ri] = { ...oldData[ri] }
|
|
5103
|
+
newData[ri][col.key] = v
|
|
5104
|
+
}
|
|
5105
|
+
}
|
|
5106
|
+
appliedRanges.push({
|
|
5107
|
+
sourceRange: { startRow: srcRow, endRow: srcRow, startCol: r.startCol, endCol: r.endCol },
|
|
5108
|
+
targetRange: { startRow: firstTargetRow, endRow: lastTargetRow, startCol: r.startCol, endCol: r.endCol }
|
|
5109
|
+
})
|
|
5110
|
+
} else {
|
|
5111
|
+
let srcCol, firstTargetCol, lastTargetCol
|
|
5112
|
+
if (r.startCol === r.endCol) {
|
|
5113
|
+
// Single-column selection: Excel fills from the column directly to the left.
|
|
5114
|
+
srcCol = r.startCol - 1
|
|
5115
|
+
if (srcCol < 0) continue
|
|
5116
|
+
firstTargetCol = r.startCol
|
|
5117
|
+
lastTargetCol = r.startCol
|
|
5118
|
+
} else {
|
|
5119
|
+
srcCol = r.startCol
|
|
5120
|
+
firstTargetCol = r.startCol + 1
|
|
5121
|
+
lastTargetCol = r.endCol
|
|
5122
|
+
}
|
|
5123
|
+
const srcColDef = this.leafCols[srcCol]
|
|
5124
|
+
for (let ri = r.startRow; ri <= r.endRow; ri++) {
|
|
5125
|
+
const srcVal = srcColDef && oldData[ri] ? oldData[ri][srcColDef.key] : ''
|
|
5126
|
+
for (let ci = firstTargetCol; ci <= lastTargetCol; ci++) {
|
|
5127
|
+
const col = this.leafCols[ci]
|
|
5128
|
+
if (!col || !this.isCellEditable(ri, ci)) continue
|
|
5129
|
+
const v = this._coerceCellValue(ci, this._applyColMask(ci, srcVal))
|
|
5130
|
+
if (!this.isCellValueValid(ri, ci, v)) { skipped.push({ row: ri, col: ci, value: v }); continue }
|
|
5131
|
+
if (newData[ri] === oldData[ri]) newData[ri] = { ...oldData[ri] }
|
|
5132
|
+
newData[ri][col.key] = v
|
|
5133
|
+
}
|
|
5134
|
+
}
|
|
5135
|
+
appliedRanges.push({
|
|
5136
|
+
sourceRange: { startRow: r.startRow, endRow: r.endRow, startCol: srcCol, endCol: srcCol },
|
|
5137
|
+
targetRange: { startRow: r.startRow, endRow: r.endRow, startCol: firstTargetCol, endCol: lastTargetCol }
|
|
5138
|
+
})
|
|
5139
|
+
}
|
|
5140
|
+
}
|
|
5141
|
+
|
|
5142
|
+
if (!appliedRanges.length) return
|
|
5143
|
+
|
|
5144
|
+
if (this.strictBulkValidation && skipped.length > 0) {
|
|
5145
|
+
this._emitBulkValidationError(skipped, true)
|
|
5146
|
+
return
|
|
5147
|
+
}
|
|
5148
|
+
|
|
5149
|
+
this._emitDataChange(oldData, newData)
|
|
5150
|
+
for (const ar of appliedRanges) {
|
|
5151
|
+
this.$emit('fill', { sourceRange: ar.sourceRange, targetRange: ar.targetRange, values: newData })
|
|
5152
|
+
}
|
|
5153
|
+
if (skipped.length > 0) this._emitBulkValidationError(skipped, false)
|
|
5154
|
+
|
|
5155
|
+
// See pasteAt's/commitFillDrag's _fireCellCallbacksForRange call — same
|
|
5156
|
+
// nextTick deferral reasoning (col.onInput/onSelect after the DOM settles).
|
|
5157
|
+
await this.$nextTick()
|
|
5158
|
+
for (const ar of appliedRanges) {
|
|
5159
|
+
this._fireCellCallbacksForRange(oldData, newData, ar.targetRange.startRow, ar.targetRange.endRow, ar.targetRange.startCol, ar.targetRange.endCol)
|
|
5160
|
+
}
|
|
5161
|
+
},
|
|
5162
|
+
|
|
5163
|
+
fillDown() { return this._fillAxis('down') },
|
|
5164
|
+
fillRight() { return this._fillAxis('right') },
|
|
5165
|
+
|
|
5054
5166
|
// =========================================================
|
|
5055
5167
|
// COPY / PASTE (3.4)
|
|
5056
5168
|
// =========================================================
|