mirror of
https://github.com/anomalyco/opencode.git
synced 2026-06-01 22:10:06 +02:00
fix(stats): restore leaderboard spacing
This commit is contained in:
@@ -83,6 +83,10 @@
|
||||
background: var(--stats-bg);
|
||||
}
|
||||
|
||||
[data-page="stats"] [hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
[data-page="stats"] [data-component="content"] {
|
||||
color: var(--stats-text);
|
||||
font-family:
|
||||
@@ -1706,15 +1710,30 @@
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
[data-page="stats"] [data-component="leaderboard"],
|
||||
[data-page="stats"] [data-slot="leaderboard-featured"],
|
||||
[data-page="stats"] [data-slot="leaderboard-compact"],
|
||||
[data-page="stats"] [data-slot="leaderboard-column"],
|
||||
[data-page="stats"] [data-slot="leaderboard-mobile"] {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
[data-page="stats"] [data-component="leaderboard"] {
|
||||
display: block;
|
||||
gap: 0;
|
||||
width: 100%;
|
||||
margin-top: 36px;
|
||||
scroll-margin-top: 88px;
|
||||
}
|
||||
|
||||
[data-page="stats"] [data-slot="leaderboard-featured"],
|
||||
[data-page="stats"] [data-slot="leaderboard-compact"] {
|
||||
grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
[data-page="stats"] [data-slot="leaderboard-pattern"] {
|
||||
scroll-margin-top: 88px;
|
||||
height: 16px;
|
||||
margin: 32px 0 16px;
|
||||
margin: 16px 0;
|
||||
overflow: hidden;
|
||||
background: var(--stats-hero-pattern);
|
||||
mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 6 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0H2V2H0V0Z' fill='black'/%3E%3C/svg%3E");
|
||||
@@ -1727,30 +1746,15 @@
|
||||
-webkit-mask-size: 6px 6px;
|
||||
}
|
||||
|
||||
[data-page="stats"] [data-slot="leaderboard-scroll"] {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
[data-page="stats"] [data-slot="leaderboard-column"] {
|
||||
gap: 8px;
|
||||
width: calc(100% + 80px);
|
||||
margin-inline: -40px;
|
||||
padding: 4px 40px 8px;
|
||||
overflow-x: auto;
|
||||
overscroll-behavior-x: contain;
|
||||
scroll-padding-inline: 40px;
|
||||
scroll-snap-type: x proximity;
|
||||
scrollbar-width: none;
|
||||
align-content: start;
|
||||
}
|
||||
|
||||
[data-page="stats"] [data-slot="leaderboard-scroll"]::-webkit-scrollbar {
|
||||
[data-page="stats"] [data-slot="leaderboard-mobile"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[data-page="stats"] [data-slot="leaderboard-scroll"] [data-component="leader-card"] {
|
||||
flex: 0 0 clamp(240px, 31vw, 360px);
|
||||
width: clamp(240px, 31vw, 360px);
|
||||
scroll-snap-align: start;
|
||||
}
|
||||
|
||||
[data-page="stats"] [data-component="leader-card"] {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
@@ -2598,14 +2602,6 @@
|
||||
[data-page="stats"] [data-section="session-cost"] {
|
||||
padding: 64px 32px;
|
||||
}
|
||||
|
||||
[data-page="stats"] [data-slot="leaderboard-scroll"] {
|
||||
width: calc(100% + 64px);
|
||||
margin-inline: -32px;
|
||||
padding-right: 32px;
|
||||
padding-left: 32px;
|
||||
scroll-padding-inline: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 58rem) {
|
||||
@@ -2649,9 +2645,9 @@
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
[data-page="stats"] [data-slot="leaderboard-scroll"] [data-component="leader-card"] {
|
||||
flex-basis: 280px;
|
||||
width: 280px;
|
||||
[data-page="stats"] [data-slot="leaderboard-featured"],
|
||||
[data-page="stats"] [data-slot="leaderboard-compact"] {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
[data-page="stats"] [data-component="leader-card"][data-size="featured"],
|
||||
@@ -2760,49 +2756,11 @@
|
||||
}
|
||||
|
||||
[data-page="stats"] [data-slot="leaderboard-featured"],
|
||||
[data-page="stats"] [data-slot="leaderboard-pattern"],
|
||||
[data-page="stats"] [data-slot="leaderboard-compact"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[data-page="stats"] [data-slot="leaderboard-pattern"] {
|
||||
margin: 24px 0 12px;
|
||||
}
|
||||
|
||||
[data-page="stats"] [data-slot="leaderboard-scroll"] {
|
||||
gap: 12px;
|
||||
width: calc(100% + 48px);
|
||||
margin-inline: -24px;
|
||||
padding-right: 24px;
|
||||
padding-left: 24px;
|
||||
scroll-padding-inline: 24px;
|
||||
}
|
||||
|
||||
[data-page="stats"] [data-slot="leaderboard-scroll"] [data-component="leader-card"] {
|
||||
flex: 0 0 240px;
|
||||
width: 240px;
|
||||
min-height: 156px;
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
[data-page="stats"] [data-slot="leaderboard-scroll"] [data-slot="leader-body"] {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
[data-page="stats"] [data-slot="leaderboard-scroll"] [data-slot="leader-avatar"] {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
padding: 4px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
[data-page="stats"] [data-slot="leaderboard-scroll"] [data-slot="leader-watermark"] {
|
||||
right: -68px;
|
||||
width: 240px;
|
||||
height: 240px;
|
||||
}
|
||||
|
||||
[data-page="stats"] [data-slot="leaderboard-mobile"] {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
|
||||
@@ -368,7 +368,7 @@ function formatUpdatedAtLabel(value: { date: string; time: string }) {
|
||||
}
|
||||
|
||||
function TopModelsSection(props: { data: StatsHomeData["usage"]; leaderboard: StatsHomeData["leaderboard"] }) {
|
||||
const [product, setProduct] = createSignal<UsageProduct>("All Users")
|
||||
const [product, setProduct] = createSignal<UsageProduct>("Go")
|
||||
const [range, setRange] = createSignal<UsageRange>("2M")
|
||||
const [sheet, setSheet] = createSignal<"product" | "range">()
|
||||
const [activeModel, setActiveModel] = createSignal<string>()
|
||||
@@ -409,7 +409,6 @@ function TopModelsSection(props: { data: StatsHomeData["usage"]; leaderboard: St
|
||||
onActiveModelChange={setActiveModel}
|
||||
/>
|
||||
</Show>
|
||||
<div id="leaderboard" data-slot="leaderboard-pattern" aria-hidden="true" />
|
||||
<Show
|
||||
when={leaderboard().length > 0}
|
||||
fallback={
|
||||
@@ -418,7 +417,7 @@ function TopModelsSection(props: { data: StatsHomeData["usage"]; leaderboard: St
|
||||
>
|
||||
<Leaderboard data={leaderboard()} activeModel={activeModel()} onActiveModelChange={setActiveModel} />
|
||||
</Show>
|
||||
<div data-slot="chart-footer">
|
||||
<div data-slot="chart-footer" hidden>
|
||||
<StatsFilters product={product()} range={range()} onProductSelect={setProduct} onRangeSelect={setRange} />
|
||||
<div data-slot="top-models-mobile-controls">
|
||||
<MobileFilterButton
|
||||
@@ -848,13 +847,50 @@ function Leaderboard(props: {
|
||||
activeModel: string | undefined
|
||||
onActiveModelChange: (model: string | undefined) => void
|
||||
}) {
|
||||
const featured = createMemo(() => props.data.slice(0, 3))
|
||||
const columns = createMemo(() =>
|
||||
[0, 1, 2].map((index) => props.data.slice(3 + index * 5, 8 + index * 5)).filter((column) => column.length > 0),
|
||||
)
|
||||
|
||||
return (
|
||||
<div data-component="leaderboard" role="list" aria-label="Model token leaderboard">
|
||||
<div data-slot="leaderboard-scroll" aria-label="Scrollable model token leaderboard">
|
||||
<div id="leaderboard" data-component="leaderboard" role="list" aria-label="Model token leaderboard">
|
||||
<div data-slot="leaderboard-featured">
|
||||
<For each={featured()}>
|
||||
{(entry) => (
|
||||
<LeaderboardCard
|
||||
entry={entry}
|
||||
size="featured"
|
||||
active={props.activeModel === entry.model}
|
||||
onActiveModelChange={props.onActiveModelChange}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
<div data-slot="leaderboard-pattern" aria-hidden="true" />
|
||||
<div data-slot="leaderboard-compact">
|
||||
<For each={columns()}>
|
||||
{(column) => (
|
||||
<div data-slot="leaderboard-column">
|
||||
<For each={column}>
|
||||
{(entry) => (
|
||||
<LeaderboardCard
|
||||
entry={entry}
|
||||
size="compact"
|
||||
active={props.activeModel === entry.model}
|
||||
onActiveModelChange={props.onActiveModelChange}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
<div data-slot="leaderboard-mobile" aria-label="Scrollable model token leaderboard">
|
||||
<For each={props.data}>
|
||||
{(entry) => (
|
||||
<LeaderboardCard
|
||||
entry={entry}
|
||||
size="featured"
|
||||
active={props.activeModel === entry.model}
|
||||
onActiveModelChange={props.onActiveModelChange}
|
||||
/>
|
||||
@@ -867,13 +903,14 @@ function Leaderboard(props: {
|
||||
|
||||
function LeaderboardCard(props: {
|
||||
entry: LeaderboardEntry
|
||||
size: "featured" | "compact"
|
||||
active: boolean
|
||||
onActiveModelChange: (model: string | undefined) => void
|
||||
}) {
|
||||
return (
|
||||
<article
|
||||
data-component="leader-card"
|
||||
data-size="featured"
|
||||
data-size={props.size}
|
||||
data-active={props.active ? "true" : undefined}
|
||||
role="listitem"
|
||||
tabIndex={0}
|
||||
@@ -986,17 +1023,19 @@ function MarketShareSection(props: { data: StatsHomeData["market"] }) {
|
||||
<span>[*]</span>
|
||||
<strong>{inspecting() ? formatMarketDate(activeDay()) : formatMarketRange(data())}</strong>
|
||||
</p>
|
||||
<FilterPills
|
||||
items={ranges}
|
||||
selected={range()}
|
||||
label="Date range"
|
||||
variant="range"
|
||||
onSelect={(item) => {
|
||||
setRange(item)
|
||||
setActiveAuthor(undefined)
|
||||
setInspecting(false)
|
||||
}}
|
||||
/>
|
||||
<div hidden>
|
||||
<FilterPills
|
||||
items={ranges}
|
||||
selected={range()}
|
||||
label="Date range"
|
||||
variant="range"
|
||||
onSelect={(item) => {
|
||||
setRange(item)
|
||||
setActiveAuthor(undefined)
|
||||
setInspecting(false)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
@@ -1215,7 +1254,7 @@ function marketDateParts(label: string) {
|
||||
}
|
||||
|
||||
function TokenCostSection(props: { data: StatsHomeData["tokenCost"] }) {
|
||||
const [product, setProduct] = createSignal<TokenProduct>("Zen")
|
||||
const [product, setProduct] = createSignal<TokenProduct>("Go")
|
||||
const [activeIndex, setActiveIndex] = createSignal(2)
|
||||
const data = createMemo(() => props.data[product()])
|
||||
const visible = createMemo(() => data().slice(0, 13))
|
||||
@@ -1233,7 +1272,7 @@ function TokenCostSection(props: { data: StatsHomeData["tokenCost"] }) {
|
||||
>
|
||||
<TokenCostChart data={visible()} activeIndex={selectedIndex()} onActiveIndexChange={setActiveIndex} />
|
||||
</Show>
|
||||
<div data-slot="token-footer">
|
||||
<div data-slot="token-footer" hidden>
|
||||
<FilterPills
|
||||
items={tokenProducts}
|
||||
selected={product()}
|
||||
@@ -1313,7 +1352,7 @@ function MetricBar(props: { value: number; max: number; active: boolean }) {
|
||||
}
|
||||
|
||||
function SessionCostSection(props: { data: StatsHomeData["sessionCost"] }) {
|
||||
const [product, setProduct] = createSignal<TokenProduct>("Zen")
|
||||
const [product, setProduct] = createSignal<TokenProduct>("Go")
|
||||
const [activeIndex, setActiveIndex] = createSignal(2)
|
||||
const data = createMemo(() => props.data[product()])
|
||||
const visible = createMemo(() => data().slice(0, 16))
|
||||
@@ -1334,7 +1373,7 @@ function SessionCostSection(props: { data: StatsHomeData["sessionCost"] }) {
|
||||
>
|
||||
<SessionCostChart data={visible()} activeIndex={selectedIndex()} onActiveIndexChange={setActiveIndex} />
|
||||
</Show>
|
||||
<div data-slot="token-footer">
|
||||
<div data-slot="token-footer" hidden>
|
||||
<FilterPills
|
||||
items={tokenProducts}
|
||||
selected={product()}
|
||||
|
||||
Reference in New Issue
Block a user