From 156cfc7e76b5420ca14a5e606c31e37ebcea49dc Mon Sep 17 00:00:00 2001 From: Ahsan Khaleeq Date: Tue, 7 Apr 2026 00:33:53 +0500 Subject: [PATCH] fix(core): improve table header sorting logic in processTable function (#14797) Bug Resolved #14795 ## Summary by CodeRabbit * **Bug Fixes** * Made row and column sorting deterministic when items share the same order value, reducing unexpected cell shifts. * Adjusted comparator behavior to preserve tied-order grouping, which may change displayed column/row sequence in edge cases. * Improved consistency of table rendering and cell placement across refreshes and edits. --- blocksuite/affine/blocks/table/src/adapters/utils.ts | 10 ++++------ .../affine/blocks/table/src/table-data-manager.ts | 9 +++------ blocksuite/affine/blocks/table/src/utils.ts | 5 +++++ 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/blocksuite/affine/blocks/table/src/adapters/utils.ts b/blocksuite/affine/blocks/table/src/adapters/utils.ts index d7a6b87a2..7d969c1e0 100644 --- a/blocksuite/affine/blocks/table/src/adapters/utils.ts +++ b/blocksuite/affine/blocks/table/src/adapters/utils.ts @@ -15,6 +15,8 @@ import { nanoid } from '@blocksuite/store'; import type { Element } from 'hast'; import type { Table as MarkdownTable } from 'mdast'; +import { compareByOrder } from '../utils'; + type RichTextType = DeltaInsert[]; const createRichText = (text: RichTextType) => { return { @@ -70,12 +72,8 @@ export const processTable = ( rows: Record, cells: Record ): Table => { - const sortedColumns = Object.values(columns).sort((a, b) => - a.order.localeCompare(b.order) - ); - const sortedRows = Object.values(rows).sort((a, b) => - a.order.localeCompare(b.order) - ); + const sortedColumns = Object.values(columns).sort(compareByOrder); + const sortedRows = Object.values(rows).sort(compareByOrder); const table: Table = { rows: [], }; diff --git a/blocksuite/affine/blocks/table/src/table-data-manager.ts b/blocksuite/affine/blocks/table/src/table-data-manager.ts index 916999d4c..a201a8551 100644 --- a/blocksuite/affine/blocks/table/src/table-data-manager.ts +++ b/blocksuite/affine/blocks/table/src/table-data-manager.ts @@ -4,6 +4,7 @@ import { nanoid, Text } from '@blocksuite/store'; import { computed, type ReadonlySignal, signal } from '@preact/signals-core'; import type { TableAreaSelection } from './selection-schema'; +import { compareByOrder } from './utils'; export class TableDataManager { constructor(private readonly model: TableBlockModel) {} @@ -28,15 +29,11 @@ export class TableDataManager { `${this.virtualRowCount$.value + this.rows$.value.length} x ${this.virtualColumnCount$.value + this.columns$.value.length}` ); readonly rows$ = computed(() => { - return Object.values(this.model.props.rows$.value).sort((a, b) => - a.order > b.order ? 1 : -1 - ); + return Object.values(this.model.props.rows$.value).sort(compareByOrder); }); readonly columns$ = computed(() => { - return Object.values(this.model.props.columns$.value).sort((a, b) => - a.order > b.order ? 1 : -1 - ); + return Object.values(this.model.props.columns$.value).sort(compareByOrder); }); readonly uiRows$ = computed(() => { diff --git a/blocksuite/affine/blocks/table/src/utils.ts b/blocksuite/affine/blocks/table/src/utils.ts index 526bbdf1c..5c84e9559 100644 --- a/blocksuite/affine/blocks/table/src/utils.ts +++ b/blocksuite/affine/blocks/table/src/utils.ts @@ -4,3 +4,8 @@ export const cleanSelection = () => { selection.removeAllRanges(); } }; + +export const compareByOrder = ( + a: T, + b: T +): number => (a.order === b.order ? 0 : a.order > b.order ? 1 : -1);