fix(core): improve table header sorting logic in processTable function (#14797)

Bug Resolved
#14795


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## 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.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Ahsan Khaleeq
2026-04-07 00:33:53 +05:00
committed by GitHub
parent 2ca4973167
commit 156cfc7e76
3 changed files with 12 additions and 12 deletions

View File

@@ -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<string, TableRow>,
cells: Record<string, TableCellSerialized>
): 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: [],
};

View File

@@ -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(() => {

View File

@@ -4,3 +4,8 @@ export const cleanSelection = () => {
selection.removeAllRanges();
}
};
export const compareByOrder = <T extends { order: string }>(
a: T,
b: T
): number => (a.order === b.order ? 0 : a.order > b.order ? 1 : -1);