diff --git a/packages/amis-core/src/store/table.ts b/packages/amis-core/src/store/table.ts index 4efc5daf3..2b9bf11aa 100644 --- a/packages/amis-core/src/store/table.ts +++ b/packages/amis-core/src/store/table.ts @@ -1380,14 +1380,14 @@ export const TableStore = iRendererStore } } - // 按住 shift 的时候点击选项 - function toggleShift(row: IRow, checked: boolean) { + function getToggleShiftRows(row: IRow) { // 如果是同一个或非 multiple 模式下就和不用 shift 一样 if (!lastCheckedRow || row === lastCheckedRow || !self.multiple) { - toggle(row, checked); - return; + return [row]; } + const toggleRows = []; + const maxLength = self.maxKeepItemSelectionLength; const checkableRows = self.checkableRows; const lastCheckedRowIndex = checkableRows.findIndex( @@ -1395,32 +1395,45 @@ export const TableStore = iRendererStore ); const rowIndex = checkableRows.findIndex(rowItem => row === rowItem); const minIndex = - lastCheckedRowIndex > rowIndex ? rowIndex : lastCheckedRowIndex; + lastCheckedRowIndex > rowIndex ? rowIndex : lastCheckedRowIndex + 1; const maxIndex = - lastCheckedRowIndex > rowIndex ? lastCheckedRowIndex : rowIndex; + lastCheckedRowIndex > rowIndex ? lastCheckedRowIndex : rowIndex + 1; const rows = checkableRows.slice(minIndex, maxIndex); - rows.push(row); // 将当前行也加入进行判断 for (const rowItem of rows) { - const idx = self.selectedRows.indexOf(rowItem); - if (idx === -1 && checked) { - // 如果上一个是选中状态,则将之间的所有 check 都变成可选 - if (lastCheckedRow.checked) { - if (maxLength) { - if (self.selectedRows.length < maxLength) { - self.selectedRows.push(rowItem); - } - } else { - self.selectedRows.push(rowItem); - } - } - } else if (!checked) { - if (!lastCheckedRow.checked) { - self.selectedRows.splice(idx, 1); - } + // 如果上一个是选中状态,则将之间的所有 check 都变成可选 + if ( + !( + lastCheckedRow.checked && + maxLength && + self.selectedRows.length + toggleRows.length >= maxLength + ) + ) { + toggleRows.push(rowItem); } } + return toggleRows; + } + + // 按住 shift 的时候点击选项 + function toggleShift(row: IRow, checked: boolean) { + const toggleRows = getToggleShiftRows(row); + + if (toggleRows?.length === 1) { + toggle(row, checked); + return; + } + + toggleRows.forEach(row => { + const idx = self.selectedRows.indexOf(row); + if (idx === -1 && checked) { + self.selectedRows.push(row); + } else if (~idx && !checked) { + self.selectedRows.splice(idx, 1); + } + }); + lastCheckedRow = row; } @@ -1633,6 +1646,7 @@ export const TableStore = iRendererStore getSelectedRows, toggle, toggleShift, + getToggleShiftRows, toggleExpandAll, toggleExpanded, collapseAllAtDepth, diff --git a/packages/amis/src/renderers/Table/index.tsx b/packages/amis/src/renderers/Table/index.tsx index 7c5250582..68579eabf 100644 --- a/packages/amis/src/renderers/Table/index.tsx +++ b/packages/amis/src/renderers/Table/index.tsx @@ -878,16 +878,33 @@ export default class Table extends React.Component { return; } + let rows = [item]; + if (shift) { + rows = store.getToggleShiftRows(item); + } + const selectedItems = value - ? [...store.selectedRows.map(row => row.data), item.data] + ? [ + ...store.selectedRows.map((row: IRow) => row.data), + ...rows.map((row: IRow) => row.data) + ] : store.selectedRows - .filter(row => row.id !== item.id) - .map(row => row.data); + .filter( + (row: IRow) => + rows.findIndex((rowItem: IRow) => rowItem === row) === -1 + ) + .map((row: IRow) => row.data); const unSelectedItems = value ? store.unSelectedRows - .filter(row => row.id !== item.id) - .map(row => row.data) - : [...store.unSelectedRows.map(row => row.data), item.data]; + .filter( + (row: IRow) => + rows.findIndex((rowItem: IRow) => rowItem === row) === -1 + ) + .map((row: IRow) => row.data) + : [ + ...store.unSelectedRows.map((row: IRow) => row.data), + ...rows.map((row: IRow) => row.data) + ]; const rendererEvent = await dispatchEvent( 'selectedChange',