milestone 23 s3: convert features/dashboard/StatCards.tsx to stylex
This commit is contained in:
@@ -69,9 +69,6 @@ const styles = stylex.create({
|
||||
textOverflow: "ellipsis",
|
||||
whiteSpace: "nowrap",
|
||||
},
|
||||
numeric: {
|
||||
fontVariantNumeric: "tabular-nums",
|
||||
},
|
||||
actions: {
|
||||
display: "flex",
|
||||
gap: "0.75rem",
|
||||
@@ -186,9 +183,9 @@ export default function BlocklistsPage() {
|
||||
{...stylex.props(shared.focusRing)}
|
||||
/>
|
||||
</td>
|
||||
<td {...stylex.props(shared.td, styles.numeric)}>{b.domain_count}</td>
|
||||
<td {...stylex.props(shared.td, styles.numeric)}>{b.wildcard_count}</td>
|
||||
<td {...stylex.props(shared.td, styles.numeric)}>{b.skipped_regex_count}</td>
|
||||
<td {...stylex.props(shared.td, shared.tabularNums)}>{b.domain_count}</td>
|
||||
<td {...stylex.props(shared.td, shared.tabularNums)}>{b.wildcard_count}</td>
|
||||
<td {...stylex.props(shared.td, shared.tabularNums)}>{b.skipped_regex_count}</td>
|
||||
<td {...stylex.props(shared.td)}>
|
||||
{b.last_updated === null ? "never" : formatTime(b.last_updated)}
|
||||
</td>
|
||||
|
||||
@@ -1,8 +1,49 @@
|
||||
import * as stylex from "@stylexjs/stylex";
|
||||
import { formatMicros } from "@/lib/format";
|
||||
import type { StatsTotals } from "@/lib/types";
|
||||
import { styles as shared } from "@/ui/styles";
|
||||
import { colors } from "@/ui/tokens.stylex";
|
||||
|
||||
const numberFormat = new Intl.NumberFormat();
|
||||
|
||||
const styles = stylex.create({
|
||||
/** Two columns on a phone, three from `md`, five from `xl`, as before. */
|
||||
grid: {
|
||||
display: "grid",
|
||||
gap: "0.75rem",
|
||||
gridTemplateColumns: {
|
||||
default: "repeat(2, minmax(0, 1fr))",
|
||||
"@media (min-width: 768px)": "repeat(3, minmax(0, 1fr))",
|
||||
"@media (min-width: 1280px)": "repeat(5, minmax(0, 1fr))",
|
||||
},
|
||||
},
|
||||
card: {
|
||||
borderRadius: "0.25rem",
|
||||
borderWidth: 1,
|
||||
borderStyle: "solid",
|
||||
borderColor: colors.border,
|
||||
backgroundColor: colors.surfaceRaised,
|
||||
paddingInline: "1rem",
|
||||
paddingBlock: "0.75rem",
|
||||
},
|
||||
label: {
|
||||
fontSize: "0.875rem",
|
||||
lineHeight: "1.25rem",
|
||||
color: colors.textMuted,
|
||||
},
|
||||
value: {
|
||||
fontSize: "1.5rem",
|
||||
lineHeight: "2rem",
|
||||
fontWeight: 600,
|
||||
},
|
||||
detail: {
|
||||
marginLeft: "0.5rem",
|
||||
fontSize: "0.875rem",
|
||||
lineHeight: "1.25rem",
|
||||
color: colors.textMuted,
|
||||
},
|
||||
});
|
||||
|
||||
function percentOf(part: number, total: number): string | null {
|
||||
if (total === 0) return null;
|
||||
return `${((part / total) * 100).toFixed(1)}%`;
|
||||
@@ -10,11 +51,11 @@ function percentOf(part: number, total: number): string | null {
|
||||
|
||||
function Card({ label, value, detail }: { label: string; value: string; detail?: string | null }) {
|
||||
return (
|
||||
<div className="rounded border border-zinc-200 bg-white px-4 py-3 dark:border-zinc-800 dark:bg-zinc-900">
|
||||
<dt className="text-sm text-zinc-500">{label}</dt>
|
||||
<div {...stylex.props(styles.card)}>
|
||||
<dt {...stylex.props(styles.label)}>{label}</dt>
|
||||
<dd>
|
||||
<span className="text-2xl font-semibold tabular-nums">{value}</span>
|
||||
{detail != null && <span className="ml-2 text-sm text-zinc-500 tabular-nums">{detail}</span>}
|
||||
<span {...stylex.props(styles.value, shared.tabularNums)}>{value}</span>
|
||||
{detail != null && <span {...stylex.props(styles.detail, shared.tabularNums)}>{detail}</span>}
|
||||
</dd>
|
||||
</div>
|
||||
);
|
||||
@@ -22,7 +63,7 @@ function Card({ label, value, detail }: { label: string; value: string; detail?:
|
||||
|
||||
export default function StatCards({ stats }: { stats: StatsTotals }) {
|
||||
return (
|
||||
<dl className="grid grid-cols-2 gap-3 md:grid-cols-3 xl:grid-cols-5">
|
||||
<dl {...stylex.props(styles.grid)}>
|
||||
<Card label="Queries" value={numberFormat.format(stats.queries)} />
|
||||
<Card
|
||||
label="Blocked"
|
||||
|
||||
@@ -43,9 +43,6 @@ const styles = stylex.create({
|
||||
whiteSpace: "nowrap",
|
||||
fontWeight: 500,
|
||||
},
|
||||
numeric: {
|
||||
fontVariantNumeric: "tabular-nums",
|
||||
},
|
||||
actions: {
|
||||
display: "flex",
|
||||
gap: "0.75rem",
|
||||
@@ -128,7 +125,7 @@ export default function UpstreamsPage() {
|
||||
{u.url}
|
||||
</span>
|
||||
</td>
|
||||
<td {...stylex.props(shared.td, styles.numeric)}>{u.priority}</td>
|
||||
<td {...stylex.props(shared.td, shared.tabularNums)}>{u.priority}</td>
|
||||
<td {...stylex.props(shared.td)}>
|
||||
<input
|
||||
type="checkbox"
|
||||
|
||||
@@ -151,6 +151,10 @@ export const styles = stylex.create({
|
||||
color: colors.dangerText,
|
||||
},
|
||||
|
||||
/** Digits of equal width, so a column of counts does not jitter as it updates. */
|
||||
tabularNums: {
|
||||
fontVariantNumeric: "tabular-nums",
|
||||
},
|
||||
/** For a value the operator reads character by character: a domain, an IP, a URL. */
|
||||
mono: {
|
||||
fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",
|
||||
|
||||
Reference in New Issue
Block a user