Repository navigation
Conversation
Collaborator
🟡 Heimdall Review Status
🟡
|
| Code Owner | Status | Calculation | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| ui-systems-eng-team |
🟡
0/1
|
Denominator calculation
|
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The comparator passed to
Array.prototype.sortinpackages/common/src/hooks/useSort.tsnever returned0:Array.prototype.sortrequires0when both values are equal. Returning1in both directions means the comparator claims
a > bandb > aat thesame time — an inconsistent comparator, for which the resulting order is
implementation-defined.
This triggers whenever two or more rows share the same value for the sort key,
which is very common in real tables: the same
appStatus, the same balance,the same price or rating. In that case the engine (V8 uses TimSort) can
reorder the tied rows arbitrarily.
Impact
Array.prototype.sortisstable, and stability is only observable for equal elements — exactly what
this comparator gets wrong.
renders for no user-visible reason.
(Safari/iOS) and Hermes (React Native) can each produce a different order
for the same data. CDS ships across web, mobile and native, so the same
table can render differently per platform.
useSortis exported as@coinbase/cds-common/hooks/useSort, is documented on the docs site, and isused in the Table stories and docs examples.
Fix
Resolve the sort values once and return
0when they are equal:Both sort directions are otherwise unchanged — ascending previously read
b > a ? -1 : 1, which is identical toa < b ? -1 : 1.Tests
useSortalready had tests, so a regression test was added topackages/common/src/hooks/__tests__/useSort.test.ts:Preserves the original order of tied values— asserts that rows sharing thesame
floorvalue keep their input order, for both ascending and descending.The pre-existing tests (ascending, descending, nested, deeply nested,
no-mutation) are unaffected: for unequal values the behavior is unchanged, and
the fix only affects pairs with equal values.