diff --git a/common/changes/@visactor/vtable/fix-issues-5211-checkbox-record-index_2026-07-28-00-00.json b/common/changes/@visactor/vtable/fix-issues-5211-checkbox-record-index_2026-07-28-00-00.json new file mode 100644 index 0000000000..bf7b04563f --- /dev/null +++ b/common/changes/@visactor/vtable/fix-issues-5211-checkbox-record-index_2026-07-28-00-00.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "fix: support updating checkbox state by record index", + "type": "patch", + "packageName": "@visactor/vtable" + } + ], + "packageName": "@visactor/vtable", + "email": "github@visactor.io" +} diff --git a/docs/assets/api/en/methods.md b/docs/assets/api/en/methods.md index f41c4a192c..d24cc48048 100644 --- a/docs/assets/api/en/methods.md +++ b/docs/assets/api/en/methods.md @@ -2107,14 +2107,21 @@ Get the selection state of all checkbox data under a field, the order correspond getCheckboxState(field?: string | number): Array ``` +- field: Optional checkbox field. If omitted, returns checkbox states for all fields +- return: Checkbox state array. Tree data keeps state by children path + ## getCellCheckboxState(Function) Get the state of a checkbox in a specific cell ``` -getCellCheckboxState(col: number, row: number): Array +getCellCheckboxState(col: number, row: number): boolean | 'indeterminate' | undefined ``` +- col: Column number +- row: Row number +- return: Checkbox state of the cell + ## getRadioState(Function) Get the selection state of all radio data under a field, the order corresponds to the original input data records, not the state value of the table display row @@ -2143,6 +2150,38 @@ setCellCheckboxState(col: number, row: number, checked: boolean) => void - row: Row number - checked: Whether selected +## setCellCheckboxStateByRecordIndex(Function) + +Set the checkbox state by source records index and field. For tree tables, pass a children path such as `[0, 1]` for the second child of the first root record. The state is updated even when the target node is collapsed and not currently visible. + +``` +setCellCheckboxStateByRecordIndex(recordIndex: number | number[], field: string | number, checked: boolean | 'indeterminate') => void +``` + +- recordIndex: Source data index; number for normal tables, number[] for tree tables +- field: Field of the checkbox column +- checked: Checkbox state, including `'indeterminate'` + +## clearCheckboxState(Function) + +Clear all checkbox checked states under the specified field. `clearAllCheckboxState(field)` is an alias of this method. + +``` +clearCheckboxState(field: string | number) => void +``` + +- field: Field of the checkbox column + +## clearAllCheckboxState(Function) + +Alias of `clearCheckboxState(field)`. Clear all checkbox checked states under the specified field. + +``` +clearAllCheckboxState(field: string | number) => void +``` + +- field: Field of the checkbox column + ## setCellRadioState(Function) Set the radio state of the cell to selected state diff --git a/docs/assets/api/zh/methods.md b/docs/assets/api/zh/methods.md index e10c0b8330..0168642727 100644 --- a/docs/assets/api/zh/methods.md +++ b/docs/assets/api/zh/methods.md @@ -2106,14 +2106,21 @@ arrangeCustomCellStyle: (cellPosition: { col?: number; row?: number; range?: Cel getCheckboxState(field?: string | number): Array ``` +- field: 可选,checkbox 所在字段;不传时返回所有字段的 checkbox 状态 +- 返回值: checkbox 状态数组,树形数据会按 children 路径组织状态 + ## getCellCheckboxState(Function) 获取某个单元格 checkbox 的状态 ``` -getCellCheckboxState(col: number, row: number): Array +getCellCheckboxState(col: number, row: number): boolean | 'indeterminate' | undefined ``` +- col: 列号 +- row: 行号 +- 返回值: 当前单元格 checkbox 状态 + ## getRadioState(Function) 获取某个字段下 radio 全部数据的选中状态 顺序对应原始传入数据 records 不是对应表格展示 row 的状态值 @@ -2142,6 +2149,38 @@ setCellCheckboxState(col: number, row: number, checked: boolean) => void - row: 行号 - checked: 是否选中 +## setCellCheckboxStateByRecordIndex(Function) + +根据源数据 records 的 index 和 field 设置 checkbox 状态。树形表格可传入 children 路径,例如 `[0, 1]` 表示第 1 条根节点下第 2 条子节点;即使该节点当前处于折叠不可见状态,也会更新其 checkbox 状态。 + +``` +setCellCheckboxStateByRecordIndex(recordIndex: number | number[], field: string | number, checked: boolean | 'indeterminate') => void +``` + +- recordIndex: 源数据索引;普通表格为 number,树形表格为 number[] +- field: checkbox 所在字段 +- checked: 是否选中,支持半选状态 `'indeterminate'` + +## clearCheckboxState(Function) + +清除指定 field 下所有 checkbox 的选中状态。`clearAllCheckboxState(field)` 是该方法的别名。 + +``` +clearCheckboxState(field: string | number) => void +``` + +- field: checkbox 所在字段 + +## clearAllCheckboxState(Function) + +`clearCheckboxState(field)` 的别名,用于清除指定 field 下所有 checkbox 的选中状态。 + +``` +clearAllCheckboxState(field: string | number) => void +``` + +- field: checkbox 所在字段 + ## setCellRadioState(Function) 将单元格的 radio 状态设置为选中状态 diff --git a/packages/vtable/__tests__/listTable-checkbox-record-index.test.ts b/packages/vtable/__tests__/listTable-checkbox-record-index.test.ts new file mode 100644 index 0000000000..5ecd791266 --- /dev/null +++ b/packages/vtable/__tests__/listTable-checkbox-record-index.test.ts @@ -0,0 +1,166 @@ +// @ts-nocheck +import { ListTable, TYPES } from '../src'; +import { createDiv } from './dom'; + +global.__VERSION__ = 'none'; + +describe('ListTable checkbox record index api', () => { + let table: ListTable; + + afterEach(() => { + table?.release(); + document.body.innerHTML = ''; + }); + + test('sets collapsed tree child checkbox state by record index path', () => { + table = new ListTable({ + container: createDiv(), + columns: [ + { + field: 'task', + title: 'Task', + tree: true, + cellType: 'checkbox', + headerType: 'checkbox' + } + ], + records: [ + { + task: { text: 'parent', checked: true }, + hierarchyState: TYPES.HierarchyState.collapse, + children: [{ task: { text: 'child', checked: true } }] + } + ], + enableCheckboxCascade: false + }); + const renderAsync = jest.spyOn(table, 'renderAsync').mockImplementation(() => Promise.resolve()); + + table.setCellCheckboxStateByRecordIndex([0, 0], 'task', false); + + expect(table.stateManager.checkedState.get('0,0').task).toBe(false); + expect(renderAsync).toHaveBeenCalledTimes(1); + }); + + test('clears all checkbox states for a field', () => { + table = new ListTable({ + container: createDiv(), + columns: [ + { + field: 'task', + title: 'Task', + tree: true, + cellType: 'checkbox', + headerType: 'checkbox' + } + ], + records: [ + { + task: { text: 'parent', checked: true }, + hierarchyState: TYPES.HierarchyState.collapse, + children: [{ task: { text: 'child', checked: true } }] + }, + { task: { text: 'sibling', checked: true } } + ], + enableCheckboxCascade: false + }); + const renderAsync = jest.spyOn(table, 'renderAsync').mockImplementation(() => Promise.resolve()); + + table.clearAllCheckboxState('task'); + + expect(table.stateManager.checkedState.get('0').task).toBe(false); + expect(table.stateManager.checkedState.get('0,0').task).toBe(false); + expect(table.stateManager.checkedState.get('1').task).toBe(false); + expect(table.stateManager.headerCheckedState.task).toBe(false); + expect(renderAsync).toHaveBeenCalledTimes(1); + }); + + test('keeps header indeterminate when checkedState is sparse', () => { + table = new ListTable({ + container: createDiv(), + columns: [ + { + field: 'task', + title: 'Task', + cellType: 'checkbox', + headerType: 'checkbox' + } + ], + records: [{ task: { text: 'checked', checked: true } }, { task: { text: 'unchecked' } }], + enableCheckboxCascade: false + }); + table.stateManager.checkedState.delete('1'); + + table.setCellCheckboxStateByRecordIndex(0, 'task', true); + + expect(table.stateManager.headerCheckedState.task).toBe('indeterminate'); + }); + + test('does not create false state for records that are already unchecked when clearing', () => { + table = new ListTable({ + container: createDiv(), + columns: [ + { + field: 'task', + title: 'Task', + tree: true, + cellType: 'checkbox', + headerType: 'checkbox' + } + ], + records: [ + { + task: { text: 'parent', checked: true }, + hierarchyState: TYPES.HierarchyState.collapse, + children: [{ task: { text: 'child', checked: true } }] + }, + { task: { text: 'already unchecked', checked: false } } + ], + enableCheckboxCascade: false + }); + table.stateManager.checkedState.delete('1'); + + table.clearAllCheckboxState('task'); + + expect(table.stateManager.checkedState.get('0').task).toBe(false); + expect(table.stateManager.checkedState.get('0,0').task).toBe(false); + expect(table.stateManager.checkedState.has('1')).toBe(false); + }); + + test('updates children and parent state when cascade is enabled', () => { + table = new ListTable({ + container: createDiv(), + columns: [ + { + field: 'task', + title: 'Task', + tree: true, + cellType: 'checkbox', + headerType: 'checkbox' + } + ], + records: [ + { + task: { text: 'parent', checked: true }, + hierarchyState: TYPES.HierarchyState.collapse, + children: [ + { task: { text: 'child 1', checked: true } }, + { task: { text: 'child 2', checked: true } } + ] + } + ], + enableCheckboxCascade: true + }); + + table.setCellCheckboxStateByRecordIndex([0, 0], 'task', false); + + expect(table.stateManager.checkedState.get('0').task).toBe('indeterminate'); + expect(table.stateManager.checkedState.get('0,0').task).toBe(false); + expect(table.stateManager.checkedState.get('0,1').task).toBe(true); + + table.setCellCheckboxStateByRecordIndex(0, 'task', false); + + expect(table.stateManager.checkedState.get('0').task).toBe(false); + expect(table.stateManager.checkedState.get('0,0').task).toBe(false); + expect(table.stateManager.checkedState.get('0,1').task).toBe(false); + }); +}); diff --git a/packages/vtable/examples/list/issue-5211-tree-checkbox-record-index.ts b/packages/vtable/examples/list/issue-5211-tree-checkbox-record-index.ts new file mode 100644 index 0000000000..5c8de24968 --- /dev/null +++ b/packages/vtable/examples/list/issue-5211-tree-checkbox-record-index.ts @@ -0,0 +1,79 @@ +import * as VTable from '../../src'; + +const CONTAINER_ID = 'vTable'; + +export function createTable() { + const records = [ + { + task: { text: 'Project A', checked: true }, + owner: 'Alice', + status: 'collapsed parent', + hierarchyState: VTable.TYPES.HierarchyState.collapse, + children: [ + { + task: { text: 'Hidden task A-1', checked: true }, + owner: 'Bob', + status: 'hidden child' + }, + { + task: { text: 'Hidden task A-2', checked: true }, + owner: 'Cindy', + status: 'hidden child' + } + ] + }, + { + task: { text: 'Project B', checked: true }, + owner: 'David', + status: 'root' + } + ]; + + const option: VTable.ListTableConstructorOptions = { + container: document.getElementById(CONTAINER_ID), + records, + columns: [ + { + field: 'task', + title: 'Task', + tree: true, + cellType: 'checkbox', + headerType: 'checkbox', + width: 260 + }, + { field: 'owner', title: 'Owner', width: 120 }, + { field: 'status', title: 'Status', width: 180 } + ], + defaultRowHeight: 38, + hierarchyIndent: 20, + enableCheckboxCascade: false, + enableHeaderCheckboxCascade: false, + theme: VTable.themes.BRIGHT + }; + + const tableInstance = new VTable.ListTable(option); + window.tableInstance = tableInstance; + + const toolbar = document.createElement('div'); + toolbar.style.cssText = 'position:absolute;top:8px;left:8px;z-index:10;display:flex;gap:8px;'; + + const setHiddenChildButton = document.createElement('button'); + setHiddenChildButton.textContent = 'Uncheck hidden child [0,0]'; + setHiddenChildButton.onclick = () => { + tableInstance.setCellCheckboxStateByRecordIndex([0, 0], 'task', false); + console.log('checkbox state after set hidden child:', tableInstance.getCheckboxState('task')); + }; + + const clearAllButton = document.createElement('button'); + clearAllButton.textContent = 'Clear task checkbox field'; + clearAllButton.onclick = () => { + tableInstance.clearAllCheckboxState('task'); + console.log('checkbox state after clear:', tableInstance.getCheckboxState('task')); + }; + + toolbar.appendChild(setHiddenChildButton); + toolbar.appendChild(clearAllButton); + document.body.appendChild(toolbar); + + return tableInstance; +} diff --git a/packages/vtable/examples/menu.ts b/packages/vtable/examples/menu.ts index 13b2c16107..34dbb96a68 100644 --- a/packages/vtable/examples/menu.ts +++ b/packages/vtable/examples/menu.ts @@ -123,6 +123,10 @@ export const menus = [ path: 'list', name: 'list-checkbox-tree' }, + { + path: 'list', + name: 'issue-5211-tree-checkbox-record-index' + }, { path: 'list', name: 'list-tree-20000' diff --git a/packages/vtable/src/ListTable.ts b/packages/vtable/src/ListTable.ts index 8366170c65..0dda560261 100644 --- a/packages/vtable/src/ListTable.ts +++ b/packages/vtable/src/ListTable.ts @@ -39,7 +39,12 @@ import type { IEditor } from '@visactor/vtable-editors'; import type { ColumnData, ColumnDefine, HeaderData } from './ts-types/list-table/layout-map/api'; import { getCellRadioState, setCellRadioState } from './state/radio/radio'; import { cloneDeepSpec } from '@visactor/vutils-extension'; -import { getGroupCheckboxState, setCellCheckboxState } from './state/checkbox/checkbox'; +import { + clearCheckboxState, + getGroupCheckboxState, + setCellCheckboxState, + setCheckboxStateByRecordIndex +} from './state/checkbox/checkbox'; import type { IEmptyTipComponent } from './components/empty-tip/empty-tip'; import { Factory } from './core/factory'; import { getGroupByDataConfig } from './core/group-helper'; @@ -1568,6 +1573,19 @@ export class ListTable extends BaseTable implements ListTableAPI { setCellCheckboxState(col: number, row: number, checked: boolean | 'indeterminate') { setCellCheckboxState(col, row, checked, this); } + setCellCheckboxStateByRecordIndex( + recordIndex: number | number[], + field: FieldDef, + checked: boolean | 'indeterminate' + ) { + setCheckboxStateByRecordIndex(recordIndex, field, checked, this); + } + clearCheckboxState(field: FieldDef) { + clearCheckboxState(field, this); + } + clearAllCheckboxState(field: FieldDef) { + this.clearCheckboxState(field); + } setCellRadioState(col: number, row: number, index?: number) { setCellRadioState(col, row, index, this); } diff --git a/packages/vtable/src/state/checkbox/checkbox.ts b/packages/vtable/src/state/checkbox/checkbox.ts index 9ac8d7eef0..9b7d676f07 100644 --- a/packages/vtable/src/state/checkbox/checkbox.ts +++ b/packages/vtable/src/state/checkbox/checkbox.ts @@ -1,6 +1,6 @@ import { isArray, isFunction, isNumber, isObject, isValid } from '@visactor/vutils'; import type { StateManager } from '../state'; -import type { CheckboxColumnDefine, ListTableAPI } from '../../ts-types'; +import type { CheckboxColumnDefine, FieldDef, ListTableAPI } from '../../ts-types'; import { getOrApply } from '../../tools/helper'; import type { BaseTableAPI } from '../../ts-types/base-table'; import type { CachedDataSource } from '../../data'; @@ -304,6 +304,34 @@ export function setCellCheckboxState( } } +export function setCheckboxStateByRecordIndex( + recordIndex: number | number[], + field: FieldDef, + checked: boolean | 'indeterminate', + table: BaseTableAPI +) { + setRecordCheckboxState(recordIndex, field, checked, table.stateManager.checkedState); + + if (table.internalProps.enableCheckboxCascade && checked !== 'indeterminate') { + updateChildrenCheckboxStateByRecordIndex(recordIndex, field, checked, table); + updateParentCheckboxStateByRecordIndex(recordIndex, field, table); + } + + updateVisibleCheckboxCellByRecordIndex(recordIndex, field, checked, table); + updateHeaderCheckboxStateByField(field, table); + renderCheckboxStateUpdate(table); +} + +export function clearCheckboxState(field: FieldDef, table: BaseTableAPI) { + if (!isValid(field)) { + return; + } + clearRecordCheckboxState((table as any).records, field, table); + updateVisibleCheckboxCellsByField(field, false, table); + updateHeaderCheckboxStateByField(field, table); + renderCheckboxStateUpdate(table); +} + export function setCellCheckboxStateByAttribute( col: number, row: number, @@ -404,6 +432,227 @@ export function getGroupCheckboxState(table: BaseTableAPI) { return result; } +function normalizeRecordIndex(recordIndex: number | number[]): number | number[] { + if (isArray(recordIndex) && recordIndex.length === 1) { + return recordIndex[0]; + } + return recordIndex; +} + +function setRecordCheckboxState( + recordIndex: number | number[], + field: FieldDef, + checked: boolean | 'indeterminate', + checkedState: Map +) { + const dataIndex = normalizeRecordIndex(recordIndex).toString(); + if (checkedState.get(dataIndex)) { + checkedState.get(dataIndex)[field as string | number] = checked; + } else { + checkedState.set(dataIndex, { + [field as string | number]: checked + }); + } +} + +function clearRecordCheckboxState(records: any[], field: FieldDef, table: BaseTableAPI, parentIndex: number[] = []) { + if (!isArray(records)) { + return; + } + + records.forEach((record, index) => { + const recordIndex = parentIndex.length ? parentIndex.concat(index) : [index]; + const currentState = getRecordCheckboxState(recordIndex, record, field, table); + if (currentState !== false) { + setRecordCheckboxState(recordIndex, field, false, table.stateManager.checkedState); + } + + if (isArray(record?.children)) { + clearRecordCheckboxState(record.children, field, table, recordIndex); + } + }); +} + +function updateVisibleCheckboxCellByRecordIndex( + recordIndex: number | number[], + field: FieldDef, + checked: boolean | 'indeterminate', + table: BaseTableAPI +) { + const bodyRowIndex = (table as ListTableAPI).getBodyRowIndexByRecordIndex?.(recordIndex); + if (!isNumber(bodyRowIndex) || bodyRowIndex < 0) { + return; + } + + const row = bodyRowIndex + table.columnHeaderLevelCount; + const cols = getCheckboxColsByField(field, row, table); + cols.forEach(col => { + setCellCheckboxStateByAttribute(col, row, checked, table); + }); +} + +function updateVisibleCheckboxCellsByField(field: FieldDef, checked: boolean | 'indeterminate', table: BaseTableAPI) { + const bodyStartRow = table.columnHeaderLevelCount; + const cols = getCheckboxColsByField(field, bodyStartRow, table); + for (let row = table.columnHeaderLevelCount; row < table.rowCount; row++) { + cols.forEach(col => { + setCellCheckboxStateByAttribute(col, row, checked, table); + }); + } +} + +function renderCheckboxStateUpdate(table: BaseTableAPI) { + const renderAsync = (table as any).renderAsync; + if (isFunction(renderAsync)) { + renderAsync.call(table); + } else { + table.render(); + } +} + +function updateHeaderCheckboxStateByField(field: FieldDef, table: BaseTableAPI) { + const fieldKey = field as string | number; + let hasChecked = false; + let hasUnchecked = false; + let hasRecord = false; + + traverseRecords((table as any).records, (record, recordIndex) => { + const state = getRecordCheckboxState(recordIndex, record, field, table); + hasRecord = true; + if (state === true) { + hasChecked = true; + } else if (state === 'indeterminate') { + hasChecked = true; + hasUnchecked = true; + } else { + hasUnchecked = true; + } + }); + + const checked = hasRecord && hasChecked && !hasUnchecked ? true : hasChecked ? 'indeterminate' : false; + table.stateManager.headerCheckedState[fieldKey] = checked; + updateVisibleHeaderCheckboxCellByField(field, checked, table); +} + +function updateVisibleHeaderCheckboxCellByField( + field: FieldDef, + checked: boolean | 'indeterminate', + table: BaseTableAPI +) { + for (let row = 0; row < table.columnHeaderLevelCount; row++) { + for (let col = 0; col < table.colCount; col++) { + if (table.getHeaderField(col, row) === field && table.getCellType(col, row) === 'checkbox') { + table.scenegraph.updateHeaderCheckboxCellState(col, row, checked); + } + } + } +} + +function getCheckboxColsByField(field: FieldDef, row: number, table: BaseTableAPI): number[] { + const cols: number[] = []; + for (let col = 0; col < table.colCount; col++) { + if (table.isHeader(col, row)) { + continue; + } + const define = table.getBodyColumnDefine(col, row); + if (define?.field === field && table.getCellType(col, row) === 'checkbox') { + cols.push(col); + } + } + return cols; +} + +function updateChildrenCheckboxStateByRecordIndex( + recordIndex: number | number[], + field: FieldDef, + checked: boolean, + table: BaseTableAPI +) { + const record = getRecordByRecordIndex((table as any).records, recordIndex); + if (!record?.children?.length) { + return; + } + + record.children.forEach((child: any, childIndex: number) => { + const childRecordIndex = normalizeRecordIndexToArray(recordIndex).concat(childIndex); + setRecordCheckboxState(childRecordIndex, field, checked, table.stateManager.checkedState); + updateVisibleCheckboxCellByRecordIndex(childRecordIndex, field, checked, table); + updateChildrenCheckboxStateByRecordIndex(childRecordIndex, field, checked, table); + }); +} + +function updateParentCheckboxStateByRecordIndex(recordIndex: number | number[], field: FieldDef, table: BaseTableAPI) { + const recordIndexPath = normalizeRecordIndexToArray(recordIndex); + for (let level = recordIndexPath.length - 1; level > 0; level--) { + const parentIndex = recordIndexPath.slice(0, level); + const parentRecord = getRecordByRecordIndex((table as any).records, parentIndex); + if (!parentRecord?.children?.length) { + continue; + } + + const childStates = parentRecord.children.map((child: any, childIndex: number) => + getRecordCheckboxState(parentIndex.concat(childIndex), child, field, table) + ); + const allChecked = childStates.every(state => state === true); + const allUnchecked = childStates.every(state => state !== true && state !== 'indeterminate'); + const parentState = allChecked ? true : allUnchecked ? false : 'indeterminate'; + setRecordCheckboxState(parentIndex, field, parentState, table.stateManager.checkedState); + updateVisibleCheckboxCellByRecordIndex(parentIndex, field, parentState, table); + } +} + +function getRecordCheckboxState( + recordIndex: number | number[], + record: any, + field: FieldDef, + table: BaseTableAPI +): boolean | 'indeterminate' { + const fieldKey = field as string | number; + const dataIndex = normalizeRecordIndex(recordIndex).toString(); + const cachedState = table.stateManager.checkedState.get(dataIndex)?.[fieldKey]; + if (isValid(cachedState)) { + return cachedState; + } + + const value = record?.[fieldKey]; + if (isObject(value) && isValid(value.checked)) { + return value.checked; + } + if (typeof value === 'boolean') { + return value; + } + return false; +} + +function getRecordByRecordIndex(records: any[], recordIndex: number | number[]): any { + const recordIndexPath = normalizeRecordIndexToArray(recordIndex); + let currentRecords = records; + let record; + for (let i = 0; i < recordIndexPath.length; i++) { + record = currentRecords?.[recordIndexPath[i]]; + currentRecords = record?.children; + } + return record; +} + +function normalizeRecordIndexToArray(recordIndex: number | number[]): number[] { + return isArray(recordIndex) ? recordIndex : [recordIndex]; +} + +function traverseRecords(records: any[], handler: (record: any, recordIndex: number | number[]) => void, parentIndex: number[] = []) { + if (!isArray(records)) { + return; + } + + records.forEach((record, index) => { + const recordIndex = parentIndex.length ? parentIndex.concat(index) : index; + handler(record, recordIndex); + if (isArray(record?.children)) { + traverseRecords(record.children, handler, isArray(recordIndex) ? recordIndex : [recordIndex]); + } + }); +} + function initRecordCheckState(records: any[], state: StateManager) { const table = state.table; const start = table.isPivotTable() diff --git a/packages/vtable/src/ts-types/table-engine.ts b/packages/vtable/src/ts-types/table-engine.ts index 5655c12ad8..00f45593ec 100644 --- a/packages/vtable/src/ts-types/table-engine.ts +++ b/packages/vtable/src/ts-types/table-engine.ts @@ -458,6 +458,25 @@ export interface ListTableAPI extends BaseTableAPI { reapplySort?: boolean; clearRowHeightCache?: boolean; }) => void; + /** 获取某个字段下 checkbox 全部数据的选中状态,顺序对应原始 records。 */ + getCheckboxState: (field?: string | number) => any[]; + /** 获取某个单元格 checkbox 的状态。 */ + getCellCheckboxState: (col: number, row: number) => boolean | 'indeterminate' | undefined; + /** 设置某个可见单元格 checkbox 的状态。 */ + setCellCheckboxState: (col: number, row: number, checked: boolean | 'indeterminate') => void; + /** + * 根据源数据 records 的 index + field 设置 checkbox 状态。 + * recordIndex 为源数据中的索引:普通表格为 number;树形表格为 number[](children 路径)。 + */ + setCellCheckboxStateByRecordIndex: ( + recordIndex: number | number[], + field: FieldDef, + checked: boolean | 'indeterminate' + ) => void; + /** 清除指定 field 的全部 checkbox 选中状态。 */ + clearCheckboxState: (field: FieldDef) => void; + /** clearCheckboxState 的别名,兼容 issue 中提出的 API 命名。 */ + clearAllCheckboxState: (field: FieldDef) => void; getFieldData: (field: FieldDef | FieldFormat | undefined, col: number, row: number) => FieldData; //#region 编辑器相关demo /** 获取单元格配置的编辑器 */