mirror of
https://github.com/liubinfighter/csv-lite.git
synced 2026-07-22 05:43:52 +00:00
feat: enhance sticky functionality by adding default sticky headers and row numbers in CSV table view #12
This commit is contained in:
parent
201a040a8a
commit
d37a872e76
2 changed files with 76 additions and 19 deletions
45
src/view.ts
45
src/view.ts
|
|
@ -72,6 +72,8 @@ export class CSVView extends TextFileView {
|
|||
// 新增:固定行列功能
|
||||
private stickyRows: Set<number> = new Set();
|
||||
private stickyColumns: Set<number> = new Set();
|
||||
private stickyHeaders: boolean = true; // 表头默认固定
|
||||
private stickyRowNumbers: boolean = true; // 行号默认固定
|
||||
|
||||
constructor(leaf: any) {
|
||||
super(leaf);
|
||||
|
|
@ -949,35 +951,48 @@ export class CSVView extends TextFileView {
|
|||
if (!this.tableEl) return;
|
||||
|
||||
// 移除所有现有的sticky类
|
||||
this.tableEl.querySelectorAll('.csv-sticky-row, .csv-sticky-col').forEach(el => {
|
||||
el.classList.remove('csv-sticky-row', 'csv-sticky-col');
|
||||
this.tableEl.querySelectorAll('.csv-sticky-row, .csv-sticky-col, .csv-sticky-header, .csv-sticky-row-number').forEach(el => {
|
||||
el.classList.remove('csv-sticky-row', 'csv-sticky-col', 'csv-sticky-header', 'csv-sticky-row-number');
|
||||
});
|
||||
|
||||
// 应用固定行样式
|
||||
// 默认固定表头行(A、B、C、D...)
|
||||
if (this.stickyHeaders) {
|
||||
const headerCells = this.tableEl.querySelectorAll('thead tr th');
|
||||
headerCells.forEach(cell => cell.classList.add('csv-sticky-header'));
|
||||
}
|
||||
|
||||
// 默认固定行号列(0、1、2、3...)
|
||||
if (this.stickyRowNumbers) {
|
||||
// 行号列在表头中(左上角和行号标题)
|
||||
const headerRowNumber = this.tableEl.querySelector('thead tr th:first-child');
|
||||
if (headerRowNumber) headerRowNumber.classList.add('csv-sticky-row-number');
|
||||
|
||||
// 行号列在数据行中
|
||||
const rowNumberCells = this.tableEl.querySelectorAll('tbody tr td:first-child');
|
||||
rowNumberCells.forEach(cell => cell.classList.add('csv-sticky-row-number'));
|
||||
}
|
||||
|
||||
// 应用用户手动固定的行样式
|
||||
this.stickyRows.forEach(rowIndex => {
|
||||
// 表头行(列标题行)
|
||||
if (rowIndex === -1) {
|
||||
const headerCells = this.tableEl.querySelectorAll('thead tr th');
|
||||
headerCells.forEach(cell => cell.classList.add('csv-sticky-row'));
|
||||
} else {
|
||||
// 数据行(在tbody中,从第1个tr开始)
|
||||
const rowCells = this.tableEl.querySelectorAll(`tbody tr:nth-child(${rowIndex + 1}) td`);
|
||||
rowCells.forEach(cell => cell.classList.add('csv-sticky-row'));
|
||||
}
|
||||
// 数据行(在tbody中,从第1个tr开始)
|
||||
const rowCells = this.tableEl.querySelectorAll(`tbody tr:nth-child(${rowIndex + 1}) td`);
|
||||
rowCells.forEach(cell => cell.classList.add('csv-sticky-row'));
|
||||
});
|
||||
|
||||
// 应用固定列样式
|
||||
// 应用用户手动固定的列样式
|
||||
this.stickyColumns.forEach(colIndex => {
|
||||
// 列头(在thead中)
|
||||
// 列头(在thead中,跳过行号列)
|
||||
const headerCell = this.tableEl.querySelector(`thead tr th:nth-child(${colIndex + 2})`);
|
||||
if (headerCell) headerCell.classList.add('csv-sticky-col');
|
||||
|
||||
// 数据列(在tbody的所有行中)
|
||||
// 数据列(在tbody的所有行中,跳过行号列)
|
||||
const dataCells = this.tableEl.querySelectorAll(`tbody tr td:nth-child(${colIndex + 2})`);
|
||||
dataCells.forEach(cell => cell.classList.add('csv-sticky-col'));
|
||||
});
|
||||
|
||||
console.log('Applied sticky styles:', {
|
||||
stickyHeaders: this.stickyHeaders,
|
||||
stickyRowNumbers: this.stickyRowNumbers,
|
||||
stickyRows: Array.from(this.stickyRows),
|
||||
stickyColumns: Array.from(this.stickyColumns)
|
||||
});
|
||||
|
|
|
|||
50
styles.css
50
styles.css
|
|
@ -134,25 +134,67 @@ If your plugin does not need CSS, delete this file.
|
|||
}
|
||||
|
||||
/* Sticky行列样式 */
|
||||
.csv-sticky-row {
|
||||
|
||||
/* 默认固定表头样式(A、B、C、D...) */
|
||||
.csv-sticky-header {
|
||||
position: sticky !important;
|
||||
top: 0 !important;
|
||||
background: var(--background-secondary) !important;
|
||||
z-index: 20 !important;
|
||||
background: var(--background-secondary) !important;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1) !important;
|
||||
}
|
||||
|
||||
.csv-sticky-col {
|
||||
/* 第一个数据列的表头(A列)需要在行号列右侧 */
|
||||
.csv-sticky-header:nth-child(2) {
|
||||
left: 40px !important;
|
||||
z-index: 22 !important;
|
||||
}
|
||||
|
||||
/* 第一个数据列的所有单元格(A列数据)也需要在行号列右侧 */
|
||||
tbody tr td:nth-child(2) {
|
||||
position: sticky !important;
|
||||
left: 40px !important;
|
||||
z-index: 18 !important;
|
||||
background: var(--background-secondary) !important;
|
||||
box-shadow: 2px 0 4px rgba(0, 0, 0, 0.1) !important;
|
||||
}
|
||||
|
||||
/* 默认固定行号列样式(0、1、2、3...) */
|
||||
.csv-sticky-row-number {
|
||||
position: sticky !important;
|
||||
left: 0 !important;
|
||||
z-index: 20 !important;
|
||||
background: var(--background-secondary) !important;
|
||||
box-shadow: 2px 0 4px rgba(0, 0, 0, 0.1) !important;
|
||||
}
|
||||
|
||||
/* 左上角单元格(行号表头)同时是表头和行号 */
|
||||
.csv-sticky-header.csv-sticky-row-number {
|
||||
z-index: 25 !important;
|
||||
background: var(--background-modifier-hover) !important;
|
||||
}
|
||||
|
||||
/* 用户手动固定行样式 */
|
||||
.csv-sticky-row {
|
||||
position: sticky !important;
|
||||
top: 30px !important; /* 在表头下方 */
|
||||
z-index: 15 !important;
|
||||
background: var(--background-primary) !important;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1) !important;
|
||||
}
|
||||
|
||||
/* 用户手动固定列样式 */
|
||||
.csv-sticky-col {
|
||||
position: sticky !important;
|
||||
left: 40px !important; /* 在行号列右侧 */
|
||||
z-index: 15 !important;
|
||||
background: var(--background-primary) !important;
|
||||
box-shadow: 2px 0 4px rgba(0, 0, 0, 0.1) !important;
|
||||
}
|
||||
|
||||
/* 同时是sticky行和列的单元格 */
|
||||
.csv-sticky-row.csv-sticky-col {
|
||||
z-index: 25 !important;
|
||||
z-index: 18 !important;
|
||||
box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.15) !important;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue