mirror of
https://github.com/liubinfighter/csv-lite.git
synced 2026-07-22 05:43:52 +00:00
feat: 添加源码模式和相关样式,支持在表格和源码视图之间切换
This commit is contained in:
parent
f2a8c03c6e
commit
d0123e6b5a
5 changed files with 84 additions and 4 deletions
|
|
@ -6,7 +6,9 @@ export const enUS = {
|
|||
deleteRow: 'Delete row',
|
||||
addColumn: 'Add column',
|
||||
deleteColumn: 'Delete column',
|
||||
resetColumnWidth: 'Reset column width'
|
||||
resetColumnWidth: 'Reset column width',
|
||||
sourceMode: 'Source Mode',
|
||||
tableMode: 'Table Mode'
|
||||
},
|
||||
editBar: {
|
||||
placeholder: 'Edit selected cell...'
|
||||
|
|
|
|||
|
|
@ -85,3 +85,6 @@ export class I18n {
|
|||
}
|
||||
|
||||
export const i18n = new I18n();
|
||||
|
||||
export * from "./en";
|
||||
export * from "./zh-cn";
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ export const zhCN = {
|
|||
deleteRow: '删除行',
|
||||
addColumn: '添加列',
|
||||
deleteColumn: '删除列',
|
||||
resetColumnWidth: '重置列宽'
|
||||
resetColumnWidth: '重置列宽',
|
||||
sourceMode: '源码模式',
|
||||
tableMode: '表格模式'
|
||||
},
|
||||
editBar: {
|
||||
placeholder: '编辑选中单元格...'
|
||||
|
|
|
|||
61
src/view.ts
61
src/view.ts
|
|
@ -50,6 +50,11 @@ export class CSVView extends TextFileView {
|
|||
private searchMatches: Array<{row: number, col: number, value: string}> = [];
|
||||
private currentSearchIndex: number = -1;
|
||||
|
||||
// 新增:源码模式相关属性
|
||||
private isSourceMode: boolean = false;
|
||||
private sourceTextarea: HTMLTextAreaElement | null = null;
|
||||
private sourceCursorPos: { start: number, end: number } = { start: 0, end: 0 };
|
||||
|
||||
constructor(leaf: any) {
|
||||
super(leaf);
|
||||
this.historyManager = new TableHistoryManager(
|
||||
|
|
@ -140,8 +145,35 @@ export class CSVView extends TextFileView {
|
|||
|
||||
refresh() {
|
||||
// Safety check: ensure tableEl exists
|
||||
if (!this.tableEl) {
|
||||
console.warn("Table element not initialized in refresh()");
|
||||
if (!this.contentEl) return;
|
||||
this.contentEl.querySelectorAll('.csv-source-mode').forEach(el => el.remove());
|
||||
if (this.isSourceMode) {
|
||||
// 源码模式:显示textarea
|
||||
let textarea = this.sourceTextarea;
|
||||
if (!textarea) {
|
||||
textarea = document.createElement('textarea');
|
||||
textarea.className = 'csv-source-mode';
|
||||
textarea.style.width = '100%';
|
||||
textarea.style.height = '60vh';
|
||||
this.sourceTextarea = textarea;
|
||||
}
|
||||
textarea.value = CSVUtils.unparseCSV(this.tableData);
|
||||
this.contentEl.appendChild(textarea);
|
||||
// 恢复光标
|
||||
if (this.sourceCursorPos) {
|
||||
setTimeout(() => {
|
||||
textarea.selectionStart = this.sourceCursorPos.start;
|
||||
textarea.selectionEnd = this.sourceCursorPos.end;
|
||||
textarea.focus();
|
||||
}, 0);
|
||||
}
|
||||
// 监听内容变更
|
||||
textarea.oninput = () => {
|
||||
try {
|
||||
this.tableData = CSVUtils.parseCSV(textarea.value, { delimiter: this.delimiter, quoteChar: this.quoteChar });
|
||||
this.requestSave();
|
||||
} catch (e) {}
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -674,6 +706,12 @@ export class CSVView extends TextFileView {
|
|||
}
|
||||
};
|
||||
|
||||
// 源码模式切换按钮
|
||||
const sourceToggleBtn = new ButtonComponent(this.operationEl)
|
||||
.setButtonText(this.isSourceMode ? i18n.t("buttons.tableMode") : i18n.t("buttons.sourceMode"))
|
||||
.setIcon(this.isSourceMode ? "table" : "code")
|
||||
.onClick(() => this.toggleSourceMode());
|
||||
|
||||
// 创建表格区域 - 只使用顶部滚动条
|
||||
const tableWrapper = this.contentEl.createEl("div", {
|
||||
cls: "table-wrapper",
|
||||
|
|
@ -754,6 +792,25 @@ export class CSVView extends TextFileView {
|
|||
}
|
||||
}
|
||||
|
||||
private toggleSourceMode() {
|
||||
this.isSourceMode = !this.isSourceMode;
|
||||
// 切换到源码模式时保存当前表格选中单元格
|
||||
if (this.isSourceMode) {
|
||||
if (this.activeCellEl) {
|
||||
this.sourceCursorPos = { start: 0, end: 0 };
|
||||
}
|
||||
} else {
|
||||
// 切换回表格模式时,保存textarea光标位置
|
||||
if (this.sourceTextarea) {
|
||||
this.sourceCursorPos = {
|
||||
start: this.sourceTextarea.selectionStart,
|
||||
end: this.sourceTextarea.selectionEnd
|
||||
};
|
||||
}
|
||||
}
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
// 新增:创建搜索容器,接受父容器参数
|
||||
private createSearchContainer(parentContainer?: HTMLElement) {
|
||||
// 如果提供了父容器,在其中创建搜索框,否则在contentEl中创建
|
||||
|
|
|
|||
16
styles.css
16
styles.css
|
|
@ -437,3 +437,19 @@ td input:focus {
|
|||
.csv-search-current .csv-cell-input {
|
||||
background-color: var(--text-highlight-bg) !important;
|
||||
}
|
||||
|
||||
/* 源码模式样式 */
|
||||
.csv-source-mode {
|
||||
font-family: var(--font-monospace, monospace);
|
||||
font-size: 1em;
|
||||
width: 100%;
|
||||
min-height: 300px;
|
||||
resize: vertical;
|
||||
box-sizing: border-box;
|
||||
margin: 1em 0;
|
||||
padding: 0.5em;
|
||||
background: var(--background-secondary);
|
||||
color: var(--text-normal);
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue