mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-30 14:58:08 +00:00
80 lines
3.5 KiB
TypeScript
80 lines
3.5 KiB
TypeScript
'use client'
|
|
|
|
import { Award } from 'lucide-react'
|
|
import { Text, View, XStack, YStack } from '@hanzo/ui'
|
|
import { Maker } from '@/components/models/Maker'
|
|
import { pct } from '@/lib/enso'
|
|
import type { Bar as Row, Bars } from '@/lib/home'
|
|
import { Win, useGrow } from './chrome'
|
|
|
|
/**
|
|
* A benchmark board as bars, group by group: ours in ink, every other row in
|
|
* outline, each at its share of the top score on the board, growing in once
|
|
* seen, each wearing the mark of the lab that makes it (components/models/Maker;
|
|
* none for a row that names no lab), and each figure with what lib/home says
|
|
* beside it: a cost, or which questions it is on.
|
|
*/
|
|
function Bar({ r, top, i, play, still }: { r: Row; top: number; i: number; play: boolean; still: boolean }) {
|
|
const ref = useGrow(play, still, { delay: i * 80, duration: 800 })
|
|
return (
|
|
<YStack gap={4} py={5} data-row={r.system}>
|
|
<XStack justify="space-between" columnGap={12} rowGap={2} flexWrap="wrap">
|
|
<XStack items="center" gap={8} minW={0}>
|
|
<Maker id={r.mark} ours={r.ours} />
|
|
<Text fontFamily="$mono" fontSize="$2" lineHeight="$2" color="var(--foreground)" fontWeight={r.ours ? '600' : '400'}>
|
|
{r.name}
|
|
</Text>
|
|
</XStack>
|
|
<Text ml="auto" fontFamily="$mono" fontSize="$2" lineHeight="$2" color="var(--foreground)" text="right" $platform-web={{ fontVariantNumeric: 'tabular-nums' }}>
|
|
{pct(r.accuracy)}
|
|
{r.aside ? (
|
|
<Text fontFamily="$mono" fontSize="$2" lineHeight="$2" color="var(--muted-foreground)">
|
|
{` ยท ${r.aside}`}
|
|
</Text>
|
|
) : null}
|
|
</Text>
|
|
</XStack>
|
|
<View height={8} rounded={9999} borderWidth={1} borderColor="var(--border)" overflow="hidden" $platform-web={{ borderRadius: '9999px' }}>
|
|
<View
|
|
ref={ref}
|
|
height="100%"
|
|
rounded={9999}
|
|
width={`${((r.accuracy / top) * 100).toFixed(2)}%`}
|
|
bg={r.ours ? 'var(--foreground)' : 'transparent'}
|
|
borderWidth={r.ours ? 0 : 1}
|
|
borderColor="var(--foreground)"
|
|
$platform-web={{ borderRadius: '9999px', transformOrigin: 'left center' }}
|
|
/>
|
|
</View>
|
|
</YStack>
|
|
)
|
|
}
|
|
|
|
/** A board's window: its groups of bars, each under its heading, and the line under them; `limit` keeps the first rows of the first group. */
|
|
export function Board({ b, title, play, still, slot, limit }: { b: Bars; title: string; play: boolean; still: boolean; slot: string; limit?: number }) {
|
|
const groups = b.groups.map((g, i) => (i === 0 && limit ? { ...g, rows: g.rows.slice(0, limit) } : g))
|
|
const top = Math.max(...groups.flatMap((g) => g.rows.map((r) => r.accuracy)))
|
|
let n = 0
|
|
return (
|
|
<Win title={title} icon={<Award size={14} color="var(--background)" strokeWidth={2.2} />} aside={b.aside ?? undefined} slot={slot}>
|
|
<YStack px={16} py={12} gap={14}>
|
|
{groups.map((g) => (
|
|
<YStack key={g.title ?? 'rows'} data-group={g.title ?? undefined}>
|
|
{g.title ? (
|
|
<Text fontFamily="$mono" fontSize="$1" lineHeight="$1" color="var(--muted-foreground)" pb={4}>
|
|
{g.title}
|
|
</Text>
|
|
) : null}
|
|
{g.rows.map((r) => (
|
|
<Bar key={r.key} r={r} top={top} i={n++} play={play} still={still} />
|
|
))}
|
|
</YStack>
|
|
))}
|
|
<Text fontSize="$1" lineHeight="$1" color="var(--muted-foreground)">
|
|
{b.foot}
|
|
</Text>
|
|
</YStack>
|
|
</Win>
|
|
)
|
|
}
|