@@ -150,7 +150,7 @@ function ColumnVisibilityDropdown({
150150
151151
152152export function StablecoinTable ( { data, isLoading, activeFilters, logos, pegRates = { } , searchQuery, pegScores, dexLiquidity, reportCards, onClearSearch, onClearFilters } : StablecoinTableProps ) {
153- type SortKey = "name" | "price" | "mcap" | "change24h" | "change7d" | "stability" | "liquidity" | "grade" ;
153+ type SortKey = "name" | "price" | "mcap" | "change24h" | "change7d" | "stability" | "liquidity" | "grade" | "peg" ;
154154 const { sortKey, sortDirection, toggleSort, getAriaSortValue, handleSortKeyDown } = useSort < SortKey > ( "mcap" , "desc" ) ;
155155 const sort = useMemo ( ( ) => ( { key : sortKey , direction : sortDirection } ) , [ sortKey , sortDirection ] ) ;
156156 const router = useRouter ( ) ;
@@ -177,6 +177,7 @@ export function StablecoinTable({ data, isLoading, activeFilters, logos, pegRate
177177 stability : "stability" ,
178178 liquidity : "liquidity" ,
179179 grade : "grade" ,
180+ peg : "peg" ,
180181 } ;
181182 const colId = SORT_KEY_TO_COLUMN [ sortKey ] ;
182183 return visibleSet . has ( colId ) ? sortKey : "mcap" as SortKey ;
@@ -267,13 +268,30 @@ export function StablecoinTable({ data, isLoading, activeFilters, logos, pegRate
267268 bVal = bGrade ;
268269 break ;
269270 }
271+ case "peg" : {
272+ const getAbsBps = ( coin : ( typeof filtered ) [ 0 ] ) => {
273+ const m = metaById . get ( coin . id ) ;
274+ if ( m ?. flags . navToken ) return null ;
275+ const ref = getPegReference ( coin . pegType , pegRates , m ?. commodityOunces ) ;
276+ const price = coin . price ;
277+ return price != null && ref > 0 ? Math . abs ( price / ref - 1 ) * 10_000 : null ;
278+ } ;
279+ const aDev = getAbsBps ( a ) ;
280+ const bDev = getAbsBps ( b ) ;
281+ if ( aDev === null && bDev === null ) return 0 ;
282+ if ( aDev === null ) return 1 ;
283+ if ( bDev === null ) return - 1 ;
284+ aVal = aDev ;
285+ bVal = bDev ;
286+ break ;
287+ }
270288 default :
271289 aVal = getCirculatingRaw ( a ) ;
272290 bVal = getCirculatingRaw ( b ) ;
273291 }
274292 return sort . direction === "asc" ? aVal - bVal : bVal - aVal ;
275293 } ) ;
276- } , [ filtered , sort , effectiveSortKey , pegScores , dexLiquidity , reportCards ] ) ;
294+ } , [ filtered , sort , effectiveSortKey , pegScores , dexLiquidity , reportCards , pegRates , metaById ] ) ;
277295
278296 // Reset scroll when filters, search, or sort change
279297 const [ prev , setPrev ] = useState ( { filtered, sort } ) ;
@@ -402,7 +420,17 @@ export function StablecoinTable({ data, isLoading, activeFilters, logos, pegRate
402420 />
403421 ) }
404422 { isVisible ( "peg" ) && (
405- < TableHead className = "text-right" title = "Current peg deviation from target price" > Peg</ TableHead >
423+ < SortableTableHead
424+ sortKey = "peg"
425+ currentSortKey = { sortKey }
426+ sortDirection = { sortDirection }
427+ label = "Peg"
428+ toggleSort = { toggleSort }
429+ getAriaSortValue = { getAriaSortValue }
430+ handleSortKeyDown = { handleSortKeyDown }
431+ className = "text-right"
432+ title = "Sort by peg deviation — ascending shows tightest pegs first, descending shows worst depegs first"
433+ />
406434 ) }
407435 { isVisible ( "mcap" ) && (
408436 < SortableTableHead
0 commit comments